128 lines
3 KiB
C#
128 lines
3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using NeoModLoader.services;
|
|
|
|
namespace IdleSpectator;
|
|
|
|
/// <summary>
|
|
/// Ring buffer of why a beat stayed Layer B or failed to take / keep Layer A camera.
|
|
/// </summary>
|
|
public static class InterestDropLog
|
|
{
|
|
public const int Capacity = 48;
|
|
|
|
private static readonly string[] Buffer = new string[Capacity];
|
|
private static int _write;
|
|
private static int _count;
|
|
private static float _lastPlayerLogAt = -999f;
|
|
private const float PlayerLogInterval = 8f;
|
|
|
|
public static int Count => _count;
|
|
|
|
public static void Clear()
|
|
{
|
|
_write = 0;
|
|
_count = 0;
|
|
for (int i = 0; i < Capacity; i++)
|
|
{
|
|
Buffer[i] = null;
|
|
}
|
|
}
|
|
|
|
public static void Record(string reason, string detail = "")
|
|
{
|
|
if (string.IsNullOrEmpty(reason))
|
|
{
|
|
return;
|
|
}
|
|
|
|
string line = string.IsNullOrEmpty(detail)
|
|
? reason
|
|
: (reason + ": " + detail);
|
|
Buffer[_write] = line;
|
|
_write = (_write + 1) % Capacity;
|
|
if (_count < Capacity)
|
|
{
|
|
_count++;
|
|
}
|
|
|
|
float now = UnityEngine.Time.unscaledTime;
|
|
if (now - _lastPlayerLogAt >= PlayerLogInterval)
|
|
{
|
|
_lastPlayerLogAt = now;
|
|
try
|
|
{
|
|
LogService.LogInfo("[IdleSpectator][DROP] " + line);
|
|
}
|
|
catch
|
|
{
|
|
// ignore log failures
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>Newest-first snapshot for harness / diagnostics.</summary>
|
|
public static List<string> Snapshot(int max = 12)
|
|
{
|
|
var list = new List<string>(Math.Min(max, _count));
|
|
if (_count == 0 || max <= 0)
|
|
{
|
|
return list;
|
|
}
|
|
|
|
int n = Math.Min(max, _count);
|
|
for (int i = 0; i < n; i++)
|
|
{
|
|
int idx = (_write - 1 - i + Capacity) % Capacity;
|
|
if (!string.IsNullOrEmpty(Buffer[idx]))
|
|
{
|
|
list.Add(Buffer[idx]);
|
|
}
|
|
}
|
|
|
|
return list;
|
|
}
|
|
|
|
public static bool RecentContains(string needle, int max = 24)
|
|
{
|
|
if (string.IsNullOrEmpty(needle))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
List<string> lines = Snapshot(max);
|
|
for (int i = 0; i < lines.Count; i++)
|
|
{
|
|
if (!string.IsNullOrEmpty(lines[i])
|
|
&& lines[i].IndexOf(needle, StringComparison.OrdinalIgnoreCase) >= 0)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public static string FormatRecent(int max = 8)
|
|
{
|
|
List<string> lines = Snapshot(max);
|
|
if (lines.Count == 0)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
var sb = new StringBuilder();
|
|
for (int i = 0; i < lines.Count; i++)
|
|
{
|
|
if (i > 0)
|
|
{
|
|
sb.Append(" | ");
|
|
}
|
|
|
|
sb.Append(lines[i]);
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
}
|