From 76f164c89e08088e30dfa2172e06ab7b7c0a62c7 Mon Sep 17 00:00:00 2001 From: wuwenbo Date: Sat, 26 Jul 2025 17:45:39 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dbug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Unity/Assets/Scripts/Data/MapData.cs | 59 ++++++- .../Achievement/AchievementDataManager.cs | 25 ++- .../Logic/CrashSight/CrashSightManager.cs | 24 +++ .../Scripts/Logic/Editor/BuildEditor.cs | 151 +++++++++++++++--- .../Logic/Skill/AllSkill/SplashSkill.cs | 12 +- .../Logic/Skill/AllSkill/TaiChiSkill.cs | 2 +- .../Scripts/Logic/Timeline/Fragments.cs | 19 ++- .../Scripts/Logic/Timeline/TimelineManager.cs | 2 +- Unity/Assets/Scripts/Logic/Unit/UnitLogic.cs | 4 +- 9 files changed, 258 insertions(+), 40 deletions(-) diff --git a/Unity/Assets/Scripts/Data/MapData.cs b/Unity/Assets/Scripts/Data/MapData.cs index 93db6888f..d432e3807 100644 --- a/Unity/Assets/Scripts/Data/MapData.cs +++ b/Unity/Assets/Scripts/Data/MapData.cs @@ -12,6 +12,7 @@ using System.IO; using Logic; using Logic.Action; using Logic.AI; +using Logic.CrashSight; using UnityEngine; @@ -925,8 +926,32 @@ namespace RuntimeData public static void SaveMapData(MapData map) { - string json = JsonUtility.ToJson(map); - File.WriteAllText(Application.persistentDataPath + "/map_archive.json", json); + if (map == null) return; + + string path = Application.persistentDataPath + "/map_archive.json"; + int retryCount = 3; + + while (retryCount > 0) + { + try + { + string json = JsonUtility.ToJson(map); + using (StreamWriter writer = new StreamWriter(path, false)) + { + writer.Write(json); + writer.Close(); + } + return; + } + catch (IOException ex) + { + retryCount--; + if (retryCount <= 0) + { + LogSystem.LogError($"保存地图数据失败: {ex.Message}"); + } + } + } } public static MapData GetMapData() @@ -934,9 +959,30 @@ namespace RuntimeData string path = Application.persistentDataPath + "/map_archive.json"; if (!File.Exists(path)) return null; - string json = File.ReadAllText(path); - MapData map = JsonUtility.FromJson(json); - return map; + int retryCount = 3; + while (retryCount > 0) + { + try + { + string json; + using (StreamReader reader = new StreamReader(path)) + { + json = reader.ReadToEnd(); + reader.Close(); + } + return JsonUtility.FromJson(json); + } + catch (IOException ex) + { + retryCount--; + if (retryCount <= 0) + { + LogSystem.LogError($"读取地图数据失败: {ex.Message}"); + return null; + } + } + } + return null; } public GameRecord ExportGameRecord() @@ -1034,4 +1080,5 @@ namespace RuntimeData _idGenerator = copy._idGenerator; } } -} \ No newline at end of file +} + diff --git a/Unity/Assets/Scripts/Logic/Achievement/AchievementDataManager.cs b/Unity/Assets/Scripts/Logic/Achievement/AchievementDataManager.cs index b76d3318a..3456ab2b6 100644 --- a/Unity/Assets/Scripts/Logic/Achievement/AchievementDataManager.cs +++ b/Unity/Assets/Scripts/Logic/Achievement/AchievementDataManager.cs @@ -9,6 +9,7 @@ using System.Collections.Generic; using System.IO; using Logic.Achievement; +using Logic.CrashSight; using UnityEngine; @@ -99,7 +100,29 @@ namespace RuntimeData { if (Achievement == null) return; string json = JsonUtility.ToJson(Achievement); - File.WriteAllText(Application.persistentDataPath + "/achievement.json", json); + string path = Application.persistentDataPath + "/achievement.json"; + + int retryCount = 3; + while (retryCount > 0) + { + try + { + using (StreamWriter writer = new StreamWriter(path, false)) + { + writer.Write(json); + writer.Close(); + } + return; + } + catch (IOException ex) + { + retryCount--; + if (retryCount <= 0) + { + LogSystem.LogError($"保存成就数据失败: {ex.Message}"); + } + } + } } } } \ No newline at end of file diff --git a/Unity/Assets/Scripts/Logic/CrashSight/CrashSightManager.cs b/Unity/Assets/Scripts/Logic/CrashSight/CrashSightManager.cs index 183cc906b..ffc6fc4ec 100644 --- a/Unity/Assets/Scripts/Logic/CrashSight/CrashSightManager.cs +++ b/Unity/Assets/Scripts/Logic/CrashSight/CrashSightManager.cs @@ -28,6 +28,30 @@ namespace Logic.CrashSight public class LogSystem { + public static string Record = string.Empty; + + + private static string GenerateHashCode() + { + string deviceId = SystemInfo.deviceUniqueIdentifier; + string timestamp = System.DateTime.UtcNow.Ticks.ToString(); + string combined = deviceId + timestamp; + + using (var md5 = System.Security.Cryptography.MD5.Create()) + { + byte[] inputBytes = System.Text.Encoding.UTF8.GetBytes(combined); + byte[] hashBytes = md5.ComputeHash(inputBytes); + + // Convert the byte array to hexadecimal string + System.Text.StringBuilder sb = new System.Text.StringBuilder(); + for (int i = 0; i < hashBytes.Length; i++) + { + sb.Append(hashBytes[i].ToString("x2")); + } + return sb.ToString(); + } + } + public static void LogError(string message, Object context = null) { #if !UNITY_EDITOR diff --git a/Unity/Assets/Scripts/Logic/Editor/BuildEditor.cs b/Unity/Assets/Scripts/Logic/Editor/BuildEditor.cs index e7df554fa..b1b4096fe 100644 --- a/Unity/Assets/Scripts/Logic/Editor/BuildEditor.cs +++ b/Unity/Assets/Scripts/Logic/Editor/BuildEditor.cs @@ -6,44 +6,48 @@ */ +using System.Collections.Generic; using Logic.Config; using UnityEditor; using UnityEngine; +using OPS.Obfuscator.Editor; +using OPS.Obfuscator.Editor.Settings; namespace Logic.Editor { - // 编辑器工具类 public class BuildEditor : EditorWindow { private VersionConfig _asset; + private const string OUTPUT_PATH = "Build/StandaloneWindows64"; - [MenuItem("Tools/打包窗口")] - public static void ShowWindow() + [MenuItem("Tools/打包工具")] + private static void ShowWindow() { var window = GetWindow(); - window.titleContent = new GUIContent("打包"); + window.titleContent = new GUIContent("打包工具"); + window.Show(); + } + + private void OnEnable() + { + var path = $"Assets/Resources/DataAssets/VersionConfig.asset"; + _asset = AssetDatabase.LoadAssetAtPath(path); + if (!_asset) + { + _asset = CreateInstance(); + AssetDatabase.CreateAsset(_asset, path); + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + } } private void OnGUI() { - if (!_asset) - { - var path = $"Assets/Resources/DataAssets/VersionConfig.asset"; - _asset = AssetDatabase.LoadAssetAtPath(path); - if (!_asset) - { - _asset = CreateInstance(); - AssetDatabase.CreateAsset(_asset, path); - AssetDatabase.SaveAssets(); - AssetDatabase.Refresh(); - } - } _asset.majorVersion = EditorGUILayout.TextField("重大更新", _asset.majorVersion); _asset.minorVersion = EditorGUILayout.TextField("功能更新", _asset.minorVersion); _asset.patchVersion = EditorGUILayout.TextField("补丁修复", _asset.patchVersion); - EditorGUILayout.IntField("构建号", _asset.buildNumber); - if (GUILayout.Button("构建版本号")) + if (GUILayout.Button($"构建 Debug 包")) { _asset.buildNumber++; EditorUtility.SetDirty(_asset); @@ -51,7 +55,118 @@ namespace Logic.Editor // 更新Unity版本号 PlayerSettings.bundleVersion = _asset.FullVersion; + + // Debug包配置 + SetDebugBuildSettings(); + + // 开始构建 + BuildPipeline.BuildPlayer(GetBuildScenes(), + $"{OUTPUT_PATH}/Debug_{_asset.FullVersion}/{Application.productName}.exe", + BuildTarget.StandaloneWindows64, + BuildOptions.Development | BuildOptions.AllowDebugging | BuildOptions.ConnectWithProfiler); } + + if (GUILayout.Button($"构建 Release 包")) + { + _asset.buildNumber++; + EditorUtility.SetDirty(_asset); + AssetDatabase.SaveAssets(); + + // 更新Unity版本号 + PlayerSettings.bundleVersion = _asset.FullVersion; + + // Release包配置 + SetReleaseBuildSettings(); + + // 开始构建 + BuildPipeline.BuildPlayer(GetBuildScenes(), + $"{OUTPUT_PATH}/Release_{_asset.FullVersion}/{Application.productName}.exe", + BuildTarget.StandaloneWindows64, + BuildOptions.None); + } + } + + private void SetDebugBuildSettings() + { + // 脚本后端 + PlayerSettings.SetScriptingBackend(BuildTargetGroup.Standalone, ScriptingImplementation.Mono2x); + + // 开发者模式 + EditorUserBuildSettings.development = true; + + // 允许debug + EditorUserBuildSettings.allowDebugging = true; + + // 日志等级 + PlayerSettings.SetStackTraceLogType(LogType.Log, StackTraceLogType.ScriptOnly); + PlayerSettings.SetStackTraceLogType(LogType.Warning, StackTraceLogType.ScriptOnly); + PlayerSettings.SetStackTraceLogType(LogType.Error, StackTraceLogType.ScriptOnly); + PlayerSettings.SetStackTraceLogType(LogType.Assert, StackTraceLogType.ScriptOnly); + PlayerSettings.SetStackTraceLogType(LogType.Exception, StackTraceLogType.ScriptOnly); + + // 开启详细日志 + PlayerSettings.usePlayerLog = true; + + // 其他Debug相关设置 + PlayerSettings.fullScreenMode = FullScreenMode.Windowed; + PlayerSettings.defaultScreenWidth = 1280; + PlayerSettings.defaultScreenHeight = 720; + PlayerSettings.resizableWindow = true; + + // 开启深度剖析器 + // PlayerSettings.enableDynamicBatching = true; + PlayerSettings.enableInternalProfiler = true; + } + + private void SetReleaseBuildSettings() + { + // 脚本后端 + PlayerSettings.SetScriptingBackend(BuildTargetGroup.Standalone, ScriptingImplementation.IL2CPP); + + // 关闭开发者模式 + EditorUserBuildSettings.development = false; + + // 关闭debug + EditorUserBuildSettings.allowDebugging = false; + + // 日志等级(只显示错误和异常) + PlayerSettings.SetStackTraceLogType(LogType.Log, StackTraceLogType.None); + PlayerSettings.SetStackTraceLogType(LogType.Warning, StackTraceLogType.None); + PlayerSettings.SetStackTraceLogType(LogType.Error, StackTraceLogType.ScriptOnly); + PlayerSettings.SetStackTraceLogType(LogType.Assert, StackTraceLogType.ScriptOnly); + PlayerSettings.SetStackTraceLogType(LogType.Exception, StackTraceLogType.ScriptOnly); + + // 关闭详细日志 + PlayerSettings.usePlayerLog = false; + + // 其他Release相关设置 + PlayerSettings.fullScreenMode = FullScreenMode.FullScreenWindow; + PlayerSettings.defaultScreenWidth = 1920; + PlayerSettings.defaultScreenHeight = 1080; + PlayerSettings.resizableWindow = true; + + // 关闭深度剖析器 + // PlayerSettings.enableDynamicBatching = false; + PlayerSettings.enableInternalProfiler = false; + + // IL2CPP优化 + PlayerSettings.SetIl2CppCompilerConfiguration(BuildTargetGroup.Standalone, Il2CppCompilerConfiguration.Release); + PlayerSettings.SetManagedStrippingLevel(BuildTargetGroup.Standalone, ManagedStrippingLevel.High); + + // 开启OPS混淆 + ObfuscatorSettings.Load().Add_Or_UpdateSettingElement("Global_Enable_Obfuscation", true); + } + + private string[] GetBuildScenes() + { + // 获取需要打包的场景列表 + var scenes = new List(); + foreach (var scene in EditorBuildSettings.scenes) + { + if (scene.enabled) + scenes.Add(scene.path); + } + return scenes.ToArray(); } } } \ No newline at end of file diff --git a/Unity/Assets/Scripts/Logic/Skill/AllSkill/SplashSkill.cs b/Unity/Assets/Scripts/Logic/Skill/AllSkill/SplashSkill.cs index 9c0073e5f..d63b01691 100644 --- a/Unity/Assets/Scripts/Logic/Skill/AllSkill/SplashSkill.cs +++ b/Unity/Assets/Scripts/Logic/Skill/AllSkill/SplashSkill.cs @@ -39,17 +39,13 @@ namespace Logic.Skill if (!mapData.GetPlayerDataByUnitId(info.DamageOrigin.Id, out var player)) return; var selfUnitList = new HashSet(); mapData.GetUnitDataListByPlayerId(player.Id, selfUnitList); - - GridData targetGrid = info.DamageTargetGrid; - if (targetGrid == null) + + if (info.DamageTargetGrid == null) { - var text = $""; - if (info.DamageTarget == null) text += $"info.DamageTarget is null "; - if (info.DamageTargetGrid == null) text += $"info.DamageTargetGrid is null "; - LogSystem.LogError(text); + LogSystem.LogError($"SplashSkill info.DamageTarget is null"); return; } - var roundGrid = mapData.GridMap.GetAroundGridData(1, 1, targetGrid); + var roundGrid = mapData.GridMap.GetAroundGridData(1, 1, info.DamageTargetGrid); foreach (var grid in roundGrid) { MapRenderer.Instance.ROGridMap[grid.Id].SetBounceAnim(NeedRandomWait:true); diff --git a/Unity/Assets/Scripts/Logic/Skill/AllSkill/TaiChiSkill.cs b/Unity/Assets/Scripts/Logic/Skill/AllSkill/TaiChiSkill.cs index eb28a5588..e50b99cd4 100644 --- a/Unity/Assets/Scripts/Logic/Skill/AllSkill/TaiChiSkill.cs +++ b/Unity/Assets/Scripts/Logic/Skill/AllSkill/TaiChiSkill.cs @@ -32,7 +32,7 @@ namespace Logic.Skill if (info == null) return; if (info.DamageType != DamageType.ActiveAttack) return; if (info.DamageOrigin == null || info.DamageTarget == null) return; - + if (info.DamageOrigin.GetAttackRange() >= 2) return; Main.UnitLogic.DamageSettlement(mapData, info.DamageTarget, info.DamageOrigin, info.DamageValue, DamageType.FollowAttack); } diff --git a/Unity/Assets/Scripts/Logic/Timeline/Fragments.cs b/Unity/Assets/Scripts/Logic/Timeline/Fragments.cs index 75c56c9ef..e40845125 100644 --- a/Unity/Assets/Scripts/Logic/Timeline/Fragments.cs +++ b/Unity/Assets/Scripts/Logic/Timeline/Fragments.cs @@ -6,6 +6,7 @@ */ +using Logic.CrashSight; using RuntimeData; using TH1Renderer; using UnityEngine; @@ -25,6 +26,12 @@ namespace Logic.Timeline public override void OnStart() { + if (Origin == null || Target == null) + { + LogSystem.LogError($"MoveKill Origin:{Origin} or Target:{Target} is null"); + return; + } + //立刻死亡并播放受伤动画,必须先处理死亡,再处理移动,不然gridToUnit的dict会出错 // 这里改成直接结算,包含了死亡,包含了经验增长和权利奇观记录 Main.UnitLogic.DamageSettlement(Map, Origin, Target, Dmg, DamageType.ActiveAttack); @@ -91,8 +98,11 @@ namespace Logic.Timeline public override void OnUpdate(float progressTime) { - if (Target == null || Origin == null) + if (Origin == null || Target == null) + { + LogSystem.LogError($"NotMoveKill Origin:{Origin} or Target:{Target} is null"); return; + } if (progressTime >= AttackTime) { AttackTime = float.MaxValue; @@ -159,8 +169,11 @@ namespace Logic.Timeline public override void OnUpdate(float progressTime) { - if (Target == null || Origin == null) + if (Origin == null || Target == null) + { + LogSystem.LogError($"AttackAndCounter Origin:{Origin} or Target:{Target} is null"); return; + } if (progressTime >= AttackAnimTime) { AttackAnimTime = float.MaxValue; @@ -191,7 +204,7 @@ namespace Logic.Timeline { CounterAttackWait = float.MaxValue; var settlement = Main.UnitLogic.DamageSettlement(Map, Target, Origin, Dmg2, DamageType.CounterAttack); - + if (settlement == null) return; if (settlement.IsKill) { OriginGrid.VFXRenderMarkHurt = true; diff --git a/Unity/Assets/Scripts/Logic/Timeline/TimelineManager.cs b/Unity/Assets/Scripts/Logic/Timeline/TimelineManager.cs index bc268ee4c..924fb1618 100644 --- a/Unity/Assets/Scripts/Logic/Timeline/TimelineManager.cs +++ b/Unity/Assets/Scripts/Logic/Timeline/TimelineManager.cs @@ -40,7 +40,7 @@ namespace Logic.Timeline if (fragment.State == FragmentState.Playing) { fragment.OnUpdate(Time.time - fragment.StartTime); - if (Time.time > fragment.StartTime + fragment.Duration) + if (Time.time >= fragment.StartTime + fragment.Duration) { fragment.OnFinished(); fragment.State = FragmentState.Finished; diff --git a/Unity/Assets/Scripts/Logic/Unit/UnitLogic.cs b/Unity/Assets/Scripts/Logic/Unit/UnitLogic.cs index ca5a0e147..c6c329092 100644 --- a/Unity/Assets/Scripts/Logic/Unit/UnitLogic.cs +++ b/Unity/Assets/Scripts/Logic/Unit/UnitLogic.cs @@ -328,12 +328,12 @@ namespace Logic { if (origin == null || target == null) { - LogSystem.LogError($"DamageSettlement origin:{origin} target{target}"); + LogSystem.LogError($"DamageSettlement origin:{origin} or target{target} is null"); return null; } if (!mapData.GetGridDataByUnitId(target.Id, out var targetGrid)) { - LogSystem.LogError($"WULI Target Grid is null target.id:{target.Id}"); + LogSystem.LogError($"Target Grid is null target.id:{target.Id}"); return null; }