diff --git a/client/net/minecraftforge/client/ClientCommandHandler.java b/client/net/minecraftforge/client/ClientCommandHandler.java new file mode 100644 index 000000000..b929e723e --- /dev/null +++ b/client/net/minecraftforge/client/ClientCommandHandler.java @@ -0,0 +1,140 @@ +package net.minecraftforge.client; + +import java.util.List; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiChat; +import net.minecraft.command.CommandException; +import net.minecraft.command.CommandHandler; +import net.minecraft.command.ICommand; +import net.minecraft.command.ICommandSender; +import net.minecraft.command.WrongUsageException; +import net.minecraft.util.ChatMessageComponent; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.CommandEvent; +import cpw.mods.fml.client.FMLClientHandler; +import static net.minecraft.util.EnumChatFormatting.*; + +/** + * The class that handles client-side chat commands. You should register any + * commands that you want handled on the client with this command handler. + * + * If there is a command with the same name registered both on the server and + * client, the client takes precedence! + * + */ +public class ClientCommandHandler extends CommandHandler +{ + public static final ClientCommandHandler instance = new ClientCommandHandler(); + + public String[] latestAutoComplete = null; + + /** + * @return 1 if successfully executed, 0 if wrong usage, it doesn't exist or + * it was canceled. + */ + @Override + public int executeCommand(ICommandSender sender, String message) + { + message = message.trim(); + + if (message.startsWith("/")) + { + message = message.substring(1); + } + + String[] args = message.split(" "); + String commandName = args[0]; + System.arraycopy(args, 1, args, 0, args.length - 1); + ICommand icommand = (ICommand) getCommands().get(commandName); + + try + { + if (icommand == null) + { + return 0; + } + + if (icommand.canCommandSenderUseCommand(sender)) + { + CommandEvent event = new CommandEvent(icommand, sender, args); + if (MinecraftForge.EVENT_BUS.post(event)) + { + if (event.exception != null) + { + throw event.exception; + } + return 0; + } + + icommand.processCommand(sender, args); + return 1; + } + else + { + sender.sendChatToPlayer(format("commands.generic.permission").setColor(RED)); + } + } + catch (WrongUsageException wue) + { + sender.sendChatToPlayer(format("commands.generic.usage", format(wue.getMessage(), wue.getErrorOjbects())).setColor(RED)); + } + catch (CommandException ce) + { + sender.sendChatToPlayer(format(ce.getMessage(), ce.getErrorOjbects()).setColor(RED)); + } + catch (Throwable t) + { + sender.sendChatToPlayer(format("commands.generic.exception").setColor(RED)); + t.printStackTrace(); + } + + return 0; + } + + //Couple of helpers because the mcp names are stupid and long... + private ChatMessageComponent format(String str, Object... args) + { + return ChatMessageComponent.createFromTranslationWithSubstitutions(str, args); + } + + private ChatMessageComponent format(String str) + { + return ChatMessageComponent.createFromTranslationKey(str); + } + + public void autoComplete(String leftOfCursor, String full) + { + latestAutoComplete = null; + + if (leftOfCursor.charAt(0) == '/') + { + leftOfCursor = leftOfCursor.substring(1); + + Minecraft mc = FMLClientHandler.instance().getClient(); + if (mc.currentScreen instanceof GuiChat) + { + List commands = getPossibleCommands(mc.thePlayer, leftOfCursor); + if (commands != null && !commands.isEmpty()) + { + if (leftOfCursor.indexOf(' ') == -1) + { + for (int i = 0; i < commands.size(); i++) + { + commands.set(i, GRAY + "/" + commands.get(i) + RESET); + } + } + else + { + for (int i = 0; i < commands.size(); i++) + { + commands.set(i, GRAY + commands.get(i) + RESET); + } + } + + latestAutoComplete = commands.toArray(new String[commands.size()]); + } + } + } + } +} \ No newline at end of file diff --git a/patches/minecraft/net/minecraft/client/Minecraft.java.patch b/patches/minecraft/net/minecraft/client/Minecraft.java.patch index 021d32ef9..5e3cec260 100644 --- a/patches/minecraft/net/minecraft/client/Minecraft.java.patch +++ b/patches/minecraft/net/minecraft/client/Minecraft.java.patch @@ -1,9 +1,10 @@ --- ../src_base/minecraft/net/minecraft/client/Minecraft.java +++ ../src_work/minecraft/net/minecraft/client/Minecraft.java -@@ -137,6 +137,15 @@ +@@ -137,6 +137,16 @@ import com.google.common.collect.MapDifference; ++import net.minecraftforge.client.ClientCommandHandler; +import net.minecraftforge.client.ForgeHooksClient; +import net.minecraftforge.client.GuiIngameForge; +import net.minecraftforge.client.event.GuiOpenEvent; @@ -16,7 +17,7 @@ @SideOnly(Side.CLIENT) public class Minecraft implements IPlayerUsage { -@@ -416,7 +425,7 @@ +@@ -416,7 +426,7 @@ try { @@ -25,7 +26,7 @@ } catch (LWJGLException lwjglexception) { -@@ -497,7 +506,7 @@ +@@ -497,7 +507,7 @@ this.effectRenderer = new EffectRenderer(this.theWorld, this.renderEngine); FMLClientHandler.instance().finishMinecraftLoading(); this.checkGLError("Post startup"); @@ -34,7 +35,7 @@ if (this.serverName != null) { -@@ -679,11 +688,6 @@ +@@ -679,11 +689,6 @@ */ public void displayGuiScreen(GuiScreen par1GuiScreen) { @@ -46,7 +47,7 @@ this.statFileWriter.syncStats(); if (par1GuiScreen == null && this.theWorld == null) -@@ -693,6 +697,20 @@ +@@ -693,6 +698,20 @@ else if (par1GuiScreen == null && this.thePlayer.getHealth() <= 0.0F) { par1GuiScreen = new GuiGameOver(); @@ -67,7 +68,7 @@ } if (par1GuiScreen instanceof GuiMainMenu) -@@ -1300,7 +1318,7 @@ +@@ -1300,7 +1319,7 @@ if (this.thePlayer.isCurrentToolAdventureModeExempt(j, k, l)) { @@ -76,7 +77,7 @@ this.thePlayer.swingItem(); } } -@@ -1366,7 +1384,8 @@ +@@ -1366,7 +1385,8 @@ { int j1 = itemstack != null ? itemstack.stackSize : 0; @@ -86,7 +87,7 @@ { flag = false; this.thePlayer.swingItem(); -@@ -1392,7 +1411,8 @@ +@@ -1392,7 +1412,8 @@ { ItemStack itemstack1 = this.thePlayer.inventory.getCurrentItem(); @@ -96,7 +97,7 @@ { this.entityRenderer.itemRenderer.resetEquippedProgress2(); } -@@ -1574,6 +1594,8 @@ +@@ -1574,6 +1595,8 @@ while (Mouse.next()) { @@ -105,7 +106,7 @@ i = Mouse.getEventButton(); if (isRunningOnMac && i == 0 && (Keyboard.isKeyDown(29) || Keyboard.isKeyDown(157))) -@@ -2046,6 +2068,11 @@ +@@ -2046,6 +2069,11 @@ { this.statFileWriter.syncStats(); @@ -117,7 +118,7 @@ if (par1WorldClient == null) { NetClientHandler netclienthandler = this.getNetHandler(); -@@ -2063,6 +2090,18 @@ +@@ -2063,6 +2091,18 @@ if (this.theIntegratedServer != null) { this.theIntegratedServer.initiateShutdown(); @@ -136,7 +137,16 @@ } this.theIntegratedServer = null; -@@ -2236,107 +2275,12 @@ +@@ -2225,7 +2265,7 @@ + */ + public boolean handleClientCommand(String par1Str) + { +- return false; ++ return ClientCommandHandler.instance.executeCommand(thePlayer, par1Str) == 1; + } + + /** +@@ -2236,107 +2276,12 @@ if (this.objectMouseOver != null) { boolean flag = this.thePlayer.capabilities.isCreativeMode; @@ -248,7 +258,7 @@ if (flag) { -@@ -2419,11 +2363,18 @@ +@@ -2419,11 +2364,18 @@ par1PlayerUsageSnooper.addData("gl_max_texture_size", Integer.valueOf(getGLMaximumTextureSize())); } @@ -267,7 +277,7 @@ for (int i = 16384; i > 0; i >>= 1) { GL11.glTexImage2D(GL11.GL_PROXY_TEXTURE_2D, 0, GL11.GL_RGBA, i, i, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, (ByteBuffer)null); -@@ -2431,6 +2382,7 @@ +@@ -2431,6 +2383,7 @@ if (j != 0) { diff --git a/patches/minecraft/net/minecraft/client/gui/GuiChat.java.patch b/patches/minecraft/net/minecraft/client/gui/GuiChat.java.patch new file mode 100644 index 000000000..755d5e311 --- /dev/null +++ b/patches/minecraft/net/minecraft/client/gui/GuiChat.java.patch @@ -0,0 +1,44 @@ +--- ../src_base/minecraft/net/minecraft/client/gui/GuiChat.java ++++ ../src_work/minecraft/net/minecraft/client/gui/GuiChat.java +@@ -7,8 +7,11 @@ + import java.util.Iterator; + import java.util.List; + import net.minecraft.network.packet.Packet203AutoComplete; ++import net.minecraft.util.EnumChatFormatting; ++import net.minecraftforge.client.ClientCommandHandler; + import org.lwjgl.input.Keyboard; + import org.lwjgl.input.Mouse; ++import com.google.common.collect.ObjectArrays; + + @SideOnly(Side.CLIENT) + public class GuiChat extends GuiScreen +@@ -278,13 +281,14 @@ + this.mc.ingameGUI.getChatGUI().printChatMessageWithOptionalDeletion(stringbuilder.toString(), 1); + } + +- this.inputField.writeText((String)this.field_73904_o.get(this.field_73903_n++)); ++ this.inputField.writeText(EnumChatFormatting.func_110646_a((String)this.field_73904_o.get(this.field_73903_n++))); + } + + private void func_73893_a(String par1Str, String par2Str) + { + if (par1Str.length() >= 1) + { ++ ClientCommandHandler.instance.autoComplete(par1Str, par2Str); + this.mc.thePlayer.sendQueue.addToSendQueue(new Packet203AutoComplete(par1Str)); + this.field_73905_m = true; + } +@@ -347,6 +351,13 @@ + String[] astring1 = par1ArrayOfStr; + int i = par1ArrayOfStr.length; + ++ String[] complete = ClientCommandHandler.instance.latestAutoComplete; ++ if (complete != null) ++ { ++ astring1 = ObjectArrays.concat(complete, astring1, String.class); ++ i = astring1.length; ++ } ++ + for (int j = 0; j < i; ++j) + { + String s = astring1[j];