import { _decorator, Component, Director, director, Node } from 'cc'; import { gameNet, lobbyNet, NetGameServer, NetLobbyServer } from './NetGameServer'; import { WebsocketClient } from './WebsocketClient'; import { GameSceneUtil } from './GameSceneUtil'; import { UserMgr } from './UserMgr'; import { SceneDef } from '../../scripts/SceneDef'; import { RoomMgr } from './RoomMgr'; import { EDITOR, PREVIEW } from 'cc/env'; import { GameMgr } from './GameMgr'; import { LobbyMgr } from './LobbyMgr'; const { ccclass, property } = _decorator; //主动添加到所有场景。 director.on(Director.EVENT_AFTER_SCENE_LAUNCH, () => { if (EDITOR && PREVIEW || !EDITOR) { if (director.getScene().getChildByName('NetworkReconnector')) { throw new Error('NetworkReconnector can only be added by code, please remove from scene:.' + director.getScene().name); } let node = new Node('NetworkReconnector'); node.addComponent(NetworkReconnector); director.getScene().addChild(node); } }); @ccclass('NetworkReconnector') export class NetworkReconnector extends Component { start() { this.schedule(() => { this.checkNetwork(); }, 1.0); } public get isInGame() { return director.getScene().name.indexOf('game_') == 0; } private _tryTimes = 0; needReconnect(v: { code?: number, reason?: string, isManual?: boolean }) { if(!v){ return true; } if (v.reason == 'login_to_other') { this.enabled = false; tgx.UIAlert.show('Account is logged in on other devices!').onClick(() => { tgx.SceneUtil.loadScene(SceneDef.LOGIN); }); return false; } if (v.reason == 'normal' || v.reason == 'room_closed') { return false; } if (v.isManual) { return false; } return true; } private _isReconnecting = false; private checkNetwork(): void { if (this.isInGame) { if (gameNet.conn && !this._isReconnecting && !gameNet.conn.isConnected) { if (this.needReconnect(gameNet.lastDisconnectReason)) { this._isReconnecting = true; this.enabled = false; this.tryReconnect(gameNet); } } } else { if(lobbyNet.type != 'http'){ let net = lobbyNet as NetLobbyServer; if (net.conn && !this._isReconnecting && !net.conn.isConnected) { if (this.needReconnect(net.lastDisconnectReason)) { this._isReconnecting = true; this.enabled = false; this.tryReconnect(net); } } } } } private async tryReconnect(net: WebsocketClient) { this._tryTimes++; if (this._tryTimes > 10) { tgx.UIWaiting.hide(); this.enabled = false; tgx.UIAlert.show('Please check the network and login again!').onClick(() => { tgx.SceneUtil.loadScene(SceneDef.LOGIN); }); return; } let isSucc = false; if (this.isInGame) { if (net == gameNet) { console.log('game reconnecting.'); tgx.UIWaiting.show('Reconnecting...'); let ret = await GameSceneUtil.inst.enterGame(gameNet.authParams); if (ret.isSucc) { isSucc = true; } else if (ret.err.code == 'ROOM_NOT_EXISTS') { RoomMgr.inst.backToLobby(); return; } } } else { console.log('lobby reconnecting.'); tgx.UIWaiting.show('Reconnecting...'); let ret = await net.ensureConnected(); isSucc = ret.isSucc; /** * @en if already login success, need to verify again * @zh 如果已经登录成功,则需要再次验证 */ if (ret.isSucc) { let ret1 = await LobbyMgr.inst.doAuth(); if (!ret1.isSucc) { tgx.UIWaiting.hide(); this.enabled = false; tgx.UIAlert.show("请检查网络,重新登录!").onClick(bOK => { tgx.SceneUtil.loadScene(SceneDef.LOGIN); }); return; } } } /** * @en if re-connect failed, try again after 3s * @zh 如果没有重连成功,则一定时间后再次尝试 */ if (!isSucc) { setTimeout(() => { this.tryReconnect(net); }, 3000); } } }