Compare commits

...
20 Commits
Author SHA1 Message Date
Martin Robertz cfe6588d79 Merge remote-tracking branch 'slprime/jei_search' into dev 2024-06-20 21:09:19 +02:00
slprime 4f98ab6c64 clean cache after add new provider 2024-06-20 20:51:40 +03:00
Martin Robertz cb4fd40a53 Merge branch 'master' into dev 2024-06-18 20:34:20 +02:00
Martin Robertz 7823923231 update 2024-06-18 20:31:26 +02:00
Martin Robertz 9fc099f877 update 2024-06-18 20:31:16 +02:00
Martin Robertz ca5c54e157 Merge remote-tracking branch 'slprime/jei_search' into dev 2024-06-18 20:30:13 +02:00
Martin Robertz 2e2bcfdbdf Merge remote-tracking branch 'origin/master' into dev 2024-06-18 20:29:57 +02:00
slprime 76b315caec fix modname search 2024-06-18 18:28:25 +03:00
slprime 685477b381 fix type 2024-06-13 08:38:53 +03:00
slprime 28d653a3b5 add matching language to searh parser 2024-06-13 08:25:33 +03:00
Martin Robertz 34734a622b Merge branch 'master' into jei_search 2024-06-11 20:19:43 +02:00
slprime 331a9fd638 code refactoring 2024-06-11 00:15:24 +03:00
slprime 98c49caff9 move autofocus config to seatch widget panel 2024-06-10 23:56:43 +03:00
Martin Robertz 622b696389 Merge branch 'master' into jei_search 2024-06-10 22:22:29 +02:00
slprime 985e1e0425 add regexp to extended patternMode 2024-06-08 20:21:10 +03:00
slprime da05482ef0 fix unicode case in search 2024-05-31 10:30:40 +03:00
slprime b41c570315 fix search crash without prefixes 2024-05-31 07:44:40 +03:00
slprime 0373e7376b fix extended search pattern 2024-05-30 20:16:35 +03:00
slprime 178021a8e8 add subfilter 2024-05-30 19:24:20 +03:00
slprime 8dd9014109 Create JEI like Search 2024-05-29 19:50:29 +03:00
34 changed files with 1233 additions and 291 deletions

No files matched your search

@@ -0,0 +1,251 @@
package codechicken.nei;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.client.gui.Gui;
import net.minecraft.client.gui.GuiTextField;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.util.EnumChatFormatting;
import org.lwjgl.opengl.GL11;
class FormattedTextField extends GuiTextField {
public static interface TextFormatter {
TextFormatter DEFAULT = (text) -> text;
public String format(String text);
}
protected FontRenderer fontRenderer;
protected String rawText = "";
protected String formattedText = "";
protected boolean editable = true;
protected int editableColor = 14737632;
protected int notEditableColor = 7368816;
protected TextFormatter formatter = TextFormatter.DEFAULT;
protected int lineScrollOffset = 0;
protected int frame = 0;
public FormattedTextField(FontRenderer fontRenderer, int xPosition, int yPosition, int width, int height) {
super(fontRenderer, xPosition, yPosition, width, height);
this.fontRenderer = fontRenderer;
}
public void setFormatter(TextFormatter formatter) {
this.formatter = formatter;
}
@Override
public void updateCursorCounter() {
super.updateCursorCounter();
++this.frame;
}
@Override
public void setFocused(boolean focus) {
if (focus && !this.isFocused()) {
this.frame = 0;
}
super.setFocused(focus);
}
@Override
public void setSelectionPos(int p_146199_1_) {
String text = this.getText();
int j = text.length();
super.setSelectionPos(p_146199_1_);
p_146199_1_ = Math.max(0, Math.min(p_146199_1_, j));
if (this.fontRenderer != null) {
if (this.lineScrollOffset > j) {
this.lineScrollOffset = j;
}
int k = this.getWidth();
String s = this.fontRenderer.trimStringToWidth(text.substring(this.lineScrollOffset), k);
int l = s.length() + this.lineScrollOffset;
if (p_146199_1_ == this.lineScrollOffset) {
this.lineScrollOffset -= this.fontRenderer.trimStringToWidth(text, k, true).length();
}
if (p_146199_1_ > l) {
this.lineScrollOffset += p_146199_1_ - l;
} else if (p_146199_1_ <= this.lineScrollOffset) {
this.lineScrollOffset -= this.lineScrollOffset - p_146199_1_;
}
this.lineScrollOffset = Math.max(0, Math.min(this.lineScrollOffset, j));
}
}
@Override
public void setTextColor(int p_146193_1_) {
super.setTextColor(p_146193_1_);
this.editableColor = p_146193_1_;
}
@Override
public void setDisabledTextColour(int p_146204_1_) {
super.setDisabledTextColour(p_146204_1_);
this.notEditableColor = p_146204_1_;
}
@Override
public void setEnabled(boolean p_146184_1_) {
super.setEnabled(p_146184_1_);
this.editable = p_146184_1_;
}
@Override
public void drawTextBox() {
if (this.getVisible()) {
if (this.getEnableBackgroundDrawing()) {
drawRect(
this.xPosition - 1,
this.yPosition - 1,
this.xPosition + this.width + 1,
this.yPosition + this.height + 1,
-6250336);
drawRect(
this.xPosition,
this.yPosition,
this.xPosition + this.width,
this.yPosition + this.height,
-16777216);
}
if (!this.rawText.equals(getText())) {
this.rawText = getText();
this.formattedText = this.formatter.format(this.rawText);
if (!EnumChatFormatting.getTextWithoutFormattingCodes(this.formattedText).toLowerCase()
.equals(this.rawText.toLowerCase())) {
this.formattedText = this.rawText;
}
}
int firstCharacterIndex = getFormattedTextShift(this.lineScrollOffset);
String rawTextClipped = this.fontRenderer
.trimStringToWidth(this.rawText.substring(this.lineScrollOffset), this.getWidth());
String textClipped = this.formattedText.substring(
firstCharacterIndex,
getFormattedTextShift(this.lineScrollOffset + rawTextClipped.length()));
int cursorPosition = getFormattedTextShift(this.getCursorPosition());
int selectionEnd = getFormattedTextShift(this.getSelectionEnd());
int color = this.editable ? this.editableColor : this.notEditableColor;
int cursorA = cursorPosition - firstCharacterIndex;
int cursorB = selectionEnd - firstCharacterIndex;
boolean flag = cursorA >= 0 && cursorA <= textClipped.length();
boolean flag1 = this.isFocused() && this.frame / 6 % 2 == 0 && flag;
boolean flag2 = this.getCursorPosition() < this.rawText.length()
|| this.rawText.length() >= this.getMaxStringLength();
int x = this.getEnableBackgroundDrawing() ? this.xPosition + 4 : this.xPosition;
int y = this.getEnableBackgroundDrawing() ? this.yPosition + (this.height - 8) / 2 : this.yPosition;
int x2 = x;
if (cursorB > textClipped.length()) {
cursorB = textClipped.length();
}
if (textClipped.length() > 0) {
String s1 = flag ? textClipped.substring(0, cursorA) : textClipped;
String colorA = getPreviousColor(firstCharacterIndex);
x2 = this.fontRenderer.drawStringWithShadow(colorA + s1, x, y, color);
}
int k1 = x2;
if (!flag) {
k1 = cursorA > 0 ? x + this.width : x;
} else if (flag2) {
k1 = x2 - 1;
--x2;
}
if (textClipped.length() > 0 && flag && cursorA < textClipped.length()) {
String colorB = getPreviousColor(firstCharacterIndex + cursorA);
this.fontRenderer.drawStringWithShadow(colorB + textClipped.substring(cursorA), x2, y, color);
}
if (flag1) {
if (flag2) {
Gui.drawRect(k1, y - 1, k1 + 1, y + 1 + this.fontRenderer.FONT_HEIGHT, -3092272);
} else {
this.fontRenderer.drawStringWithShadow("_", k1, y, color);
}
}
if (cursorB != cursorA) {
int l1 = x + this.fontRenderer.getStringWidth(textClipped.substring(0, cursorB));
drawCursorVertical(k1, y - 1, l1 - 1, y + 1 + this.fontRenderer.FONT_HEIGHT);
}
}
}
private void drawCursorVertical(int x1, int y1, int x2, int y2) {
int i1;
if (x1 < x2) {
i1 = x1;
x1 = x2;
x2 = i1;
}
if (y1 < y2) {
i1 = y1;
y1 = y2;
y2 = i1;
}
if (x2 > this.xPosition + this.width) {
x2 = this.xPosition + this.width;
}
if (x1 > this.xPosition + this.width) {
x1 = this.xPosition + this.width;
}
Tessellator tessellator = Tessellator.instance;
GL11.glColor4f(0.0F, 0.0F, 255.0F, 255.0F);
GL11.glDisable(GL11.GL_TEXTURE_2D);
GL11.glEnable(GL11.GL_COLOR_LOGIC_OP);
GL11.glLogicOp(GL11.GL_OR_REVERSE);
tessellator.startDrawingQuads();
tessellator.addVertex((double) x1, (double) y2, 0.0D);
tessellator.addVertex((double) x2, (double) y2, 0.0D);
tessellator.addVertex((double) x2, (double) y1, 0.0D);
tessellator.addVertex((double) x1, (double) y1, 0.0D);
tessellator.draw();
GL11.glDisable(GL11.GL_COLOR_LOGIC_OP);
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
private int getFormattedTextShift(int position) {
int shift = 0;
for (int i = 0; i < position; i++) {
while (this.formattedText.length() > i + shift && this.formattedText.charAt(i + shift) == '\u00a7') {
shift += 2;
}
}
return position + shift;
}
private String getPreviousColor(int position) {
while (position >= 0) {
if (this.formattedText.charAt(position) == '\u00a7') {
return this.formattedText.substring(position, position + 2);
}
position--;
}
return "";
}
}
+37 -4
View File
@@ -5,11 +5,13 @@ import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.StringJoiner;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import net.minecraft.client.Minecraft;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.IIcon;
@@ -21,7 +23,6 @@ import codechicken.nei.ThreadOperationTimer.TimeoutException;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.guihook.GuiContainerManager;
public class ItemList {
@@ -63,6 +64,20 @@ public class ItemList {
}
}
public static class NegatedItemFilter implements ItemFilter {
public ItemFilter filter;
public NegatedItemFilter(ItemFilter filter) {
this.filter = filter;
}
@Override
public boolean matches(ItemStack item) {
return this.filter == null || !this.filter.matches(item);
}
}
public static class PatternItemFilter implements ItemFilter {
public Pattern pattern;
@@ -73,7 +88,7 @@ public class ItemList {
@Override
public boolean matches(ItemStack item) {
return pattern.matcher(ItemInfo.getSearchName(item)).find();
return pattern.matcher(item.getDisplayName()).find();
}
}
@@ -161,7 +176,9 @@ public class ItemList {
public static List<ItemFilter> getItemFilters() {
LinkedList<ItemFilter> filters = new LinkedList<>();
synchronized (itemFilterers) {
for (ItemFilterProvider p : itemFilterers) filters.add(p.getFilter());
for (ItemFilterProvider p : itemFilterers) {
filters.add(p.getFilter());
}
}
return filters;
}
@@ -173,7 +190,7 @@ public class ItemList {
for (int damage = 0; damage < 16; damage++) try {
ItemStack itemstack = new ItemStack(item, 1, damage);
IIcon icon = item.getIconIndex(itemstack);
String name = GuiContainerManager.concatenatedDisplayName(itemstack, false);
String name = getTooltip(itemstack);
String s = name + "@" + (icon == null ? 0 : icon.hashCode());
if (!damageIconSet.contains(s)) {
damageIconSet.add(s);
@@ -190,6 +207,22 @@ public class ItemList {
}
}
private String getTooltip(ItemStack stack) {
try {
@SuppressWarnings("unchecked")
final List<String> namelist = stack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
final StringJoiner sb = new StringJoiner("\n");
for (String name : namelist) {
sb.add(name);
}
return sb.toString();
} catch (Throwable ignored) {}
return "";
}
@Override
@SuppressWarnings("unchecked")
public void execute() {
@@ -123,8 +123,8 @@ public class ItemSorter implements Comparator<ItemStack>, ItemsLoadedCallback {
return compareInt(id1, id2);
});
API.addSortOption("nei.itemsort.name", (o1, o2) -> {
String name1 = ItemInfo.getSearchName(o1);
String name2 = ItemInfo.getSearchName(o2);
String name1 = o1.getDisplayName();
String name2 = o2.getDisplayName();
return name1.compareTo(name2);
});
tag.getTag("inventory.itemsort").setDefaultValue(getSaveString(list));
@@ -90,7 +90,8 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
public static PresetsWidget presetsPanel;
public static SearchField searchField;
public static boolean searchInitFocusedCancellable = false;
public static int mousePriorX, mousePriorY;
protected static int mousePriorX;
protected static int mousePriorY;
public static ButtonCycled options;
public static ButtonCycled bookmarksButton;
@@ -167,7 +168,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
return getSideWidth(gui);
}
public boolean isAllowedGuiAutoSearchFocus(GuiContainer gui) {
protected boolean isAllowedGuiAutoSearchFocus(GuiContainer gui) {
if (gui instanceof INEIAutoFocusSearchEnable) {
return true;
}
@@ -182,9 +183,9 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
return false;
}
public void searchFocusInitCancelCheck() {
protected void searchFocusInitCancelCheck() {
if (searchInitFocusedCancellable) {
if (searchField.isVisible() && NEIClientConfig.isFocusSearchWidgetOnOpen()
if (searchField.isVisible() && NEIClientConfig.searchWidgetAutofocus()
&& getInputFocused() == searchField) {
searchField.setFocus(false);
setInputFocused(null);
@@ -306,8 +307,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
if (mousePriorX == -1) {
mousePriorX = mousex;
mousePriorY = mousey;
}
if (mousePriorX != mousex || mousePriorY != mousey) {
} else if (mousePriorX != mousex || mousePriorY != mousey) {
searchFocusInitCancelCheck();
mousePriorX = mousex;
mousePriorY = mousey;
@@ -676,7 +676,7 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
mousePriorX = -1;
mousePriorY = -1;
if (searchField.isVisible() && NEIClientConfig.isFocusSearchWidgetOnOpen()
if (searchField.isVisible() && NEIClientConfig.searchWidgetAutofocus()
&& isAllowedGuiAutoSearchFocus(gui)) {
searchField.setFocus(true);
setInputFocused(searchField);
@@ -15,6 +15,7 @@ import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.World;
import net.minecraft.world.storage.SaveFormatComparator;
import net.minecraftforge.common.MinecraftForge;
@@ -168,6 +169,76 @@ public class NEIClientConfig {
ItemSorter.initConfig(tag);
tag.getTag("inventory.search.widgetPosition").setComment("Widget Position").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.search.widgetPosition", true));
tag.getTag("inventory.search.widgetAutofocus")
.setComment(
"Focus Search Widget on Open, blurs/unfocuses on mouse move unless typing has started first")
.getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.search.widgetAutofocus", true));
tag.getTag("inventory.search.patternMode").setComment("Search Mode").getIntValue(1);
API.addOption(new OptionCycled("inventory.search.patternMode", 3, true));
tag.getTag("inventory.search.quoteDropItemName").setComment("Quote Drop Item Name").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.search.quoteDropItemName", true));
tag.getTag("inventory.search.modNameSearchMode").setComment("Search mode for Mod Names (prefix: @)")
.getIntValue(1);
API.addOption(new OptionCycled("inventory.search.modNameSearchMode", 3, true) {
@Override
public String getButtonText() {
return translateN(name + "." + value(), EnumChatFormatting.LIGHT_PURPLE + "@");
}
});
tag.getTag("inventory.search.tooltipSearchMode").setComment("Search mode for Tooltips (prefix: #)")
.getIntValue(1);
API.addOption(new OptionCycled("inventory.search.tooltipSearchMode", 3, true) {
@Override
public String getButtonText() {
return translateN(name + "." + value(), EnumChatFormatting.YELLOW + "#");
}
});
tag.getTag("inventory.search.identifierSearchMode").setComment("Search mode for identifier (prefix: &)")
.getIntValue(1);
API.addOption(new OptionCycled("inventory.search.identifierSearchMode", 3, true) {
@Override
public String getButtonText() {
return translateN(name + "." + value(), EnumChatFormatting.GOLD + "&");
}
});
tag.getTag("inventory.search.oreDictSearchMode").setComment("Search mode for Tag Names (prefix: $)")
.getIntValue(1);
API.addOption(new OptionCycled("inventory.search.oreDictSearchMode", 3, true) {
@Override
public String getButtonText() {
return translateN(name + "." + value(), EnumChatFormatting.AQUA + "$");
}
});
tag.getTag("inventory.search.subsetsSearchMode").setComment("Search mode for Item Subsets (prefix: %)")
.getIntValue(1);
API.addOption(new OptionCycled("inventory.search.subsetsSearchMode", 3, true) {
@Override
public String getButtonText() {
return translateN(name + "." + value(), EnumChatFormatting.DARK_PURPLE + "%");
}
});
tag.getTag("inventory.history.enabled").setComment("Enable/disable History Panel").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.history.enabled", true));
@@ -184,9 +255,6 @@ public class NEIClientConfig {
tag.getTag("inventory.itemIDs").getIntValue(1);
API.addOption(new OptionCycled("inventory.itemIDs", 3, true));
tag.getTag("inventory.searchmode").getIntValue(1);
API.addOption(new OptionCycled("inventory.searchmode", 3, true));
tag.getTag("world.highlight_tips").getBooleanValue(false);
tag.getTag("world.highlight_tips.x").getIntValue(5000);
tag.getTag("world.highlight_tips.y").getIntValue(100);
@@ -275,15 +343,6 @@ public class NEIClientConfig {
tag.getTag("inventory.showItemQuantityWidget").setComment("Show Item Quantity Widget").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.showItemQuantityWidget", true));
tag.getTag("inventory.centerSearchWidget").setComment("Center Search Widget").getBooleanValue(true);
API.addOption(new OptionToggleButton("inventory.centerSearchWidget", true));
tag.getTag("inventory.focusSearchWidgetOnOpen")
.setComment(
"Focus Search Widget on Open, blurs/unfocuses on mouse move unless typing has started first")
.getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.focusSearchWidgetOnOpen", true));
tag.getTag("inventory.firstInvCloseClosesInSearch").setComment(
"Pressing the open inventory key when the inventory was just opened when the search is focused will close it instead of typing in the search")
.getBooleanValue(true);
@@ -628,11 +687,11 @@ public class NEIClientConfig {
}
public static boolean isSearchWidgetCentered() {
return getBooleanSetting("inventory.centerSearchWidget");
return getBooleanSetting("inventory.search.widgetPosition");
}
public static boolean isFocusSearchWidgetOnOpen() {
return getBooleanSetting("inventory.focusSearchWidgetOnOpen");
public static boolean searchWidgetAutofocus() {
return getBooleanSetting("inventory.search.widgetAutofocus");
}
public static boolean isFirstInvCloseClosesInSearch() {
@@ -1,5 +1,6 @@
package codechicken.nei;
import net.minecraft.client.Minecraft;
import net.minecraft.util.EnumChatFormatting;
import codechicken.nei.api.ItemFilter;
@@ -14,6 +15,14 @@ public abstract class RecipeSearchField extends TextField {
this.field.setVisible(false);
}
@Override
protected void initInternalTextField() {
field = new FormattedTextField(Minecraft.getMinecraft().fontRenderer, 0, 0, 0, 0);
((FormattedTextField) field).setFormatter(new SearchTextFormatter(SearchField.searchParser));
field.setMaxStringLength(maxSearchLength);
field.setCursorPositionZero();
}
public boolean isVisible() {
return this.field.getVisible();
}
+140 -45
View File
@@ -4,18 +4,24 @@ import static codechicken.nei.NEIClientConfig.world;
import java.util.LinkedList;
import java.util.List;
import java.util.function.Function;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
import net.minecraft.client.Minecraft;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.fluids.FluidStack;
import codechicken.lib.gui.GuiDraw;
import codechicken.nei.ItemList.AnyMultiItemFilter;
import codechicken.nei.ItemList.EverythingItemFilter;
import codechicken.nei.ItemList.PatternItemFilter;
import codechicken.nei.ItemList.NothingItemFilter;
import codechicken.nei.SearchTokenParser.ISearchParserProvider;
import codechicken.nei.SearchTokenParser.SearchMode;
import codechicken.nei.api.API;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
import codechicken.nei.recipe.StackInfo;
import codechicken.nei.util.TextHistory;
public class SearchField extends TextField implements ItemFilterProvider {
@@ -23,6 +29,7 @@ public class SearchField extends TextField implements ItemFilterProvider {
/**
* Interface for returning a custom filter based on search field text
*/
@Deprecated
public static interface ISearchProvider {
/**
@@ -36,30 +43,72 @@ public class SearchField extends TextField implements ItemFilterProvider {
public ItemFilter getFilter(String searchText);
}
private static class DefaultSearchProvider implements ISearchProvider {
public static class SearchParserProvider implements ISearchParserProvider {
@Override
public boolean isPrimary() {
return false;
protected final Function<Pattern, ItemFilter> createFilter;
protected final String name;
protected final char prefix;
protected final EnumChatFormatting highlightedColor;
public SearchParserProvider(char prefix, String name, EnumChatFormatting highlightedColor,
Function<Pattern, ItemFilter> createFilter) {
this.prefix = prefix;
this.name = name;
this.highlightedColor = highlightedColor;
this.createFilter = createFilter;
}
@Override
public ItemFilter getFilter(String searchText) {
Pattern pattern = getPattern(searchText);
return pattern == null ? null : new PatternItemFilter(pattern);
Pattern pattern = SearchField.getPattern(searchText);
if (pattern != null) {
return this.createFilter(pattern);
}
return new NothingItemFilter();
}
protected ItemFilter createFilter(Pattern pattern) {
final ItemFilter filter = this.createFilter.apply(pattern);
return filter == null ? new NothingItemFilter() : filter;
}
@Override
public char getPrefix() {
return this.prefix;
}
@Override
public EnumChatFormatting getHighlightedColor() {
return this.highlightedColor;
}
@Override
public SearchMode getSearchMode() {
return SearchMode.fromInt(NEIClientConfig.getIntSetting("inventory.search." + this.name + "SearchMode"));
}
}
@Deprecated
public static List<ISearchProvider> searchProviders = new LinkedList<>();
public static SearchTokenParser searchParser = new SearchTokenParser();
private static final TextHistory history = new TextHistory();
private boolean isVisible = true;
long lastclicktime;
private long lastclicktime;
public SearchField(String ident) {
super(ident);
API.addItemFilter(this);
API.addSearchProvider(new DefaultSearchProvider());
}
@Override
protected void initInternalTextField() {
field = new FormattedTextField(Minecraft.getMinecraft().fontRenderer, 0, 0, 0, 0);
((FormattedTextField) field).setFormatter(new SearchTextFormatter(SearchField.searchParser));
field.setMaxStringLength(maxSearchLength);
field.setCursorPositionZero();
}
public static boolean searchInventories() {
@@ -85,7 +134,6 @@ public class SearchField extends TextField implements ItemFilterProvider {
@Override
public void draw(int mousex, int mousey) {
super.draw(mousex, mousey);
if (searchInventories()) {
@@ -110,10 +158,11 @@ public class SearchField extends TextField implements ItemFilterProvider {
@Override
public void onTextChange(String oldText) {
final String newText = text();
if (newText.length() > 0) NEIClientConfig.logger.debug("Searching for " + text());
NEIClientConfig.setSearchExpression(newText);
ItemList.updateFilter.restart();
if (!newText.equals(oldText)) {
if (newText.length() > 0) NEIClientConfig.logger.debug("Searching for " + newText);
NEIClientConfig.setSearchExpression(newText);
ItemList.updateFilter.restart();
}
}
@Override
@@ -137,21 +186,84 @@ public class SearchField extends TextField implements ItemFilterProvider {
}
public static Pattern getPattern(String search) {
switch (NEIClientConfig.getIntSetting("inventory.searchmode")) {
return getPattern(search, NEIClientConfig.getIntSetting("inventory.search.patternMode"));
}
public static Pattern getPattern(String search, int patternMode) {
switch (patternMode) {
case 0: // plain
search = "\\Q" + search + "\\E";
search = Pattern.quote(search);
break;
case 1:
search = search.replace(".", "").replace("?", ".").replace("*", ".+?");
case 1: // extended
if (search.length() >= 3 && search.startsWith("r/") && search.endsWith("/")) {
search = search.substring(2, search.length() - 1);
} else {
final Matcher matcher = Pattern.compile("(\\?|\\*)").matcher(search);
String cleanedString = "";
int lastEndIndex = 0;
while (matcher.find()) {
cleanedString += Pattern.quote(search.substring(lastEndIndex, matcher.start()));
switch (matcher.group(0).charAt(0)) {
case '?':
cleanedString += ".";
break;
case '*':
cleanedString += ".+?";
break;
default:
break;
}
lastEndIndex = matcher.end();
}
search = cleanedString + Pattern.quote(search.substring(lastEndIndex, search.length()));
}
break;
}
Pattern pattern = null;
try {
pattern = Pattern.compile(search);
} catch (PatternSyntaxException ignored) {}
if (!search.isEmpty()) {
try {
return Pattern.compile(search, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
} catch (PatternSyntaxException ignored) {}
}
return pattern == null || pattern.toString().length() == 0 ? null : pattern;
return null;
}
public static String getEscapedSearchText(ItemStack stack) {
final FluidStack fluidStack = StackInfo.isFluidContainer(stack) ? null : StackInfo.getFluid(stack);
String displayName;
if (fluidStack != null) {
displayName = fluidStack.getLocalizedName();
} else {
displayName = stack.getDisplayName();
}
return getEscapedSearchText(displayName);
}
public static String getEscapedSearchText(String text) {
text = EnumChatFormatting.getTextWithoutFormattingCodes(text);
switch (NEIClientConfig.getIntSetting("inventory.search.patternMode")) {
case 1:
text = text.replaceAll("[\\?|\\*]", "\\\\$0");
break;
case 2:
text = text.replaceAll("[{}()\\[\\].+*?^$\\\\|]", "\\\\$0");
break;
}
if (text.contains(" ") && NEIClientConfig.getBooleanSetting("inventory.search.quoteDropItemName")) {
text = "\"" + text + "\"";
}
return text;
}
@Override
@@ -159,25 +271,8 @@ public class SearchField extends TextField implements ItemFilterProvider {
return getFilter(text());
}
public static ItemFilter getFilter(String s_filter) {
List<ItemFilter> primary = new LinkedList<>();
List<ItemFilter> secondary = new LinkedList<>();
s_filter = s_filter.toLowerCase();
for (ISearchProvider p : searchProviders) {
ItemFilter filter = p.getFilter(s_filter);
if (filter != null) (p.isPrimary() ? primary : secondary).add(filter);
}
if (!primary.isEmpty()) {
return new AnyMultiItemFilter(primary);
}
if (!secondary.isEmpty()) {
return new AnyMultiItemFilter(secondary);
}
return new EverythingItemFilter();
public static ItemFilter getFilter(String filterText) {
return SearchField.searchParser.getFilter(filterText);
}
@Override
@@ -0,0 +1,79 @@
package codechicken.nei;
import java.util.StringJoiner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.minecraft.util.EnumChatFormatting;
import codechicken.nei.FormattedTextField.TextFormatter;
public class SearchTextFormatter implements TextFormatter {
protected final SearchTokenParser searchParser;
public SearchTextFormatter(SearchTokenParser searchParser) {
this.searchParser = searchParser;
}
public String format(String text) {
final String[] parts = text.split("\\|");
final Pattern splitPattern = searchParser.getSplitPattern();
StringJoiner formattedText = new StringJoiner(EnumChatFormatting.GRAY + "|");
for (String filterText : parts) {
Matcher filterMatcher = splitPattern.matcher(filterText);
StringBuilder formattedPart = new StringBuilder();
int startIndex = 0;
while (filterMatcher.find()) {
boolean ignore = "-".equals(filterMatcher.group(2));
String firstChar = filterMatcher.group(3);
String token = filterMatcher.group(4);
boolean quotes = token.length() > 1 && token.startsWith("\"") && token.endsWith("\"");
if (quotes) {
token = token.substring(1, token.length() - 1);
}
formattedPart.append(filterText.substring(startIndex, filterMatcher.start()));
EnumChatFormatting tokenColor = EnumChatFormatting.RESET;
if (!firstChar.isEmpty()) {
tokenColor = searchParser.getProvider(firstChar.charAt(0)).getHighlightedColor();
}
if (ignore) {
formattedPart.append(EnumChatFormatting.BLUE + "-");
}
if (!firstChar.isEmpty()) {
formattedPart.append(tokenColor + firstChar);
}
if (quotes) {
formattedPart.append(EnumChatFormatting.GOLD + "\"");
}
if (!token.isEmpty()) {
formattedPart.append(tokenColor + token);
}
if (quotes) {
formattedPart.append(EnumChatFormatting.GOLD + "\"");
}
startIndex = filterMatcher.end();
}
formattedPart.append(filterText.substring(startIndex, filterText.length()));
formattedText.add(formattedPart);
}
if (text.endsWith("|")) {
formattedText.add("");
}
return formattedText.toString();
}
}
@@ -0,0 +1,200 @@
package codechicken.nei;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.Language;
import net.minecraft.util.EnumChatFormatting;
import codechicken.nei.ItemList.AllMultiItemFilter;
import codechicken.nei.ItemList.AnyMultiItemFilter;
import codechicken.nei.ItemList.EverythingItemFilter;
import codechicken.nei.ItemList.NegatedItemFilter;
import codechicken.nei.ItemList.NothingItemFilter;
import codechicken.nei.api.ItemFilter;
public class SearchTokenParser {
public enum SearchMode {
ALWAYS,
PREFIX,
NEVER;
public static SearchMode fromInt(int value) {
switch (value) {
case 0:
return ALWAYS;
case 1:
return PREFIX;
case 2:
return NEVER;
default:
return ALWAYS;
}
}
}
public static interface ISearchParserProvider {
public ItemFilter getFilter(String searchText);
@SuppressWarnings("unchecked")
public static List<Language> getAllLanguages() {
return new ArrayList<>(Minecraft.getMinecraft().getLanguageManager().getLanguages());
}
default List<Language> getMatchingLanguages() {
return getAllLanguages();
}
public char getPrefix();
public EnumChatFormatting getHighlightedColor();
public SearchMode getSearchMode();
}
private static class ProvidersCache {
public String languageCode = null;
public List<ISearchParserProvider> providers = new ArrayList<>();
public void clear() {
this.languageCode = null;
this.providers.clear();
}
}
protected final List<ISearchParserProvider> searchProviders;
protected final ProvidersCache providersCache = new ProvidersCache();
public SearchTokenParser(List<ISearchParserProvider> searchProviders) {
this.searchProviders = searchProviders;
}
public SearchTokenParser() {
this(new ArrayList<>());
}
public void addProvider(ISearchParserProvider provider) {
this.searchProviders.add(provider);
this.providersCache.clear();
}
protected List<ISearchParserProvider> getProviders() {
Language currentLanguage = Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage();
if (!currentLanguage.getLanguageCode().equals(providersCache.languageCode)) {
Map<Character, ISearchParserProvider> providers = new HashMap<>();
for (int index = this.searchProviders.size() - 1; index >= 0; index--) {
ISearchParserProvider provider = this.searchProviders.get(index);
if (!providers.containsKey(provider.getPrefix())
&& provider.getMatchingLanguages().contains(currentLanguage)) {
providers.put(provider.getPrefix(), provider);
}
}
providersCache.providers = new ArrayList<>(providers.values());
providersCache.languageCode = currentLanguage.getLanguageCode();
}
return providersCache.providers;
}
public ISearchParserProvider getProvider(char ch) {
return getProviders().stream()
.filter(provider -> provider.getSearchMode() == SearchMode.PREFIX && provider.getPrefix() == ch)
.findFirst().orElse(null);
}
public ItemFilter getFilter(String filterText) {
final String[] parts = EnumChatFormatting.getTextWithoutFormattingCodes(filterText).toLowerCase().split("\\|");
final List<ItemFilter> searchTokens = Arrays.stream(parts).map(s -> parseSearchText(s)).filter(s -> s != null)
.collect(Collectors.toCollection(ArrayList::new));
if (searchTokens.isEmpty()) {
return new EverythingItemFilter();
} else if (searchTokens.size() == 1) {
return searchTokens.get(0);
} else {
return new AnyMultiItemFilter(searchTokens);
}
}
public Pattern getSplitPattern() {
StringJoiner prefixes = new StringJoiner("");
prefixes.add(String.valueOf('\0'));
for (ISearchParserProvider provider : getProviders()) {
if (provider.getSearchMode() == SearchMode.PREFIX) {
prefixes.add(String.valueOf(provider.getPrefix()));
}
}
return Pattern.compile("((-*)([" + Pattern.quote(prefixes.toString()) + "]*)(\\\".*?(?:\\\"|$)|\\S+))");
}
private ItemFilter parseSearchText(String filterText) {
if (filterText.isEmpty()) {
return null;
}
final Matcher filterMatcher = getSplitPattern().matcher(filterText);
final AllMultiItemFilter searchTokens = new AllMultiItemFilter();
while (filterMatcher.find()) {
boolean ignore = "-".equals(filterMatcher.group(2));
String firstChar = filterMatcher.group(3);
String token = filterMatcher.group(4);
boolean quotes = token.length() > 1 && token.startsWith("\"") && token.endsWith("\"");
if (quotes) {
token = token.substring(1, token.length() - 1);
}
if (!token.isEmpty()) {
ItemFilter result = parseToken(firstChar, token);
if (ignore) {
searchTokens.filters.add(new NegatedItemFilter(result));
} else {
searchTokens.filters.add(result);
}
} else if (!ignore) {
searchTokens.filters.add(new NothingItemFilter());
}
}
return searchTokens;
}
private ItemFilter parseToken(String firstChar, String token) {
final ISearchParserProvider provider = firstChar.isEmpty() ? null : this.getProvider(firstChar.charAt(0));
if (provider == null || provider.getSearchMode() == SearchMode.NEVER) {
final List<ItemFilter> filters = new ArrayList<>();
for (ISearchParserProvider _provider : getProviders()) {
if (_provider.getSearchMode() == SearchMode.ALWAYS) {
filters.add(_provider.getFilter(token));
}
}
return filters.isEmpty() ? new NothingItemFilter() : new AnyMultiItemFilter(filters);
} else {
return provider.getFilter(token);
}
}
}
+63 -63
View File
@@ -28,14 +28,15 @@ import codechicken.lib.vec.Rectangle4i;
import codechicken.nei.ItemList.AnyMultiItemFilter;
import codechicken.nei.ItemList.ItemsLoadedCallback;
import codechicken.nei.ItemList.NothingItemFilter;
import codechicken.nei.SearchField.ISearchProvider;
import codechicken.nei.SearchTokenParser.ISearchParserProvider;
import codechicken.nei.SearchTokenParser.SearchMode;
import codechicken.nei.api.API;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.guihook.GuiContainerManager;
public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoadedCallback, ISearchProvider {
public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoadedCallback {
public static ReentrantReadWriteLock hiddenItemLock = new ReentrantReadWriteLock();
public static Lock writeLock = hiddenItemLock.writeLock();
@@ -70,14 +71,20 @@ public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoa
protected void slotClicked(int slot, int button, int mx, int my, int count) {
if (slot < sorted.size()) {
SubsetTag tag = sorted.get(slot);
if (NEIClientUtils.shiftKey())
codechicken.nei.LayoutManager.searchField.setText("@" + tag.fullname);
else if (button == 0 && count >= 2) SubsetWidget.showOnly(tag);
else SubsetWidget.setHidden(tag, button == 1);
if (NEIClientUtils.shiftKey()) {
codechicken.nei.LayoutManager.searchField.setText("%" + tag.fullname);
} else if (button == 0 && count >= 2) {
SubsetWidget.showOnly(tag);
} else {
SubsetWidget.setHidden(tag, button == 1);
}
} else {
ItemStack item = state.items.get(slot - sorted.size());
if (NEIClientUtils.controlKey()) NEIClientUtils.cheatItem(item, button, -1);
else SubsetWidget.setHidden(state.items.get(slot - sorted.size()), button == 1);
if (NEIClientUtils.controlKey()) {
NEIClientUtils.cheatItem(item, button, -1);
} else {
SubsetWidget.setHidden(state.items.get(slot - sorted.size()), button == 1);
}
}
}
@@ -170,7 +177,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoa
private SubsetTag getTag(String name) {
int idx = name.indexOf('.');
String childname = idx > 0 ? name.substring(0, idx) : name;
SubsetTag child = children.get(childname.toLowerCase());
SubsetTag child = children.get(childname.replaceAll(" ", "").toLowerCase());
if (child == null) return null;
return idx > 0 ? child.getTag(name.substring(idx + 1)) : child;
@@ -187,7 +194,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoa
int idx = name.indexOf('.');
if (idx < 0) { // add or replace tag
SubsetTag prev = children.put(name.toLowerCase(), tag);
SubsetTag prev = children.put(name.replaceAll(" ", "").toLowerCase(), tag);
if (prev != null) { // replaced, load children
tag.children = prev.children;
tag.sorted = prev.sorted;
@@ -195,10 +202,12 @@ public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoa
recacheChildren();
} else {
String childname = name.substring(0, idx);
SubsetTag child = children.get(childname.toLowerCase());
if (child == null) children.put(
childname.toLowerCase(),
child = new SubsetTag(fullname == null ? childname : fullname + '.' + childname));
SubsetTag child = children.get(childname.replaceAll(" ", "").toLowerCase());
if (child == null) {
children.put(
childname.replaceAll(" ", "").toLowerCase(),
child = new SubsetTag(fullname == null ? childname : fullname + '.' + childname));
}
recacheChildren();
child.addTag(tag);
}
@@ -209,16 +218,6 @@ public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoa
for (SubsetTag tag : sorted) tag.cacheState();
}
public void addFiltersWithItem(List<ItemFilter> filters, String itemSearch) {
if (itemSearch == null) {
addFilters(filters);
} else {
if (filter != null) filters.add(new DoubleFilteredFilter(filter, itemSearch));
for (SubsetTag child : sorted) child.addFiltersWithItem(filters, itemSearch);
}
}
public void addFilters(List<ItemFilter> filters) {
if (filter != null) filters.add(filter);
@@ -356,6 +355,45 @@ public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoa
}
}
private static class DefaultParserProvider implements ISearchParserProvider {
public ItemFilter getFilter(String searchText) {
final AnyMultiItemFilter filter = new AnyMultiItemFilter();
final SubsetTag tag = getTag(searchText);
if (tag != null) {
// We've got an exact match
tag.addFilters(filter.filters);
} else {
// Try searching for a substring
Pattern p = SearchField.getPattern(searchText);
if (p == null) return null;
List<SubsetTag> matching = new LinkedList<>();
root.search(matching, p);
if (matching.isEmpty()) return null;
for (SubsetTag tag2 : matching) {
tag2.addFilters(filter.filters);
}
}
return filter;
}
public char getPrefix() {
return '%';
}
public EnumChatFormatting getHighlightedColor() {
return EnumChatFormatting.DARK_PURPLE;
}
@Override
public SearchMode getSearchMode() {
return SearchMode.fromInt(NEIClientConfig.getIntSetting("inventory.search.subsetsSearchMode"));
}
}
protected static final SubsetTag root = new SubsetTag(null);
public static Rectangle4i area = new Rectangle4i();
public static ItemStack hoverStack;
@@ -659,7 +697,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoa
public SubsetWidget() {
super("NEI Subsets");
API.addItemFilter(this);
API.addSearchProvider(this);
API.addSearchProvider(new DefaultParserProvider());
ItemList.loadCallbacks.add(this);
}
@@ -774,44 +812,6 @@ public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoa
};
}
@Override
public boolean isPrimary() {
return true;
}
@Override
public ItemFilter getFilter(String searchText) {
if (!searchText.startsWith("@")) return null;
searchText = searchText.substring(1);
String itemSearch = null;
if (searchText.contains("->")) {
String[] split = searchText.split("->");
searchText = split[0];
if (split.length > 1) itemSearch = split[1];
}
AnyMultiItemFilter filter = new AnyMultiItemFilter();
SubsetTag tag = getTag(searchText);
if (tag != null) {
// We've got an exact match
tag.addFiltersWithItem(filter.filters, itemSearch);
} else {
// Try searching for a substring
Pattern p = SearchField.getPattern(searchText);
if (p == null) return null;
List<SubsetTag> matching = new LinkedList<>();
root.search(matching, p);
if (matching.isEmpty()) return null;
for (SubsetTag tag2 : matching) {
tag2.addFiltersWithItem(filter.filters, itemSearch);
}
}
return filter;
}
@Override
public void itemsLoaded() {
updateState.reallocate();
+1 -1
View File
@@ -9,7 +9,7 @@ public abstract class TextField extends Widget {
protected GuiTextField field;
private static final int maxSearchLength = 256;
protected static final int maxSearchLength = 256;
public boolean centered;
public String identifier;
+6 -2
View File
@@ -25,6 +25,7 @@ import codechicken.nei.NEIClientConfig;
import codechicken.nei.OffsetPositioner;
import codechicken.nei.SearchField;
import codechicken.nei.SearchField.ISearchProvider;
import codechicken.nei.SearchTokenParser.ISearchParserProvider;
import codechicken.nei.SubsetWidget;
import codechicken.nei.SubsetWidget.SubsetTag;
import codechicken.nei.api.IRecipeFilter.IRecipeFilterProvider;
@@ -314,11 +315,14 @@ public class API {
SubsetWidget.addTag(tag);
}
@Deprecated
public static void addSearchProvider(ISearchProvider provider) {}
/**
* Adds a new search provider to the search field
*/
public static void addSearchProvider(ISearchProvider provider) {
SearchField.searchProviders.add(provider);
public static void addSearchProvider(ISearchParserProvider provider) {
SearchField.searchParser.addProvider(provider);
}
/**
+51 -51
View File
@@ -6,7 +6,6 @@ import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import net.minecraft.block.Block;
import net.minecraft.client.resources.I18n;
@@ -45,11 +44,14 @@ import codechicken.core.featurehack.GameDataManipulator;
import codechicken.nei.InfiniteStackSizeHandler;
import codechicken.nei.InfiniteToolHandler;
import codechicken.nei.ItemList;
import codechicken.nei.ItemList.PatternItemFilter;
import codechicken.nei.ItemMobSpawner;
import codechicken.nei.ItemStackMap;
import codechicken.nei.ItemStackSet;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.PopupInputHandler;
import codechicken.nei.SearchField.SearchParserProvider;
import codechicken.nei.SearchTokenParser.SearchMode;
import codechicken.nei.config.ArrayDumper;
import codechicken.nei.config.HandlerDumper;
import codechicken.nei.config.ItemPanelDumper;
@@ -57,6 +59,10 @@ import codechicken.nei.config.RegistryDumper;
import codechicken.nei.guihook.GuiContainerManager;
import codechicken.nei.recipe.BrewingRecipeHandler;
import codechicken.nei.recipe.RecipeItemInputHandler;
import codechicken.nei.search.IdentifierFilter;
import codechicken.nei.search.ModNameFilter;
import codechicken.nei.search.OreDictionaryFilter;
import codechicken.nei.search.TooltipFilter;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.registry.GameRegistry;
@@ -86,36 +92,6 @@ public class ItemInfo {
public static final HashMap<Item, String> itemOwners = new HashMap<>();
private static class ItemStackKey {
public final ItemStack stack;
public ItemStackKey(ItemStack stack) {
this.stack = stack;
}
@Override
public int hashCode() {
if (this.stack == null) return 1;
int hashCode = 1;
hashCode = 31 * hashCode + stack.stackSize;
hashCode = 31 * hashCode + Item.getIdFromItem(stack.getItem());
hashCode = 31 * hashCode + stack.getItemDamage();
hashCode = 31 * hashCode + (!stack.hasTagCompound() ? 0 : stack.getTagCompound().hashCode());
return hashCode;
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof ItemStackKey)) return false;
return ItemStack.areItemStacksEqual(this.stack, ((ItemStackKey) o).stack);
}
}
// lookup optimisation
public static final ConcurrentHashMap<ItemStackKey, String> itemSearchNames = new ConcurrentHashMap<>();
public static boolean isHidden(ItemStack stack) {
return hiddenItems.contains(stack);
}
@@ -155,28 +131,54 @@ public class ItemInfo {
addInputHandlers();
addIDDumps();
addHiddenItemFilter();
addSearchOptimisation();
}
private static void addSearchOptimisation() {
ItemList.loadCallbacks.add(ItemInfo::populateSearchMap);
}
private static void populateSearchMap() {
/* Create a snapshot of the current keys in the cache */
HashSet<ItemStackKey> oldItems = new HashSet<>(itemSearchNames.keySet());
for (ItemStack stack : ItemList.items) {
/* Populate each entry and remove it from the snapshot */
getSearchName(stack);
oldItems.remove(new ItemStackKey(stack));
}
itemSearchNames.keySet().removeAll(oldItems);
addSearchProviders();
ItemList.loadCallbacks.add(TooltipFilter::populateSearchMap);
}
private static void addHiddenItemFilter() {
API.addItemFilter(() -> item -> !hiddenItems.contains(item));
}
private static void addSearchProviders() {
API.addSearchProvider(
new SearchParserProvider(
'\0',
"default",
EnumChatFormatting.RESET,
(pattern) -> new PatternItemFilter(pattern)) {
@Override
public SearchMode getSearchMode() {
return SearchMode.ALWAYS;
}
});
API.addSearchProvider(
new SearchParserProvider(
'@',
"modName",
EnumChatFormatting.LIGHT_PURPLE,
(pattern) -> new ModNameFilter(pattern)));
API.addSearchProvider(
new SearchParserProvider(
'$',
"oreDict",
EnumChatFormatting.AQUA,
(pattern) -> new OreDictionaryFilter(pattern)));
API.addSearchProvider(
new SearchParserProvider(
'#',
"tooltip",
EnumChatFormatting.YELLOW,
(pattern) -> new TooltipFilter(pattern)));
API.addSearchProvider(
new SearchParserProvider(
'&',
"identifier",
EnumChatFormatting.GOLD,
(pattern) -> new IdentifierFilter(pattern)));
}
private static void addIDDumps() {
API.addOption(new RegistryDumper<Item>("tools.dump.item") {
@@ -516,10 +518,8 @@ public class ItemInfo {
return retString;
}
@Deprecated
public static String getSearchName(ItemStack stack) {
return itemSearchNames.computeIfAbsent(
new ItemStackKey(stack),
key -> EnumChatFormatting.getTextWithoutFormattingCodes(
GuiContainerManager.concatenatedDisplayName(key.stack, true).toLowerCase()));
return GuiContainerManager.concatenatedDisplayName(stack, true);
}
}
@@ -11,6 +11,7 @@ import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.StringJoiner;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.regex.Pattern;
@@ -133,6 +134,7 @@ public class GuiContainerManager {
* @param includeHandlers If true tooltip handlers will add to the item tip
* @return A list of Strings representing the text to be displayed on each line of the tool tip.
*/
@SuppressWarnings("unchecked")
public static List<String> itemDisplayNameMultiline(ItemStack stack, GuiContainer gui, boolean includeHandlers) {
List<String> namelist = null;
try {
@@ -218,8 +220,18 @@ public class GuiContainerManager {
* @return The first line of the multiline display name.
*/
public static String itemDisplayNameShort(ItemStack itemstack) {
List<String> list = itemDisplayNameMultiline(itemstack, null, false);
return list.get(0);
try {
@SuppressWarnings("unchecked")
List<String> namelist = itemstack.getTooltip(Minecraft.getMinecraft().thePlayer, false);
if (!namelist.isEmpty() && !"".equals(namelist.get(0))) {
return itemstack.getRarity().rarityColor.toString() + namelist.get(0) + EnumChatFormatting.RESET;
}
} catch (Throwable ignored) {}
return "Unnamed";
}
/**
@@ -229,18 +241,17 @@ public class GuiContainerManager {
* @param itemstack The stack to get the name for
* @return The multiline display name of this item separated by '#'
*/
@Deprecated
public static String concatenatedDisplayName(ItemStack itemstack, boolean includeHandlers) {
List<String> list = itemDisplayNameMultiline(itemstack, null, includeHandlers);
StringBuilder sb = new StringBuilder();
boolean first = true;
StringJoiner sb = new StringJoiner("#");
for (String name : list) {
if (first) {
first = false;
} else {
sb.append("#");
if (!name.isEmpty()) {
sb.add(name);
}
sb.append(name);
}
return EnumChatFormatting.getTextWithoutFormattingCodes(sb.toString());
}
@@ -11,7 +11,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import net.minecraft.client.gui.GuiButton;
@@ -22,8 +21,6 @@ import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.renderer.RenderHelper;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraftforge.fluids.FluidStack;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.GL11;
@@ -38,6 +35,7 @@ import codechicken.nei.NEIClientUtils;
import codechicken.nei.PositionedStack;
import codechicken.nei.RecipeSearchField;
import codechicken.nei.RestartableTask;
import codechicken.nei.SearchField;
import codechicken.nei.VisiblityData;
import codechicken.nei.api.IGuiContainerOverlay;
import codechicken.nei.api.INEIGuiHandler;
@@ -1212,25 +1210,13 @@ public abstract class GuiRecipe<H extends IRecipeHandler> extends GuiContainer i
public boolean handleDragNDrop(GuiContainer gui, int mousex, int mousey, ItemStack draggedStack, int button) {
if (searchField.isVisible() && searchField.contains(mousex - guiLeft, mousey - guiTop)) {
final FluidStack fluidStack = StackInfo.getFluid(draggedStack);
if (fluidStack != null) {
searchField.setText(formattingText(fluidStack.getLocalizedName()));
} else {
searchField.setText(formattingText(draggedStack.getDisplayName()));
}
searchField.setText(SearchField.getEscapedSearchText(draggedStack));
return true;
}
return false;
}
protected String formattingText(String displayName) {
return Pattern.compile("[{}()\\[\\].+*?^$\\\\|]")
.matcher(EnumChatFormatting.getTextWithoutFormattingCodes(displayName)).replaceAll("\\\\$0");
}
@Override
public boolean hideItemPanelSlot(GuiContainer gui, int x, int y, int w, int h) {
// Because some of the handlers *cough avaritia* are oversized
@@ -4,8 +4,8 @@ import static codechicken.nei.LayoutManager.searchField;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.item.ItemStack;
import net.minecraftforge.fluids.FluidStack;
import codechicken.nei.SearchField;
import codechicken.nei.api.INEIGuiAdapter;
public class SearchInputDropHandler extends INEIGuiAdapter {
@@ -14,14 +14,7 @@ public class SearchInputDropHandler extends INEIGuiAdapter {
public boolean handleDragNDrop(GuiContainer gui, int mouseX, int mouseY, ItemStack draggedStack, int button) {
if (searchField.isVisible() && searchField.contains(mouseX, mouseY)) {
final FluidStack fluidStack = StackInfo.getFluid(draggedStack);
if (fluidStack != null) {
searchField.setText(formattingText(fluidStack.getLocalizedName()));
} else {
searchField.setText(formattingText(draggedStack.getDisplayName()));
}
searchField.setText(SearchField.getEscapedSearchText(draggedStack));
return true;
}
@@ -0,0 +1,33 @@
package codechicken.nei.search;
import java.util.regex.Pattern;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import codechicken.nei.api.ItemFilter;
import cpw.mods.fml.common.registry.GameData;
public class IdentifierFilter implements ItemFilter {
private final Pattern pattern;
public IdentifierFilter(Pattern pattern) {
this.pattern = pattern;
}
@Override
public boolean matches(ItemStack stack) {
return this.pattern.matcher(getStringIdentifier(stack) + "\n" + getIdentifier(stack)).find();
}
protected String getIdentifier(ItemStack stack) {
return Item.getIdFromItem(stack.getItem()) + ":" + stack.getItemDamage();
}
protected String getStringIdentifier(ItemStack stack) {
String name = GameData.getItemRegistry().getNameForObject(stack.getItem());
return name == null || name.isEmpty() ? "Unknown:Unknown" : name;
}
}
@@ -0,0 +1,53 @@
package codechicken.nei.search;
import java.util.regex.Pattern;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.api.ItemInfo;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.registry.GameRegistry;
import cpw.mods.fml.common.registry.GameRegistry.UniqueIdentifier;
public class ModNameFilter implements ItemFilter {
private final Pattern pattern;
public ModNameFilter(Pattern pattern) {
this.pattern = pattern;
}
@Override
public boolean matches(ItemStack itemStack) {
return this.pattern.matcher(nameFromStack(itemStack.getItem())).find();
}
protected static String nameFromStack(Item item) {
try {
ModContainer mod = Loader.instance().getIndexedModList().get(getModId(item));
return mod == null ? "Minecraft" : mod.getName();
} catch (NullPointerException e) {
return "";
}
}
protected static String getModId(Item item) {
if (!ItemInfo.itemOwners.containsKey(item)) {
try {
UniqueIdentifier ident = GameRegistry.findUniqueIdentifierFor(item);
ItemInfo.itemOwners.put(item, ident.modId);
} catch (Exception ignored) {
NEIClientConfig.logger.error("Failed to find identifier for: " + item);
ItemInfo.itemOwners.put(item, "Unknown");
}
}
return ItemInfo.itemOwners.get(item);
}
}
@@ -0,0 +1,25 @@
package codechicken.nei.search;
import java.util.regex.Pattern;
import java.util.stream.IntStream;
import net.minecraft.item.ItemStack;
import net.minecraftforge.oredict.OreDictionary;
import codechicken.nei.api.ItemFilter;
public class OreDictionaryFilter implements ItemFilter {
private final Pattern pattern;
public OreDictionaryFilter(Pattern pattern) {
this.pattern = pattern;
}
@Override
public boolean matches(ItemStack stack) {
return IntStream.of(OreDictionary.getOreIDs(stack))
.anyMatch(id -> this.pattern.matcher(OreDictionary.getOreName(id)).find());
}
}
@@ -0,0 +1,87 @@
package codechicken.nei.search;
import java.util.HashSet;
import java.util.List;
import java.util.StringJoiner;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import codechicken.nei.ItemList;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.guihook.GuiContainerManager;
public class TooltipFilter implements ItemFilter {
// lookup optimisation
private static final ConcurrentHashMap<ItemStackKey, String> itemSearchNames = new ConcurrentHashMap<>();
private static class ItemStackKey {
public final ItemStack stack;
public ItemStackKey(ItemStack stack) {
this.stack = stack;
}
@Override
public int hashCode() {
if (this.stack == null) return 1;
int hashCode = 1;
hashCode = 31 * hashCode + stack.stackSize;
hashCode = 31 * hashCode + Item.getIdFromItem(stack.getItem());
hashCode = 31 * hashCode + stack.getItemDamage();
hashCode = 31 * hashCode + (!stack.hasTagCompound() ? 0 : stack.getTagCompound().hashCode());
return hashCode;
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof ItemStackKey)) return false;
return ItemStack.areItemStacksEqual(this.stack, ((ItemStackKey) o).stack);
}
}
private final Pattern pattern;
public TooltipFilter(Pattern pattern) {
this.pattern = pattern;
}
@Override
public boolean matches(ItemStack itemStack) {
return pattern.matcher(getSearchTooltip(itemStack)).find();
}
public static void populateSearchMap() {
/* Create a snapshot of the current keys in the cache */
HashSet<ItemStackKey> oldItems = new HashSet<>(itemSearchNames.keySet());
for (ItemStack stack : ItemList.items) {
oldItems.remove(new ItemStackKey(stack));
}
itemSearchNames.keySet().removeAll(oldItems);
}
protected static String getSearchTooltip(ItemStack stack) {
return itemSearchNames.computeIfAbsent(new ItemStackKey(stack), key -> getTooltip(key.stack));
}
private static String getTooltip(ItemStack itemstack) {
final List<String> list = GuiContainerManager.itemDisplayNameMultiline(itemstack, null, true);
final StringJoiner sb = new StringJoiner("\n");
final int size = list.size();
for (int i = 1; i < size; i++) {
sb.add(list.get(i));
}
return EnumChatFormatting.getTextWithoutFormattingCodes(sb.toString());
}
}
@@ -96,10 +96,10 @@ nei.options.inventory.itemIDs=IDčka předmětů
nei.options.inventory.itemIDs.0=Skryté
nei.options.inventory.itemIDs.1=Automatické
nei.options.inventory.itemIDs.2=Zobrazené
nei.options.inventory.searchmode=Vyhledavací mód
nei.options.inventory.searchmode.0=Prostý
nei.options.inventory.searchmode.1=Rozšířený
nei.options.inventory.searchmode.2=Regexy
nei.options.inventory.search.patternMode=Vyhledavací mód
nei.options.inventory.search.patternMode.0=Prostý
nei.options.inventory.search.patternMode.1=Rozšířený
nei.options.inventory.search.patternMode.2=Regexy
nei.options.inventory.utilities=Nástroje
nei.options.inventory.utilities.tip=Vyber doplňky pro mód nástrojů
nei.options.inventory.utilities.time=Čas
@@ -100,10 +100,10 @@ nei.options.inventory.itemIDs=Item-IDs
nei.options.inventory.itemIDs.0=Versteckt
nei.options.inventory.itemIDs.1=Auto
nei.options.inventory.itemIDs.2=Gezeigt
nei.options.inventory.searchmode=Suchmodus
nei.options.inventory.searchmode.0=Gewöhnlich
nei.options.inventory.searchmode.1=Erweitert
nei.options.inventory.searchmode.2=Regex
nei.options.inventory.search.patternMode=Suchmodus
nei.options.inventory.search.patternMode.0=Gewöhnlich
nei.options.inventory.search.patternMode.1=Erweitert
nei.options.inventory.search.patternMode.2=Regex
nei.options.inventory.utilities=Nützliches
nei.options.inventory.utilities.tip=Wähle Inhalte für den Mehrzweckmodus
nei.options.inventory.utilities.time=Zeit
+34 -10
View File
@@ -176,12 +176,40 @@ nei.options.inventory.showRecipeMarker.false=No
nei.options.inventory.showItemQuantityWidget=Show Item Quantity Widget
nei.options.inventory.showItemQuantityWidget.true=Yes
nei.options.inventory.showItemQuantityWidget.false=No
nei.options.inventory.centerSearchWidget=Center Search Widget
nei.options.inventory.centerSearchWidget.true=Yes
nei.options.inventory.centerSearchWidget.false=No
nei.options.inventory.focusSearchWidgetOnOpen=Focus Search Widget on Open
nei.options.inventory.focusSearchWidgetOnOpen.true=Yes
nei.options.inventory.focusSearchWidgetOnOpen.false=No
nei.options.inventory.search=Search Widget
nei.options.inventory.search.widgetPosition=Widget Position
nei.options.inventory.search.widgetPosition.true=Center
nei.options.inventory.search.widgetPosition.false=Right
nei.options.inventory.search.widgetAutofocus=Autofocus
nei.options.inventory.search.widgetAutofocus.true=Yes
nei.options.inventory.search.widgetAutofocus.false=No
nei.options.inventory.search.patternMode=Search Mode
nei.options.inventory.search.patternMode.0=Plain
nei.options.inventory.search.patternMode.1=Extended
nei.options.inventory.search.patternMode.2=Regex
nei.options.inventory.search.quoteDropItemName=Quote Drop Item Name
nei.options.inventory.search.quoteDropItemName.true=Yes
nei.options.inventory.search.quoteDropItemName.false=No
nei.options.inventory.search.modNameSearchMode=Mod Name Search
nei.options.inventory.search.modNameSearchMode.0=Always
nei.options.inventory.search.modNameSearchMode.1=Prefix: %s
nei.options.inventory.search.modNameSearchMode.2=Never
nei.options.inventory.search.tooltipSearchMode=Tooltip Search
nei.options.inventory.search.tooltipSearchMode.0=Always
nei.options.inventory.search.tooltipSearchMode.1=Prefix: %s
nei.options.inventory.search.tooltipSearchMode.2=Never
nei.options.inventory.search.identifierSearchMode=Resource ID Search
nei.options.inventory.search.identifierSearchMode.0=Always
nei.options.inventory.search.identifierSearchMode.1=Prefix: %s
nei.options.inventory.search.identifierSearchMode.2=Never
nei.options.inventory.search.oreDictSearchMode=OreDict Search
nei.options.inventory.search.oreDictSearchMode.0=Always
nei.options.inventory.search.oreDictSearchMode.1=Prefix: %s
nei.options.inventory.search.oreDictSearchMode.2=Never
nei.options.inventory.search.subsetsSearchMode=Item Subsets Search
nei.options.inventory.search.subsetsSearchMode.0=Always
nei.options.inventory.search.subsetsSearchMode.1=Prefix: %s
nei.options.inventory.search.subsetsSearchMode.2=Never
nei.options.inventory.firstInvCloseClosesInSearch=First Inventory Close Closes in Search
nei.options.inventory.firstInvCloseClosesInSearch.true=Yes
nei.options.inventory.firstInvCloseClosesInSearch.false=No
@@ -213,10 +241,6 @@ nei.options.inventory.itemIDs=Item IDs
nei.options.inventory.itemIDs.0=Hidden
nei.options.inventory.itemIDs.1=Auto
nei.options.inventory.itemIDs.2=Shown
nei.options.inventory.searchmode=Search Mode
nei.options.inventory.searchmode.0=Plain
nei.options.inventory.searchmode.1=Extended
nei.options.inventory.searchmode.2=Regex
nei.options.inventory.utilities=Utilities
nei.options.inventory.utilities.tip=Select features for utility mode
nei.options.inventory.utilities.time=Time
@@ -99,10 +99,10 @@ nei.options.inventory.itemIDs=Asja ID-d
nei.options.inventory.itemIDs.0=Peidetud
nei.options.inventory.itemIDs.1=Auto
nei.options.inventory.itemIDs.2=Näidatud
nei.options.inventory.searchmode=Otsimis mood
nei.options.inventory.searchmode.0=Plain
nei.options.inventory.searchmode.1=Extended
nei.options.inventory.searchmode.2=Regex
nei.options.inventory.search.patternMode=Otsimis mood
nei.options.inventory.search.patternMode.0=Plain
nei.options.inventory.search.patternMode.1=Extended
nei.options.inventory.search.patternMode.2=Regex
nei.options.inventory.utilities=Utiliidid
nei.options.inventory.utilities.tip=Vali funktsioonid utiliidi moodi jaoks
nei.options.inventory.utilities.time=Aeg
@@ -97,10 +97,10 @@ nei.options.inventory.itemIDs=Objet IDs
nei.options.inventory.itemIDs.0=Cachés
nei.options.inventory.itemIDs.1=Auto
nei.options.inventory.itemIDs.2=Montrés
nei.options.inventory.searchmode=Mode de recherche
nei.options.inventory.searchmode.0=Simple
nei.options.inventory.searchmode.1=Avancé
nei.options.inventory.searchmode.2=Expression rationnelle
nei.options.inventory.search.patternMode=Mode de recherche
nei.options.inventory.search.patternMode.0=Simple
nei.options.inventory.search.patternMode.1=Avancé
nei.options.inventory.search.patternMode.2=Expression rationnelle
nei.options.inventory.utilities=Utilitaires
nei.options.inventory.utilities.tip=Sélectionnez les fonctions pour le mode utilitaire
nei.options.inventory.utilities.time=Heure
@@ -100,10 +100,10 @@ nei.options.inventory.itemIDs=ID degli oggetti
nei.options.inventory.itemIDs.0=Nascosti
nei.options.inventory.itemIDs.1=Auto
nei.options.inventory.itemIDs.2=Mostrati
nei.options.inventory.searchmode=Modalità di ricerca
nei.options.inventory.searchmode.0=Piatto
nei.options.inventory.searchmode.1=Esteso
nei.options.inventory.searchmode.2=Regex
nei.options.inventory.search.patternMode=Modalità di ricerca
nei.options.inventory.search.patternMode.0=Piatto
nei.options.inventory.search.patternMode.1=Esteso
nei.options.inventory.search.patternMode.2=Regex
nei.options.inventory.utilities=Utilità
nei.options.inventory.utilities.tip=Seleziona funzioni per modalità utilità
nei.options.inventory.utilities.time=Tempo
@@ -219,4 +219,4 @@ nei.subsets.Items.Tools.Shovels=Pale
nei.subsets.Items.Weapons=Armi
nei.subsets.Items.Weapons.Ranged=Da lancio
nei.subsets.Items.Weapons.Swords=Spade
nei.subsets.Mod=Mod
nei.subsets.Mod=Mod
@@ -95,10 +95,10 @@ nei.options.inventory.itemIDs=아이템 ID
nei.options.inventory.itemIDs.0= 숨기기
nei.options.inventory.itemIDs.1=자동
nei.options.inventory.itemIDs.2=보이기
nei.options.inventory.searchmode=검색모드
nei.options.inventory.searchmode.0=모두
nei.options.inventory.searchmode.1=확장
nei.options.inventory.searchmode.2=정규표현식
nei.options.inventory.search.patternMode=검색모드
nei.options.inventory.search.patternMode.0=모두
nei.options.inventory.search.patternMode.1=확장
nei.options.inventory.search.patternMode.2=정규표현식
nei.options.inventory.utilities=유틸리티
nei.options.inventory.utilities.tip=유틸리티 모드기능을 선택
nei.options.inventory.utilities.time=시간
@@ -97,10 +97,10 @@ nei.options.inventory.itemIDs=ID przedmiotów
nei.options.inventory.itemIDs.0=Ukryte
nei.options.inventory.itemIDs.1=Automatyczne
nei.options.inventory.itemIDs.2=Pokazane
nei.options.inventory.searchmode=Tryb wyszukiwania
nei.options.inventory.searchmode.0=Prosty
nei.options.inventory.searchmode.1=Rozszerzony
nei.options.inventory.searchmode.2=Wyrażenia regularne
nei.options.inventory.search.patternMode=Tryb wyszukiwania
nei.options.inventory.search.patternMode.0=Prosty
nei.options.inventory.search.patternMode.1=Rozszerzony
nei.options.inventory.search.patternMode.2=Wyrażenia regularne
nei.options.inventory.utilities=Narzędzia
nei.options.inventory.utilities.tip=Wybierz cechy trybu użytkowego
nei.options.inventory.utilities.time=Czas
@@ -97,10 +97,10 @@ nei.options.inventory.itemIDs=IDs de Itens
nei.options.inventory.itemIDs.0=Escondido
nei.options.inventory.itemIDs.1=Auto
nei.options.inventory.itemIDs.2=Mostrado
nei.options.inventory.searchmode=Modo de Pesquisa
nei.options.inventory.searchmode.0=Plano
nei.options.inventory.searchmode.1=Extendido
nei.options.inventory.searchmode.2=Regex
nei.options.inventory.search.patternMode=Modo de Pesquisa
nei.options.inventory.search.patternMode.0=Plano
nei.options.inventory.search.patternMode.1=Extendido
nei.options.inventory.search.patternMode.2=Regex
nei.options.inventory.utilities=Utilidades
nei.options.inventory.utilities.tip=Selecionar funções para o modo utilidade
nei.options.inventory.utilities.time=Tempo
@@ -100,10 +100,10 @@ nei.options.inventory.itemIDs=ID предметов
nei.options.inventory.itemIDs.0=Спрятаны
nei.options.inventory.itemIDs.1=Авто
nei.options.inventory.itemIDs.2=Показаны
nei.options.inventory.searchmode=Режим поиска
nei.options.inventory.searchmode.0=Обычный
nei.options.inventory.searchmode.1=Расширенный
nei.options.inventory.searchmode.2=Регулярные выражения
nei.options.inventory.search.patternMode=Режим поиска
nei.options.inventory.search.patternMode.0=Обычный
nei.options.inventory.search.patternMode.1=Расширенный
nei.options.inventory.search.patternMode.2=Регулярные выражения
nei.options.inventory.utilities=Полезности
nei.options.inventory.utilities.tip=Выберете функции для режима полезностей
nei.options.inventory.utilities.time=Время
@@ -97,10 +97,10 @@ nei.options.inventory.itemIDs=ID itemov
nei.options.inventory.itemIDs.0=Skryté
nei.options.inventory.itemIDs.1=Automatické
nei.options.inventory.itemIDs.2=Zobrazené
nei.options.inventory.searchmode=Spôsob vyhľadávania
nei.options.inventory.searchmode.0=Jednoduchý
nei.options.inventory.searchmode.1=Rozšírený
nei.options.inventory.searchmode.2=Regulárne výrazy
nei.options.inventory.search.patternMode=Spôsob vyhľadávania
nei.options.inventory.search.patternMode.0=Jednoduchý
nei.options.inventory.search.patternMode.1=Rozšírený
nei.options.inventory.search.patternMode.2=Regulárne výrazy
nei.options.inventory.utilities=Utility
nei.options.inventory.utilities.tip=Zvoľ funkcie pre úžitkový mód
nei.options.inventory.utilities.time=Čas
@@ -19,14 +19,14 @@ nei.inventory.delete.0=Silme modunu kapat
nei.inventory.rain.enable=Yağmuru Aktif Et
nei.inventory.rain.1=Yağmur yağdır
nei.inventory.rain.0=Yağmuru durdur
nei.inventory.magnet.enable=Mıknatısı aktif et
nei.inventory.magnet.enable=Mıknatısı aktif et
nei.inventory.magnet.1=Mıknatısı aç
nei.inventory.magnet.0=Mıknatısı kapat
nei.inventory.dawn.enable=Sabah-Öğle aktif et
nei.inventory.dawn.set=Sabah yap
nei.inventory.noon.enable=Öğlen-akşam aktif et
nei.inventory.noon.set=Öğlen yap
nei.inventory.dusk.enable=Akşam-Gece aktif et
nei.inventory.dusk.enable=Akşam-Gece aktif et
nei.inventory.dusk.set=Akşam yap
nei.inventory.midnight.enable=Gece-Sabah aktif et
nei.inventory.midnight.set=Gece yarısı yap
@@ -97,10 +97,10 @@ nei.options.inventory.itemIDs=Item IDleri
nei.options.inventory.itemIDs.0=Gizli
nei.options.inventory.itemIDs.1=Otomatik
nei.options.inventory.itemIDs.2=Göster
nei.options.inventory.searchmode=Arama Modu
nei.options.inventory.searchmode.0=Normal
nei.options.inventory.searchmode.1=Gelişmiş
nei.options.inventory.searchmode.2=Regex
nei.options.inventory.search.patternMode=Arama Modu
nei.options.inventory.search.patternMode.0=Normal
nei.options.inventory.search.patternMode.1=Gelişmiş
nei.options.inventory.search.patternMode.2=Regex
nei.options.inventory.utilities=Yardımcılar
nei.options.inventory.utilities.tip=Yardımcıları seç
nei.options.inventory.utilities.time=Saat
@@ -152,7 +152,7 @@ nei.options.tools.dump.enchantments=Büyüler
nei.options.tools.dump.biome=Biyom
nei.options.tools.dump.biomes=Biyomlar
nei.options.tools.dump.itempanel=Item Paneli
nei.options.tools.dump.itempanel.dumped=Item panelinden %s kadar silindi
nei.options.tools.dump.itempanel.dumped=Item panelinden %s kadar silindi
nei.options.tools.dump.itempanel.mode.0=CSV
nei.options.tools.dump.itempanel.mode.1=NBT
nei.options.tools.dump.itempanel.mode.2=Json
@@ -174,10 +174,10 @@ nei.options.inventory.itemIDs=物品ID
nei.options.inventory.itemIDs.0=隐藏
nei.options.inventory.itemIDs.1=自动
nei.options.inventory.itemIDs.2=显示
nei.options.inventory.searchmode=搜索模式
nei.options.inventory.searchmode.0=简单
nei.options.inventory.searchmode.1=扩展
nei.options.inventory.searchmode.2=正则表达式
nei.options.inventory.search.patternMode=搜索模式
nei.options.inventory.search.patternMode.0=简单
nei.options.inventory.search.patternMode.1=扩展
nei.options.inventory.search.patternMode.2=正则表达式
nei.options.inventory.utilities=按钮
nei.options.inventory.utilities.tip=选择实用模式的功能
nei.options.inventory.utilities.time=时间
@@ -96,10 +96,10 @@ nei.options.inventory.itemIDs=物品ID
nei.options.inventory.itemIDs.0=隱藏
nei.options.inventory.itemIDs.1=自動
nei.options.inventory.itemIDs.2=顯示
nei.options.inventory.searchmode=搜索模式
nei.options.inventory.searchmode.0=簡單
nei.options.inventory.searchmode.1=擴展
nei.options.inventory.searchmode.2=正則表達式
nei.options.inventory.search.patternMode=搜索模式
nei.options.inventory.search.patternMode.0=簡單
nei.options.inventory.search.patternMode.1=擴展
nei.options.inventory.search.patternMode.2=正則表達式
nei.options.inventory.utilities=按鈕
nei.options.inventory.utilities.tip=選擇實用模式的功能
nei.options.inventory.utilities.time=時間
@@ -176,7 +176,7 @@ nei.recipe.profiler.crafting=合成查詢性能分析
nei.recipe.profiler.usage=用途查詢性能分析
nei.itemsort.minecraft=Minecraft
nei.itemsort.minecraft.tip=從原版物品開始排序
nei.itemsort.minecraft.tip=從原版物品開始排序
nei.itemsort.mod=Mod
nei.itemsort.mod.tip=將每一個mod分為一組,按照mod名稱排序
nei.itemsort.id=按物品ID排序