Ship the WeChat hot-update catalogs and the camp, TideWhale T2, UI atlas, and animation-lab work.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,8 +1,12 @@
|
||||
#if UNITY_EDITOR
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using HybridCLR.Editor.Installer;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using WeChatWASM;
|
||||
@@ -16,7 +20,7 @@ namespace AOT.Editor.WeChat
|
||||
{
|
||||
const string BootScene = "Assets/Scenes/Boot.unity";
|
||||
const string RelativeDst = "Build/WeChat/Base";
|
||||
const string DataCdn = "https://www.xworld.ren/wechat/1.0.0/minigame/";
|
||||
const string DataCdn = "https://www.xworld.ren/game/Friends/webgl/";
|
||||
const int ShellHeapMb = 496;
|
||||
const string ResumeKey = "AIGame.WeChat.ExportBase.Resume";
|
||||
|
||||
@@ -92,6 +96,9 @@ namespace AOT.Editor.WeChat
|
||||
return Fail("微信转换失败 " + error + ",详见 Console");
|
||||
|
||||
string dst = Path.GetFullPath(Path.Combine(Application.dataPath, "..", RelativeDst));
|
||||
string projectError = PrepareDevToolsProject(dst);
|
||||
if (projectError != null)
|
||||
return Fail(projectError);
|
||||
string summary = WriteReport(dst);
|
||||
string minigame = Path.Combine(dst, "minigame");
|
||||
string result = "ok minigame=" + minigame + " " + summary;
|
||||
@@ -99,6 +106,94 @@ namespace AOT.Editor.WeChat
|
||||
return result;
|
||||
}
|
||||
|
||||
[MenuItem("AIGame/WeChat/Repair Exported DevTools Project")]
|
||||
public static string RepairExportedProject()
|
||||
{
|
||||
string dst = Path.GetFullPath(Path.Combine(Application.dataPath, "..", RelativeDst));
|
||||
string error = PrepareDevToolsProject(dst);
|
||||
if (error != null) return Fail(error);
|
||||
string result = "ok devtools=" + dst + " source=minigame/ " + WriteReport(dst);
|
||||
Debug.Log("[AIGame] " + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
[MenuItem("AIGame/WeChat/Refresh Exported Config (No Build)")]
|
||||
public static string RefreshExportedConfig()
|
||||
{
|
||||
string dst = Path.GetFullPath(Path.Combine(Application.dataPath, "..", RelativeDst));
|
||||
string gamePath = Path.Combine(dst, "minigame", "game.js");
|
||||
if (!File.Exists(gamePath)) return Fail("尚未导出小游戏,请先执行 Export Base Package");
|
||||
string game = File.ReadAllText(gamePath);
|
||||
var cdnPattern = new Regex(@"\bDATA_CDN\s*:\s*(['""])[^'""]*\1");
|
||||
if (cdnPattern.Matches(game).Count != 1)
|
||||
return Fail("无法识别导出 game.js 的 DATA_CDN,未修改配置");
|
||||
string error = ApplyBaseConfig();
|
||||
if (error != null) return Fail(error);
|
||||
error = PrepareDevToolsProject(dst);
|
||||
if (error != null) return Fail(error);
|
||||
string updated = cdnPattern.Replace(game, _ => "DATA_CDN: " + JsonConvert.SerializeObject(DataCdn), 1);
|
||||
if (updated != game) File.WriteAllText(gamePath, updated, new UTF8Encoding(false));
|
||||
string result = "ok config refreshed (no WebGL build) " + WriteReport(dst);
|
||||
Debug.Log("[AIGame] " + result);
|
||||
return result;
|
||||
}
|
||||
|
||||
[MenuItem("AIGame/WeChat/Open Exported MiniGame Folder")]
|
||||
public static void OpenExportedMiniGameFolder()
|
||||
{
|
||||
string game = Path.GetFullPath(Path.Combine(Application.dataPath, "..", RelativeDst, "minigame", "game.json"));
|
||||
if (!File.Exists(game))
|
||||
{
|
||||
Fail("尚未导出小游戏,请先执行 Export Base Package");
|
||||
return;
|
||||
}
|
||||
EditorUtility.RevealInFinder(game);
|
||||
}
|
||||
|
||||
/// <summary>Allow importing either the export container or its minigame directory.</summary>
|
||||
public static string PrepareDevToolsProject(string dst)
|
||||
{
|
||||
string mini = Path.Combine(dst, "minigame");
|
||||
foreach (string required in new[] { "game.json", "game.js", "project.config.json" })
|
||||
if (!File.Exists(Path.Combine(mini, required)))
|
||||
return "小游戏导出不完整,缺少 " + Path.Combine(mini, required);
|
||||
|
||||
try
|
||||
{
|
||||
JObject.Parse(File.ReadAllText(Path.Combine(mini, "game.json")));
|
||||
string miniConfigPath = Path.Combine(mini, "project.config.json");
|
||||
string rootConfigPath = Path.Combine(dst, "project.config.json");
|
||||
JObject miniConfig = JObject.Parse(File.ReadAllText(miniConfigPath));
|
||||
JObject rootConfig = File.Exists(rootConfigPath)
|
||||
? JObject.Parse(File.ReadAllText(rootConfigPath)) : new JObject();
|
||||
string appid = (string)miniConfig["appid"];
|
||||
if (string.IsNullOrWhiteSpace(appid)) appid = (string)rootConfig["appid"];
|
||||
|
||||
// Carry SDK compiler options and symbol exclusions to the parent entry.
|
||||
// Keep other existing user fields and combine package ignore rules.
|
||||
rootConfig.Merge(miniConfig, new JsonMergeSettings { MergeArrayHandling = MergeArrayHandling.Union });
|
||||
rootConfig["compileType"] = "game";
|
||||
rootConfig["miniprogramRoot"] = "minigame/";
|
||||
if (!string.IsNullOrWhiteSpace(appid))
|
||||
{
|
||||
rootConfig["appid"] = appid;
|
||||
if (string.IsNullOrWhiteSpace((string)miniConfig["appid"]))
|
||||
{
|
||||
miniConfig["appid"] = appid;
|
||||
File.WriteAllText(miniConfigPath, miniConfig.ToString(Formatting.Indented), new UTF8Encoding(false));
|
||||
}
|
||||
}
|
||||
string rootJson = rootConfig.ToString(Formatting.Indented);
|
||||
if (!File.Exists(rootConfigPath) || File.ReadAllText(rootConfigPath) != rootJson)
|
||||
File.WriteAllText(rootConfigPath, rootJson, new UTF8Encoding(false));
|
||||
return null;
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
return "小游戏项目配置失败: " + exception.Message;
|
||||
}
|
||||
}
|
||||
|
||||
static string ValidateBootOnly()
|
||||
{
|
||||
if (!File.Exists(BootScene))
|
||||
@@ -167,6 +262,14 @@ namespace AOT.Editor.WeChat
|
||||
text.AppendLine("minigameBytes: " + miniBytes);
|
||||
text.AppendLine("dataBytes: " + dataBytes);
|
||||
text.AppendLine("devtools: " + mini);
|
||||
text.AppendLine("devtoolsContainer: " + dst + " (miniprogramRoot=minigame/)");
|
||||
text.AppendLine("uploadSource: " + Path.Combine(dst, "webgl"));
|
||||
text.AppendLine("uploadContentsTo: " + DataCdn);
|
||||
text.AppendLine("uploadNote: copy the CONTENTS of webgl, preserving relative paths; export does not upload to the server.");
|
||||
string webgl = Path.Combine(dst, "webgl");
|
||||
if (Directory.Exists(webgl))
|
||||
foreach (string resource in Directory.GetFiles(webgl, "*.webgl.data.unityweb.bin.*"))
|
||||
text.AppendLine("startupData: " + Path.GetFileName(resource) + " -> " + DataCdn + Path.GetFileName(resource));
|
||||
if (Directory.Exists(mini))
|
||||
{
|
||||
text.AppendLine("largest:");
|
||||
|
||||
Reference in New Issue
Block a user