import ServerEnvironment, { ServerTarget } from "./ServerEnvironment"; import ClientUpdate from "./ClientUpdate"; import Utils from "../Pay/Utils"; import DailyTaskProgressTracker from "../Task/DailyTaskProgressTracker"; import { MiniGameSdk } from "../../Sdk/MiniGameSdk"; declare const wx: any; /** Home-only, full-process switch. Never changes the active transport or storage scope. */ export default class ServerSwitch { static inProgress = false; private static confirming = false; static choose(target: ServerTarget, refresh: () => void): void { if (!ServerEnvironment.canSwitch() || this.inProgress || this.confirming || ClientUpdate.blocked || cc.director.getScene()?.name !== "HomeScene") return; if (target === ServerEnvironment.current() && target === ServerEnvironment.next()) return; const cancelPending = target === ServerEnvironment.current(); this.confirming = true; wx.showModal({ title: cancelPending ? "取消服务器切换" : "切换服务器", content: cancelPending ? "取消待生效的切换,继续使用当前服务器?" : `将切换到${target === "test" ? "测试服" : "正式服"}并重启游戏,是否继续?`, confirmText: cancelPending ? "确认取消" : "重启切换", success: result => { if (!result.confirm) return; if (cancelPending) { try { ServerEnvironment.saveNext(target); refresh(); } catch (_) { MiniGameSdk.API.showToast("服务器选择保存失败,请重试"); } } else { this.perform(target, refresh); } }, complete: () => { this.confirming = false; }, }); } private static async perform(target: ServerTarget, refresh: () => void): Promise { const scene = cc.director.getScene(); if (scene?.name !== "HomeScene" || this.inProgress || ClientUpdate.blocked) return; this.inProgress = true; let saved = false; let restartTimer: any = null; scene.pauseSystemEvents(true); try { wx.showLoading({ title: "正在保存进度", mask: true }); DailyTaskProgressTracker.stopOnline(); DailyTaskProgressTracker.flushNow(); await Utils.prepareServerSwitch(); if (cc.director.getScene() !== scene) throw new Error("页面已变化,请返回首页重试"); ServerEnvironment.saveNext(target); saved = true; refresh(); wx.showLoading({ title: "正在重启", mask: true }); // A real restart destroys this process. If it stays alive, keep the old session usable. await new Promise((_, reject) => { const failed = () => reject(new Error("自动重启失败")); restartTimer = setTimeout(failed, 8000); MiniGameSdk.API.reboot(undefined, failed); }); } catch (error) { clearTimeout(restartTimer); Utils.cancelServerSwitch(); this.inProgress = false; if (ClientUpdate.blocked) { ClientUpdate.onShow(); return; } wx.hideLoading(); if (cc.isValid(scene)) scene.resumeSystemEvents(true); cc.game.resume(); cc.audioEngine.resumeAll(); DailyTaskProgressTracker.startOnline(); refresh(); wx.showModal({ title: saved ? "请重启游戏" : "暂未切换", content: saved ? "选择已保存,完整重启后生效。当前仍连接原服务器,请重试重启或退出后重新进入。" : (error?.message || "存档保存失败,请稍后重试"), confirmText: saved ? "重试重启" : "知道了", cancelText: "稍后重启", showCancel: saved, success: result => { if (saved && result.confirm) this.perform(target, refresh); }, }); } } }