All checks were successful
SonarQube Analysis / Build and analyze (push) Successful in 1m45s
242 lines
9.8 KiB
C#
242 lines
9.8 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using HarmonyLib;
|
|
using RimWorld;
|
|
using UnityEngine;
|
|
using Verse;
|
|
|
|
namespace AIImages.Patches
|
|
{
|
|
/// <summary>
|
|
/// Патч для получения записей лога пешки через ITab_Pawn_Log
|
|
/// </summary>
|
|
[HarmonyPatch(typeof(ITab_Pawn_Log), "FillTab")]
|
|
public static class ITab_Pawn_Log_Patch
|
|
{
|
|
private static Pawn lastPawn = null;
|
|
private static List<LogEntry> cachedEntries = new List<LogEntry>();
|
|
|
|
[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<LogEntry> 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<LogEntry> 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<LogEntry> 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<LogEntry>();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Патч для получения записей лога пешки
|
|
/// Упрощённая версия - только для получения данных
|
|
/// </summary>
|
|
public static class PawnLogPatch
|
|
{
|
|
/// <summary>
|
|
/// Получает все записи лога пешки
|
|
/// </summary>
|
|
public static IEnumerable<LogEntry> GetAllLogEntries(Pawn pawn)
|
|
{
|
|
// Сначала пробуем получить из кэша ITab_Pawn_Log
|
|
var cachedEntries = ITab_Pawn_Log_Patch.GetCachedEntries(pawn);
|
|
if (cachedEntries != null && cachedEntries.Any())
|
|
{
|
|
return cachedEntries;
|
|
}
|
|
|
|
// Затем пробуем другие способы
|
|
return GetAllLogEntriesInternal(pawn);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Внутренний метод получения записей лога
|
|
/// </summary>
|
|
private static IEnumerable<LogEntry> GetAllLogEntriesInternal(Pawn pawn)
|
|
{
|
|
if (pawn == null)
|
|
return Enumerable.Empty<LogEntry>();
|
|
|
|
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<LogEntry> entriesList)
|
|
{
|
|
return entriesList;
|
|
}
|
|
}
|
|
|
|
// Пробуем метод GetEntries
|
|
var getEntriesMethod = AccessTools.Method(logs.GetType(), "GetEntries");
|
|
if (getEntriesMethod != null)
|
|
{
|
|
var entries = getEntriesMethod.Invoke(logs, null);
|
|
if (entries is IEnumerable<LogEntry> entriesList)
|
|
{
|
|
return entriesList;
|
|
}
|
|
}
|
|
|
|
// Пробуем поле entries
|
|
var entriesField = AccessTools.Field(logs.GetType(), "entries");
|
|
if (entriesField != null)
|
|
{
|
|
var entries = entriesField.GetValue(logs);
|
|
if (entries is IEnumerable<LogEntry> entriesList)
|
|
{
|
|
return entriesList;
|
|
}
|
|
if (entries is System.Collections.IList entriesCollection)
|
|
{
|
|
return entriesCollection.Cast<LogEntry>();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Способ 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<LogEntry> 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<LogEntry>();
|
|
}
|
|
}
|
|
}
|