From 2f18d17e7218262dc7599c00bf552556f8247539 Mon Sep 17 00:00:00 2001
From: yyl <yyl>
Date: 星期二, 27 一月 2026 18:50:56 +0800
Subject: [PATCH] 战报查看器

---
 Assets/Editor/ScriptEditor/BattleReportChecker.cs |  740 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 721 insertions(+), 19 deletions(-)

diff --git a/Assets/Editor/ScriptEditor/BattleReportChecker.cs b/Assets/Editor/ScriptEditor/BattleReportChecker.cs
index f75f759..fada9dc 100644
--- a/Assets/Editor/ScriptEditor/BattleReportChecker.cs
+++ b/Assets/Editor/ScriptEditor/BattleReportChecker.cs
@@ -195,11 +195,24 @@
     private Vector2 scrollPosition;
     private Vector2 detailScrollPosition;
     private string searchText = "";
+    private string detailSearchText = ""; // 璇︽儏鎼滅储鏂囨湰
+    private string lastDetailSearchText = ""; // 涓婃鐨勮鎯呮悳绱㈡枃鏈紝鐢ㄤ簬妫�娴嬪彉鍖�
     private string selectedGuid = "";
     private List<string> guidList = new List<string>();
     private int selectedGuidIndex = 0;
     private List<PackageInfo> filteredPackages = new List<PackageInfo>();
     private PackageInfo selectedPackage = null;
+    private PackageInfo lastSelectedPackage = null; // 涓婃閫変腑鐨勫寘锛岀敤浜庢娴嬪寘鍒囨崲
+    
+    // 楂樹寒鐩稿叧
+    private PackageInfo highlightedPackage = null;
+    private double highlightStartTime = 0;
+    private const double highlightDuration = 5.0; // 楂樹寒鎸佺画5绉�
+    private int selectedPackageIndex = -1; // 璁板綍閫変腑鍖呭湪鍒楄〃涓殑绱㈠紩锛岀敤浜庢粴鍔�
+    
+    // 鎼滅储缂撳瓨
+    private HashSet<string> matchedFieldNames = new HashSet<string>(); // 缂撳瓨鍖归厤鐨勫瓧娈靛悕
+    private Dictionary<string, bool> fieldHasMatchedChild = new Dictionary<string, bool>(); // 缂撳瓨瀛楁鏄惁鏈夊尮閰嶇殑瀛愬厓绱�
     
     #endregion
     
@@ -250,6 +263,12 @@
         
         if (GUILayout.Button("鍒锋柊", EditorStyles.toolbarButton, GUILayout.Width(60)))
         {
+            // 鍒锋柊鍓嶆竻绌烘悳绱㈢紦瀛橈紝閬垮厤鍗℃
+            matchedFieldNames.Clear();
+            fieldHasMatchedChild.Clear();
+            lastSelectedPackage = null;
+            lastDetailSearchText = "";
+            
             RefreshGuidList();
             FilterPackages();
         }
@@ -307,6 +326,15 @@
         {
             searchText = newSearchText;
             FilterPackages();
+            
+            // 鎼滅储鍚庤嚜鍔ㄩ�変腑绗竴涓粨鏋滃苟楂樹寒
+            if (filteredPackages.Count > 0)
+            {
+                selectedPackage = filteredPackages[0];
+                selectedPackageIndex = 0;
+                StartHighlight(selectedPackage);
+                ScrollToSelectedPackage();
+            }
         }
         
         if (GUILayout.Button("娓呯┖", GUILayout.Width(60)))
@@ -353,9 +381,18 @@
         bool isExecuted = executedPackUIDs.ContainsKey(selectedGuid) && 
                          executedPackUIDs[selectedGuid].Contains(packInfo.packUID);
         
+        // 鍒ゆ柇鏄惁鏄珮浜姸鎬�
+        bool isHighlighted = IsPackageHighlighted(packInfo);
+        
         // 璁剧疆鑳屾櫙棰滆壊
         Color originalBgColor = GUI.backgroundColor;
-        if (isExecuting)
+        if (isHighlighted)
+        {
+            // 楂樹寒鐘舵�� - 浣跨敤缁胯壊闂儊鏁堟灉
+            float pulse = Mathf.PingPong((float)EditorApplication.timeSinceStartup * 2f, 1f);
+            GUI.backgroundColor = Color.Lerp(new Color(0.3f, 0.8f, 0.3f), new Color(0.5f, 1f, 0.5f), pulse);
+        }
+        else if (isExecuting)
         {
             GUI.backgroundColor = new Color(0.3f, 0.3f, 0.3f); // 娣遍粦鑹诧紙姝e湪鎵ц锛�
         }
@@ -406,6 +443,7 @@
         if (GUILayout.Button(packInfo.displayName, style))
         {
             selectedPackage = packInfo;
+            selectedPackageIndex = filteredPackages.IndexOf(packInfo);
         }
         
         EditorGUILayout.EndHorizontal();
@@ -452,23 +490,64 @@
         }
         else
         {
+            // 璇︽儏鎼滅储鏍�
+            EditorGUILayout.BeginHorizontal();
+            GUILayout.Label("鎼滅储瀛楁:", GUILayout.Width(70));
+            detailSearchText = EditorGUILayout.TextField(detailSearchText);
+            if (GUILayout.Button("娓呯┖", GUILayout.Width(50)))
+            {
+                detailSearchText = "";
+            }
+            EditorGUILayout.EndHorizontal();
+            
+            // 妫�娴嬮�変腑鍖呮垨鎼滅储鏂囨湰鍙樺寲锛屾洿鏂扮紦瀛�
+            bool packageChanged = selectedPackage != lastSelectedPackage;
+            bool searchTextChanged = detailSearchText != lastDetailSearchText;
+            
+            if (packageChanged || searchTextChanged)
+            {
+                lastDetailSearchText = detailSearchText;
+                lastSelectedPackage = selectedPackage;
+                UpdateDetailSearchCache();
+            }
+            
+            if (string.IsNullOrEmpty(detailSearchText))
+            {
+                GUILayout.Label("鍦ㄦ鍖呯殑瀛楁涓悳绱紙瀛楁鍚嶆垨鍊硷級", EditorStyles.miniLabel);
+            }
+            else
+            {
+                GUILayout.Label($"鎵惧埌 {matchedFieldNames.Count} 涓尮閰嶇殑瀛楁锛堝凡鑷姩灞曞紑骞堕珮浜級", EditorStyles.miniLabel);
+            }
+            EditorGUILayout.Space(5);
+            
             detailScrollPosition = EditorGUILayout.BeginScrollView(detailScrollPosition, GUI.skin.box);
             
             // 鏍囬
             GUILayout.Label(selectedPackage.displayName, EditorStyles.boldLabel);
             EditorGUILayout.Space(5);
             
-            // 鍩烘湰淇℃伅
-            DrawDetailField("鍖呯被鍨�", selectedPackage.typeName);
-            DrawDetailField("UID", selectedPackage.packUID.ToString());
-            DrawDetailField("Cmd", selectedPackage.package.cmd.ToString());
+            // 鍩烘湰淇℃伅 - 鏀寔鎼滅储楂樹寒
+            string searchLower = detailSearchText.ToLower();
+            bool typeMatched = !string.IsNullOrEmpty(detailSearchText) && selectedPackage.typeName.ToLower().Contains(searchLower);
+            bool uidMatched = !string.IsNullOrEmpty(detailSearchText) && selectedPackage.packUID.ToString().Contains(searchLower);
+            bool cmdMatched = !string.IsNullOrEmpty(detailSearchText) && selectedPackage.package.cmd.ToString().Contains(searchLower);
+            
+            DrawDetailFieldWithHighlight("鍖呯被鍨�", selectedPackage.typeName, typeMatched);
+            DrawDetailFieldWithHighlight("UID", selectedPackage.packUID.ToString(), uidMatched);
+            DrawDetailFieldWithHighlight("Cmd", selectedPackage.package.cmd.ToString(), cmdMatched);
             EditorGUILayout.Space(10);
             
             // 鎵�鏈夊瓧娈�
             GUILayout.Label("瀛楁鍒楄〃:", EditorStyles.boldLabel);
+            
+            // 鏍规嵁鎼滅储鏂囨湰杩囨护瀛楁
             foreach (var field in selectedPackage.fields)
             {
-                DrawDetailFieldWithExpand(field.Key, field.Value, selectedPackage);
+                if (ShouldShowDetailField(field.Key, field.Value, selectedPackage))
+                {
+                    DrawDetailFieldWithExpand(field.Key, field.Value, selectedPackage);
+                }
             }
             
             EditorGUILayout.EndScrollView();
@@ -488,6 +567,27 @@
         EditorGUILayout.EndHorizontal();
     }
     
+    private void DrawDetailFieldWithHighlight(string fieldName, string value, bool isMatched)
+    {
+        if (isMatched)
+        {
+            Color originalBgColor = GUI.backgroundColor;
+            GUI.backgroundColor = new Color(1f, 1f, 0.5f); // 娣¢粍鑹茶儗鏅�
+            EditorGUILayout.BeginHorizontal(GUI.skin.box);
+            GUI.backgroundColor = originalBgColor;
+            
+            GUIStyle labelStyle = new GUIStyle(GUI.skin.label) { fontStyle = FontStyle.Bold };
+            GUILayout.Label(fieldName + ":", labelStyle, GUILayout.Width(150));
+            EditorGUILayout.SelectableLabel(value, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
+            
+            EditorGUILayout.EndHorizontal();
+        }
+        else
+        {
+            DrawDetailField(fieldName, value);
+        }
+    }
+    
     private void DrawDetailFieldWithExpand(string fieldName, string value, PackageInfo packInfo)
     {
         if (!packInfo.fieldDetails.ContainsKey(fieldName))
@@ -497,6 +597,22 @@
         }
         
         var detail = packInfo.fieldDetails[fieldName];
+        
+        // 浣跨敤缂撳瓨妫�鏌ユ槸鍚﹀尮閰�
+        bool isMatched = matchedFieldNames.Contains(fieldName);
+        
+        // 浣跨敤缂撳瓨妫�鏌ュ瓙鍏冪礌鏄惁鍖归厤
+        bool hasMatchedChild = false;
+        if (!string.IsNullOrEmpty(detailSearchText))
+        {
+            fieldHasMatchedChild.TryGetValue(fieldName, out hasMatchedChild);
+        }
+        
+        // 濡傛灉鑷韩鍖归厤鎴栧瓙鍏冪礌鍖归厤锛岃嚜鍔ㄥ睍寮�
+        if ((isMatched || hasMatchedChild) && !string.IsNullOrEmpty(detailSearchText))
+        {
+            detail.isExpanded = true;
+        }
         
         // 鍒ゆ柇鏄惁鏄鏉傚璞★紙闈炲熀鏈被鍨嬨�侀潪瀛楃涓层�侀潪鏋氫妇锛�
         bool isComplexObject = detail.value != null && 
@@ -509,7 +625,15 @@
         // 濡傛灉鏄暟缁勩�佸垪琛ㄦ垨澶嶆潅瀵硅薄锛屾樉绀哄睍寮�鎸夐挳
         if (detail.isArray || detail.isList || isComplexObject)
         {
-            EditorGUILayout.BeginHorizontal();
+            // 濡傛灉鍖归厤鎴栨湁鍖归厤鐨勫瓙鍏冪礌锛屾坊鍔犺儗鏅鑹�
+            Color originalBgColor = GUI.backgroundColor;
+            if (isMatched || hasMatchedChild)
+            {
+                GUI.backgroundColor = new Color(1f, 1f, 0.5f); // 娣¢粍鑹茶儗鏅�
+            }
+            
+            EditorGUILayout.BeginHorizontal((isMatched || hasMatchedChild) ? GUI.skin.box : GUIStyle.none);
+            GUI.backgroundColor = originalBgColor;
             
             // 灞曞紑鎸夐挳
             string foldoutLabel = detail.isExpanded ? "鈻�" : "鈻�";
@@ -518,7 +642,9 @@
                 detail.isExpanded = !detail.isExpanded;
             }
             
-            GUILayout.Label(fieldName + ":", GUILayout.Width(130));
+            // 瀛楁鍚嶆牱寮�
+            GUIStyle labelStyle = (isMatched || hasMatchedChild) ? new GUIStyle(GUI.skin.label) { fontStyle = FontStyle.Bold } : GUI.skin.label;
+            GUILayout.Label(fieldName + ":", labelStyle, GUILayout.Width(130));
             EditorGUILayout.SelectableLabel(value, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
             
             EditorGUILayout.EndHorizontal();
@@ -547,7 +673,24 @@
         }
         else
         {
-            DrawDetailField(fieldName, value);
+            // 绠�鍗曞瓧娈典篃娣诲姞楂樹寒
+            if (isMatched)
+            {
+                Color originalBgColor = GUI.backgroundColor;
+                GUI.backgroundColor = new Color(1f, 1f, 0.5f);
+                EditorGUILayout.BeginHorizontal(GUI.skin.box);
+                GUI.backgroundColor = originalBgColor;
+                
+                GUIStyle labelStyle = new GUIStyle(GUI.skin.label) { fontStyle = FontStyle.Bold };
+                GUILayout.Label(fieldName + ":", labelStyle, GUILayout.Width(150));
+                EditorGUILayout.SelectableLabel(value, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
+                
+                EditorGUILayout.EndHorizontal();
+            }
+            else
+            {
+                DrawDetailField(fieldName, value);
+            }
         }
     }
     
@@ -597,13 +740,63 @@
         
         var type = element.GetType();
         
+        // 妫�鏌ュ厓绱犳槸鍚﹀尮閰嶆悳绱�
+        bool isElementMatched = false;
+        if (!string.IsNullOrEmpty(detailSearchText))
+        {
+            HashSet<object> visited = new HashSet<object>();
+            isElementMatched = RecursiveSearchInObject(element, detailSearchText.ToLower(), visited);
+        }
+        
+        // 妫�鏌ユ槸鍚︽槸 GameNetPackBasic 绫诲瀷锛屽苟鍒ゆ柇鏄惁澶勪簬鎵ц鐘舵��
+        bool isPackageElement = element is GameNetPackBasic;
+        bool isHighlightedPackage = false;
+        bool isExecutingPackage = false;
+        bool isExecutedPackage = false;
+        
+        if (isPackageElement)
+        {
+            GameNetPackBasic pack = element as GameNetPackBasic;
+            ulong packUID = pack.packUID;
+            
+            // 妫�鏌ラ珮浜姸鎬�
+            if (highlightedPackage != null && highlightedPackage.packUID == packUID)
+            {
+                double elapsed = EditorApplication.timeSinceStartup - highlightStartTime;
+                isHighlightedPackage = elapsed < highlightDuration;
+            }
+            
+            // 妫�鏌ユ墽琛岀姸鎬�
+            isExecutingPackage = currentExecutingPackUID.ContainsKey(selectedGuid) && 
+                                currentExecutingPackUID[selectedGuid] == packUID;
+            isExecutedPackage = executedPackUIDs.ContainsKey(selectedGuid) && 
+                               executedPackUIDs[selectedGuid].Contains(packUID);
+        }
+        
         // 濡傛灉鏄熀鏈被鍨嬶紝鐩存帴鏄剧ず
         if (type.IsPrimitive || type == typeof(string) || type.IsEnum)
         {
-            EditorGUILayout.BeginHorizontal();
-            EditorGUILayout.PrefixLabel($"[{index}]");
-            EditorGUILayout.SelectableLabel(element.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
-            EditorGUILayout.EndHorizontal();
+            // 濡傛灉鍖归厤锛屾坊鍔犻珮浜�
+            if (isElementMatched)
+            {
+                Color originalBgColor = GUI.backgroundColor;
+                GUI.backgroundColor = new Color(1f, 1f, 0.5f);
+                EditorGUILayout.BeginHorizontal(GUI.skin.box);
+                GUI.backgroundColor = originalBgColor;
+                
+                GUIStyle labelStyle = new GUIStyle(EditorStyles.label) { fontStyle = FontStyle.Bold };
+                EditorGUILayout.PrefixLabel($"[{index}]", labelStyle, labelStyle);
+                EditorGUILayout.SelectableLabel(element.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
+                
+                EditorGUILayout.EndHorizontal();
+            }
+            else
+            {
+                EditorGUILayout.BeginHorizontal();
+                EditorGUILayout.PrefixLabel($"[{index}]");
+                EditorGUILayout.SelectableLabel(element.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
+                EditorGUILayout.EndHorizontal();
+            }
         }
         else
         {
@@ -616,11 +809,89 @@
             
             var elemDetail = parentDetail?.elementDetails[index];
             
+            // 濡傛灉鍏冪礌鍖归厤鎼滅储锛岃嚜鍔ㄥ睍寮�
+            if (isElementMatched && elemDetail != null)
+            {
+                elemDetail.isExpanded = true;
+            }
+            
+            // 涓哄寘鍏冪礌璁剧疆鑳屾櫙棰滆壊
+            Color originalBgColor = GUI.backgroundColor;
+            if (isPackageElement)
+            {
+                if (isHighlightedPackage)
+                {
+                    // 楂樹寒鐘舵�� - 浣跨敤缁胯壊闂儊鏁堟灉
+                    float pulse = Mathf.PingPong((float)EditorApplication.timeSinceStartup * 2f, 1f);
+                    GUI.backgroundColor = Color.Lerp(new Color(0.3f, 0.8f, 0.3f), new Color(0.5f, 1f, 0.5f), pulse);
+                }
+                else if (isExecutingPackage)
+                {
+                    GUI.backgroundColor = new Color(0.3f, 0.3f, 0.3f); // 娣遍粦鑹诧紙姝e湪鎵ц锛�
+                }
+                else if (isExecutedPackage)
+                {
+                    GUI.backgroundColor = new Color(0.6f, 0.6f, 0.6f); // 鐏拌壊锛堝凡鎵ц锛�
+                }
+                else if (isElementMatched)
+                {
+                    GUI.backgroundColor = new Color(1f, 1f, 0.5f); // 榛勮壊锛堟悳绱㈠尮閰嶏級
+                }
+            }
+            else if (isElementMatched)
+            {
+                GUI.backgroundColor = new Color(1f, 1f, 0.5f); // 榛勮壊锛堟悳绱㈠尮閰嶏級
+            }
+            
+            EditorGUILayout.BeginVertical(isPackageElement || isElementMatched ? GUI.skin.box : GUIStyle.none);
+            GUI.backgroundColor = originalBgColor;
+            
             // 灞曞紑鎸夐挳 + 绫诲瀷鍚�
+            GUIStyle labelStyle = EditorStyles.foldout;
+            if (isPackageElement)
+            {
+                if (isHighlightedPackage)
+                {
+                    labelStyle = new GUIStyle(EditorStyles.foldout) { normal = { textColor = Color.green }, fontStyle = FontStyle.Bold };
+                }
+                else if (isExecutingPackage)
+                {
+                    labelStyle = new GUIStyle(EditorStyles.foldout) { normal = { textColor = Color.yellow }, fontStyle = FontStyle.Bold };
+                }
+                else if (isExecutedPackage)
+                {
+                    labelStyle = new GUIStyle(EditorStyles.foldout) { normal = { textColor = Color.gray } };
+                }
+                else if (isElementMatched)
+                {
+                    labelStyle = new GUIStyle(EditorStyles.foldout) { fontStyle = FontStyle.Bold };
+                }
+            }
+            else if (isElementMatched)
+            {
+                labelStyle = new GUIStyle(EditorStyles.foldout) { fontStyle = FontStyle.Bold };
+            }
+            
             if (elemDetail != null)
             {
-                string foldoutLabel = elemDetail.isExpanded ? "鈻�" : "鈻�";
-                elemDetail.isExpanded = EditorGUILayout.Foldout(elemDetail.isExpanded, $"[{index}] {type.Name}", true);
+                GameNetPackBasic pack = element as GameNetPackBasic;
+                string displayText = isPackageElement ? $"[{index}] [{pack.packUID}] {type.Name}" : $"[{index}] {type.Name}";
+                
+                // 鐗规畩澶勭悊锛欻B427 鎶�鑳藉寘鏄剧ず閲婃斁鑰呭拰鎶�鑳藉悕
+                if (element is HB427_tagSCUseSkill skillPack)
+                {
+                    string casterName = GetObjectName(skillPack.ObjID);
+                    string skillName = GetSkillName(skillPack.SkillID);
+                    displayText += $" - {casterName} 浣跨敤 {skillName}";
+                }
+                // 鐗规畩澶勭悊锛欳ustomHB426CombinePack 鏄剧ず鏄惁闇�瑕佺瓑寰�
+                else if (element is CustomHB426CombinePack combinePack)
+                {
+                    bool needWaiting = combinePack.NeedWaiting();
+                    displayText += needWaiting ? " [闇�瑕佺瓑寰匽" : " [鏃犻渶绛夊緟]";
+                }
+                
+                elemDetail.isExpanded = EditorGUILayout.Foldout(elemDetail.isExpanded, displayText, true, labelStyle);
             }
             else
             {
@@ -633,6 +904,11 @@
                 EditorGUI.indentLevel++;
                 DrawObjectFields(element, elemDetail.fieldDetails);
                 EditorGUI.indentLevel--;
+            }
+            
+            if (isPackageElement || isElementMatched)
+            {
+                EditorGUILayout.EndVertical();
             }
         }
     }
@@ -693,13 +969,53 @@
         
         var type = value.GetType();
         
+        // 妫�鏌ュ瓧娈靛�兼槸鍚﹀尮閰嶆悳绱�
+        bool isValueMatched = false;
+        if (!string.IsNullOrEmpty(detailSearchText))
+        {
+            string searchLower = detailSearchText.ToLower();
+            // 瀛楁鍚嶅尮閰�
+            if (fieldName.ToLower().Contains(searchLower))
+                isValueMatched = true;
+            // 瀛楁鍊煎尮閰�
+            else if (value.ToString().Contains(searchLower))
+                isValueMatched = true;
+        }
+        
         // 鍩烘湰绫诲瀷鐩存帴鏄剧ず
         if (type.IsPrimitive || type == typeof(string) || type.IsEnum)
         {
-            EditorGUILayout.BeginHorizontal();
-            EditorGUILayout.PrefixLabel(fieldName);
-            EditorGUILayout.SelectableLabel(value.ToString(), EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
-            EditorGUILayout.EndHorizontal();
+            // 鑾峰彇鏄剧ず鍊硷紝濡傛灉鏄疧bjID鍒欒拷鍔犲璞″悕绉�
+            string displayValue = value.ToString();
+            if (fieldName == "ObjID" && uint.TryParse(displayValue, out uint objID))
+            {
+                string objName = GetObjectName(objID);
+                displayValue = $"{displayValue} ({objName})";
+            }
+            
+            if (isValueMatched)
+            {
+                // 楂樹寒鏄剧ず鍖归厤鐨勫瓧娈�
+                Color originalBgColor = GUI.backgroundColor;
+                GUI.backgroundColor = new Color(1f, 1f, 0.5f); // 娣¢粍鑹茶儗鏅�
+                EditorGUILayout.BeginHorizontal(GUI.skin.box);
+                GUI.backgroundColor = originalBgColor;
+                
+                GUIStyle labelStyle = new GUIStyle(GUI.skin.label) { fontStyle = FontStyle.Bold };
+                GUILayout.Space(EditorGUI.indentLevel * 15); // 鎵嬪姩缂╄繘
+                GUILayout.Label(fieldName + ":", labelStyle, GUILayout.Width(120));
+                EditorGUILayout.SelectableLabel(displayValue, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
+                
+                EditorGUILayout.EndHorizontal();
+            }
+            else
+            {
+                EditorGUILayout.BeginHorizontal();
+                GUILayout.Space(EditorGUI.indentLevel * 15); // 鎵嬪姩缂╄繘
+                GUILayout.Label(fieldName + ":", GUILayout.Width(120));
+                EditorGUILayout.SelectableLabel(displayValue, EditorStyles.textField, GUILayout.Height(EditorGUIUtility.singleLineHeight));
+                EditorGUILayout.EndHorizontal();
+            }
         }
         // 鏁扮粍绫诲瀷
         else if (type.IsArray && fieldDetail.arrayValue != null)
@@ -745,6 +1061,392 @@
     
     #endregion
     
+    #region 璇︽儏鎼滅储
+    
+    /// <summary>
+    /// 鏇存柊璇︽儏鎼滅储缂撳瓨锛堜粎鍦ㄦ悳绱㈡枃鏈敼鍙樻椂璋冪敤锛�
+    /// </summary>
+    private void UpdateDetailSearchCache()
+    {
+        matchedFieldNames.Clear();
+        fieldHasMatchedChild.Clear();
+        
+        if (selectedPackage == null || string.IsNullOrEmpty(detailSearchText))
+            return;
+            
+        string searchLower = detailSearchText.ToLower();
+        
+        // 妫�鏌ュ熀鏈俊鎭槸鍚﹀尮閰嶏紙鍖呯被鍨嬨�乁ID銆丆md锛�
+        bool basicInfoMatched = selectedPackage.typeName.ToLower().Contains(searchLower) ||
+                               selectedPackage.packUID.ToString().Contains(searchLower) ||
+                               selectedPackage.package.cmd.ToString().Contains(searchLower);
+        
+        foreach (var field in selectedPackage.fields)
+        {
+            string fieldName = field.Key;
+            string fieldValue = field.Value;
+            
+            // 妫�鏌ュ瓧娈靛悕鎴栧瓧娈靛�兼槸鍚﹀尮閰�
+            bool fieldMatched = fieldName.ToLower().Contains(searchLower) || 
+                               fieldValue.ToLower().Contains(searchLower);
+            
+            if (fieldMatched)
+            {
+                matchedFieldNames.Add(fieldName);
+            }
+            
+            // 妫�鏌ユ暟缁�/鍒楄〃鐨勫瓙鍏冪礌鏄惁鍖归厤
+            if (selectedPackage.fieldDetails.ContainsKey(fieldName))
+            {
+                var detail = selectedPackage.fieldDetails[fieldName];
+                if (detail.isArray || detail.isList)
+                {
+                    bool hasMatch = CheckChildElementsMatch(detail, searchLower);
+                    if (hasMatch)
+                    {
+                        fieldHasMatchedChild[fieldName] = true;
+                        if (!fieldMatched)
+                        {
+                            matchedFieldNames.Add(fieldName); // 涔熺畻浣滃尮閰嶅瓧娈�
+                        }
+                    }
+                }
+            }
+        }
+        
+        // 濡傛灉鍩烘湰淇℃伅鍖归厤浣嗘病鏈夊瓧娈靛尮閰嶏紝鑷冲皯鏄剧ず涓�涓瓧娈佃鐢ㄦ埛鐭ラ亾鏈夊尮閰�
+        if (basicInfoMatched && matchedFieldNames.Count == 0 && selectedPackage.fields.Count > 0)
+        {
+            // 娣诲姞绗竴涓瓧娈碉紝杩欐牱鑷冲皯浼氭樉绀轰竴浜涘唴瀹�
+            var firstField = selectedPackage.fields.First();
+            matchedFieldNames.Add(firstField.Key);
+        }
+    }
+    
+    /// <summary>
+    /// 妫�鏌ュ瓧娈垫槸鍚﹀尮閰嶆悳绱紙鐢ㄤ簬楂樹寒鏄剧ず锛�
+    /// </summary>
+    private bool IsFieldMatched(string fieldName, string fieldValue, FieldDetail detail)
+    {
+        if (string.IsNullOrEmpty(detailSearchText))
+            return false;
+            
+        string searchLower = detailSearchText.ToLower();
+        
+        // 瀛楁鍚嶅尮閰�
+        if (fieldName.ToLower().Contains(searchLower))
+            return true;
+            
+        // 瀛楁鍊煎尮閰�
+        if (fieldValue.ToLower().Contains(searchLower))
+            return true;
+            
+        return false;
+    }
+    
+    /// <summary>
+    /// 妫�鏌ユ暟缁�/鍒楄〃涓槸鍚︽湁鍖归厤鐨勫瓙鍏冪礌锛堢敤浜庣紦瀛樿绠楋級
+    /// </summary>
+    private bool CheckChildElementsMatch(FieldDetail detail, string searchLower)
+    {
+        HashSet<object> visited = new HashSet<object>();
+        
+        // 妫�鏌ユ暟缁�
+        if (detail.isArray && detail.arrayValue != null)
+        {
+            foreach (var element in detail.arrayValue)
+            {
+                if (element != null)
+                {
+                    // 鐗规畩澶勭悊锛氬鏋滄槸 GameNetPackBasic锛屼紭鍏堟鏌� packUID
+                    if (element is GameNetPackBasic pack && pack.packUID.ToString().Contains(searchLower))
+                        return true;
+                    
+                    if (RecursiveSearchInObject(element, searchLower, visited))
+                        return true;
+                }
+            }
+        }
+        
+        // 妫�鏌ュ垪琛�
+        if (detail.isList && detail.listValue != null)
+        {
+            foreach (var element in detail.listValue)
+            {
+                if (element != null)
+                {
+                    // 鐗规畩澶勭悊锛氬鏋滄槸 GameNetPackBasic锛屼紭鍏堟鏌� packUID
+                    if (element is GameNetPackBasic pack && pack.packUID.ToString().Contains(searchLower))
+                        return true;
+                    
+                    if (RecursiveSearchInObject(element, searchLower, visited))
+                        return true;
+                }
+            }
+        }
+        
+        return false;
+    }
+    
+    /// <summary>
+    /// 鍒ゆ柇瀛楁鏄惁搴旇鏄剧ず锛堟牴鎹鎯呮悳绱㈡枃鏈級
+    /// </summary>
+    private bool ShouldShowDetailField(string fieldName, string fieldValue, PackageInfo packInfo)
+    {
+        if (string.IsNullOrEmpty(detailSearchText))
+            return true;
+            
+        string searchLower = detailSearchText.ToLower();
+        
+        // 鎼滅储瀛楁鍚�
+        if (fieldName.ToLower().Contains(searchLower))
+            return true;
+            
+        // 鎼滅储瀛楁鍊�
+        if (fieldValue.ToLower().Contains(searchLower))
+            return true;
+            
+        // 濡傛灉鏈夎缁嗕俊鎭紝閫掑綊鎼滅储
+        if (packInfo.fieldDetails.ContainsKey(fieldName))
+        {
+            var detail = packInfo.fieldDetails[fieldName];
+            HashSet<object> visited = new HashSet<object>();
+            if (RecursiveSearchInFieldDetail(detail, searchLower, visited))
+                return true;
+        }
+        
+        return false;
+    }
+    
+    /// <summary>
+    /// 閫掑綊鎼滅储瀛楁璇︽儏
+    /// </summary>
+    private bool RecursiveSearchInFieldDetail(FieldDetail detail, string searchLower, HashSet<object> visited)
+    {
+        if (detail.value != null)
+        {
+            // 闃叉寰幆寮曠敤
+            if (!detail.value.GetType().IsPrimitive && 
+                detail.value.GetType() != typeof(string) && 
+                !detail.value.GetType().IsEnum)
+            {
+                if (visited.Contains(detail.value))
+                    return false;
+                visited.Add(detail.value);
+            }
+            
+            // 鎼滅储鍊兼湰韬�
+            if (detail.value.ToString().ToLower().Contains(searchLower))
+                return true;
+                
+            // 濡傛灉鏄暟缁�
+            if (detail.isArray && detail.arrayValue != null)
+            {
+                foreach (var element in detail.arrayValue)
+                {
+                    if (element != null && RecursiveSearchInObject(element, searchLower, visited))
+                        return true;
+                }
+            }
+            
+            // 濡傛灉鏄垪琛�
+            if (detail.isList && detail.listValue != null)
+            {
+                foreach (var element in detail.listValue)
+                {
+                    if (element != null && RecursiveSearchInObject(element, searchLower, visited))
+                        return true;
+                }
+            }
+            
+            // 鎼滅储瀛愬瓧娈�
+            foreach (var subField in detail.subFieldDetails.Values)
+            {
+                if (RecursiveSearchInFieldDetail(subField, searchLower, visited))
+                    return true;
+            }
+        }
+        
+        return false;
+    }
+    
+    /// <summary>
+    /// 閫掑綊鎼滅储瀵硅薄鍐呭
+    /// </summary>
+    private bool RecursiveSearchInObject(object obj, string searchLower, HashSet<object> visited)
+    {
+        if (obj == null) return false;
+        
+        var type = obj.GetType();
+        
+        // 鐗规畩澶勭悊锛氬鏋滄槸 GameNetPackBasic锛屼紭鍏堟鏌� packUID
+        if (obj is GameNetPackBasic pack)
+        {
+            if (pack.packUID.ToString().Contains(searchLower))
+                return true;
+            // 杩樿妫�鏌ョ被鍨嬪悕
+            if (pack.GetType().Name.ToLower().Contains(searchLower))
+                return true;
+        }
+        
+        // 鍩烘湰绫诲瀷鐩存帴姣旇緝锛堝寘鎷墍鏈夋暟瀛楃被鍨嬶級
+        if (type.IsPrimitive || type == typeof(string) || type.IsEnum)
+        {
+            string valueStr = obj.ToString();
+            // 瀵逛簬鏁板瓧锛岀洿鎺ユ瘮杈冨瓧绗︿覆锛堜笉杞皬鍐欙紝鍥犱负鏁板瓧娌℃湁澶у皬鍐欙級
+            if (type.IsPrimitive && !type.IsEnum)
+            {
+                return valueStr.Contains(searchLower);
+            }
+            // 瀵逛簬瀛楃涓插拰鏋氫妇锛岃浆灏忓啓姣旇緝
+            return valueStr.ToLower().Contains(searchLower);
+        }
+        
+        // 闃叉寰幆寮曠敤
+        if (visited.Contains(obj))
+            return false;
+        visited.Add(obj);
+        
+        // 闄愬埗閫掑綊娣卞害锛岄槻姝㈣繃娣辩殑宓屽
+        if (visited.Count > 1000)
+            return false;
+        
+        // 鐗规畩澶勭悊鏁扮粍
+        if (type.IsArray)
+        {
+            var array = obj as System.Array;
+            if (array != null)
+            {
+                foreach (var element in array)
+                {
+                    if (element != null && RecursiveSearchInObject(element, searchLower, visited))
+                        return true;
+                }
+            }
+            return false;
+        }
+        
+        // 鐗规畩澶勭悊鍒楄〃
+        if (obj is System.Collections.IList list && !(obj is string))
+        {
+            foreach (var element in list)
+            {
+                if (element != null && RecursiveSearchInObject(element, searchLower, visited))
+                    return true;
+            }
+            return false;
+        }
+        
+        // 澶嶆潅瀵硅薄锛屾悳绱㈡墍鏈夊瓧娈�
+        var fields = type.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
+        foreach (var field in fields)
+        {
+            try
+            {
+                // 鎼滅储瀛楁鍚�
+                if (field.Name.ToLower().Contains(searchLower))
+                    return true;
+                    
+                var value = field.GetValue(obj);
+                if (value != null && RecursiveSearchInObject(value, searchLower, visited))
+                    return true;
+            }
+            catch { }
+        }
+        
+        return false;
+    }
+    
+    #endregion
+    
+    #region 杈呭姪鏂规硶
+    
+    /// <summary>
+    /// 鏍规嵁瀵硅薄ID鑾峰彇瀵硅薄鍚嶇О
+    /// </summary>
+    private string GetObjectName(uint objID)
+    {
+        try
+        {
+            var battleField = BattleManager.Instance?.GetBattleField(selectedGuid);
+            if (battleField != null && battleField.battleObjMgr != null)
+            {
+                var battleObj = battleField.battleObjMgr.GetBattleObject((int)objID);
+                if (battleObj != null && battleObj.teamHero != null)
+                {
+                    return battleObj.teamHero.name;
+                }
+            }
+        }
+        catch { }
+        
+        return $"瀵硅薄{objID}";
+    }
+    
+    /// <summary>
+    /// 鏍规嵁鎶�鑳絀D鑾峰彇鎶�鑳藉悕绉�
+    /// </summary>
+    private string GetSkillName(uint skillID)
+    {
+        try
+        {
+            var skillConfig = SkillConfig.Get((int)skillID);
+            if (skillConfig != null && !string.IsNullOrEmpty(skillConfig.SkillName))
+            {
+                return skillConfig.SkillName;
+            }
+        }
+        catch { }
+        
+        return $"鎶�鑳絳skillID}";
+    }
+    
+    #endregion
+    
+    #region 楂樹寒鍜屾粴鍔�
+    
+    /// <summary>
+    /// 寮�濮嬮珮浜竴涓寘
+    /// </summary>
+    private void StartHighlight(PackageInfo package)
+    {
+        highlightedPackage = package;
+        highlightStartTime = EditorApplication.timeSinceStartup;
+    }
+    
+    /// <summary>
+    /// 鍒ゆ柇鍖呮槸鍚﹀浜庨珮浜姸鎬�
+    /// </summary>
+    private bool IsPackageHighlighted(PackageInfo package)
+    {
+        if (highlightedPackage == null || highlightedPackage != package)
+            return false;
+            
+        double elapsed = EditorApplication.timeSinceStartup - highlightStartTime;
+        return elapsed < highlightDuration;
+    }
+    
+    /// <summary>
+    /// 婊氬姩鍒伴�変腑鐨勫寘浣嶇疆
+    /// </summary>
+    private void ScrollToSelectedPackage()
+    {
+        if (selectedPackageIndex < 0 || filteredPackages.Count == 0)
+            return;
+            
+        // 璁$畻鐩爣婊氬姩浣嶇疆
+        // 姣忎釜鍖呮潯鐩殑澶ф楂樺害锛堝彲鏍规嵁瀹為檯鎯呭喌璋冩暣锛�
+        float itemHeight = 60f;
+        float targetY = selectedPackageIndex * itemHeight;
+        
+        // 婊氬姩鍒扮洰鏍囦綅缃�
+        scrollPosition.y = targetY;
+        
+        Repaint();
+    }
+    
+    #endregion
+    
     #region 鏁版嵁澶勭悊
     
     private void RefreshGuidList()

--
Gitblit v1.8.0