using System; using System.IO; using System.Linq; using System.Text.RegularExpressions; using AOT.Editor.WeChat; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using UnityEngine; using WeChatWASM; public static class VerifyWeChatExport { public static string RefreshAndVerify() { string root = Path.GetFullPath(Path.Combine(Application.dataPath, "../Build/WeChat/Base")); string output = Path.GetFullPath(Path.Combine(Application.dataPath, "../../Tools/output/wechat_export")); Directory.CreateDirectory(output); foreach (string name in new[] { "project.config.json", "minigame/project.config.json", "minigame/game.js", "base-package-report.txt" }) { string source = Path.Combine(root, name); string backup = Path.Combine(output, "before_" + name.Replace('/', '_')); if (File.Exists(source) && !File.Exists(backup)) File.Copy(source, backup); } var resourceState = Snapshot(Path.Combine(root, "webgl")); string[] privatePaths = { Path.Combine(root, "project.private.config.json"), Path.Combine(root, "minigame/project.private.config.json") }; string[] privateBefore = privatePaths.Select(p => File.Exists(p) ? File.ReadAllText(p) : null).ToArray(); JObject rootBefore = JObject.Parse(File.ReadAllText(Path.Combine(root, "project.config.json"))); JObject miniBefore = JObject.Parse(File.ReadAllText(Path.Combine(root, "minigame/project.config.json"))); string expectedAppid = (string)miniBefore["appid"]; if (string.IsNullOrWhiteSpace(expectedAppid)) expectedAppid = (string)rootBefore["appid"]; string result = ExportWeChatBasePackage.RefreshExportedConfig(); Require(result.StartsWith("ok", StringComparison.Ordinal), result); JObject config = JObject.Parse(File.ReadAllText(Path.Combine(root, "project.config.json"))); Require((string)config["miniprogramRoot"] == "minigame/" && (string)config["compileType"] == "game", "Invalid project root"); Require(File.Exists(Path.Combine(root, (string)config["miniprogramRoot"], "game.json")), "game.json cannot be resolved"); Require((string)config["appid"] == expectedAppid, "AppID was changed"); Require(config.SelectToken("setting.babelSetting.ignore").Values().Contains("webgl.wasm.framework.unityweb.js"), "SDK Babel exclusion missing"); Require(config.SelectToken("packOptions.ignore").Any(t => (string)t["value"] == ".symbols.unityweb"), "Symbol exclusion missing"); string gamePath = Path.Combine(root, "minigame/game.js"); string game = File.ReadAllText(gamePath); string cdn = WXConvertCore.config.ProjectConf.CDN; Require(game.Contains("DATA_CDN: " + JsonConvert.SerializeObject(cdn)), "SDK/export CDN mismatch"); Match md5 = Regex.Match(game, @"DATA_FILE_MD5:\s*'([0-9a-f]+)'"); string dataName = md5.Groups[1].Value + ".webgl.data.unityweb.bin.txt"; string dataPath = Path.Combine(root, "webgl", dataName); Require(md5.Success && File.Exists(dataPath), "Missing startup data file"); for (int i = 0; i < privatePaths.Length; ++i) Require((File.Exists(privatePaths[i]) ? File.ReadAllText(privatePaths[i]) : null) == privateBefore[i], "Private config changed"); Require(resourceState.SequenceEqual(Snapshot(Path.Combine(root, "webgl"))), "WebGL resources changed"); string configText = config.ToString(); Require(ExportWeChatBasePackage.RefreshExportedConfig().StartsWith("ok"), "Second refresh failed"); Require(JObject.Parse(File.ReadAllText(Path.Combine(root, "project.config.json"))).ToString() == configText && File.ReadAllText(gamePath) == game, "Config refresh was not idempotent"); string report = JsonConvert.SerializeObject(new { passed = true, noBuild = true, cdn, startupData = dataPath, startupUrl = cdn + dataName, bytes = new FileInfo(dataPath).Length, appidPreserved = true, privateConfigsPreserved = true, resourceFilesPreserved = true, devtoolsSourceResolved = true, sdkExclusionsPreserved = true, idempotent = true }, Formatting.Indented); File.WriteAllText(Path.Combine(output, "configuration.json"), report); return report; } static string[] Snapshot(string path) => Directory.GetFiles(path, "*", SearchOption.AllDirectories) .OrderBy(p => p, StringComparer.Ordinal).Select(p => { var file = new FileInfo(p); return p + ":" + file.Length + ":" + file.LastWriteTimeUtc.Ticks; }).ToArray(); static void Require(bool condition, string message) { if (!condition) throw new Exception(message); } }