safety snapshot: recover geo importers and current quest/server state
This commit is contained in:
167
Assets/Scripts/Debug/RuntimeBootProbe.cs
Normal file
167
Assets/Scripts/Debug/RuntimeBootProbe.cs
Normal file
@@ -0,0 +1,167 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using UnityEngine;
|
||||
using UnityEngine.SceneManagement;
|
||||
|
||||
[DisallowMultipleComponent]
|
||||
public sealed class RuntimeBootProbe : MonoBehaviour
|
||||
{
|
||||
[Header("Optional References")]
|
||||
[SerializeField] private GameObject hudRoot;
|
||||
[SerializeField] private GeoTileAddressablesLoader geoTileLoader;
|
||||
[SerializeField] private Transform expectedPlayer;
|
||||
|
||||
[Header("Probe Settings")]
|
||||
[SerializeField] private bool logOnAwake = true;
|
||||
[SerializeField] private bool logOnStart = true;
|
||||
[SerializeField] private bool logAfterDelay = true;
|
||||
[SerializeField] private float delayedLogSeconds = 2.0f;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (logOnAwake)
|
||||
Dump("Awake");
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (logOnStart)
|
||||
Dump("Start");
|
||||
|
||||
if (logAfterDelay && delayedLogSeconds > 0.0f)
|
||||
Invoke(nameof(DumpDelayed), delayedLogSeconds);
|
||||
}
|
||||
|
||||
private void DumpDelayed()
|
||||
{
|
||||
Dump("Delayed");
|
||||
}
|
||||
|
||||
private void Dump(string phase)
|
||||
{
|
||||
var sb = new StringBuilder(1024);
|
||||
sb.Append("[RuntimeBootProbe] ").Append(phase).Append(" ");
|
||||
sb.Append("activeScene=").Append(SceneManager.GetActiveScene().name).Append(" ");
|
||||
sb.Append("loadedScenes=").Append(SceneManager.sceneCount).Append(" ");
|
||||
sb.Append("persistentDataPath=").Append(Application.persistentDataPath).Append(" ");
|
||||
|
||||
if (hudRoot == null)
|
||||
{
|
||||
sb.Append("hudRoot=null ");
|
||||
}
|
||||
else
|
||||
{
|
||||
sb.Append("hudRoot.activeInHierarchy=").Append(hudRoot.activeInHierarchy).Append(" ");
|
||||
sb.Append("hudRoot.activeSelf=").Append(hudRoot.activeSelf).Append(" ");
|
||||
}
|
||||
|
||||
if (expectedPlayer == null)
|
||||
{
|
||||
sb.Append("expectedPlayer=null ");
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector3 p = expectedPlayer.position;
|
||||
sb.Append("expectedPlayer.pos=(")
|
||||
.Append(p.x.ToString("F2")).Append(",")
|
||||
.Append(p.y.ToString("F2")).Append(",")
|
||||
.Append(p.z.ToString("F2")).Append(") ");
|
||||
}
|
||||
|
||||
if (geoTileLoader == null)
|
||||
{
|
||||
sb.Append("geoTileLoader=null ");
|
||||
Debug.Log(sb.ToString());
|
||||
return;
|
||||
}
|
||||
|
||||
bool loaderEnabled = geoTileLoader.enabled && geoTileLoader.gameObject.activeInHierarchy;
|
||||
sb.Append("geoTileLoader.enabled=").Append(loaderEnabled).Append(" ");
|
||||
|
||||
string tileBundleFolderName = ReadPrivateField(geoTileLoader, "tileBundleFolderName", "TileBundles");
|
||||
string manifestFileName = ReadPrivateField(geoTileLoader, "manifestFileName", "TileManifest.json");
|
||||
string buildingManifestFileName = ReadPrivateField(geoTileLoader, "buildingManifestFileName", "TileBuildingsManifest.json");
|
||||
string buildTargetFolderOverride = ReadPrivateField(geoTileLoader, "buildTargetFolderOverride", "");
|
||||
|
||||
string buildTargetFolder = string.IsNullOrWhiteSpace(buildTargetFolderOverride)
|
||||
? GetBuildTargetFolderName()
|
||||
: buildTargetFolderOverride;
|
||||
|
||||
string basePath = Path.Combine(Application.persistentDataPath, tileBundleFolderName, buildTargetFolder);
|
||||
string manifestPath = Path.Combine(basePath, manifestFileName);
|
||||
string buildingsManifestPath = Path.Combine(basePath, buildingManifestFileName);
|
||||
string catalogPath = ResolveCatalogPath(manifestPath);
|
||||
|
||||
sb.Append("basePath=").Append(basePath).Append(" ");
|
||||
sb.Append("manifestExists=").Append(File.Exists(manifestPath)).Append(" ");
|
||||
sb.Append("buildingsManifestExists=").Append(File.Exists(buildingsManifestPath)).Append(" ");
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(catalogPath))
|
||||
sb.Append("catalogExists=").Append(File.Exists(catalogPath)).Append(" ");
|
||||
else
|
||||
sb.Append("catalogExists=unknown ");
|
||||
|
||||
Debug.Log(sb.ToString());
|
||||
}
|
||||
|
||||
private static string ReadPrivateField(GeoTileAddressablesLoader loader, string fieldName, string fallback)
|
||||
{
|
||||
try
|
||||
{
|
||||
FieldInfo fi = typeof(GeoTileAddressablesLoader).GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
if (fi == null)
|
||||
return fallback;
|
||||
|
||||
object value = fi.GetValue(loader);
|
||||
return value as string ?? fallback;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return fallback;
|
||||
}
|
||||
}
|
||||
|
||||
private static string ResolveCatalogPath(string manifestPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(manifestPath))
|
||||
return null;
|
||||
|
||||
string json = File.ReadAllText(manifestPath);
|
||||
TileManifest manifest = JsonUtility.FromJson<TileManifest>(json);
|
||||
if (manifest == null || string.IsNullOrWhiteSpace(manifest.catalogFile))
|
||||
return null;
|
||||
|
||||
return Path.Combine(Path.GetDirectoryName(manifestPath) ?? string.Empty, manifest.catalogFile);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetBuildTargetFolderName()
|
||||
{
|
||||
switch (Application.platform)
|
||||
{
|
||||
case RuntimePlatform.Android:
|
||||
return "Android";
|
||||
case RuntimePlatform.IPhonePlayer:
|
||||
return "iOS";
|
||||
case RuntimePlatform.WindowsPlayer:
|
||||
case RuntimePlatform.WindowsEditor:
|
||||
return "Windows";
|
||||
case RuntimePlatform.OSXPlayer:
|
||||
case RuntimePlatform.OSXEditor:
|
||||
return "macOS";
|
||||
case RuntimePlatform.LinuxPlayer:
|
||||
case RuntimePlatform.LinuxEditor:
|
||||
return "Linux";
|
||||
default:
|
||||
return "Android";
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user