local Login_Implement = {} local HttpReq = require('Http/HttpReq') local JSON = require('cjson') local EventSystem = require('Event/EventSystem') local BAN_CODE = 100005 --角色封禁 local BAN_CODE2 = 100001 --用户名密码封禁 local this = Login_Implement local private = { _myAuthInfo = {}, _tempAuthInfo = nil, _whiteListBase64Input = nil } local TAI_HTTP_HEADER_KEY = "TYX-Request-Id" local TAI_HTTP_HEADER_VALUE = "f88a78a83463f1e03bbf0acb3883aefb" local CONST_CODE = { ERRORCODE_HTTP_NOTHASHTABLE = 10000, ERRORCODE_HTTP_UNEXPECTED = 10001, ERRORCODE_HTTP_ABORTED = 10002, ERRORCODE_HTTP_CONNECTIONTIMEOUT = 10003, ERRORCODE_HTTP_TIMEDOUT = 10004, ERRORCODE_HTTP_BADCONTENT = 10005, } function Login_Implement.AuthInfoRequest(username, password) local authInfo = { _userName = username, _pwd = password, } private.Auth(authInfo) end function Login_Implement.SDKAuthInfoRequest(authType, username) local authInfo = { _authType = authType, _userName = username, } private.Auth(authInfo) end function Login_Implement.ClientReAuthRequest() logging.crit(LTAG.CRIT, "Auth登录失败,重新登录") private.Auth(private._tempAuthInfo) end function Login_Implement.RegisterRequest(tempUsername, tempPassword) local authInfo = { _userName = tempUsername, _pwd = tempPassword, _deviceId = SystemInfo.deviceUniqueIdentifier .. "@" .. AuxUtil.GetNowTimeFormat("MMddHHmmssffff") .. "@apple.com"; } private.Register(authInfo) end function Login_Implement.RequestServerList() private.ReqServerList(false) end function Login_Implement.ClickStartGame(shardId, shardName, shardState) BIManager.DispatchBIClientEvent(BIManager.EventName.ReqServerAddress, "serverId", shardId, "serverName", shardName, "serverState", shardState) this.SetMyAuthInfo("_shardId", shardId) this.SetMyAuthInfo("_shardName", shardName) SDKUtil.SetServerInfo(shardId, shardName) PersistentData.DeviceData:Set("ServerName", "服务器:" .. (AuxUtil.GetAuthURLPrefixTips() or shardName), true) CTL.Login.OpenConnectingPanel(true) private.GetServerAddress() end function Login_Implement.SetEntryAddressAndAnnouncementBaseUrl() -- 此版本不需要是实现这个接口 end function Login_Implement.SetInputWhiteList(inputWhiteList) if not string.isNilOrEmpty(inputWhiteList) then if inputWhiteList == HttpReq.Base64PlanXToUTF8(MDL.Login.WhiteListPwd) then private._whiteListBase64Input = HttpReq.DefaultToBase64PlanX(inputWhiteList) return true end end return false end function Login_Implement.HasWhiteListBase64Input() return not string.isNilOrEmpty(private._whiteListBase64Input) end function Login_Implement.SetMyAuthInfo(k, v) private._myAuthInfo[k] = v end function Login_Implement.BuildConnectionReq(msg) msg.DeviceId = SDKUtil.DeviceID msg.AccountName = private._myAuthInfo._userName msg.ChannelId = SDKUtil.ChannelID msg.PlatformId = SDKUtil.PlatformType msg.IP = AuxUtil.GetIP(0) msg.UID = tostring(SDKUtil.CurrentUserInfo.Uid) msg.AppChannelId = SDKUtil.ProjectID --目前线上不需要新的新手关,先屏蔽功能,如果要启用,只需恢复以下逻辑和PackageType即可。需要确保配套的资源都分包配置都正确 --local useNewGuideLevel = CTL.Login.GetLocalABTestMode() == 1 and 1 or 0 --新加新手关的ab包测试 --local forceEnter = MDL.Cheat.Get_ForceNewGuideLevel() --if forceEnter then -- useNewGuideLevel = forceEnter --end --msg.PackageType = useNewGuideLevel msg.PackageType = 0 end --region *************** Auth step1 *************** get auth token by device id or username function private.Auth(info) CTL.Login.OpenConnectingPanel(true) logging.log(LTAG.LOG, "[TionAuth] Step1 - Auth Start") BIManager.SendWithEncode("ReqAuth") local url private._tempAuthInfo = info if string.isNilOrEmpty(info._authType) then if string.isNilOrEmpty(info._userName) then local deviceId = info._deviceId local encodeDeviceId = HttpReq.DefaultToBase64PlanX(deviceId) url = string.format("%s/auth/v1/device/%s?crc=%s", AuxUtil.GetAuthURLPrefix(), deviceId, encodeDeviceId) logging.log(LTAG.LOG, "[TionAuth] Step1 -Auth Quickplay [URL]: ", url) else local usernameURL = HttpReq.DefaultToBase64URL(info._userName) local passwordURL = HttpReq.DefaultMD5HashToBase64PlanX(info._pwd) url = string.format("%s/auth/v1/user/login?name=%s&passwd=%s", AuxUtil.GetAuthURLPrefix(), usernameURL, passwordURL) logging.log(LTAG.LOG, "[TionAuth] Step1 - Auth usrname/pwd [URL]: ", url) end local handle = HttpReq.Create(url, HttpReq.HTTPMethods.Get, private.OnAuthCallback) HttpReq.AddHeader(handle, TAI_HTTP_HEADER_KEY, TAI_HTTP_HEADER_VALUE) HttpReq.Send(handle) else if info._authType == "quick" then if not SDKUtil.IsHasUserInfo() then return end url = string.format("%s/auth/v2/sdk/login", AuxUtil.GetAuthURLPrefix()) logging.log(LTAG.LOG, "[TionAuth] Step1 - Sdk auth [URL]: ", url) local sdkChannelUID = SDKUtil.SdkChannelUID if UNITY_IOS and GameAppInfo.IsChinesePackage() then sdkChannelUID = SDKUtil.HeroUserId end local handle = HttpReq.Create(url, HttpReq.HTTPMethods.Post, private.OnAuthCallback) HttpReq.AddHeader(handle, TAI_HTTP_HEADER_KEY, TAI_HTTP_HEADER_VALUE) HttpReq.SetField(handle,"uid", SDKUtil.CurrentUserInfo.Uid) HttpReq.SetField(handle,"token", SDKUtil.CurrentUserInfo.Token) HttpReq.SetField(handle,"channelId", SDKUtil.ChannelID) HttpReq.SetField(handle,"sdkChannelUID", sdkChannelUID or "") HttpReq.SetField(handle,"app_channelId", SDKUtil.ProjectID) HttpReq.SetField(handle,"device_Id", SDKUtil.SytemUniqueID) HttpReq.SetField(handle,"ip", AuxUtil.GetIP(0)) HttpReq.SetField(handle,"typ", SDKUtil.PlatformTypeForAuth) HttpReq.SetField(handle,"device", SystemInfo.deviceModel) HttpReq.SetField(handle,"address_flag", SDKUtil.AdsJson) HttpReq.SetField(handle,"bdc_common_info", SDKUtil.BDCServerBean) HttpReq.SetField(handle,"sdk_deviceid", SDKUtil.BDCDeviceId or "") HttpReq.SetField(handle,"environment", AppInfo.isOfficial and "RELEASE" or "DEBUG") HttpReq.Send(handle) end end end function private.OnAuthCallback(handle, success, state, absoluteUri, message, respCode, respJson) CTL.Login.OpenConnectingPanel(false) private.HandleAuthStepCallback(success, state, absoluteUri, message, respCode, respJson, private.OnAuthSuccess, private.OnAuthFail, private.OnAuthFailByBan) end function private.OnAuthSuccess(respJson) local t = JSON.decode(respJson) local authToken = tostring(t["authtoken"]) logging.log(LTAG.LOG, "[TionAuth] Step1 - OK, [AuthToken]: ", authToken) BIManager.SendWithEncode("RespAuthSuccess") MDL.Login.InitShardInfo(respJson) CTL.Login.OpenConnectingPanel(false) if private._tempAuthInfo then for k, v in pairs(private._tempAuthInfo) do this.SetMyAuthInfo(k, v) end end this.SetMyAuthInfo("_authToken", authToken) private.ReqServerList(true) end function private.OnAuthFailByBan(errorCode, respJson, message, url) logging.crit(LTAG.CRIT, "[TionAuth] Step:OnAuthFailByBan, Code:", errorCode, "URL:", url) BIManager.SendWithEncode("RespAuthFail", "functionName", "OnAuthFailByBan", "errorCode", tostring(errorCode), "failedURL", url) local t = JSON.decode(respJson) local reason = t["banreason"] and tostring(t["banreason"]) or "" local banTime = t["BanTime"] and tonumber(t["BanTime"]) or 0 private.HandleAuthError(errorCode, reason, banTime) end function private.OnAuthFail(errorCode, respJson, message, url) logging.crit(LTAG.CRIT, "[TionAuth] Step:OnAuthFail, Code:", errorCode, "URL:", url) BIManager.SendWithEncode("RespAuthFail", "functionName", "OnAuthFailByBan", "errorCode", tostring(errorCode), "failedURL", url) CTL.Login.OnAuthFail(errorCode) end --endregion Auth step1 --region *************** Auth step2 *************** get shard list function private.ReqServerList(withFailCallback) CTL.Login.OpenConnectingPanel(true) local url if string.isNilOrEmpty(private._whiteListBase64Input) then url = string.format(MDL.Login.NormalShardListUrl, AuxUtil.GetAuthURLPrefix(), GameAppInfo.Global_ProductId, SDKUtil.SytemUniqueID, Localization.GetLanguage2Server(), AppInfo.marketVersion, private._myAuthInfo._authToken, SDKUtil.ChannelID) else url = string.format(MDL.Login.WhiteListShardListUrl, AuxUtil.GetAuthURLPrefix(), GameAppInfo.Global_ProductId, SDKUtil.SytemUniqueID, private._whiteListBase64Input, Localization.GetLanguage2Server(), AppInfo.marketVersion, private._myAuthInfo._authToken, SDKUtil.ChannelID) end logging.log(LTAG.LOG, "[TionAuth] Step2 - Start, get shard list. [URL]: ", url) local callback = withFailCallback and private.OnReqServerListCallback or private.OnReqServerListCallback_WithoutFail local handle = HttpReq.Create(url, HttpReq.HTTPMethods.Get, callback) HttpReq.AddHeader(handle, TAI_HTTP_HEADER_KEY, TAI_HTTP_HEADER_VALUE) HttpReq.Send(handle) end function private.OnReqServerListCallback(handle, success, state, absoluteUri, message, respCode, respJson) CTL.Login.OpenConnectingPanel(false) private.HandleAuthStepCallback(success, state, absoluteUri, message, respCode, respJson, private.OnReqServerListSuccess, private.OnReqServerListFail) end function private.OnReqServerListCallback_WithoutFail(handle, success, state, absoluteUri, message, respCode, respJson) CTL.Login.OpenConnectingPanel(false) private.HandleAuthStepCallback(success, state, absoluteUri, message, respCode, respJson, private.OnReqServerListSuccess) end function private.OnReqServerListSuccess(respJson) BIManager.SendWithEncode(BIManager.EventName.RespGetServerlistSuccess) MDL.Login.InitServerListInfo(respJson) end function private.OnReqServerListFail(errorCode, respJson, message, url) BIManager.SendWithEncode(BIManager.EventName.RespGetServerlistFail, "errorCode", errorCode, "failedURL", url) private.HandleAuthError(errorCode) end --endregion Auth step2 --region *************** Auth step3 *************** get shard list function private.GetServerAddress() local requireHost = CTL.Login.GetHttpRequireHost() logging.log(LTAG.LOG, "[TionAuth] Step3 - Start, enter shard with AT:",private._myAuthInfo," Shard:", private._myAuthInfo._shardId, "requireHost: ", requireHost) local url if string.isNilOrEmpty(private._whiteListBase64Input) then url = string.format("%s/login/v1/getgate?at=%s&sn=%s&ver=%s&deviceId=%s&requireHost=%s", AuxUtil.GetAuthURLPrefix(), private._myAuthInfo._authToken, private._myAuthInfo._shardId, AppInfo.marketVersion, SDKUtil.SytemUniqueID, requireHost) else url = string.format("%s/login/v1/getgate?at=%s&sn=%s&ver=%s&deviceId=%s&requireHost=%s&sp=%s", AuxUtil.GetAuthURLPrefix(), private._myAuthInfo._authToken, private._myAuthInfo._shardId, AppInfo.marketVersion, SDKUtil.SytemUniqueID, requireHost, private._whiteListBase64Input) end local handle = HttpReq.Create(url, HttpReq.HTTPMethods.Get, private.OnGetServerAddressCallback) HttpReq.AddHeader(handle, TAI_HTTP_HEADER_KEY, TAI_HTTP_HEADER_VALUE) HttpReq.Send(handle) logging.crit(LTAG.CRIT, "GetServerAddress") end function private.OnGetServerAddressCallback(handle, success, state, absoluteUri, message, respCode, respJson) private.HandleAuthStepCallback(success, state, absoluteUri, message, respCode, respJson, private.OnGetServerAddressSuccess, private.OnGetServerAddressFail) end function private.OnGetServerAddressSuccess(respJson) logging.crit(LTAG.CRIT, "OnGetServerAddressSuccess") BIManager.SendWithEncode("RespServerAddressSuccess") BIManager.SendBDCServerEvent(true) local t = JSON.decode(respJson) if tostring(t["result"]) == "ok" then local ipWithPort = HttpReq.Base64PlanXToUTF8(tostring(t["ip"])) local split = string.split(ipWithPort,':') local ip = split[1] local port = tonumber(split[2]) local token = HttpReq.Base64PlanXToUTF8(tostring(t["logintoken"])) local realtime = Time.realtimeSinceStartup logging.log(LTAG.LOG, "[TionAuth] Step3 OK, ip:", ip, "login token:", token) AuxUtil.SetLoginDataAndConnect(ip, port, token, realtime) else --顶号情况下,第一次进入失败,等2秒再进 --服务器这边顶号第一次为保护措施,踢下另外一个账号 --retry local delay = tonumber(t["ms"]) / 1000 TimerUtil.Interval(private.GetServerAddress,delay,1) end end function private.OnGetServerAddressFail(errorCode, respJson, message, url) logging.crit(LTAG.CRIT, "[TionAuth] Step:OnGetServerAddressFail, Code:", errorCode, "URL:", url) BIManager.SendWithEncode("RespServerAddressFail", "errorCode", errorCode, "message", message) BIManager.SendBDCServerEvent(false) CTL.Login.OpenConnectingPanel(false) --断网情况下是没有respJson的 local t = string.isNilOrEmpty(respJson) and {} or JSON.decode(respJson) private.HandleAuthError(errorCode, t.banreason, t.bantime) if errorCode == 401 then --for 401 error, quit game and re-auth UTL.MessageBox.ShowOnlyOkNoCloseBox("", Const_IDS.IDS_ERROR_NETWORK_90001, LuaNetManager.RebootGame) end end --endregion Auth step3 --region *************** Register *************** function private.Register(info) CTL.Login.OpenConnectingPanel(true) logging.log(LTAG.LOG, "[TionAuth] Register Start") private._tempAuthInfo = info local usernameURL = HttpReq.DefaultToBase64URL(info._userName) local passwordURL = HttpReq.DefaultMD5HashToBase64PlanX(info._pwd) local param = string.format("name=%s&passwd=%s", usernameURL, passwordURL) local url = string.format("%s/auth/v1/user/reg/%s?%s", AuxUtil.GetAuthURLPrefix(), info._deviceId, param) logging.log(LTAG.LOG, "[TionAuth] Register with [URL]: ", url) local handle = HttpReq.Create(url, HttpReq.HTTPMethods.Get, private.OnRegisterCallback) HttpReq.AddHeader(handle, TAI_HTTP_HEADER_KEY, TAI_HTTP_HEADER_VALUE) HttpReq.Send(handle) end function private.OnRegisterCallback(handle, success, state, absoluteUri, message, respCode, respJson) CTL.Login.OpenConnectingPanel(false) private.HandleAuthStepCallback(success, state, absoluteUri, message, respCode, respJson, private.OnRegisterSuccess, private.OnRegisterFail) end function private.OnRegisterSuccess(respJson) EventSystem.Dispatch(EventID.UI_Login_RegisterComplete) end function private.OnRegisterFail(errorCode, respJson, message, url) private.HandleAuthError(errorCode) CTL.Tips.AddTipsMsg(Const_IDS.IDS_LoginSystem_Register_Tips1) end --endregion Register --region *************** GetCfg *************** function Login_Implement.StartGetGamePackageCfg(url, completeCallback, failCallback) local callback = private.GenerateGetCfgCallback(url, completeCallback, failCallback) local handle = HttpReq.Create(url, HttpReq.HTTPMethods.Get, callback) HttpReq.Send(handle) end function Login_Implement.StartGetEntryAddressCfg(url, completeCallback, failCallback) local callback = private.GenerateGetCfgCallback(url, completeCallback, failCallback) local handle = HttpReq.Create(url, HttpReq.HTTPMethods.Get, callback) HttpReq.Send(handle) end function Login_Implement.StartGetAnnouncemenCfg(url, completeCallback, failCallback) local callback = private.GenerateGetCfgCallback(url, completeCallback, failCallback) local handle = HttpReq.Create(url, HttpReq.HTTPMethods.Get, callback) HttpReq.AddHeader(handle, TAI_HTTP_HEADER_KEY, TAI_HTTP_HEADER_VALUE) HttpReq.Send(handle) end function private.GenerateGetCfgCallback(url, completeCallback, failCallback) local callback = function(handle, success, state, absoluteUri, message, respCode, respJson) if state == HttpReq.HTTPRequestState.Finished then if success then if completeCallback then completeCallback(respJson, url) end else logging.crit(LTAG.CRIT, "Request finished Successfully, but the server sent an error, code=", respCode, "\nMessage", message) if failCallback then failCallback(respCode, message, "", absoluteUri) end end else logging.crit(LTAG.CRIT, "Request Finished with Error, State=", state, "uri", absoluteUri, "\nMessage", message) local errorCode = private.GetUnfinishedCode(state) or respCode if failCallback then failCallback(errorCode, message, "", absoluteUri) end end end return callback end --endregion GetCfg function private.HandleAuthError(code, banReason, banTime) local msg local type if code == 206 then --206 这个码问了服务器目前没用了 if string.isNilOrEmpty(banReason) then if banTime then --TODO 需要配置IDS? string.format("账号处于封停状态\n需要%s后才能登录", AuxUtil.GetTimeLeftTextFromNow(banTime)) type = CTL.Login.InfoTypeEnum.Error else msg = UTL.String.GetErrorCodeMsg(code) type = CTL.Login.InfoTypeEnum.Warn end else msg = UIUtils.GetLocalizedTxt(Const_IDS[banReason]) type = CTL.Login.InfoTypeEnum.Error end elseif code == BAN_CODE then msg = string.FormatByIdsId(Const_IDS.IDS_GMServer_AccountBlocked, os.date(UTL.Time.FormatDateEnum.YMDHMS, banTime)) type = CTL.Login.InfoTypeEnum.Warn else msg = UTL.String.GetErrorCodeMsg(code) type = CTL.Login.InfoTypeEnum.Warn --用户名密码封禁,不再重试登录 if code == BAN_CODE2 then CTL.Login.OpenInfoPanel(type, true, msg) CTL.Loading.EndLoading() return end end CTL.Login.OpenInfoPanel(type, true, msg, CTL.Login.ClientReAuth) CTL.Loading.EndLoading() end function private.HandleAuthStepCallback(success, state, absoluteUri, message, respCode, respJson, successAction, failAction, banAction) if state == HttpReq.HTTPRequestState.Finished then if success or respCode == 400 or respCode == 500 then local t = JSON.decode(respJson) local result = t["result"] if result == "ok" then if successAction then successAction(respJson) end elseif result == "retry" then if successAction then successAction(respJson) end else local errorCode = tonumber(t["forclient"]) if errorCode == 206 and banAction then banAction(errorCode, respJson, message, absoluteUri) elseif failAction then failAction(errorCode, respJson, message, absoluteUri) end end else logging.crit(LTAG.CRIT, "Request finished Successfully, but the server sent an error, code=", respCode, "\nMessage", message) if failAction then failAction(respCode, respJson, message, absoluteUri) end end else logging.crit(LTAG.CRIT, "Request Finished with Error, State=", state, "uri", absoluteUri, "\nMessage", message) local errorCode = private.GetUnfinishedCode(state) or respCode if failAction then failAction(errorCode, respJson, message, absoluteUri) end end end function private.GetUnfinishedCode(state) local errorCode if state == HttpReq.HTTPRequestState.Error then errorCode = CONST_CODE.ERRORCODE_HTTP_UNEXPECTED elseif state == HttpReq.HTTPRequestState.Aborted then errorCode = CONST_CODE.ERRORCODE_HTTP_ABORTED elseif state == HttpReq.HTTPRequestState.ConnectionTimedOut then errorCode = CONST_CODE.ERRORCODE_HTTP_CONNECTIONTIMEOUT elseif state == HttpReq.HTTPRequestState.TimedOut then errorCode = CONST_CODE.ERRORCODE_HTTP_TIMEDOUT end return errorCode end --PC登录相关 function Login_Implement.StartNTLogin(url, loginDataStr, completeCallback, failCallback) local callback = private.GenerateGetCfgCallback(url, completeCallback, failCallback) local handle = HttpReq.Create(url, HttpReq.HTTPMethods.Post, callback) HttpReq.AddHeader(handle, "Content-Type", "application/json; charset=utf-8") HttpReq.SetRawDataByStr(handle, loginDataStr, true) HttpReq.Send(handle) end function Login_Implement.UploadPCLogs(url, filePaths, fieldDatas, completeCallback, failCallback) local callback = private.GenerateGetCfgCallback(url, completeCallback, failCallback) local handle = HttpReq.Create(url, HttpReq.HTTPMethods.Post, callback) HttpReq.AddHeader(handle, "Content-Type", "multipart/form-data; boundary=logs_boundary") for __, filePath in ipairs(filePaths) do HttpReq.AddBinaryDataByFilePath(handle, "logFiles", filePath) end for fieldKey, fieldValue in pairs(fieldDatas) do HttpReq.SetField(handle, fieldKey, fieldValue) end HttpReq.Send(handle, nil, nil, true) end function Login_Implement.UploadRoleInfo(url, fieldDatas, completeCallback, failCallback) local callback = private.GenerateGetCfgCallback(url, completeCallback, failCallback) local handle = HttpReq.Create(url, HttpReq.HTTPMethods.Post, callback) HttpReq.AddHeader(handle, "Content-Type", "multipart/form-data; boundary=logs_boundary") for fieldKey, fieldValue in pairs(fieldDatas) do HttpReq.SetField(handle, fieldKey, fieldValue) end HttpReq.Send(handle, nil, nil, true) end return Login_Implement