Files
AIGame/AIClient/AgentScripts/VerifyPreviewDeployment.cs
T

120 lines
7.0 KiB
C#

using System;
using System.IO;
using System.Linq;
using System.Reflection;
using HotUpdate.UI;
using Newtonsoft.Json;
using UnityEditor;
using UnityEngine;
using UnityEngine.UI;
using Object = UnityEngine.Object;
public static class VerifyPreviewDeployment
{
static string Output => Path.GetFullPath(Path.Combine(Application.dataPath, "../../Tools/output/server_release"));
const string MaterialPath = "Assets/Bundles/UI/Material/HomeExplorerCutout.mat";
public static string PackedMaterial()
{
string art = Path.GetFullPath(Path.Combine(Application.dataPath, "../../Tools/cdn_root/wechat/1.0.0/Art"));
var shaders = AssetBundle.LoadFromFile(Directory.GetFiles(art, "unityshaders_*.bundle").Single());
var bundle = AssetBundle.LoadFromFile(Directory.GetFiles(art, "share_assets_bundles_ui_material_*.bundle").Single());
Check(bundle != null, "Material bundle unavailable");
try
{
var material = bundle.LoadAllAssets<Material>().Single(m => m.name == "HomeExplorerCutout");
var saved = new SerializedObject(material).FindProperty("m_SavedProperties.m_Colors");
var key = Color.clear;
for (int i = 0; i < saved.arraySize; i++)
{
var pair = saved.GetArrayElementAtIndex(i);
if (pair.FindPropertyRelative("first").stringValue == "_Key") key = pair.FindPropertyRelative("second").colorValue;
}
Directory.CreateDirectory(Output);
string json = JsonConvert.SerializeObject(new { shippedKey = new[] { key.r, key.g, key.b },
sourceKey = AssetDatabase.LoadAssetAtPath<Material>(MaterialPath).GetColor("_Key").ToString(),
hardcodedMagentaMismatch = Vector4.Distance(key, Color.magenta) > .5f });
File.WriteAllText(Path.Combine(Output, "packed_preview.json"), json);
return json;
}
finally { bundle.Unload(true); if (shaders != null) shaders.Unload(true); }
}
public static string StartLegacyPreview()
{
Check(EditorApplication.isPlaying, "Play isolated scene first");
var holder = new GameObject("LegacyPreviewHolder"); holder.SetActive(false);
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/Bundles/UI/Prefab/UI_MainHUD.prefab");
var hud = Object.Instantiate(prefab, holder.transform, false); hud.name = "LegacyPreviewHUD";
var raw = hud.transform.Find("ExplorerStage").GetComponent<RawImage>();
var material = new Material(AssetDatabase.LoadAssetAtPath<Material>(MaterialPath));
material.SetColor("_Key", new Color(.07f,.02f,.09f,1)); raw.material = material;
holder.SetActive(true);
var camera = new GameObject("LegacyPreviewCamera", typeof(Camera)).GetComponent<Camera>();
camera.clearFlags = CameraClearFlags.SolidColor; camera.backgroundColor = Color.gray; camera.cullingMask = 0;
return "Started authored HUD with shipped legacy material key";
}
public static string RuntimeStatus() => JsonConvert.SerializeObject(new {
roots = Object.FindObjectsOfType<HomeExplorerPresenter>(true).Select(p => new { p.name,p.enabled,
active=p.gameObject.activeInHierarchy,p.Ready,material=p.GetComponent<RawImage>()?.material?.name,
shader=p.GetComponent<RawImage>()?.material?.shader?.name,
supported=p.GetComponent<RawImage>()?.material?.shader?.isSupported }).ToArray(),
cameras=Object.FindObjectsOfType<Camera>().Select(c=>c.name).ToArray()
});
public static string CheckAndCapture()
{
var hud = GameObject.Find("LegacyPreviewHUD"); var raw = hud.transform.Find("ExplorerStage").GetComponent<RawImage>();
var presenter = raw.GetComponent<HomeExplorerPresenter>();
Check(presenter != null && presenter.Ready, "Preview not ready");
var previewCamera = (Camera)typeof(HomeExplorerPresenter).GetField("_camera", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(presenter);
Check(Vector4.Distance(previewCamera.backgroundColor, raw.material.GetColor("_Key")) < .001f, "Camera clear differs from shipped material");
VerifyDiscard(raw.material);
var canvas = hud.GetComponent<Canvas>(); var oldMode = canvas.renderMode; var oldCamera = canvas.worldCamera;
var camera = GameObject.Find("LegacyPreviewCamera").GetComponent<Camera>();
var target = new RenderTexture(540, 960, 24); var pixels = new Texture2D(540, 960, TextureFormat.RGB24, false);
var previous = RenderTexture.active;
try
{
camera.targetTexture = target; camera.cullingMask = 1 << LayerMask.NameToLayer("UI");
canvas.renderMode = RenderMode.ScreenSpaceCamera; canvas.worldCamera = camera; canvas.planeDistance = 1;
Canvas.ForceUpdateCanvases(); camera.Render(); RenderTexture.active = target;
pixels.ReadPixels(new Rect(0,0,540,960),0,0); pixels.Apply(); Directory.CreateDirectory(Output);
File.WriteAllBytes(Path.Combine(Output,"legacy_preview.png"),pixels.EncodeToPNG());
}
finally
{
RenderTexture.active = previous; camera.targetTexture = null; canvas.renderMode = oldMode; canvas.worldCamera = oldCamera;
target.Release(); Object.Destroy(target); Object.Destroy(pixels);
}
return "PASS: legacy shipped material and camera match; GPU removes the key, foreground retained; screenshot captured";
}
static void VerifyDiscard(Material material)
{
var input = new Texture2D(2,2,TextureFormat.RGBA32,false,true);
var output = new RenderTexture(8,8,0,RenderTextureFormat.ARGB32,RenderTextureReadWrite.Linear);
var read = new Texture2D(8,8,TextureFormat.RGBA32,false,true); var previous = RenderTexture.active;
try
{
foreach (var key in new[] { new Color(.07f,.02f,.09f,1), Color.magenta })
{
var test = new Material(material); test.SetColor("_Key",key);
try
{
input.SetPixels(Enumerable.Repeat(key,4).ToArray()); input.Apply(); output.Create();
RenderTexture.active = output; GL.Clear(true,true,Color.cyan); Graphics.Blit(input,output,test);
RenderTexture.active = output; read.ReadPixels(new Rect(0,0,8,8),0,0);read.Apply();
var color = read.GetPixel(4,4); Check(color.r < .05f && color.g > .95f && color.b > .95f,"GPU did not discard background");
Graphics.Blit(Texture2D.whiteTexture,output,test); RenderTexture.active = output;
read.ReadPixels(new Rect(0,0,8,8),0,0);read.Apply(); Check(read.GetPixel(4,4).r > .95f,"GPU discarded foreground");
}
finally { Object.Destroy(test); }
}
}
finally { RenderTexture.active = previous; output.Release(); Object.Destroy(input); Object.Destroy(output); Object.Destroy(read); }
}
static void Check(bool pass,string message) { if (!pass) throw new Exception(message); }
}