Add server_type variable with capability sets (vanilla/paper) for command whitelisting

This commit is contained in:
Claude Code
2026-03-16 19:36:11 -04:00
parent fe36ae3739
commit b6c8abdeea
2 changed files with 47 additions and 6 deletions
+46 -6
View File
@@ -498,6 +498,38 @@ def get_player_context(player: str, config) -> str:
# LLM
# ---------------------------------------------------------------------------
# ---------------------------------------------------------------------------
# Server type capability sets
# ---------------------------------------------------------------------------
SERVER_CAPABILITIES = {
"vanilla": {
"safe_prefixes": [
'give ', 'effect ', 'xp ', 'tp ', 'time ', 'weather ',
'execute ', 'kill ', 'summon ', 'tellraw ', 'worldborder ',
],
"sudo_whitelist_note": "give, effect, xp, tp, time, weather, execute, kill, summon, tellraw, worldborder",
"template_build": False,
},
"paper": {
"safe_prefixes": [
'give ', 'effect ', 'xp ', 'tp ', 'time ', 'weather ',
'execute ', 'kill ', 'summon ', 'tellraw ', 'worldborder ',
'fill ', 'setblock ', 'clone ',
],
"sudo_whitelist_note": "give, effect, xp, tp, time, weather, execute, kill, summon, tellraw, worldborder, fill, setblock, clone",
"template_build": True,
},
}
DEFAULT_SERVER_TYPE = "vanilla"
def get_server_capabilities(config) -> dict:
server_type = str(config.get("server_type", DEFAULT_SERVER_TYPE)).lower().strip() if config else DEFAULT_SERVER_TYPE
return SERVER_CAPABILITIES.get(server_type, SERVER_CAPABILITIES[DEFAULT_SERVER_TYPE])
COMMAND_PALETTE = """
GIVE (any item, based on player need — see Item Naming Rules below):
SYNTAX: give <player> minecraft:<item_id> <count>
@@ -729,13 +761,16 @@ COMMANDS_SYSTEM_PROMPT = (
+ ENCHANTMENT_CONTEXT
)
SUDO_COMMANDS_SYSTEM_PROMPT = (
def build_sudo_commands_system_prompt(config=None) -> str:
caps = get_server_capabilities(config) if config else SERVER_CAPABILITIES[DEFAULT_SERVER_TYPE]
whitelist = caps["sudo_whitelist_note"]
return (
"You are a Minecraft command translator. Convert a player's natural-language request into "
"Minecraft server commands. You do NOT roleplay.\n\n"
"Respond ONLY with valid JSON:\n"
"{\"commands\": [\"cmd1\", \"cmd2\"]}\n\n"
"Rules:\n"
"- Use commands from this whitelist only: give, effect, xp, tp, time, weather, execute, kill, summon, tellraw, worldborder.\n"
f"- Use commands from this whitelist only: {whitelist}.\n"
"- If the request cannot be mapped safely, return commands: [].\n"
"- If player says 'me' or 'my', target the requesting player.\n"
"- You will receive LAST 10 SUDO ACTIONS. Use them for continuity and corrections when the player says previous output was wrong.\n"
@@ -801,7 +836,10 @@ SUDO_COMMANDS_SYSTEM_PROMPT = (
" give <p> minecraft:shield[enchantments={unbreaking:3,mending:1}] 1\n"
"\n"
"When player asks for 'fully enchanted', 'max enchanted', 'best', 'godlike' gear — use the above templates.\n"
)
)
# Keep backward-compatible alias using default (vanilla) config
SUDO_COMMANDS_SYSTEM_PROMPT = build_sudo_commands_system_prompt()
FIRST_LOGIN_BENEVOLENCE_PROMPT = (
"You are generating FIRST-LOGIN benevolence actions for a Minecraft server.\n"
@@ -1165,8 +1203,10 @@ def validate_command(cmd, online_players, fallback_player, config=None):
resolved = cmd.replace("{player}", fallback_player).replace("{target}", fallback_player)
resolved = fix_give_command(resolved)
resolved = fix_effect_command(resolved)
if not any(resolved.startswith(p) for p in SAFE_PREFIXES):
log.warning(f"Command blocked (unknown prefix): {resolved}")
caps = get_server_capabilities(config) if config else SERVER_CAPABILITIES[DEFAULT_SERVER_TYPE]
prefixes = caps["safe_prefixes"]
if not any(resolved.startswith(p) for p in prefixes):
log.warning(f"Command blocked (unknown prefix for server_type={config.get('server_type', DEFAULT_SERVER_TYPE) if config else DEFAULT_SERVER_TYPE}): {resolved}")
return resolved, False
if config and _extract_tp_abs_xyz(resolved) and not _tp_inside_worldborder(resolved, config):
log.warning(f"Command blocked (tp outside worldborder): {resolved}")
@@ -1383,7 +1423,7 @@ def process_sudo(player, prompt, config):
try:
content = _llm_call(
model=command_model,
system=SUDO_COMMANDS_SYSTEM_PROMPT,
system=build_sudo_commands_system_prompt(config),
user=context_hint,
config=config,
fmt="json",
+1
View File
@@ -1,5 +1,6 @@
{
"server_name": "shrink-world",
"server_type": "vanilla",
"log_path": "/opt/mcsmanager/daemon/data/InstanceData/shrinkborder1234567890abcdef12345/logs/latest.log",
"rcon_host": "127.0.0.1",
"rcon_port": 25576,