package net.minecraft.client.gui; import com.google.common.collect.Lists; import java.io.IOException; import java.util.Iterator; import java.util.List; import net.minecraft.network.play.client.C14PacketTabComplete; import net.minecraft.util.BlockPos; import net.minecraft.util.ChatComponentText; import net.minecraft.util.IChatComponent; import net.minecraft.util.MathHelper; import net.minecraft.util.MovingObjectPosition; import org.apache.commons.lang3.StringUtils; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.lwjgl.input.Keyboard; import org.lwjgl.input.Mouse; public class GuiChat extends GuiScreen { private static final Logger logger = LogManager.getLogger(); private String historyBuffer = ""; /** * keeps position of which chat message you will select when you press up, (does not increase for duplicated * messages sent immediately after each other) */ private int sentHistoryCursor = -1; private boolean playerNamesFound; private boolean waitingOnAutocomplete; private int autocompleteIndex; private List foundPlayerNames = Lists.newArrayList(); /** Chat entry field */ protected GuiTextField inputField; /** * is the text that appears when you press the chat key and the input box appears pre-filled */ private String defaultInputFieldText = ""; private static final String __OBFID = "CL_00000682"; public GuiChat() {} public GuiChat(String p_i1024_1_) { this.defaultInputFieldText = p_i1024_1_; } /** * Adds the buttons (and other controls) to the screen in question. */ public void initGui() { Keyboard.enableRepeatEvents(true); this.sentHistoryCursor = this.mc.ingameGUI.getChatGUI().getSentMessages().size(); this.inputField = new GuiTextField(0, this.fontRendererObj, 4, this.height - 12, this.width - 4, 12); this.inputField.setMaxStringLength(100); this.inputField.setEnableBackgroundDrawing(false); this.inputField.setFocused(true); this.inputField.setText(this.defaultInputFieldText); this.inputField.setCanLoseFocus(false); } /** * Called when the screen is unloaded. Used to disable keyboard repeat events */ public void onGuiClosed() { Keyboard.enableRepeatEvents(false); this.mc.ingameGUI.getChatGUI().resetScroll(); } /** * Called from the main game loop to update the screen. */ public void updateScreen() { this.inputField.updateCursorCounter(); } /** * Fired when a key is typed (except F11 who toggle full screen). This is the equivalent of * KeyListener.keyTyped(KeyEvent e). Args : character (character on the key), keyCode (lwjgl Keyboard key code) */ protected void keyTyped(char typedChar, int keyCode) throws IOException { this.waitingOnAutocomplete = false; if (keyCode == 15) { this.autocompletePlayerNames(); } else { this.playerNamesFound = false; } if (keyCode == 1) { this.mc.displayGuiScreen((GuiScreen)null); } else if (keyCode != 28 && keyCode != 156) { if (keyCode == 200) { this.getSentHistory(-1); } else if (keyCode == 208) { this.getSentHistory(1); } else if (keyCode == 201) { this.mc.ingameGUI.getChatGUI().scroll(this.mc.ingameGUI.getChatGUI().getLineCount() - 1); } else if (keyCode == 209) { this.mc.ingameGUI.getChatGUI().scroll(-this.mc.ingameGUI.getChatGUI().getLineCount() + 1); } else { this.inputField.textboxKeyTyped(typedChar, keyCode); } } else { String var3 = this.inputField.getText().trim(); if (var3.length() > 0) { this.func_175275_f(var3); } this.mc.displayGuiScreen((GuiScreen)null); } } /** * Handles mouse input. */ public void handleMouseInput() throws IOException { super.handleMouseInput(); int var1 = Mouse.getEventDWheel(); if (var1 != 0) { if (var1 > 1) { var1 = 1; } if (var1 < -1) { var1 = -1; } if (!isShiftKeyDown()) { var1 *= 7; } this.mc.ingameGUI.getChatGUI().scroll(var1); } } /** * Called when the mouse is clicked. Args : mouseX, mouseY, clickedButton */ protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOException { if (mouseButton == 0) { IChatComponent var4 = this.mc.ingameGUI.getChatGUI().getChatComponent(Mouse.getX(), Mouse.getY()); if (this.func_175276_a(var4)) { return; } } this.inputField.mouseClicked(mouseX, mouseY, mouseButton); super.mouseClicked(mouseX, mouseY, mouseButton); } protected void func_175274_a(String p_175274_1_, boolean p_175274_2_) { if (p_175274_2_) { this.inputField.setText(p_175274_1_); } else { this.inputField.writeText(p_175274_1_); } } public void autocompletePlayerNames() { String var3; if (this.playerNamesFound) { this.inputField.deleteFromCursor(this.inputField.func_146197_a(-1, this.inputField.getCursorPosition(), false) - this.inputField.getCursorPosition()); if (this.autocompleteIndex >= this.foundPlayerNames.size()) { this.autocompleteIndex = 0; } } else { int var1 = this.inputField.func_146197_a(-1, this.inputField.getCursorPosition(), false); this.foundPlayerNames.clear(); this.autocompleteIndex = 0; String var2 = this.inputField.getText().substring(var1).toLowerCase(); var3 = this.inputField.getText().substring(0, this.inputField.getCursorPosition()); this.sendAutocompleteRequest(var3, var2); if (this.foundPlayerNames.isEmpty()) { return; } this.playerNamesFound = true; this.inputField.deleteFromCursor(var1 - this.inputField.getCursorPosition()); } if (this.foundPlayerNames.size() > 1) { StringBuilder var4 = new StringBuilder(); for (Iterator var5 = this.foundPlayerNames.iterator(); var5.hasNext(); var4.append(var3)) { var3 = (String)var5.next(); if (var4.length() > 0) { var4.append(", "); } } this.mc.ingameGUI.getChatGUI().printChatMessageWithOptionalDeletion(new ChatComponentText(var4.toString()), 1); } this.inputField.writeText((String)this.foundPlayerNames.get(this.autocompleteIndex++)); } private void sendAutocompleteRequest(String p_146405_1_, String p_146405_2_) { if (p_146405_1_.length() >= 1) { BlockPos var3 = null; if (this.mc.objectMouseOver != null && this.mc.objectMouseOver.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK) { var3 = this.mc.objectMouseOver.func_178782_a(); } this.mc.thePlayer.sendQueue.addToSendQueue(new C14PacketTabComplete(p_146405_1_, var3)); this.waitingOnAutocomplete = true; } } /** * input is relative and is applied directly to the sentHistoryCursor so -1 is the previous message, 1 is the next * message from the current cursor position */ public void getSentHistory(int p_146402_1_) { int var2 = this.sentHistoryCursor + p_146402_1_; int var3 = this.mc.ingameGUI.getChatGUI().getSentMessages().size(); var2 = MathHelper.clamp_int(var2, 0, var3); if (var2 != this.sentHistoryCursor) { if (var2 == var3) { this.sentHistoryCursor = var3; this.inputField.setText(this.historyBuffer); } else { if (this.sentHistoryCursor == var3) { this.historyBuffer = this.inputField.getText(); } this.inputField.setText((String)this.mc.ingameGUI.getChatGUI().getSentMessages().get(var2)); this.sentHistoryCursor = var2; } } } /** * Draws the screen and all the components in it. Args : mouseX, mouseY, renderPartialTicks */ public void drawScreen(int mouseX, int mouseY, float partialTicks) { drawRect(2, this.height - 14, this.width - 2, this.height - 2, Integer.MIN_VALUE); this.inputField.drawTextBox(); IChatComponent var4 = this.mc.ingameGUI.getChatGUI().getChatComponent(Mouse.getX(), Mouse.getY()); if (var4 != null && var4.getChatStyle().getChatHoverEvent() != null) { this.func_175272_a(var4, mouseX, mouseY); } super.drawScreen(mouseX, mouseY, partialTicks); } public void onAutocompleteResponse(String[] p_146406_1_) { if (this.waitingOnAutocomplete) { this.playerNamesFound = false; this.foundPlayerNames.clear(); String[] var2 = p_146406_1_; int var3 = p_146406_1_.length; for (int var4 = 0; var4 < var3; ++var4) { String var5 = var2[var4]; if (var5.length() > 0) { this.foundPlayerNames.add(var5); } } String var6 = this.inputField.getText().substring(this.inputField.func_146197_a(-1, this.inputField.getCursorPosition(), false)); String var7 = StringUtils.getCommonPrefix(p_146406_1_); if (var7.length() > 0 && !var6.equalsIgnoreCase(var7)) { this.inputField.deleteFromCursor(this.inputField.func_146197_a(-1, this.inputField.getCursorPosition(), false) - this.inputField.getCursorPosition()); this.inputField.writeText(var7); } else if (this.foundPlayerNames.size() > 0) { this.playerNamesFound = true; this.autocompletePlayerNames(); } } } /** * Returns true if this GUI should pause the game when it is displayed in single-player */ public boolean doesGuiPauseGame() { return false; } }