123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- using System;
- using System.Reflection;
- using System.Collections.Generic;
- using UnityEngine;
- using Object = UnityEngine.Object;
- namespace LLM.Editor.Analysis
- {
- /// <summary>
- /// Provides access to the Unity Editor's console log entries using reflection.
- /// </summary>
- public class ConsoleLogProvider : IContextProvider
- {
- private class ConsoleLogEntry
- {
- public string type;
- public string message;
- }
- // Reflection-based access to internal Unity log types
- private static Type _logEntriesType;
- private static MethodInfo _getCountMethod;
- private static MethodInfo _getEntryMethod;
- private static MethodInfo _startGettingEntriesMethod;
- private static MethodInfo _endGettingEntriesMethod;
- private static object _logEntryInstance;
- static ConsoleLogProvider()
- {
- // Initialize reflection types once
- _logEntriesType = Type.GetType("UnityEditor.LogEntries, UnityEditor.dll");
- if (_logEntriesType == null) return;
- _getCountMethod = _logEntriesType.GetMethod("GetCount", BindingFlags.Static | BindingFlags.Public);
- _getEntryMethod = _logEntriesType.GetMethod("GetEntryInternal", BindingFlags.Static | BindingFlags.Public);
- _startGettingEntriesMethod = _logEntriesType.GetMethod("StartGettingEntries", BindingFlags.Static | BindingFlags.Public);
- _endGettingEntriesMethod = _logEntriesType.GetMethod("EndGettingEntries", BindingFlags.Static | BindingFlags.Public);
-
- // The LogEntry class is nested within LogEntries
- var logEntryType = Type.GetType("UnityEditor.LogEntry, UnityEditor.dll");
- if (logEntryType != null)
- {
- _logEntryInstance = Activator.CreateInstance(logEntryType);
- }
- }
- public object GetContext(Object target, string qualifier)
- {
- if (_logEntriesType == null || _getCountMethod == null || _getEntryMethod == null || _logEntryInstance == null)
- {
- return "Error: Could not access Unity's internal console log API via reflection.";
- }
- // Parse the qualifier for filters (e.g., "errors:10")
- var parts = qualifier?.Split(':');
- var filterType = parts is { Length: > 0 } ? parts[0].ToLower() : "all";
- var count = (parts is { Length: > 1 } && int.TryParse(parts[1], out var num)) ? num : 10;
- var logEntries = new List<ConsoleLogEntry>();
-
- _startGettingEntriesMethod.Invoke(null, null);
- var totalCount = (int)_getCountMethod.Invoke(null, null);
- count = Mathf.Min(count, totalCount);
- for (var i = 0; i < totalCount && logEntries.Count < count; i++)
- {
- var index = totalCount - 1 - i; // Read from the most recent
- _getEntryMethod.Invoke(null, new object[] { index, _logEntryInstance });
- var message = (string)_logEntryInstance.GetType().GetField("message", BindingFlags.Instance | BindingFlags.Public)?.GetValue(_logEntryInstance);
- var mode = (int)_logEntryInstance.GetType().GetField("mode", BindingFlags.Instance | BindingFlags.Public)?.GetValue(_logEntryInstance)!;
-
- var logType = GetLogTypeFromMode(mode);
- if (filterType != "all" && (filterType != "errors" || logType != "Error") &&
- (filterType != "warnings" || logType != "Warning")) continue;
- if (message != null)
- logEntries.Add(new ConsoleLogEntry { type = logType, message = message.Trim() });
- }
- _endGettingEntriesMethod.Invoke(null, null);
- return logEntries;
- }
- private static string GetLogTypeFromMode(int mode)
- {
- // These mode values are constants defined internally in UnityEditor.LogEntry
- if ((mode & 1) != 0) return "Error"; // 0x0001
- return (mode & 2) != 0 ? "Warning" : // 0x0002
- "Log";
- }
- }
- }
|