fix: support 1.21.11 recipe book display ids

Agent-Logs-Url: https://github.com/MCCTeam/Minecraft-Console-Client/sessions/4cdf26f2-112b-4502-88f7-8f589c424f69

Co-authored-by: milutinke <441903+milutinke@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot] 2026-03-29 18:45:14 +00:00
parent dfc1164839
commit b05c8cfe0d
5 changed files with 209 additions and 30 deletions

View file

@ -49,7 +49,7 @@ namespace MinecraftClient
private readonly List<ChatBot> bots = new();
private static readonly List<ChatBot> botsOnHold = new();
private static readonly Dictionary<int, Container> inventories = new();
private readonly HashSet<string> unlockedRecipes = new(StringComparer.Ordinal);
private readonly Dictionary<string, RecipeBookRecipeEntry> unlockedRecipes = new(StringComparer.Ordinal);
private readonly Dictionary<string, List<ChatBot>> registeredBotPluginChannels = new();
private readonly List<string> registeredServerPluginChannels = new();
@ -1345,11 +1345,11 @@ namespace MinecraftClient
/// Get all unlocked recipe book recipe identifiers.
/// </summary>
/// <returns>Unlocked recipe identifiers sorted alphabetically</returns>
public string[] GetUnlockedRecipes()
public RecipeBookRecipeEntry[] GetUnlockedRecipes()
{
lock (recipeBookLock)
{
return [.. unlockedRecipes.OrderBy(static recipeId => recipeId, StringComparer.Ordinal)];
return unlockedRecipes.Values.OrderBy(static recipe => recipe.CommandId, StringComparer.Ordinal).ToArray();
}
}
@ -2728,7 +2728,7 @@ namespace MinecraftClient
if (activeInventory is null)
return false;
string normalizedRecipeId = NormalizeRecipeId(recipeId);
string normalizedRecipeId = NormalizeRecipeArgument(recipeId, protocolversion);
if (normalizedRecipeId.Length == 0)
return false;
@ -4111,17 +4111,18 @@ namespace MinecraftClient
Log.Debug("CanSendMessage = " + canSendMessage);
}
public void OnRecipeBookAdd(string[] recipeIds, bool replace)
public void OnRecipeBookAdd(RecipeBookRecipeEntry[] recipes, bool replace)
{
lock (recipeBookLock)
{
if (replace)
unlockedRecipes.Clear();
foreach (string recipeId in recipeIds)
foreach (RecipeBookRecipeEntry recipe in recipes)
{
if (!string.IsNullOrWhiteSpace(recipeId))
unlockedRecipes.Add(recipeId);
// Guard against malformed server packets that send empty display IDs.
if (!string.IsNullOrWhiteSpace(recipe.CommandId))
unlockedRecipes[recipe.CommandId] = recipe;
}
}
}
@ -4173,7 +4174,19 @@ namespace MinecraftClient
}
}
internal static string NormalizeRecipeId(string recipeId)
/// <summary>
/// Normalize a recipe argument for the target protocol version.
/// Legacy recipe-book packets use identifiers and default to the minecraft namespace.
/// 1.21.2+ recipe-book packets use numeric recipe display ids and should be left trimmed-only.
/// </summary>
internal static string NormalizeRecipeArgument(string recipeId, int protocolVersion)
{
return protocolVersion >= Protocol18Handler.MC_1_21_2_Version
? recipeId.Trim()
: NormalizeRecipeId(recipeId);
}
private static string NormalizeRecipeId(string recipeId)
{
string trimmedRecipeId = recipeId.Trim();
if (trimmedRecipeId.Length == 0)