From 5a9786cb0bb23ebdc80b253f7f0c89468d61878c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 23 Mar 2026 00:41:40 +0000 Subject: [PATCH] Add Discord RPC setup tutorial, Discord Bridge AllowOtherBotMessages config, and enhance integration tests Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com> Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/a41f3e83-c88d-4c57-971b-54c380891556 --- .../references/command-matrix.md | 38 ++++++++ .../scripts/run_full_spectrum_test.sh | 87 +++++++++++++++++++ MinecraftClient/ChatBots/DiscordBridge.cs | 17 +++- .../ConfigComments/ConfigComments.Designer.cs | 15 +++- .../ConfigComments/ConfigComments.resx | 11 ++- 5 files changed, 164 insertions(+), 4 deletions(-) diff --git a/.skills/mcc-integration-testing/references/command-matrix.md b/.skills/mcc-integration-testing/references/command-matrix.md index 9880f2f8..31077374 100644 --- a/.skills/mcc-integration-testing/references/command-matrix.md +++ b/.skills/mcc-integration-testing/references/command-matrix.md @@ -9,9 +9,19 @@ This skill uses a fixed set of stable commands for local offline integration tes - `inventory player list` - `/gamemode creative` - `inventory creativegive 36 Diamond 16` +- `inventory creativegive 37 IronSword 1` +- `inventory creativegive 38 GoldenApple 8` +- `inventory creativeclear 38` - `entity` - `/time query daytime` +- `look up` +- `look down` +- `look east` +- `/gamemode survival` +- `respawn` +- `/tp CursorBot 0 -60 0` - `smoke_test_from_mcc_full_spectrum` +- `integration_test_chat_response` Notes: - Lines starting with `/` are sent to the server as chat/commands. @@ -24,6 +34,11 @@ Notes: - `gamerule logAdminCommands true` - `time set day` - `weather clear` +- `say Hello from the server console` +- `msg CursorBot This is a private whisper` +- `effect give CursorBot minecraft:speed 30 1` +- `effect give CursorBot minecraft:regeneration 10 1` +- `kill CursorBot` ## Representative entity coverage @@ -34,6 +49,21 @@ Notes: - `execute as CursorBot at @s run summon minecraft:villager ~-2 ~ ~` - `execute as CursorBot at @s run summon minecraft:allay ~-4 ~ ~` - `execute as CursorBot at @s run summon minecraft:armor_stand ~ ~ ~2` +- `execute as CursorBot at @s run summon minecraft:item_display ~-6 ~ ~ {item:{id:"minecraft:diamond",count:1}}` +- `execute as CursorBot at @s run summon minecraft:spider ~10 ~ ~` +- `execute as CursorBot at @s run summon minecraft:pig ~-8 ~ ~` + +## Block placement coverage + +- `execute as CursorBot at @s run fill ~1 ~ ~1 ~3 ~2 ~3 minecraft:stone` +- `execute as CursorBot at @s run setblock ~5 ~ ~5 minecraft:chest` +- `execute as CursorBot at @s run setblock ~5 ~1 ~5 minecraft:furnace` +- `execute as CursorBot at @s run setblock ~6 ~ ~5 minecraft:crafting_table` + +## Dimension change coverage + +- `execute in minecraft:the_nether run tp CursorBot 0 64 0` +- `execute in minecraft:overworld run tp CursorBot 0 -60 0` ## Representative particle coverage @@ -41,13 +71,21 @@ Notes: - `execute as CursorBot at @s run particle minecraft:end_rod ~ ~1 ~ 0.5 0.5 0.5 0.01 20 force` - `execute as CursorBot at @s run particle minecraft:explosion ~ ~1 ~ 0 0 0 0 1 force` - `execute as CursorBot at @s run particle minecraft:totem_of_undying ~ ~1 ~ 0.5 0.5 0.5 0.1 20 force` +- `execute as CursorBot at @s run particle minecraft:flame ~ ~1 ~ 0.2 0.2 0.2 0.02 30 force` +- `execute as CursorBot at @s run particle minecraft:heart ~ ~2 ~ 0.3 0.3 0.3 0 5 force` ## Representative sound coverage - `execute as CursorBot at @s run playsound minecraft:entity.lightning_bolt.thunder master CursorBot ~ ~ ~ 1 1 0` - `execute as CursorBot at @s run playsound minecraft:block.note_block.bell master CursorBot ~ ~ ~ 1 1 0` +- `execute as CursorBot at @s run playsound minecraft:entity.experience_orb.pickup master CursorBot ~ ~ ~ 1 1 0` ## Explosion coverage - `execute as CursorBot at @s run summon minecraft:tnt ~3 ~ ~` - `execute as CursorBot at @s run summon minecraft:tnt ~6 ~ ~` + +## Kill and respawn cycle + +- `kill CursorBot` (via RCON, requires survival mode) +- `respawn` (via MCC command after death) diff --git a/.skills/mcc-integration-testing/scripts/run_full_spectrum_test.sh b/.skills/mcc-integration-testing/scripts/run_full_spectrum_test.sh index 1ae6e983..02bc4f9f 100755 --- a/.skills/mcc-integration-testing/scripts/run_full_spectrum_test.sh +++ b/.skills/mcc-integration-testing/scripts/run_full_spectrum_test.sh @@ -155,6 +155,7 @@ run_server_command "time set day" run_server_command "weather clear" sleep 2 +# ── Phase 1: Basic status and info commands ── run_mcc_command "health" run_mcc_command "list" run_mcc_command "inventory player list" @@ -165,6 +166,34 @@ run_mcc_command "entity" run_mcc_command "/time query daytime" run_mcc_command "smoke_test_from_mcc_full_spectrum" +# ── Phase 2: Movement and look commands ── +run_mcc_command "/tp CursorBot 0 -60 0" +sleep 3 +run_mcc_command "look up" +sleep 1 +run_mcc_command "look down" +sleep 1 +run_mcc_command "look east" +sleep 1 + +# ── Phase 3: Advanced inventory operations ── +run_mcc_command "inventory creativegive 37 IronSword 1" +run_mcc_command "inventory creativegive 38 GoldenApple 8" +run_mcc_command "inventory player list" +run_mcc_command "inventory creativeclear 38" +run_mcc_command "inventory player list" + +# ── Phase 4: Block placement and interaction ── +run_server_command "execute as CursorBot at @s run fill ~1 ~ ~1 ~3 ~2 ~3 minecraft:stone" +sleep 2 +run_server_command "execute as CursorBot at @s run setblock ~5 ~ ~5 minecraft:chest" +sleep 1 +run_server_command "execute as CursorBot at @s run setblock ~5 ~1 ~5 minecraft:furnace" +sleep 1 +run_server_command "execute as CursorBot at @s run setblock ~6 ~ ~5 minecraft:crafting_table" +sleep 1 + +# ── Phase 5: Entity spawning (expanded coverage) ── run_server_command "execute as CursorBot at @s run summon minecraft:cow ~2 ~ ~" run_server_command "execute as CursorBot at @s run summon minecraft:zombie ~4 ~ ~" run_server_command "execute as CursorBot at @s run summon minecraft:creeper ~6 ~ ~" @@ -172,41 +201,99 @@ run_server_command "execute as CursorBot at @s run summon minecraft:skeleton ~8 run_server_command "execute as CursorBot at @s run summon minecraft:villager ~-2 ~ ~" run_server_command "execute as CursorBot at @s run summon minecraft:allay ~-4 ~ ~" run_server_command "execute as CursorBot at @s run summon minecraft:armor_stand ~ ~ ~2" +run_server_command "execute as CursorBot at @s run summon minecraft:item_display ~-6 ~ ~ {item:{id:\"minecraft:diamond\",count:1}}" +run_server_command "execute as CursorBot at @s run summon minecraft:spider ~10 ~ ~" +run_server_command "execute as CursorBot at @s run summon minecraft:pig ~-8 ~ ~" sleep 2 run_mcc_command "entity" +# ── Phase 6: Effects and environment ── +run_server_command "effect give CursorBot minecraft:speed 30 1" +sleep 2 +run_mcc_command "health" +run_server_command "effect give CursorBot minecraft:regeneration 10 1" +sleep 2 +run_mcc_command "health" + +# ── Phase 7: Gamemode cycling ── +run_mcc_command "/gamemode survival" +sleep 2 +run_mcc_command "health" +run_mcc_command "/gamemode creative" +sleep 2 + +# ── Phase 8: Dimension change (nether) ── +run_server_command "execute in minecraft:the_nether run tp CursorBot 0 64 0" +sleep 4 +run_mcc_command "health" +run_server_command "execute in minecraft:overworld run tp CursorBot 0 -60 0" +sleep 4 + +# ── Phase 9: Server chat and whisper ── +run_server_command "say Hello from the server console" +sleep 2 +run_server_command "msg CursorBot This is a private whisper" +sleep 2 +run_mcc_command "integration_test_chat_response" + +# ── Phase 10: Particles, sounds, and explosions ── run_server_command "execute as CursorBot at @s run particle minecraft:happy_villager ~ ~1 ~ 0.5 0.5 0.5 0 12 force" run_server_command "execute as CursorBot at @s run particle minecraft:end_rod ~ ~1 ~ 0.5 0.5 0.5 0.01 20 force" run_server_command "execute as CursorBot at @s run particle minecraft:explosion ~ ~1 ~ 0 0 0 0 1 force" run_server_command "execute as CursorBot at @s run particle minecraft:totem_of_undying ~ ~1 ~ 0.5 0.5 0.5 0.1 20 force" +run_server_command "execute as CursorBot at @s run particle minecraft:flame ~ ~1 ~ 0.2 0.2 0.2 0.02 30 force" +run_server_command "execute as CursorBot at @s run particle minecraft:heart ~ ~2 ~ 0.3 0.3 0.3 0 5 force" run_server_command "execute as CursorBot at @s run playsound minecraft:entity.lightning_bolt.thunder master CursorBot ~ ~ ~ 1 1 0" run_server_command "execute as CursorBot at @s run playsound minecraft:block.note_block.bell master CursorBot ~ ~ ~ 1 1 0" +run_server_command "execute as CursorBot at @s run playsound minecraft:entity.experience_orb.pickup master CursorBot ~ ~ ~ 1 1 0" run_server_command "execute as CursorBot at @s run summon minecraft:tnt ~3 ~ ~" sleep 2 run_server_command "execute as CursorBot at @s run summon minecraft:tnt ~6 ~ ~" +# ── Phase 11: Kill and respawn cycle ── +run_mcc_command "/gamemode survival" +sleep 2 +run_server_command "kill CursorBot" +sleep 4 +run_mcc_command "respawn" +sleep 4 +run_mcc_command "health" +run_mcc_command "/gamemode creative" +sleep 2 + sleep 6 capture_server_logs +# ── Assertions: MCC log ── assert_contains "$MCC_LOG" "Server was successfully joined." "MCC never joined the server" assert_contains "$MCC_LOG" "[FileInput] > inventory player list" "Inventory command was not executed" assert_contains "$MCC_LOG" "[FileInput] > entity" "Entity command was not executed" assert_contains "$MCC_LOG" "[FileInput] > /gamemode creative" "Creative mode command was not executed from MCC" assert_contains "$MCC_LOG" "Requested Diamond x16 in slot #36" "Creative inventory give did not succeed" assert_contains "$MCC_LOG" "smoke_test_from_mcc_full_spectrum" "Client-originated chat was not observed" +assert_contains "$MCC_LOG" "[FileInput] > look up" "Look command was not executed" +assert_contains "$MCC_LOG" "[FileInput] > /gamemode survival" "Survival mode switch was not executed" +assert_contains "$MCC_LOG" "[FileInput] > respawn" "Respawn command was not executed" +assert_contains "$MCC_LOG" "[FileInput] > health" "Health command was not executed" +assert_contains "$MCC_LOG" "integration_test_chat_response" "Chat response test message was not observed" assert_not_contains "$MCC_LOG" "Please enable InventoryHandling" "Inventory handling is still disabled" assert_not_contains "$MCC_LOG" "Please enable EntityHandling" "Entity handling is still disabled" assert_not_contains "$MCC_LOG" "You must be in Creative gamemode" "Creative mode was not active when creativegive ran" assert_not_contains "$MCC_LOG" "Failed to load settings" "MCC failed to reload its config" +assert_not_contains "$MCC_LOG" "NullReferenceException" "A NullReferenceException occurred during the test" +# ── Assertions: Server log ── assert_contains "$SERVER_FILE_LOG" "CursorBot joined the game" "Server never saw CursorBot join" assert_contains "$SERVER_FILE_LOG" "smoke_test_from_mcc_full_spectrum" "Server never received the client chat message" assert_contains "$SERVER_FILE_LOG" "Displaying particle minecraft:happy_villager" "Particle events were not recorded on the server" assert_contains "$SERVER_FILE_LOG" "Played sound minecraft:block.note_block.bell to CursorBot" "Sound events were not recorded on the server" assert_contains "$SERVER_FILE_LOG" "Summoned new Primed TNT" "TNT summon did not occur on the server" +assert_contains "$SERVER_FILE_LOG" "integration_test_chat_response" "Server never received the chat response test message" +assert_contains "$SERVER_FILE_LOG" "Hello from the server console" "Server say command was not logged" +assert_contains "$SERVER_FILE_LOG" "Killed CursorBot" "Server kill command did not execute" assert_not_contains "$SERVER_FILE_LOG" "Sending unknown packet 'clientbound/minecraft:disconnect'" "Server hit the disconnect packet regression during the test" cat < - /// Looks up a localized string similar to Automatically farms crops for you (plants, breaks and bonemeals them). + /// Looks up a localized string similar to When enabled, messages from other Discord bots in the channel will be relayed to Minecraft chat.. + /// + internal static string ChatBot_DiscordBridge_AllowOtherBotMessages { + get { + return ResourceManager.GetString("ChatBot.DiscordBridge.AllowOtherBotMessages", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Automatically farms cropsfor you (plants, breaks and bonemeals them). ///Crop types available: Beetroot, Carrot, Melon, Netherwart, Pumpkin, Potato, Wheat. ///Usage: "/farmer start" command and "/farmer stop" command. ///NOTE: This a newly added bot, it is not perfect and was only tested in 1.19.2, there are some minor issues like not being able to bonemeal carrots/potatoes sometimes. @@ -899,7 +908,9 @@ namespace MinecraftClient { } /// - /// Looks up a localized string similar to Show a Discord Rich Presence status with your current Minecraft session info.. + /// Looks up a localized string similar to Show a Discord Rich Presence status with your current Minecraft session info. + ///Setup: + ///1. Go to https://discord.com/developers/applications and log in with your Discord account. [rest of string was truncated]";. /// internal static string ChatBot_DiscordRpc { get { diff --git a/MinecraftClient/Resources/ConfigComments/ConfigComments.resx b/MinecraftClient/Resources/ConfigComments/ConfigComments.resx index b68844fa..9c6152df 100644 --- a/MinecraftClient/Resources/ConfigComments/ConfigComments.resx +++ b/MinecraftClient/Resources/ConfigComments/ConfigComments.resx @@ -390,6 +390,9 @@ For Discord message formatting, check the following: https://mccteam.github.io/r Your Discord Bot token. + + When enabled, messages from other Discord bots in the channel will be relayed to Minecraft chat. The bridge always ignores its own messages to prevent loops. + Automatically farms crops for you (plants, breaks and bonemeals them). Crop types available: Beetroot, Carrot, Melon, Netherwart, Pumpkin, Potato, Wheat. @@ -829,7 +832,13 @@ If the connection to the Minecraft game server is blocked by the firewall, set E A Chat Bot that collects items on the ground - Show a Discord Rich Presence status with your current Minecraft session info.\nRequires a Discord Application ID from https://discord.com/developers/applications\nYou can customize what is shown using placeholders: {server_host}, {server_port}, {username}, {health}, {max_health}, {food}, {dimension}, {gamemode}, {x}, {y}, {z}, {player_count}, {protocol} + Show a Discord Rich Presence status with your current Minecraft session info. +Setup: +1. Go to https://discord.com/developers/applications and log in with your Discord account. +2. Click "New Application", give it a name (e.g. "MCC") and confirm. +3. On the application page, copy the "Application ID" and paste it in the "ApplicationId" field below. +4. (Optional) Go to "Rich Presence" -> "Art Assets" to upload custom images for LargeImageKey/SmallImageKey. +Note: This does NOT require a Bot Token, only an Application ID. Discord must be running on the same machine as MCC. Your Discord Application ID. Create one at https://discord.com/developers/applications