Files
daluandou/.codely.packages/cn.tuanjie.codely.bridge@1.0.85-785dea6a/Editor/Bridge/Helpers/BridgeUpdateRestartPrompt.cs
T
huadexuan 53d95802e5 ```
feat(gameplay): 更新单位属性和材质配置

- 调整多个单位的基础生命值和攻击力数值平衡
- 修改CoreBattleGround材质的纹理缩放比例
- 更新地砖材质颜色为白色
- 优化纹理资源设置,调整最大纹理尺寸并添加PlayableAds平台支持
- 修复弓箭手技能目标查找逻辑,改用统一的敌人检测方法
- 为水晶矿添加中立阵营设置和光球视觉效果同步
- 调整预制体中的全局缩放参数
- 为狼人和石巨人添加NavMeshAgent组件支持
- 优化水晶矿血条显示位置计算方式
```
2026-09-20 21:52:31 +08:00

143 lines
5.2 KiB
C#

using System;
using System.IO;
using System.Security.Cryptography;
using UnityEditor;
using UnityEngine;
namespace UnityTcp.Editor.Helpers
{
/// <summary>
/// Prompt to restart Unity after the Bridge native plugin changes.
/// Pending lives in SessionState so a domain reload still shows the dialog.
/// </summary>
[InitializeOnLoad]
internal static class BridgeUpdateRestartPrompt
{
internal const string PendingKey = "UnityTcp.BridgeRestartPending";
internal const string LastDllHashKey = "UnityTcp.BridgeLastNativeDllHash";
private const string PromptedKey = "UnityTcp.BridgeRestartPrompted";
internal const string DialogTitle = "Codely Bridge Updated";
internal const string DialogMessage =
"The Codely Bridge package has been updated. Restart the Tuanjie Editor to load it.\n\n" +
"Codely Bridge 已更新。请重启团结编辑器以加载新版本。";
internal const string RestartButton = "Restart Now";
internal const string LaterButton = "Later";
internal static Func<string, string, string, string, bool> ShowDialog;
internal static Action RestartEditor;
internal static Func<bool> IsAutomated;
static BridgeUpdateRestartPrompt()
{
EditorApplication.delayCall += TryShowPendingPrompt;
}
internal static bool IsPending() => SessionState.GetBool(PendingKey, false);
internal static string LastKnownNativeDllHash() =>
SessionState.GetString(LastDllHashKey, null);
internal static void RememberNativeDllFromFile(string path)
{
string hash = TryHashFile(path);
if (string.IsNullOrEmpty(hash)) return;
SessionState.SetString(LastDllHashKey, hash);
}
/// <summary>
/// True when the incoming native plugin bytes differ from the
/// currently loaded plugin (or, if nothing is remembered yet, from
/// the changedFrom file). Missing changedFrom / unreadable files
/// are not an update.
/// </summary>
internal static bool IsNativeDllContentChanged(string fromDllPath, string toDllPath)
{
if (string.IsNullOrEmpty(fromDllPath) || string.IsNullOrEmpty(toDllPath))
return false;
string toHash = TryHashFile(toDllPath);
if (string.IsNullOrEmpty(toHash))
return false;
string known = LastKnownNativeDllHash();
if (!string.IsNullOrEmpty(known))
return known != toHash;
string fromHash = TryHashFile(fromDllPath);
if (string.IsNullOrEmpty(fromHash))
return false;
return fromHash != toHash;
}
internal static void MarkUpdated()
{
SessionState.SetBool(PendingKey, true);
SessionState.SetBool(PromptedKey, false);
}
internal static void TryShowPendingPrompt()
{
if (ShowDialog == null &&
(EditorApplication.isCompiling || EditorApplication.isUpdating))
{
EditorApplication.delayCall += TryShowPendingPrompt;
return;
}
bool automated = (IsAutomated ?? EditorAutomationGuard.IsAutomatedEditorRun)();
if (automated || !IsPending() || SessionState.GetBool(PromptedKey, false))
return;
SessionState.SetBool(PromptedKey, true);
SessionState.SetBool(PendingKey, false);
var show = ShowDialog ?? DefaultShowDialog;
if (show(DialogTitle, DialogMessage, RestartButton, LaterButton))
(RestartEditor ?? DefaultRestartEditor)();
}
internal static void ResetForTests()
{
SessionState.EraseBool(PendingKey);
SessionState.EraseBool(PromptedKey);
SessionState.EraseString(LastDllHashKey);
ShowDialog = null;
RestartEditor = null;
IsAutomated = null;
}
private static string TryHashFile(string path)
{
try
{
if (string.IsNullOrEmpty(path) || !File.Exists(path))
return null;
using (var md5 = MD5.Create())
using (var stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
byte[] hash = md5.ComputeHash(stream);
return BitConverter.ToString(hash).Replace("-", "");
}
}
catch (Exception ex)
{
CodelyLogger.LogWarning(
$"BridgeUpdateRestartPrompt: failed to hash '{path}': {ex.Message}");
return null;
}
}
private static bool DefaultShowDialog(string title, string message, string ok, string cancel)
=> EditorUtility.DisplayDialog(title, message, ok, cancel);
private static void DefaultRestartEditor()
{
string projectPath = Path.GetDirectoryName(Application.dataPath);
if (string.IsNullOrEmpty(projectPath))
projectPath = Directory.GetCurrentDirectory();
EditorApplication.OpenProject(projectPath);
}
}
}