Enhance AIImages mod by adding debug logging functionality to various components, improving troubleshooting capabilities. Introduce a new setting to enable or disable debug logs in the UI, with localized strings in English and Russian. Update StableDiffusionNet.Core dependency to version 1.1.5. Update AIImages.dll to reflect these changes.

This commit is contained in:
Leonid Pershin
2025-10-28 19:01:38 +03:00
parent 0bdcd3036a
commit beb1e2b2fc
14 changed files with 385 additions and 52 deletions

View File

@@ -83,11 +83,15 @@ namespace AIImages
/// </summary>
private void RefreshPawnData()
{
DebugLogger.Log($"[AI Images] RefreshPawnData called for {pawn?.Name}");
appearanceData = pawnDescriptionService.ExtractAppearanceData(pawn);
generationSettings = AIImagesMod.Settings.ToStableDiffusionSettings();
// Загружаем сохраненный портрет, если есть
LoadSavedPortrait();
DebugLogger.Log($"[AI Images] RefreshPawnData completed for {pawn?.Name}");
}
/// <summary>
@@ -95,13 +99,30 @@ namespace AIImages
/// </summary>
private void LoadSavedPortrait()
{
DebugLogger.Log($"[AI Images] LoadSavedPortrait called for {pawn?.Name}");
if (PawnPortraitHelper.HasPortrait(pawn))
{
DebugLogger.Log($"[AI Images] Portrait found for {pawn?.Name}, loading...");
generatedImage = PawnPortraitHelper.LoadPortrait(pawn);
if (generatedImage != null)
{
generationStatus = "AIImages.Generation.LoadedFromSave".Translate();
DebugLogger.Log($"[AI Images] Successfully loaded portrait for {pawn?.Name}");
DebugLogger.Log(
$"[AI Images] generatedImage is now set: {generatedImage != null}, size: {generatedImage.width}x{generatedImage.height}"
);
}
else
{
DebugLogger.Warning(
$"[AI Images] Failed to load portrait texture for {pawn?.Name}"
);
}
}
else
{
DebugLogger.Log($"[AI Images] No saved portrait found for {pawn?.Name}");
}
}
@@ -127,13 +148,36 @@ namespace AIImages
/// </summary>
public void UpdatePawn(Pawn newPawn)
{
DebugLogger.Log(
$"[AI Images] UpdatePawn called - switching from {pawn?.Name} to {newPawn?.Name}"
);
this.pawn = newPawn;
RefreshPawnData();
// Очищаем старое изображение при смене персонажа
generatedImage = null;
generationStatus = "";
generationProgress = 0.0;
currentStep = 0;
totalSteps = 0;
etaSeconds = 0.0;
// Сбрасываем состояние сворачиваемых секций
showPositivePrompt = false;
showNegativePrompt = false;
// Обновляем данные персонажа (включая загрузку портрета)
RefreshPawnData();
// Принудительно обновляем окно
this.windowRect = new Rect(
this.windowRect.x,
this.windowRect.y,
this.InitialSize.x,
this.InitialSize.y
);
DebugLogger.Log($"[AI Images] UpdatePawn completed for {newPawn?.Name}");
}
/// <summary>
@@ -141,6 +185,80 @@ namespace AIImages
/// </summary>
public Pawn CurrentPawn => pawn;
/// <summary>
/// Отладочный метод для проверки состояния всех пешек
/// </summary>
public static void DebugAllPawns()
{
DebugLogger.Log("[AI Images] === DEBUG: Checking all pawns ===");
if (Current.Game?.Maps == null)
{
DebugLogger.Log("[AI Images] No game or maps available");
return;
}
int totalPawns = 0;
int pawnsWithComponents = 0;
int pawnsWithPortraits = 0;
foreach (var map in Current.Game.Maps)
{
foreach (var pawn in map.mapPawns.AllPawns)
{
if (pawn.RaceProps?.Humanlike == true)
{
totalPawns++;
var (hasComponent, hasPortrait) = CheckPawnPortraitStatus(pawn);
if (hasComponent)
pawnsWithComponents++;
if (hasPortrait)
pawnsWithPortraits++;
}
}
}
LogDebugSummary(totalPawns, pawnsWithComponents, pawnsWithPortraits);
}
private static (bool hasComponent, bool hasPortrait) CheckPawnPortraitStatus(Pawn pawn)
{
var comp = PawnPortraitHelper.GetPortraitComp(pawn);
if (comp != null)
{
if (comp.HasPortrait)
{
DebugLogger.Log(
$"[AI Images] {pawn.Name}: Has component with portrait '{comp.PortraitPath}'"
);
return (true, true);
}
else
{
DebugLogger.Log($"[AI Images] {pawn.Name}: Has component but no portrait");
return (true, false);
}
}
else
{
DebugLogger.Warning($"[AI Images] {pawn.Name}: No portrait component found!");
return (false, false);
}
}
private static void LogDebugSummary(
int totalPawns,
int pawnsWithComponents,
int pawnsWithPortraits
)
{
DebugLogger.Log($"[AI Images] === DEBUG SUMMARY ===");
DebugLogger.Log($"[AI Images] Total humanlike pawns: {totalPawns}");
DebugLogger.Log($"[AI Images] Pawns with components: {pawnsWithComponents}");
DebugLogger.Log($"[AI Images] Pawns with portraits: {pawnsWithPortraits}");
DebugLogger.Log($"[AI Images] === END DEBUG ===");
}
/// <summary>
/// Вызывается каждый кадр для обновления окна
/// </summary>
@@ -238,6 +356,12 @@ namespace AIImages
if (result.Success)
{
DebugLogger.Log($"[AI Images] Generation successful for {pawn?.Name}");
DebugLogger.Log(
$"[AI Images] Image data size: {result.ImageData?.Length ?? 0} bytes"
);
DebugLogger.Log($"[AI Images] Saved path: {result.SavedPath}");
// Загружаем текстуру
generatedImage = new Texture2D(2, 2);
generatedImage.LoadImage(result.ImageData);
@@ -245,12 +369,19 @@ namespace AIImages
generationProgress = 1.0;
// Сохраняем путь к портрету на персонаже
DebugLogger.Log(
$"[AI Images] About to save portrait path for {pawn?.Name}: {result.SavedPath}"
);
PawnPortraitHelper.SavePortraitPath(pawn, result.SavedPath);
Messages.Message(
"AIImages.Generation.SavedTo".Translate(result.SavedPath),
MessageTypeDefOf.PositiveEvent
);
DebugLogger.Log(
$"[AI Images] Portrait generation and saving completed for {pawn?.Name}"
);
}
else
{
@@ -262,12 +393,12 @@ namespace AIImages
catch (OperationCanceledException)
{
generationStatus = "AIImages.Generation.Cancelled".Translate();
Log.Message("[AI Images] Generation cancelled by user");
DebugLogger.Log("[AI Images] Generation cancelled by user");
}
catch (Exception ex)
{
generationStatus = $"Error: {ex.Message}";
Log.Error($"[AI Images] Generation error: {ex}");
DebugLogger.Error($"[AI Images] Generation error: {ex}");
Messages.Message(
$"AIImages.Generation.Error".Translate() + ": {ex.Message}",
MessageTypeDefOf.RejectInput
@@ -299,7 +430,7 @@ namespace AIImages
totalSteps = progress.TotalSteps;
etaSeconds = progress.EtaRelative;
Log.Message(
DebugLogger.Log(
$"[AI Images] Progress: {progress.Progress:P} - Step {progress.CurrentStep}/{progress.TotalSteps} - ETA: {progress.EtaRelative:F1}s"
);
}
@@ -314,7 +445,7 @@ namespace AIImages
}
catch (Exception ex)
{
Log.Warning($"[AI Images] Progress monitoring error: {ex.Message}");
DebugLogger.Warning($"[AI Images] Progress monitoring error: {ex.Message}");
}
}
@@ -910,13 +1041,24 @@ namespace AIImages
? "AIImages.Generation.Cancel".Translate()
: "AIImages.Generation.Generate".Translate();
if (Widgets.ButtonText(new Rect(rect.x, curY, rect.width, 35f), buttonLabel))
// Основная кнопка генерации (занимает 70% ширины)
float buttonWidth = rect.width * 0.7f;
if (Widgets.ButtonText(new Rect(rect.x, curY, buttonWidth, 35f), buttonLabel))
{
if (isGenerating)
CancelGeneration();
else
StartGeneration();
}
// Отладочная кнопка (занимает 25% ширины)
float debugButtonWidth = rect.width * 0.25f;
float debugButtonX = rect.x + buttonWidth + 10f;
if (Widgets.ButtonText(new Rect(debugButtonX, curY, debugButtonWidth, 35f), "Debug"))
{
DebugAllPawns();
}
return curY + 40f;
}
}