Fix issues with client only commands in combination with server only commands not using MC's command system. (#8452)

This commit is contained in:
Take Weiland authored and GitHub committed 2022-02-08 11:24:55 -08:00
1 parent 3b754fef5e
commit 4f4849b60c
3 files changed
+37 -3

No files matched your search

@@ -35,6 +35,7 @@ import com.mojang.brigadier.tree.RootCommandNode;
import net.minecraft.ChatFormatting;
import net.minecraft.Util;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ClientPacketListener;
import net.minecraft.client.player.LocalPlayer;
import net.minecraft.commands.CommandRuntimeException;
import net.minecraft.commands.CommandSourceStack;
@@ -46,6 +47,7 @@ import net.minecraft.network.chat.HoverEvent;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.TextComponent;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraftforge.client.event.ClientPlayerNetworkEvent;
import net.minecraftforge.client.event.RegisterClientCommandsEvent;
import net.minecraftforge.common.MinecraftForge;
import org.apache.logging.log4j.LogManager;
@@ -60,6 +62,22 @@ public class ClientCommandHandler
private static final Logger LOGGER = LogManager.getLogger();
private static CommandDispatcher<CommandSourceStack> commands = null;
public static void init()
{
MinecraftForge.EVENT_BUS.addListener(ClientCommandHandler::handleClientPlayerLogin);
}
private static void handleClientPlayerLogin(ClientPlayerNetworkEvent.LoggedInEvent event)
{
// some custom server implementations do not send ClientboundCommandsPacket, provide a fallback
var suggestionDispatcher = mergeServerCommands(new CommandDispatcher<>());
if (event.getConnection().getPacketListener() instanceof ClientPacketListener listener)
{
// Must set this, so that suggestions for client-only commands work, if server never sends commands packet
listener.commands = suggestionDispatcher;
}
}
/*
* For internal use
*
@@ -144,11 +162,17 @@ public class ClientCommandHandler
*/
private static <S> void copy(CommandNode<S> sourceNode, CommandNode<S> resultNode)
{
Map<CommandNode<S>, CommandNode<S>> newNodes = new IdentityHashMap<>();
newNodes.put(sourceNode, resultNode);
for (CommandNode<S> child : sourceNode.getChildren())
{
ArgumentBuilder<S, ?> builder = child.createBuilder();
CommandNode<S> copy = builder.build();
copy(child, copy);
CommandNode<S> copy = newNodes.computeIfAbsent(child, innerChild ->
{
ArgumentBuilder<S, ?> builder = innerChild.createBuilder();
CommandNode<S> innerCopy = builder.build();
copy(innerChild, innerCopy);
return innerCopy;
});
resultNode.addChild(copy);
}
}
@@ -278,6 +302,11 @@ public class ClientCommandHandler
}
catch (CommandSyntaxException syntax)// Usually thrown by the CommandDispatcher
{
if (syntax.getType() == CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownCommand())
{
// in case of unknown command, let the server try and handle it
return false;
}
Minecraft.getInstance().player.sendMessage(
new TextComponent("").append(ComponentUtils.fromMessage(syntax.getRawMessage())).withStyle(ChatFormatting.RED), Util.NIL_UUID);
if (syntax.getInput() != null && syntax.getCursor() >= 0)
@@ -19,8 +19,11 @@
package net.minecraftforge.common;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.ClientCommandHandler;
import net.minecraftforge.eventbus.api.BusBuilder;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.loading.FMLEnvironment;
import net.minecraftforge.versions.forge.ForgeVersion;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@@ -52,6 +55,7 @@ public class MinecraftForge
UsernameCache.load();
TierSortingRegistry.init();
if (FMLEnvironment.dist == Dist.CLIENT) ClientCommandHandler.init();
}
/*