using UnityEngine; using UnityEditor; using System.Collections.Generic; using System.Linq; using System.IO; public class GMQuickPlayingEditor : EditorWindow { private string searchText = ""; private string commandText = ""; private Vector2 scrollPosition; private Vector2 reportScrollPosition; private Vector2 battleInfoScrollPosition; private List searchResults = new List(); private int itemCount = 1; private bool isBattlePaused = false; private bool showBattleInfo = false; // 控制战场信息显示/隐藏 // 战报相关 private string reportFilePath = ""; private string[] reportFiles = new string[0]; private int selectedReportIndex = 0; [MenuItem("Tools/GM快捷工具 &9")] public static void ShowWindow() { GetWindow("GM快捷工具"); } private void OnEnable() { RefreshReportList(); } private void Update() { // 每帧更新战场信息 Repaint(); } private void OnGUI() { GUILayout.BeginHorizontal(); // ========== 左侧面板 ========== float leftWidth = showBattleInfo ? position.width * 0.6f : position.width - 20; GUILayout.BeginVertical("box", GUILayout.Width(leftWidth)); // 搜索栏 GUILayout.Label("物品搜索", EditorStyles.boldLabel); GUILayout.BeginHorizontal(); searchText = EditorGUILayout.TextField("搜索:", searchText); if (GUILayout.Button("查询物品", GUILayout.Width(80))) { OnSearchItem(); } GUILayout.EndHorizontal(); GUILayout.Space(10); // 搜索结果显示区域 GUILayout.BeginHorizontal(); GUILayout.Label($"搜索结果 ({searchResults.Count})", EditorStyles.boldLabel); GUILayout.FlexibleSpace(); if (GUILayout.Button("清空列表", GUILayout.Width(80))) { searchResults.Clear(); } GUILayout.EndHorizontal(); scrollPosition = GUILayout.BeginScrollView(scrollPosition, GUILayout.Height(200)); GUILayout.BeginVertical("box"); if (searchResults.Count > 0) { foreach (var item in searchResults) { GUILayout.BeginHorizontal("box"); GUILayout.Label($"ID: {item.ID}", GUILayout.Width(80)); GUILayout.Label($"名称: {item.ItemName}", GUILayout.Width(150)); GUILayout.Label($"等级: {item.LV}", GUILayout.Width(60)); if (GUILayout.Button("选择", GUILayout.Width(60))) { OnSelectItem(item); } GUILayout.EndHorizontal(); } } else { GUILayout.Label("搜索结果将在这里显示..."); } GUILayout.EndVertical(); GUILayout.EndScrollView(); GUILayout.Space(10); // 数量输入 GUILayout.BeginHorizontal(); GUILayout.Label("物品数量:", GUILayout.Width(80)); itemCount = EditorGUILayout.IntField(itemCount, GUILayout.Width(100)); GUILayout.EndHorizontal(); GUILayout.Space(10); // GM命令编辑区域 GUILayout.Label("GM命令", EditorStyles.boldLabel); GUILayout.BeginVertical("box"); commandText = EditorGUILayout.TextArea(commandText, GUILayout.Height(60)); GUILayout.EndVertical(); GUILayout.Space(5); // 发送命令按钮 GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); if (GUILayout.Button("发送命令", GUILayout.Width(100), GUILayout.Height(30))) { OnSendCommand(); } if (GUILayout.Button("清空", GUILayout.Width(60), GUILayout.Height(30))) { commandText = ""; } GUILayout.EndHorizontal(); GUILayout.Space(10); // 提示信息 GUIStyle warningStyle = new GUIStyle(EditorStyles.helpBox); warningStyle.normal.textColor = new Color(1f, 0.6f, 0f); warningStyle.fontSize = 11; EditorGUILayout.LabelField("⚠ 添加物品最好跟服务器确认过物品的存在后再添加", warningStyle); GUILayout.Space(10); // 战报浏览区域 GUILayout.Label("战报浏览", EditorStyles.boldLabel); GUILayout.BeginVertical("box"); GUILayout.BeginHorizontal(); if (GUILayout.Button("刷新战报列表", GUILayout.Width(120))) { RefreshReportList(); } if (GUILayout.Button("打开战报文件夹", GUILayout.Width(120))) { OpenReportFolder(); } GUILayout.EndHorizontal(); GUILayout.Space(5); if (reportFiles.Length > 0) { reportScrollPosition = GUILayout.BeginScrollView(reportScrollPosition, GUILayout.Height(150)); for (int i = 0; i < reportFiles.Length; i++) { GUILayout.BeginHorizontal("box"); string fileName = Path.GetFileName(reportFiles[i]); GUILayout.Label(fileName, GUILayout.Width(300)); if (GUILayout.Button("加载", GUILayout.Width(60))) { LoadReport(reportFiles[i]); } if (GUILayout.Button("删除", GUILayout.Width(60))) { DeleteReport(reportFiles[i]); } GUILayout.EndHorizontal(); } GUILayout.EndScrollView(); } else { GUILayout.Label("未找到战报文件(.bytes)"); } GUILayout.EndVertical(); GUILayout.Space(10); // 战场信息Toggle GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); GUILayout.Label("显示战场信息", GUILayout.Width(100)); showBattleInfo = EditorGUILayout.Toggle(showBattleInfo, GUILayout.Width(20)); GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.EndVertical(); // ========== 右侧面板 - 战场信息 ========== if (showBattleInfo) { // 分割线 GUILayout.Box("", GUILayout.Width(2), GUILayout.ExpandHeight(true)); GUILayout.BeginVertical("box", GUILayout.ExpandWidth(true)); GUILayout.Label("战场信息", EditorStyles.boldLabel); // 暂停/开始战斗按钮 GUILayout.BeginHorizontal(); GUILayout.FlexibleSpace(); string buttonText = isBattlePaused ? "开始当前战斗" : "暂停当前战斗"; if (GUILayout.Button(buttonText, GUILayout.Width(120), GUILayout.Height(30))) { OnPauseBattle(); } GUILayout.FlexibleSpace(); GUILayout.EndHorizontal(); GUILayout.Space(5); battleInfoScrollPosition = GUILayout.BeginScrollView(battleInfoScrollPosition); DrawBattleFieldInfo(); GUILayout.EndScrollView(); GUILayout.EndVertical(); } GUILayout.EndHorizontal(); } private void DrawBattleFieldInfo() { BattleField battleField = GetActiveBattleField(); if (battleField == null) { GUILayout.Label("暂无战场", EditorStyles.centeredGreyMiniLabel); return; } // 战场基本信息 GUILayout.BeginVertical("box"); GUILayout.Label($"战场类型: {battleField.GetType().Name}", EditorStyles.boldLabel); GUILayout.Label($"GUID: {battleField.guid}"); GUILayout.Label($"地图ID: {battleField.MapID}"); GUILayout.Label($"暂停状态: {battleField.IsPause}"); GUILayout.EndVertical(); GUILayout.Space(10); // 红方队伍信息 DrawTeamInfo("红方队伍", battleField.battleObjMgr.redCampList, new Color(1f, 0.5f, 0.5f)); GUILayout.Space(10); // 蓝方队伍信息 DrawTeamInfo("蓝方队伍", battleField.battleObjMgr.blueCampList, new Color(0.5f, 0.5f, 1f)); } private void DrawTeamInfo(string teamName, List team, Color headerColor) { GUIStyle headerStyle = new GUIStyle(EditorStyles.boldLabel); headerStyle.normal.textColor = headerColor; GUILayout.Label(teamName, headerStyle); if (team == null || team.Count == 0) { GUILayout.Label(" 无角色", EditorStyles.miniLabel); return; } foreach (var obj in team) { if (obj == null || obj.teamHero == null) continue; GUILayout.BeginVertical("box"); // 角色名称和ID GUILayout.BeginHorizontal(); GUILayout.Label($"ID: {obj.ObjID}", GUILayout.Width(80)); GUILayout.Label($"名称: {obj.teamHero.name}", GUILayout.ExpandWidth(true)); GUILayout.EndHorizontal(); // 血量信息 long curHp = obj.teamHero.curHp; long maxHp = obj.teamHero.maxHp; float hpPercent = maxHp > 0 ? (float)curHp / maxHp : 0f; GUILayout.BeginHorizontal(); GUILayout.Label("血量:", GUILayout.Width(50)); // 血条 Rect hpBarRect = GUILayoutUtility.GetRect(100, 18); EditorGUI.DrawRect(hpBarRect, new Color(0.3f, 0.3f, 0.3f)); Rect hpFillRect = new Rect(hpBarRect.x, hpBarRect.y, hpBarRect.width * hpPercent, hpBarRect.height); Color hpColor = hpPercent > 0.5f ? Color.green : hpPercent > 0.2f ? Color.yellow : Color.red; EditorGUI.DrawRect(hpFillRect, hpColor); GUILayout.Label($"{curHp}/{maxHp} ({(hpPercent * 100f):F1}%)", GUILayout.Width(150)); GUILayout.EndHorizontal(); // 怒气信息 long curMp = obj.teamHero.rage; long maxMp = 100; float mpPercent = maxMp > 0 ? (float)curMp / maxMp : 0f; GUILayout.BeginHorizontal(); GUILayout.Label("怒气:", GUILayout.Width(50)); // 怒气条 Rect mpBarRect = GUILayoutUtility.GetRect(100, 18); EditorGUI.DrawRect(mpBarRect, new Color(0.3f, 0.3f, 0.3f)); Rect mpFillRect = new Rect(mpBarRect.x, mpBarRect.y, mpBarRect.width * mpPercent, mpBarRect.height); EditorGUI.DrawRect(mpFillRect, new Color(1f, 0.5f, 0f)); // 橙色 GUILayout.Label($"{curMp}/{maxMp} ({(mpPercent * 100f):F1}%)", GUILayout.Width(150)); GUILayout.EndHorizontal(); GUILayout.EndVertical(); } } private BattleField GetActiveBattleField() { if (!Application.isPlaying) return null; for (int i = 0; i < BattleConst.BattleWindows.Count; i++) { var win = UIManager.Instance.GetUI(BattleConst.BattleWindows[i].Name); if (win != null && win.IsActive()) { // 使用反射获取 battleField 字段 var battleFieldField = win.GetType().GetField("battleField", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (battleFieldField != null) { var battleField = battleFieldField.GetValue(win) as BattleField; if (battleField != null) { return battleField; } } } } return null; } private void RefreshReportList() { string reportFolder = Application.dataPath + "/../BattleReport/"; if (Directory.Exists(reportFolder)) { reportFiles = Directory.GetFiles(reportFolder, "*.bytes"); Debug.Log($"找到 {reportFiles.Length} 个战报文件"); } else { Directory.CreateDirectory(reportFolder); reportFiles = new string[0]; Debug.Log("创建战报文件夹: " + reportFolder); } } private void OpenReportFolder() { string reportFolder = Application.dataPath + "/../BattleReport/"; if (!Directory.Exists(reportFolder)) { Directory.CreateDirectory(reportFolder); } EditorUtility.RevealInFinder(reportFolder); } private void LoadReport(string filePath) { if (!File.Exists(filePath)) { Debug.LogError("战报文件不存在: " + filePath); return; } reportFilePath = filePath; Debug.Log("已加载战报: " + Path.GetFileName(filePath)); HB430_tagSCTurnFightReport hB430_TagSCTurnFightReport = new HB430_tagSCTurnFightReport(); hB430_TagSCTurnFightReport.isRecord = true; byte[] vBytes = File.ReadAllBytes(filePath); hB430_TagSCTurnFightReport.ReadFromBytes(vBytes); PackageRegedit.Distribute(hB430_TagSCTurnFightReport); } private void DeleteReport(string filePath) { if (!File.Exists(filePath)) { Debug.LogError("战报文件不存在: " + filePath); return; } if (EditorUtility.DisplayDialog("确认删除", $"确定要删除战报文件吗?\n{Path.GetFileName(filePath)}", "删除", "取消")) { try { File.Delete(filePath); Debug.Log("已删除战报: " + Path.GetFileName(filePath)); RefreshReportList(); } catch (System.Exception e) { Debug.LogError("删除战报文件失败: " + e.Message); } } } private string ExtractGuidFromFileName(string fileName) { // 从文件名中提取 GUID // 格式: B430_ReportBytes_{GUID}_{DateTime} string[] parts = fileName.Split('_'); if (parts.Length >= 3) { return parts[2]; // 返回 GUID 部分 } return "unknown_guid"; } private void OnSearchItem() { searchResults.Clear(); if (string.IsNullOrEmpty(searchText)) { Debug.Log("搜索文本为空"); return; } // 遍历 ItemConfig.dic 进行模糊搜索 foreach (var kvp in ItemConfig.dic) { var item = kvp.Value; if (!string.IsNullOrEmpty(item.ItemName) && item.ItemName.Contains(searchText)) { searchResults.Add(item); } } // 按 ID 排序 searchResults = searchResults.OrderBy(x => x.ID).ToList(); Debug.Log($"搜索物品: {searchText}, 找到 {searchResults.Count} 个结果"); } private void OnSelectItem(ItemConfig item) { Debug.Log($"选择物品: {item.ItemName} (ID: {item.ID})"); commandText = $"MakeItemCount {item.ID} {itemCount}"; } private void OnSendCommand() { if (string.IsNullOrEmpty(commandText)) { Debug.LogWarning("命令为空,无法发送"); return; } Debug.Log("发送命令: " + commandText); GMCmdManager.Instance.OnSendGMQuest(commandText); GMCmdManager.Instance.SetRecordCmdlist(commandText); } private void OnPauseBattle() { for (int i = 0; i < BattleConst.BattleWindows.Count; i++) { var win = UIManager.Instance.GetUI(BattleConst.BattleWindows[i].Name); if (win != null && win.IsActive()) { // 使用反射获取 battleField 字段 var battleFieldField = win.GetType().GetField("battleField", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); if (battleFieldField != null) { var battleField = battleFieldField.GetValue(win) as BattleField; if (battleField != null) { battleField.IsPause = !battleField.IsPause; isBattlePaused = battleField.IsPause; Debug.Log($"战斗暂停状态切换: {battleField.IsPause}"); return; } } } } Debug.LogWarning("未找到激活的战斗窗口或 battleField 为空"); } }