From 3802055673e7877d66614791eba6ea0599488c7a Mon Sep 17 00:00:00 2001 From: shedaniel Date: Sat, 6 Jun 2020 16:29:32 +0800 Subject: Improved Search Signed-off-by: shedaniel --- .../me/shedaniel/rei/RoughlyEnoughItemsCore.java | 2 +- src/main/java/me/shedaniel/rei/api/EntryStack.java | 13 +- .../me/shedaniel/rei/api/TextRepresentable.java | 25 ++ src/main/java/me/shedaniel/rei/api/TextTest.java | 13 ++ .../rei/api/fluid/FluidSupportProvider.java | 8 +- .../me/shedaniel/rei/gui/OverlaySearchField.java | 4 +- .../me/shedaniel/rei/gui/RecipeViewingScreen.java | 3 +- .../rei/gui/VillagerRecipeViewingScreen.java | 7 +- .../shedaniel/rei/gui/widget/EntryListWidget.java | 11 +- .../rei/gui/widget/FavoritesListWidget.java | 9 +- .../shedaniel/rei/gui/widget/TextFieldWidget.java | 240 ++++++++++---------- .../me/shedaniel/rei/impl/FluidEntryStack.java | 42 ++-- .../rei/impl/FluidSupportProviderImpl.java | 12 - .../java/me/shedaniel/rei/impl/ItemEntryStack.java | 38 +++- .../java/me/shedaniel/rei/impl/RenderingEntry.java | 2 +- .../java/me/shedaniel/rei/impl/SearchArgument.java | 252 ++++----------------- .../me/shedaniel/rei/impl/SimpleFluidRenderer.java | 62 +++++ .../rei/impl/search/AlwaysMatchingArgument.java | 27 +++ .../me/shedaniel/rei/impl/search/Argument.java | 41 ++++ .../rei/impl/search/ArgumentsRegistry.java | 20 ++ .../me/shedaniel/rei/impl/search/MatchStatus.java | 63 ++++++ .../me/shedaniel/rei/impl/search/MatchType.java | 18 ++ .../me/shedaniel/rei/impl/search/ModArgument.java | 43 ++++ .../shedaniel/rei/impl/search/RegexArgument.java | 56 +++++ .../me/shedaniel/rei/impl/search/TagArgument.java | 51 +++++ .../me/shedaniel/rei/impl/search/TextArgument.java | 33 +++ .../shedaniel/rei/impl/search/TooltipArgument.java | 35 +++ .../me/shedaniel/rei/plugin/DefaultPlugin.java | 9 - 28 files changed, 752 insertions(+), 387 deletions(-) create mode 100644 src/main/java/me/shedaniel/rei/api/TextRepresentable.java create mode 100644 src/main/java/me/shedaniel/rei/api/TextTest.java create mode 100644 src/main/java/me/shedaniel/rei/impl/SimpleFluidRenderer.java create mode 100644 src/main/java/me/shedaniel/rei/impl/search/AlwaysMatchingArgument.java create mode 100644 src/main/java/me/shedaniel/rei/impl/search/Argument.java create mode 100644 src/main/java/me/shedaniel/rei/impl/search/ArgumentsRegistry.java create mode 100644 src/main/java/me/shedaniel/rei/impl/search/MatchStatus.java create mode 100644 src/main/java/me/shedaniel/rei/impl/search/MatchType.java create mode 100644 src/main/java/me/shedaniel/rei/impl/search/ModArgument.java create mode 100644 src/main/java/me/shedaniel/rei/impl/search/RegexArgument.java create mode 100644 src/main/java/me/shedaniel/rei/impl/search/TagArgument.java create mode 100644 src/main/java/me/shedaniel/rei/impl/search/TextArgument.java create mode 100644 src/main/java/me/shedaniel/rei/impl/search/TooltipArgument.java (limited to 'src/main/java') diff --git a/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java b/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java index d8886e991..c9a5a45ba 100644 --- a/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java +++ b/src/main/java/me/shedaniel/rei/RoughlyEnoughItemsCore.java @@ -192,7 +192,7 @@ public class RoughlyEnoughItemsCore implements ClientModInitializer { ClientSidePacketRegistry.INSTANCE.register(RoughlyEnoughItemsNetwork.CREATE_ITEMS_MESSAGE_PACKET, (packetContext, packetByteBuf) -> { ItemStack stack = packetByteBuf.readItemStack(); String player = packetByteBuf.readString(32767); - packetContext.getPlayer().addMessage(new LiteralText(I18n.translate("text.rei.cheat_items").replaceAll("\\{item_name}", SearchArgument.tryGetItemStackName(stack.copy())).replaceAll("\\{item_count}", stack.copy().getCount() + "").replaceAll("\\{player_name}", player)), false); + packetContext.getPlayer().addMessage(new LiteralText(I18n.translate("text.rei.cheat_items").replaceAll("\\{item_name}", EntryStack.create(stack.copy()).asFormattedText().getString()).replaceAll("\\{item_count}", stack.copy().getCount() + "").replaceAll("\\{player_name}", player)), false); }); ClientSidePacketRegistry.INSTANCE.register(RoughlyEnoughItemsNetwork.NOT_ENOUGH_ITEMS_PACKET, (packetContext, packetByteBuf) -> { Screen currentScreen = MinecraftClient.getInstance().currentScreen; diff --git a/src/main/java/me/shedaniel/rei/api/EntryStack.java b/src/main/java/me/shedaniel/rei/api/EntryStack.java index 66c711b3d..9db7dca58 100644 --- a/src/main/java/me/shedaniel/rei/api/EntryStack.java +++ b/src/main/java/me/shedaniel/rei/api/EntryStack.java @@ -32,6 +32,7 @@ import me.shedaniel.rei.api.widgets.Tooltip; import me.shedaniel.rei.impl.EmptyEntryStack; import me.shedaniel.rei.impl.FluidEntryStack; import me.shedaniel.rei.impl.ItemEntryStack; +import me.shedaniel.rei.utils.CollectionUtils; import net.minecraft.client.resource.language.I18n; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.fluid.Fluid; @@ -40,7 +41,9 @@ import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.StringNbtReader; +import net.minecraft.text.LiteralText; import net.minecraft.text.Text; +import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; import net.minecraft.util.math.MathHelper; import net.minecraft.util.registry.Registry; @@ -54,7 +57,7 @@ import java.util.function.Function; import java.util.function.Supplier; @SuppressWarnings("deprecation") -public interface EntryStack { +public interface EntryStack extends TextRepresentable { static EntryStack empty() { return EmptyEntryStack.EMPTY; @@ -137,8 +140,14 @@ public interface EntryStack { return copyFluidToItem(stack); } + @Deprecated + @ApiStatus.ScheduledForRemoval static EntryStack copyFluidToItem(EntryStack stack) { - return FluidSupportProvider.INSTANCE.fluidToItem(stack); + Item bucketItem = stack.getFluid().getBucketItem(); + if (bucketItem != null) { + return EntryStack.create(bucketItem); + } + return EntryStack.empty(); } @Deprecated diff --git a/src/main/java/me/shedaniel/rei/api/TextRepresentable.java b/src/main/java/me/shedaniel/rei/api/TextRepresentable.java new file mode 100644 index 000000000..fd058b0cc --- /dev/null +++ b/src/main/java/me/shedaniel/rei/api/TextRepresentable.java @@ -0,0 +1,25 @@ +package me.shedaniel.rei.api; + +import me.shedaniel.math.impl.PointHelper; +import me.shedaniel.rei.api.widgets.Tooltip; +import net.minecraft.text.LiteralText; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import org.jetbrains.annotations.NotNull; + +public interface TextRepresentable { + @NotNull + default Text asFormattedText() { + if (this instanceof EntryStack) { + Tooltip tooltip = ((EntryStack) this).getTooltip(PointHelper.ofMouse()); + if (tooltip != null && !tooltip.getText().isEmpty()) + return tooltip.getText().get(0); + } + return new LiteralText(""); + } + + @NotNull + default Text asFormatStrippedText() { + return new LiteralText(Formatting.strip(asFormattedText().getString())); + } +} diff --git a/src/main/java/me/shedaniel/rei/api/TextTest.java b/src/main/java/me/shedaniel/rei/api/TextTest.java new file mode 100644 index 000000000..0749aae62 --- /dev/null +++ b/src/main/java/me/shedaniel/rei/api/TextTest.java @@ -0,0 +1,13 @@ +package me.shedaniel.rei.api; + +import net.minecraft.text.LiteralText; +import net.minecraft.text.MutableText; +import net.minecraft.util.Formatting; + +public class TextTest { + public static void main(String[] args) { + MutableText text = new LiteralText("adaw").append("dawdwdaw").formatted(Formatting.RED); + System.out.println(text.getString()); + System.out.println(text.getString()); + } +} diff --git a/src/main/java/me/shedaniel/rei/api/fluid/FluidSupportProvider.java b/src/main/java/me/shedaniel/rei/api/fluid/FluidSupportProvider.java index 0356e887d..97d75d0d3 100644 --- a/src/main/java/me/shedaniel/rei/api/fluid/FluidSupportProvider.java +++ b/src/main/java/me/shedaniel/rei/api/fluid/FluidSupportProvider.java @@ -37,13 +37,19 @@ public interface FluidSupportProvider { void registerFluidProvider(@NotNull FluidProvider provider); + @Deprecated + @ApiStatus.ScheduledForRemoval @NotNull - EntryStack fluidToItem(@NotNull EntryStack fluidStack); + default EntryStack fluidToItem(@NotNull EntryStack fluidStack) { + return EntryStack.empty(); + } @NotNull EntryStack itemToFluid(@NotNull EntryStack itemStack); interface FluidProvider { + @Deprecated + @ApiStatus.ScheduledForRemoval @NotNull default EntryStack fluidToItem(@NotNull EntryStack fluidStack) { return EntryStack.empty(); diff --git a/src/main/java/me/shedaniel/rei/gui/OverlaySearchField.java b/src/main/java/me/shedaniel/rei/gui/OverlaySearchField.java index 2f186c138..ef8d2a6ec 100644 --- a/src/main/java/me/shedaniel/rei/gui/OverlaySearchField.java +++ b/src/main/java/me/shedaniel/rei/gui/OverlaySearchField.java @@ -135,7 +135,7 @@ public class OverlaySearchField extends TextFieldWidget { addToHistory(getText()); setFocused(false); return true; - } else if (int_1 == 265) { + } else if (int_1 == 264) { int i = history.indexOf(getText()) - 1; if (i < -1 && getText().isEmpty()) i = history.size() - 1; @@ -147,7 +147,7 @@ public class OverlaySearchField extends TextFieldWidget { setText(history.get(i)); return true; } - } else if (int_1 == 264) { + } else if (int_1 == 265) { int i = history.indexOf(getText()) + 1; if (i > 0) { setText(i < history.size() ? history.get(i) : ""); diff --git a/src/main/java/me/shedaniel/rei/gui/RecipeViewingScreen.java b/src/main/java/me/shedaniel/rei/gui/RecipeViewingScreen.java index ed797d601..52efc96c3 100644 --- a/src/main/java/me/shedaniel/rei/gui/RecipeViewingScreen.java +++ b/src/main/java/me/shedaniel/rei/gui/RecipeViewingScreen.java @@ -342,10 +342,9 @@ public class RecipeViewingScreen extends Screen implements RecipeScreen { preWidgets.add(workingStationsBaseWidget = Widgets.createCategoryBase(new Rectangle(xx - 5, yy - 5, 15 + innerWidth * 16, 10 + actualHeight * 16))); preWidgets.add(Widgets.createSlotBase(new Rectangle(xx - 1, yy - 1, innerWidth * 16 + 2, actualHeight * 16 + 2))); int index = 0; - List list = Collections.singletonList(new TranslatableText("text.rei.working_station").formatted(Formatting.YELLOW)); xx += (innerWidth - 1) * 16; for (List workingStation : workingStations) { - preWidgets.add(new WorkstationSlotWidget(xx, yy, CollectionUtils.map(workingStation, stack -> stack.copy().setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, s -> list)))); + preWidgets.add(new WorkstationSlotWidget(xx, yy, workingStation)); index++; yy += 16; if (index >= hh) { diff --git a/src/main/java/me/shedaniel/rei/gui/VillagerRecipeViewingScreen.java b/src/main/java/me/shedaniel/rei/gui/VillagerRecipeViewingScreen.java index 79068c07b..39bb93746 100644 --- a/src/main/java/me/shedaniel/rei/gui/VillagerRecipeViewingScreen.java +++ b/src/main/java/me/shedaniel/rei/gui/VillagerRecipeViewingScreen.java @@ -41,7 +41,6 @@ import me.shedaniel.rei.gui.widget.Widget; import me.shedaniel.rei.impl.ClientHelperImpl; import me.shedaniel.rei.impl.InternalWidgets; import me.shedaniel.rei.impl.ScreenHelper; -import me.shedaniel.rei.utils.CollectionUtils; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.Element; import net.minecraft.client.gui.screen.Screen; @@ -51,15 +50,12 @@ import net.minecraft.client.util.NarratorManager; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.sound.SoundEvents; import net.minecraft.text.LiteralText; -import net.minecraft.text.Text; import net.minecraft.text.TranslatableText; -import net.minecraft.util.Formatting; import net.minecraft.util.Identifier; import net.minecraft.util.math.MathHelper; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; -import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; @@ -171,9 +167,8 @@ public class VillagerRecipeViewingScreen extends Screen implements RecipeScreen widgets.add(Widgets.createCategoryBase(new Rectangle(xx - 5, bounds.y + bounds.height - 5, 10 + w * 16, 12 + h * 16))); widgets.add(Widgets.createSlotBase(new Rectangle(xx - 1, yy - 1, 2 + w * 16, 2 + h * 16))); int index = 0; - List list = Collections.singletonList(new TranslatableText("text.rei.working_station").formatted(Formatting.YELLOW)); for (List workingStation : workingStations) { - widgets.add(new RecipeViewingScreen.WorkstationSlotWidget(xx, yy, CollectionUtils.map(workingStation, stack -> stack.copy().setting(EntryStack.Settings.TOOLTIP_APPEND_EXTRA, s -> list)))); + widgets.add(new RecipeViewingScreen.WorkstationSlotWidget(xx, yy, workingStation)); index++; xx += 16; if (index >= ww) { diff --git a/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java b/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java index be76074e1..4aee01ce9 100644 --- a/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java +++ b/src/main/java/me/shedaniel/rei/gui/widget/EntryListWidget.java @@ -46,6 +46,7 @@ import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.render.Tessellator; import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.item.Item; import net.minecraft.item.ItemGroup; import net.minecraft.text.LiteralText; import net.minecraft.text.Text; @@ -69,7 +70,7 @@ import java.util.stream.Collectors; public class EntryListWidget extends WidgetWithBounds { static final Supplier RENDER_ENCHANTMENT_GLINT = ConfigObject.getInstance()::doesRenderEntryEnchantmentGlint; - static final Comparator ENTRY_NAME_COMPARER = Comparator.comparing(SearchArgument::tryGetEntryStackName); + static final Comparator ENTRY_NAME_COMPARER = Comparator.comparing(stack -> stack.asFormatStrippedText().getString()); static final Comparator ENTRY_GROUP_COMPARER = Comparator.comparingInt(stack -> { if (stack.getType() == EntryStack.Type.ITEM) { ItemGroup group = stack.getItem().getGroup(); @@ -729,8 +730,12 @@ public class EntryListWidget extends WidgetWithBounds { if (containsMouse(mouseX, mouseY) && ClientHelper.getInstance().isCheating()) { EntryStack entry = getCurrentEntry().copy(); if (!entry.isEmpty()) { - if (entry.getType() == EntryStack.Type.FLUID) - entry = EntryStack.copyFluidToItem(entry); + if (entry.getType() == EntryStack.Type.FLUID) { + Item bucketItem = entry.getFluid().getBucketItem(); + if (bucketItem != null) { + entry = EntryStack.create(bucketItem); + } + } if (entry.getType() == EntryStack.Type.ITEM) entry.setAmount(button != 1 && !Screen.hasShiftDown() ? 1 : entry.getItemStack().getMaxCount()); ClientHelper.getInstance().tryCheatingEntry(entry); diff --git a/src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java b/src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java index bd7243cb6..b828a9eae 100644 --- a/src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java +++ b/src/main/java/me/shedaniel/rei/gui/widget/FavoritesListWidget.java @@ -41,6 +41,7 @@ import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.network.ClientPlayerEntity; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.item.Item; import net.minecraft.text.TranslatableText; import net.minecraft.util.math.MathHelper; import org.jetbrains.annotations.ApiStatus; @@ -297,8 +298,12 @@ public class FavoritesListWidget extends WidgetWithBounds { if (containsMouse(mouseX, mouseY) && ClientHelper.getInstance().isCheating()) { EntryStack entry = getCurrentEntry().copy(); if (!entry.isEmpty()) { - if (entry.getType() == EntryStack.Type.FLUID) - entry = EntryStack.copyFluidToItem(entry); + if (entry.getType() == EntryStack.Type.FLUID) { + Item bucketItem = entry.getFluid().getBucketItem(); + if (bucketItem != null) { + entry = EntryStack.create(bucketItem); + } + } if (entry.getType() == EntryStack.Type.ITEM) entry.setAmount(button != 1 && !Screen.hasShiftDown() ? 1 : entry.getItemStack().getMaxCount()); ClientHelper.getInstance().tryCheatingEntry(entry); diff --git a/src/main/java/me/shedaniel/rei/gui/widget/TextFieldWidget.java b/src/main/java/me/shedaniel/rei/gui/widget/TextFieldWidget.java index 88896da40..868fa9ee7 100644 --- a/src/main/java/me/shedaniel/rei/gui/widget/TextFieldWidget.java +++ b/src/main/java/me/shedaniel/rei/gui/widget/TextFieldWidget.java @@ -34,6 +34,7 @@ import net.minecraft.client.render.Tessellator; import net.minecraft.client.render.VertexFormats; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.util.Tickable; +import net.minecraft.util.Util; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Matrix4f; import org.jetbrains.annotations.ApiStatus; @@ -55,9 +56,9 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { public Function stripInvalid; protected int focusedTicks; protected boolean editable; - protected int field_2103; - protected int cursorMax; - protected int cursorMin; + protected int firstCharacterIndex; + protected int selectionStart; + protected int selectionEnd; protected int editableColor; protected int notEditableColor; protected BiFunction renderTextProvider; @@ -65,9 +66,10 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { private String text; private int maxLength; private boolean hasBorder; - private boolean field_2096; + private boolean focusUnlocked; private boolean focused; private boolean visible; + private boolean selecting; private String suggestion; private Consumer changedListener; private Predicate textPredicate; @@ -76,7 +78,7 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { this.text = ""; this.maxLength = 32; this.hasBorder = true; - this.field_2096 = true; + this.focusUnlocked = true; this.editable = true; this.editableColor = 14737632; this.notEditableColor = 7368816; @@ -111,7 +113,7 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { this.changedListener = biConsumer_1; } - public void method_1854(BiFunction biFunction_1) { + public void setRenderTextProvider(BiFunction biFunction_1) { this.renderTextProvider = biFunction_1; } @@ -133,25 +135,25 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { } this.onChanged(string_1); - this.moveCursorToEnd(); + this.setCursorToEnd(); } } public String getSelectedText() { - int int_1 = Math.min(this.cursorMax, this.cursorMin); - int int_2 = Math.max(this.cursorMax, this.cursorMin); - return this.text.substring(int_1, int_2); + int i = Math.min(this.selectionStart, this.selectionEnd); + int j = Math.max(this.selectionStart, this.selectionEnd); + return this.text.substring(i, j); } - public void method_1890(Predicate predicate_1) { + public void setTextPredicate(Predicate predicate_1) { this.textPredicate = predicate_1; } public void addText(String string_1) { String string_2 = ""; String string_3 = stripInvalid.apply(string_1); - int int_1 = Math.min(this.cursorMax, this.cursorMin); - int int_2 = Math.max(this.cursorMax, this.cursorMin); + int int_1 = Math.min(this.selectionStart, this.selectionEnd); + int int_2 = Math.max(this.selectionStart, this.selectionEnd); int int_3 = this.maxLength - this.text.length() - (int_1 - int_2); if (!this.text.isEmpty()) { string_2 = string_2 + this.text.substring(0, int_1); @@ -172,8 +174,8 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { if (this.textPredicate.test(string_2)) { this.text = string_2; - this.setCursor(int_1 + int_5); - this.method_1884(this.cursorMax); + this.setSelectionStart(int_1 + int_5); + this.setSelectionEnd(this.selectionStart); this.onChanged(this.text); } } @@ -185,119 +187,111 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { } - private void method_16873(int int_1) { + private void erase(int int_1) { if (Screen.hasControlDown()) { - this.method_1877(int_1); + this.eraseWords(int_1); } else { - this.method_1878(int_1); + this.eraseCharacters(int_1); } - } - public void method_1877(int int_1) { + public void eraseWords(int wordOffset) { if (!this.text.isEmpty()) { - if (this.cursorMin != this.cursorMax) { + if (this.selectionEnd != this.selectionStart) { this.addText(""); } else { - this.method_1878(this.method_1853(int_1) - this.cursorMax); + this.eraseCharacters(this.getWordSkipPosition(wordOffset) - this.selectionStart); } } } - public void method_1878(int int_1) { + public void eraseCharacters(int characterOffset) { if (!this.text.isEmpty()) { - if (this.cursorMin != this.cursorMax) { + if (this.selectionEnd != this.selectionStart) { this.addText(""); } else { - boolean boolean_1 = int_1 < 0; - int int_2 = boolean_1 ? this.cursorMax + int_1 : this.cursorMax; - int int_3 = boolean_1 ? this.cursorMax : this.cursorMax + int_1; - String string_1 = ""; - if (int_2 >= 0) { - string_1 = this.text.substring(0, int_2); - } - - if (int_3 < this.text.length()) { - string_1 = string_1 + this.text.substring(int_3); - } - - if (this.textPredicate.test(string_1)) { - this.text = string_1; - if (boolean_1) { - this.moveCursor(int_1, true); + int i = this.getMovedCursorIndex(characterOffset); + int j = Math.min(i, this.selectionStart); + int k = Math.max(i, this.selectionStart); + if (j != k) { + String string = (new StringBuilder(this.text)).delete(j, k).toString(); + if (this.textPredicate.test(string)) { + this.text = string; + this.setCursor(j); } - - this.onChanged(this.text); } + this.onChanged(this.text); } } } - public int method_1853(int int_1) { - return this.method_1869(int_1, this.getCursor()); + public int getWordSkipPosition(int int_1) { + return this.getWordSkipPosition(int_1, this.getCursor()); } - public int method_1869(int int_1, int int_2) { - return this.method_1864(int_1, int_2, true); + public int getWordSkipPosition(int int_1, int int_2) { + return this.getWordSkipPosition(int_1, int_2, true); } - public int method_1864(int int_1, int int_2, boolean boolean_1) { - int int_3 = int_2; - boolean boolean_2 = int_1 < 0; - int int_4 = Math.abs(int_1); + public int getWordSkipPosition(int wordOffset, int cursorPosition, boolean skipOverSpaces) { + int i = cursorPosition; + boolean bl = wordOffset < 0; + int j = Math.abs(wordOffset); - for (int int_5 = 0; int_5 < int_4; ++int_5) { - if (!boolean_2) { - int int_6 = this.text.length(); - int_3 = this.text.indexOf(32, int_3); - if (int_3 == -1) { - int_3 = int_6; + for (int k = 0; k < j; ++k) { + if (!bl) { + int l = this.text.length(); + i = this.text.indexOf(32, i); + if (i == -1) { + i = l; } else { - while (boolean_1 && int_3 < int_6 && this.text.charAt(int_3) == ' ') { - ++int_3; + while (skipOverSpaces && i < l && this.text.charAt(i) == ' ') { + ++i; } } } else { - while (boolean_1 && int_3 > 0 && this.text.charAt(int_3 - 1) == ' ') { - --int_3; + while (skipOverSpaces && i > 0 && this.text.charAt(i - 1) == ' ') { + --i; } - while (int_3 > 0 && this.text.charAt(int_3 - 1) != ' ') { - --int_3; + while (i > 0 && this.text.charAt(i - 1) != ' ') { + --i; } } } - return int_3; + return i; } - public void moveCursor(int int_1, boolean resetSelect) { - this.moveCursorTo(this.cursorMax + int_1, resetSelect); + public void moveCursor(int int_1) { + this.setCursor(this.selectionStart + int_1); } - public void moveCursorTo(int int_1, boolean resetSelect) { - this.setCursor(int_1); - // if (!this.field_17037) { - if (resetSelect) { - this.method_1884(this.cursorMax); + private int getMovedCursorIndex(int i) { + return Util.moveCursor(this.text, this.selectionStart, i); + } + + public void setCursor(int int_1) { + this.setSelectionStart(int_1); + if (!selecting) { + this.setSelectionEnd(this.selectionStart); } - - this.onChanged(this.text); } - public void moveCursorToHead() { - this.moveCursorTo(0, true); + public void setCursorToStart() { + this.setCursor(0); } - public void moveCursorToEnd() { - this.moveCursorTo(this.text.length(), true); + public void setCursorToEnd() { + this.setCursor(this.text.length()); } public boolean keyPressed(int int_1, int int_2, int int_3) { if (this.isVisible() && this.isFocused()) { + this.selecting = Screen.hasShiftDown(); if (Screen.isSelectAll(int_1)) { - this.moveCursorToEnd(); - this.method_1884(0); + this.setCursorToEnd(); + this.setSelectionEnd(0); return true; } else if (Screen.isCopy(int_1)) { minecraft.keyboard.setClipboard(this.getSelectedText()); @@ -319,7 +313,9 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { switch (int_1) { case 259: if (this.editable) { - this.method_16873(-1); + this.selecting = false; + this.erase(-1); + this.selecting = Screen.hasShiftDown(); } return true; @@ -332,31 +328,33 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { return int_1 != 256; case 261: if (this.editable) { - this.method_16873(1); + this.selecting = false; + this.erase(1); + this.selecting = Screen.hasShiftDown(); } return true; case 262: if (Screen.hasControlDown()) { - this.moveCursorTo(this.method_1853(1), !Screen.hasShiftDown()); + this.setCursor(this.getWordSkipPosition(1)); } else { - this.moveCursor(1, !Screen.hasShiftDown()); + this.moveCursor(1); } return true; case 263: if (Screen.hasControlDown()) { - this.moveCursorTo(this.method_1853(-1), !Screen.hasShiftDown()); + this.setCursor(this.getWordSkipPosition(-1)); } else { - this.moveCursor(-1, !Screen.hasShiftDown()); + this.moveCursor(-1); } return true; case 268: - this.moveCursorToHead(); + this.setCursorToStart(); return true; case 269: - this.moveCursorToEnd(); + this.setCursorToEnd(); return true; } } @@ -368,7 +366,11 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { @Override public boolean charTyped(char char_1, int int_1) { if (this.isVisible() && this.isFocused()) { - if (SharedConstants.isValidChar(char_1)) { + if (SharedConstants.isValidChar(char_1) && !( + Screen.hasControlDown() && !Screen.hasShiftDown() && !Screen.hasAltDown() && ( + char_1 == 'a' || char_1 == 'c' || char_1 == 'v' + ) + )) { if (this.editable) { this.addText(Character.toString(char_1)); } @@ -393,7 +395,7 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { return false; } else { boolean boolean_1 = double_1 >= (double) this.bounds.x && double_1 < (double) (this.bounds.x + this.bounds.width) && double_2 >= (double) this.bounds.y && double_2 < (double) (this.bounds.y + this.bounds.height); - if (this.field_2096) { + if (this.focusUnlocked) { this.setFocused(boolean_1); } @@ -403,8 +405,8 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { int_2 -= 4; } - String string_1 = this.font.trimToWidth(this.text.substring(this.field_2103), this.getWidth()); - this.moveCursorTo(this.font.trimToWidth(string_1, int_2).length() + this.field_2103, true); + String string_1 = this.font.trimToWidth(this.text.substring(this.firstCharacterIndex), this.getWidth()); + this.setCursor(this.font.trimToWidth(string_1, int_2).length() + this.firstCharacterIndex); return true; } else { return false; @@ -428,9 +430,9 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { renderBorder(matrices); int color = this.editable ? this.editableColor : this.notEditableColor; - int int_4 = this.cursorMax - this.field_2103; - int int_5 = this.cursorMin - this.field_2103; - String string_1 = this.font.trimToWidth(this.text.substring(this.field_2103), this.getWidth()); + int int_4 = this.selectionStart - this.firstCharacterIndex; + int int_5 = this.selectionEnd - this.firstCharacterIndex; + String string_1 = this.font.trimToWidth(this.text.substring(this.firstCharacterIndex), this.getWidth()); boolean boolean_1 = int_4 >= 0 && int_4 <= string_1.length(); boolean boolean_2 = this.focused && this.focusedTicks / 6 % 2 == 0 && boolean_1; int x = this.hasBorder ? this.bounds.x + 4 : this.bounds.x; @@ -442,10 +444,10 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { if (!string_1.isEmpty()) { String string_2 = boolean_1 ? string_1.substring(0, int_4) : string_1; - int_8 = this.font.drawWithShadow(matrices, this.renderTextProvider.apply(string_2, this.field_2103), (float) x, (float) y, color); + int_8 = this.font.drawWithShadow(matrices, this.renderTextProvider.apply(string_2, this.firstCharacterIndex), (float) x, (float) y, color); } - boolean isCursorInsideText = this.cursorMax < this.text.length() || this.text.length() >= this.getMaxLength(); + boolean isCursorInsideText = this.selectionStart < this.text.length() || this.text.length() >= this.getMaxLength(); int int_9 = int_8; if (!boolean_1) { int_9 = int_4 > 0 ? x + this.bounds.width : x; @@ -455,7 +457,7 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { int_9--; if (!string_1.isEmpty() && boolean_1 && int_4 < string_1.length()) { - this.font.drawWithShadow(matrices, this.renderTextProvider.apply(string_1.substring(int_4), this.cursorMax), (float) int_8, (float) y, color); + this.font.drawWithShadow(matrices, this.renderTextProvider.apply(string_1.substring(int_4), this.selectionStart), (float) int_8, (float) y, color); } if (!isCursorInsideText && text.isEmpty() && this.suggestion != null) { @@ -537,11 +539,11 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { } public int getCursor() { - return this.cursorMax; + return this.selectionStart; } - public void setCursor(int int_1) { - this.cursorMax = MathHelper.clamp(int_1, 0, this.text.length()); + public void setSelectionStart(int int_1) { + this.selectionStart = MathHelper.clamp(int_1, 0, this.text.length()); } public boolean hasBorder() { @@ -587,46 +589,46 @@ public class TextFieldWidget extends WidgetWithBounds implements Tickable { return this.hasBorder() ? this.bounds.width - 8 : this.bounds.width; } - public void method_1884(int int_1) { - int int_2 = this.text.length(); - this.cursorMin = MathHelper.clamp(int_1, 0, int_2); + public void setSelectionEnd(int i) { + int j = this.text.length(); + this.selectionEnd = MathHelper.clamp(i, 0, j); if (this.font != null) { - if (this.field_2103 > int_2) { - this.field_2103 = int_2; + if (this.firstCharacterIndex > j) { + this.firstCharacterIndex = j; } int int_3 = this.getWidth(); - String string_1 = this.font.trimToWidth(this.text.substring(this.field_2103), int_3); - int int_4 = string_1.length() + this.field_2103; - if (this.cursorMin == this.field_2103) { - this.field_2103 -= this.font.trimToWidth(this.text, int_3, true).length(); + String string_1 = this.font.trimToWidth(this.text.substring(this.firstCharacterIndex), int_3); + int int_4 = string_1.length() + this.firstCharacterIndex; + if (this.selectionEnd == this.firstCharacterIndex) { + this.firstCharacterIndex -= this.font.trimToWidth(this.text, int_3, true).length(); } - if (this.cursorMin > int_4) { - this.field_2103 += this.cursorMin - int_4; - } else if (this.cursorMin <= this.field_2103) { - this.field_2103 -= this.field_2103 - this.cursorMin; + if (this.selectionEnd > int_4) { + this.firstCharacterIndex += this.selectionEnd - int_4; + } else if (this.selectionEnd <= this.firstCharacterIndex) { + this.firstCharacterIndex -= this.firstCharacterIndex - this.selectionEnd; } - this.field_2103 = MathHelper.clamp(this.field_2103, 0, int_2); + this.firstCharacterIndex = MathHelper.clamp(this.firstCharacterIndex, 0, j); } } - public void method_1856(boolean boolean_1) { - this.field_2096 = boolean_1; + public void setFocusUnlocked(boolean boolean_1) { + this.focusUnlocked = boolean_1; } public boolean isVisible() { return this.visible; } - public void setVisible(boolean boolean_1) { - this.visible = boolean_1; + public void setVisible(boolean visible) { + this.visible = visible; } - public int method_1889(int int_1) { - return int_1 > this.text.length() ? this.bounds.x : this.bounds.x + this.font.getStringWidth(this.text.substring(0, int_1)); + public int getCharacterX(int index) { + return index > this.text.length() ? this.bounds.x : this.bounds.x + this.font.getStringWidth(this.text.substring(0, index)); } } diff --git a/src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java b/src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java index f417e0d5f..b038fe07b 100644 --- a/src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java +++ b/src/main/java/me/shedaniel/rei/impl/FluidEntryStack.java @@ -30,12 +30,14 @@ import me.shedaniel.rei.api.ClientHelper; import me.shedaniel.rei.api.ConfigObject; import me.shedaniel.rei.api.EntryStack; import me.shedaniel.rei.api.widgets.Tooltip; +import me.shedaniel.rei.utils.CollectionUtils; import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandler; import net.fabricmc.fabric.api.client.render.fluid.v1.FluidRenderHandlerRegistry; import net.minecraft.client.MinecraftClient; import net.minecraft.client.render.BufferBuilder; import net.minecraft.client.render.Tessellator; import net.minecraft.client.render.VertexFormats; +import net.minecraft.client.resource.language.I18n; import net.minecraft.client.texture.Sprite; import net.minecraft.client.texture.SpriteAtlasTexture; import net.minecraft.client.util.math.MatrixStack; @@ -43,12 +45,15 @@ import net.minecraft.fluid.Fluid; import net.minecraft.fluid.Fluids; import net.minecraft.text.LiteralText; import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; import net.minecraft.util.Identifier; import net.minecraft.util.Pair; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Matrix4f; import net.minecraft.util.registry.Registry; +import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.HashMap; @@ -60,7 +65,6 @@ import java.util.stream.Stream; @ApiStatus.Internal public class FluidEntryStack extends AbstractEntryStack { - private static final Map> FLUID_SPRITE_CACHE = new HashMap<>(); private static final double IGNORE_AMOUNT = -1319182373; private Fluid fluid; private double amount; @@ -78,23 +82,6 @@ public class FluidEntryStack extends AbstractEntryStack { this.amount = amount; } - protected static Pair getOrLoadSprite(Fluid fluid) { - Pair possibleCached = FLUID_SPRITE_CACHE.get(fluid); - if (possibleCached != null) - return possibleCached; - - FluidRenderHandler fluidRenderHandler = FluidRenderHandlerRegistry.INSTANCE.get(fluid); - if (fluidRenderHandler == null) - return null; - Sprite[] sprites = fluidRenderHandler.getFluidSprites(MinecraftClient.getInstance().world, MinecraftClient.getInstance().world == null ? null : BlockPos.ORIGIN, fluid.getDefaultState()); - int color = -1; - if (MinecraftClient.getInstance().world != null) - color = fluidRenderHandler.getFluidColor(MinecraftClient.getInstance().world, BlockPos.ORIGIN, fluid.getDefaultState()); - Pair pair = new Pair<>(sprites[0], color); - FLUID_SPRITE_CACHE.put(fluid, pair); - return pair; - } - @Override public Optional getIdentifier() { return Optional.ofNullable(Registry.FLUID.getId(getFluid())); @@ -201,7 +188,7 @@ public class FluidEntryStack extends AbstractEntryStack { public Tooltip getTooltip(Point point) { if (!get(Settings.TOOLTIP_ENABLED).get() || isEmpty()) return null; - List toolTip = Lists.newArrayList(new LiteralText(SearchArgument.tryGetEntryStackName(this))); + List toolTip = Lists.newArrayList(asFormattedText()); if (amount >= 0) { String amountTooltip = get(Settings.Fluid.AMOUNT_TOOLTIP).apply(this); if (amountTooltip != null) @@ -228,10 +215,10 @@ public class FluidEntryStack extends AbstractEntryStack { @Override public void render(MatrixStack matrices, Rectangle bounds, int mouseX, int mouseY, float delta) { if (get(Settings.RENDER).get()) { - Pair pair = getOrLoadSprite(getFluid()); - if (pair != null) { - Sprite sprite = pair.getLeft(); - int color = pair.getRight(); + SimpleFluidRenderer.FluidRenderingData renderingData = SimpleFluidRenderer.fromFluid(fluid); + if (renderingData != null) { + Sprite sprite = renderingData.getSprite(); + int color = renderingData.getColor(); int a = 255; int r = (color >> 16 & 255); int g = (color >> 8 & 255); @@ -249,4 +236,13 @@ public class FluidEntryStack extends AbstractEntryStack { } } } + + @NotNull + @Override + public Text asFormattedText() { + Identifier id = Registry.FLUID.getId(fluid); + if (I18n.hasTranslation("block." + id.toString().replaceFirst(":", "."))) + return new TranslatableText("block." + id.toString().replaceFirst(":", ".")); + return new LiteralText(CollectionUtils.mapAndJoinToString(id.getPath().split("_"), StringUtils::capitalize, " ")); + } } diff --git a/src/main/java/me/shedaniel/rei/impl/FluidSupportProviderImpl.java b/src/main/java/me/shedaniel/rei/impl/FluidSupportProviderImpl.java index 19e5d36db..d14ac271b 100644 --- a/src/main/java/me/shedaniel/rei/impl/FluidSupportProviderImpl.java +++ b/src/main/java/me/shedaniel/rei/impl/FluidSupportProviderImpl.java @@ -46,18 +46,6 @@ public class FluidSupportProviderImpl implements FluidSupportProvider { providers.add(Objects.requireNonNull(provider, "Registered provider is null!")); } - @Override - public @NotNull EntryStack fluidToItem(@NotNull EntryStack fluidStack) { - if (fluidStack.isEmpty()) return EntryStack.empty(); - if (fluidStack.getType() != EntryStack.Type.FLUID) - throw new IllegalArgumentException("EntryStack must be fluid!"); - for (FluidProvider provider : providers) { - EntryStack stack = Objects.requireNonNull(provider.fluidToItem(fluidStack), provider.getClass() + " is creating null objects for fluidToItem!"); - if (!stack.isEmpty()) return stack; - } - return EntryStack.empty(); - } - @Override public @NotNull EntryStack itemToFluid(@NotNull EntryStack itemStack) { if (itemStack.isEmpty()) return EntryStack.empty(); diff --git a/src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java b/src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java index 9c723581b..bffcde62c 100644 --- a/src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java +++ b/src/main/java/me/shedaniel/rei/impl/ItemEntryStack.java @@ -30,6 +30,7 @@ import me.shedaniel.math.Rectangle; import me.shedaniel.rei.api.*; import me.shedaniel.rei.api.widgets.Tooltip; import net.minecraft.client.MinecraftClient; +import net.minecraft.client.item.TooltipContext; import net.minecraft.client.render.DiffuseLighting; import net.minecraft.client.render.OverlayTexture; import net.minecraft.client.render.VertexConsumerProvider; @@ -37,16 +38,21 @@ import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.render.model.json.ModelTransformation; import net.minecraft.client.texture.SpriteAtlasTexture; import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.Tag; +import net.minecraft.text.LiteralText; import net.minecraft.text.Text; +import net.minecraft.text.TranslatableText; import net.minecraft.util.Identifier; import net.minecraft.util.math.MathHelper; import net.minecraft.util.registry.Registry; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Optional; @@ -257,7 +263,7 @@ public class ItemEntryStack extends AbstractEntryStack implements OptimalEntrySt public Tooltip getTooltip(Point point) { if (isEmpty() || !get(Settings.TOOLTIP_ENABLED).get()) return null; - List toolTip = Lists.newArrayList(SearchArgument.tryGetItemStackToolTip(getItemStack(), true)); + List toolTip = Lists.newArrayList(tryGetItemStackToolTip(true)); toolTip.addAll(get(Settings.TOOLTIP_APPEND_EXTRA).apply(this)); if (get(Settings.TOOLTIP_APPEND_MOD).get() && ConfigObject.getInstance().shouldAppendModNames()) { final Text modString = ClientHelper.getInstance().getFormattedModFromItem(getItem()); @@ -329,4 +335,34 @@ public class ItemEntryStack extends AbstractEntryStack implements OptimalEntrySt MinecraftClient.getInstance().getItemRenderer().zOffset = 0.0F; } } + + private static final List SEARCH_BLACKLISTED = Lists.newArrayList(); + + @Override + public @NotNull Text asFormattedText() { + if (!SEARCH_BLACKLISTED.contains(getItem())) + try { + return getItemStack().getName(); + } catch (Throwable e) { + e.printStackTrace(); + SEARCH_BLACKLISTED.add(getItem()); + } + try { + return new TranslatableText("item." + Registry.ITEM.getId(getItem()).toString().replace(":", ".")); + } catch (Throwable e) { + e.printStackTrace(); + } + return new LiteralText("ERROR"); + } + + private List tryGetItemStackToolTip(boolean careAboutAdvanced) { + if (!SEARCH_BLACKLISTED.contains(getItem())) + try { + return itemStack.getTooltip(MinecraftClient.getInstance().player, MinecraftClient.getInstance().options.advancedItemTooltips && careAboutAdvanced ? TooltipContext.Default.ADVANCED : TooltipContext.Default.NORMAL); + } catch (Throwable e) { + e.printStackTrace(); + SEARCH_BLACKLISTED.add(getItem()); + } + return Collections.singletonList(asFormattedText()); + } } diff --git a/src/main/java/me/shedaniel/rei/impl/RenderingEntry.java b/src/main/java/me/shedaniel/rei/impl/RenderingEntry.java index 6c3c5fa47..05e54f263 100644 --- a/src/main/java/me/shedaniel/rei/impl/RenderingEntry.java +++ b/src/main/java/me/shedaniel/rei/impl/RenderingEntry.java @@ -30,7 +30,7 @@ import org.jetbrains.annotations.ApiStatus; import java.util.Optional; -@ApiStatus.Internal +@ApiStatus.OverrideOnly public abstract class RenderingEntry extends DrawableHelper implements EntryStack { @Override public Optional getIdentifier() { diff --git a/src/main/java/me/shedaniel/rei/impl/SearchArgument.java b/src/main/java/me/shedaniel/rei/impl/SearchArgument.java index 20d113058..52696a2b8 100644 --- a/src/main/java/me/shedaniel/rei/impl/SearchArgument.java +++ b/src/main/java/me/shedaniel/rei/impl/SearchArgument.java @@ -23,83 +23,72 @@ package me.shedaniel.rei.impl; +import com.google.common.base.MoreObjects; import com.google.common.collect.Lists; import me.shedaniel.math.Point; -import me.shedaniel.math.impl.PointHelper; -import me.shedaniel.rei.api.ClientHelper; import me.shedaniel.rei.api.EntryStack; import me.shedaniel.rei.api.widgets.Tooltip; +import me.shedaniel.rei.impl.search.AlwaysMatchingArgument; +import me.shedaniel.rei.impl.search.Argument; +import me.shedaniel.rei.impl.search.ArgumentsRegistry; +import me.shedaniel.rei.impl.search.MatchStatus; import me.shedaniel.rei.utils.CollectionUtils; import net.minecraft.client.MinecraftClient; -import net.minecraft.client.item.TooltipContext; -import net.minecraft.client.resource.language.I18n; -import net.minecraft.fluid.Fluid; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.text.LiteralText; import net.minecraft.text.Text; -import net.minecraft.util.Identifier; -import net.minecraft.util.registry.Registry; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.ApiStatus; -import java.util.Collections; import java.util.List; import java.util.Locale; -import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; @ApiStatus.Internal public class SearchArgument { - - private static final String SPACE = " ", EMPTY = ""; - private static final SearchArgument ALWAYS = new SearchArgument(ArgumentType.ALWAYS, "", true); - private static List searchBlacklisted = Lists.newArrayList(); - private ArgumentType argumentType; + public static final String SPACE = " ", EMPTY = ""; + private static final SearchArgument ALWAYS = new SearchArgument(AlwaysMatchingArgument.INSTANCE, EMPTY, true); + private Argument argument; private String text; - private final Function INCLUDE = s -> s.contains(text); - private final Function NOT_INCLUDE = s -> !s.contains(text); - private boolean include; + private Object data; + private boolean regular; + private static final Pattern SPLIT_PATTERN = Pattern.compile("(?:\"([^\"]*)\")|([^\\s]+)"); - public SearchArgument(ArgumentType argumentType, String text, boolean include) { - this(argumentType, text, include, true); + public SearchArgument(Argument argument, String text, boolean regular) { + this(argument, text, regular, true); } - public SearchArgument(ArgumentType argumentType, String text, boolean include, boolean autoLowerCase) { - this.argumentType = argumentType; - this.text = autoLowerCase ? text.toLowerCase(Locale.ROOT) : text; - this.include = include; + public SearchArgument(Argument argument, String text, boolean regular, boolean lowercase) { + this.argument = argument; + this.text = lowercase ? text.toLowerCase(Locale.ROOT) : text; + this.regular = regular; + this.data = null; } @ApiStatus.Internal public static List processSearchTerm(String searchTerm) { List searchArguments = Lists.newArrayList(); - for (String split : StringUtils.splitByWholeSeparatorPreserveAllTokens(searchTerm.toLowerCase(Locale.ROOT), "|")) { - String[] terms = StringUtils.split(split); - if (terms.length == 0) - searchArguments.add(SearchArgument.SearchArguments.ALWAYS); - else { - SearchArgument[] arguments = new SearchArgument[terms.length]; - for (int i = 0; i < terms.length; i++) { - String term = terms[i]; - if (term.startsWith("-@") || term.startsWith("@-")) { - arguments[i] = new SearchArgument(SearchArgument.ArgumentType.MOD, term.substring(2), false); - } else if (term.startsWith("@")) { - arguments[i] = new SearchArgument(SearchArgument.ArgumentType.MOD, term.substring(1), true); - } else if (term.startsWith("-$") || term.startsWith("$-")) { - arguments[i] = new SearchArgument(SearchArgument.ArgumentType.TAG, term.substring(2), false); - } else if (term.startsWith("$")) { - arguments[i] = new SearchArgument(SearchArgument.ArgumentType.TAG, term.substring(1), true); - } else if (term.startsWith("-#") || term.startsWith("#-")) { - arguments[i] = new SearchArgument(SearchArgument.ArgumentType.TOOLTIP, term.substring(2), false); - } else if (term.startsWith("#")) { - arguments[i] = new SearchArgument(SearchArgument.ArgumentType.TOOLTIP, term.substring(1), true); - } else if (term.startsWith("-")) { - arguments[i] = new SearchArgument(SearchArgument.ArgumentType.TEXT, term.substring(1), false); - } else { - arguments[i] = new SearchArgument(SearchArgument.ArgumentType.TEXT, term, true); + for (String split : StringUtils.splitByWholeSeparatorPreserveAllTokens(searchTerm, "|")) { + Matcher terms = SPLIT_PATTERN.matcher(split); + List arguments = Lists.newArrayList(); + while (terms.find()) { + String term = MoreObjects.firstNonNull(terms.group(1), terms.group(2)); + for (Argument argument : ArgumentsRegistry.ARGUMENTS) { + MatchStatus status = argument.matchesArgumentPrefix(term); + if (status.isMatched()) { + arguments.add(new SearchArgument(argument, status.getText(), !status.isInverted(), !status.shouldPreserveCasing())); + break; } } - searchArguments.add(new SearchArgument.SearchArguments(arguments)); + } + if (arguments.isEmpty()) { + searchArguments.add(SearchArgument.SearchArguments.ALWAYS); + } else { + searchArguments.add(new SearchArgument.SearchArguments(arguments.toArray(new SearchArgument[0]))); + } + } + for (SearchArguments arguments : searchArguments) { + for (SearchArgument argument : arguments.getArguments()) { + argument.data = argument.argument.prepareSearchData(argument.getText()); } } return searchArguments; @@ -110,72 +99,13 @@ public class SearchArgument { if (searchArguments.isEmpty()) return true; MinecraftClient minecraft = MinecraftClient.getInstance(); - String mod = null; - String modName = null; - String name = null; - String tooltip = null; - String[] tags = null; + Object[] data = new Object[ArgumentsRegistry.ARGUMENTS.size()]; for (SearchArgument.SearchArguments arguments : searchArguments) { boolean applicable = true; for (SearchArgument argument : arguments.getArguments()) { - if (argument.getArgumentType() == SearchArgument.ArgumentType.ALWAYS) - return true; - else if (argument.getArgumentType() == SearchArgument.ArgumentType.MOD) { - if (mod == null) - mod = stack.getIdentifier().map(Identifier::getNamespace).orElse("").replace(SPACE, EMPTY).toLowerCase(Locale.ROOT); - if (mod != null && !mod.isEmpty()) { - if (argument.getFunction(!argument.isInclude()).apply(mod)) { - if (modName == null) - modName = ClientHelper.getInstance().getModFromModId(mod).replace(SPACE, EMPTY).toLowerCase(Locale.ROOT); - if (modName == null || modName.isEmpty() || argument.getFunction(!argument.isInclude()).apply(modName)) { - applicable = false; - break; - } - break; - } - } - } else if (argument.getArgumentType() == SearchArgument.ArgumentType.TEXT) { - if (name == null) - name = SearchArgument.tryGetEntryStackName(stack).replace(SPACE, EMPTY).toLowerCase(Locale.ROOT); - if (name != null && !name.isEmpty() && argument.getFunction(!argument.isInclude()).apply(name)) { - applicable = false; - break; - } - } else if (argument.getArgumentType() == SearchArgument.ArgumentType.TOOLTIP) { - if (tooltip == null) - tooltip = SearchArgument.tryGetEntryStackTooltip(stack).replace(SPACE, EMPTY).toLowerCase(Locale.ROOT); - if (tooltip != null && !tooltip.isEmpty() && argument.getFunction(!argument.isInclude()).apply(tooltip)) { - applicable = false; - break; - } - } else if (argument.getArgumentType() == SearchArgument.ArgumentType.TAG) { - if (tags == null) { - if (stack.getType() == EntryStack.Type.ITEM) { - Identifier[] tagsFor = minecraft.getNetworkHandler().getTagManager().items().getTagsFor(stack.getItem()).toArray(new Identifier[0]); - tags = new String[tagsFor.length]; - for (int i = 0; i < tagsFor.length; i++) - tags[i] = tagsFor[i].toString(); - } else if (stack.getType() == EntryStack.Type.FLUID) { - Identifier[] tagsFor = minecraft.getNetworkHandler().getTagManager().fluids().getTagsFor(stack.getFluid()).toArray(new Identifier[0]); - tags = new String[tagsFor.length]; - for (int i = 0; i < tagsFor.length; i++) - tags[i] = tagsFor[i].toString(); - } else - tags = new String[0]; - } - if (tags != null && tags.length > 0) { - boolean a = false; - for (String tag : tags) - if (argument.getFunction(argument.isInclude()).apply(tag)) - a = true; - if (!a) { - applicable = false; - break; - } - } else { - applicable = false; - break; - } + if (argument.getArgument().matches(data, stack, argument.getText(), argument.data) != argument.isRegular()) { + applicable = false; + break; } } if (applicable) @@ -184,28 +114,6 @@ public class SearchArgument { return false; } - public static String tryGetEntryStackName(EntryStack stack) { - if (stack.getType() == EntryStack.Type.ITEM) - return tryGetItemStackName(stack.getItemStack()); - else if (stack.getType() == EntryStack.Type.FLUID) - return tryGetFluidName(stack.getFluid()); - Tooltip tooltip = stack.getTooltip(PointHelper.ofMouse()); - if (tooltip != null) - return tooltip.getText().isEmpty() ? "" : tooltip.getText().get(0).getString(); - return ""; - } - - public static String tryGetEntryStackNameNoFormatting(EntryStack stack) { - if (stack.getType() == EntryStack.Type.ITEM) - return tryGetItemStackNameNoFormatting(stack.getItemStack()); - else if (stack.getType() == EntryStack.Type.FLUID) - return tryGetFluidName(stack.getFluid()); - Tooltip tooltip = stack.getTooltip(PointHelper.ofMouse()); - if (tooltip != null) - return tooltip.getText().isEmpty() ? "" : tooltip.getText().get(0).getString(); - return ""; - } - public static String tryGetEntryStackTooltip(EntryStack stack) { Tooltip tooltip = stack.getTooltip(new Point()); if (tooltip != null) @@ -213,83 +121,21 @@ public class SearchArgument { return ""; } - public static String tryGetFluidName(Fluid fluid) { - Identifier id = Registry.FLUID.getId(fluid); - if (I18n.hasTranslation("block." + id.toString().replaceFirst(":", "."))) - return I18n.translate("block." + id.toString().replaceFirst(":", ".")); - return CollectionUtils.mapAndJoinToString(id.getPath().split("_"), StringUtils::capitalize, " "); - } - - public static List tryGetItemStackToolTip(ItemStack itemStack, boolean careAboutAdvanced) { - if (!searchBlacklisted.contains(itemStack.getItem())) - try { - return itemStack.getTooltip(MinecraftClient.getInstance().player, MinecraftClient.getInstance().options.advancedItemTooltips && careAboutAdvanced ? TooltipContext.Default.ADVANCED : TooltipContext.Default.NORMAL); - } catch (Throwable e) { - e.printStackTrace(); - searchBlacklisted.add(itemStack.getItem()); - } - return Collections.singletonList(new LiteralText(tryGetItemStackName(itemStack))); - } - - public static String tryGetItemStackName(ItemStack stack) { - if (!searchBlacklisted.contains(stack.getItem())) - try { - return stack.getName().getString(); - } catch (Throwable e) { - e.printStackTrace(); - searchBlacklisted.add(stack.getItem()); - } - try { - return I18n.translate("item." + Registry.ITEM.getId(stack.getItem()).toString().replace(":", ".")); - } catch (Throwable e) { - e.printStackTrace(); - } - return "ERROR"; - } - - public static String tryGetItemStackNameNoFormatting(ItemStack stack) { - if (!searchBlacklisted.contains(stack.getItem())) - try { - return stack.getName().asString(); - } catch (Throwable e) { - e.printStackTrace(); - searchBlacklisted.add(stack.getItem()); - } - try { - return I18n.translate