84 lines
4.0 KiB
TypeScript
84 lines
4.0 KiB
TypeScript
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<void> {
|
|
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<void>((_, 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); },
|
|
});
|
|
}
|
|
}
|
|
}
|