mirror of
https://github.com/MCCTeam/Minecraft-Console-Client
synced 2026-08-15 13:04:36 +00:00
147 lines
4.5 KiB
C#
147 lines
4.5 KiB
C#
using System;
|
|
using MinecraftClient.Mcp;
|
|
using MinecraftClient.Scripting;
|
|
using Tomlet.Attributes;
|
|
|
|
namespace MinecraftClient.ChatBots
|
|
{
|
|
public class McpServer : ChatBot
|
|
{
|
|
public static Configs Config = new();
|
|
|
|
[TomlDoNotInlineObject]
|
|
public class Configs
|
|
{
|
|
[NonSerialized]
|
|
private const string BotName = "McpServer";
|
|
|
|
[TomlInlineComment("$ChatBot.McpServer.Enabled$")]
|
|
public bool Enabled = false;
|
|
|
|
[TomlPrecedingComment("$ChatBot.McpServer.Transport$")]
|
|
public MccMcpTransportConfig Transport = new();
|
|
|
|
[TomlPrecedingComment("$ChatBot.McpServer.Capabilities$")]
|
|
public MccMcpCapabilityToggles Capabilities = new();
|
|
|
|
public void OnSettingUpdate()
|
|
{
|
|
Transport ??= new MccMcpTransportConfig();
|
|
Capabilities ??= new MccMcpCapabilityToggles();
|
|
|
|
if (Transport.Port is < 1 or > 65535)
|
|
Transport.Port = 33333;
|
|
|
|
if (string.IsNullOrWhiteSpace(Transport.BindHost))
|
|
Transport.BindHost = "127.0.0.1";
|
|
|
|
if (string.IsNullOrWhiteSpace(Transport.Route))
|
|
Transport.Route = "/mcp";
|
|
|
|
if (!Transport.Route.StartsWith('/'))
|
|
Transport.Route = "/" + Transport.Route;
|
|
|
|
if (string.IsNullOrWhiteSpace(Transport.AuthTokenEnvVar))
|
|
Transport.AuthTokenEnvVar = "MCC_MCP_AUTH_TOKEN";
|
|
}
|
|
}
|
|
|
|
private MccEmbeddedMcpHost? host;
|
|
|
|
public override void Initialize()
|
|
{
|
|
Config.OnSettingUpdate();
|
|
}
|
|
|
|
public override void AfterGameJoined()
|
|
{
|
|
if (!Config.Enabled)
|
|
return;
|
|
|
|
MccMcpChatHistoryStore.Clear();
|
|
|
|
MccMcpConfig mcpConfig = new()
|
|
{
|
|
Enabled = Config.Enabled,
|
|
Transport = Config.Transport,
|
|
Capabilities = Config.Capabilities
|
|
};
|
|
|
|
host ??= new MccEmbeddedMcpHost(mcpConfig, new MccMcpCapabilities(() => Config.Capabilities));
|
|
|
|
if (host.IsRunning)
|
|
return;
|
|
|
|
LogToConsole(Translations.bot_mcpserver_starting);
|
|
if (!host.Start(out string? error))
|
|
{
|
|
if (error == "missing_auth_token")
|
|
LogToConsole(string.Format(Translations.bot_mcpserver_missing_auth_token, Config.Transport.AuthTokenEnvVar));
|
|
LogToConsole(string.Format(Translations.bot_mcpserver_start_failed, error ?? "unknown"));
|
|
return;
|
|
}
|
|
|
|
LogToConsole(string.Format(Translations.bot_mcpserver_started, host.Endpoint));
|
|
}
|
|
|
|
public override bool OnDisconnect(DisconnectReason reason, string message)
|
|
{
|
|
StopHost();
|
|
MccMcpChatHistoryStore.Clear();
|
|
return false;
|
|
}
|
|
|
|
public override void OnUnload()
|
|
{
|
|
StopHost();
|
|
MccMcpChatHistoryStore.Clear();
|
|
}
|
|
|
|
public override void GetText(string text, string? json)
|
|
{
|
|
string clean = GetVerbatim(text);
|
|
if (string.IsNullOrWhiteSpace(clean))
|
|
return;
|
|
|
|
string kind = "system";
|
|
string? sender = null;
|
|
string? message = null;
|
|
|
|
string parsedMessage = string.Empty;
|
|
string parsedSender = string.Empty;
|
|
if (IsPrivateMessage(clean, ref parsedMessage, ref parsedSender))
|
|
{
|
|
kind = "private";
|
|
sender = parsedSender;
|
|
message = parsedMessage;
|
|
}
|
|
else if (IsChatMessage(clean, ref parsedMessage, ref parsedSender))
|
|
{
|
|
kind = "chat";
|
|
sender = parsedSender;
|
|
message = parsedMessage;
|
|
}
|
|
|
|
MccMcpChatHistoryStore.Add(new MccMcpChatHistoryEntry
|
|
{
|
|
TimestampUtc = DateTimeOffset.UtcNow,
|
|
Kind = kind,
|
|
Text = clean,
|
|
Sender = sender,
|
|
Message = message,
|
|
Json = json
|
|
});
|
|
}
|
|
|
|
private void StopHost()
|
|
{
|
|
if (host is null || !host.IsRunning)
|
|
return;
|
|
|
|
if (host.Stop(out string? error))
|
|
LogToConsole(Translations.bot_mcpserver_stopped);
|
|
else
|
|
LogToConsole(string.Format(Translations.bot_mcpserver_stop_failed, error ?? "unknown"));
|
|
}
|
|
}
|
|
}
|