// // SubGameDirectoryStore.swift // ylgamehall // // 子游戏目录名持久化映射:H5 传的 Gamedirectory(也是 gameStart 同名)→ 实际沙盒 // 目录名。与 daoqi msext gameController.m:1414 / 2183-2188 等价: // - 首次安装:actualDir = directory,写入 NSUserDefaults // - 每次 zip 升级(远端 game_version > 本地 version.xml):actualDir 末尾追加 "1", // 新版本解压到新目录,旧目录残留在沙盒(msext 同款"追加而非原子替换"策略) // // 存储约定:UserDefaults key = "ylgh.subGameDir.",value = 实际目录名 // import Foundation /// UserDefaults 线程安全,所有方法 nonisolated 让 actor / MainActor / 后台线程都能直接调用。 public enum SubGameDirectoryStore { private static let keyPrefix = "ylgh.subGameDir." /// 当前实际目录名。已持久化 → 返回持久化值;未持久化 → 返回 directory 本身 /// (对应 msext NSUserDefaults 缺 key 时 gamefilepath = gamename 的默认)。 nonisolated public static func current(forKey directory: String) -> String { UserDefaults.standard.string(forKey: keyPrefix + directory) ?? directory } /// 触发升级:末尾追加 "1",写回 UserDefaults,返回新值。 /// msext gameController.m:1414 等价 `gamefilepath = [NSString stringWithFormat:@"%@1", gamefilepath]`。 @discardableResult nonisolated public static func advance(forKey directory: String) -> String { let next = current(forKey: directory) + "1" UserDefaults.standard.set(next, forKey: keyPrefix + directory) return next } /// 首次访问时把 directory 自身写入(与 msext gameController.m:2187 /// SaveDefaultInfo 等价)。后续 advance 会基于此值追加。 nonisolated public static func saveInitialIfNeeded(forKey directory: String) { let k = keyPrefix + directory if UserDefaults.standard.string(forKey: k) == nil { UserDefaults.standard.set(directory, forKey: k) } } }