syntax = "proto3";
package AxibugProtobuf;
option optimize_for = SPEED;

enum CommandID
{
    CMD_DEFAUL = 0;//缺省不使用
	
	//服务器或客户端,均可主动ping请求,对方响应。(这里测全流程延迟,即序 列化->发送->传输过程->接收->反序列化)
	CMD_PING = 1;  //Ping | 请求 对应 Protobuf_Ping
	CMD_PONG = 2;  //Pong | 响应 对应 Protobuf_Pong
	
	CMD_LOGIN = 2001;  //自动登录上行 | 下行 对应 Protobuf_Login | Protobuf_Login_RESP
	
	CMD_USER_ONLINELIST = 3000;  //获取在线用户列表 上行 | 下行 对应 Protobuf_UserList | Protobuf_UserList_RESP
	CMD_USER_JOIN = 3031;  //用户上线 下行 对应 Protobuf_UserOnline_RESP
	CMD_USER_LEAVE = 3032;  //用户下线 下行 对应 Protobuf_UserOffline_RESP
	CMD_USER_STATE_UPDATE = 3033;  //更新在线用户状态 下行 对应 Protobuf_UserState_RESP
	
	CMD_Modify_NickName = 3101;  //修改名称上行 | 下行 对应 Protobuf_Modify_NickName | Protobuf_Modify_NickName_RESP
	CMD_Update_SelfUserInfo = 3110;  //更新用户信息 下行 Protobuf_Update_UserInfo_RESP
	CMD_Update_OtherUserInfo = 3112;  //更新其他用户信息 下行 Protobuf_Update_OtherUserInfo_RESP
	
	CMD_CHATMSG = 4001;  //广播聊天信息上行 | 下行 对应 Protobuf_ChatMsg | Protobuf_ChatMsg_RESP
	
	//房间列表相关(仅用于列表显示)
	CMD_Room_List = 5001;  //房间列表 上行 | 下行 对应 Protobuf_Room_List | Protobuf_Room_List_RESP
	CMD_Room_List_Update = 5002;  //房间单个房间信息更新 对应 Protobuf_Room_Update_RESP
	CMD_Room_Get_Screen = 5011;  //房间列表 上行 | 下行 对应 Protobuf_Room_Get_Screen | Protobuf_Room_Get_Screen_RESP
	
	//房间内相关
	CMD_Room_Create = 5101;  //房间创建 对应 Protobuf_Room_Create | Protobuf_Room_Create_RESP
	CMD_Room_Join = 5105;  //房间加入 对应 Protobuf_Room_Join | Protobuf_Room_Join_RESP //建议Join之前按照房间信息,提前下载并读取本地Rom
	CMD_Room_Leave = 5106;  //房间离开 对应 Protobuf_Room_Leave | Protobuf_Room_Leave_RESP
	CMD_Room_MyRoom_State_Changed = 5110;  //我所在的房间内状态发生变化 对应 Protobuf_Room_MyRoom_State_Change
	
		//准备和开始流程(5201 ~ 5204 ~ 5208)
		//
		// 我们采用,玩家可以随时进入的方式开发
		//
		// 设计流程: 
		//
		// Step0:服务器广播"等待-主机上报即使存档" CMD_Room_WaitStep WaitStep=[0] ---> 客户端:暂停模拟器核心:全员等待(主机玩家一人上传即时存档)
		// 			主机玩家 上行 CMD_Room_HostPlayer_UpdateStateRaw消息,上传即时存档
		// 			主机玩家上传完毕之后,服务器会通知进入Step1
		//
		// Step1:服务器广播"等待-全员加载即时存档" CMD_Room_WaitStep WaitStep=[1] 附带即时存档 ---> 客户端:全员等待
		//			所有玩家确保加载ROM和即时存档,并保持模拟器暂停,准备完毕后 发送 CMD_Room_Player_Ready
		//			所有玩家Ready之后,服务器会根据所有玩家延迟提前跑若干Frame,通知进入Step2 
		//			
		// Step2:服务器广播"开始" CMD_Room_WaitStep WaitStep=[2] ---> 客户端:立即开始
		//
		//
		// PS:[联机过程中加载即时存档] 房间在游玩过程中,单个玩家发送CMD_Room_HostPlayer_UpdateStateRaw 上报即时存档
		// 		重新从Step1走流程
		// 
	CMD_Room_WaitStep = 5201;  //服务器等待Step通知 下行 Protobuf_Room_WaitStep_RESP
	CMD_Room_HostPlayer_UpdateStateRaw = 5204;  //主机玩家上传即时存档 上行 | 下行 对应 Protobuf_Room_HostPlayer_UpdateStateRaw | Protobuf_Room_HostPlayer_UpdateStateRaw_RESP
	CMD_Room_Player_Ready = 5208;  //玩家准备完毕 上行 Protobuf_Room_Player_Ready
	
	//游戏同步
	CMD_Room_Singel_PlayerInput = 6010; //单个玩家操作同步上行 对应 Protobuf_Room_SinglePlayerInputData
	CMD_ROOM_SYN_PlayerInput = 6015; //所有玩家操作同步下行  对应 Protobuf_Room_Syn_RoomFrameAllInputData
	
	//画面采集
	CMD_Screen = 7001;  //画面采集 | 同步广播 对应 Protobuf_Screnn_Frame
}

enum ErrorCode
{
    ERROR_DEFAUL = 0;//缺省不使用
	ERROR_OK = 1;   //成功
	
	ERROR_ROOM_NOT_FOUND = 10;//房间不存在
	ERROR_ROOM_SLOT_READLY_HAD_PLAYER=11;//加入目标位置已经有人
	
	ERROR_ROOM_CANT_DO_CURR_STATE =50;//当前房间状态不允许本操作
}

enum LoginType
{
	UseDevice = 0;//使用设备登录
	UseAccount = 1;//使用账户
	UseHaoYueAccount = 2;//使用皓月通行证
}

enum DeviceType
{
    DeviceType_Default = 0;//缺省不使用
	PC = 1;
	Android = 2;
	IOS = 3;
	PSV = 4;
}

//enum RoomPlayerState
//{
//    None_PlayerState = 0;//缺省
//	OnlyP1 = 1;   //仅P1
//	OnlyP2 = 2;   //仅P2
//	BothOnline = 3;   //玩家都在
//}

enum RoomGameState
{
    None_GameState = 0;//缺省
    OnlyHost = 1;//仅主机,待加入
	WaitRawUpdate = 2;//等待即时存档
	WaitReady = 3;//等待Ready
	Pause = 4;//暂停
	InOnlineGame = 5;//联机中
}


enum LoginResultStatus
{
    LoginResultStatus_BaseDefault = 0;//缺省不使用
	OK = 1;
	AccountErr = 2;
}

//聊天 上行
message Protobuf_ChatMsg
{
	string ChatMsg = 1;//消息
}

//聊天 下行
message Protobuf_ChatMsg_RESP
{
	string NickName = 1;//昵称
	string ChatMsg = 2;//消息
	int64 Date = 3;//时间
}

message Protobuf_Ping
{
	int32 Seed = 1;//随机数
}

message Protobuf_Pong
{
	int32 Seed = 1;//原样返回随机数
}

//登录数据上行
message Protobuf_Login
{
	LoginType loginType = 1;//登录操作类型
	DeviceType deviceType = 2;//设备类型 [0] PC [1] AndroidPad预留 [3] IPad预留
	string deviceStr = 3;//设备串
	string Account = 4;//用户名
	string Password = 5;//密码
}

//登录数据下行
message Protobuf_Login_RESP
{
	string NickName = 1;//昵称(第一次是自动生成)
	string Token = 2;//登录凭据 (本次登录之后,所有业务请求凭据,需要存储在内存中)
	string LastLoginDate = 3;//上次登录时间(只用于呈现的字符串,若界面需求需要)
	string RegDate = 4;//注册时间(只用于呈现的字符串,若界面需求需要)
	LoginResultStatus Status = 5;//账号状态 (预留) [1]正常[0]被禁封
	int64 UID = 6;
}



//获取在线用户列表 上行
message Protobuf_UserList
{
}

//获取在线用户列表 下行
message Protobuf_UserList_RESP
{
	int32 UserCount = 1;//玩家数量
	repeated UserMiniInfo UserList = 2;//用户列表
}

//用户上线 下行
message Protobuf_UserJoin_RESP
{
	UserMiniInfo UserInfo = 1;//用户
}

//用户下线 下行
message Protobuf_UserLeave_RESP
{
	int64 UID = 1;//用户ID
}

//更新在线用户状态 下行
message Protobuf_UserState_RESP
{
	int64 UID = 1;//用户ID
	int32 State = 2;//状态
}

message UserMiniInfo
{
	int64 UID = 1;//用户ID
	string NickName = 2;//昵称
}

//修改昵称上行
message Protobuf_Modify_NickName
{
	string NickName = 1;//昵称
}

//修改昵称下行
message Protobuf_Modify_NickName_RESP
{

}

//用户信息更新
message Protobuf_Update_UserInfo_RESP
{
	UserMiniInfo UserInfo = 1;//用户
}

//其他用户信息更新
message Protobuf_Update_OtherUserInfo_RESP
{
	int64 UID = 1;//用户ID
	UserMiniInfo UserInfo = 2;//用户
}

message Protobuf_Room_List
{
	
}

message Protobuf_Room_List_RESP
{
	repeated Protobuf_Room_MiniInfo RoomMiniInfoList = 1;//房间列表
}

message Protobuf_Room_MiniInfo
{
	int32 RoomID = 1;//房间ID
	int32 GameRomID = 2;//游戏ID
	string GameRomHash = 3;
	int64 HostPlayerUID = 4;//主机玩家ID
	RoomGameState GameState = 5;//游戏状态
	int32 ObsUserCount = 6;//观战用户数量
	int64 Player1_UID = 7;//玩家1 UID
	string Player1_NickName = 8;//玩家1 昵称
	int64 Player2_UID = 9;//玩家2 UID
	string Player2_NickName = 10;//玩家2 昵称
	int64 Player3_UID = 11;//玩家3 UID
	string Player3_NickName = 12;//玩家3 昵称
	int64 Player4_UID = 13;//玩家4 UID
	string Player4_NickName = 14;//玩家4 昵称
	int64 ScreenProviderUID = 15;//屏幕数据供应者
}

message Protobuf_Room_Update_RESP
{
	int32 UpdateType = 1;//[0] 更新或新增 [1] 删除
	Protobuf_Room_MiniInfo RoomMiniInfo = 2;//房间信息
}

message Protobuf_Screnn_Frame
{
	int32 RoomID = 1;//房间ID
	int32 FrameID = 2;//帧编号
    bytes RawBitmap = 3;//渲染层画面
}

message Protobuf_Room_SinglePlayerInputData
{
	uint32 FrameID = 1;//帧编号
	uint32 InputData = 2;//单个玩家操作位运算汇总
}

message Protobuf_Room_Syn_RoomFrameAllInputData
{
	uint32 FrameID = 1;//帧编号
	uint64 InputData = 2;//所有玩家操作位运算汇总
	uint32 ServerFrameID = 3;//服务器帧编号
}

message Protobuf_Room_Create
{
	int32 GameRomID = 1;
	string GameRomHash = 2;
	int32 JoinPlayerIdx = 3;//P1~P4[0~3] 以几号位玩家创建房间
}

message Protobuf_Room_Create_RESP
{
	Protobuf_Room_MiniInfo RoomMiniInfo = 1;//房间信息
}

message Protobuf_Room_Join
{
	int32 RoomID = 1;//房间ID
	int32 PlayerNum = 2;//玩家编号 [0]1号玩家 [1]2号玩家
}

message Protobuf_Room_Join_RESP
{
	Protobuf_Room_MiniInfo RoomMiniInfo = 1;//房间信息
}

message Protobuf_Room_Leave
{
	int32 RoomID = 1;//离开的房间ID
}

message Protobuf_Room_Leave_RESP
{
	int32 RoomID = 1;//离开的房间ID
}

message Protobuf_Room_MyRoom_State_Change
{
	Protobuf_Room_MiniInfo RoomMiniInfo = 1;//更新房间信息
}

message Protobuf_Room_WaitStep_RESP
{
	int32 WaitStep = 1;//状态 [0]等待主机上报即时存档 [1]要求客户端准备 [2]开始(收到本状态时,立即开始跑模拟器核心)
	
	//如下是 WaitStep = 1 时,才有值。广播即时存档
    bytes LoadStateRaw = 2;//即时存档byte数据
}

message Protobuf_Room_HostPlayer_UpdateStateRaw
{
    bytes LoadStateRaw = 1;//即时存档byte数据
}

message Protobuf_Room_HostPlayer_UpdateStateRaw_RESP
{
}

message Protobuf_Room_Player_Ready
{
}

message Protobuf_Room_Get_Screen
{
	int32 RoomID = 1;//房间ID
}

message Protobuf_Room_Get_Screen_RESP
{
	int32 RoomID = 1;//房间ID
	int32 FrameID = 2;//帧编号
    bytes RawBitmap = 3;//渲染层画面
}