YZ_Tool_QTT.ts 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. import PlatUtils from "./PlatUtils";
  2. import { utils } from "./Utils";
  3. import YZ_Constant, { LevelStatus } from "./YZ_Constant";
  4. import YZ_LocalStorage from "./YZ_LocalStorage";
  5. const { ccclass, property } = cc._decorator;
  6. let ST_DefaultServerConfig: string = "";
  7. const ST_ServerUrl: string = "http://apps.youlesp.com/gss?";
  8. const POST_ServerUrl: string = "http://report.youlesp.com/gss?";
  9. //@ts-ignore
  10. const md5 = require('./md5.js');
  11. const QTT_ServerUrl: string = "https://newidea4-gamecenter-backend.1sapp.com/x/open/user/ticket?"
  12. const QTT_Report: string = "https://newidea4-gamecenter-backend.1sapp.com/x/open/report/round"
  13. /**
  14. * 趣头条工具类
  15. */
  16. @ccclass
  17. export default class YZ_Tool_QTT {
  18. /**
  19. * 平台标示
  20. */
  21. platForm: string = "";
  22. //@ts-ignore
  23. qttGame = window.qttGame;
  24. _serverConfig: any = null;
  25. public get ServerConfig() {
  26. return this._serverConfig;
  27. }
  28. /**
  29. * 用户临时标示
  30. */
  31. ticket: string = "";
  32. _ip: string = "192.168.0.1";
  33. _sign: string = "";
  34. /**
  35. * 服务器地址
  36. */
  37. private serverPath: string = "http://apps.youlesp.com/gss?";
  38. //设备UID
  39. _uid: string = "0";
  40. public get uid() {
  41. if (this._service_uid != "0") return this._uid;
  42. this._login();
  43. return "0";
  44. }
  45. //服务器返回UID
  46. _service_uid: string = "0";
  47. /**
  48. * 服务器返回UID
  49. */
  50. public get serviceId() {
  51. if (this._service_uid != "0") return this._service_uid;
  52. this.reportLogin();
  53. return "0";
  54. }
  55. _loginTime: number = 0;
  56. _loginInterval: number = 30;
  57. async _login() {
  58. let curTime: number = new Date().getTime();
  59. let interval: number = (curTime - this._loginTime) / 1000;
  60. if (interval > 0 && interval < 30) {
  61. utils.showLog(`登录请求间隔小于:${this._loginInterval}秒`);
  62. return;
  63. }
  64. this._loginTime = curTime;
  65. let self = this;
  66. utils.showLog("qtt暂时不获取uid,uid全部为0");
  67. this._uid = "0";
  68. let url = this.getUrl();
  69. console.log("qtt获取用户的地址为:" + url)
  70. let xhr = new XMLHttpRequest();
  71. xhr.timeout = 6000; // 单位毫秒
  72. xhr.open('get', url);
  73. xhr.send();
  74. xhr.onreadystatechange = function () {
  75. utils.showLog("请求状态改变, reaedyState=", xhr.readyState, "; status=", xhr.status);
  76. if (xhr.readyState == 4 && xhr.status == 200) {
  77. console.log("请求成功");
  78. console.log(xhr.responseText);
  79. let msg = xhr.responseText
  80. let result = JSON.parse(msg);
  81. console.log(result)
  82. utils.showLog("获取数据成功1");
  83. self._uid = result.data.open_id;
  84. self.postServerData(QTT_REPORT_TYPE.ready);
  85. YZ_LocalStorage.setItem(YZ_Constant.ST_UID, self._uid);
  86. console.log(self._uid)
  87. }
  88. if (xhr.status != 200) {
  89. }
  90. }
  91. xhr.ontimeout = function () {
  92. utils.showLog("请求超时!");
  93. }
  94. xhr.onerror = function (err) {
  95. utils.showLog("请求出错! err=", JSON.stringify(err));
  96. }
  97. // this.reportLogin();
  98. }
  99. _reportLoginTime: number = 0;
  100. _reportLoginInterval: number = 30;
  101. isReport: boolean = false;
  102. /**
  103. * 上报登录接口获取UID
  104. */
  105. reportLogin() {
  106. if (this.isReport) return;
  107. this.isReport = true;
  108. let self = this;
  109. let curTime: number = new Date().getTime();
  110. let interval: number = (curTime - self._reportLoginTime) / 1000;
  111. if (interval > 0 && interval < 30) {
  112. utils.showLog(`上报登录获取UID小于:${self._reportLoginInterval}秒`);
  113. return;
  114. }
  115. self._reportLoginTime = curTime;
  116. let method = "m=login";
  117. let url: string = ST_ServerUrl + method + `&device_data=0`;
  118. utils.commomHttpRequest(url, (ret, data) => {
  119. if (ret) {
  120. if (data) {
  121. let result = JSON.parse(data);
  122. utils.showLog("data=" + data);
  123. utils.showLog("result=" + result);
  124. utils.showLog("result.uid=" + result.uid);
  125. if (result.ip) {
  126. this._ip = result.ip;
  127. }
  128. if (result.uid) {
  129. self._service_uid = "" + result.uid;
  130. utils.showLog("服务器请求登录成功! _service_uid=" + self._service_uid);
  131. YZ_LocalStorage.setItem(YZ_Constant.ST_SERVICE_UID, self._service_uid);
  132. }
  133. }
  134. } else {
  135. utils.showLog("获取数据失败1");
  136. }
  137. this.isReport = false;
  138. })
  139. }
  140. /**
  141. * 初始化
  142. * @param data 配置数据
  143. */
  144. public init(data: string): void {
  145. utils.showLog("qtt 初始化>>", data);
  146. if (data) {
  147. let configObj: any = JSON.parse(data);
  148. if (configObj && configObj.qutoutiao) {
  149. ST_DefaultServerConfig = JSON.stringify(configObj.qutoutiao);
  150. }
  151. }
  152. cc.game.on(QTT_REPORT_TYPE.ready, () => {
  153. this.postServerData(QTT_REPORT_TYPE.login);
  154. }, this)
  155. cc.game.on(QTT_REPORT_TYPE.login, () => {
  156. this.postServerData(QTT_REPORT_TYPE.load);
  157. }, this)
  158. this._uid = YZ_LocalStorage.getItem(YZ_Constant.ST_UID);
  159. this._uid = this._uid ? this._uid : "0";
  160. this.postServerData(QTT_REPORT_TYPE.ready);
  161. this._service_uid = YZ_LocalStorage.getItem(YZ_Constant.ST_SERVICE_UID);
  162. this._service_uid = this._service_uid ? this._service_uid : "0";
  163. this.platForm = this.GetRequest("platform");
  164. this.ticket = this.GetRequest("ticket");
  165. if (this.ticket && this.platForm) {
  166. // this.getUserInfo();
  167. // new QTTHELP().g
  168. // let qttHelp = new QTTHELP();
  169. // QTTHelp();
  170. // QTTHelp().then((res) => {
  171. // utils.showLog(">>>>>>>>>>>");
  172. // }).catch(() => {
  173. // })
  174. }
  175. this.loadServerData();
  176. }
  177. /**
  178. * 每局结束上报数据
  179. */
  180. public postGameOverData(level: number): void {
  181. if (PlatUtils.IsQTT) {
  182. this.qttGame.completeTask();
  183. this.qttGame.userInfo({ role: '趣头条', region: '区域1', level: level, ce: '1000000', round: '1', revenue: '100000', extend_info: { age: '18' } })
  184. }
  185. // Sys
  186. let time = Math.floor(new Date().getTime() / 1000);
  187. const values: any = {
  188. app_id: utils.config.qttconfig.appID,
  189. open_id: this.uid,
  190. ip: this._ip,
  191. round: level,
  192. game_time: time,
  193. };
  194. this.getSign(values);
  195. var formData = new FormData();
  196. formData.append("app_id", values.app_id);
  197. formData.append("open_id", values.open_id);
  198. formData.append("ip", values.ip);
  199. formData.append("round", values.round);
  200. formData.append("game_time", values.game_time);
  201. formData.append("sign", this._sign);
  202. this.post(values)
  203. }
  204. iframe: HTMLIFrameElement = null;
  205. form: HTMLFormElement = null;
  206. post(values) {
  207. if (!this.form) {
  208. this.form = document.createElement("form")
  209. } else {
  210. this.form.innerHTML = "";
  211. }
  212. if (!this.iframe) {
  213. this.iframe = document.createElement("iframe")
  214. }
  215. this.form.action = QTT_Report;
  216. this.form.enctype = "application/x-www-form-urlencoded";
  217. this.form.method = "post";
  218. this.iframe.name = "form"
  219. this.iframe.id = "form"
  220. this.form.target = "form";
  221. for (var item in values) {
  222. var opt = document.createElement("textarea");
  223. opt.name = item;
  224. opt.value = values[item];
  225. this.form.appendChild(opt);
  226. }
  227. document.body.appendChild(this.iframe);
  228. this.iframe.appendChild(this.form);
  229. this.form.submit();
  230. }
  231. /**
  232. * 获取用户信息
  233. */
  234. public getUserInfo() {
  235. this.qttGame.getUserInfo(utils.config.qttconfig.appKey, utils.config.qttconfig.appID, this.ticket, this.platForm).then(res => {
  236. // 成功
  237. utils.showLog("获取用户信息成功 #userInfo=", JSON.stringify(res));
  238. }).catch(err => {
  239. // 失败
  240. })
  241. }
  242. /**
  243. * 通过参数名称获取链接里的值
  244. * @param key 参数名称
  245. */
  246. private GetRequest(key) {
  247. var url = location.search;
  248. var theRequest = new Object();
  249. if (url.indexOf("?") != -1) {
  250. var str: string = url.substr(1);
  251. let strs = str.split("&");
  252. for (var i = 0; i < strs.length; i++) {
  253. theRequest[strs[i].split("=")[0]] = unescape(strs[i].split("=")[1]);
  254. }
  255. }
  256. var value = theRequest[key];
  257. return value;
  258. }
  259. /**
  260. * 请求服务器数据
  261. */
  262. public loadServerData() {
  263. if (!this.uid) {
  264. cc.error("用户ID为空>>>");
  265. this._uid = "0";
  266. }
  267. let method: string = "m=g";
  268. utils.commomHttpRequest(ST_ServerUrl + method, (ret: boolean, data: any) => {
  269. utils.showLog("loadServerUserdate #ret=", ret, " #data=", data);
  270. if (ret) {
  271. if (data) {
  272. utils.showLog("qtt服务器配置数据获取成功: data = ", data);
  273. let result = JSON.parse(data);
  274. if (result) {
  275. if (!utils.DebugLoacalConfig) {
  276. this._serverConfig = result;
  277. if (this._serverConfig.is_show_log_view && this._serverConfig.is_show_log_view == "true") {
  278. utils.showLogView = true;
  279. utils.showLog();
  280. }
  281. } else {
  282. cc.warn("开启了本地数据测试,使用本地配置!");
  283. }
  284. } else {
  285. utils.showLog("qtt服务器配置数据不是合法的JSON数据, 使用本地配置!");
  286. }
  287. } else {
  288. utils.showLog("qtt服务器配置数据获取失败, 使用本地配置!");
  289. }
  290. } else {
  291. }
  292. if (!this._serverConfig) {
  293. this._serverConfig = JSON.parse(ST_DefaultServerConfig);
  294. } else {
  295. if (this._serverConfig.is_local_pos_id
  296. && this._serverConfig.is_local_pos_id == "false") {
  297. // 使用服务器下发的广告id
  298. utils.showLog("使用服务器下发的广告id");
  299. utils.showLog("趣头条没有广告id")
  300. } else {
  301. utils.showLog("使用本地配置的广告ID");
  302. }
  303. }
  304. utils.emitServerInitEvent();
  305. })
  306. }
  307. /**
  308. * 上报关卡数据
  309. * @param level 当前关卡ID
  310. * @param levelName 关卡名称
  311. * @param status 状态
  312. */
  313. public postLevel(level: string, status: LevelStatus, levelName?: string) {
  314. if (PlatUtils.IsQTT) {
  315. let method = "m=rlevel";
  316. let url: string = POST_ServerUrl + method + `&level_id=${level}&level_name=${encodeURI(levelName)}&status=${status}`;
  317. utils.commomHttpRequest(url, function (ret, data) {
  318. if (ret) {
  319. utils.showLog("关卡数据上报成功!");
  320. } else {
  321. utils.showLog("关卡数据上报失败!");
  322. }
  323. }.bind(this));
  324. if (status == LevelStatus.GameStart) {
  325. this.postServerData(QTT_REPORT_TYPE.start);
  326. }
  327. //上报到qtt的官方服务器
  328. if (status == LevelStatus.GameWin) {
  329. this.postGameOverData(Number(level));
  330. }
  331. }
  332. }
  333. getSign(values) {
  334. let s = this.sign(values);
  335. values.sign = s
  336. this.checkSign(values);
  337. this._sign = s;
  338. }
  339. public getUrl(): string {
  340. let params = this.getParams();
  341. const values: any = {
  342. app_id: utils.config.qttconfig.appID,
  343. platform: params.platform,
  344. ticket: params.ticket,
  345. time: Math.floor(new Date().getTime() / 1000)
  346. }
  347. let s = this.sign(values);
  348. values.sign = s
  349. this._sign = s;
  350. return QTT_ServerUrl + "app_id=" + values.app_id + "&platform=" + params.platform + "&ticket=" + params.ticket + "&time=" + values.time + "&sign=" + values.sign;
  351. }
  352. getParams(): any {
  353. let url: string = window.location.href;
  354. let paramArr = url.split("&");
  355. let platform;
  356. let ticket;
  357. paramArr.forEach(str => {
  358. if (str.indexOf("platform") != -1) {
  359. platform = str.split("=")[1];
  360. }
  361. if (str.indexOf("ticket") != -1) {
  362. ticket = str.split("=")[1];
  363. }
  364. });
  365. return { platform: platform, ticket: ticket };
  366. }
  367. public sign(values) {
  368. delete values.sign;
  369. values.app_key = utils.config.qttconfig.appKey;
  370. let keysArr = [];
  371. for (let key in values) {
  372. keysArr.push(key)
  373. }
  374. keysArr.sort();
  375. let keys = ''
  376. keysArr.forEach((e) => {
  377. keys += e;
  378. keys += values[e];
  379. });
  380. console.log("原串:" + keys)
  381. delete values.app_key;
  382. let sign = md5(keys);
  383. return sign;
  384. }
  385. public checkSign(values) {
  386. let sign1 = values.sign;
  387. if (!sign1) {
  388. console.log('sign error');
  389. return false;
  390. }
  391. let sign2 = this.sign(values);
  392. if (sign1 !== sign2) {
  393. console.log("sign error")
  394. return false;
  395. }
  396. console.log('ok')
  397. return true;
  398. }
  399. _isReady: boolean = false;
  400. _isLogin: boolean = false;
  401. _isLoad: boolean = false;
  402. _isStart: boolean = false;
  403. /**
  404. * 趣头条服务器上报
  405. *
  406. * 参数为object对象, 根据type 属性传入对应字段
  407. * @param type {String} ready 游戏资源加载完毕 login 用户成功登陆 load 成功进入游戏界面/主页 start 开始游戏
  408. * @param app_id { String} [必填]
  409. * @param open_id {String} 参考具体上报说明
  410. * @param game_name {String} 参考具体上报说明
  411. * @param extend_info [选填] json对象 {}
  412. *
  413. **/
  414. public postServerData(type: QTT_REPORT_TYPE, info?: any) {
  415. console.log("趣头条数据上报:" + type, this._uid)
  416. if (!this.uid && this._uid != "0") {
  417. cc.error("用户ID不存在 ,不上报数据>>>");
  418. return;
  419. }
  420. switch (type) {
  421. case QTT_REPORT_TYPE.ready:
  422. if (this._isReady) {
  423. console.log("已经上传过资源加载完毕事件")
  424. return;
  425. }
  426. break;
  427. case QTT_REPORT_TYPE.login:
  428. if (this._isLogin) {
  429. console.log("以及上传过资源加载完毕事件")
  430. return;
  431. }
  432. break;
  433. case QTT_REPORT_TYPE.load:
  434. if (this._isLoad) {
  435. console.log("以及上传过资源加载完毕事件")
  436. return;
  437. }
  438. break;
  439. case QTT_REPORT_TYPE.start:
  440. if (this._isStart) {
  441. console.log("以及上传过资源加载完毕事件")
  442. return;
  443. }
  444. break;
  445. default:
  446. break;
  447. }
  448. let app_id = utils.config.qttconfig.appID;
  449. let game_name = utils.config.qttconfig.gamename;
  450. let extend_info = info ? info : {};
  451. if (this.qttGame && this.qttGame.reportData) {
  452. switch (type) {
  453. case QTT_REPORT_TYPE.ready:
  454. this._isReady = true;
  455. break;
  456. case QTT_REPORT_TYPE.login:
  457. this._isLogin = true;
  458. break;
  459. case QTT_REPORT_TYPE.load:
  460. this._isLoad = true;
  461. break;
  462. case QTT_REPORT_TYPE.start:
  463. this._isStart = true;
  464. break;
  465. }
  466. this.qttGame.reportData({ "type": type, "open_id": this.uid, "app_id": app_id, "game_name": game_name, "extend_info": extend_info })
  467. console.log("趣头条成功发送事件:" + type);
  468. cc.game.emit(type);
  469. } else {
  470. let self = this;
  471. console.log("趣头条发送:" + type + "失败");
  472. setTimeout(() => {
  473. self.postServerData(type, info);
  474. }, 100);
  475. }
  476. }
  477. /**
  478. * 上报自定义事件
  479. * @param level 当前关卡ID
  480. * @param levelName 关卡名称
  481. * @param status 状态
  482. */
  483. public sendEvent(eventName: string) {
  484. if (PlatUtils.IsQTT) {
  485. let method = "m=revent";
  486. let url: string = POST_ServerUrl + method + `&event=${encodeURI(eventName)}`;
  487. utils.commomHttpRequest(url, function (ret, data) {
  488. if (ret) {
  489. utils.showLog("上报自定义事件成功!");
  490. } else {
  491. utils.showLog("上报自定义事件失败!");
  492. }
  493. }.bind(this));
  494. }
  495. }
  496. }
  497. export enum QTT_REPORT_TYPE {
  498. ready = "ready", //游戏资源加载完毕
  499. login = "login", //用户成功登陆
  500. load = "load", //成功进入游戏界面/主页
  501. start = "start", //开始游戏
  502. newRole = "newRole", //新增创角
  503. newUser = "newUser", //新增用户
  504. upgrade = "upgrade", //用户等级提升
  505. userInfo = "userInfo", //用户游戏信息
  506. abnormal = "abnormal", //游戏异常
  507. }