Login.ts 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. import { _decorator, Component, ProgressBar, EditBox, Enum, Button, EventTouch, Node, director, Label, sys } from 'cc';
  2. import { DEBUG } from 'cc/env';
  3. import { DataSystem } from '../core/data/DataSystem';
  4. import { Http, ResponseType } from '../core/net/Http';
  5. import { HttpSystem } from '../core/net/HttpSystem';
  6. import { BitmapFont } from '../core/ui/BitmapFont';
  7. import { WindowSystem } from '../core/ui/window/WindowSystem';
  8. import { RC4 } from '../core/utils/RC4';
  9. import { StringUtils } from '../core/utils/StringUtils';
  10. import { Utils } from '../core/utils/Utils';
  11. import { ConfigData } from '../data/ConfigData';
  12. import { ADData } from '../data/jsb/ADData';
  13. import { DeviceData } from '../data/jsb/DeviceData';
  14. import { ISJSB, platform } from '../data/jsb/platform';
  15. import { WechatData } from '../data/jsb/WechatData';
  16. import { UserData } from '../data/UserData';
  17. const { ccclass, property, requireComponent } = _decorator;
  18. /**
  19. * 登录类型
  20. * @author 袁浩
  21. */
  22. export enum LoginType {
  23. guest,
  24. wechat
  25. }
  26. /**
  27. * 登录组件
  28. * @description 负责进行游戏的登录,其中正式服对于游客登录是关闭的
  29. * @author 袁浩
  30. */
  31. @ccclass('Login')
  32. @requireComponent(Http)
  33. export class Login extends Component {
  34. @property({ type: ProgressBar, tooltip: "加载进度条组件" })
  35. public progressBar: ProgressBar;
  36. @property({ type: BitmapFont, tooltip: "加载进度文本" })
  37. public progressTxt: BitmapFont;
  38. @property({ tooltip: "账号输入组件(仅仅在开发环境下才会显示)", type: EditBox })
  39. public accountInput: EditBox;
  40. @property({ tooltip: "登录类型,游客、微信", type: Enum(LoginType) })
  41. public loginType: LoginType = LoginType.guest;
  42. @property({ type: Node, tooltip: "登录面板" })
  43. public loginPanel: Node;
  44. private http: Http;
  45. start() {
  46. platform.reportThinking("loading", JSON.stringify({ is_first: localStorage.getItem("account") ? false : true }));
  47. this.http = this.getComponent(Http);
  48. this.accountInput.node.active = this.loginType == LoginType.guest;
  49. //隐藏登录按钮和输入框
  50. this.loginPanel.active = false;
  51. //初始化用户数据
  52. DataSystem.createData(UserData);
  53. //获取本地保存的账号
  54. this.accountInput.string = localStorage.getItem("account") || "";
  55. }
  56. /**
  57. * 登录功能准备好了
  58. */
  59. public async readyLogin() {
  60. let account = localStorage.getItem("account");
  61. if (this.loginType == LoginType.guest) {//如果是游客登录手动点击登录
  62. this.progressBar.node.active = false;
  63. this.loginPanel.active = true;
  64. }
  65. if (this.loginType == LoginType.wechat) {//如果是微信才自动登录
  66. if (account) {
  67. this.autoLogin(account);
  68. }
  69. else {
  70. this.progressBar.node.active = false;
  71. this.loginPanel.active = true;
  72. }
  73. }
  74. }
  75. public onLogin(event: EventTouch) {
  76. if (this.loginType == LoginType.guest) {//如果是游客登录手动点击登录
  77. let account = StringUtils.trim(this.accountInput.string);
  78. if (!account) {//空账号验证-TODO
  79. return;
  80. }
  81. this.doLogin(false, account);
  82. }
  83. else if (this.loginType == LoginType.wechat) {//如果是微信登录
  84. platform.wxLogin();
  85. }
  86. }
  87. update() {
  88. //如果配置加载完成
  89. if (DataSystem.watch(ConfigData, "loaded") && !ISJSB()) {
  90. this.readyLogin();
  91. }
  92. //如果配置加载已经完成,跟上面条件不一样是因为watch只会执行一次,而当watch到的时候,jsb不一定就已经给js返回了imei这些数据,所以得使用loaded属性来一直判断
  93. if (DataSystem.getData(ConfigData).loaded && ISJSB()) {
  94. let deviceData = DataSystem.getData(DeviceData);
  95. if (deviceData.versionIsNew != -1 && (DataSystem.watch(DeviceData, "imei") || deviceData.needlogin)) {//如果版本号不是老的、imei获得成功或者需要登录
  96. deviceData.needlogin = false;
  97. this.readyLogin();
  98. }
  99. }
  100. if (DataSystem.watch(WechatData, "code")) {//jsb返回了微信登录的code
  101. let wechatData = DataSystem.getData(WechatData);
  102. this.progressBar.node.active = true;
  103. this.loginPanel.active = false;
  104. this.doLogin(false, wechatData.code, wechatData.nickName, wechatData.avatar);
  105. }
  106. // if (DataSystem.watch(ADData, "rewardVideoADShow")) {//开屏展示
  107. // DataSystem.getData(ADData).ad_type = 6;
  108. // //上报展示
  109. // this.getComponent(Http).send("/api/ad/videoLog", { adData: DataSystem.getData(ADData).obj });
  110. // }
  111. }
  112. private autoLogined = false;
  113. private async autoLogin(account: string) {
  114. if (this.autoLogined) {
  115. return;
  116. }
  117. this.autoLogined = true;
  118. this.doLogin(true, account);
  119. }
  120. private async doLogin(onlyLogin = false, account: string = null, nickName: string = '', avator: string = '') {
  121. console.log(`${account}开始登录`);
  122. HttpSystem.resetTail();
  123. this.progressBar.node.active = false;
  124. this.loginPanel.active = false;
  125. this.http.useEncrypt = false;
  126. this.http.responseType = ResponseType.Arraybuffer;
  127. let data = await this.http.send("/api/user/logo");
  128. if (!data) {
  129. this.progressBar.node.active = false;
  130. this.loginPanel.active = true;
  131. WindowSystem.showTips("登录失败,请检查网络");
  132. return;
  133. }
  134. let moka = String.fromCharCode.apply(null, new Uint8Array(data));
  135. let code = "";
  136. for (let i = 0; i < moka.length - 1; i++) {
  137. const charCode0 = moka.charCodeAt(i).toString(16);
  138. const charCode1 = moka.charCodeAt(i + 1).toString(16);
  139. if (charCode0 == "ff" && charCode1 == "d9") {
  140. code = moka.substring(i + 2);
  141. break;
  142. }
  143. }
  144. HttpSystem.publicKey = RC4.rc4(decodeURI(code), "moka");
  145. this.http.responseType = ResponseType.Json;
  146. let deviceData = DataSystem.getData(DeviceData);
  147. let result = await this.http.send("/api/user/login", {
  148. account: account,
  149. onlyLogin: onlyLogin,
  150. type: LoginType[this.loginType],
  151. nickName: nickName,
  152. avator: avator,
  153. channel: deviceData.channel || 0,
  154. fromUserID: 0,
  155. imei: deviceData.imei,
  156. oaid: deviceData.oaid,
  157. androId: deviceData.androId,
  158. mac: deviceData.mac
  159. });
  160. if (result && result.data) {//登录成功
  161. this.progressBar.node.active = true;
  162. platform.setThinkingID(result.data.id);
  163. let userData = JSON.parse(JSON.stringify(result.data));
  164. userData.createTime = Utils.formatDate(new Date(userData.createTime));
  165. userData.updateTime = Utils.formatDate(new Date(userData.updateTime));
  166. platform.reportThinkingUserInfo(JSON.stringify(result.data));
  167. localStorage.setItem("account", result.data.account);
  168. DataSystem.getData(UserData).copy(result.data);
  169. HttpSystem.initServerTimestamp(result.data.timestamp);
  170. HttpSystem.addTail(`sessionID=${result.data.token}`);
  171. HttpSystem.setEncryptionKey(result.data.id);
  172. director.preloadScene("main", this.onProgress.bind(this), this.onLoaded.bind(this));
  173. }
  174. else {//网络连接失败
  175. WindowSystem.showTips("登录失败,请检查网络");
  176. localStorage.removeItem("account");
  177. if (this.loginType == LoginType.wechat) {
  178. this.progressBar.node.active = false;
  179. this.loginPanel.active = true;
  180. }
  181. }
  182. }
  183. private onProgress(completedCount: number, totalCount: number, item: any): void {
  184. this.progressBar.progress = completedCount / totalCount;
  185. this.progressTxt && (this.progressTxt.string = `${Math.floor(completedCount / totalCount * 100)}%`)
  186. }
  187. private onLoaded(): void {
  188. platform.reportThinking("login");
  189. director.loadScene("main");
  190. }
  191. }