204 lines
6.3 KiB
C#
204 lines
6.3 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace BrewMonster.Scripts
|
|
{
|
|
public static class DebugCmdHistoryStore
|
|
{
|
|
private const string ResourcesJsonPathNoExt = "DebugCmdHistory";
|
|
private const string PlayerPrefsJsonKey = "DebugCmdHistory_v1";
|
|
private const string PlayerPrefsInitedKey = "DebugCmdHistory_inited_v1";
|
|
private const int MaxEntries = 200;
|
|
|
|
[Serializable]
|
|
public class Entry
|
|
{
|
|
public int header;
|
|
public int param;
|
|
public bool hasParam;
|
|
public string describe;
|
|
public long lastUsedUtcTicks;
|
|
|
|
public string KeyString => hasParam ? $"{header}:{param}" : $"{header}:";
|
|
}
|
|
|
|
[Serializable]
|
|
private class EntryListWrapper
|
|
{
|
|
public List<Entry> items = new List<Entry>();
|
|
}
|
|
|
|
public static List<Entry> Load()
|
|
{
|
|
// First-run: seed from Resources into PlayerPrefs so runtime can modify via PlayerPrefs.
|
|
if (!IsInited())
|
|
{
|
|
var seed = LoadFromResources();
|
|
SaveToPlayerPrefs(seed);
|
|
SetInited();
|
|
return seed;
|
|
}
|
|
|
|
return LoadFromPlayerPrefs();
|
|
}
|
|
|
|
public static void Save(List<Entry> entries)
|
|
{
|
|
SaveToPlayerPrefs(entries);
|
|
}
|
|
|
|
public static bool Upsert(List<Entry> entries, int header, int param, bool hasParam, string describe)
|
|
{
|
|
if (entries == null)
|
|
throw new ArgumentNullException(nameof(entries));
|
|
|
|
describe = (describe ?? string.Empty).Trim();
|
|
|
|
int idx = FindIndex(entries, header, param, hasParam);
|
|
if (idx >= 0)
|
|
{
|
|
var e = entries[idx];
|
|
bool changed = false;
|
|
|
|
// Overwrite describe whenever it differs (supports updating from empty -> non-empty).
|
|
if (!string.Equals((e.describe ?? string.Empty).Trim(), describe, StringComparison.Ordinal))
|
|
{
|
|
e.describe = describe;
|
|
changed = true;
|
|
}
|
|
|
|
e.lastUsedUtcTicks = DateTime.UtcNow.Ticks;
|
|
if (idx != 0)
|
|
{
|
|
entries.RemoveAt(idx);
|
|
entries.Insert(0, e);
|
|
changed = true;
|
|
}
|
|
else if (!changed)
|
|
{
|
|
// still considered "used"; keep order
|
|
}
|
|
|
|
return changed;
|
|
}
|
|
else
|
|
{
|
|
var e = new Entry
|
|
{
|
|
header = header,
|
|
param = param,
|
|
hasParam = hasParam,
|
|
describe = describe,
|
|
lastUsedUtcTicks = DateTime.UtcNow.Ticks
|
|
};
|
|
entries.Insert(0, e);
|
|
|
|
if (entries.Count > MaxEntries)
|
|
entries.RemoveRange(MaxEntries, entries.Count - MaxEntries);
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
public static void Clear()
|
|
{
|
|
PlayerPrefs.DeleteKey(PlayerPrefsJsonKey);
|
|
PlayerPrefs.DeleteKey(PlayerPrefsInitedKey);
|
|
PlayerPrefs.Save();
|
|
}
|
|
|
|
public static bool Remove(List<Entry> entries, int header, int param, bool hasParam)
|
|
{
|
|
if (entries == null)
|
|
throw new ArgumentNullException(nameof(entries));
|
|
|
|
int idx = FindIndex(entries, header, param, hasParam);
|
|
if (idx < 0)
|
|
return false;
|
|
|
|
entries.RemoveAt(idx);
|
|
return true;
|
|
}
|
|
|
|
private static List<Entry> LoadFromResources()
|
|
{
|
|
try
|
|
{
|
|
var asset = Resources.Load<TextAsset>(ResourcesJsonPathNoExt);
|
|
if (asset == null || string.IsNullOrWhiteSpace(asset.text))
|
|
return new List<Entry>();
|
|
|
|
var wrapper = JsonUtility.FromJson<EntryListWrapper>(asset.text);
|
|
if (wrapper == null || wrapper.items == null)
|
|
return new List<Entry>();
|
|
|
|
wrapper.items.RemoveAll(e => e == null);
|
|
return wrapper.items;
|
|
}
|
|
catch
|
|
{
|
|
return new List<Entry>();
|
|
}
|
|
}
|
|
|
|
private static List<Entry> LoadFromPlayerPrefs()
|
|
{
|
|
string json = PlayerPrefs.GetString(PlayerPrefsJsonKey, string.Empty);
|
|
if (string.IsNullOrWhiteSpace(json))
|
|
return new List<Entry>();
|
|
|
|
try
|
|
{
|
|
var wrapper = JsonUtility.FromJson<EntryListWrapper>(json);
|
|
if (wrapper == null || wrapper.items == null)
|
|
return new List<Entry>();
|
|
|
|
wrapper.items.RemoveAll(e => e == null);
|
|
return wrapper.items;
|
|
}
|
|
catch
|
|
{
|
|
return new List<Entry>();
|
|
}
|
|
}
|
|
|
|
private static void SaveToPlayerPrefs(List<Entry> entries)
|
|
{
|
|
try
|
|
{
|
|
var wrapper = new EntryListWrapper { items = entries ?? new List<Entry>() };
|
|
string json = JsonUtility.ToJson(wrapper);
|
|
PlayerPrefs.SetString(PlayerPrefsJsonKey, json);
|
|
PlayerPrefs.Save();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Debug.LogWarning($"[DebugCmdHistoryStore] Save failed: {ex.Message}");
|
|
}
|
|
}
|
|
|
|
private static bool IsInited() => PlayerPrefs.GetInt(PlayerPrefsInitedKey, 0) == 1;
|
|
private static void SetInited()
|
|
{
|
|
PlayerPrefs.SetInt(PlayerPrefsInitedKey, 1);
|
|
PlayerPrefs.Save();
|
|
}
|
|
|
|
private static int FindIndex(List<Entry> entries, int header, int param, bool hasParam)
|
|
{
|
|
for (int i = 0; i < entries.Count; i++)
|
|
{
|
|
var e = entries[i];
|
|
if (e == null) continue;
|
|
if (e.header != header) continue;
|
|
if (e.hasParam != hasParam) continue;
|
|
if (hasParam && e.param != param) continue;
|
|
return i;
|
|
}
|
|
return -1;
|
|
}
|
|
}
|
|
}
|
|
|