--[[ 说明:从服务器获取的所有配置信息 更新记录: ------------------------------------------------------------------ 2018-03-01 重新优化获取子游戏列表的流程 获取服务器配置成功之后,开始初始化子游戏列表,同时请求登录。 也就是说,登录时可以子游戏列表的数据可能是空的。 初始化子游戏列表的流程 1、从本地读取子游戏列表数据 2、从服务器获取子游戏列表数据,成功后覆盖本地数据 3、将子游戏列表数据写入到本地文件 玩家登陆成功需要显示游戏列表时,肯定是又数据的。 如果此时网络状况良好,则数据是服务器下发的最新数据, 如果此时网络状况差,则使用的是本地文件的数据,即上一次从服务器获取的数据。 加入玩家是第一次打开游戏,就碰到网络状况差,则游戏列表是空的。此题无解。 ------------------------------------------------------------------ --]] require("luaScript.Protocol.ProtocolCommon") local ServerConfigs = class("ServerConfigs", require("luaScript.Protocol.Protocol")) local ConfigCmd = { --[[/** * 客户端请求获取配置信息 *
	 * 请求: {@code ServerConfigRequest}
	 * 
*/--]] GAME_COMMAND_GET_SERVER_CONF = 0x0301, --[[/** * server返回游戏的配置信息 *
	 * 推送: {@code ServerConfigResponse}
	 * 
*/--]] GAME_COMMAND_SEND_SERVER_CONF = 0x0302, --[[/** * server返回游戏的配置信息 *
	 * 推送: {@code ServerConfigsResponse}
	 * 
*/--]] GAME_COMMAND_SEND_GAME_CONF = 0x0303, --[[/** * 客户端和PHP之间交互使用的TCP通道 *
	 * 请求: {@code StringPacket}
	 * 
*/--]] GAME_COMMAND_PHP = 0x0401, } -- 登陆之前配置请求 ServerConfigRequest = defClass("ServerConfigRequest" -- gameId ,defVar("appId", VT_String, "") ) -- 服务器返回配置 ServerConfigResponse= defClass("ServerConfigResponse" --json格式的信息 , defVar("strContent", VT_String, "") ) -- 多游戏配置数据 ServerConfigsResponse = defClass("ServerConfigsResponse" -- 各个游戏的配置信息,json格式, , defVar("gameServerConfigList", VT_Vector(VT_String), {}) ) -- 登录之前需要做的初始化 function ServerConfigs:initBeforeLogin() if not self._isInited then self:requestGetServerConfig() end end function ServerConfigs:initBeforLoginSuccessed(bInit) self._isInited = (bInit == true) if self._isInited then self:dispatchEvent({name = "initBeforLoginSuccessed"}) end end function ServerConfigs:getInitStatus() return (self._isInited == true) end ------------------------- PHP 通道 ------------------------- -- ttInfo : 传送给PHP的数据 -- callback : 处理后的回调 function ServerConfigs:sendPhpMsg(ttInfo, callback) if not ttInfo or type(ttInfo) ~= "table" then return end -- 索引++ self.phpIndex = self.phpIndex + 1; -- 记录回调索引 local callbackKey = self.phpIndex .. "_" .. (ttInfo.pSSq or "0") self.phpCallbackList[callbackKey] = callback -- 改变发往服务器的索引 ttInfo.pSSq = callbackKey local strContent = json.encode(ttInfo) -- 发送消息到服务器 local request = StringPacket:new() request.stringValue = strContent; logD("ServerConfigs:sendPhpMsg() request = " .. table.tostring(request)) self:sendResponse{cmd = ConfigCmd.GAME_COMMAND_PHP , sender = request}; end function ServerConfigs:onPhpMsgResponse(status, response) logD("ServerConfigs:onPhpMsgResponse()", tostring(status), table.tostring(response)) if status ~= 0 then return end local ttResult = json.decode(response.stringValue) if not ttResult then return end local index = tostring(ttResult.pSSq) if not index then return end if not self.phpCallbackList[index] then return end self.phpCallbackList[index](0, ttResult); self.phpCallbackList[index] = nil; end ------------------------- 配置相关 ------------------------- -- 获取配置信息 function ServerConfigs:requestGetServerConfig() local request = ServerConfigRequest:new() request.appId = getAppId() log("ServerConfigs:requestGetServerConfig() request = ", table.tostring(request)) self:sendResponse{cmd = ConfigCmd.GAME_COMMAND_GET_SERVER_CONF , sender = request}; end function ServerConfigs:onServerConfigResponse(status, response) logD("ServerConfigs:onServerConfigResponse()", tostring(status), table.tostring(response)) if status ~= 0 then return end local ttResult = json.decode(response.strContent) -- 公告信息 self.notice = {} local notice = tostring(ttResult.notice) or "" if notice ~= "" then local arr = string.split(notice, "\n") for k,v in pairs(arr) do table.insert(self.notice, v) end end -- 滚动公告 self.scroll = tostring(ttResult.scroll) or "" -- 游戏ID self.gameId = tonumber(ttResult.gameId) or 0 -- 区域信息 self.areano = tonumber(ttResult.areano) or 0 -- 记录获取大厅配置成功 self.isGetConfigSuccess = true self:onServerConfigSuccessed(); end function ServerConfigs:onServerConfigsResponse(status, response) log("ServerConfigs:onServerConfigsResponse()", tostring(status), table.tostring(response)) if status ~= 0 then return end self.configs = {} for _, value in pairs(response.gameServerConfigList) do local ttConfig = json.decode(value) if ttConfig and type(ttConfig) == "table" and ttConfig.gameid then self.configs[tonumber(ttConfig.gameid)] = ttConfig; if ttConfig.contiTimer then--连打房间解散时间,黄十八用 app.user.contiTimer = ttConfig.contiTimer end end end self.isGetConfigsSuccess = true; self:onServerConfigSuccessed(); end function ServerConfigs:onServerConfigSuccessed() if self.isGetConfigSuccess and self.isGetConfigsSuccess then -- 先请求一次全国数据,亲友圈、创建房间、修改玩法里面显示的必须是所有游戏 self:requestGameList(0, true, function () -- 再根据当前选择地区,再拉取对应地区的游戏列表 local regionCode = cc.UserDefault:getInstance():getIntegerForKey("address_code_" .. app.config.RomSetting.Platform) self:requestGameList(regionCode) end) self:initBeforLoginSuccessed(true) end end ------------------------- 子游戏列表 ------------------------- function ServerConfigs:saveSubGameListToFile() logD("ServerConfigs:saveSubGameListToFile()", table.tostring(self.subGameList)) table.saveToLocFile(self.subGameList, "SubGameList.lua") end function ServerConfigs:loadSubGameListFromFile() self.subGameList = table.loadFromLocFile("SubGameList.lua") or {} logD("ServerConfigs:loadSubGameListFromFile()", table.tostring(self.subGameList)) end -- 获取子游戏版本信息 function ServerConfigs:requestGetSubGameVersions(endCallback) local params = { action = "system.games", app = getAppId(), uid = loadUserId(), apkver = "",-- 获取子游戏版本号时不再依赖APK的版本号 - zzb,20190715 installGameVer = "", isNew=1, } for gameId,v in pairs(self.subGameList) do local ver=app.subGameManager:isInstaller(gameId) and app.subGameManager.GameVersions[gameId] or -1 params.installGameVer=params.installGameVer..gameId..","..ver.."|" end --基础包 local baseIds={1001,1002,1003} for k,gameId in pairs(baseIds) do local ver=app.subGameManager:isInstaller(gameId) and app.subGameManager.GameVersions[gameId] or -1 params.installGameVer=params.installGameVer..gameId..","..ver.."|" end logD("ServerConfigs:requestGetSubGameVersions() ", table.tostring(params)); self:sendPhpMsg(params, function(status, response) self:getSubGameVersionsResponse(status, response) if endCallback then endCallback() end end) end function ServerConfigs:getSubGameVersionsResponse(status, ttResult) logD("ServerConfigs:getSubGameVersionsResponse() " .. table.tostring(ttResult)) self.getsubGameList = true if ttResult and tonumber(ttResult.code) == 200 and ttResult.result and type(ttResult.result) == "table" then for k,v in pairs(ttResult.result) do if k~="new" then local gameId = tonumber(k) local gameInfo = self.subGameList[gameId] or {} -- 下载提示 gameInfo.desc = tostring(v.desc) -- 新版本 gameInfo.version = tostring(v.ver) -- 资源下载地址 if v.url and v.url ~= "" then gameInfo.versionUrls = toStringArray(",")(v.url) end self.subGameList[gameId] = gameInfo; end end --添加新更新数据 if ttResult.result.new then for k,v in pairs(ttResult.result.new) do local gameId = tonumber(k) if self.subGameList[gameId] then self.subGameList[gameId].newUpdate=v else self.subGameList[gameId] = {} self.subGameList[gameId].newUpdate=v end end end end -- 添加更多游戏的显示 -- local gameInfo = -- { -- gameId = 0; -- gameName = "更多游戏"; -- sortIndex = 9999; -- show = true; -- } -- self.subGameList[gameInfo.gameId] = gameInfo if isIOSReviewVersion() then -- 苹果审核 ---self:updateSubGameVisible({7,12}) self:updateSubGameVisible() elseif isRuanZhu() then -- 软著 if app.config.RomSetting.ruanZhuGames then self:updateSubGameVisible(app.config.RomSetting.ruanZhuGames or {}) else -- 六胡抢 self:updateSubGameVisible({5}) end else --self:updateSubGameVisible() --logD("ServerConfigs requestGameList4 :", table.tostring(self.subGameList)) if self.subGameList[3] then --欢乐拼五张 self.subGameList[3].show = false end end -- 保存到本地 self:saveSubGameListToFile(); self:dispatchEvent({name = "getSubGameListSuccessed"}) end -- 设置哪些子游戏是需要显示的 -- ttShow = {gameid, gameid, gameid} function ServerConfigs:updateSubGameVisible(ttShow) if ttShow then -- 全部标记为不显示 for k,v in pairs(self.subGameList) do v.show = false; end for _,v in pairs(ttShow) do if self.subGameList[v] then self.subGameList[v].show = true end end else -- 全部标记为显示 for k,v in pairs(self.subGameList) do v.show = true; end end end -- 获取指定子游戏的配置信息 -- 可能返回 nil function ServerConfigs:getSubGameConfig(gameId) if not gameId then return nil end return self.subGameList[gameId] end -- 获取指定web子游戏的配置信息 -- 可能返回 nil function ServerConfigs:getWebGameConfig(gameId) for i,v in pairs(self.webGameList) do if v.gameId == gameId then return v end end return nil end function ServerConfigs:requestClientConfig(callback) logD("ServerConfigs:requestClientConfig()") local params = { action = "system.clicfg", app = getAppId(), uid = loadUserId(), } logD("ServerConfigs:requestClientConfig() ", table.tostring(params)); app.waitDialogManager:showWaitNetworkDialog("请稍等...") self:sendPhpMsg(params, function(status,response) app.waitDialogManager:closeWaitNetworkDialog() logD("ServerConfigs:requestClientConfig() ", table.tostring(response)); if tonumber(response.code)==200 then if response.result and table.nums(response.result)>0 then self.clientConfig = response.result table.saveToLocFile(self.clientConfig, "ClientConfig.lua") math.randomseed(tostring(os.time()):reverse():sub(1, 6)); local wx = response.result.wx or {}; if table.nums(wx) > 0 then local idx = math.random(table.nums(wx)) if wx[idx] then app.plugin:initWxShare(wx[idx].appid, wx[idx].secret); else app.plugin:initWxShare(wx.appid, wx.secret); end else if app.plugin and wx.appid and wx.secret then app.plugin:initWxShare(wx.appid, wx.secret); end end end end if callback then callback() end app:dispatchEvent({name = "onRequestClientConfig"}) end) end function ServerConfigs:requestWebGameUrl(gameId,callback) local function getOrientation (url) local orientation = 1; local index = string.find(url,"?") if index then local params=string.sub(url,index+1,string.len(url)) local tmp = string.split(params,"&"); local args = {}; for k, v in pairs(tmp) do local arr = string.split(v, "="); if arr[1] == "orientation" then orientation = arr[2] or 1; break; end end end return orientation; end local params = { action = "platform.geturl", app = getAppId(), uid = loadUserId(), tinyid = gameId, } -- logD("ProtocolSubGame:requestWebGameList() ", table.tostring(params)); self:sendPhpMsg(params,function (status,response) -- dump(response) if tonumber(response.code)==200 then local orientation = getOrientation(response.result); if callback then callback(response.result, tonumber(orientation)) end else if callback then callback() end end end) end function ServerConfigs:getGameGroupConfig(gameId, regionCode) regionCode = regionCode or 0 local subGameList = self.regionGameList[regionCode] or self.subGameList if subGameList[gameId] then local strGameConfig = subGameList[gameId].gameRule if strGameConfig and strGameConfig~="" then local gameConfig = json.decode(strGameConfig) if gameConfig and gameConfig.group and gameConfig.group.games then return gameConfig.group end end end return nil end function ServerConfigs:getWebGameGroupConfig(gameId) for i,v in pairs(self.webGameList) do if v.gameId == gameId then local strGameConfig = v.gamecfg if strGameConfig and strGameConfig~="" then local gameConfig = json.decode(strGameConfig) if gameConfig and gameConfig.group then return gameConfig.group end end end end return nil end --- -- 子游戏是否在合集里面 -- @return boolean -- function ServerConfigs:isWebGameInGroup (gameId) local isExist = false for i,v in pairs(self.webGameList) do local groupConfig = self:getWebGameGroupConfig(v.gameId) or {} local games = groupConfig.games or {} for _, id in ipairs(games) do if tonumber(id) == tonumber(gameId) then isExist = true break end end if isExist then break end end return isExist end function ServerConfigs:isNewGame(gameId) if self.subGameList[gameId] then local strGameConfig = self.subGameList[gameId].gameRule if strGameConfig and strGameConfig~="" then local gameConfig = json.decode(strGameConfig) if gameConfig and gameConfig.isNew then return gameConfig.isNew end end end return false end --- -- 获取子游戏列表 -- @return -- function ServerConfigs:getSubGameList() return self.subGameList end --- -- 获取子游戏列表(没有子游戏具体信息) -- @return -- function ServerConfigs:getGameList(regionCode) regionCode = regionCode or 0 local gameList = {} local baseIds={ [1001]=true, [1002]=true, [1003]=true } if isIOSReviewVersion() then -- 添加更多游戏的显示 local gameInfo = { gameId = 0; gameName = "更多游戏"; sortIndex = 9999; show = true; visible = true; } self.subGameList[gameInfo.gameId] = gameInfo end local subGameList = self.regionGameList[regionCode] or self.subGameList local tt = {} for k,v in pairs(subGameList) do if v.visible and v.showInHall == 1 then if v.other_name and v.other_name ~= "" then if not tt[v.other_name] then tt[v.other_name] = {} end table.insert(tt[v.other_name],{gameId = v.gameId, sort = v.sortIndex ,gameType = "sub"}) elseif v.gameId and not baseIds[v.gameId] then table.insert(gameList,{gameId = v.gameId, sort = v.sortIndex ,gameType = "sub"}) end end end for k,v in pairs(tt) do --求最小排序 table.sort(v, function (a,b) return a.sort0 then local config = self.popConfigs[1] table.remove(self.popConfigs,1) return config end return nil end function ServerConfigs:initPopConfig() if self.popConfigs then return end --弹出配置 if cc.Application:getInstance():getTargetPlatform() == 0 then -- self.popConfigs = {"luaScript.Views.Main.HongBaoKa.HongBaoKaView", "luaScript.Views.Activity.ActivityMainView"} self.popConfigs = {} else local popWindows = PhpSetting["pop_window"] or {} table.sort(popWindows, function (a, b) return a.index < b.index end) local configs = {} for _, v in ipairs(popWindows or {}) do if v then table.insert(configs, v.view) end end self.popConfigs = configs; end end function ServerConfigs:ctor(net) ServerConfigs.super.ctor(self , net, ModuleId); -- php 通道相关 self.phpIndex = 0 self.phpCallbackList = {}; self.isGetGameVerList = false -- 大厅的配置信息 self.notice = {}; --{"",""} self.scroll = ""; -- self.areano = ""; -- -- 从gameServer获取的游戏列表 self.configs = {} --活动配置 self.missions = {} -- 从php获取的游戏列表 --[[ self.subGameList = { [gameid] = { show = true; gameId = 5; gameName = "六胡抢"; gameIcon = "http://img.dingdingqipai.com/images/games/lhq.png?v=1515639314"; sortIndex = 4; version = "1000"; versionUrls = {url, url} }, } --]] self.subGameList = {} self.webGameList = table.loadFromLocFile("WebGameList.lua") or {} self.clientConfig = table.loadFromLocFile("ClientConfig.lua") or { myHead = "http://cnplayer.ddpenghu.com/client/user/loginpost?wechatid=8&wechatmpid=8", -- 我的装扮 webgamb = RomSetting.ZhanJiUrl, -- 网页战绩 } -- 是否已经初始化完成 self._isInited = false -- 默认读取本地信息 self:loadSubGameListFromFile() self:updateSubGameVisible() -- 请求配置信息 self:defPushMsg{cmd = ConfigCmd.GAME_COMMAND_SEND_SERVER_CONF, reader = ServerConfigResponse, func = handler(self , self.onServerConfigResponse)}; self:defPushMsg{cmd = ConfigCmd.GAME_COMMAND_SEND_GAME_CONF, reader = ServerConfigsResponse, func = handler(self , self.onServerConfigsResponse)}; -- PHP 通道 self:defPushMsg{cmd = ConfigCmd.GAME_COMMAND_PHP, reader = StringPacket, func = handler(self , self.onPhpMsgResponse)}; end -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------- function ServerConfigs:requestGameList(regionCode, isFirstRequest, callback) -- 保存所有地区的游戏列表数据 self.regionGameList = self.regionGameList or {} regionCode = regionCode or 0 if self.regionGameList[regionCode] then -- 如果已经请求过该地区的数据,则不再请求游戏列表 self:dispatchEvent({name = "getSubGameListSuccessed"}) app.waitDialogManager:closeWaitNetworkDialog() return end local params = { action = "system.uniongameinfo", app = getAppId(), uid = loadUserId(), region = regionCode, } logD("ServerConfigs requestGameList :", table.tostring(params)) self:sendPhpMsg(params, function(status, response) logD("ServerConfigs requestGameList :", table.tostring(response)) app.waitDialogManager:closeWaitNetworkDialog() if tonumber(response.code) == 200 then -- self.subGameList = {} local subGameList = {} if response.result.game then for k,v in pairs(response.result.game) do local gameId = tonumber(k) local gamecfg = v.gamecfg local gamecfgData = json.decode(gamecfg) local gameInfo = {} -- gameId = gameId == 43 and 22 or gameId gameInfo.gameId = gameId gameInfo.gameName = tostring(v.name) gameInfo.gameIcon = tostring(v.icon) gameInfo.gameRule = tostring(v.gamecfg) gameInfo.sortIndex = tonumber(v.sort) gameInfo.other_name = tostring(v.other_name) gameInfo.show = true --游戏列表的显示逻辑用visible,创建房间的逻辑用show if gamecfgData then if gamecfgData.group and gamecfgData.group.show == "0" then gameInfo.visible = false else gameInfo.visible = true end if not gamecfgData.showInHall then gameInfo.showInHall = 1 else gameInfo.showInHall = tonumber(gamecfgData.showInHall) end else gameInfo.visible = true gameInfo.showInHall = 1 end -- self.subGameList[gameId] = gameInfo subGameList[gameId] = gameInfo end end -- 记录已经拉取过的地区游戏列表 self.regionGameList[regionCode] = subGameList if isFirstRequest then -- self.subGameList为所有的游戏列表,检测游戏是否存在、热更等使用这个self.subGameList -- 大厅主界面显示游戏列表,使用self.regionGameList[regionCode] self.subGameList = self.regionGameList[regionCode] end self.webGameList = {} if response.result.tiny then for gameId,v in pairs(response.result.tiny) do v.gameId = tonumber(gameId) local gamecfgData = json.decode(v.gamecfg) if gamecfgData then local uids = gamecfgData.uids local uid = app.user.loginInfo.uid if uids then for _, vv in pairs(uids) do if tonumber(vv) == uid then table.insert(self.webGameList, v) break end end else table.insert(self.webGameList, v) end else table.insert(self.webGameList, v) end end table.saveToLocFile(self.webGameList, "WebGameList.lua") end if isFirstRequest then -- 只有第一次拉取所有全国游戏列表的时候,才会拉取版本信息 self:requestGetSubGameVersions(callback) else self:dispatchEvent({name = "getSubGameListSuccessed"}) end end end) end return ServerConfigs