edit tool

This commit is contained in:
VDH
2025-09-16 15:34:48 +07:00
parent 6d49aef738
commit 2f109d039f
5 changed files with 76 additions and 132 deletions
+25 -97
View File
@@ -2,14 +2,14 @@
#if UNITY_EDITOR
using System;
using System.IO;
using System.Threading;
using UnityEditor;
using UnityEngine;
public static class EditorLogTools
{
// ===== Public Menu =====
[MenuItem("Tools/Logs/Clear Editor.log")]
public static void ClearEditorLogMenu()
[MenuItem("Tools/Logs/Delete Editor.log")]
public static void DeleteEditorLogMenu()
{
string path = GetEditorLogPath();
if (string.IsNullOrEmpty(path))
@@ -20,121 +20,49 @@ public static class EditorLogTools
if (!File.Exists(path))
{
EditorUtility.DisplayDialog("Editor.log", $"Không tìm thấy file:\n{path}", "OK");
EditorUtility.DisplayDialog("Editor.log", $"Không tìm thấy file (có thể đã bị xóa):\n{path}", "OK");
return;
}
try
{
TruncateFile(path);
EditorUtility.DisplayDialog("Editor.log", "Đã xoá sạch nội dung Editor.log ✅", "OK");
TryDeleteOrTruncate(path);
EditorUtility.DisplayDialog("Editor.log", "Đã xoá/clear Editor.log ✅", "OK");
}
catch (Exception e)
{
Debug.LogError($"[EditorLogTools] Clear failed: {e}");
Debug.LogError($"[EditorLogTools] Delete failed: {e}");
EditorUtility.DisplayDialog("Editor.log", "Xoá thất bại. Xem Console để biết chi tiết.", "OK");
}
}
[MenuItem("Tools/Logs/Trim Editor.log…")]
public static void TrimEditorLogMenu()
// ===== Helpers =====
private static void TryDeleteOrTruncate(string path)
{
string input = EditorUtility.DisplayDialogComplex("Trim Editor.log",
"Chọn kích thước còn lại của Editor.log sau khi cắt:",
"Giữ 256 KB", "Giữ 1 MB", "Tự nhập (KB)") switch
// Thử xóa với một vài lần retry (phòng trường hợp bị lock ngắn hạn)
const int retries = 3;
for (int i = 0; i < retries; i++)
{
0 => "256",
1 => "1024",
_ => EditorUtility.DisplayDialog("Nhập dung lượng", "Nhập số KB muốn giữ lại (ví dụ 512):", "OK")
? "512" // fallback, Unity không có input prompt chuẩn; giữ default
: null
};
if (string.IsNullOrEmpty(input)) return;
if (!int.TryParse(input, out int keepKb) || keepKb < 1) keepKb = 512;
string path = GetEditorLogPath();
if (!File.Exists(path))
{
EditorUtility.DisplayDialog("Editor.log", $"Không tìm thấy file:\n{path}", "OK");
return;
try
{
File.Delete(path);
return; // xóa OK
}
catch (IOException)
{
// đợi rồi thử lại
Thread.Sleep(80);
}
}
try
{
TrimTail(path, keepKb * 1024);
EditorUtility.DisplayDialog("Editor.log", $"Đã cắt Editor.log, giữ lại ~{keepKb} KB cuối cùng ✅", "OK");
}
catch (Exception e)
{
Debug.LogError($"[EditorLogTools] Trim failed: {e}");
EditorUtility.DisplayDialog("Editor.log", "Trim thất bại. Xem Console để biết chi tiết.", "OK");
}
}
[MenuItem("Tools/Logs/Open Editor.log")]
public static void OpenEditorLogMenu()
{
string path = GetEditorLogPath();
if (File.Exists(path))
EditorUtility.OpenWithDefaultApp(path);
else
EditorUtility.DisplayDialog("Editor.log", $"Không tìm thấy file:\n{path}", "OK");
}
[MenuItem("Tools/Logs/Reveal log folder")]
public static void RevealLogFolder()
{
string path = GetEditorLogPath();
string dir = string.IsNullOrEmpty(path) ? null : Path.GetDirectoryName(path);
if (!string.IsNullOrEmpty(dir) && Directory.Exists(dir))
EditorUtility.RevealInFinder(dir);
else
EditorUtility.DisplayDialog("Editor.log", "Không mở được thư mục log.", "OK");
}
// ===== Core =====
private static void TruncateFile(string path)
{
// Cho phép Editor tiếp tục ghi khi ta truncate (FileShare.ReadWrite)
// Nếu vẫn không xóa được (bị lock bởi Editor), ta truncate để file rỗng
using var fs = new FileStream(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite);
fs.SetLength(0);
fs.Flush(true);
}
private static void TrimTail(string path, int keepBytes)
{
var fi = new FileInfo(path);
long size = fi.Length;
if (size <= keepBytes)
return; // không cần cắt
// đọc phần đuôi rồi ghi đè lại
byte[] buffer;
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
fs.Seek(size - keepBytes, SeekOrigin.Begin);
buffer = new byte[keepBytes];
int read = fs.Read(buffer, 0, keepBytes);
if (read < keepBytes)
{
Array.Resize(ref buffer, read);
}
}
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Write, FileShare.ReadWrite))
{
fs.SetLength(0);
fs.Write(buffer, 0, buffer.Length);
fs.Flush(true);
}
}
// ===== OS Paths =====
private static string GetEditorLogPath()
{
// Tham chiếu đường dẫn theo Unity docs
switch (Application.platform)
{
case RuntimePlatform.WindowsEditor:
@@ -145,10 +73,10 @@ public static class EditorLogTools
case RuntimePlatform.OSXEditor:
// ~/Library/Logs/Unity/Editor.log
string home = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
return Path.Combine(home, "Library", "Logs", "Unity", "Editor.log");
return Path.Combine(home, "Library", "Logs", "Unity", "Editor", "Editor.log");
case RuntimePlatform.LinuxEditor:
// ~/.config/unity3d/Editor.log (đường dẫn phổ biến cho Editor)
// ~/.config/unity3d/Editor.log
string homeLinux = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
return Path.Combine(homeLinux, ".config", "unity3d", "Editor.log");
Binary file not shown.
@@ -32,7 +32,8 @@ namespace BrewMonster
instance = this;
//TODO: Remove later
EC_ManPlayer = new EC_ManPlayer();
EC_ManMessage.RegisterHandler(EC_ManPlayer);
EC_ManMessage.RegisterHandler(EC_ManPlayer);
Debug.Log($"EC_ManMessage RegisterHandlerRegisterHandlerRegisterHandler");
}
private void OnDestroy()
@@ -95,11 +95,12 @@ namespace BrewMonster.UI
isDoneNPCRender = false;
Action actLoadChar = () =>
{
Debug.Log(" isDoneNPCRender || !isDoneWorldRende.isDoneNPCRender || !isDoneWorldRende(");
if (!isDoneNPCRender || !isDoneWorldRender)
{
return;
}
Debug.Log(" UnityGameSession.SendProtocol(");
// now we have to enter the world
UnityGameSession.SendProtocol(
new enterworld()
+47 -33
View File
@@ -25,25 +25,29 @@ public static class EventBus
// ===== GLOBAL STRUCT EVENTS =====
public static void Subscribe<T>(Action<T> listener) where T : struct
{
if (!globalListeners.ContainsKey(typeof(T)))
globalListeners[typeof(T)] = null;
var type = typeof(T);
globalListeners[typeof(T)] = (Action<T>)globalListeners[typeof(T)] + listener;
if (!globalListeners.ContainsKey(typeof(T)))
globalListeners[type] = null;
globalListeners[type] = (Action<T>)globalListeners[type] + listener;
}
public static void Unsubscribe<T>(Action<T> listener) where T : struct
{
var type = typeof(T);
if (globalListeners.ContainsKey(typeof(T)))
{
globalListeners[typeof(T)] = (Action<T>)globalListeners[typeof(T)] - listener;
if (globalListeners[typeof(T)] == null)
globalListeners.Remove(typeof(T));
globalListeners[type] = (Action<T>)globalListeners[type] - listener;
if (globalListeners[type] == null)
globalListeners.Remove(type);
}
}
public static void Publish<T>(T eventData) where T : struct
{
if (globalListeners.TryGetValue(typeof(T), out var del) && del is Action<T> action)
var type = typeof(T);
if (globalListeners.TryGetValue(type, out var del) && del is Action<T> action)
{
DebugLog($"Publish Global Struct Event: {typeof(T).Name}");
action.Invoke(eventData);
@@ -53,25 +57,28 @@ public static class EventBus
// ===== GLOBAL CLASS EVENTS =====
public static void SubscribeClass<T>(Action<T> listener) where T : class
{
if (!globalClassListeners.ContainsKey(typeof(T)))
globalClassListeners[typeof(T)] = null;
var type = typeof(T);
if (!globalClassListeners.ContainsKey(type))
globalClassListeners[type] = null;
globalClassListeners[typeof(T)] = (Action<T>)globalClassListeners[typeof(T)] + listener;
globalClassListeners[type] = (Action<T>)globalClassListeners[type] + listener;
}
public static void UnsubscribeClass<T>(Action<T> listener) where T : class
{
if (globalClassListeners.ContainsKey(typeof(T)))
var type = typeof(T);
if (globalClassListeners.ContainsKey(type))
{
globalClassListeners[typeof(T)] = (Action<T>)globalClassListeners[typeof(T)] - listener;
if (globalClassListeners[typeof(T)] == null)
globalClassListeners.Remove(typeof(T));
globalClassListeners[type] = (Action<T>)globalClassListeners[type] - listener;
if (globalClassListeners[type] == null)
globalClassListeners.Remove(type);
}
}
public static void PublishClass<T>(T eventData) where T : class
{
if (globalClassListeners.TryGetValue(typeof(T), out var del) && del is Action<T> action)
var type = typeof(T);
if (globalClassListeners.TryGetValue(type, out var del) && del is Action<T> action)
{
DebugLog($"Publish Global Class Event: {typeof(T).Name}");
action.Invoke(eventData);
@@ -81,22 +88,25 @@ public static class EventBus
// ===== CHANNEL STRUCT EVENTS =====
public static void SubscribeChannel<T>(int channelId, Action<T> listener) where T : struct
{
var type = typeof(T);
if (!channelListeners.ContainsKey(channelId))
channelListeners[channelId] = new Dictionary<Type, Delegate>();
if (!channelListeners[channelId].ContainsKey(typeof(T)))
channelListeners[channelId][typeof(T)] = null;
if (!channelListeners[channelId].ContainsKey(type))
channelListeners[channelId][type] = null;
channelListeners[channelId][typeof(T)] = (Action<T>)channelListeners[channelId][typeof(T)] + listener;
channelListeners[channelId][type] = (Action<T>)channelListeners[channelId][type] + listener;
}
public static void UnsubscribeChannel<T>(int channelId, Action<T> listener) where T : struct
{
if (channelListeners.ContainsKey(channelId) && channelListeners[channelId].ContainsKey(typeof(T)))
var type = typeof(T);
if (channelListeners.ContainsKey(channelId) && channelListeners[channelId].ContainsKey(type))
{
channelListeners[channelId][typeof(T)] = (Action<T>)channelListeners[channelId][typeof(T)] - listener;
if (channelListeners[channelId][typeof(T)] == null)
channelListeners[channelId].Remove(typeof(T));
channelListeners[channelId][type] = (Action<T>)channelListeners[channelId][type] - listener;
if (channelListeners[channelId][type] == null)
channelListeners[channelId].Remove(type);
if (channelListeners[channelId].Count == 0)
channelListeners.Remove(channelId);
}
@@ -104,11 +114,12 @@ public static class EventBus
public static void PublishChannel<T>(int channelId, T eventData) where T : struct
{
var type = typeof(T);
if (channelListeners.TryGetValue(channelId, out var listeners) &&
listeners.TryGetValue(typeof(T), out var del) &&
listeners.TryGetValue(type, out var del) &&
del is Action<T> action)
{
DebugLog($"Publish Channel Struct Event: {typeof(T).Name} to channel '{channelId}'");
DebugLog($"Publish Channel Struct Event: {type.Name} to channel '{channelId}'");
action.Invoke(eventData);
}
}
@@ -116,22 +127,24 @@ public static class EventBus
// ===== CHANNEL CLASS EVENTS =====
public static void SubscribeChannelClass<T>(int channelId, Action<T> listener) where T : class
{
var type = typeof(T);
if (!channelClassListeners.ContainsKey(channelId))
channelClassListeners[channelId] = new Dictionary<Type, Delegate>();
if (!channelClassListeners[channelId].ContainsKey(typeof(T)))
channelClassListeners[channelId][typeof(T)] = null;
if (!channelClassListeners[channelId].ContainsKey(type))
channelClassListeners[channelId][type] = null;
channelClassListeners[channelId][typeof(T)] = (Action<T>)channelClassListeners[channelId][typeof(T)] + listener;
channelClassListeners[channelId][type] = (Action<T>)channelClassListeners[channelId][type] + listener;
}
public static void UnsubscribeChannelClass<T>(int channelId, Action<T> listener) where T : class
{
if (channelClassListeners.ContainsKey(channelId) && channelClassListeners[channelId].ContainsKey(typeof(T)))
var type = typeof(T);
if (channelClassListeners.ContainsKey(channelId) && channelClassListeners[channelId].ContainsKey(type))
{
channelClassListeners[channelId][typeof(T)] = (Action<T>)channelClassListeners[channelId][typeof(T)] - listener;
if (channelClassListeners[channelId][typeof(T)] == null)
channelClassListeners[channelId].Remove(typeof(T));
channelClassListeners[channelId][type] = (Action<T>)channelClassListeners[channelId][type] - listener;
if (channelClassListeners[channelId][type] == null)
channelClassListeners[channelId].Remove(type);
if (channelClassListeners[channelId].Count == 0)
channelClassListeners.Remove(channelId);
}
@@ -139,11 +152,12 @@ public static class EventBus
public static void PublishChannelClass<T>(int channelId, T eventData) where T : class
{
var type = typeof(T);
if (channelClassListeners.TryGetValue(channelId, out var listeners) &&
listeners.TryGetValue(typeof(T), out var del) &&
listeners.TryGetValue(type, out var del) &&
del is Action<T> action)
{
DebugLog($"Publish Channel Class Event: {typeof(T).Name} to channel '{channelId}'");
DebugLog($"Publish Channel Class Event: {type.Name} to channel '{channelId}'");
action.Invoke(eventData);
}
}