declare const wx: any; export type ServerTarget = "production" | "test"; /** Fixed for the lifetime of the JS process. A saved choice only affects the next launch. */ export default class ServerEnvironment { private static readonly preferenceKey = "matchmaster:nextServer:v1"; private static active: ServerTarget = null; private static switchAllowed = false; static current(): ServerTarget { if (this.active !== null) return this.active; try { const version = typeof wx !== "undefined" && wx.getAccountInfoSync?.().miniProgram?.envVersion; this.switchAllowed = version === "develop" || version === "trial"; } catch (_) { this.switchAllowed = false; } this.active = this.switchAllowed ? this.readChoice() || "test" : "production"; return this.active; } static canSwitch(): boolean { this.current(); return this.switchAllowed; } static next(): ServerTarget { return this.canSwitch() ? this.readChoice() || "test" : "production"; } static saveNext(target: ServerTarget): void { if (!this.canSwitch() || (target !== "production" && target !== "test")) { throw new Error("当前版本不允许切换服务器"); } cc.sys.localStorage.setItem(this.preferenceKey, target); if (cc.sys.localStorage.getItem(this.preferenceKey) !== target) { throw new Error("服务器选择保存失败,请重试"); } } private static readChoice(): ServerTarget { try { const value = cc.sys.localStorage.getItem(this.preferenceKey); return value === "production" || value === "test" ? value : null; } catch (_) { return null; } } static storageKey(key: string): string { // Device preferences and the existing standalone web preview retain their keys. if (key === "music" || typeof wx === "undefined") return key; // Unscoped legacy data remains on disk as a backup, never uploaded to an unknown server. return "matchmaster:server:v1:" + this.current() + ":" + key; } }