From 963f66bf4df11ec9de552f50f1d5d65bae9ace0f Mon Sep 17 00:00:00 2001 From: Lorenz Date: Fri, 15 Jul 2022 15:59:56 +0200 Subject: add STRG + A, C, V, X support --- .../java/at/hannibal2/skyhanni/sign/IEditSign.java | 7 + .../at/hannibal2/skyhanni/sign/IModifiedSign.java | 19 ++ .../hannibal2/skyhanni/sign/LorenzSignUtils.java | 64 ++++++ .../hannibal2/skyhanni/sign/SignSelectionList.java | 241 +++++++++++++++++++++ .../skyhanni/sign/SkyBlockEventHandler.java | 7 + .../skyhanni/sign/SkyBlockcatiaConfig.java | 7 + .../at/hannibal2/skyhanni/sign/TextInputUtil.java | 202 +++++++++++++++++ 7 files changed, 547 insertions(+) create mode 100644 src/main/java/at/hannibal2/skyhanni/sign/IEditSign.java create mode 100644 src/main/java/at/hannibal2/skyhanni/sign/IModifiedSign.java create mode 100644 src/main/java/at/hannibal2/skyhanni/sign/LorenzSignUtils.java create mode 100644 src/main/java/at/hannibal2/skyhanni/sign/SignSelectionList.java create mode 100644 src/main/java/at/hannibal2/skyhanni/sign/SkyBlockEventHandler.java create mode 100644 src/main/java/at/hannibal2/skyhanni/sign/SkyBlockcatiaConfig.java create mode 100644 src/main/java/at/hannibal2/skyhanni/sign/TextInputUtil.java (limited to 'src/main/java/at/hannibal2/skyhanni/sign') diff --git a/src/main/java/at/hannibal2/skyhanni/sign/IEditSign.java b/src/main/java/at/hannibal2/skyhanni/sign/IEditSign.java new file mode 100644 index 000000000..278ec7224 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/sign/IEditSign.java @@ -0,0 +1,7 @@ +package at.hannibal2.skyhanni.sign; + +public interface IEditSign { + TextInputUtil getTextInputUtil(); + + SignSelectionList getSignSelectionList(); +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/sign/IModifiedSign.java b/src/main/java/at/hannibal2/skyhanni/sign/IModifiedSign.java new file mode 100644 index 000000000..38375d5ac --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/sign/IModifiedSign.java @@ -0,0 +1,19 @@ +package at.hannibal2.skyhanni.sign; + +import net.minecraft.util.IChatComponent; + +public interface IModifiedSign { + IChatComponent getText(int line); + + void setText(int line, IChatComponent component); + + void setSelectionState(int currentRow, int selectionStart, int selectionEnd, boolean caretVisible); + + void resetSelectionState(); + + boolean getCaretVisible(); + + int getSelectionStart(); + + int getSelectionEnd(); +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/sign/LorenzSignUtils.java b/src/main/java/at/hannibal2/skyhanni/sign/LorenzSignUtils.java new file mode 100644 index 000000000..5b450a734 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/sign/LorenzSignUtils.java @@ -0,0 +1,64 @@ +package at.hannibal2.skyhanni.sign; + +import net.minecraft.client.gui.inventory.GuiEditSign; +import net.minecraft.tileentity.TileEntitySign; + +import java.lang.reflect.Field; + +public class LorenzSignUtils { + + private static boolean once = false; + private static Field field = null; + //(field_146848_f) class net.minecraft.client.gui.inventory.GuiEditSign + + public static TileEntitySign getTileSign(GuiEditSign editSign) { + +// Field field1 = ReflectionHelper.findField(editSign.getClass(), "editSign"); +// ObfuscationReflectionHelper.getPrivateValue(editSign.getClass(), editSign, 0) + + if (field != null) { + try { + return (TileEntitySign) field.get(editSign); + } catch (IllegalAccessException e) { + throw new RuntimeException("hidden", e); + } + } + + if (once) { + throw new RuntimeException("hidden"); + } + once = true; + + try { + Class aClass = editSign.getClass(); +// System.out.println(""); +// System.out.println(""); +// System.out.println(""); + for (Field field : aClass.getDeclaredFields()) { + String name = field.getName(); + Class fieldDeclaringClass = field.getDeclaringClass(); +// System.out.println(""); +// System.out.println("(" + name + ") " + fieldDeclaringClass); + + field.setAccessible(true); + Object o = field.get(editSign); + if (o instanceof TileEntitySign) { +// System.out.println("DONE!!!!!"); + LorenzSignUtils.field = field; + return (TileEntitySign) o; + } + +// System.out.println(""); + } + +// System.out.println(""); +// System.out.println(""); +// System.out.println(""); + Field field = aClass.getDeclaredField("tileSign"); + field.setAccessible(true); + return (TileEntitySign) field.get(editSign); + } catch (NoSuchFieldException | IllegalAccessException e) { + throw new RuntimeException("can not refactor getTileSign! (" + e.getMessage() + ")", e); + } + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/sign/SignSelectionList.java b/src/main/java/at/hannibal2/skyhanni/sign/SignSelectionList.java new file mode 100644 index 000000000..c9c963cee --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/sign/SignSelectionList.java @@ -0,0 +1,241 @@ +package at.hannibal2.skyhanni.sign; + +import net.minecraft.client.Minecraft; +import net.minecraft.client.audio.PositionedSoundRecord; +import net.minecraft.client.gui.GuiListExtended; +import net.minecraft.client.gui.inventory.GuiEditSign; +import net.minecraft.client.network.NetHandlerPlayClient; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.network.play.client.C12PacketUpdateSign; +import net.minecraft.tileentity.TileEntitySign; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.ResourceLocation; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +public class SignSelectionList extends GuiListExtended +{ + public static final List AUCTION_STARTING_BID_PRICES = new ArrayList<>(); + public static final List AUCTION_BID_PRICES = new ArrayList<>(); + public static final List AUCTION_QUERIES = new ArrayList<>(); + public static final List BANK_WITHDRAW = new ArrayList<>(); + public static final List BANK_DEPOSIT = new ArrayList<>(); + public static final List BAZAAR_ORDER = new ArrayList<>(); + public static final List BAZAAR_PRICE = new ArrayList<>(); + private int selectedSlotIndex = -1; + private final List list; + private final String title; + + public SignSelectionList(Minecraft mc, int width, int height, int top, int bottom, List list, String title) + { + super(mc, width, height, top, bottom, 16); + this.list = list; + this.title = title; + + if (this.getSize() > 5) + { + this.list.remove(0); + } + Collections.reverse(this.list); + } + + @Override + protected void elementClicked(int slotIndex, boolean isDoubleClick, int mouseX, int mouseY) + { + this.selectedSlotIndex = slotIndex; + } + + @Override + public IGuiListEntry getListEntry(int index) + { + return this.list.stream().distinct().collect(Collectors.toList()).get(index); + } + + @Override + protected int getSize() + { + return this.list.stream().distinct().collect(Collectors.toList()).size(); + } + + @Override + protected boolean isSelected(int index) + { + return index == this.selectedSlotIndex; + } + + @Override + protected void drawContainerBackground(Tessellator tessellator) {} + + @Override + protected void overlayBackground(int startY, int endY, int startAlpha, int endAlpha) {} + + @Override + public int getListWidth() + { + return 100; + } + + @Override + public int getSlotHeight() + { + return 10; + } + + @Override + public void drawScreen(int mouseX, int mouseY, float partialTicks) + { + if (this.field_178041_q) + { + this.mouseX = mouseX; + this.mouseY = mouseY; + this.drawBackground(); + this.bindAmountScrolled(); + GlStateManager.disableLighting(); + GlStateManager.disableFog(); + Tessellator tessellator = Tessellator.getInstance(); + this.drawContainerBackground(tessellator); + int k = this.left + this.width / 2 - this.getListWidth() / 2 + 2; + int l = this.top + 4 - (int)this.amountScrolled; + + if (this.hasListHeader) + { + this.drawListHeader(k, l, tessellator); + } + + this.drawSelectionBox(k, l, mouseX, mouseY); + this.mc.fontRendererObj.drawString(this.title + ":", k, l - 12, 16777215); + GlStateManager.disableDepth(); + this.overlayBackground(0, this.top, 255, 255); + this.overlayBackground(this.bottom, this.height, 255, 255); + this.func_148142_b(mouseX, mouseY); + } + GlStateManager.enableDepth(); + } + + public void add(String value) + { + this.list.add(new Entry(value)); + } + + public static void clearAll() + { + SignSelectionList.AUCTION_STARTING_BID_PRICES.clear(); + SignSelectionList.AUCTION_BID_PRICES.clear(); + SignSelectionList.AUCTION_QUERIES.clear(); + SignSelectionList.BANK_WITHDRAW.clear(); + SignSelectionList.BANK_DEPOSIT.clear(); + SignSelectionList.BAZAAR_ORDER.clear(); + SignSelectionList.BAZAAR_PRICE.clear(); + } + + public static class Entry implements GuiListExtended.IGuiListEntry + { + private final Minecraft mc; + private final String value; + private long lastClicked; + + public Entry(String value) + { + this.mc = Minecraft.getMinecraft(); + this.value = value; + } + + @Override + public void setSelected(int p_178011_1_, int p_178011_2_, int p_178011_3_) {} + + @Override + public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight, int mouseX, int mouseY, boolean isSelected) + { + this.mc.fontRendererObj.drawString(this.value, x + 2, y + 2, 16777215); + } + + @Override + public boolean mousePressed(int slotIndex, int mouseX, int mouseY, int mouseEvent, int relativeX, int relativeY) + { +// TileEntitySign sign = ((GuiEditSign)this.mc.currentScreen).tileSign; +// TileEntitySign sign = ().tileSign; + TileEntitySign sign = LorenzSignUtils.getTileSign((GuiEditSign)this.mc.currentScreen); + sign.markDirty(); + + if (Minecraft.getSystemTime() - this.lastClicked < 250L) + { +// if (SkyBlockcatiaSettings.INSTANCE.auctionBidConfirm && NumberUtils.isNumeric(this.value)) +// { +// int price = Integer.parseInt(this.value); +// +// if (price >= SkyBlockcatiaSettings.INSTANCE.auctionBidConfirmValue) +// { +// this.mc.displayGuiScreen(new GuiYesNo(this.mc.currentScreen, LangUtils.translate("message.bid_confirm_title"), LangUtils.translate("message.bid_confirm"), 201)); +// } +// else +// { +// SignSelectionList.processSignData(sign); +// this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F)); +// this.mc.displayGuiScreen(null); +// } +// } +// else +// { + SignSelectionList.processSignData(sign); + this.mc.getSoundHandler().playSound(PositionedSoundRecord.create(new ResourceLocation("gui.button.press"), 1.0F)); + this.mc.displayGuiScreen(null); +// } + } + + sign.signText[0] = new ChatComponentText(this.value); + + if (this.mc.currentScreen instanceof IEditSign) + { + ((IEditSign)this.mc.currentScreen).getTextInputUtil().moveCaretToEnd(); + } + this.lastClicked = Minecraft.getSystemTime(); + return false; + } + + @Override + public void mouseReleased(int slotIndex, int x, int y, int mouseEvent, int relativeX, int relativeY) {} + + @Override + public boolean equals(Object obj) + { + if (!(obj instanceof Entry)) + { + return false; + } + if (obj == this) + { + return true; + } + Entry other = (Entry) obj; + return new EqualsBuilder().append(this.value, other.value).isEquals(); + } + + @Override + public int hashCode() + { + return new HashCodeBuilder().append(this.value).toHashCode(); + } + + public String getValue() + { + return this.value; + } + } + + public static void processSignData(TileEntitySign sign) + { + NetHandlerPlayClient nethandlerplayclient = Minecraft.getMinecraft().getNetHandler(); + + if (nethandlerplayclient != null) + { + nethandlerplayclient.addToSendQueue(new C12PacketUpdateSign(sign.getPos(), sign.signText)); + } + sign.setEditable(true); + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/sign/SkyBlockEventHandler.java b/src/main/java/at/hannibal2/skyhanni/sign/SkyBlockEventHandler.java new file mode 100644 index 000000000..6934e5820 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/sign/SkyBlockEventHandler.java @@ -0,0 +1,7 @@ +package at.hannibal2.skyhanni.sign; + +import at.hannibal2.skyhanni.utils.LorenzUtils; + +public class SkyBlockEventHandler { + public static boolean isSkyBlock = LorenzUtils.INSTANCE.getInSkyblock(); +} diff --git a/src/main/java/at/hannibal2/skyhanni/sign/SkyBlockcatiaConfig.java b/src/main/java/at/hannibal2/skyhanni/sign/SkyBlockcatiaConfig.java new file mode 100644 index 000000000..2bd80e8df --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/sign/SkyBlockcatiaConfig.java @@ -0,0 +1,7 @@ +package at.hannibal2.skyhanni.sign; + +public class SkyBlockcatiaConfig { + public static boolean enableOverwriteSignEditing = true; + public static boolean enableSignSelectionList = false; +} + diff --git a/src/main/java/at/hannibal2/skyhanni/sign/TextInputUtil.java b/src/main/java/at/hannibal2/skyhanni/sign/TextInputUtil.java new file mode 100644 index 000000000..a66b31327 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/sign/TextInputUtil.java @@ -0,0 +1,202 @@ +package at.hannibal2.skyhanni.sign; + +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.util.ChatAllowedCharacters; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.MathHelper; +import org.lwjgl.input.Keyboard; + +import java.util.function.Consumer; +import java.util.function.Supplier; + +public class TextInputUtil { + private final FontRenderer fontRenderer; + private final Supplier stringSupplier; + private final Consumer stringConsumer; + private final int maxLength; + private int selectionStart; + private int selectionEnd; + + public TextInputUtil(FontRenderer fontRenderer, Supplier stringSupplier, Consumer stringConsumer, int maxLength) { + this.fontRenderer = fontRenderer; + this.stringSupplier = stringSupplier; + this.stringConsumer = stringConsumer; + this.maxLength = maxLength; + this.moveCaretToEnd(); + } + + public boolean insert(char typedChar) { + if (ChatAllowedCharacters.isAllowedCharacter(typedChar)) { + this.insert(Character.toString(typedChar)); + } + return true; + } + + private void insert(String typedChar) { + if (this.selectionEnd != this.selectionStart) { + this.deleteSelectedText(); + } + + String s = this.stringSupplier.get(); + this.selectionStart = MathHelper.clamp_int(this.selectionStart, 0, s.length()); + String s1 = new StringBuilder(s).insert(this.selectionStart, typedChar).toString(); + + if (this.fontRenderer.getStringWidth(s1) <= this.maxLength) { + this.stringConsumer.accept(s1); + this.selectionEnd = this.selectionStart = Math.min(s1.length(), this.selectionStart + typedChar.length()); + } + } + + public boolean handleSpecialKey(int keyCode) { + String s = this.stringSupplier.get(); + + if (GuiScreen.isKeyComboCtrlA(keyCode)) { + this.selectionEnd = 0; + this.selectionStart = s.length(); + return true; + } else if (GuiScreen.isKeyComboCtrlC(keyCode)) { + GuiScreen.setClipboardString(this.getSelectedText()); + return true; + } else if (GuiScreen.isKeyComboCtrlV(keyCode)) { + this.insert(ChatAllowedCharacters.filterAllowedCharacters(EnumChatFormatting.getTextWithoutFormattingCodes(GuiScreen.getClipboardString().replaceAll("\\r", "")))); + this.selectionEnd = this.selectionStart; + return true; + } else if (GuiScreen.isKeyComboCtrlX(keyCode)) { + GuiScreen.setClipboardString(this.getSelectedText()); + this.deleteSelectedText(); + return true; + } else { + switch (keyCode) { + case Keyboard.KEY_BACK: + if (!s.isEmpty()) { + if (this.selectionEnd != this.selectionStart) { + this.deleteSelectedText(); + } else if (this.selectionStart > 0) { + s = new StringBuilder(s).deleteCharAt(Math.max(0, this.selectionStart - 1)).toString(); + this.selectionEnd = this.selectionStart = Math.max(0, this.selectionStart - 1); + this.stringConsumer.accept(s); + } + } + return true; + case Keyboard.KEY_DELETE: + if (!s.isEmpty()) { + if (this.selectionEnd != this.selectionStart) { + this.deleteSelectedText(); + } else if (this.selectionStart < s.length()) { + s = new StringBuilder(s).deleteCharAt(Math.max(0, this.selectionStart)).toString(); + this.stringConsumer.accept(s); + } + } + return true; + case Keyboard.KEY_LEFT: + int j = this.fontRenderer.getBidiFlag() ? 1 : -1; + if (GuiScreen.isCtrlKeyDown()) { + this.selectionStart = this.findWordEdge(s, j, this.selectionStart); + } else { + this.selectionStart = Math.max(0, Math.min(s.length(), this.selectionStart + j)); + } + if (!GuiScreen.isShiftKeyDown()) { + this.selectionEnd = this.selectionStart; + } + return true; + case Keyboard.KEY_RIGHT: + int i = this.fontRenderer.getBidiFlag() ? -1 : 1; + if (GuiScreen.isCtrlKeyDown()) { + this.selectionStart = this.findWordEdge(s, i, this.selectionStart); + } else { + this.selectionStart = Math.max(0, Math.min(s.length(), this.selectionStart + i)); + } + if (!GuiScreen.isShiftKeyDown()) { + this.selectionEnd = this.selectionStart; + } + return true; + case Keyboard.KEY_HOME: + this.selectionStart = 0; + if (!GuiScreen.isShiftKeyDown()) { + this.selectionEnd = this.selectionStart; + } + return true; + case Keyboard.KEY_END: + this.selectionStart = this.stringSupplier.get().length(); + if (!GuiScreen.isShiftKeyDown()) { + this.selectionEnd = this.selectionStart; + } + return true; + default: + return false; + } + } + } + + private String getSelectedText() { + String s = this.stringSupplier.get(); + int i = Math.min(this.selectionStart, this.selectionEnd); + int j = Math.max(this.selectionStart, this.selectionEnd); + return s.substring(i, j); + } + + private void deleteSelectedText() { + if (this.selectionEnd != this.selectionStart) { + String s = this.stringSupplier.get(); + int i = Math.min(this.selectionStart, this.selectionEnd); + int j = Math.max(this.selectionStart, this.selectionEnd); + String s1 = s.substring(0, i) + s.substring(j); + this.selectionStart = i; + this.selectionEnd = this.selectionStart; + this.stringConsumer.accept(s1); + } + } + + public void moveCaretToEnd() { + this.selectionEnd = this.selectionStart = this.stringSupplier.get().length(); + } + + public int getSelectionStart() { + return this.selectionStart; + } + + public int getSelectionEnd() { + return this.selectionEnd; + } + + private int findWordEdge(String text, int bidiFlag, int selectionStart) { + int i = selectionStart; + boolean flag = bidiFlag < 0; + int j = Math.abs(bidiFlag); + + for (int k = 0; k < j; ++k) { + if (flag) { + while (i > 0 && (text.charAt(i - 1) == ' ' || text.charAt(i - 1) == '\n')) { + --i; + } + while (i > 0 && text.charAt(i - 1) != ' ' && text.charAt(i - 1) != '\n') { + --i; + } + } else { + int l = text.length(); + int i1 = text.indexOf(32, i); + int j1 = text.indexOf(10, i); + + if (i1 == -1 && j1 == -1) { + i = -1; + } else if (i1 != -1 && j1 != -1) { + i = Math.min(i1, j1); + } else if (i1 != -1) { + i = i1; + } else { + i = j1; + } + + if (i == -1) { + i = l; + } else { + while (i < l && (text.charAt(i) == ' ' || text.charAt(i) == '\n')) { + ++i; + } + } + } + } + return i; + } +} \ No newline at end of file -- cgit