0094603a0536c0222b1cbb5d5cffe19fbc2859c7.js 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  1. System.register(["__unresolved_0", "cc", "__unresolved_1", "__unresolved_2", "__unresolved_3"], function (_export, _context) {
  2. "use strict";
  3. var _reporterNs, _cclegacy, NetRoom, NetTeam, WsClient, ch_net, _crd, HEARTBEAT_INTERVAL, HEARTBEAT_TIMEOUT, DIRTYDATACHECK_INTERVAL, EVTCHECK_INTERVAL, RECONNECT_COUNT, RECONNECT_INTERVAL, PING, PONG, S2C_LOGIN_SUCCESS, S2C_TEAM_SUCCESS, S2C_JOIN_TEAM_FAIL, S2C_TEAM_USER_JOIN, S2C_TEAM_USER_EXIT, S2C_TEAM_CHANGE_HOST, S2C_USER_RECONNECT, S2C_USER_DISCONNECT, S2C_MATCH, S2C_MATCH_SUCCESS, S2C_MATCH_CANCEL, S2C_ROOM_GAMEDATA_CHANGE, S2C_USER_GAMEDATA_CHANGE, S2C_ROOM_CHANGE_HOST, S2C_ROOM_CLOSED, S2C_TALK, S2C_FINISH, S2C_SETTLEMENT, S2C_READY, S2C_NOT_READY, C2S_UPDATE_USER_GAMEDATA, C2S_UPDATE_ROOM_GAMEDATA, C2S_SET_TEAM, C2S_JOIN_TEAM, C2S_EXIT_TEAM, C2S_CLOSE_ROOM, C2S_ROOM_EXIT, C2S_MESSAGE, C2S_MESSAGE_TO_HOST, C2S_MESSAGE_TO_OTHER, C2S_TALK, C2S_BACKED_RETURN, C2S_BACKED, C2S_FINISH, Ver;
  4. /**自定义同步游戏变量(只能以r_或p_开头,按帧率同步,重新进入会收到最新的数据)
  5. * 只有第一个参数有效,可加上第一个参数跟第一个参数同类型,用于接收改变前的数据
  6. * t_开头为队伍事件
  7. * r_开头 主机游戏数据 主机权限
  8. * revt_ 开头房间事件
  9. * p_ 开头玩家数据 玩家权限和主机ai权限
  10. * online 玩家在线下线状态
  11. * 尽量拆分数据类型,不要设置过于复杂的数据类型*/
  12. /**网络状态*/
  13. function isArrayBuffer(it) {
  14. try {
  15. return it instanceof ArrayBuffer;
  16. } catch (_) {
  17. return false;
  18. }
  19. }
  20. function _reportPossibleCrUseOfNetRoom(extras) {
  21. _reporterNs.report("NetRoom", "./NetRoom", _context.meta, extras);
  22. }
  23. function _reportPossibleCrUseOfNetTeam(extras) {
  24. _reporterNs.report("NetTeam", "./NetTeam", _context.meta, extras);
  25. }
  26. function _reportPossibleCrUseOfWsClient(extras) {
  27. _reporterNs.report("WsClient", "./WsClient", _context.meta, extras);
  28. }
  29. _export("ch_net", void 0);
  30. return {
  31. setters: [function (_unresolved_) {
  32. _reporterNs = _unresolved_;
  33. }, function (_cc) {
  34. _cclegacy = _cc.cclegacy;
  35. }, function (_unresolved_2) {
  36. NetRoom = _unresolved_2.NetRoom;
  37. }, function (_unresolved_3) {
  38. NetTeam = _unresolved_3.NetTeam;
  39. }, function (_unresolved_4) {
  40. WsClient = _unresolved_4.WsClient;
  41. }],
  42. execute: function () {
  43. _crd = true;
  44. _cclegacy._RF.push({}, "3f10au8XnFG2b0ZjXy1nl0i", "net", undefined);
  45. HEARTBEAT_INTERVAL = 1000; //每秒发送一次 Ping
  46. HEARTBEAT_TIMEOUT = 30000; //30 秒的断线超时
  47. DIRTYDATACHECK_INTERVAL = 200; //每200毫秒同步一次自定义游戏变量
  48. EVTCHECK_INTERVAL = 66; //每66毫秒同步一次自定义游戏事件
  49. RECONNECT_COUNT = 10; //默认重连次数
  50. RECONNECT_INTERVAL = 2000; //默认重连间隔
  51. PING = 'ping';
  52. PONG = 'pong'; //
  53. S2C_LOGIN_SUCCESS = 's2c_login_success';
  54. S2C_TEAM_SUCCESS = 's2c_team_success';
  55. S2C_JOIN_TEAM_FAIL = 's2c_join_team_fail';
  56. S2C_TEAM_USER_JOIN = 's2c_team_user_join';
  57. S2C_TEAM_USER_EXIT = 's2c_team_user_exit';
  58. S2C_TEAM_CHANGE_HOST = 's2c_team_change_host';
  59. S2C_USER_RECONNECT = 's2c_user_reconnect';
  60. S2C_USER_DISCONNECT = 's2c_user_disconnect';
  61. S2C_MATCH = 's2c_match';
  62. S2C_MATCH_SUCCESS = 's2c_match_success';
  63. S2C_MATCH_CANCEL = 's2c_match_cancel';
  64. S2C_ROOM_GAMEDATA_CHANGE = 's2c_room_gameData_change';
  65. S2C_USER_GAMEDATA_CHANGE = 's2c_user_gameData_change';
  66. S2C_ROOM_CHANGE_HOST = 's2c_room_change_host';
  67. S2C_ROOM_CLOSED = 's2c_room_closed';
  68. S2C_TALK = 's2c_talk';
  69. S2C_FINISH = 's2c_finish';
  70. S2C_SETTLEMENT = 's2c_settlement';
  71. S2C_READY = 's2c_ready';
  72. S2C_NOT_READY = 's2c_not_ready'; //
  73. C2S_UPDATE_USER_GAMEDATA = 'c2s_update_user_gameData';
  74. C2S_UPDATE_ROOM_GAMEDATA = 'c2s_update_room_gameData';
  75. C2S_SET_TEAM = 'c2s_set_team';
  76. C2S_JOIN_TEAM = 'c2s_join_team';
  77. C2S_EXIT_TEAM = 'c2s_exit_team';
  78. C2S_CLOSE_ROOM = 'c2s_close_room';
  79. C2S_ROOM_EXIT = 'c2s_room_exit';
  80. C2S_MESSAGE = 'c2s_message';
  81. C2S_MESSAGE_TO_HOST = 'c2s_message_to_host';
  82. C2S_MESSAGE_TO_OTHER = 'c2s_message_without_self';
  83. C2S_TALK = 'c2s_talk';
  84. C2S_BACKED_RETURN = 'c2s_backed_return';
  85. C2S_BACKED = 'c2s_to_backed';
  86. C2S_FINISH = 'c2s_finish'; //
  87. Ver = '0.1.8';
  88. /**客户端*/
  89. _export("ch_net", ch_net = class ch_net {
  90. _new_resolve(id) {
  91. return new Promise(resolve => this._callbacks[id] = resolve);
  92. }
  93. get ownLevel() {
  94. return this._lv;
  95. }
  96. _do_resolve(id, data) {
  97. const resolveCallback = this._callbacks[id];
  98. if (!resolveCallback) return false;
  99. resolveCallback(data);
  100. delete this._callbacks[id];
  101. return true;
  102. }
  103. get dataInterval() {
  104. return this.gameDataInterval * 0.001;
  105. }
  106. get evtInterval() {
  107. return this.gameEvtInterval * 0.001;
  108. }
  109. get isActive() {
  110. return this._ws && this._ws.isActive;
  111. }
  112. /**队伍信息*/
  113. get team() {
  114. return this._team;
  115. }
  116. /**是否在队伍中*/
  117. get inTeam() {
  118. return this._team != null && this._team.own != null;
  119. }
  120. /**房间信息*/
  121. get room() {
  122. return this._room;
  123. }
  124. /**是否在房间中*/
  125. get inRoom() {
  126. return this._room != null && !this._room.cloosed;
  127. }
  128. /**
  129. * 创建一个客户端
  130. */
  131. constructor() {
  132. /**连接状态事件*/
  133. this.state = chsdk.get_new_event();
  134. this._ws = null;
  135. this._url = void 0;
  136. this._ca = void 0;
  137. this.reconnection = void 0;
  138. this.reconnectCount = void 0;
  139. this.reconnectInterval = void 0;
  140. this.timeoutInterval = void 0;
  141. this.gameDataInterval = void 0;
  142. this.gameEvtInterval = void 0;
  143. this.timeout = null;
  144. this.json = false;
  145. this.heartbeatInterval = null;
  146. // 心跳定时器
  147. this.dirtyDataCheckInterval = null;
  148. //变量同步定时器
  149. this.evtCheckInterval = null;
  150. //事件同步定时器
  151. this._currentReconnectCount = 0;
  152. this._pingTime = 0;
  153. this._ping = 0;
  154. //ping值
  155. this._callbacks = {};
  156. this._waitSends = [];
  157. this._lv = {
  158. LowerRank: 0,
  159. Rank: 0,
  160. Star: 0
  161. };
  162. this._team = void 0;
  163. this._room = void 0;
  164. this._waitSends = [];
  165. this._callbacks = {};
  166. }
  167. /**初始化
  168. * @param url - 连接的地址 'ws://localhost:3000'
  169. * @param options - 可选的配置选项对象,支持以下属性:
  170. * - **ca**: (可选) CA 证书字符串,用于 SSL 连接的验证。
  171. * - **reconnection**: (可选) 指示是否启用重连机制,默认为 `true`。
  172. * - **reconnectCount**: (可选) 在连接失败后重连的最大次数,默认值为 `10`。
  173. * - **reconnectInterval**: (可选) 每次重连之间的间隔时间,以毫秒为单位,默认值为 `2000` (2 秒)。
  174. * - **timeoutInterval**: (可选) 心跳断线时间,以毫秒为单位,默认值为 `30000` (30 秒)。
  175. * - **gameEvtInterval**:(可选) 游戏事件同步间隔,默认值为 `66` (0.06秒 1秒钟15次)。
  176. * - **gameDataInterval**:(可选) 游戏变量同步间隔,默认值为 `200` (0.2秒 1秒钟5次)。
  177. * - **json**: (可选) 是否用json序列化否则用messagepck 默认为 `false`。
  178. * @example
  179. * 自定义消息
  180. interface message extends message_protocol {
  181. useItem(userId: string, otherId: string, itemId: number): void//使用道具
  182. }
  183. 自定义数据
  184. export interface gd extends game_data {
  185. r_lv(lv: number);//关卡信息
  186. r_time(time: number);//关卡时间
  187. }
  188. export const net = ch.get_new_net<gd, message>();
  189. const url = chsdk.getUrl('/handle').replace(chsdk.getUrl('/handle').split(':')[0], 'ws');
  190. const token = chsdk.getToken();
  191. net.init(url,{query: `token=${token}`});
  192. */
  193. init(url, options) {
  194. var _options$query, _options$reconnection, _options$reconnectCou, _options$reconnectInt, _options$timeoutInter, _options$gameDataInte, _options$gameEvtInter, _options$json;
  195. this._url = url;
  196. this._url = `${this._url}${options != null && (_options$query = options.query) != null && _options$query.length ? '?' + options.query : ''}`;
  197. this._ca = options == null ? void 0 : options.ca;
  198. this.reconnection = (_options$reconnection = options == null ? void 0 : options.reconnection) != null ? _options$reconnection : true;
  199. this.reconnectCount = (_options$reconnectCou = options == null ? void 0 : options.reconnectCount) != null ? _options$reconnectCou : RECONNECT_COUNT;
  200. this.reconnectInterval = (_options$reconnectInt = options == null ? void 0 : options.reconnectInterval) != null ? _options$reconnectInt : RECONNECT_INTERVAL;
  201. this.timeoutInterval = (_options$timeoutInter = options == null ? void 0 : options.timeoutInterval) != null ? _options$timeoutInter : HEARTBEAT_TIMEOUT;
  202. this.gameDataInterval = (_options$gameDataInte = options == null ? void 0 : options.gameDataInterval) != null ? _options$gameDataInte : DIRTYDATACHECK_INTERVAL;
  203. this.gameEvtInterval = (_options$gameEvtInter = options == null ? void 0 : options.gameEvtInterval) != null ? _options$gameEvtInter : EVTCHECK_INTERVAL;
  204. this.json = (_options$json = options == null ? void 0 : options.json) != null ? _options$json : false;
  205. this._ws = new (_crd && WsClient === void 0 ? (_reportPossibleCrUseOfWsClient({
  206. error: Error()
  207. }), WsClient) : WsClient)(this._url, this._ca);
  208. this._ws.onConnected = this._onConnected.bind(this);
  209. this._ws.onError = this._onError.bind(this);
  210. this._ws.onClosing = this._onClosing.bind(this);
  211. this._ws.onClosed = this._onClosed.bind(this);
  212. this._ws.onMessage = this._onMessage.bind(this);
  213. const isbuffer = typeof ArrayBuffer !== 'undefined';
  214. console.log('ch_net 初始化 ver:', Ver, isbuffer, this.json, this._url); //
  215. chsdk.sdk_event.on('hide', this.on_hide, this);
  216. chsdk.sdk_event.on('show', this.on_show, this);
  217. }
  218. /**主动断开连接*/
  219. dispose() {
  220. this.state.clearAll();
  221. this._clear_team();
  222. this._clear_room();
  223. this._callbacks = {};
  224. this._waitSends.length = 0;
  225. this._ws.close(5000, 'client disconnect');
  226. chsdk.sdk_event.off('hide', this.on_hide, this);
  227. chsdk.sdk_event.off('show', this.on_show, this);
  228. }
  229. on_hide() {
  230. if (!this.inRoom) return;
  231. this.send_data(C2S_BACKED);
  232. }
  233. on_show() {
  234. if (!this.inRoom) return;
  235. this.send_data(C2S_BACKED_RETURN);
  236. }
  237. encode(msg) {
  238. return this.json ? JSON.stringify(msg) : msgpack.encode(msg);
  239. }
  240. decode(medata) {
  241. return isArrayBuffer(medata) ? msgpack.decode(new Uint8Array(medata)) : JSON.parse(medata);
  242. }
  243. send_data(type, data) {
  244. this._send(this.encode(data ? {
  245. type: type,
  246. data: data
  247. } : {
  248. type: type
  249. }));
  250. }
  251. /**开始连接,返回null为成功,否则为错误提示*/
  252. async connect() {
  253. if (!this._ws) {
  254. chsdk.log.error('not init');
  255. return 'not init';
  256. }
  257. if (!this._ws.connect()) return 'no netconnect';
  258. this.state.emit(this.state.key.Connecting);
  259. return this._new_resolve('connect');
  260. }
  261. /**主动重新连接*/
  262. reconnect() {
  263. if (!this._ws) {
  264. chsdk.log.error('not init');
  265. return 'not init';
  266. }
  267. this._currentReconnectCount = 1;
  268. this.do_reconnect();
  269. }
  270. do_reconnect() {
  271. if (!this._ws.connect()) return;
  272. this.state.emit(this.state.key.Reconnecting, this._currentReconnectCount);
  273. }
  274. /**玩家创建队伍,返回null为成功,否则为错误提示*/
  275. async creat_team(player_count = 4) {
  276. if (!this._ws) return 'no netconnect';
  277. if (this.inTeam) return null;
  278. this.send_data(C2S_SET_TEAM, player_count);
  279. return this._new_resolve('creat_team');
  280. }
  281. /**玩家进入队伍,返回null为成功,否则为错误提示*/
  282. async join_team(password) {
  283. if (!this._ws) return 'no netconnect';
  284. if (this.inTeam) return null;
  285. this.send_data(C2S_JOIN_TEAM, {
  286. password: password
  287. });
  288. return this._new_resolve('join_team');
  289. }
  290. /**玩家退出队伍,返回null为成功,否则为错误提示*/
  291. async exit_team() {
  292. if (!this._ws) return 'no netconnect';
  293. if (!this.inTeam) return 'not in team';
  294. if (this.inRoom) return 'in game';
  295. this.send_data(C2S_EXIT_TEAM);
  296. return this._new_resolve('exit_team');
  297. }
  298. /**主机结束游戏关闭房间,成功后收到房间关闭事件*/
  299. close_room() {
  300. if (!this._ws) return;
  301. if (!this.inRoom) return;
  302. if (!this.room.isHost) return;
  303. this.send_data(C2S_CLOSE_ROOM);
  304. }
  305. /**玩家退出房间 ,返回null为成功,否则为错误提示,退出成功后收到房间关闭事件*/
  306. async exit_room() {
  307. if (!this._ws) return 'no netconnect';
  308. if (!this.inRoom) return 'not in room';
  309. this.send_data(C2S_ROOM_EXIT);
  310. return this._new_resolve('exit_room');
  311. }
  312. _clear_team() {
  313. var _this$_team;
  314. (_this$_team = this._team) == null || _this$_team.dispose();
  315. this._team = null;
  316. }
  317. _clear_room() {
  318. var _this$_room;
  319. if (!this._room) return;
  320. (_this$_room = this._room) == null || _this$_room.dispose();
  321. this._room = null;
  322. }
  323. _send(data) {
  324. if (!this._ws) return;
  325. if (this._ws.isActive) {
  326. this._ws.send(data);
  327. } else {
  328. this._waitSends.push(data);
  329. }
  330. }
  331. _updatePlayerStatus(id, online) {
  332. if (this.inTeam) this._team.updatePlayerStatus(id, online);
  333. if (this.inRoom) this._room.updatePlayerStatus(id, online);
  334. } //
  335. _onMessage(msg) {
  336. this.resetHeartbeat();
  337. try {
  338. const {
  339. data: medata
  340. } = msg;
  341. const data = this.decode(medata);
  342. if (data.type !== PONG) chsdk.log.log('receive', JSON.stringify(data));
  343. switch (data.type) {
  344. case PONG:
  345. this._ping = chsdk.date.now() - this._pingTime;
  346. chsdk.date.updateServerTime(data.data); //chsdk.log.log("pong:", this._ping, data.data, chsdk.date.now());
  347. break;
  348. case S2C_LOGIN_SUCCESS:
  349. this._lv = data.data;
  350. if (this._do_resolve('connect', null)) {
  351. this.state.emit(this.state.key.Connected);
  352. } else {
  353. this.state.emit(this.state.key.Reconnected);
  354. }
  355. this._callbacks = {};
  356. this.startHeartbeat();
  357. while (this._waitSends.length) {
  358. if (!this._ws) break;
  359. const data = this._waitSends.shift();
  360. if (data) this._ws.send(data);
  361. }
  362. break;
  363. case S2C_TEAM_SUCCESS:
  364. if (this._team) this._clear_team();
  365. this._team = new (_crd && NetTeam === void 0 ? (_reportPossibleCrUseOfNetTeam({
  366. error: Error()
  367. }), NetTeam) : NetTeam)(data.data, this.send_data.bind(this));
  368. if (!this._do_resolve('creat_team', null)) this._do_resolve('join_team', null);
  369. break;
  370. case S2C_JOIN_TEAM_FAIL:
  371. this._do_resolve('join_team', data.data);
  372. break;
  373. case S2C_TEAM_USER_JOIN:
  374. const join_user = data.data;
  375. join_user.status = true;
  376. this._team.addPlayer({
  377. key: join_user.userKey,
  378. data: join_user
  379. }, true);
  380. break;
  381. case S2C_TEAM_USER_EXIT:
  382. const esit_id = data.data;
  383. if (esit_id === this._team.own.Id) {
  384. this._team.closed();
  385. this._clear_team();
  386. this._do_resolve('exit_team', null);
  387. } else {
  388. this._team.removePlayer(esit_id);
  389. }
  390. break;
  391. case S2C_TEAM_CHANGE_HOST:
  392. this._team.changeHost(data.data);
  393. break;
  394. case S2C_ROOM_CHANGE_HOST:
  395. this._room.changeHost(data.data);
  396. break;
  397. case S2C_USER_RECONNECT:
  398. this._updatePlayerStatus(data.data, true);
  399. break;
  400. case S2C_USER_DISCONNECT:
  401. this._updatePlayerStatus(data.data, false);
  402. break;
  403. case S2C_MATCH:
  404. this._team.match_start();
  405. break;
  406. case S2C_MATCH_CANCEL:
  407. this._team.match_cancel();
  408. break;
  409. case S2C_NOT_READY:
  410. this._team.not_ready();
  411. break;
  412. case S2C_READY:
  413. this._team.updatePlayerReady(data.data, true);
  414. break;
  415. case S2C_MATCH_SUCCESS:
  416. this._clear_room();
  417. const roomData = data.data.roomData;
  418. const pData = data.data.playerData;
  419. this._room = new (_crd && NetRoom === void 0 ? (_reportPossibleCrUseOfNetRoom({
  420. error: Error()
  421. }), NetRoom) : NetRoom)(roomData, pData);
  422. if (this._team) this._team.match_success();
  423. break;
  424. case S2C_ROOM_GAMEDATA_CHANGE:
  425. this._room.server_change(data.data);
  426. break;
  427. case S2C_USER_GAMEDATA_CHANGE:
  428. const p = this._room.getPlayer(data.data.userKey);
  429. if (!p) break;
  430. p.server_change(data.data.data);
  431. break;
  432. case S2C_ROOM_CLOSED:
  433. this._room.closed(data.data);
  434. if (this.inTeam) {
  435. const list = this.room.all;
  436. for (let i = 0; i < list.length; i++) {
  437. const rp = list[i];
  438. if (rp.isAI) continue;
  439. const p = this.team.getPlayer(rp.Id);
  440. if (!p) continue;
  441. p.set_level(rp.level, rp.rank, rp.score, rp.totalRank);
  442. }
  443. }
  444. this._do_resolve('exit_room', null);
  445. break;
  446. case S2C_TALK:
  447. if (this.inRoom) {
  448. this._room.onChat(data.data.userKey, data.data.msg);
  449. } else if (this.inTeam) {
  450. this._team.onChat(data.data.userKey, data.data.msg);
  451. }
  452. break;
  453. case S2C_FINISH:
  454. this._room.finish(data.data.userKey, data.data.rank);
  455. break;
  456. case S2C_SETTLEMENT:
  457. this._room.settlement(data.data);
  458. break;
  459. case C2S_MESSAGE:
  460. if (Array.isArray(data.data)) {
  461. for (let i = 0; i < data.data.length; i++) {
  462. const d = data.data[i];
  463. this._room._onEvt(d.type, d.data);
  464. }
  465. } else {
  466. chsdk.log.log('no def type:', data.data); //(this.receive as any)._emit(data.type, data.data);
  467. }
  468. break;
  469. default:
  470. break;
  471. }
  472. } catch (error) {
  473. chsdk.log.warn(error);
  474. this.state.emit(this.state.key.Error, error);
  475. }
  476. }
  477. _onConnected(evt) {
  478. if (this.timeout) clearTimeout(this.timeout);
  479. this._currentReconnectCount = 0;
  480. this.timeout = setTimeout(() => {
  481. this._ws.close();
  482. chsdk.log.error("Closing connection.");
  483. }, 3000);
  484. }
  485. _onError(err) {
  486. chsdk.log.log('err', err);
  487. this.state.emit(this.state.key.Error, err);
  488. }
  489. _onClosing() {
  490. chsdk.log.log('closing');
  491. this.state.emit(this.state.key.Connecting);
  492. }
  493. _onClosed(event) {
  494. chsdk.log.log("WebSocket connection closed", event);
  495. this.stopHeartbeat();
  496. if (!this.reconnection || event.reason && event.code > 4000) {
  497. this.state.emit(this.state.key.Closed, event);
  498. this._do_resolve('connect', event);
  499. chsdk.log.log("WebSocket connection closed", event);
  500. return;
  501. }
  502. if (this._currentReconnectCount < this.reconnectCount) {
  503. this._currentReconnectCount += 1;
  504. chsdk.log.log(`Reconnecting... Attempt ${this._currentReconnectCount}`);
  505. setTimeout(() => {
  506. this.do_reconnect();
  507. }, this.reconnectInterval);
  508. } else {
  509. chsdk.log.error("Max reconnect attempts reached. Giving up.");
  510. this.state.emit(this.state.key.Closed, event);
  511. this._do_resolve('connect', event);
  512. }
  513. }
  514. startHeartbeat() {
  515. this.heartbeatInterval = setInterval(() => {
  516. this.sendHeartbeat();
  517. }, HEARTBEAT_INTERVAL);
  518. this.dirtyDataCheckInterval = setInterval(() => {
  519. this.dirtyDataCheck();
  520. }, this.gameDataInterval);
  521. this.evtCheckInterval = setInterval(() => {
  522. this.evtCheck();
  523. }, this.gameEvtInterval);
  524. }
  525. resetHeartbeat() {
  526. if (this.timeout) clearTimeout(this.timeout);
  527. this.timeout = setTimeout(() => {
  528. chsdk.log.error("Heartbeat timeout. Closing connection.");
  529. this._ws.close();
  530. }, this.timeoutInterval);
  531. }
  532. sendHeartbeat() {
  533. this._pingTime = chsdk.date.now();
  534. this.send_data(PING, this._ping);
  535. }
  536. stopHeartbeat() {
  537. if (this.heartbeatInterval) clearInterval(this.heartbeatInterval);
  538. if (this.timeout) clearTimeout(this.timeout);
  539. if (this.dirtyDataCheckInterval) clearInterval(this.dirtyDataCheckInterval);
  540. if (this.evtCheckInterval) clearInterval(this.evtCheckInterval);
  541. }
  542. evtCheck() {
  543. if (this.inRoom) {
  544. this.room.doSendChat(msg => {
  545. if (!msg) return;
  546. this.send_data(C2S_TALK, msg);
  547. });
  548. this.room.doSendMode((mode0, mode1, mode2) => {
  549. if (mode0.length > 0) this.send_data(C2S_MESSAGE, mode0);
  550. if (mode1.length > 0) this.send_data(C2S_MESSAGE_TO_HOST, mode1);
  551. if (mode2.length > 0) this.send_data(C2S_MESSAGE_TO_OTHER, mode2);
  552. });
  553. const ps = this.room.all;
  554. for (let i = 0; i < ps.length; i++) {
  555. const p = ps[i];
  556. p.doFinishGame(() => {
  557. this.send_data(C2S_FINISH, p.Id);
  558. });
  559. }
  560. } else if (this.inTeam) {
  561. this.team.doSendChat(msg => {
  562. if (!msg) return;
  563. this.send_data(C2S_TALK, msg);
  564. });
  565. }
  566. }
  567. dirtyDataCheck() {
  568. if (!this.inRoom) return;
  569. this.room.own.doDirtyData(dirty => {
  570. this.send_data(C2S_UPDATE_USER_GAMEDATA, {
  571. userKey: this.room.own.Id,
  572. data: dirty
  573. });
  574. });
  575. if (!this.room.isHost) return;
  576. this._room.doDirtyData(dirty => {
  577. this.send_data(C2S_UPDATE_ROOM_GAMEDATA, dirty);
  578. });
  579. const ais = this.room.all;
  580. for (let i = 0; i < ais.length; i++) {
  581. const ai = ais[i];
  582. ai.doDirtyData(dirty => {
  583. this.send_data(C2S_UPDATE_USER_GAMEDATA, {
  584. userKey: ai.Id,
  585. data: dirty
  586. });
  587. });
  588. }
  589. }
  590. /**
  591. * 分享队伍信息,邀请进队
  592. * @param extend (可选)分享数据
  593. * @param title 分享显示标题
  594. * @param imageUrl 分享显示图片
  595. */
  596. shareNetTeam(title, imageUrl, extend) {
  597. if (!this.inTeam) return;
  598. chsdk.shareAppMessage(title, '', imageUrl, JSON.stringify({
  599. type: 'NetTeam',
  600. pw: this.team.Password,
  601. extends: extend
  602. }));
  603. }
  604. /**
  605. *获取从好友分享的net数据进入游戏的数据
  606. */
  607. getShareNetTeam() {
  608. const query = chsdk.getQuery();
  609. if (!query) return null;
  610. const message = query.message;
  611. if (!message) return null;
  612. const data = JSON.parse(message);
  613. if (!data) return null;
  614. if (data.type != 'NetTeam') return null;
  615. query.message = null;
  616. return {
  617. password: data.pw,
  618. extend: data.extends
  619. };
  620. }
  621. });
  622. _cclegacy._RF.pop();
  623. _crd = false;
  624. }
  625. };
  626. });
  627. //# sourceMappingURL=0094603a0536c0222b1cbb5d5cffe19fbc2859c7.js.map