using System.Collections.Generic; using System.Linq; using System.Reflection; using HarmonyLib; using RimWorld; using UnityEngine; using Verse; namespace AIImages.Patches { /// /// Патч для получения записей лога пешки через ITab_Pawn_Log /// [HarmonyPatch(typeof(ITab_Pawn_Log), "FillTab")] public static class ITab_Pawn_Log_Patch { private static Pawn lastPawn = null; private static List cachedEntries = new List(); [HarmonyPrefix] public static void Prefix(ITab_Pawn_Log __instance) { try { // Получаем пешку через рефлексию var selPawnProp = AccessTools.Property(typeof(ITab), "SelPawn"); if (selPawnProp != null) { var pawn = selPawnProp.GetValue(__instance) as Pawn; if (pawn != null) { // Пробуем получить записи напрямую через Pawn.logs var logsProperty = AccessTools.Property(typeof(Pawn), "logs"); if (logsProperty != null) { var logs = logsProperty.GetValue(pawn); if (logs != null) { // Пробуем AllEntries var allEntriesProperty = AccessTools.Property( logs.GetType(), "AllEntries" ); if (allEntriesProperty != null) { var entries = allEntriesProperty.GetValue(logs); if (entries is IEnumerable entriesList) { cachedEntries = entriesList.ToList(); lastPawn = pawn; UnityEngine.Debug.Log( $"[AI Images] Cached {cachedEntries.Count} log entries for {pawn.Name}" ); return; } } } } } } } catch (System.Exception ex) { UnityEngine.Debug.LogWarning( $"[AI Images] ITab_Pawn_Log patch error: {ex.Message}" ); } } public static List GetCachedEntries(Pawn pawn) { if (pawn == lastPawn && cachedEntries != null && cachedEntries.Any()) { return cachedEntries; } // Если кэш не подходит, пытаемся получить напрямую if (pawn != null) { try { var logsProperty = AccessTools.Property(typeof(Pawn), "logs"); if (logsProperty != null) { var logs = logsProperty.GetValue(pawn); if (logs != null) { var allEntriesProperty = AccessTools.Property( logs.GetType(), "AllEntries" ); if (allEntriesProperty != null) { var entries = allEntriesProperty.GetValue(logs); if (entries is IEnumerable entriesList) { var list = entriesList.ToList(); if (list.Any()) { cachedEntries = list; lastPawn = pawn; return list; } } } } } } catch (System.Exception ex) { UnityEngine.Debug.LogWarning( $"[AI Images] Error getting entries directly: {ex.Message}" ); } } return new List(); } } /// /// Патч для получения записей лога пешки /// Упрощённая версия - только для получения данных /// public static class PawnLogPatch { /// /// Получает все записи лога пешки /// public static IEnumerable GetAllLogEntries(Pawn pawn) { // Сначала пробуем получить из кэша ITab_Pawn_Log var cachedEntries = ITab_Pawn_Log_Patch.GetCachedEntries(pawn); if (cachedEntries != null && cachedEntries.Any()) { return cachedEntries; } // Затем пробуем другие способы return GetAllLogEntriesInternal(pawn); } /// /// Внутренний метод получения записей лога /// private static IEnumerable GetAllLogEntriesInternal(Pawn pawn) { if (pawn == null) return Enumerable.Empty(); try { // Способ 1: Через property через reflection var logsProperty = AccessTools.Property(typeof(Pawn), "logs"); if (logsProperty != null) { var logs = logsProperty.GetValue(pawn); if (logs != null) { var allEntriesProperty = AccessTools.Property(logs.GetType(), "AllEntries"); if (allEntriesProperty != null) { var entries = allEntriesProperty.GetValue(logs); if (entries is IEnumerable entriesList) { return entriesList; } } // Пробуем метод GetEntries var getEntriesMethod = AccessTools.Method(logs.GetType(), "GetEntries"); if (getEntriesMethod != null) { var entries = getEntriesMethod.Invoke(logs, null); if (entries is IEnumerable entriesList) { return entriesList; } } // Пробуем поле entries var entriesField = AccessTools.Field(logs.GetType(), "entries"); if (entriesField != null) { var entries = entriesField.GetValue(logs); if (entries is IEnumerable entriesList) { return entriesList; } if (entries is System.Collections.IList entriesCollection) { return entriesCollection.Cast(); } } } } // Способ 3: Через story.logs if (pawn.story != null) { var logsField = AccessTools.Field(pawn.story.GetType(), "logs"); if (logsField != null) { var logs = logsField.GetValue(pawn.story); if (logs != null) { var allEntriesProperty = AccessTools.Property( logs.GetType(), "AllEntries" ); if (allEntriesProperty != null) { var entries = allEntriesProperty.GetValue(logs); if (entries is IEnumerable entriesList) { return entriesList; } } } } } } catch (System.Exception ex) { // Логируем ошибку для отладки UnityEngine.Debug.LogWarning( $"[AI Images] Error getting log entries for {pawn?.Name}: {ex.Message}" ); } // Если все способы не сработали, логируем информацию UnityEngine.Debug.Log( $"[AI Images] Could not get log entries for {pawn?.Name}. " + $"logs property exists: {AccessTools.Property(typeof(Pawn), "logs") != null}, " + $"story property exists: {AccessTools.Property(typeof(Pawn), "story") != null}" ); return Enumerable.Empty(); } } }