mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
Refactored to share the new utilities between the MCP and the Chat Bot API
This commit is contained in:
parent
a88ca3cb71
commit
dfef24ad10
12 changed files with 2225 additions and 1027 deletions
205
MinecraftClient/Scripting/MccObservedState.cs
Normal file
205
MinecraftClient/Scripting/MccObservedState.cs
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
|
||||
namespace MinecraftClient.Scripting;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a recent high-signal runtime event observed by MCC.
|
||||
/// </summary>
|
||||
public sealed class MccRecentEventEntry
|
||||
{
|
||||
public required long Id { get; init; }
|
||||
public required DateTimeOffset TimestampUtc { get; init; }
|
||||
public required string Type { get; init; }
|
||||
public object? Data { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a recent chat or system line observed by MCC.
|
||||
/// </summary>
|
||||
public sealed class MccChatHistoryEntry
|
||||
{
|
||||
public required DateTimeOffset TimestampUtc { get; init; }
|
||||
public required string Kind { get; init; }
|
||||
public required string Text { get; init; }
|
||||
public string? Sender { get; init; }
|
||||
public string? Message { get; init; }
|
||||
public string? Json { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the latest observed world time and weather values.
|
||||
/// </summary>
|
||||
public sealed class MccRuntimeStateSnapshot
|
||||
{
|
||||
public long? WorldAge { get; init; }
|
||||
public long? TimeOfDay { get; init; }
|
||||
public float? RainLevel { get; init; }
|
||||
public float? ThunderLevel { get; init; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Shared observed-state store populated from ChatBot callbacks and consumed by MCP and bots/scripts.
|
||||
/// </summary>
|
||||
public static class MccObservedStateStore
|
||||
{
|
||||
private const int MaxEntries = 500;
|
||||
|
||||
private static readonly Lock s_recentEventsLock = new();
|
||||
private static readonly Lock s_chatHistoryLock = new();
|
||||
private static readonly Lock s_runtimeStateLock = new();
|
||||
|
||||
private static readonly List<MccRecentEventEntry> s_recentEvents = [];
|
||||
private static readonly List<MccChatHistoryEntry> s_chatHistory = [];
|
||||
|
||||
private static long s_nextRecentEventId = 1;
|
||||
private static long? s_worldAge;
|
||||
private static long? s_timeOfDay;
|
||||
private static float? s_rainLevel;
|
||||
private static float? s_thunderLevel;
|
||||
|
||||
public static long AddRecentEvent(string type, object? data = null)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrEmpty(type);
|
||||
|
||||
lock (s_recentEventsLock)
|
||||
{
|
||||
long id = s_nextRecentEventId++;
|
||||
s_recentEvents.Add(new MccRecentEventEntry
|
||||
{
|
||||
Id = id,
|
||||
TimestampUtc = DateTimeOffset.UtcNow,
|
||||
Type = type,
|
||||
Data = data
|
||||
});
|
||||
|
||||
TrimToMaxEntries(s_recentEvents);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
public static long GetLatestRecentEventId()
|
||||
{
|
||||
lock (s_recentEventsLock)
|
||||
{
|
||||
return s_recentEvents.Count > 0 ? s_recentEvents[^1].Id : 0;
|
||||
}
|
||||
}
|
||||
|
||||
public static MccRecentEventEntry[] GetRecentEventsAfter(long afterId, int maxCount, string? typeFilter = null)
|
||||
{
|
||||
int count = Math.Clamp(maxCount, 1, MaxEntries);
|
||||
string? normalizedFilter = string.IsNullOrWhiteSpace(typeFilter) ? null : typeFilter.Trim();
|
||||
|
||||
lock (s_recentEventsLock)
|
||||
{
|
||||
return s_recentEvents
|
||||
.Where(entry => entry.Id > afterId)
|
||||
.Where(entry => normalizedFilter is null
|
||||
|| entry.Type.Contains(normalizedFilter, StringComparison.OrdinalIgnoreCase))
|
||||
.Take(count)
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static void AddChatHistoryEntry(MccChatHistoryEntry entry)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(entry);
|
||||
|
||||
lock (s_chatHistoryLock)
|
||||
{
|
||||
s_chatHistory.Add(entry);
|
||||
TrimToMaxEntries(s_chatHistory);
|
||||
}
|
||||
}
|
||||
|
||||
public static MccChatHistoryEntry[] GetLatestChatHistory(int maxCount)
|
||||
{
|
||||
int count = Math.Clamp(maxCount, 1, MaxEntries);
|
||||
lock (s_chatHistoryLock)
|
||||
{
|
||||
return s_chatHistory.TakeLast(count).ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetTime(long worldAge, long timeOfDay)
|
||||
{
|
||||
lock (s_runtimeStateLock)
|
||||
{
|
||||
s_worldAge = worldAge;
|
||||
s_timeOfDay = timeOfDay;
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetRainLevel(float level)
|
||||
{
|
||||
lock (s_runtimeStateLock)
|
||||
{
|
||||
s_rainLevel = level;
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetThunderLevel(float level)
|
||||
{
|
||||
lock (s_runtimeStateLock)
|
||||
{
|
||||
s_thunderLevel = level;
|
||||
}
|
||||
}
|
||||
|
||||
public static MccRuntimeStateSnapshot GetRuntimeStateSnapshot()
|
||||
{
|
||||
lock (s_runtimeStateLock)
|
||||
{
|
||||
return new MccRuntimeStateSnapshot
|
||||
{
|
||||
WorldAge = s_worldAge,
|
||||
TimeOfDay = s_timeOfDay,
|
||||
RainLevel = s_rainLevel,
|
||||
ThunderLevel = s_thunderLevel
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public static void ClearRecentEvents()
|
||||
{
|
||||
lock (s_recentEventsLock)
|
||||
{
|
||||
s_recentEvents.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static void ClearChatHistory()
|
||||
{
|
||||
lock (s_chatHistoryLock)
|
||||
{
|
||||
s_chatHistory.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static void ClearRuntimeState()
|
||||
{
|
||||
lock (s_runtimeStateLock)
|
||||
{
|
||||
s_worldAge = null;
|
||||
s_timeOfDay = null;
|
||||
s_rainLevel = null;
|
||||
s_thunderLevel = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static void ClearAll()
|
||||
{
|
||||
ClearChatHistory();
|
||||
ClearRuntimeState();
|
||||
ClearRecentEvents();
|
||||
}
|
||||
|
||||
private static void TrimToMaxEntries<T>(List<T> entries)
|
||||
{
|
||||
if (entries.Count > MaxEntries)
|
||||
entries.RemoveRange(0, entries.Count - MaxEntries);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue