Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
08c5c15
1.20.6 - Not working yet
milutinke Jun 15, 2024
67e36a9
First working version, not fully tested
milutinke Jun 30, 2024
58a5260
Merge branch 'master' of github.com:milutinke/Minecraft-Console-Clien…
milutinke Jun 30, 2024
5a6fd57
Inventory, Terrain and Entity handling
milutinke Jul 2, 2024
63b027d
First Version of Structured Components
milutinke Sep 1, 2024
76e873e
WIP: Added some strctured components
milutinke Sep 11, 2024
49319fe
Added more components + added item palette reference
milutinke Sep 11, 2024
4dea688
Added more structured components
milutinke Sep 11, 2024
0da4a71
Implemented all structured components, renamed them all to a better f…
milutinke Oct 5, 2024
7bd213a
Fixed the potion component crash
milutinke Dec 4, 2024
f83e7c5
Preliminary 1.21 Support
milutinke Dec 6, 2024
7152072
Ported to .NET 8
milutinke Dec 22, 2024
a1acd55
Updated the pipeline
milutinke Dec 22, 2024
a5ab30f
Fix session cache serializer failure
breadbyte Dec 24, 2024
304c8f0
Merge pull request #10 from Visual-Novel-Decompilation-Project/1.20.6
milutinke Dec 24, 2024
494be09
Merge branch 'master' into 1.20.6
breadbyte Dec 1, 2025
ff1c570
Handle non-interactive terminal environments gracefully
BruceChenQAQ Mar 18, 2026
a7a95d9
Fix EntityProperties attribute ID mapping for 1.20.6
BruceChenQAQ Mar 18, 2026
41a701b
Fix RegistryData parsing and KnownDataPacks negotiation for 1.20.6
BruceChenQAQ Mar 18, 2026
bb18399
Use dynamic dimension registry lookup in JoinGame and Respawn packets
BruceChenQAQ Mar 18, 2026
8eac21b
Wire up 1.20.6 structured components to Item and fix GetItemSlot seri…
BruceChenQAQ Mar 18, 2026
967f671
Add FileInputBot for non-interactive debugging and fix NbtToString crash
BruceChenQAQ Mar 18, 2026
99ac3d0
Dynamically parse minecraft:attribute registry from server RegistryData
BruceChenQAQ Mar 18, 2026
b692b13
Fix EntityProperties crash and add default attribute registry fallback
BruceChenQAQ Mar 18, 2026
56f2426
Fix StructuredComponent serialization correctness for 1.20.6
BruceChenQAQ Mar 18, 2026
1e2b853
Fix PotionContentsComponent and InstrumentComponent serialization for…
BruceChenQAQ Mar 18, 2026
79a0dff
Fix enchantment name display for 1.20.6 structured components
BruceChenQAQ Mar 18, 2026
a36ba23
fix: StructuredComponents batch 1 audit — TrimComponent, ProfileCompo…
BruceChenQAQ Mar 19, 2026
4944497
fix: StructuredComponents batch 2 audit — BlockPredicate and Property…
BruceChenQAQ Mar 19, 2026
c689343
fix: StructuredComponents batch 3 audit — EnchantmentGlintOverrideCom…
BruceChenQAQ Mar 19, 2026
5e416d6
fix: StructuredComponents batch 4 audit — CustomName, ItemName, Lore …
BruceChenQAQ Mar 19, 2026
cc10f4e
refactor: StructuredComponents batch 5 audit — remove redundant count…
BruceChenQAQ Mar 19, 2026
2fb0934
feat: add ItemPalette121 and new 1.21 music disc item types
BruceChenQAQ Mar 19, 2026
c23c229
feat: protocol 767 (1.21) packet handling and AttributeSubComponent u…
BruceChenQAQ Mar 19, 2026
ee02974
fix: Explosion packet parsing and update attribute fallback for 1.21
BruceChenQAQ Mar 19, 2026
e1cb18c
fix: add EntityMetadataPalette1206 for correct 1.20.6+ entity metadat…
BruceChenQAQ Mar 19, 2026
7609832
chore: add reusable version adaptation scripts
BruceChenQAQ Mar 19, 2026
896263a
fix: resolve entity tracking, container interaction, and enchantment …
BruceChenQAQ Mar 19, 2026
df833ae
feat: add palettes and version constants for MC 1.21.2 (protocol 768)
BruceChenQAQ Mar 19, 2026
57a0ded
feat: add packet palette, data components, and protocol fixes for MC …
BruceChenQAQ Mar 19, 2026
a92bf5b
feat: complete 1.21.2 protocol handling for terrain, inventory, and e…
BruceChenQAQ Mar 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions .cursor/skills/mcc-version-adaptation/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
---
name: mcc-version-adaptation
description: Adapt MCC palettes and protocol handling for a new Minecraft version. Use when the user wants to add support for a new MC version, compare version registries, update item/entity/block/metadata palettes, or fix protocol mismatches between MC versions.
---

# MCC Version Adaptation

Systematic workflow for updating Minecraft Console Client to support a new Minecraft version, focusing on palette/registry changes and entity metadata.

## Prerequisites

- Decompiled server source for both the old and new MC versions in `$MCC_REPO/MinecraftOfficial/<version>-decompiled/`
- If missing, decompile first:
```bash
cd $MCC_REPO/MinecraftOfficial
java -jar MinecraftDecompiler.jar --version <ver> --side SERVER \
--decompile --output <ver>-remapped.jar --decompiled-output <ver>-decompiled
```

## Step 1: Run Registry Diff

```bash
python3 $MCC_REPO/tools/diff_registries.py <old_ver> <new_ver>
```

This compares five registries and reports which need palette updates:

| Registry | MCC File | When to Update |
|----------|----------|----------------|
| Items.java | `ItemPalettes/ItemPaletteXXX.cs` | New/removed/reordered items |
| EntityType.java | `EntityPalettes/EntityPaletteXXX.cs` | New/removed/reordered entity types |
| Blocks.java | `BlockPalettes/BlockPaletteXXX.cs` | New/removed/reordered blocks |
| DataComponents.java | `StructuredComponents/StructuredComponentsRegistryXXX.cs` | New/reordered components |
| EntityDataSerializers.java | `EntityMetadataPalettes/EntityMetadataPaletteXXX.cs` | New/reordered serializer types |

## Step 2: Generate Updated Palettes

For registries marked "PALETTE UPDATE NEEDED":

### Item Palette
```bash
python3 $MCC_REPO/tools/gen_item_palette.py <new_ver> <suffix>
# e.g., gen_item_palette.py 1.21.1 121
```
- If new items are reported missing from `ItemType.cs`, add them to the enum in alphabetical order.
- The script auto-generates the C# palette file.

### Entity Metadata Palette
```bash
python3 $MCC_REPO/tools/gen_entity_metadata_palette.py <new_ver> <suffix>
# e.g., gen_entity_metadata_palette.py 1.20.6 1206
```
- If new serializer types appear as UNMAPPED, add them to both:
1. The script's `FIELD_TO_ENUM` dictionary
2. MCC's `EntityMetaDataType.cs` enum
3. `DataTypes.cs` read logic (add a `case` to consume the correct bytes)

### Entity/Block Palettes
No generator script yet — these change rarely. When needed, manually create by following the pattern of existing palette files, using `register("name", ...)` call order from the decompiled source.

### DataComponents / StructuredComponents
Compare `DataComponents.java` registration order. If new components appear, update `StructuredComponentsRegistryXXX.cs`. For new component types, implement corresponding reader in `StructuredComponents/Components/`.

## Step 3: Update Version Routing

After creating palette files, update version selection logic:

| Palette Type | Routing Location |
|-------------|-----------------|
| Item | `Protocol18.cs` → `itemPalette` switch expression |
| Entity | `Protocol18.cs` → `entityPalette` switch expression |
| Block | `Protocol18.cs` → `blockPalette` initialization |
| EntityMetadata | `EntityMetadataPalette.cs` → `GetPalette()` switch |
| DataComponents | `StructuredComponentsRegistry.cs` → factory/routing |

Pattern: add a new `>= MC_X_Y_Z_Version => new XxxPaletteXYZ()` case.

## Step 4: Check Variant Encoding Changes

For entity types that use variant serializers (Cat, Wolf, Frog, Painting), check if the codec changed between versions by inspecting:

- `EntityDataSerializers.java` — look at how each `*_VARIANT` field is constructed
- Key codecs:
- `ByteBufCodecs.holderRegistry()` → wire format: `VarInt(registry_id)`
- `ByteBufCodecs.holder()` → wire format: `VarInt(id+1)` for registered, `VarInt(0) + inline_data` for direct
- If codec changed, update `DataTypes.cs` entity metadata reading logic accordingly.

## Step 5: Handle New EntityDataSerializer Types

When new serializer types are added (detected in Step 1):

1. Add enum value to `EntityMetaDataType.cs` with XML doc comment
2. Add read logic in `DataTypes.cs` `ReadNextMetadata()`:
- Determine byte consumption from the decompiled codec
- Examples: VarInt read, list of particles, etc.
3. Create the new palette file (Step 2)
4. Update palette routing (Step 3)

## Step 6: Compile and Verify

```bash
dotnet build $MCC_REPO/MinecraftClient.sln -c Release
```

Then connect to a test server of the target version (see `mcc-dev-workflow` skill) and verify:
- Successful connection
- `/give` new items → check inventory
- Summon entities (especially variant types) → no metadata parse errors
- Particle effects → no crashes

## Key Source Files Reference

| Decompiled Java Source | Purpose |
|----------------------|---------|
| `world/item/Items.java` | Item registry (field declaration order = ID) |
| `world/entity/EntityType.java` | Entity type registry (`register()` call order = ID) |
| `world/level/block/Blocks.java` | Block registry (`register()` call order = ID) |
| `core/component/DataComponents.java` | Data component registry |
| `network/syncher/EntityDataSerializers.java` | Entity metadata type registry (static block order = ID) |

## Common Pitfalls

- **ID order matters**: IDs are determined by declaration/registration order, not alphabetical. Always use the decompiled source as ground truth.
- **Cross-version jumps**: When MCC skips versions (e.g., 1.20.4→1.20.6), registries from ALL intermediate versions may have changed. Always diff against the actual last-supported version, not the latest palette.
- **EntityMetadata type shifts**: A single new serializer type shifts all subsequent IDs, causing widespread metadata parse failures. Symptoms: entity rendering glitches, disconnections, or silent data corruption.
- **CUT_STANDSTONE_SLAB**: This is an intentional typo in Minecraft source (should be SANDSTONE). MCC's `ItemType.cs` uses `CutSandstoneSlab` — the gen script handles this via the OVERRIDES dict.

## Reusable Scripts

All scripts are in `$MCC_REPO/tools/`. See `tools/README.md` for detailed usage.
4 changes: 2 additions & 2 deletions .github/workflows/build-and-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

env:
PROJECT: "MinecraftClient"
target-version: "net7.0"
target-version: "net8.0"
compile-flags: "--self-contained=true -c Release -p:UseAppHost=true -p:IncludeNativeLibrariesForSelfExtract=true -p:EnableCompressionInSingleFile=true -p:DebugType=Embedded"

jobs:
Expand All @@ -19,7 +19,7 @@ jobs:
timeout-minutes: 15
strategy:
matrix:
target: [win-x86, win-x64, win-arm, win-arm64, linux-x64, linux-arm, linux-arm64, osx-x64, osx-arm64]
target: [win-x86, win-x64, win-arm64, linux-x64, linux-arm, linux-arm64, osx-x64, osx-arm64]

steps:
- name: Checkout
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,9 @@ FodyWeavers.xsd
!.vscode/extensions.json
*.code-workspace

# Cursor files
!.cursor/

# Local History for Visual Studio Code
.history/

Expand Down
105 changes: 105 additions & 0 deletions MinecraftClient/ChatBots/FileInputBot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
using System;
using System.IO;
using System.Threading;
using MinecraftClient.CommandHandler;
using MinecraftClient.Scripting;

namespace MinecraftClient.ChatBots
{
/// <summary>
/// Debug-only ChatBot that monitors a text file for commands.
/// Write lines to the file from any external tool (e.g. Cursor Shell)
/// and this bot will execute them as MCC internal commands.
///
/// Usage from Cursor Shell:
/// Add-Content mcc_input.txt "inventory"
/// Add-Content mcc_input.txt "send /give @s diamond_sword 1"
///
/// Lines starting with "/" are sent as server chat; others are treated
/// as MCC internal commands (same as typing in the MCC console).
/// </summary>
public class FileInputBot : ChatBot
{
private const string BotName = "FileInput";
private string _filePath = string.Empty;
private long _lastPosition;
private int _tickCounter;

public override void Initialize()
{
_filePath = Path.GetFullPath(
Environment.GetEnvironmentVariable("MCC_INPUT_FILE") ?? "mcc_input.txt");

if (File.Exists(_filePath))
_lastPosition = new FileInfo(_filePath).Length;
else
File.WriteAllText(_filePath, "");

LogToConsole(BotName, $"Watching: {_filePath}");
LogToConsole(BotName, "Write commands to this file to execute them.");
}

public override void Update()
{
// Poll every ~500ms (Update is called every ~100ms)
if (++_tickCounter < 5)
return;
_tickCounter = 0;

try
{
if (!File.Exists(_filePath))
return;

var info = new FileInfo(_filePath);
if (info.Length <= _lastPosition)
return;

string newContent;
using (var fs = new FileStream(_filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
fs.Seek(_lastPosition, SeekOrigin.Begin);
using var reader = new StreamReader(fs);
newContent = reader.ReadToEnd();
}
_lastPosition = info.Length;

foreach (var rawLine in newContent.Split('\n'))
{
var line = rawLine.Trim();
if (string.IsNullOrEmpty(line))
continue;

LogToConsole(BotName, $"> {line}");

if (line.StartsWith("/"))
{
SendText(line);
}
else
{
CmdResult result = new();
if (PerformInternalCommand(line, ref result))
{
if (!string.IsNullOrEmpty(result.ToString()))
LogToConsole(BotName, result.ToString());
}
else
{
// Not an internal command — send as chat
SendText(line);
}
}
}
}
catch (IOException)
{
// File may be temporarily locked by the writer
}
catch (Exception ex)
{
LogToConsole(BotName, $"Error: {ex.Message}");
}
}
}
}
9 changes: 6 additions & 3 deletions MinecraftClient/ChatBots/Map.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
Expand Down Expand Up @@ -344,8 +344,11 @@ public override void Update()
private static void RenderInConsole(McMap map)
{
StringBuilder sb = new();
int consoleWidth = Math.Max(Console.BufferWidth, Settings.Config.Main.Advanced.MinTerminalWidth) / 2;
int consoleHeight = Math.Max(Console.BufferHeight, Settings.Config.Main.Advanced.MinTerminalHeight) - 1;
int safeBufWidth, safeBufHeight;
try { safeBufWidth = Console.BufferWidth; } catch { safeBufWidth = 120; }
try { safeBufHeight = Console.BufferHeight; } catch { safeBufHeight = 50; }
int consoleWidth = Math.Max(safeBufWidth, Settings.Config.Main.Advanced.MinTerminalWidth) / 2;
int consoleHeight = Math.Max(safeBufHeight, Settings.Config.Main.Advanced.MinTerminalHeight) - 1;
int scaleX = (map.Width + consoleWidth - 1) / consoleWidth;
int scaleY = (map.Height + consoleHeight - 1) / consoleHeight;
int scale = Math.Max(scaleX, scaleY);
Expand Down
10 changes: 7 additions & 3 deletions MinecraftClient/Commands/Chunk.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Text;
using Brigadier.NET;
using Brigadier.NET.Builder;
Expand Down Expand Up @@ -100,11 +100,15 @@ private static int LogChunkStatus(CmdResult r, Location? pos = null, Tuple<int,
sb.AppendLine(string.Format(Translations.cmd_chunk_chunk_pos, markChunkX, markChunkZ)); ;
}

int consoleHeight = Math.Max(Math.Max(Console.BufferHeight, Settings.Config.Main.Advanced.MinTerminalHeight) - 2, 25);
int safeHeight;
int safeWidth;
try { safeHeight = Console.BufferHeight; } catch { safeHeight = 50; }
try { safeWidth = Console.BufferWidth; } catch { safeWidth = 120; }
int consoleHeight = Math.Max(Math.Max(safeHeight, Settings.Config.Main.Advanced.MinTerminalHeight) - 2, 25);
if (consoleHeight % 2 == 0)
--consoleHeight;

int consoleWidth = Math.Max(Math.Max(Console.BufferWidth, Settings.Config.Main.Advanced.MinTerminalWidth) / 2, 17);
int consoleWidth = Math.Max(Math.Max(safeWidth, Settings.Config.Main.Advanced.MinTerminalWidth) / 2, 17);
if (consoleWidth % 2 == 0)
--consoleWidth;

Expand Down
4 changes: 2 additions & 2 deletions MinecraftClient/Commands/Useblock.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Brigadier.NET;
using Brigadier.NET;
using Brigadier.NET.Builder;
using MinecraftClient.CommandHandler;
using MinecraftClient.Mapping;
Expand Down Expand Up @@ -48,7 +48,7 @@ private int UseBlockAtLocation(CmdResult r, Location block)
Location current = handler.GetCurrentLocation();
block = block.ToAbsolute(current).ToFloor();
Location blockCenter = block.ToCenter();
bool res = handler.PlaceBlock(block, Direction.Down);
bool res = handler.PlaceBlock(block, Direction.Down, lookAtBlock: true);
return r.SetAndReturn(string.Format(Translations.cmd_useblock_use, blockCenter.X, blockCenter.Y, blockCenter.Z, res ? "succeeded" : "failed"), res);
}
}
Expand Down
10 changes: 10 additions & 0 deletions MinecraftClient/Inventory/BookPage.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Collections.Generic;

namespace MinecraftClient.Inventory;

public record BookPage(
string RawContent,
bool HasFilteredContent,
string? FilteredContent,
Dictionary<string, object>? RawContentNbt = null,
Dictionary<string, object>? FilteredContentNbt = null);
3 changes: 3 additions & 0 deletions MinecraftClient/Inventory/Enchantment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
namespace MinecraftClient.Inventory;

public record Enchantment(Enchantments Type, int Level);
6 changes: 3 additions & 3 deletions MinecraftClient/Inventory/EnchantmentData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
{
public class EnchantmentData
{
public Enchantment TopEnchantment { get; set; }
public Enchantment MiddleEnchantment { get; set; }
public Enchantment BottomEnchantment { get; set; }
public Enchantments TopEnchantment { get; set; }
public Enchantments MiddleEnchantment { get; set; }
public Enchantments BottomEnchantment { get; set; }

// Seed for rendering Standard Galactic Language (symbols in the enchanting table) (Useful for poeple who use MCC for the protocol)
public short Seed { get; set; }
Expand Down
Loading