import { _decorator, Component, ProgressBar, EditBox, Enum, Button, EventTouch, Node, director, Label, sys } from 'cc'; import { DEBUG } from 'cc/env'; import { DataSystem } from '../core/data/DataSystem'; import { Http, ResponseType } from '../core/net/Http'; import { HttpSystem } from '../core/net/HttpSystem'; import { BitmapFont } from '../core/ui/BitmapFont'; import { WindowSystem } from '../core/ui/window/WindowSystem'; import { RC4 } from '../core/utils/RC4'; import { StringUtils } from '../core/utils/StringUtils'; import { Utils } from '../core/utils/Utils'; import { ConfigData } from '../data/ConfigData'; import { ADData } from '../data/jsb/ADData'; import { DeviceData } from '../data/jsb/DeviceData'; import { ISJSB, platform } from '../data/jsb/platform'; import { WechatData } from '../data/jsb/WechatData'; import { UserData } from '../data/UserData'; const { ccclass, property, requireComponent } = _decorator; /** * 登录类型 * @author 袁浩 */ export enum LoginType { guest, wechat } /** * 登录组件 * @description 负责进行游戏的登录,其中正式服对于游客登录是关闭的 * @author 袁浩 */ @ccclass('Login') @requireComponent(Http) export class Login extends Component { @property({ type: ProgressBar, tooltip: "加载进度条组件" }) public progressBar: ProgressBar; @property({ type: BitmapFont, tooltip: "加载进度文本" }) public progressTxt: BitmapFont; @property({ tooltip: "账号输入组件(仅仅在开发环境下才会显示)", type: EditBox }) public accountInput: EditBox; @property({ tooltip: "登录类型,游客、微信", type: Enum(LoginType) }) public loginType: LoginType = LoginType.guest; @property({ type: Node, tooltip: "登录面板" }) public loginPanel: Node; private http: Http; start() { platform.reportThinking("loading", JSON.stringify({ is_first: localStorage.getItem("account") ? false : true })); this.http = this.getComponent(Http); this.accountInput.node.active = this.loginType == LoginType.guest; //隐藏登录按钮和输入框 this.loginPanel.active = false; //初始化用户数据 DataSystem.createData(UserData); //获取本地保存的账号 this.accountInput.string = localStorage.getItem("account") || ""; } /** * 登录功能准备好了 */ public async readyLogin() { let account = localStorage.getItem("account"); if (this.loginType == LoginType.guest) {//如果是游客登录手动点击登录 this.progressBar.node.active = false; this.loginPanel.active = true; } if (this.loginType == LoginType.wechat) {//如果是微信才自动登录 if (account) { this.autoLogin(account); } else { this.progressBar.node.active = false; this.loginPanel.active = true; } } } public onLogin(event: EventTouch) { if (this.loginType == LoginType.guest) {//如果是游客登录手动点击登录 let account = StringUtils.trim(this.accountInput.string); if (!account) {//空账号验证-TODO return; } this.doLogin(false, account); } else if (this.loginType == LoginType.wechat) {//如果是微信登录 platform.wxLogin(); } } update() { //如果配置加载完成 if (DataSystem.watch(ConfigData, "loaded") && !ISJSB()) { this.readyLogin(); } //如果配置加载已经完成,跟上面条件不一样是因为watch只会执行一次,而当watch到的时候,jsb不一定就已经给js返回了imei这些数据,所以得使用loaded属性来一直判断 if (DataSystem.getData(ConfigData).loaded && ISJSB()) { let deviceData = DataSystem.getData(DeviceData); if (deviceData.versionIsNew != -1 && (DataSystem.watch(DeviceData, "imei") || deviceData.needlogin)) {//如果版本号不是老的、imei获得成功或者需要登录 deviceData.needlogin = false; this.readyLogin(); } } if (DataSystem.watch(WechatData, "code")) {//jsb返回了微信登录的code let wechatData = DataSystem.getData(WechatData); this.progressBar.node.active = true; this.loginPanel.active = false; this.doLogin(false, wechatData.code, wechatData.nickName, wechatData.avatar); } // if (DataSystem.watch(ADData, "rewardVideoADShow")) {//开屏展示 // DataSystem.getData(ADData).ad_type = 6; // //上报展示 // this.getComponent(Http).send("/api/ad/videoLog", { adData: DataSystem.getData(ADData).obj }); // } } private autoLogined = false; private async autoLogin(account: string) { if (this.autoLogined) { return; } this.autoLogined = true; this.doLogin(true, account); } private async doLogin(onlyLogin = false, account: string = null, nickName: string = '', avator: string = '') { console.log(`${account}开始登录`); HttpSystem.resetTail(); this.progressBar.node.active = false; this.loginPanel.active = false; this.http.useEncrypt = false; this.http.responseType = ResponseType.Arraybuffer; let data = await this.http.send("/api/user/logo"); if (!data) { this.progressBar.node.active = false; this.loginPanel.active = true; WindowSystem.showTips("登录失败,请检查网络"); return; } let moka = String.fromCharCode.apply(null, new Uint8Array(data)); let code = ""; for (let i = 0; i < moka.length - 1; i++) { const charCode0 = moka.charCodeAt(i).toString(16); const charCode1 = moka.charCodeAt(i + 1).toString(16); if (charCode0 == "ff" && charCode1 == "d9") { code = moka.substring(i + 2); break; } } HttpSystem.publicKey = RC4.rc4(decodeURI(code), "moka"); this.http.responseType = ResponseType.Json; let deviceData = DataSystem.getData(DeviceData); let result = await this.http.send("/api/user/login", { account: account, onlyLogin: onlyLogin, type: LoginType[this.loginType], nickName: nickName, avator: avator, channel: deviceData.channel || 0, fromUserID: 0, imei: deviceData.imei, oaid: deviceData.oaid, androId: deviceData.androId, mac: deviceData.mac }); if (result && result.data) {//登录成功 this.progressBar.node.active = true; platform.setThinkingID(result.data.id); let userData = JSON.parse(JSON.stringify(result.data)); userData.createTime = Utils.formatDate(new Date(userData.createTime)); userData.updateTime = Utils.formatDate(new Date(userData.updateTime)); platform.reportThinkingUserInfo(JSON.stringify(result.data)); localStorage.setItem("account", result.data.account); DataSystem.getData(UserData).copy(result.data); HttpSystem.initServerTimestamp(result.data.timestamp); HttpSystem.addTail(`sessionID=${result.data.token}`); HttpSystem.setEncryptionKey(result.data.id); director.preloadScene("main", this.onProgress.bind(this), this.onLoaded.bind(this)); } else {//网络连接失败 WindowSystem.showTips("登录失败,请检查网络"); localStorage.removeItem("account"); if (this.loginType == LoginType.wechat) { this.progressBar.node.active = false; this.loginPanel.active = true; } } } private onProgress(completedCount: number, totalCount: number, item: any): void { this.progressBar.progress = completedCount / totalCount; this.progressTxt && (this.progressTxt.string = `${Math.floor(completedCount / totalCount * 100)}%`) } private onLoaded(): void { platform.reportThinking("login"); director.loadScene("main"); } }