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();
}
}
}