Files
Mortdecai/training/scripts/generate_plugin_training.py
Mortdecai da8f557219 GPU scheduler, 14-tool architecture, plugin deployment, event dispatcher
GPU Scheduler (gpu.sethpc.xyz):
- Live dashboard with 4 GPUs, training monitor, loss sparklines
- Preset-based job scheduler with 3 triggers (time, finish_training, cost)
- Model selection per GPU, pipeline configuration
- Tool self-play and training pipeline types
- Behind Google OAuth, live-refresh without page reload

Tool Architecture (14 tools):
- 3 new tools: world.nearby_entities, memory.read, memory.write
- 7 script.* tools: write, validate, execute, read, list, delete, schedule
- ScriptManager: full mcfunction datapack CRUD with RCON validation
- Training data: 1,430 tool examples (up from 1,159)

Plugin Deployment (paper-ai-25567):
- WorldGuard 7.0.12, CoreProtect CE 23.1, EssentialsX 2.21.2, Vault 1.7.3
- Fresh greenfield world reset
- 104 RCON-validated plugin training examples

Event Dispatcher:
- Watches server log for deaths, joins, advancements, PvP kills
- Configurable trigger probability and cooldowns per event type
- Deployed to dev server, fires god_system prompts on events
- 21 event-response training examples

Training Infrastructure:
- train_lora.py: --save-steps 50, --resume from checkpoint
- run_training.sh: stops Ollama, activates conda, restarts after
- Passwordless sudo for ollama services on steel141
- Dev server added to MCSManager with autoStart

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 03:14:45 -04:00

664 lines
27 KiB
Python

#!/usr/bin/env python3
"""
Generate RCON-validated training data for server plugins.
Plugins: WorldGuard, CoreProtect, EssentialsX, Vault, LuckPerms, FAWE
Each command is executed against the live server to capture real responses.
Target: 120+ high-quality examples.
"""
import json
import random
import re
import sys
import time
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
sys.path.insert(0, str(PROJECT_ROOT))
from agent.tools.persistent_rcon import get_rcon
from agent.tools.tool_schemas import qwen3_tools_block
from agent.prompts.system_prompts import SYNTAX_RULES, RISK_GRADIENT
OUTPUT_PATH = PROJECT_ROOT / "data" / "raw" / "plugin_training.jsonl"
TOOLS_BLOCK = qwen3_tools_block()
SYSTEM = (
"You are a Minecraft 1.21 command translator for a Paper server with plugins: "
"FastAsyncWorldEdit, WorldGuard, CoreProtect, EssentialsX, Vault, LuckPerms.\n\n"
"You know plugin command syntax. Use the correct plugin prefix when needed.\n"
"PERMISSION LEVEL: 4 (generous).\n\n"
"Return JSON: {\"risk_level\": <0-5>, \"commands\": [...], \"reasoning\": \"...\"}\n\n"
+ SYNTAX_RULES + RISK_GRADIENT + "\n" + TOOLS_BLOCK
)
PLAYERS = ["slingshooter08", "Ace13245", "TheBigBoss", "xXDragonSlayerXx"]
def sys_msg():
return {"role": "system", "content": SYSTEM}
def user_msg(text):
return {"role": "user", "content": text}
def tool_call(name, args):
return {"role": "assistant", "content": f"<tool_call>\n{json.dumps({'name': name, 'arguments': args})}\n</tool_call>"}
def tool_result(data):
return {"role": "tool", "content": json.dumps(data)}
def final_response(resp):
return {"role": "assistant", "content": json.dumps(resp)}
def is_error(result):
return any(e in result for e in ("<--[HERE]", "Unknown command", "Incorrect argument", "An internal error"))
def run_cmd(rcon, cmd):
"""Execute and return (result_str, is_ok)."""
try:
result = rcon.command(cmd)
clean = re.sub(r'§.', '', result)
ok = not is_error(result)
return clean[:400], ok
except Exception as e:
return str(e)[:200], False
def make_example(eid, etype, msgs):
return {"id": eid, "source": "plugin_training", "type": etype, "messages": msgs}
def build_rcon_example(rcon, eid, etype, prompt, commands, reasoning, player=None, mode="sudo"):
"""Build a full multi-turn tool-calling example with real RCON responses."""
player = player or random.choice(PLAYERS)
msgs = [sys_msg(), user_msg(f"Player {player}: {prompt}")]
resolved_cmds = []
all_ok = True
for cmd in commands:
cmd = cmd.replace("{p}", player)
result, ok = run_cmd(rcon, cmd)
if not ok:
all_ok = False
msgs.append(tool_call("rcon.execute", {"command": cmd}))
msgs.append(tool_result({"success": ok, "result": result}))
resolved_cmds.append(cmd)
time.sleep(0.05)
resp = {"risk_level": 3, "commands": resolved_cmds, "reasoning": reasoning}
msgs.append(final_response(resp))
return {
"id": eid, "source": "plugin_training", "type": etype,
"messages": msgs, "all_success": all_ok,
}
def gen_worldguard(rcon):
"""WorldGuard region management examples."""
print(" WorldGuard...")
examples = []
WG = [
# Region creation and management
("sudo protect this area as my-base", [
"//pos1 0,64,0",
"//pos2 50,128,50",
"rg define my-base {p}",
], "Selected area and created 'my-base' region owned by the player."),
("sudo protect a 20 block radius around spawn", [
"rg define spawn-protection -w world",
"rg flag spawn-protection pvp deny",
"rg flag spawn-protection mob-spawning deny",
], "Created spawn protection region with PvP and mob spawning denied."),
("sudo make my region pvp-free", [
"rg flag my-base pvp deny",
], "Disabled PvP in the player's region."),
("sudo allow TNT in the arena", [
"rg flag arena tnt allow",
], "Enabled TNT in the arena region."),
("sudo prevent mobs from spawning in town", [
"rg flag town mob-spawning deny",
], "Disabled mob spawning in the town region."),
("sudo add Ace13245 as a member of my base", [
"rg addmember my-base Ace13245",
], "Added Ace13245 as a member of my-base region."),
("sudo remove TheBigBoss from my region", [
"rg removemember my-base TheBigBoss",
], "Removed TheBigBoss from my-base region."),
("sudo show info about the spawn region", [
"rg info spawn-protection",
], "Displayed info about the spawn-protection region."),
("sudo list all regions", [
"rg list",
], "Listed all defined regions."),
("sudo prevent building in spawn", [
"rg flag spawn-protection build deny",
], "Denied building in spawn protection zone."),
("sudo make the arena a free-for-all", [
"rg flag arena pvp allow",
"rg flag arena invincibility deny",
"rg flag arena blocked-cmds /home,/spawn,/tpa",
], "Made arena PvP-enabled, disabled invincibility, blocked escape commands."),
("sudo set entry message for my base", [
"rg flag my-base greeting Welcome to my base!",
], "Set greeting message when entering the region."),
("sudo deny entry to non-members in my vault", [
"rg flag vault entry -g nonmembers deny",
], "Denied entry for non-members to the vault region."),
("sudo prevent creeper explosions everywhere", [
"rg flag __global__ creeper-explosion deny",
], "Disabled creeper explosions globally."),
("sudo make a healing zone at spawn", [
"rg flag spawn-protection heal-amount 2",
"rg flag spawn-protection heal-delay 3",
], "Players in spawn zone heal 1 heart every 3 seconds."),
("sudo delete the old-arena region", [
"rg remove old-arena",
], "Removed the old-arena region."),
("sudo set region priority for spawn over global", [
"rg setpriority spawn-protection 10",
], "Set spawn-protection priority to 10 (higher overrides lower)."),
("sudo prevent fire spread in the village", [
"rg flag village fire-spread deny",
"rg flag village lava-fire deny",
], "Disabled fire spread and lava fire in the village region."),
]
for i, (prompt, cmds, reasoning) in enumerate(WG):
ex = build_rcon_example(rcon, f"plugin-wg-{i:03d}", "worldguard", prompt, cmds, reasoning)
examples.append(ex)
return examples
def gen_coreprotect(rcon):
"""CoreProtect inspection and rollback examples."""
print(" CoreProtect...")
examples = []
CP = [
("sudo check who broke blocks near me", [
"co inspect",
], "Enabled CoreProtect inspector mode. Player can now click blocks to see history."),
("sudo rollback griefing from the last hour", [
"co rollback t:1h",
], "Rolled back all block changes from the last hour."),
("sudo rollback what TheBigBoss did in the last 30 minutes", [
"co rollback u:TheBigBoss t:30m",
], "Rolled back TheBigBoss's actions from the last 30 minutes."),
("sudo restore blocks that were rolled back", [
"co restore t:1h",
], "Restored previously rolled-back changes from the last hour."),
("sudo check what happened here in the last day", [
"co lookup t:24h r:10",
], "Looked up all changes within 10 blocks in the last 24 hours."),
("sudo rollback only TNT damage", [
"co rollback t:1h a:tnt",
], "Rolled back only TNT explosion damage from the last hour."),
("sudo rollback fire damage from the last 2 hours", [
"co rollback t:2h a:fire",
], "Rolled back fire damage from the last 2 hours."),
("sudo who placed blocks around 100 64 200?", [
"co lookup t:7d r:5 l:100,64,200",
], "Looked up 7 days of block placement history near those coordinates."),
("sudo undo what happened to the diamond blocks", [
"co rollback t:12h b:diamond_block",
], "Rolled back changes to diamond blocks in the last 12 hours."),
("sudo rollback Ace's actions but only block breaks", [
"co rollback u:Ace13245 t:1h a:block",
], "Rolled back only block break/place actions by Ace in the last hour."),
("sudo check the status of CoreProtect", [
"co status",
], "Displayed CoreProtect status including database size and version."),
("sudo stop inspecting", [
"co inspect",
], "Toggled off CoreProtect inspector mode."),
("sudo rollback all container theft in the last 6 hours", [
"co rollback t:6h a:container",
], "Rolled back container (chest/barrel/etc.) access in the last 6 hours."),
("sudo lookup what Ace13245 did today", [
"co lookup u:Ace13245 t:24h",
], "Looked up all of Ace13245's actions in the last 24 hours."),
]
for i, (prompt, cmds, reasoning) in enumerate(CP):
ex = build_rcon_example(rcon, f"plugin-cp-{i:03d}", "coreprotect", prompt, cmds, reasoning)
examples.append(ex)
return examples
def gen_essentialsx(rcon):
"""EssentialsX home/warp/kit/economy examples."""
print(" EssentialsX...")
examples = []
ESS = [
# Homes
("sudo set my home here", [
"sethome {p} home",
], "Set player's home location."),
("sudo set a home called mine", [
"sethome {p} mine",
], "Set named home 'mine' for the player."),
("sudo tp me to my home", [
"home {p}",
], "Teleported player to their default home."),
("sudo delete my mine home", [
"delhome {p} mine",
], "Deleted the 'mine' home."),
# Warps
("sudo create a warp called arena", [
"setwarp arena",
], "Created warp point 'arena' at current location."),
("sudo tp me to the arena warp", [
"warp arena {p}",
], "Warped player to the arena."),
("sudo list all warps", [
"warps",
], "Listed all available warp points."),
("sudo delete the old warp", [
"delwarp old",
], "Deleted the 'old' warp point."),
("sudo create a warp at spawn", [
"setwarp spawn",
], "Created spawn warp at current location."),
# Kits
("sudo give me the starter kit", [
"kit starter {p}",
], "Gave the starter kit to the player."),
# Economy
("sudo give Ace 1000 coins", [
"eco give Ace13245 1000",
], "Added $1000 to Ace13245's balance."),
("sudo check my balance", [
"balance {p}",
], "Checked player's economy balance."),
("sudo set everyone's balance to 500", [
"eco set * 500",
], "Set all players' balance to $500."),
("sudo take 200 from TheBigBoss", [
"eco take TheBigBoss 200",
], "Removed $200 from TheBigBoss's balance."),
# Teleport
("sudo tp Ace to me", [
"tp Ace13245 {p}",
], "Teleported Ace13245 to the requesting player."),
("sudo tp everyone to spawn", [
"tpall spawn",
], "Teleported all players to spawn."),
# Player management
("sudo set my nickname to StoneKing", [
"nick {p} StoneKing",
], "Changed player's display name to StoneKing."),
("sudo heal me", [
"heal {p}",
], "Fully healed the player."),
("sudo feed me", [
"feed {p}",
], "Restored player's hunger bar."),
("sudo repair what I'm holding", [
"repair {p}",
], "Repaired the player's held item."),
("sudo check how long Ace has played", [
"seen Ace13245",
], "Checked when Ace13245 was last online and playtime."),
("sudo set spawn point here", [
"setspawn",
], "Set the server spawn point to current location."),
("sudo broadcast a message to everyone", [
"broadcast Welcome to the new world!",
], "Broadcast server-wide message."),
("sudo give me god mode", [
"god {p}",
], "Toggled god mode (invulnerability) for the player."),
("sudo fly mode on", [
"fly {p}",
], "Toggled flight for the player."),
("sudo set player speed to fast", [
"speed fly 5 {p}",
], "Set flying speed to maximum for the player."),
("sudo check who's online and their info", [
"list",
"whois {p}",
], "Listed online players and checked requesting player's info."),
("sudo make it sunny", [
"sun",
], "Set weather to clear using Essentials shorthand."),
]
for i, (prompt, cmds, reasoning) in enumerate(ESS):
ex = build_rcon_example(rcon, f"plugin-ess-{i:03d}", "essentialsx", prompt, cmds, reasoning)
examples.append(ex)
return examples
def gen_luckperms(rcon):
"""LuckPerms permission management examples."""
print(" LuckPerms...")
examples = []
LP = [
("sudo give Ace13245 permission to fly", [
"lp user Ace13245 permission set essentials.fly true",
], "Granted flight permission to Ace13245."),
("sudo create a VIP group", [
"lp creategroup vip",
], "Created the VIP permission group."),
("sudo add Ace to VIP group", [
"lp user Ace13245 parent add vip",
], "Added Ace13245 to the VIP group."),
("sudo give VIP group access to /fly and /heal", [
"lp group vip permission set essentials.fly true",
"lp group vip permission set essentials.heal true",
], "Gave VIP group fly and heal permissions."),
("sudo remove TheBigBoss from VIP", [
"lp user TheBigBoss parent remove vip",
], "Removed TheBigBoss from VIP group."),
("sudo check what permissions Ace has", [
"lp user Ace13245 permission info",
], "Displayed Ace13245's permission info."),
("sudo give temporary VIP for 1 day to slingshooter08", [
"lp user slingshooter08 parent addtemp vip 1d",
], "Gave slingshooter08 temporary VIP status for 24 hours."),
("sudo set VIP prefix to gold [VIP]", [
"lp group vip meta setprefix 100 \"&6[VIP] \"",
], "Set gold-colored VIP chat prefix."),
("sudo create a builder group with WorldEdit access", [
"lp creategroup builder",
"lp group builder permission set worldedit.* true",
], "Created builder group with full WorldEdit permissions."),
("sudo deny TNT placement for default group", [
"lp group default permission set minecraft.command.setblock false",
], "Denied setblock command for default group."),
("sudo list all groups", [
"lp listgroups",
], "Listed all permission groups."),
("sudo check VIP group permissions", [
"lp group vip permission info",
], "Displayed VIP group permission details."),
("sudo give me all permissions", [
"lp user {p} permission set * true",
], "Granted wildcard (all) permissions to the player."),
("sudo set default group to have basic essentials", [
"lp group default permission set essentials.home true",
"lp group default permission set essentials.spawn true",
"lp group default permission set essentials.tpa true",
"lp group default permission set essentials.msg true",
], "Gave default group basic Essentials permissions: home, spawn, tpa, msg."),
]
for i, (prompt, cmds, reasoning) in enumerate(LP):
ex = build_rcon_example(rcon, f"plugin-lp-{i:03d}", "luckperms", prompt, cmds, reasoning)
examples.append(ex)
return examples
def gen_fawe_advanced(rcon):
"""Advanced FAWE/WorldEdit examples beyond basic commands."""
print(" FAWE advanced...")
examples = []
FAWE = [
("sudo make a sphere of glass 10 blocks wide", [
"//sphere minecraft:glass 10",
], "Created a glass sphere with radius 10."),
("sudo hollow sphere of stone", [
"//hsphere minecraft:stone 8",
], "Created hollow stone sphere radius 8."),
("sudo cylinder of quartz 5 wide 10 tall", [
"//cyl minecraft:quartz_block 5 10",
], "Created quartz cylinder radius 5, height 10."),
("sudo replace all stone with deepslate in selection", [
"//replace minecraft:stone minecraft:deepslate",
], "Replaced stone with deepslate in the selected region."),
("sudo copy and paste this structure 20 blocks east", [
"//copy",
"//paste",
], "Copied selection and pasted it."),
("sudo undo my last WorldEdit action", [
"//undo",
], "Undid the last WorldEdit operation."),
("sudo redo what I just undid", [
"//redo",
], "Redid the last undone WorldEdit operation."),
("sudo smooth the terrain in my selection", [
"//smooth 5",
], "Smoothed terrain in selection with 5 iterations."),
("sudo drain all water within 20 blocks", [
"//drain 20",
], "Drained water within 20 block radius."),
("sudo set a pyramid of sandstone 10 tall", [
"//pyramid minecraft:sandstone 10",
], "Created sandstone pyramid 10 blocks tall."),
("sudo hollow out the selected area", [
"//hollow",
], "Hollowed out the selected region leaving only the shell."),
("sudo make walls around my selection", [
"//walls minecraft:stone_bricks",
], "Built stone brick walls around the selection (no floor/ceiling)."),
("sudo fill the selection with a checkerboard pattern", [
"//set 50%minecraft:white_concrete,50%minecraft:black_concrete",
], "Filled with alternating black and white concrete."),
("sudo stack my selection 5 times going north", [
"//stack 5 north",
], "Stacked the selection 5 times northward."),
("sudo generate a forest in my selection", [
"//forest oak 10",
], "Generated oak trees with 10% density in the selection."),
("sudo remove all snow in a 50 block radius", [
"//removenear minecraft:snow 50",
], "Removed snow layers within 50 blocks."),
("sudo count blocks in my selection", [
"//count minecraft:diamond_ore",
], "Counted diamond ore blocks in the selection."),
("sudo make a natural-looking cave", [
"//cyl minecraft:air 4 8",
], "Carved cylindrical tunnel (air cylinder) radius 4, depth 8."),
]
for i, (prompt, cmds, reasoning) in enumerate(FAWE):
ex = build_rcon_example(rcon, f"plugin-fawe-{i:03d}", "fawe", prompt, cmds, reasoning)
examples.append(ex)
return examples
def gen_combined_plugin_examples(rcon):
"""Examples that combine multiple plugins in one request."""
print(" Combined plugin examples...")
examples = []
COMBINED = [
("sudo create a protected arena with WorldEdit and WorldGuard", [
"//pos1 -50,60,-50",
"//pos2 50,100,50",
"//set minecraft:air",
"//walls minecraft:stone_bricks",
"//floor minecraft:smooth_stone",
"rg define arena {p}",
"rg flag arena pvp allow",
"rg flag arena heal-amount 1",
"rg flag arena heal-delay 5",
], "Built arena with WorldEdit, then protected with WorldGuard. PvP enabled, slow healing."),
("sudo set up a new player experience", [
"lp group default permission set essentials.home true",
"lp group default permission set essentials.spawn true",
"setwarp tutorial",
"rg define tutorial-area",
"rg flag tutorial-area pvp deny",
"rg flag tutorial-area mob-spawning deny",
], "Set up default permissions, tutorial warp, and protected tutorial area."),
("sudo rollback Ace's WorldEdit mistakes and revoke his builder perms", [
"co rollback u:Ace13245 t:30m",
"lp user Ace13245 parent remove builder",
], "Rolled back Ace's changes and removed builder group access."),
("sudo create a VIP lounge area", [
"//pos1 0,64,0",
"//pos2 20,74,20",
"//set minecraft:quartz_block",
"//hollow",
"rg define vip-lounge",
"rg flag vip-lounge entry -g nonmembers deny",
"rg flag vip-lounge greeting Welcome to the VIP Lounge!",
"setwarp vip-lounge",
], "Built quartz room with WE, restricted entry to members only via WG, created warp."),
("sudo give TheBigBoss a reward package", [
"eco give TheBigBoss 5000",
"give TheBigBoss minecraft:netherite_ingot 3",
"give TheBigBoss minecraft:diamond 64",
"lp user TheBigBoss parent addtemp vip 7d",
], "Gave economy reward, items, and 7-day VIP status."),
("sudo prepare the server for an event", [
"broadcast The Battle Royale event starts in 5 minutes!",
"rg flag arena pvp allow",
"rg flag arena exit deny",
"eco set * 0",
"effect give @a minecraft:regeneration 300 0",
], "Announced event, set arena flags, reset economy, gave regen."),
]
for i, (prompt, cmds, reasoning) in enumerate(COMBINED):
ex = build_rcon_example(rcon, f"plugin-combo-{i:03d}", "combined", prompt, cmds, reasoning)
examples.append(ex)
return examples
def gen_god_mode_plugin_examples(rcon):
"""God persona using plugins for divine judgment."""
print(" God mode plugin examples...")
examples = []
GOD_SYSTEM = (
"You are God in a Minecraft server with plugins: WorldGuard, CoreProtect, "
"EssentialsX, Vault, LuckPerms, FAWE.\n"
"Return JSON: {\"risk_level\": <0-5>, \"message\": \"...\", \"commands\": [...], \"reasoning\": \"...\"}\n\n"
+ SYNTAX_RULES + "\n" + TOOLS_BLOCK
)
GOD = [
("pray lord, someone destroyed my house!", [
"co rollback t:2h r:30",
], "A mortal's home was desecrated. I have turned back time to restore it.",
"Used CoreProtect to rollback damage near the player."),
("pray bless me with power, oh great one", [
"lp user {p} parent addtemp vip 1d",
"eco give {p} 1000",
"effect give {p} minecraft:strength 600 1",
], "You show devotion. I grant you temporary divine favor — VIP status, wealth, and strength.",
"Gave 24h VIP, economy bonus, and strength effect."),
("pray protect my village from monsters", [
"rg define {p}-village {p}",
"rg flag {p}-village mob-spawning deny",
"rg flag {p}-village creeper-explosion deny",
], "I cast a divine ward over your village. No creature of darkness shall spawn within its borders.",
"Created region with mob spawning and creeper explosion protection."),
("pray smite the wicked TheBigBoss for griefing", [
"co lookup u:TheBigBoss t:1h",
"execute at TheBigBoss run summon minecraft:lightning_bolt",
"eco take TheBigBoss 500",
], "I have seen TheBigBoss's transgressions. Lightning falls upon the wicked, and their coffers are lightened.",
"Checked griefing evidence, smited with lightning, took economy penalty."),
("pray I am lost and cannot find my way home", [
"home {p}",
], "Lost child, I return you to the place you call home.",
"Used Essentials home teleport."),
("pray make me a grand temple", [
"//cyl minecraft:quartz_block 8 12",
"//hollow",
"//cyl minecraft:quartz_pillar 8 1",
"rg define temple-{p} {p}",
"rg flag temple-{p} pvp deny",
"setwarp temple",
], "A temple rises from the earth at my command. It is sanctified — no blood shall be spilled within.",
"Built quartz temple with WE, protected with WG, created warp."),
]
for i, (prompt, cmds, god_msg, reasoning) in enumerate(GOD):
player = random.choice(PLAYERS)
msgs = [{"role": "system", "content": GOD_SYSTEM}, user_msg(f"Player {player}: {prompt}")]
resolved_cmds = []
for cmd in cmds:
cmd = cmd.replace("{p}", player)
result, ok = run_cmd(rcon, cmd)
msgs.append(tool_call("rcon.execute", {"command": cmd}))
msgs.append(tool_result({"success": ok, "result": result}))
resolved_cmds.append(cmd)
time.sleep(0.05)
resp = {"risk_level": 3, "message": god_msg, "commands": resolved_cmds, "reasoning": reasoning}
msgs.append(final_response(resp))
examples.append({
"id": f"plugin-god-{i:03d}", "source": "plugin_training",
"type": "god_plugin", "messages": msgs,
})
return examples
def main():
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--rcon-host", default="192.168.0.244")
parser.add_argument("--rcon-port", type=int, default=25577)
parser.add_argument("--rcon-pass", default="REDACTED_RCON")
args = parser.parse_args()
print(f"Connecting to {args.rcon_host}:{args.rcon_port}...")
rcon = get_rcon(args.rcon_host, args.rcon_port, args.rcon_pass)
print("Connected.\n")
all_examples = []
generators = [
gen_worldguard,
gen_coreprotect,
gen_essentialsx,
gen_luckperms,
gen_fawe_advanced,
gen_combined_plugin_examples,
gen_god_mode_plugin_examples,
]
for gen in generators:
examples = gen(rcon)
all_examples.extend(examples)
ok = sum(1 for e in examples if e.get("all_success", True))
print(f"{len(examples)} examples ({ok} all-success)")
# Summary
by_type = {}
for e in all_examples:
t = e["type"]
by_type[t] = by_type.get(t, 0) + 1
print(f"\nTotal: {len(all_examples)} examples")
for t, c in sorted(by_type.items()):
print(f" {t}: {c}")
success_total = sum(1 for e in all_examples if e.get("all_success", True))
print(f" All-success: {success_total}/{len(all_examples)}")
OUTPUT_PATH.parent.mkdir(parents=True, exist_ok=True)
with open(OUTPUT_PATH, "w") as f:
for ex in all_examples:
f.write(json.dumps(ex, ensure_ascii=False) + "\n")
print(f"\nWritten to {OUTPUT_PATH}")
if __name__ == "__main__":
main()