require("luaScript.Protocol.ProtocolCommon") local User = class("User" , require("luaScript.Protocol.Protocol")) -- 命令集合 local UserCmd = { --[[/** * 请求登录 *
	 * 请求: {@code LoginRequest}
	 * 返回:{@code LoginResponse}
	 * 
*/--]] LoginRequest = 0x0001; --[[/** * 登录返回结果 *
	 * 推送: {@code LoginResponse}
	 * 
*/--]] LoginResponse = 0x0002; --[[/** * 手机号码登录错误信息 *
	 * 推送: {@code PhoneLoginErrResponse}
	 * 
*/--]] PhoneLoginErrResponse = 0x0003; --[[/** * 绑定手机,微信,二次授权 *
	 * 推送: {@code PhoneBindRequest}
	 * 
*/--]] PhoneBindRequest = 0x0020; --[[/** * 绑定手机,微信,二次授权结果 *
	 * 推送: {@code PhoneBindResponse}
	 * 
*/--]] PhoneBindResponse = 0x0021; --[[/** * 用一个账号同时登陆时,踢出最早登陆的设备 *
	 * 推送: {@code IntPacket}
	 * 
*/--]] GAME_COMMAND_CLIENT_KICT_MULTI_LOGIN = 0x0043; --[[/** * 聊天内容 *
	 * 推送: {@code ChatMessageResponse}
	 * 
*/--]] GAME_COMMAND_CHAT_MESSAGE = 0x8004, --[[/** * 修改手机号/忘记密码 *
	 * 推送: {@code changePlayerInfoRequest}
	 * 
*/--]] GAME_COMMAND_CHANGE_PLAYER_INFO = 0x0023; --[[/** * 修改手机号/忘记密码 *
	 * 推送: {@code changePlayerInfoResponse}
	 * 
*/--]] GAME_COMMAND_CHANGE_INFO_RESPONSE= 0x0024; } -- 登陆请求 LoginRequest = defClass("LoginRequest" -- 固定为0 , defVar("uid", VT_Int, 0) -- 微信登陆 openId , defVar("openId", VT_String, "") -- 微信登陆 unionId , defVar("unionId", VT_String, "") -- 微信登陆 weixinInfo , defVar("weixinInfo", VT_String, "") -- 用户登录方式 --0: 微信登录 --1: 手机密码登录。openId为对应的手机号,unionId为密码 --2: 手机验证码登录。openId为对应的手机号,unionId为验证码 , defVar("loginType", VT_Short, 0) -- 验证码 , defVar("checkcode", VT_String, "") ) -- 登陆回复 LoginResponse = defClass("LoginResponse" -- 用户id, 根据openid 以及unionid映射得到 , defVar("uid", VT_Int, 0) -- 桌子id , defVar("tid", VT_Int, 0) -- 服务id , defVar("serverId", VT_Int, 0) -- 服务等级 , defVar("serverLevel", VT_Short, 0) -- 游戏id, 若上述tid 与gameid取值都不为0时,表示用户在游戏中 , defVar("gameId", VT_Short, 0) -- string格式, 目前只有roomCard信息(历史消耗房卡数量,当前房卡数量) , defVar("userInfo", VT_String, "") -- string格式, json数据,token,PHP登录使用 , defVar("jsonData", VT_String, "") -- byte matchFlag; //是否在比赛中0: 不在 1:在 , defVar("matchFlag", VT_Byte, "") -- 历史房卡数 , localVar("historyCardNum", VT_Int, "") -- 当前房卡数 , localVar("curCardNum", VT_Int, "") -- 当前悠闲豆 , localVar("curBeanNum", VT_Int, 0) -- 当前礼券 , localVar("curLiquanNum", VT_Int, 0) ) -- 手机号码登录结果 PhoneLoginErrResponse = defClass("PhoneLoginErrResponse" -- 登录结果 -- 1、电话号码未绑定 -- 2、密码错误 -- 3、黑名单用户 -- 4、验证码错误 , defVar("ret", VT_Short, 0) ) -- 绑定手机号码请求 PhoneBindRequest = defClass("PhoneBindRequest" -- 用户id , defVar("uid", VT_Int, 0) -- 绑定唯一标识 --, defVar("phonenum", VT_String, "") , defVar("account", VT_String, "") -- 密码 unionId , defVar("password", VT_String, "") -- 验证码 , defVar("checkcode", VT_Int, "") -- weixinInfo , defVar("weixinInfo", VT_String, "") -- 奖励类型:1. 房卡 2.金币 3. 活动房卡 4. RMB 5. 红包券 , defVar("rewardType", VT_Short, 0) -- 绑定类型 -- 0:手机绑定,account:手机号,weixinInfo 必须有值,3微信绑定 , defVar("bindType", VT_Short, 5) ) -- 绑定手机号码结果 PhoneBindResponse = defClass("PhoneBindResponse" -- 0: 绑定成功 -- 1: 验证码错误 -- 2: 已绑定过手机号 -- 6:手机绑定此微信 , defVar("ret", VT_Short, 0) -- 用户信息,绑定成功后会包含信息 , defVar("userInfo", VT_String, "") -- 奖励金币,只有在ret = 0 时有效,取值0表示没有奖励 , defVar("rewardCoin", VT_Int, 0) ) --改变玩家信息request changePlayerInfoRequest = defClass("changePlayerInfoRequest" -- uid , defVar("uid", VT_Int, 0) -- 微信登陆 openId , defVar("openId", VT_String, "") -- 微信登陆 unionId , defVar("unionId", VT_String, "") -- 请求类型 , defVar("loginType", VT_Short, 0) -- checkcode , defVar("checkcode", VT_String, "") -- 微信登陆 weixinInfo , defVar("weixinInfo", VT_String, "") ) --改变玩家信息结果 changePlayerInfoResponse = defClass("changePlayerInfoResponse" -- 返回类型 , defVar("ret", VT_Short, 0) --请求类型 , defVar("requestType", VT_Short, 0) --用户信息 , defVar("userInfo", VT_String, "") ) ------------------------- 玩家相关 ------------------------- -- 重新组织 userInfo 里面的内容 function User:updateUserInfo() local tt = { openid = self.openid, unionid = self.unionid, nickname = self.nickname, sex = self.sex, headimgurl = self.headimgurl, areano = self.areano, gpsInfo = self.gpsInfo, access_token = self.access_token, refresh_token = self.refresh_token, phonenum = self.phonenum, password = self.password, deviceInfo = self.strUserDeviceInfo, --如果是注册手机登录,登录后是5需改为手机登录,这样下次使用缓存登录发给服务器是手机登录,而如果是微信登录就还用原来的登录类型缓存 loginType = self.loginType == LoginType.LOGIN_TYPE_PHONE_REGISTER and LoginType.LOGIN_TYPE_PHONE or self.loginType, --新增MD5登录 isMd5PassWord = self.isMd5PassWord } self.userInfo = json.encode(tt); logD("User:updateUserInfo()", tostring(self.userInfo)) end -- 更新GPS信息 function User:updateGpsInfo(ttGpsInfo) ttGpsInfo = ttGpsInfo or {gpsStatus = 0, x = 0, y = 0 , addr = ""} logD("User:updateGpsInfo() ttGpsInfo = ", table.tostring(ttGpsInfo)) self.gpsInfo = ttGpsInfo self:updateUserInfo() end function User:isGpsInfoNewest(gpsInfo) logD("User:isGpsInfoSameWithLoc() gpsInfo = ", table.tostring(gpsInfo)) logD("User:isGpsInfoSameWithLoc() self.gpsInfo = ", table.tostring(self.gpsInfo)) logD("User:isGpsInfoSameWithLoc() gpsInfo.x = ", string.format("%.6f", gpsInfo.x)) logD("User:isGpsInfoSameWithLoc() self.gpsInfo.x = ", string.format("%.6f", self.gpsInfo.x)) logD("User:isGpsInfoSameWithLoc() gpsInfo.y = ", string.format("%.6f", gpsInfo.y)) logD("User:isGpsInfoSameWithLoc() self.gpsInfo.y = ", string.format("%.6f", self.gpsInfo.y)) if gpsInfo and gpsInfo.gpsStatus and gpsInfo.x and gpsInfo.y and gpsInfo.gpsStatus == self.gpsInfo.gpsStatus and string.format("%.6f", gpsInfo.x) == string.format("%.6f", self.gpsInfo.x) and string.format("%.6f", gpsInfo.y) == string.format("%.6f", self.gpsInfo.y) then return true end return false end --凡是登录前,修改的用户数据都不要本地缓存。 function User:userLoginEx() logD("User:userLoginEx()") if not self.openid or self.openid == "" then logD("User:userLoginEx() return by openid is nil or empty") return end -- local curTime = os.time() -- if curTime - self.lastLoginTime <= 5 then -- 5秒内不能重复登录 -- showTooltip("5秒内不能重复登录") -- return -- end -- self.lastLoginTime = curTime; -- 兼容旧代码,将配置信息往这里拷贝一份 self.notice = app.serverConfigs.notice; self.scroll = app.serverConfigs.scroll; self.gameId = app.serverConfigs.gameId; self.areano = app.serverConfigs.areano; self.phpInterface = app.serverConfigs.phpInterface; self:updateUserInfo(); -- 请求登录 local request = LoginRequest:new(); request.uid = 0; request.openId = self.openid; request.unionId = self.unionid; request.weixinInfo = self.userInfo request.loginType = self.loginType request.checkcode = self.checkcode or "" --如果是验证码登录/密码登录,检查内存是否有密码,有密码则当从后台断网回来前台的时候或者启动游戏自动登录两个情况,自动转化为密码登录。 if (self.loginType == LoginType.LOGIN_TYPE_PHONE_CHECKCODE or self.loginType == LoginType.LOGIN_TYPE_PHONE) and self.password and self.password ~= "" and string.len(self.password) > 5 then logD("yhj User:userLoginEx() AppBase didEnterForground") self.loginType = LoginType.LOGIN_TYPE_PHONE self.isMd5PassWord = "1" self:updateUserInfo() local tt = json.decode(self.userInfo) --如果是验证码登录unionid是?,就走不通了。所以先取用户信息里面的手机数据先 request.openId = tt.phonenum or self.openid; request.unionId = tt.password or self.unionId; request.loginType = self.loginType request.weixinInfo = self.userInfo elseif self.loginType == LoginType.LOGIN_TYPE_ID and self.password and self.password ~= "" and string.len(self.password) > 5 then logD("yhj User:userLoginEx() AppBase didEnterForground") self.isMd5PassWord = "1" self:updateUserInfo() local tt = json.decode(self.userInfo) --断线重连self.loginInfo.uid肯定是有值,如果是杀掉进程重进,就没有值,这个时候取userinfo里面的值 request.openId = self.loginInfo.uid ~= 0 and self.loginInfo.uid or tt.openid; request.unionId = tt.password or self.unionId; request.loginType = self.loginType request.weixinInfo = self.userInfo end app.waitDialogManager:showWaitNetworkDialog("登录中...") logD("yhj:User:userLoginEx() request = ", table.tostring(request)) self:sendResponse{cmd = UserCmd.LoginRequest , sender = request}; end -- 登陆结果 --凡是登录成功后,修改的用户数据都要本地缓存。特别是手机,密码,ID等会影响到登录的 function User:onLoginResponse(status, response) -- local curTime = os.time() -- self.lastLoginTime = curTime; logD("User:onLoginResponse()", tostring(status), table.tostring(response)) local curTime = os.time() if curTime - self.lastLoginTime <= 5 then -- 5秒内不能重复登录 logD("5秒内收到两次登录消息") showTooltip("5秒内不能重复登录") return end self.lastLoginTime = curTime; local jsonString = response.jsonData local jsonData = json.decode(jsonString) if jsonData then self.openid = jsonData.openid self.unionid = jsonData.unionid self.sex = jsonData.sex or self.sex self.nickname = jsonData.nickname or self.nickname self.nickname = string.getShortName(self.nickname, 99) self.headimgurl = jsonData.headimgurl or self.headimgurl self.phonenum = jsonData.phonenum self.password = jsonData.password or "" self.authorize = jsonData.authorize --是否需要二次授权,0则需要 end if self.nickname == "" then logD(" nickname == null ") self.nickname = "未知昵称" self.sex = 1 self.headimgurl = "" end self:updateUserInfo(); -- 关闭延迟的等待 app.waitDialogManager:closeAllNetWait() -- 保存玩家的登录信息 logD("User:onLoginResponse self.loginInfo()1", self.loginInfo) self.loginInfo = response:updateTo(self.loginInfo) -- 启动语音插件 -- app.plugin:startVoice(); --传送经纬度信息给EapSDK ljx if G_EapSdkMgr and not isWin32Platform() then if self.gpsInfo.gpsStatus == GpsStatus.enable then if (self.gpsInfo.y <= 180 and self.gpsInfo.y >= -180) and (self.gpsInfo.x <= 90 and self.gpsInfo.x >= -90) then G_EapSdkMgr:SetLocationInfo(self.gpsInfo.x, self.gpsInfo.y) end end end -- 启动腾讯语音 app.plugin:startGVoice(); self:startHandle() local ttExtInfo = string.split(self.loginInfo.userInfo, ",") self.loginInfo.historyCardNum = ttExtInfo[1]; self.loginInfo.curCardNum = ttExtInfo[2]; self.loginInfo.curJingbiNum = ttExtInfo[3] or 0 --金币场等级 self.serverLevel = response.serverLevel -- 写入玩家ID到本地 -- 下次启动游戏时会检测玩家ID是否特殊ID logD("User:onLoginResponse self.loginInfo()2", self.loginInfo) saveUserId(self.loginInfo.uid); local jsonData = response.jsonData local tt = json.decode(jsonData) or {} self.loginInfo.token = tt.token or "unkown" if self.loginType == LoginType.LOGIN_TYPE_WEIXIN or self.loginType == LoginType.LOGIN_TYPE_PHONE or self.loginType == LoginType.LOGIN_TYPE_PHONE_REGISTER or self.loginType == LoginType.LOGIN_TYPE_PHONE_CHECKCODE or self.loginType == LoginType.LOGIN_TYPE_ID then -- app.php:login() -- -- 发送登录成功的事件 -- self:dispatchEvent({name = "onLoginSuccessed"}) -- self:dispatchEvent({name = "onLoginSuccessedMessage"}) self:sendPhpIpBox() self:sendPhpIdentityCheck() end end local scheduler = cc.Director:getInstance():getScheduler() local _handle = nil; local beat_time = 1; function User:startHandle() self:closeHandle(); _handle = scheduler:scheduleScriptFunc(function () app.plugin:Update() end, beat_time, false) end function User:closeHandle() if _handle then scheduler:unscheduleScriptEntry(_handle) _handle = nil end end -- 请求IP盒子接口 function User:sendPhpIpBox() local isResponse = false local function onHttpResponse(status, response) app.waitDialogManager:closeAllNetWait() if status == "successed" then isResponse = true; local data = json.decode(response) if data and data.code == 0 then app.php:login() -- 发送登录成功的事件 self:dispatchEvent({name = "onLoginSuccessed"}) self:dispatchEvent({name = "onLoginSuccessedMessage"}) else showTooltip(data.error or "验证失败") end end end local taskId; local function onDelayPostCallBack(id) taskId = id; runDelayWithTime(function() if not isResponse then --没有数据回来 默认超时 logD("超时未收到IP盒子回应, 直接登陆") -- 取消之前的连接 if taskId then cc.CURLManager:getInstance():cancelTask(taskId) end app.php:login() -- 发送登录成功的事件 self:dispatchEvent({name = "onLoginSuccessed"}) self:dispatchEvent({name = "onLoginSuccessedMessage"}) end end, 5) end local params = { app_id = getAppId(), action = "ipbox.ipPass", uid = self.loginInfo.uid, } local phpUrl = getGlobalPhpUrl() httpPost(phpUrl, params, onHttpResponse, onDelayPostCallBack) end -- 请求实名认证接口 function User:sendPhpIdentityCheck() local function onHttpResponse(status, response) app.waitDialogManager:closeAllNetWait() if status == "successed" then local data = json.decode(response) if data and data.code == 200 then self.isRealname = data.result.isRealname self.isAdult = data.result.isAdult; --已实名且已成年发送电竞SDK接口 ljx if G_EapSdkMgr and not isWin32Platform() then if self.isAdult == 1 and self.isRealname == 1 then G_EapSdkMgr:VerifyRealInfo(data.result.name, data.result.card) end end else showTooltip(data.error or "验证失败") end end end local params = { app_id = getAppId(), action = "identity.check", uid = self.loginInfo.uid, } local phpUrl = getGlobalPhpUrl() httpPost(phpUrl, params, onHttpResponse) end -- 请求申请注销账号 function User:sendSubmitLogOut(callBack) local function onHttpResponse(status, response) app.waitDialogManager:closeAllNetWait() if status == "successed" then --申请成功 注销状态改为1 注销时间更新 local data = json.decode(response) if data.code == 200 then self.logOut.status = 1 self.logOut.logOutTime = data.result.endtime callBack() else showTooltip(data.error) end end end local params = { app_id = getAppId(), action = "group.ApCancelAccount", uid = self.loginInfo.uid, } local phpUrl = getGlobalPhpUrl() httpPost(phpUrl, params, onHttpResponse) end -- 请求取消撤销账号 function User:sendRevokeLogOut(callBack) local function onHttpResponse(status, response) app.waitDialogManager:closeAllNetWait() if status == "successed" then local data = json.decode(response) if data.code == 200 then --撤销成功 注销状态改为0 注销时间更新 self.logOut.status = 0 self.logOut.logOutTime = "0" callBack() end end end local params = { app_id = getAppId(), action = "group.CeCancelAccount", uid = self.loginInfo.uid, } local phpUrl = getGlobalPhpUrl() httpPost(phpUrl, params, onHttpResponse) end -- 使用手机号码登录失败 function User:onPhoneLoginErrResponse(status, response) -- 关闭延迟的等待 app.waitDialogManager:closeAllNetWait() -- 重置本地账号数据 self.openid = ""; self.unionid = ""; saveUserInfo("local_password",""); self.loginType = 0 self.checkcode = "" self.headimgurl = "" self.nickname = "" app.userManager:setLoginRecordCode(0) local errCode = response.ret self:dispatchEvent({name = "onPhoneLoginErrResponse", errCode = errCode}); end function User:reqestBindApp(bindType, openId) if not self.loginInfo or not self.loginInfo.uid then return end local request = PhoneBindRequest:new() request.uid = tonumber(self.loginInfo.uid); request.account = tostring(openId) request.bindType = tonumber(bindType) request.weixinInfo = self.userInfo; logD("User:reqestBindApp() request = ", table.tostring(request)) self:sendResponse{cmd = UserCmd.PhoneBindRequest , sender = request}; end -- 绑定手机号 function User:reqestBindPhone(phonenum, checkcode) if not phonenum or not checkcode then return end local request = PhoneBindRequest:new() request.uid = self.loginInfo.uid request.account = phonenum request.password = "" request.checkcode = checkcode request.weixinInfo = app.user.userInfo request.rewardType = 5 -- 奖励类型:1. 房卡 2.金币 3. 活动房卡 4. RMB 5. 红包券 logD("User:reqestBindPhone() request = ", table.tostring(request)) self:sendResponse{cmd = UserCmd.PhoneBindRequest , sender = request}; end -- 绑定的结果 function User:onBindResponse(status, response) logD("User:onBindResponse() response = ", table.tostring(response)) --[[ [0] = "绑定成功", [1] = "验证码错误", [2] = "已绑定过手机号,无需再次绑定", [5] = "该手机号已经被其他游戏ID绑定,请更换手机号再次绑定", [6] = "绑定成功", [7] = "该微信号已绑定过其他游戏账号", [8] = "绑定成功", --]] if response.ret == BIND_TYPE_RESULT.PHONE then --手机绑定成功 local stUserInfo = json.decode(response.userInfo) if stUserInfo then self.phonenum = stUserInfo.phonenum self.password = stUserInfo.password else logE("User:onBindResponse() stUserInfo is nil") end self:updateUserInfo(); -- 更新本地保存的数据 local tt = {} tt.forceCover = true app.user:dispatchEvent({name = "updateWxUserInfo",response = tt}) elseif response.ret == BIND_TYPE_RESULT.WEIXIN_TWICE_BIND then --二次授权 logD("yhj User:onBindResponse() WEIXIN_TWICE_BIND SUCCESS") -- local stUserInfo = json.decode(response.userInfo) -- if stUserInfo then -- self:updateWeiXinInfo(stUserInfo) -- self:updateUserInfo(); -- -- 更新本地保存的数据 -- local tt = {} -- tt.forceCover = true -- app.user:dispatchEvent({name = "updateWxUserInfo",response = tt}) -- end app:dispatchEvent({name = "showConfirmDialogNotClose"}) elseif response.ret == BIND_TYPE_RESULT.WEIXIN then --普通微信绑定 logD("yhj User:onBindResponse() WEIXIN SUCCESS") local stUserInfo = json.decode(response.userInfo) if stUserInfo then self:updateWeiXinInfo(stUserInfo) self:updateUserInfo(); -- 更新本地保存的数据 local tt = {} tt.forceCover = true app.user:dispatchEvent({name = "updateWxUserInfo",response = tt}) end app:dispatchEvent({name = "showConfirmDialogNotClose"}) elseif response.ret == BIND_TYPE_RESULT.USER_SET_PASSWORD then --用户设置密码 logD("yhj User:onBindResponse() USER_SET_PASSWORD SUCCESS") local stUserInfo = json.decode(response.userInfo) if stUserInfo then self.password = stUserInfo.password else logE("User:onBindResponse() stUserInfo is nil") end self:updateUserInfo(); -- 更新本地保存的数据 local tt = {} tt.forceCover = true app.user:dispatchEvent({name = "updateWxUserInfo",response = tt}) else--失败情况暂时只有分发提示事件 logE("yhj User:onBindResponse() Bind Failed!") end self:dispatchEvent({name = "onBindResponse", response = response}); end --微信新增字段 function User:updateWeiXinInfo(weixinInfo) if weixinInfo then self.unionid = weixinInfo.unionid or self.unionid self.openid = weixinInfo.openid or self.openid self.nickname = weixinInfo.nickname or self.nickname self.headimgurl = weixinInfo.headimgurl or self.headimgurl self.sex = weixinInfo.sex or self.sex self.access_token = weixinInfo.access_token or self.access_token self.refresh_token = weixinInfo.refresh_token or self.refresh_token else logE("weixinInfo is nil") end end -- 改变信息的结果(修改手机号/忘记密码返回) function User:onChangePlayerInfoResponse(status, response) logD("yhj:User:onChangePlayerInfoResponse() response = ", table.tostring(response)) if response.ret == 0 then local stUserInfo = json.decode(response.userInfo) local requestType = response.requestType if stUserInfo then if requestType == ChangePlayerInfo.REPLCACE_PHONE then self.phonenum = stUserInfo.phonenum self:updateUserInfo() -- 更新本地保存的数据 local tt = {} tt.forceCover = true tt.userInfo = app.user.userInfo app.user:dispatchEvent({name = "updateWxUserInfo",response = tt}) elseif requestType == ChangePlayerInfo.PHONE_RESET then --忘记密码,数据没必要缓存。缓存反而会导致,用户用ID登录输入错误密码,也会用缓存的数据登录 --[[self.password = stUserInfo.password self:updateUserInfo() -- 更新本地保存的数据 local tt = {} tt.userInfo = response.userInfo tt.forceCover = true app.user:dispatchEvent({name = "updateWxUserInfo",response = tt})--]] end else logE("User:onBindResponse() stUserInfo is nil") end end self:dispatchEvent({name = "onChangePlayerInfo", response = response}); end --//////////////////////////////////////////////////////////////////////////// -- 聊天内容 ChatMessageRequest = defClass("ChatMessageRequest" -- //类型 1: 表情 2: 语音 3:聊天 , defVar("type", VT_Short, 0) -- //内容,客户端自定义格式 , defVar("content", VT_String, "") ) -- 聊天内容 ChatMessageResponse = defClass("ChatMessageResponse" -- 用户uid , defVar("nUserId", VT_Int, 0) -- //类型 1: 表情 2: 语音 3:聊天 , defVar("type", VT_Short, 0) -- //内容,客户端自定义格式 , defVar("content", VT_String, "") ) function User:onChatMessageResponse(status, response) logD("User:onChatMessageResponse(), ", table.tostring(response)) --[[ -- 只管发送消息,而不必关注是否有人处理 if not app.room or not app.room.roomInfo then print("self.roomInfo no exist,容错处理!") return end --]] self:dispatchEvent({name = "onChatMessageResponse", response = response}); end -- 是否可以发送聊天消息 function User:canSendChatMessage(chat_type) if not self.lastChatMessage then self.lastChatMessage = {} end if not self.lastChatMessage[chat_type] then self.lastChatMessage[chat_type] = 0 end local voicePermission = tonumber(loadUserInfo("voicePermission")) or 0 voicePermission = voicePermission + 1 logD("User:canSendChatMessage voicePermission out:"..voicePermission) if voicePermission <= 3 then logD("User:canSendChatMessage voicePermission:"..tostring(voicePermission)) saveUserInfo("voicePermission",voicePermission) return true end local ChatDef = require("luaScript.GameChatDefine") local timeNow = os.time() local timeLast = self.lastChatMessage[chat_type] or 10 local timeInterval = ChatDef.TimeInterval[chat_type] or 10 if timeNow - timeLast >= timeInterval then return true else return false end end function User:sendChatMessage(chat_type, content) if not self:canSendChatMessage(chat_type) then return false; end self.lastChatMessage[chat_type] = os.time() local request = ChatMessageRequest:new() request.type = tonumber(chat_type); request.content = tostring(content) log("User:sendChatMessage() request = ", table.tostring(request)); self:sendResponse{cmd = UserCmd.GAME_COMMAND_CHAT_MESSAGE , sender = request}; return true; end function User:getLastChatTime(chat_type) return self.lastChatMessage[chat_type] or os.time() end function User:onServerKickOutResponse(status, response) uploadLogs(GAME_ERROR_TYPE.DING_HAO_ERROR) self.kickOut = true self:dispatchEvent({name = "onServerKickOutResponse", response = response}) end function User:getGameConfig(gameId) return app.serverConfigs.configs[gameId] end function User:ctor(net) User.super.ctor(self , net, ModuleId); -- 玩家的个人信息 self.userInfo = ""; self.openid = "" self.unionid = "" self.nickname = "" self.sex = 1 self.headimgurl = "" self.areano = 0 self.gpsInfo = {gpsStatus = 0, x = 0, y = 0, addr = ""} self.access_token = "" self.refresh_token = "" self.loginType = 0 --是否使用md5密码登录 self.isMd5PassWord = "0" --是否正在绑定微信 self.bindWeiXinIng = false --是否被顶号 self.kickOut = false local sysVersion= getSystemVersion(); local sysName = getSystemName(); self.userDeviceInfo = { device = getDeviceID(), --设备唯一标识,如有则传,无则无需传输 machine_type = getLocalizedModel(), --设备型号, "iPhone84"\ "OPPOR11"\ "ASK-AL00x" os = string.format(sysName..sysVersion) --设备操作系统, "android7.1.2" or "iOS13.3" } self.strUserDeviceInfo = json.encode(self.userDeviceInfo) self.lastLoginTime = 0; -- todo lwq 超时使用,5秒内不能重复登录,限制服务器叫我们客户端登录 -- 登录返回的数据 self.loginInfo = LoginResponse:new() -- 监听获取配置的消息,成功获取配置后请求登录 app.serverConfigs:addEventListener("initSuccessed", handler(self, self.userLoginEx)) -- 请求登陆 self:defMsgFunc{name = "loginRequest" , cmd = UserCmd.LoginRequest, sender = LoginRequest}; --请求改变玩家信息(忘记密码,修改手机号) self:defMsgFunc{name = "playerInfoChange" , cmd = UserCmd.GAME_COMMAND_CHANGE_PLAYER_INFO, sender = changePlayerInfoRequest}; -- 推送登陆结果 self:defPushMsg{cmd = UserCmd.LoginResponse , reader = LoginResponse, func = handler(self , self.onLoginResponse)}; -- 使用手机号码登录失败 self:defPushMsg{cmd = UserCmd.PhoneLoginErrResponse , reader = PhoneLoginErrResponse, func = handler(self , self.onPhoneLoginErrResponse)}; -- 请求绑定手机号 self:defMsgFunc{name = "requestBindPhoneNum" , cmd = UserCmd.PhoneBindRequest, sender = PhoneBindRequest}; -- 绑定手机号码的结果 self:defPushMsg{cmd = UserCmd.PhoneBindResponse , reader = PhoneBindResponse, func = handler(self , self.onBindResponse)}; -- 聊天信息 GAME_COMMAND_CHAT_MESSAGE self:defPushMsg{cmd = UserCmd.GAME_COMMAND_CHAT_MESSAGE, reader = ChatMessageResponse, func = handler(self , self.onChatMessageResponse)}; -- 账号在其他地方登陆 self:defPushMsg{cmd = UserCmd.GAME_COMMAND_CLIENT_KICT_MULTI_LOGIN, reader = IntPacket, func = handler(self , self.onServerKickOutResponse)}; --改变玩家信息的结果 self:defPushMsg{cmd = UserCmd.GAME_COMMAND_CHANGE_INFO_RESPONSE, reader = changePlayerInfoResponse, func = handler(self , self.onChangePlayerInfoResponse)}; end return User;