require("luaScript.Protocol.ProtocolCommon") local Hall = class("Hall" , require("luaScript.Protocol.Protocol")) --[[ 请求 0x0114 : 请求创建房间 │ ┌───────────────┴────────────┒ │ │ 回复 0x0116 : 回复 0x0117 返回创建结果 已经在房间里面了 │ │ 请求:0x0115 请求 0x0118 请求进入房间 请求回到房间 ]] -- 命令集合 local HallCmd = { --[[/** * 用户创建房间 *
	 * 请求: {@code CreateRoomRequest}
	 * 返回:- 创建成功返回 0x0116
	 * 返回:- 若此时用户已经在房间里面玩牌,则返回 0x0117
	 * 
*/--]] CreateRoomRequest = 0x0114, --[[/** * 申请加入私人房 *
	 * 请求: {@code JoinRoomRequest}
	 * 返回:- 加入成功返回 0x0118
	 * 
*/--]] JoinRoomRequest = 0x0115, --[[/** * 创建房间返回结果 *
	 * 推送: {@code CreateRoomResponse}
	 * 
*/--]] CreateRoomResponse = 0x0116, --[[/** * 创建房间时用户已经在桌子上玩牌,此时客户端通过0x8001消息来重新进入游戏 *
	 * 推送: {@code CreateRoomResponseIn}
	 * 
*/--]] CreateRoomResponseIn = 0x0117, --[[/** * 申请加入私人房返回结果 *
	 * 推送: {@code CreateRoomResponse}
	 * 
*/--]] JoinRoomResponse = 0x0118, --[[/** * 房间列表请求 *
	 * 推送: {@code getRoomListRequest}
	 * 
*/--]] getRoomListRequest = 0x4001, --[[/** * 房间列表返回 *
	 * 推送: {@code getRoomListResponse}
	 * 
*/--]] getRoomListResponse = 0x4002, --[[/** * 快速加入 *
	 * 推送: {@code FastJoinRoomlyRequest}
	 * 
*/--]] FastJoinRoomlyRequest = 0x011a, --[[/** * 玩家已经在房间里面了,则发送此消息请求进入房间 *
	* 推送: {@code EnterRoomRequest}
	* 
*/--]] GAME_COMMAND_ENTER_ROOM = 0x8001, --[[/** * 客户端通过0x8001协议进入房间时, 优先通知客户端桌子游戏信息 *
	* 推送: {@code EnterRoomResponse}
	* 
*/--]] GAME_COMMAND_ENTER_ROOM_RESPONSE = 0x8017, --[[/** * 通过房间号查询游戏ID *
	* 请求: {@code QueryRoomRequest}
	* 
*/--]] Query_Room_Request = 0x0201, --[[/** * 通过房间号查询游戏ID的结果 *
	* 推送: {@code QueryRoomResponse}
	* 
*/--]] Query_Room_Response = 0x0202, --[[/** * 服务器透传php推送消息协议 *
	 * 推送: {@code GetPhpMessageResponse}
	 * 
*/--]] GAME_COMMAND_PHP_MESSAGE = 0x0c0c, } -- /////////////////////////////////////////////////////////////////////////////////////// -- QueryRoomRequest = defClass("QueryRoomRequest" -- 供查询的游戏列表 , defVar("gameIdList", VT_String, "") -- 房间ID , defVar("roomId", VT_Int, 0) -- 扩展字段 , defVar("extStr", VT_String, "") ) QueryRoomResponse = defClass("QueryRoomResponse" -- 0; 找到对应的房间 1: 房间不存在 , defVar("result", VT_Short, 0) -- 房间ID , defVar("roomId", VT_Int, 0) -- result为1时,此数据为0, 找到则为对应的游戏id , defVar("gameId", VT_Short, 0) -- 扩展字段 , defVar("extStr", VT_String, "") ) -- 创建房间请求 CreateRoomRequest = defClass("CreateRoomRequest" -- 游戏id , defVar("gameId", VT_Short, 0) -- 底注 , defVar("basechips", VT_Int, 0) -- 总局数 , defVar("totalGameNum", VT_Short, 0) -- 需要的房卡信息 , defVar("requireCards", VT_Int, 0) -- 进入游戏的方式 //0:游戏开始后不允许进人,1:游戏开始后可以进人 , defVar("enterFlag", VT_Short, 0) -- json格式 ,不同游戏内容不一样 , defVar("gameInfo", VT_String, "") -- 創建者的用户信息 , defVar("userInfo", VT_String, "") ) -- 进入房间成功,则读取房间数据 CreateRoomEntitySuccess = defClass("CreateRoomEntitySuccess" -- 展示的房间id , defVar("iShowTid", VT_Int, 0) -- 服务id, 客户端无需关注 , defVar("serverId", VT_Int, 0) -- gameId , defVar("gameId", VT_Int, 0) -- 游戏信息 , defVar("gameInfo", VT_String, "") ) -- 进入房间失败,数据为空 CreateRoomEntityFailed = defClass("CreateRoomEntityFailed" ) -- 创建房间结果 CreateRoomEntity = defClass("CreateRoomEntity" -- 游戏id --1房卡数量不够,当result不为0时,则无下面3个参数 , defVar("result", VT_Short, 0) -- 扩展自定义数据 , localVar("custom", VT_Int) ) CreateRoomEntityType = { [1] = { Data = CreateRoomEntitySuccess}, [2] = { Data = CreateRoomEntityFailed}, } CreateRoomDataFactories = {}; for i , v in pairs(CreateRoomEntityType) do CreateRoomDataFactories[v.Data] = { conditionDataType = i, } end local newBindableArray = require("luaScript.Protocol.BindableArray"); local function newCreateRoomResponse(defaultValue) return newBindableArray(); end local function readCreateRoomResponse(stream) local obj = CreateRoomEntity:read(stream); print("xxxx readed:" , table.toString(obj)); if obj.result == 0 then obj.custom = CreateRoomEntityType[1].Data:read(stream); else obj.custom = CreateRoomEntityType[2].Data:read(stream); end return obj; end local function writeCreateRoomResponse(value , stream) local cls = rawget(value.custom , "NetVar"); --[[ local conditionType = NotifyDataFactories[cls]; if conditionType == nil then error("发往服务器时发现了不存在的conditionType:" .. tostring(conditionType)); end --]] -- 写入数据 CreateRoomEntity:write(stream , value); cls:write(stream , value.custom); end -- 创建房间结果 CreateRoomResponseCreator = VT_Custom("CreateRoomResponseCreator" , newCreateRoomResponse , readCreateRoomResponse , writeCreateRoomResponse) CreateRoomResponse = defClass("CreateRoomResponse" , defVar("info", CreateRoomResponseCreator) ) -- 创建房间时,玩家已经在房间里面 CreateRoomResponseIn = defClass("CreateRoomResponseIn" -- 桌子信息 , defVar("tid", VT_Int, 0) -- 游戏服务id , defVar("serverId", VT_Int, 0) -- 保留字段 , defVar("res", VT_Int, 0) -- 服务等级 , defVar("serverLevel", VT_Short, 0) -- 游戏id , defVar("gameId", VT_Short, 0) ) -- 申请加入私人房 JoinRoomRequest = defClass("JoinRoomRequest" -- 游戏id , defVar("gameId", VT_Short, 0) -- 展示的房间id , defVar("inputTid", VT_Int, 0) -- 用户信息 , defVar("userInfo", VT_String, 0) ) -- 0x8001 : 玩家已经在房间里面了,则直接发送真实房间号,申请进入房间 EnterRoomRequest = defClass("EnterRoomRequest" -- 房间真实id , defVar("tid", VT_Int, 0) -- nUserId , defVar("nUserId", VT_Int, 0) -- 用户信息 , defVar("userInfo", VT_String, "") ) -- 0x8017 EnterRoomResponse = defClass("EnterRoomResponse" -- 总局数 , defVar("totalGameNum", VT_Short, 0) -- 房间号 , defVar("ShowTableId", VT_Int, 0) -- 游戏id , defVar("gameId", VT_Int, 0) -- 游戏信息,json格式,同创建房间 , defVar("strGameInfo", VT_String, "") -- 茶馆id,大于0说明用户在茶馆中 , defVar("nClubId", VT_Int, 0) ) -------------------- FastJoinRoomlyRequest = defClass("FastJoinRoomlyRequest" -- 游戏id列表, 用逗号隔开,如“1,2,3” 则表示此合集包含游戏1,2,3 , defVar("gameIdList", VT_String, "") -- 房间号 , defVar("roomId", VT_Int, 0) -- 用户信息 , defVar("userInfo", VT_String, "") ) getRoomListRequest = defClass("getRoomListRequest" -- 游戏类型 , defVar("gameId", VT_Short, 0) -- 游戏id , defVar("uid", VT_Int, 0) ) roomList = defClass("roomList" -- 桌子的ID , defVar("nShowTableId", VT_Int, 0) -- 总局数 , defVar("nTotalGameNum", VT_Short, 0) -- 当前人数 , defVar("nUserCount", VT_Short, 0) -- 最大人数 , defVar("nMaxUserCount", VT_Short, 0) -- 游戏信息 json格 式,同创建房间json , defVar("strGameInfo", VT_String, "") ) getRoomListResponse = defClass("getRoomListResponse" -- 桌子的ID , defVar("roomList", VT_Vector(roomList), {}) ) -- //////////////////////////////////// 以上是消息结构的定义 //////////////////////////////////// -- -- //////////////////////////////////// 以下是服务器消息的处理 //////////////////////////////////// -- -- 请求创建房间 function Hall:requestCreateRoom(request) -- 为了收到服务器返回的结果时能正确接收房间消息 -- 这里应该先加载房间协议 local gameInfo = {} local gameType = nil if request.gameInfo then gameInfo = json.decode(request.gameInfo) gameType = gameInfo.gamerule or 0 end app:changeGameProtocol(request.gameId or 0,gameType); logD("Hall:requestCreateRoom() request = ", table.tostring(request)) app.waitDialogManager:showWaitNetworkDialog(); self:sendResponse{cmd = HallCmd.CreateRoomRequest , sender = request}; end -- 创建房间结果 - 创建房间的结果,成功或者失败 function Hall:onCreateRoomResponse(status, response) print("Hall:onCreateRoomResponse(), ", table.tostring(response)) app.waitDialogManager:closeWaitNetworkDialog(); local errCode = { [0] = "创建房间成功", [1] = PLN.CURRENCY_NOT_ENOUGH, [2] = "达到最高开房限制", [3] = "桌子数不够了",--需要服务器加桌子 } -- 不成功则弹出提示 if response.info.result and response.info.result ~= 0 then showTooltip(errCode[response.info.result] or tostring(response.info.result)); return; end if cc.Application:getInstance():getTargetPlatform() == 0 then cc.UserDefault:getInstance():setIntegerForKey("LastRoomID",response.info.custom.iShowTid) cc.UserDefault:getInstance():flush() end -- 如果加入失败,服务器会通过 0x8005 下发房间数据 -- 如果加入成功,服务器会通过 0x8007 或 0x8009 下发房间数据 -- 请到对应的 ProtocolRoom 里面去处理 end -- 创建房间结果 - 玩家已经在房间里面了 function Hall:onCreateRoomResponseIn(status, response) print("Hall:onCreateRoomResponseIn(), ", table.tostring(response)) app.waitDialogManager:closeWaitNetworkDialog(); -- 服务器告知玩家已经在房间里面了 -- 则直接申请回到房间 --这里应该加入协议切换类型,在金币场多次点后,第二次判断在房间里面,收到此消息,于是从金币场切回了房卡的协议去了 --[[ [2019-07-04 16:04:15][LUA] Hall:onCreateRoomResponseIn(), { ["gameId"] = 2, ["res"] = 1, ["serverId"] = 3, ["serverLevel"] = 20, ["tid"] = 198656, }--]] local protocolType = PROTOCOL_TYPE.COMMON if response.serverLevel and response.serverLevel > 1 then protocolType = PROTOCOL_TYPE.COIN end self:requestEnterRoom(response.gameId,response.tid,protocolType); end -- 申请加入房间 function Hall:requestJoinRoom(gameId, tableId) print("Hall:requestJoinRoom(), ", gameId, tableId ) local request = JoinRoomRequest:new(); request.gameId = gameId; request.inputTid = tableId; request.userInfo = app.user.userInfo; local function doRequest() app:changeGameProtocol(gameId, 1); print("Hall:requestJoinRoom(), ", table.tostring(request)) app.waitDialogManager:showWaitNetworkDialog(); self:sendResponse{cmd = HallCmd.JoinRoomRequest , sender = request}; end -- 检查一下这个子游戏是否需要更新 if app.subGameManager then local isInstall = app.subGameManager:isInstaller(gameId) local isNeedUpdate = app.subGameManager:isNeedUpdate(gameId) if not isInstall or isNeedUpdate then downloadSubGame(gameId, doRequest) return; end end doRequest() end -- 加入房间结果 function Hall:onJoinRoomResponse(status, response) print("Hall:onJoinRoomResponse(), ", table.tostring(response)) app.waitDialogManager:closeWaitNetworkDialog(); local errCode = response.info.result if errCode ~= 0 then local errString = ENTER_ROOM_RET_STR[errCode] or "房间不存在" showTooltip(errString); return; end --[[ -- 展示的房间id , defVar("iShowTid", VT_Int, 0) -- 服务id, 客户端无需关注 , defVar("serverId", VT_Int, 0) -- gameId , defVar("gameId", VT_Int, 0) -- 游戏信息 , defVar("gameInfo", VT_String, "") ]] local gameId = response.info.custom.gameId local gameInfo = json.decode(response.info.custom.gameInfo) local gameType = gameInfo.gamerule -- 为了收到服务器返回的结果时能正确接收房间消息 -- 这里应该先加载房间协议 app:changeGameProtocol(gameId,gameType); -- 如果加入失败,服务器会通过 0x8005 下发房间数据 -- 如果加入成功,服务器会通过 0x8007 或 0x8009 下发房间数据 -- 请到对应的 ProtocolRoom 里面去处理 end -- 快速加入房间 function Hall:requestFastJoinRoom(roomId) print("Hall:requestFastJoinRoom()", roomId) local listIds = app.subGameManager:getGameListInstalled() local request = FastJoinRoomlyRequest:new(); request.gameIdList = listIds request.roomId = roomId; request.userInfo = app.user.userInfo; print("Hall:requestFastJoinRoom() ", table.tostring(request)) app.waitDialogManager:showWaitNetworkDialog(); self:sendResponse{cmd = HallCmd.FastJoinRoomlyRequest , sender = request}; end -- 0x8001 : 请求回到房间,玩家已经在房间了,使用此接口 function Hall:requestEnterRoom(gameId, tableId, protocolType) print("Hall:requestEnterRoom()", tableId) local request = EnterRoomRequest:new(); request.tid = tableId request.nUserId = app.user.loginInfo.uid; request.userInfo = app.user.userInfo; app:changeGameProtocol(gameId, 1, protocolType); print("Hall:requestEnterRoom() ", table.tostring(request)) -- app.waitDialogManager:showWaitNetworkDialog(); self:sendResponse{cmd = HallCmd.GAME_COMMAND_ENTER_ROOM , sender = request}; end -- 0x8017 : 对 0x8001 的回复 function Hall:onEnterRoomResponse(status, response) print("Hall:onEnterRoomResponse", table.tostring(response)) app.waitDialogManager:closeWaitNetworkDialog(); if not response then return; end local gameid = response.gameId local gameRule = nil local gameInfo = json.decode(response.strGameInfo) if response.ShowTableId then setGameRoomId(response.ShowTableId) end if gameInfo then gameRule = gameInfo.gamerule or 0 --桌子下标 app.club_php.tableIdx = gameInfo.tableIdx end local clubID = response.nClubId; if clubID > 0 then --茶馆id>0,说明玩家从茶馆中开房 app.club_php.clubID = clubID; else app.club_php.clubID = 0; end -- 为了收到服务器返回的结果时能正确接收房间消息 -- 这里应该先加载房间协议 app:changeGameProtocol(gameid, gameRule); end -- 请求获取房间列表 function Hall:requestGetRoomList(gameId) local request = getRoomListRequest:new() request.gameId = gameId request.uid = app.user.loginInfo.uid self:sendResponse{cmd = HallCmd.getRoomListRequest , sender = request}; end -- 获取房间结果 function Hall:onGetRoomListResponse(status, response) print("Hall:onGetRoomListResponse(), ", table.tostring(response)) self:dispatchEvent({name = "onGetRoomListResponse", response = response}); end -- 通过房间号查询游戏ID -- 查询完成后返回 gameid, roomid function Hall:queryRoomId(roomId, callback) if not self.queryCallbackList then self.queryCallbackList = {} end if not self.queryIndex then self.queryIndex = 0 end self.queryIndex = self.queryIndex + 1 local extStr = tostring(self.queryIndex) self.queryCallbackList[extStr] = callback local gameIds = {} for k,v in pairs(app.serverConfigs.subGameList) do table.insert(gameIds,v.gameId or 0) end local ids = nil; for id,v in pairs(gameIds) do if v > 0 then if not ids then ids = tostring(v) else ids = tostring(ids) .. "," .. tostring(v) end end end local request = QueryRoomRequest:new() request.gameIdList = ids request.roomId = roomId request.extStr = extStr logD("Hall:queryRoomId() ", table.tostring(request)) self:sendResponse{cmd = HallCmd.Query_Room_Request , sender = request}; end -- 查询房间结果 function Hall:onQueryRoomResponse(status, response) print("Hall:onQueryRoomResponse(), ", table.tostring(response)) local result = response.result local gameId = response.gameId local roomId = response.roomId local extStr = response.extStr; local queryCallback = self.queryCallbackList[extStr] if queryCallback then queryCallback(gameId, roomId) end end --服务器透传php推送消息协议 function Hall:onGetPhpMessageResponse(status, response) logD("Hall:onGetPhpMessageResponse(), response = ", table.tostring(response)) --[[ -- 如果5分钟之内没有再次收到推送消息,则上传日志 if self.timerHandler then cc.Director:getInstance():getScheduler():unscheduleScriptEntry(self.timerHandler); self.timerHandler = nil end self.unschedule = cc.Director:getInstance():getScheduler():scheduleScriptFunc(function() uploadLogs("PHPMESSAGE") end, 5 * 60, false) --]] -- 以下是正常逻辑 if not response then logD("Hall:onGetPhpMessageResponse", "response is nil"); return ; end local message = json.decode(response.stringValue); if message == nil then return end logD("Hall:onGetPhpMessageResponse(), message = ", table.tostring(message)) if tonumber(message.type) == 10 then -- 充值钻石 local attr = message.attr logD("Hall:onGetPhpMessageResponse(), attr = ", table.tostring(attr)) app.user.loginInfo.curCardNum = tonumber(attr.curr_card) app.user.loginInfo.historyCardNum = tonumber(attr.total_card) elseif tonumber(message.type) == 12 then -- 充值欢乐豆 local attr = message.attr app.user.loginInfo.curBeanNum = tonumber(attr.curr_beans) self:dispatchEvent({name = GAME_EVENT.RECHARGE_RESULT}) elseif tonumber(message.type) == 13 then -- 充值礼券 local attr = message.attr app.user.loginInfo.curLiquanNum = tonumber(attr.curr_coupons) self:dispatchEvent({name = "couponsAdd", attr = attr}) elseif tonumber(message.type) == 14 then -- 客户端实时上传日志 if message.attr and message.attr.date then if logFileManager then logFileManager:uploadFilesByDay(message.attr.date) end end else -- 这里处理不了的,就发送事件出去,让能处理的人处理 app:dispatchEvent({name = "onPhpMessage",msg = message}); end end -- //////////////////////////////////// 以上是服务器消息的处理 //////////////////////////////////// -- function Hall:ctor(net) Hall.super.ctor(self , net); -- 玩家已经在房间里面了,则发送此消息,请求进入房间 self:defMsgFunc{name = "enterRoomRequest", cmd = HallCmd.GAME_COMMAND_ENTER_ROOM, sender = EnterRoomRequest}; -- 推送创建房间结果(正常进入)如果进房成功,服务器会快速分配桌子给玩家,分配成功返回进入桌子成功消息 RoomCmd.GAME_COMMAND_LOGIN_GAME_SUCCESS self:defPushMsg{cmd = HallCmd.CreateRoomResponse , reader = CreateRoomResponse, func = handler(self , self.onCreateRoomResponse)}; -- 推送创建房间结果(玩家已经在房间里面) self:defPushMsg{cmd = HallCmd.CreateRoomResponseIn , reader = CreateRoomResponseIn, func = handler(self , self.onCreateRoomResponseIn)}; -- 推送加入房间结果,同快速加入结果 self:defPushMsg{cmd = HallCmd.JoinRoomResponse , reader = CreateRoomResponse, func = handler(self , self.onJoinRoomResponse)}; -- 发8001返回此消息,为游戏房间信息 self:defPushMsg{cmd = HallCmd.GAME_COMMAND_ENTER_ROOM_RESPONSE , reader = EnterRoomResponse, func = handler(self , self.onEnterRoomResponse)}; -- 房间列表结果 self:defPushMsg{cmd = HallCmd.getRoomListResponse , reader = getRoomListResponse, func = handler(self , self.onGetRoomListResponse)}; self:defPushMsg{cmd = HallCmd.Query_Room_Response , reader = QueryRoomResponse, func = handler(self , self.onQueryRoomResponse)}; self:defPushMsg{cmd = HallCmd.GAME_COMMAND_PHP_MESSAGE, reader = StringPacket, func = handler(self, self.onGetPhpMessageResponse)} end return Hall;