mirror of
https://github.com/GTNewHorizons/NotEnoughItems.git
synced 2026-11-15 09:44:44 +00:00
Compare commits
10
Commits
mu
...
2.6.29-GTNH-pre
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
680cf509e9 | ||
|
|
3c14adb7cc | ||
|
|
9fd16c69d7 | ||
|
|
77cb90bdc4 | ||
|
|
088e3dc0c5 | ||
|
|
9feb9d72ce | ||
|
|
87f71b6ef9 | ||
|
|
a9e069166f | ||
|
|
2f7927fe21 | ||
|
|
3e1baa4ded |
No files matched your search
+1
-1
@@ -41,7 +41,7 @@ developmentEnvironmentUserName = Developer
|
||||
|
||||
# Enables using modern Java syntax (up to version 17) via Jabel, while still targeting JVM 8.
|
||||
# See https://github.com/bsideup/jabel for details on how this works.
|
||||
enableModernJavaSyntax = false
|
||||
enableModernJavaSyntax = true
|
||||
|
||||
# Enables injecting missing generics into the decompiled source code for a better coding experience.
|
||||
# Turns most publicly visible List, Map, etc. into proper List<E>, Map<K, V> types.
|
||||
|
||||
@@ -1764,7 +1764,12 @@ public class BookmarkPanel extends PanelWidget {
|
||||
return namespaces.size();
|
||||
}
|
||||
|
||||
public void setBookmarkFile(String worldPath) {
|
||||
public void load() {
|
||||
String worldPath = "global";
|
||||
|
||||
if (NEIClientConfig.getBooleanSetting("inventory.bookmarks.worldSpecific")) {
|
||||
worldPath = NEIClientConfig.getWorldPath();
|
||||
}
|
||||
|
||||
final File dir = new File(CommonUtils.getMinecraftDir(), "saves/NEI/" + worldPath);
|
||||
|
||||
@@ -1782,16 +1787,15 @@ public class BookmarkPanel extends PanelWidget {
|
||||
if (defaultBookmarks.exists()) {
|
||||
|
||||
try {
|
||||
bookmarkFile.createNewFile();
|
||||
if (bookmarkFile.createNewFile()) {
|
||||
InputStream src = new FileInputStream(defaultBookmarks);
|
||||
OutputStream dst = new FileOutputStream(bookmarkFile);
|
||||
|
||||
InputStream src = new FileInputStream(defaultBookmarks);
|
||||
OutputStream dst = new FileOutputStream(bookmarkFile);
|
||||
|
||||
IOUtils.copy(src, dst);
|
||||
|
||||
src.close();
|
||||
dst.close();
|
||||
IOUtils.copy(src, dst);
|
||||
|
||||
src.close();
|
||||
dst.close();
|
||||
}
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.entity.EntityPlayerSP;
|
||||
@@ -30,17 +30,16 @@ import net.minecraftforge.client.event.RenderWorldLastEvent;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
|
||||
import org.apache.commons.csv.CSVFormat;
|
||||
import org.apache.commons.csv.CSVParser;
|
||||
import org.apache.commons.csv.CSVRecord;
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import codechicken.core.ClassDiscoverer;
|
||||
import codechicken.core.ClientUtils;
|
||||
import codechicken.core.GuiModListScroll;
|
||||
import codechicken.lib.packet.PacketCustom;
|
||||
import codechicken.nei.api.API;
|
||||
import codechicken.nei.api.IConfigureNEI;
|
||||
import codechicken.nei.api.ItemInfo;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.recipe.GuiRecipeTab;
|
||||
@@ -148,6 +147,7 @@ public class ClientHandler {
|
||||
|
||||
public static void preInit() {
|
||||
loadSerialHandlers();
|
||||
loadHiddenItems();
|
||||
loadHeightHackHandlers();
|
||||
loadHiddenHandlers();
|
||||
loadEnableAutoFocus();
|
||||
@@ -155,100 +155,69 @@ public class ClientHandler {
|
||||
StackInfo.loadGuidFilters();
|
||||
}
|
||||
|
||||
public static void loadSerialHandlers() {
|
||||
File file = NEIClientConfig.serialHandlersFile;
|
||||
public static void loadSettingsFile(String resource, Consumer<Stream<String>> callback) {
|
||||
loadSettingsFile(resource, (file, writer) -> {
|
||||
String folder = resource.substring(resource.lastIndexOf(".") + 1);
|
||||
URL defaultResource = ClientHandler.class.getResource("/assets/nei/" + folder + "/" + resource);
|
||||
|
||||
if (defaultResource != null) {
|
||||
try {
|
||||
IOUtils.copy(defaultResource.openStream(), writer);
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
}, callback);
|
||||
}
|
||||
|
||||
public static void loadSettingsFile(String resource, BiConsumer<File, FileWriter> createDefault,
|
||||
Consumer<Stream<String>> callback) {
|
||||
File file = new File(NEIClientConfig.configDir, resource);
|
||||
|
||||
if (!file.exists()) {
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
NEIClientConfig.logger.info("Creating default serial handlers list {}", file);
|
||||
URL defaultSerialHandlersResource = ClientHandler.class
|
||||
.getResource("/assets/nei/cfg/serialhandlers.cfg");
|
||||
if (defaultSerialHandlersResource != null) {
|
||||
IOUtils.copy(defaultSerialHandlersResource.openStream(), writer);
|
||||
}
|
||||
NEIClientConfig.logger.info("Creating default '{}' {}", resource, file);
|
||||
createDefault.accept(file, writer);
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to save default serial handlers list to file {}", file, e);
|
||||
NEIClientConfig.logger.error("Failed to save default '{}' to file {}", resource, file, e);
|
||||
}
|
||||
}
|
||||
|
||||
try (FileReader reader = new FileReader(file)) {
|
||||
NEIClientConfig.logger.info("Loading serial handlers from file {}", file);
|
||||
NEIClientConfig.serialHandlers = IOUtils.readLines(reader).stream().filter((line) -> !line.startsWith("#"))
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
NEIClientConfig.logger.info("Loading '{}' file {}", resource, file);
|
||||
callback.accept(
|
||||
IOUtils.readLines(reader).stream().filter(line -> !line.startsWith("#") && !line.trim().isEmpty()));
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to load serial handlers from file {}", file, e);
|
||||
NEIClientConfig.logger.error("Failed to load '{}' file {}", resource, file, e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void loadSerialHandlers() {
|
||||
loadSettingsFile(
|
||||
"serialhandlers.cfg",
|
||||
lines -> NEIClientConfig.serialHandlers = lines.collect(Collectors.toCollection(HashSet::new)));
|
||||
}
|
||||
|
||||
public static void loadHeightHackHandlers() {
|
||||
File file = NEIClientConfig.heightHackHandlersFile;
|
||||
if (!file.exists()) {
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
NEIClientConfig.logger.info("Creating default height hack handlers list {}", file);
|
||||
URL defaultHeightHackHandlersResource = ClientHandler.class
|
||||
.getResource("/assets/nei/cfg/heighthackhandlers.cfg");
|
||||
if (defaultHeightHackHandlersResource != null) {
|
||||
IOUtils.copy(defaultHeightHackHandlersResource.openStream(), writer);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to save default height hack handlers list to file {}", file, e);
|
||||
}
|
||||
}
|
||||
|
||||
try (FileReader reader = new FileReader(file)) {
|
||||
NEIClientConfig.logger.info("Loading height hack handlers from file {}", file);
|
||||
NEIClientConfig.heightHackHandlerRegex = IOUtils.readLines(reader).stream()
|
||||
.filter((line) -> !line.startsWith("#")).map(Pattern::compile)
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to load height hack handlers from file {}", file, e);
|
||||
}
|
||||
loadSettingsFile(
|
||||
"heighthackhandlers.cfg",
|
||||
lines -> NEIClientConfig.heightHackHandlerRegex = lines.map(Pattern::compile)
|
||||
.collect(Collectors.toCollection(HashSet::new)));
|
||||
}
|
||||
|
||||
public static void loadHiddenHandlers() {
|
||||
File file = NEIClientConfig.hiddenHandlersFile;
|
||||
if (!file.exists()) {
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
NEIClientConfig.logger.info("Creating default hidden handlers list {}", file);
|
||||
URL defaultHeightHackHandlersResource = ClientHandler.class
|
||||
.getResource("/assets/nei/cfg/hiddenhandlers.cfg");
|
||||
if (defaultHeightHackHandlersResource != null) {
|
||||
IOUtils.copy(defaultHeightHackHandlersResource.openStream(), writer);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to save default hidden handlers list to file {}", file, e);
|
||||
}
|
||||
}
|
||||
|
||||
try (FileReader reader = new FileReader(file)) {
|
||||
NEIClientConfig.logger.info("Loading hidden handlers from file {}", file);
|
||||
NEIClientConfig.hiddenHandlers = IOUtils.readLines(reader).stream().filter((line) -> !line.startsWith("#"))
|
||||
.collect(Collectors.toCollection(HashSet::new));
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to load hidden handlers from file {}", file, e);
|
||||
}
|
||||
loadSettingsFile(
|
||||
"hiddenhandlers.cfg",
|
||||
lines -> NEIClientConfig.hiddenHandlers = lines.collect(Collectors.toCollection(HashSet::new)));
|
||||
}
|
||||
|
||||
public static void loadEnableAutoFocus() {
|
||||
File file = NEIClientConfig.enableAutoFocusFile;
|
||||
if (!file.exists()) {
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
NEIClientConfig.logger.info("Creating default enable auto focus list {}", file);
|
||||
URL defaultEnableAutoFocusResource = ClientHandler.class
|
||||
.getResource("/assets/nei/cfg/enableautofocus.cfg");
|
||||
if (defaultEnableAutoFocusResource != null) {
|
||||
IOUtils.copy(defaultEnableAutoFocusResource.openStream(), writer);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to save default enable auto focus list to file {}", file, e);
|
||||
}
|
||||
}
|
||||
loadSettingsFile(
|
||||
"enableautofocus.cfg",
|
||||
lines -> AutoFocusWidget.enableAutoFocusPrefixes = lines
|
||||
.collect(Collectors.toCollection(ArrayList::new)));
|
||||
}
|
||||
|
||||
try (FileReader reader = new FileReader(file)) {
|
||||
NEIClientConfig.logger.info("Loading enable auto focus from file {}", file);
|
||||
AutoFocusWidget.enableAutoFocusPrefixes = IOUtils.readLines(reader).stream()
|
||||
.filter((line) -> !line.startsWith("#")).collect(Collectors.toCollection(ArrayList::new));
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to load enable auto focus from file {}", file, e);
|
||||
}
|
||||
public static void loadHiddenItems() {
|
||||
loadSettingsFile("hiddenitems.cfg", lines -> lines.forEach(API::hideItem));
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
@@ -266,54 +235,33 @@ public class ClientHandler {
|
||||
|
||||
public static void postInit() {
|
||||
loadHandlerOrdering();
|
||||
loadPluginsList();
|
||||
GuiContainerManager.registerReloadResourceListener();
|
||||
}
|
||||
|
||||
public static void loadHandlerOrdering() {
|
||||
File file = NEIClientConfig.handlerOrderingFile;
|
||||
if (!file.exists()) {
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
NEIClientConfig.logger.info("Creating default handler ordering CSV {}", file);
|
||||
|
||||
List<String> toWrite = Lists.newArrayList(defaultHandlerOrdering);
|
||||
GuiRecipeTab.handlerMap.keySet().stream().sorted()
|
||||
.forEach(handlerId -> toWrite.add(String.format("%s,0", handlerId)));
|
||||
final String COMMA_DELIMITER = ",";
|
||||
|
||||
loadSettingsFile("handlerordering.csv", (file, writer) -> {
|
||||
List<String> toWrite = Lists.newArrayList(defaultHandlerOrdering);
|
||||
GuiRecipeTab.handlerMap.keySet().stream().sorted()
|
||||
.forEach(handlerId -> toWrite.add(String.format("%s,0", handlerId)));
|
||||
try {
|
||||
IOUtils.writeLines(toWrite, "\n", writer);
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to save default handler ordering to file {}", file, e);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {}
|
||||
}, lines -> lines.map(line -> line.split(COMMA_DELIMITER)).filter(parts -> parts.length == 2).forEach(parts -> {
|
||||
String handlerId = parts[0];
|
||||
int ordering = Integer.getInteger(parts[1], 0);
|
||||
NEIClientConfig.handlerOrdering.put(handlerId, ordering);
|
||||
}));
|
||||
}
|
||||
|
||||
URL url;
|
||||
try {
|
||||
url = file.toURI().toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
NEIClientConfig.logger.info("Invalid URL for handler ordering CSV.");
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
public static void loadPluginsList() {
|
||||
final ClassDiscoverer classDiscoverer = new ClassDiscoverer(
|
||||
test -> test.startsWith("NEI") && test.endsWith("Config.class"),
|
||||
IConfigureNEI.class);
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) {
|
||||
NEIClientConfig.logger.info("Loading handler ordering from file {}", file);
|
||||
CSVParser csvParser = CSVFormat.EXCEL.withCommentMarker('#').parse(reader);
|
||||
for (CSVRecord record : csvParser) {
|
||||
final String handlerId = record.get(0);
|
||||
|
||||
int ordering;
|
||||
try {
|
||||
ordering = Integer.parseInt(record.get(1));
|
||||
} catch (NumberFormatException e) {
|
||||
NEIClientConfig.logger.error("Error parsing CSV record {}: {}", record, e);
|
||||
continue;
|
||||
}
|
||||
|
||||
NEIClientConfig.handlerOrdering.put(handlerId, ordering);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
NEIClientConfig.logger.info("Error parsing CSV");
|
||||
e.printStackTrace();
|
||||
}
|
||||
NEIClientConfig.pluginsList.addAll(classDiscoverer.findClasses());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
|
||||
@@ -1,227 +1,33 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NBTBase.NBTPrimitive;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.util.StatCollector;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
|
||||
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.PresetsList.Preset;
|
||||
import codechicken.nei.PresetsList.PresetMode;
|
||||
import codechicken.nei.api.ItemFilter;
|
||||
import cpw.mods.fml.common.registry.GameData;
|
||||
import codechicken.nei.util.ItemStackFilterParser;
|
||||
|
||||
public class CollapsibleItems {
|
||||
|
||||
protected static interface ISearchParserProvider {
|
||||
|
||||
public ItemFilter getFilter(String searchText);
|
||||
|
||||
default Predicate<String> getMatcher(String searchText) {
|
||||
|
||||
if (searchText.length() >= 3 && searchText.startsWith("r/") && searchText.endsWith("/")) {
|
||||
|
||||
try {
|
||||
Pattern pattern = Pattern.compile(
|
||||
searchText.substring(2, searchText.length() - 1),
|
||||
Pattern.MULTILINE | Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
|
||||
return value -> pattern.matcher(value).find();
|
||||
} catch (PatternSyntaxException ignored) {}
|
||||
|
||||
} else if (!searchText.isEmpty()) {
|
||||
return value -> value.toLowerCase().contains(searchText);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected static class GroupTokenParser {
|
||||
|
||||
protected final HashMap<Character, ISearchParserProvider> searchProviders = new HashMap<>();
|
||||
|
||||
public void addProvider(char prefix, ISearchParserProvider provider) {
|
||||
this.searchProviders.put(prefix, provider);
|
||||
}
|
||||
|
||||
public ItemFilter getFilter(String filterText) {
|
||||
final String[] parts = filterText.toLowerCase().trim().split("\\|");
|
||||
final List<ItemFilter> searchTokens = Arrays.stream(parts).map(s -> parseSearchText(s))
|
||||
.filter(s -> s != null && !s.filters.isEmpty()).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);
|
||||
}
|
||||
}
|
||||
|
||||
private AllMultiItemFilter parseSearchText(String filterText) {
|
||||
|
||||
if (filterText.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final String[] tokens = filterText.split("\\s+");
|
||||
final AllMultiItemFilter searchTokens = new AllMultiItemFilter();
|
||||
|
||||
for (String token : tokens) {
|
||||
token = token.trim();
|
||||
boolean ignore = token.startsWith("!");
|
||||
|
||||
if (ignore) {
|
||||
token = token.substring(1);
|
||||
}
|
||||
|
||||
if (token.isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ISearchParserProvider provider = this.searchProviders.get(token.charAt(0));
|
||||
|
||||
if (provider != null) {
|
||||
token = token.substring(1);
|
||||
} else {
|
||||
provider = this.searchProviders.get('\0');
|
||||
}
|
||||
|
||||
ItemFilter filter = parseToken(ignore ? "!" + token : token, provider);
|
||||
|
||||
if (filter != null) {
|
||||
searchTokens.filters.add(filter);
|
||||
}
|
||||
}
|
||||
|
||||
return searchTokens;
|
||||
}
|
||||
|
||||
private ItemFilter parseToken(String token, ISearchParserProvider provider) {
|
||||
final String[] parts = token.split(",");
|
||||
final AnyMultiItemFilter includeFilter = new AnyMultiItemFilter();
|
||||
final AnyMultiItemFilter expludeFilter = new AnyMultiItemFilter();
|
||||
final AllMultiItemFilter groupFilter = new AllMultiItemFilter();
|
||||
|
||||
for (String part : parts) {
|
||||
boolean ignore = part.startsWith("!");
|
||||
|
||||
if (ignore) {
|
||||
part = part.substring(1);
|
||||
}
|
||||
|
||||
ItemFilter filter = provider.getFilter(part);
|
||||
|
||||
if (filter == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ignore) {
|
||||
expludeFilter.filters.add(filter);
|
||||
} else {
|
||||
includeFilter.filters.add(filter);
|
||||
}
|
||||
}
|
||||
|
||||
if (!includeFilter.filters.isEmpty()) {
|
||||
groupFilter.filters.add(includeFilter);
|
||||
}
|
||||
|
||||
if (!expludeFilter.filters.isEmpty()) {
|
||||
groupFilter.filters.add(new NegatedItemFilter(expludeFilter));
|
||||
}
|
||||
|
||||
return groupFilter.filters.isEmpty() ? null : groupFilter;
|
||||
}
|
||||
}
|
||||
|
||||
protected static class IdentifierFilter implements ISearchParserProvider {
|
||||
|
||||
@Override
|
||||
public ItemFilter getFilter(String searchText) {
|
||||
|
||||
if (Pattern.matches("^\\d+(-\\d+)*$", searchText)) {
|
||||
final Predicate<Integer> filter = generateDamageFilter(searchText);
|
||||
return (stack) -> filter.test(stack.getItemDamage());
|
||||
}
|
||||
|
||||
Predicate<String> matcher = getMatcher(searchText);
|
||||
|
||||
if (matcher != null) {
|
||||
return stack -> matcher.test(getStringIdentifier(stack));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected String getStringIdentifier(ItemStack stack) {
|
||||
String name = GameData.getItemRegistry().getNameForObject(stack.getItem());
|
||||
return name == null || name.isEmpty() ? "Unknown:Unknown" : name;
|
||||
}
|
||||
|
||||
protected Predicate<Integer> generateDamageFilter(String searchText) {
|
||||
String[] range = searchText.split("-");
|
||||
|
||||
if (range.length == 1) {
|
||||
final int damage = Integer.parseInt(range[0]);
|
||||
return (dmg) -> dmg == damage;
|
||||
} else {
|
||||
final int damageStart = Integer.parseInt(range[0]);
|
||||
final int damageEnd = Integer.parseInt(range[1]);
|
||||
return (dmg) -> dmg >= damageStart && dmg <= damageEnd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static class OreDictionaryFilter implements ISearchParserProvider {
|
||||
|
||||
@Override
|
||||
public ItemFilter getFilter(String searchText) {
|
||||
Predicate<String> matcher = getMatcher(searchText);
|
||||
|
||||
if (matcher != null) {
|
||||
return stack -> matches(stack, matcher);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected boolean matches(ItemStack stack, Predicate<String> matcher) {
|
||||
return IntStream.of(OreDictionary.getOreIDs(stack))
|
||||
.anyMatch(id -> matcher.test(OreDictionary.getOreName(id)));
|
||||
}
|
||||
}
|
||||
|
||||
protected static class GroupItem {
|
||||
|
||||
public String guid;
|
||||
@@ -232,8 +38,8 @@ public class CollapsibleItems {
|
||||
public GroupItem() {}
|
||||
|
||||
public void setFilter(String filter) {
|
||||
this.filter = CollapsibleItems.groupParser.getFilter(filter.trim());
|
||||
this.guid = UUID.nameUUIDFromBytes(filter.getBytes()).toString();
|
||||
this.filter = ItemStackFilterParser.parse(filter.trim());
|
||||
this.guid = this.filter != null ? UUID.nameUUIDFromBytes(filter.getBytes()).toString() : "";
|
||||
}
|
||||
|
||||
public void setFilter(ItemFilter filter, String guid) {
|
||||
@@ -246,17 +52,40 @@ public class CollapsibleItems {
|
||||
}
|
||||
}
|
||||
|
||||
private static final String STATE_KEY = "collapsibleitems";
|
||||
|
||||
protected File statesFile;
|
||||
protected static final GroupTokenParser groupParser = new GroupTokenParser();
|
||||
protected final List<GroupItem> groups = new ArrayList<>();
|
||||
protected final Map<ItemStack, Integer> cache = new ConcurrentHashMap<>();
|
||||
|
||||
static {
|
||||
groupParser.addProvider('\0', new IdentifierFilter());
|
||||
groupParser.addProvider('$', new OreDictionaryFilter());
|
||||
public void load() {
|
||||
try {
|
||||
|
||||
if (NEIClientConfig.world.nbt.hasKey(STATE_KEY)) {
|
||||
NBTTagCompound states = NEIClientConfig.world.nbt.getCompoundTag(STATE_KEY);
|
||||
@SuppressWarnings("unchecked")
|
||||
final Map<String, NBTPrimitive> list = (Map<String, NBTPrimitive>) states.tagMap;
|
||||
final Map<String, GroupItem> mapping = new HashMap<>();
|
||||
|
||||
for (GroupItem group : this.groups) {
|
||||
mapping.put(group.guid, group);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, NBTPrimitive> nbtEntry : list.entrySet()) {
|
||||
if (mapping.containsKey(nbtEntry.getKey())) {
|
||||
mapping.get(nbtEntry.getKey()).expanded = nbtEntry.getValue().func_150290_f() == 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
NEIClientConfig.logger.error("Error loading collapsible items states", e);
|
||||
}
|
||||
|
||||
reloadGroups();
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
public void reloadGroups() {
|
||||
this.groups.clear();
|
||||
this.cache.clear();
|
||||
|
||||
@@ -271,49 +100,17 @@ public class CollapsibleItems {
|
||||
}
|
||||
|
||||
if (NEIClientConfig.enableCollapsibleItems()) {
|
||||
loadCollapsibleItems();
|
||||
}
|
||||
|
||||
loadStates();
|
||||
|
||||
if (ItemList.loadFinished) {
|
||||
LayoutManager.markItemsDirty();
|
||||
ClientHandler.loadSettingsFile(
|
||||
"collapsibleitems.cfg",
|
||||
lines -> parseFile(lines.collect(Collectors.toCollection(ArrayList::new))));
|
||||
}
|
||||
}
|
||||
|
||||
protected void loadCollapsibleItems() {
|
||||
File file = NEIClientConfig.collapsibleItemsFile;
|
||||
if (!file.exists()) {
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
NEIClientConfig.logger.info("Creating default collapsible items list {}", file);
|
||||
URL defaultCollapsibleItemsResource = ClientHandler.class
|
||||
.getResource("/assets/nei/cfg/collapsibleitems.cfg");
|
||||
if (defaultCollapsibleItemsResource != null) {
|
||||
IOUtils.copy(defaultCollapsibleItemsResource.openStream(), writer);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to save default collapsible items list to file {}", file, e);
|
||||
}
|
||||
}
|
||||
|
||||
try (FileReader reader = new FileReader(file)) {
|
||||
NEIClientConfig.logger.info("Loading collapsible items from file {}", file);
|
||||
parseFile(IOUtils.readLines(reader));
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to load collapsible items from file {}", file, e);
|
||||
}
|
||||
}
|
||||
|
||||
public void parseFile(List<String> itemStrings) {
|
||||
private void parseFile(List<String> itemStrings) {
|
||||
final JsonParser parser = new JsonParser();
|
||||
GroupItem group = new GroupItem();
|
||||
|
||||
for (String itemStr : itemStrings) {
|
||||
|
||||
if (itemStr.startsWith("#") || itemStr.trim().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
if (itemStr.startsWith("; ")) {
|
||||
@@ -324,10 +121,10 @@ public class CollapsibleItems {
|
||||
}
|
||||
|
||||
if (settings.get("unlocalizedName") != null) {
|
||||
String displayName = StatCollector
|
||||
.translateToLocal(settings.get("unlocalizedName").getAsString());
|
||||
String unlocalizedName = settings.get("unlocalizedName").getAsString();
|
||||
String displayName = StatCollector.translateToLocal(unlocalizedName);
|
||||
|
||||
if (!displayName.equals(settings.get("unlocalizedName").getAsString())) {
|
||||
if (!displayName.equals(unlocalizedName)) {
|
||||
group.displayName = displayName;
|
||||
}
|
||||
}
|
||||
@@ -430,7 +227,7 @@ public class CollapsibleItems {
|
||||
public void toggleGroups(Boolean expanded) {
|
||||
|
||||
if (expanded == null) {
|
||||
expanded = !this.groups.stream().filter(g -> g.expanded).findAny().isPresent();
|
||||
expanded = this.groups.stream().noneMatch(g -> g.expanded);
|
||||
}
|
||||
|
||||
for (GroupItem group : this.groups) {
|
||||
@@ -440,33 +237,6 @@ public class CollapsibleItems {
|
||||
saveStates();
|
||||
}
|
||||
|
||||
private void loadStates() {
|
||||
|
||||
try {
|
||||
|
||||
if (NEIClientConfig.world.nbt.hasKey("collapsibleitems")) {
|
||||
NBTTagCompound states = NEIClientConfig.world.nbt.getCompoundTag("collapsibleitems");
|
||||
@SuppressWarnings("unchecked")
|
||||
final Map<String, NBTPrimitive> list = (Map<String, NBTPrimitive>) states.tagMap;
|
||||
final Map<String, GroupItem> mapping = new HashMap<>();
|
||||
|
||||
for (GroupItem group : this.groups) {
|
||||
mapping.put(group.guid, group);
|
||||
}
|
||||
|
||||
for (Map.Entry<String, NBTPrimitive> nbtEntry : list.entrySet()) {
|
||||
if (mapping.containsKey(nbtEntry.getKey())) {
|
||||
mapping.get(nbtEntry.getKey()).expanded = nbtEntry.getValue().func_150290_f() == 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
NEIClientConfig.logger.error("Error loading collapsible items states", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void saveStates() {
|
||||
NBTTagCompound list = new NBTTagCompound();
|
||||
|
||||
@@ -474,7 +244,7 @@ public class CollapsibleItems {
|
||||
list.setBoolean(group.guid, group.expanded);
|
||||
}
|
||||
|
||||
NEIClientConfig.world.nbt.setTag("collapsibleitems", list);
|
||||
NEIClientConfig.world.nbt.setTag(STATE_KEY, list);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import java.util.HashMap;
|
||||
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;
|
||||
@@ -105,7 +104,7 @@ public class ItemList {
|
||||
}
|
||||
|
||||
public AllMultiItemFilter(ItemFilter... filters) {
|
||||
this(Arrays.asList(filters));
|
||||
this(new LinkedList<>(Arrays.asList(filters)));
|
||||
}
|
||||
|
||||
public AllMultiItemFilter() {
|
||||
@@ -139,7 +138,7 @@ public class ItemList {
|
||||
@Override
|
||||
public boolean matches(ItemStack item) {
|
||||
for (ItemFilter filter : filters) try {
|
||||
if (filter.matches(item)) return true;
|
||||
if (filter != null && filter.matches(item)) return true;
|
||||
} catch (Exception e) {
|
||||
NEIClientConfig.logger.error("Exception filtering " + item + " with " + filter, e);
|
||||
}
|
||||
@@ -156,7 +155,7 @@ public class ItemList {
|
||||
public static boolean itemMatchesAll(ItemStack item, List<ItemFilter> filters) {
|
||||
for (ItemFilter filter : filters) {
|
||||
try {
|
||||
if (!filter.matches(item)) return false;
|
||||
if (filter != null && !filter.matches(item)) return false;
|
||||
} catch (Exception e) {
|
||||
NEIClientConfig.logger.error("Exception filtering " + item + " with " + filter, e);
|
||||
}
|
||||
@@ -211,17 +210,10 @@ public class ItemList {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
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();
|
||||
return String.join("\n", stack.getTooltip(Minecraft.getMinecraft().thePlayer, false));
|
||||
} catch (Throwable ignored) {}
|
||||
|
||||
return "";
|
||||
@@ -262,8 +254,8 @@ public class ItemList {
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void execute() {
|
||||
// System.out.println("Executing NEI Item Loading");
|
||||
ThreadOperationTimer timer = getTimer(NEIClientConfig.getItemLoadingTimeout());
|
||||
LayoutManager.itemsLoaded = true;
|
||||
loadFinished = false;
|
||||
|
||||
List<ItemStack> items = new LinkedList<>();
|
||||
@@ -282,14 +274,21 @@ public class ItemList {
|
||||
permutations.clear();
|
||||
permutations.addAll(ItemInfo.itemOverrides.get(item));
|
||||
|
||||
if (permutations.isEmpty()) item.getSubItems(item, null, permutations);
|
||||
if (permutations.isEmpty()) {
|
||||
item.getSubItems(item, null, permutations);
|
||||
}
|
||||
|
||||
if (permutations.isEmpty()) damageSearch(item, permutations);
|
||||
if (permutations.isEmpty()) {
|
||||
damageSearch(item, permutations);
|
||||
}
|
||||
|
||||
permutations.addAll(ItemInfo.itemVariants.get(item));
|
||||
|
||||
timer.reset();
|
||||
|
||||
permutations = permutations.stream().filter(stack -> !ItemInfo.isHidden(stack))
|
||||
.collect(Collectors.toCollection(ArrayList::new));
|
||||
|
||||
items.addAll(permutations);
|
||||
itemMap.putAll(item, permutations);
|
||||
} catch (Throwable t) {
|
||||
|
||||
@@ -12,6 +12,7 @@ import static codechicken.nei.NEIClientConfig.invCreativeMode;
|
||||
import static codechicken.nei.NEIClientConfig.isBookmarkPanelHidden;
|
||||
import static codechicken.nei.NEIClientConfig.isEnabled;
|
||||
import static codechicken.nei.NEIClientConfig.isHidden;
|
||||
import static codechicken.nei.NEIClientConfig.isLoaded;
|
||||
import static codechicken.nei.NEIClientConfig.showIDs;
|
||||
import static codechicken.nei.NEIClientConfig.toggleBooleanSetting;
|
||||
import static codechicken.nei.NEIClientUtils.cycleGamemode;
|
||||
@@ -638,12 +639,11 @@ public class LayoutManager implements IContainerInputHandler, IContainerTooltipH
|
||||
if (isEnabled()) {
|
||||
setInputFocused(null);
|
||||
|
||||
if (!itemsLoaded) {
|
||||
if (!itemsLoaded && isLoaded()) {
|
||||
ItemList.loadItems.restart();
|
||||
itemsLoaded = true;
|
||||
}
|
||||
overlayRenderer = null;
|
||||
|
||||
overlayRenderer = null;
|
||||
getLayoutStyle().init();
|
||||
layout(gui);
|
||||
AutoFocusWidget.instance.load(gui);
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -24,9 +25,11 @@ import org.apache.logging.log4j.Logger;
|
||||
import org.lwjgl.input.Keyboard;
|
||||
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.reflect.TypeToken;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonParseException;
|
||||
|
||||
import codechicken.core.CCUpdateChecker;
|
||||
import codechicken.core.ClassDiscoverer;
|
||||
import codechicken.core.ClientUtils;
|
||||
import codechicken.core.CommonUtils;
|
||||
import codechicken.lib.config.ConfigFile;
|
||||
@@ -75,12 +78,6 @@ public class NEIClientConfig {
|
||||
public static ConfigSet world;
|
||||
public static final File handlerFile = new File(configDir, "handlers.csv");
|
||||
public static final File catalystFile = new File(configDir, "catalysts.csv");
|
||||
public static final File serialHandlersFile = new File(configDir, "serialhandlers.cfg");
|
||||
public static final File heightHackHandlersFile = new File(configDir, "heighthackhandlers.cfg");
|
||||
public static final File handlerOrderingFile = new File(configDir, "handlerordering.csv");
|
||||
public static final File hiddenHandlersFile = new File(configDir, "hiddenhandlers.csv");
|
||||
public static final File enableAutoFocusFile = new File(configDir, "enableautofocus.cfg");
|
||||
public static final File collapsibleItemsFile = new File(configDir, "collapsibleitems.cfg");
|
||||
|
||||
@Deprecated
|
||||
public static File bookmarkFile;
|
||||
@@ -100,6 +97,8 @@ public class NEIClientConfig {
|
||||
// Any handler not in the map will be assigned to 0, and negative numbers are fine.
|
||||
public static HashMap<String, Integer> handlerOrdering = new HashMap<>();
|
||||
|
||||
public static final Set<Class<?>> pluginsList = new HashSet<>();
|
||||
|
||||
// Function that extracts the handler ID from a handler, with special logic for
|
||||
// TemplateRecipeHandler: prefer using the overlay ID if it exists.
|
||||
public static final Function<IRecipeHandler, String> HANDLER_ID_FUNCTION = handler -> Objects
|
||||
@@ -238,6 +237,20 @@ public class NEIClientConfig {
|
||||
|
||||
});
|
||||
|
||||
String prefixRedefinitions = tag.getTag("inventory.search.prefixRedefinitions").setComment(
|
||||
"Redefine search prefixes by providing a char-to-char map (JSON). The keys are the original prefixes, the values the new ones. Example: { \"$\": \"€\", \"#\": \"+\", \"@\": \"°\", \"%\": \"!\" }")
|
||||
.getValue("{}");
|
||||
try {
|
||||
TypeToken<Map<Character, Character>> typeToken = new TypeToken<Map<Character, Character>>() {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
};
|
||||
Map<Character, Character> charMap = new Gson().fromJson(prefixRedefinitions, typeToken.getType());
|
||||
SearchField.searchParser.prefixRedefinitions.putAll(charMap);
|
||||
} catch (JsonParseException e) {
|
||||
logger.warn("Failed to convert prefix redefinitions from JSON to CharToCharMap:", e);
|
||||
}
|
||||
|
||||
tag.getTag("inventory.bookmarks.enabled").setComment("Enable/Disable Bookmark Panel").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.bookmarks.enabled", true));
|
||||
|
||||
@@ -248,7 +261,7 @@ public class NEIClientConfig {
|
||||
@Override
|
||||
public boolean onClick(int button) {
|
||||
super.onClick(button);
|
||||
initBookmarkFile(worldPath);
|
||||
ItemPanels.bookmarkPanel.load();
|
||||
return true;
|
||||
}
|
||||
});
|
||||
@@ -324,8 +337,10 @@ public class NEIClientConfig {
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button) {
|
||||
super.onClick(button);
|
||||
ItemList.collapsibleItems.reloadGroups();
|
||||
LayoutManager.markItemsDirty();
|
||||
return super.onClick(button);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -428,18 +443,6 @@ public class NEIClientConfig {
|
||||
tag.getTag("command.heal").setDefaultValue("");
|
||||
API.addOption(new OptionTextField("command.heal"));
|
||||
|
||||
tag.getTag("inventory.worldSpecificPresets").setComment("Global or world specific presets")
|
||||
.getBooleanValue(false);
|
||||
API.addOption(new OptionToggleButton("inventory.worldSpecificPresets", true) {
|
||||
|
||||
@Override
|
||||
public boolean onClick(int button) {
|
||||
super.onClick(button);
|
||||
initPresetsFile(worldPath);
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
tag.getTag("inventory.showItemQuantityWidget").setComment("Show Item Quantity Widget").getBooleanValue(true);
|
||||
API.addOption(new OptionToggleButton("inventory.showItemQuantityWidget", true));
|
||||
|
||||
@@ -554,11 +557,11 @@ public class NEIClientConfig {
|
||||
}
|
||||
|
||||
public static void loadWorld(String worldPath) {
|
||||
unloadWorld();
|
||||
NEIClientConfig.worldPath = worldPath;
|
||||
|
||||
setInternalEnabled(true);
|
||||
logger.debug("Loading " + (Minecraft.getMinecraft().isSingleplayer() ? "Local" : "Remote") + " World");
|
||||
bootNEI(ClientUtils.getWorld());
|
||||
|
||||
final File specificDir = new File(CommonUtils.getMinecraftDir(), "saves/NEI/" + worldPath);
|
||||
final boolean newWorld = !specificDir.exists();
|
||||
@@ -568,11 +571,15 @@ public class NEIClientConfig {
|
||||
}
|
||||
|
||||
world = new ConfigSet(new File(specificDir, "NEI.dat"), new ConfigFile(new File(specificDir, "NEI.cfg")));
|
||||
initBookmarkFile(worldPath);
|
||||
initPresetsFile(worldPath);
|
||||
bootNEI(ClientUtils.getWorld());
|
||||
ItemPanels.bookmarkPanel.load();
|
||||
onWorldLoad(newWorld);
|
||||
}
|
||||
|
||||
public static String getWorldPath() {
|
||||
return NEIClientConfig.worldPath;
|
||||
}
|
||||
|
||||
private static void onWorldLoad(boolean newWorld) {
|
||||
world.config.setComment(
|
||||
"World based configuration of NEI.\nMost of these options can be changed ingame.\nDeleting any element will restore it to it's default value");
|
||||
@@ -671,25 +678,20 @@ public class NEIClientConfig {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
logger.debug("Started NEI plugin loading");
|
||||
ClassDiscoverer classDiscoverer = new ClassDiscoverer(
|
||||
test -> test.startsWith("NEI") && test.endsWith("Config.class"),
|
||||
IConfigureNEI.class);
|
||||
|
||||
classDiscoverer.findClasses();
|
||||
|
||||
for (Class<?> clazz : classDiscoverer.classes) {
|
||||
NEIClientConfig.pluginsList.parallelStream().forEach(clazz -> {
|
||||
try {
|
||||
IConfigureNEI config = (IConfigureNEI) clazz.newInstance();
|
||||
config.loadConfig();
|
||||
NEIModContainer.plugins.add(config);
|
||||
logger.debug("Loaded " + clazz.getName());
|
||||
logger.debug("Loaded {}", clazz.getName());
|
||||
} catch (Exception e) {
|
||||
logger.error("Failed to Load " + clazz.getName(), e);
|
||||
logger.error("Failed to Load {}", clazz.getName(), e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
RecipeCatalysts.loadCatalystInfo();
|
||||
ItemSorter.loadConfig();
|
||||
|
||||
// Set pluginNEIConfigLoaded here before posting the NEIConfigsLoadedEvent. This used to be the other
|
||||
// way around, but apparently if your modpack includes 800 mods the event poster might not return in
|
||||
@@ -697,29 +699,11 @@ public class NEIClientConfig {
|
||||
// cause issues in case one of the event handler calls the (non-thread-safe) NEI API. I don't expect any
|
||||
// handler to do this, but who knows what modders have come up with...
|
||||
pluginNEIConfigLoaded = true;
|
||||
logger.debug("NEI plugin loading finished");
|
||||
MinecraftForge.EVENT_BUS.post(new NEIConfigsLoadedEvent());
|
||||
|
||||
ItemList.loadItems.restart();
|
||||
}
|
||||
}.start();
|
||||
ItemSorter.loadConfig();
|
||||
}
|
||||
|
||||
private static void initBookmarkFile(String worldPath) {
|
||||
|
||||
if (!global.config.getTag("inventory.bookmarks.worldSpecific").getBooleanValue()) {
|
||||
worldPath = "global";
|
||||
}
|
||||
|
||||
ItemPanels.bookmarkPanel.setBookmarkFile(worldPath);
|
||||
}
|
||||
|
||||
private static void initPresetsFile(String worldPath) {
|
||||
|
||||
if (!global.config.getTag("inventory.worldSpecificPresets").getBooleanValue()) {
|
||||
worldPath = "global";
|
||||
}
|
||||
|
||||
PresetsList.setPresetsFile(worldPath);
|
||||
}
|
||||
|
||||
public static boolean isWorldSpecific(String setting) {
|
||||
|
||||
@@ -4,8 +4,6 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
@@ -145,62 +143,20 @@ public class PresetsList {
|
||||
}
|
||||
|
||||
public static final List<Preset> presets = new ArrayList<>();
|
||||
|
||||
protected static File presetsFile;
|
||||
protected static RecipesFilter recipeFilter = new RecipesFilter();
|
||||
protected static ItemPanelFilter itemFilter = new ItemPanelFilter();
|
||||
|
||||
static {
|
||||
API.addItemFilter(itemFilter);
|
||||
API.addRecipeFilter(recipeFilter);
|
||||
ItemList.loadCallbacks.add(PresetsList::itemsLoaded);
|
||||
}
|
||||
|
||||
public static ItemFilter getItemFilter() {
|
||||
return itemFilter.getFilter();
|
||||
}
|
||||
|
||||
public static void itemsLoaded() {
|
||||
recipeFilter.cache = null;
|
||||
itemFilter.cache = null;
|
||||
ItemList.collapsibleItems.reload();
|
||||
}
|
||||
|
||||
public static void setPresetsFile(String worldPath) {
|
||||
final File dir = new File(CommonUtils.getMinecraftDir(), "saves/NEI/" + worldPath);
|
||||
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
|
||||
presetsFile = new File(dir, "presets.ini");
|
||||
|
||||
if (!presetsFile.exists()) {
|
||||
final File globalPresets = new File(CommonUtils.getMinecraftDir(), "saves/NEI/global/presets.ini");
|
||||
final File configPresets = new File(NEIClientConfig.configDir, "presets.ini");
|
||||
final File defaultBookmarks = configPresets.exists() ? configPresets : globalPresets;
|
||||
|
||||
if (defaultBookmarks.exists()) {
|
||||
|
||||
try {
|
||||
presetsFile.createNewFile();
|
||||
|
||||
InputStream src = new FileInputStream(defaultBookmarks);
|
||||
OutputStream dst = new FileOutputStream(presetsFile);
|
||||
|
||||
IOUtils.copy(src, dst);
|
||||
|
||||
src.close();
|
||||
dst.close();
|
||||
|
||||
} catch (IOException e) {}
|
||||
}
|
||||
}
|
||||
|
||||
loadPresets();
|
||||
}
|
||||
|
||||
protected static void loadPresets() {
|
||||
public static void load() {
|
||||
final File presetsFile = new File(CommonUtils.getMinecraftDir(), "saves/NEI/global/presets.ini");
|
||||
|
||||
if (presetsFile == null || !presetsFile.exists()) {
|
||||
return;
|
||||
@@ -236,15 +192,15 @@ public class PresetsList {
|
||||
preset = new Preset();
|
||||
}
|
||||
|
||||
if (settings.get("name") != null) {
|
||||
if (settings.has("name")) {
|
||||
preset.name = settings.get("name").getAsString();
|
||||
}
|
||||
|
||||
if (settings.get("enabled") != null) {
|
||||
if (settings.has("enabled")) {
|
||||
preset.enabled = settings.get("enabled").getAsBoolean();
|
||||
}
|
||||
|
||||
if (settings.get("mode") != null) {
|
||||
if (settings.has("mode")) {
|
||||
preset.mode = PresetMode.valueOf(settings.get("mode").getAsString());
|
||||
}
|
||||
|
||||
@@ -260,17 +216,11 @@ public class PresetsList {
|
||||
if (!preset.items.isEmpty()) {
|
||||
presets.add(preset);
|
||||
}
|
||||
|
||||
itemsLoaded();
|
||||
}
|
||||
|
||||
public static void savePresets() {
|
||||
|
||||
if (presetsFile == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> strings = new ArrayList<>();
|
||||
final File presetsFile = new File(CommonUtils.getMinecraftDir(), "saves/NEI/global/presets.ini");
|
||||
final List<String> strings = new ArrayList<>();
|
||||
|
||||
for (Preset preset : presets) {
|
||||
JsonObject settings = new JsonObject();
|
||||
@@ -289,7 +239,10 @@ public class PresetsList {
|
||||
NEIClientConfig.logger.error("Filed to save presets list to file {}", presetsFile, e);
|
||||
}
|
||||
|
||||
itemsLoaded();
|
||||
recipeFilter.cache = null;
|
||||
itemFilter.cache = null;
|
||||
ItemList.collapsibleItems.reloadGroups();
|
||||
LayoutManager.markItemsDirty();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -5,7 +5,6 @@ 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;
|
||||
@@ -20,6 +19,8 @@ import codechicken.nei.ItemList.EverythingItemFilter;
|
||||
import codechicken.nei.ItemList.NegatedItemFilter;
|
||||
import codechicken.nei.ItemList.NothingItemFilter;
|
||||
import codechicken.nei.api.ItemFilter;
|
||||
import gnu.trove.map.TCharCharMap;
|
||||
import gnu.trove.map.hash.TCharCharHashMap;
|
||||
|
||||
public class SearchTokenParser {
|
||||
|
||||
@@ -30,16 +31,11 @@ public class SearchTokenParser {
|
||||
NEVER;
|
||||
|
||||
public static SearchMode fromInt(int value) {
|
||||
switch (value) {
|
||||
case 0:
|
||||
return ALWAYS;
|
||||
case 1:
|
||||
return PREFIX;
|
||||
case 2:
|
||||
return NEVER;
|
||||
default:
|
||||
return ALWAYS;
|
||||
}
|
||||
return switch (value) {
|
||||
case 0 -> ALWAYS;
|
||||
case 1 -> PREFIX;
|
||||
default -> NEVER;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,6 +72,7 @@ public class SearchTokenParser {
|
||||
|
||||
protected final List<ISearchParserProvider> searchProviders;
|
||||
protected final ProvidersCache providersCache = new ProvidersCache();
|
||||
protected final TCharCharMap prefixRedefinitions = new TCharCharHashMap();
|
||||
|
||||
public SearchTokenParser(List<ISearchParserProvider> searchProviders) {
|
||||
this.searchProviders = searchProviders;
|
||||
@@ -114,7 +111,9 @@ public class SearchTokenParser {
|
||||
|
||||
public ISearchParserProvider getProvider(char ch) {
|
||||
return getProviders().stream()
|
||||
.filter(provider -> provider.getSearchMode() == SearchMode.PREFIX && provider.getPrefix() == ch)
|
||||
.filter(
|
||||
provider -> provider.getSearchMode() == SearchMode.PREFIX
|
||||
&& getRedefinedPrefix(provider.getPrefix()) == ch)
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@@ -133,18 +132,24 @@ public class SearchTokenParser {
|
||||
}
|
||||
|
||||
public Pattern getSplitPattern() {
|
||||
StringJoiner prefixes = new StringJoiner("");
|
||||
prefixes.add(String.valueOf('\0'));
|
||||
StringBuilder prefixes = new StringBuilder().append('\0');
|
||||
|
||||
for (ISearchParserProvider provider : getProviders()) {
|
||||
if (provider.getSearchMode() == SearchMode.PREFIX) {
|
||||
prefixes.add(String.valueOf(provider.getPrefix()));
|
||||
prefixes.append(getRedefinedPrefix(provider.getPrefix()));
|
||||
}
|
||||
}
|
||||
|
||||
return Pattern.compile("((-*)([" + Pattern.quote(prefixes.toString()) + "]*)(\\\".*?(?:\\\"|$)|\\S+))");
|
||||
}
|
||||
|
||||
private char getRedefinedPrefix(char prefix) {
|
||||
if (this.prefixRedefinitions.containsKey(prefix)) {
|
||||
return this.prefixRedefinitions.get(prefix);
|
||||
}
|
||||
return prefix;
|
||||
}
|
||||
|
||||
private ItemFilter parseSearchText(String filterText) {
|
||||
|
||||
if (filterText.isEmpty()) {
|
||||
@@ -188,7 +193,11 @@ public class SearchTokenParser {
|
||||
|
||||
for (ISearchParserProvider _provider : getProviders()) {
|
||||
if (_provider.getSearchMode() == SearchMode.ALWAYS) {
|
||||
filters.add(_provider.getFilter(token));
|
||||
ItemFilter filter = _provider.getFilter(token);
|
||||
|
||||
if (filter != null) {
|
||||
filters.add(filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package codechicken.nei;
|
||||
|
||||
import static codechicken.nei.LayoutManager.searchField;
|
||||
import static codechicken.nei.NEIClientUtils.translate;
|
||||
|
||||
import java.awt.Point;
|
||||
@@ -33,7 +34,6 @@ 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 {
|
||||
@@ -72,7 +72,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoa
|
||||
if (slot < sorted.size()) {
|
||||
SubsetTag tag = sorted.get(slot);
|
||||
if (NEIClientUtils.shiftKey()) {
|
||||
codechicken.nei.LayoutManager.searchField.setText("%" + tag.fullname);
|
||||
searchField.setText("%" + tag.fullname.replace(" ", ""));
|
||||
} else if (button == 0 && count >= 2) {
|
||||
SubsetWidget.showOnly(tag);
|
||||
} else {
|
||||
@@ -94,7 +94,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoa
|
||||
Rectangle4i r = new Rectangle4i(x, y, w, getSlotHeight(slot));
|
||||
if (slot < sorted.size()) {
|
||||
SubsetTag tag = sorted.get(slot);
|
||||
codechicken.nei.LayoutManager.getLayoutStyle()
|
||||
LayoutManager.getLayoutStyle()
|
||||
.drawSubsetTag(tag.displayName(), x, y, r.w, r.h, tag.state.state, r.contains(mx, my));
|
||||
} else {
|
||||
ItemStack stack = state.items.get(slot - sorted.size());
|
||||
@@ -103,8 +103,7 @@ public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoa
|
||||
int itemx = w / 2 - 8;
|
||||
int itemy = 1;
|
||||
|
||||
codechicken.nei.LayoutManager.getLayoutStyle()
|
||||
.drawSubsetTag(null, x, y, r.w, r.h, hidden ? 0 : 2, false);
|
||||
LayoutManager.getLayoutStyle().drawSubsetTag(null, x, y, r.w, r.h, hidden ? 0 : 2, false);
|
||||
|
||||
GuiContainerManager.drawItem(x + itemx, y + itemy, stack);
|
||||
if (new Rectangle4i(itemx, itemy, 16, 16).contains(mx, my)) SubsetWidget.hoverStack = stack;
|
||||
@@ -642,7 +641,6 @@ public class SubsetWidget extends Button implements ItemFilterProvider, ItemsLoa
|
||||
if (reallocate) {
|
||||
for (ItemStack item : ItemList.items) {
|
||||
if (interrupted()) return;
|
||||
if (ItemInfo.isHidden(item)) continue;
|
||||
for (SubsetTag tag : tags) if (tag.filter.matches(item)) state.get(tag.fullname).items.add(item);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ import codechicken.nei.recipe.IUsageHandler;
|
||||
import codechicken.nei.recipe.RecipeCatalysts;
|
||||
import codechicken.nei.recipe.RecipeInfo;
|
||||
import codechicken.nei.recipe.StackInfo;
|
||||
import codechicken.nei.util.ItemStackFilterParser;
|
||||
|
||||
/**
|
||||
* This is the main class that handles item property configuration. WARNING: DO NOT access this class until the world
|
||||
@@ -151,6 +152,14 @@ public class API {
|
||||
}
|
||||
}
|
||||
|
||||
public static void hideItem(String rule) {
|
||||
ItemFilter filter = ItemStackFilterParser.parse(rule);
|
||||
if (filter != null) {
|
||||
ItemInfo.hiddenItemsRules.filters.add(filter);
|
||||
LayoutManager.markItemsDirty();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add or replace the name normally shown on the item tooltip
|
||||
*/
|
||||
|
||||
@@ -44,12 +44,14 @@ import codechicken.core.featurehack.GameDataManipulator;
|
||||
import codechicken.nei.InfiniteStackSizeHandler;
|
||||
import codechicken.nei.InfiniteToolHandler;
|
||||
import codechicken.nei.ItemList;
|
||||
import codechicken.nei.ItemList.AnyMultiItemFilter;
|
||||
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.PresetsList;
|
||||
import codechicken.nei.SearchField.SearchParserProvider;
|
||||
import codechicken.nei.SearchTokenParser.SearchMode;
|
||||
import codechicken.nei.config.ArrayDumper;
|
||||
@@ -82,6 +84,7 @@ public class ItemInfo {
|
||||
public static final ArrayListMultimap<Layout, IHighlightHandler> highlightHandlers = ArrayListMultimap.create();
|
||||
public static final ItemStackMap<String> nameOverrides = new ItemStackMap<>();
|
||||
public static final ItemStackSet hiddenItems = new ItemStackSet();
|
||||
public static final AnyMultiItemFilter hiddenItemsRules = new AnyMultiItemFilter();
|
||||
public static final ItemStackSet finiteItems = new ItemStackSet();
|
||||
public static final ArrayListMultimap<Item, ItemStack> itemOverrides = ArrayListMultimap.create();
|
||||
public static final ArrayListMultimap<Item, ItemStack> itemVariants = ArrayListMultimap.create();
|
||||
@@ -93,9 +96,10 @@ public class ItemInfo {
|
||||
public static final HashMap<Item, String> itemOwners = new HashMap<>();
|
||||
|
||||
public static boolean isHidden(ItemStack stack) {
|
||||
return hiddenItems.contains(stack);
|
||||
return hiddenItems.contains(stack) || hiddenItemsRules.matches(stack);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static boolean isHidden(Item item) {
|
||||
return hiddenItems.containsAll(item);
|
||||
}
|
||||
@@ -130,22 +134,15 @@ public class ItemInfo {
|
||||
addInfiniteHandlers();
|
||||
addInputHandlers();
|
||||
addIDDumps();
|
||||
addHiddenItemFilter();
|
||||
addSearchProviders();
|
||||
PresetsList.load();
|
||||
ItemList.collapsibleItems.load();
|
||||
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)) {
|
||||
new SearchParserProvider('\0', "default", EnumChatFormatting.RESET, PatternItemFilter::new) {
|
||||
|
||||
@Override
|
||||
public SearchMode getSearchMode() {
|
||||
@@ -154,29 +151,12 @@ public class ItemInfo {
|
||||
|
||||
});
|
||||
API.addSearchProvider(
|
||||
new SearchParserProvider(
|
||||
'@',
|
||||
"modName",
|
||||
EnumChatFormatting.LIGHT_PURPLE,
|
||||
(pattern) -> new ModNameFilter(pattern)));
|
||||
new SearchParserProvider('@', "modName", EnumChatFormatting.LIGHT_PURPLE, ModNameFilter::new));
|
||||
API.addSearchProvider(
|
||||
new SearchParserProvider(
|
||||
'$',
|
||||
"oreDict",
|
||||
EnumChatFormatting.AQUA,
|
||||
(pattern) -> new OreDictionaryFilter(pattern)));
|
||||
new SearchParserProvider('$', "oreDict", EnumChatFormatting.AQUA, OreDictionaryFilter::new));
|
||||
API.addSearchProvider(new SearchParserProvider('#', "tooltip", EnumChatFormatting.YELLOW, TooltipFilter::new));
|
||||
API.addSearchProvider(
|
||||
new SearchParserProvider(
|
||||
'#',
|
||||
"tooltip",
|
||||
EnumChatFormatting.YELLOW,
|
||||
(pattern) -> new TooltipFilter(pattern)));
|
||||
API.addSearchProvider(
|
||||
new SearchParserProvider(
|
||||
'&',
|
||||
"identifier",
|
||||
EnumChatFormatting.GOLD,
|
||||
(pattern) -> new IdentifierFilter(pattern)));
|
||||
new SearchParserProvider('&', "identifier", EnumChatFormatting.GOLD, IdentifierFilter::new));
|
||||
}
|
||||
|
||||
private static void addIDDumps() {
|
||||
|
||||
@@ -11,30 +11,29 @@ import codechicken.nei.config.GuiOptionList.OptionScrollSlot;
|
||||
|
||||
public class OptionTextField extends Option {
|
||||
|
||||
private TextField textField = new TextField("test") {
|
||||
protected final TextField textField = new TextField("test") {
|
||||
|
||||
{
|
||||
this.h = 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChange(String oldText) {
|
||||
if (focused() && isValidValue(text())) if (!defaulting() || !text().equals(getTag().getValue())) // don't
|
||||
// override
|
||||
// global
|
||||
// if text
|
||||
// hasn't
|
||||
// changed
|
||||
// don't override global if text hasn't changed
|
||||
if (focused() && isValidValue(text()) && (!defaulting() || !text().equals(getTag().getValue()))) {
|
||||
getTag().setValue(text());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFocus(boolean focus) {
|
||||
if (!focus && !isValidValue(text())) setText(renderTag().getValue());
|
||||
|
||||
super.setFocus(focus);
|
||||
}
|
||||
};
|
||||
|
||||
public OptionTextField(String name) {
|
||||
super(name);
|
||||
textField.h = 20;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -13,7 +13,6 @@ import org.lwjgl.opengl.GL12;
|
||||
import codechicken.core.gui.GuiWidget;
|
||||
import codechicken.lib.gui.GuiDraw;
|
||||
import codechicken.lib.vec.Rectangle4i;
|
||||
import codechicken.nei.ItemList.AllMultiItemFilter;
|
||||
import codechicken.nei.ItemPanel.ItemPanelSlot;
|
||||
import codechicken.nei.ItemsGrid;
|
||||
import codechicken.nei.Label;
|
||||
@@ -22,7 +21,6 @@ import codechicken.nei.PresetsList.Preset;
|
||||
import codechicken.nei.PresetsList.PresetMode;
|
||||
import codechicken.nei.TextField;
|
||||
import codechicken.nei.api.ItemFilter;
|
||||
import codechicken.nei.api.ItemInfo;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.guihook.IContainerTooltipHandler;
|
||||
|
||||
@@ -52,9 +50,7 @@ public class LeftPanel extends GuiWidget {
|
||||
@Override
|
||||
protected ItemFilter getFilter() {
|
||||
Set<String> identifiers = preset.items;
|
||||
return new AllMultiItemFilter(
|
||||
item -> !ItemInfo.hiddenItems.contains(item),
|
||||
item -> identifiers.contains(Preset.getIdentifier(item)));
|
||||
return item -> identifiers.contains(Preset.getIdentifier(item));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -146,6 +142,7 @@ public class LeftPanel extends GuiWidget {
|
||||
grid.restartFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(int x, int y, int button) {
|
||||
grid.mouseClicked(x, y, button);
|
||||
|
||||
@@ -183,6 +180,7 @@ public class LeftPanel extends GuiWidget {
|
||||
|
||||
protected void onItemsChanges() {}
|
||||
|
||||
@Override
|
||||
public void mouseMovedOrUp(int x, int y, int button) {
|
||||
nameField.mouseUp(x, y, button);
|
||||
|
||||
@@ -203,6 +201,7 @@ public class LeftPanel extends GuiWidget {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(int x, int y, int button, long time) {
|
||||
nameField.mouseDragged(x, y, button, time);
|
||||
|
||||
@@ -233,6 +232,7 @@ public class LeftPanel extends GuiWidget {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
int CHECKBOX_WIDTH = (this.width - 12) / 3;
|
||||
nameLabel.x = this.x + 2;
|
||||
@@ -271,6 +271,7 @@ public class LeftPanel extends GuiWidget {
|
||||
grid.refresh(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mousex, int mousey, float frame) {
|
||||
nameLabel.draw(mousex, mousey);
|
||||
nameField.draw(mousex, mousey);
|
||||
@@ -305,7 +306,7 @@ public class LeftPanel extends GuiWidget {
|
||||
}
|
||||
}
|
||||
|
||||
if (tooltip.size() > 0) {
|
||||
if (!tooltip.isEmpty()) {
|
||||
tooltip.set(0, tooltip.get(0) + GuiDraw.TOOLTIP_LINESPACE); // add space after 'title'
|
||||
}
|
||||
|
||||
@@ -320,6 +321,7 @@ public class LeftPanel extends GuiWidget {
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(char c, int keycode) {
|
||||
nameField.handleKeyPress(keycode, c);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public abstract class PresetItemsGrid extends ItemsGrid {
|
||||
}
|
||||
};
|
||||
|
||||
public PresetItemsGrid() {
|
||||
protected PresetItemsGrid() {
|
||||
|
||||
pageLabel = new Label("0/0", true);
|
||||
|
||||
|
||||
@@ -28,7 +28,6 @@ import codechicken.nei.PresetsList.Preset;
|
||||
import codechicken.nei.SearchField.GuiSearchField;
|
||||
import codechicken.nei.TextField;
|
||||
import codechicken.nei.api.ItemFilter;
|
||||
import codechicken.nei.api.ItemInfo;
|
||||
import codechicken.nei.guihook.GuiContainerManager;
|
||||
import codechicken.nei.guihook.IContainerTooltipHandler;
|
||||
import codechicken.nei.util.TextHistory;
|
||||
@@ -55,11 +54,11 @@ public class RightPanel extends GuiWidget {
|
||||
}
|
||||
}
|
||||
|
||||
protected static abstract class PresetSearchField extends TextField {
|
||||
protected abstract static class PresetSearchField extends TextField {
|
||||
|
||||
private static final TextHistory history = new TextHistory();
|
||||
|
||||
public PresetSearchField(String ident) {
|
||||
protected PresetSearchField(String ident) {
|
||||
super(ident);
|
||||
}
|
||||
|
||||
@@ -134,9 +133,7 @@ public class RightPanel extends GuiWidget {
|
||||
|
||||
@Override
|
||||
protected ItemFilter getFilter() {
|
||||
AllMultiItemFilter filter = new AllMultiItemFilter();
|
||||
filter.filters.add(item -> !ItemInfo.hiddenItems.contains(item));
|
||||
filter.filters.add(searchField.getFilter());
|
||||
AllMultiItemFilter filter = new AllMultiItemFilter(searchField.getFilter());
|
||||
|
||||
if (enabledPresets.isChecked()) {
|
||||
AllMultiItemFilter andFilter = new AllMultiItemFilter();
|
||||
@@ -162,7 +159,7 @@ public class RightPanel extends GuiWidget {
|
||||
protected boolean isSelected(ItemStack stack) {
|
||||
|
||||
if (mouseSelection != null && mouseSelection.items.contains(stack)) {
|
||||
return mouseSelection.append != false;
|
||||
return mouseSelection.append;
|
||||
}
|
||||
|
||||
return preset.items.contains(Preset.getIdentifier(stack));
|
||||
@@ -206,6 +203,7 @@ public class RightPanel extends GuiWidget {
|
||||
grid.restartFilter();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseClicked(int x, int y, int button) {
|
||||
grid.mouseClicked(x, y, button);
|
||||
|
||||
@@ -231,6 +229,7 @@ public class RightPanel extends GuiWidget {
|
||||
|
||||
protected void onItemsChanges() {}
|
||||
|
||||
@Override
|
||||
public void mouseMovedOrUp(int x, int y, int button) {
|
||||
searchField.mouseUp(x, y, button);
|
||||
|
||||
@@ -300,6 +299,7 @@ public class RightPanel extends GuiWidget {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseDragged(int x, int y, int button, long time) {
|
||||
searchField.mouseDragged(x, y, button, time);
|
||||
|
||||
@@ -330,6 +330,7 @@ public class RightPanel extends GuiWidget {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update() {
|
||||
enabledPresets.w = 20;
|
||||
enabledPresets.h = INPUT_HEIGHT;
|
||||
@@ -345,6 +346,7 @@ public class RightPanel extends GuiWidget {
|
||||
grid.refresh(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(int mousex, int mousey, float frame) {
|
||||
enabledPresets.draw(mousex, mousey);
|
||||
searchField.draw(mousex, mousey);
|
||||
@@ -372,7 +374,7 @@ public class RightPanel extends GuiWidget {
|
||||
}
|
||||
}
|
||||
|
||||
if (tooltip.size() > 0) {
|
||||
if (!tooltip.isEmpty()) {
|
||||
tooltip.set(0, tooltip.get(0) + GuiDraw.TOOLTIP_LINESPACE); // add space after 'title'
|
||||
}
|
||||
|
||||
@@ -383,10 +385,12 @@ public class RightPanel extends GuiWidget {
|
||||
return tooltip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(char c, int keycode) {
|
||||
searchField.handleKeyPress(keycode, c);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void mouseScrolled(int x, int y, int scroll) {
|
||||
if (grid.contains(x, y)) {
|
||||
grid.shiftPage(-scroll);
|
||||
|
||||
@@ -156,13 +156,15 @@ public class GuiContainerManager {
|
||||
namelist = stack.getTooltip(
|
||||
Minecraft.getMinecraft().thePlayer,
|
||||
includeHandlers && Minecraft.getMinecraft().gameSettings.advancedItemTooltips);
|
||||
} catch (Throwable ignored) {}
|
||||
} catch (Throwable ignored) {
|
||||
namelist = new ArrayList<>();
|
||||
}
|
||||
|
||||
if (namelist == null) namelist = new ArrayList<>();
|
||||
|
||||
if (namelist.size() == 0) namelist.add("Unnamed");
|
||||
|
||||
if (namelist.get(0) == null || namelist.get(0).equals("")) namelist.set(0, "Unnamed");
|
||||
if (namelist.isEmpty()) {
|
||||
namelist.add("Unnamed");
|
||||
} else if (namelist.get(0) == null || namelist.get(0).isEmpty()) {
|
||||
namelist.set(0, "Unnamed");
|
||||
}
|
||||
|
||||
if (includeHandlers) {
|
||||
for (IContainerTooltipHandler handler : tooltipHandlers) {
|
||||
|
||||
@@ -5,7 +5,9 @@ import static codechicken.lib.gui.GuiDraw.getMousePosition;
|
||||
import java.awt.Point;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -24,6 +26,7 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
|
||||
|
||||
public static ArrayList<ICraftingHandler> craftinghandlers = new ArrayList<>();
|
||||
public static ArrayList<ICraftingHandler> serialCraftingHandlers = new ArrayList<>();
|
||||
private static Set<String> existingHandlers = new HashSet<>();
|
||||
|
||||
public static boolean openRecipeGui(String outputId, Object... results) {
|
||||
return createRecipeGui(outputId, true, results) != null;
|
||||
@@ -155,12 +158,24 @@ public class GuiCraftingRecipe extends GuiRecipe<ICraftingHandler> {
|
||||
public static void registerRecipeHandler(ICraftingHandler handler) {
|
||||
final String handlerId = handler.getHandlerId();
|
||||
|
||||
if (craftinghandlers.stream().anyMatch(h -> h.getHandlerId().equals(handlerId))
|
||||
|| serialCraftingHandlers.stream().anyMatch(h -> h.getHandlerId().equals(handlerId)))
|
||||
if (existingHandlers.contains(handlerId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (existingHandlers) {
|
||||
existingHandlers.add(handlerId);
|
||||
}
|
||||
|
||||
if (NEIClientConfig.serialHandlers.contains(handlerId)) {
|
||||
synchronized (serialCraftingHandlers) {
|
||||
serialCraftingHandlers.add(handler);
|
||||
}
|
||||
} else {
|
||||
synchronized (craftinghandlers) {
|
||||
craftinghandlers.add(handler);
|
||||
}
|
||||
}
|
||||
|
||||
if (NEIClientConfig.serialHandlers.contains(handlerId)) serialCraftingHandlers.add(handler);
|
||||
else craftinghandlers.add(handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,6 +2,8 @@ package codechicken.nei.recipe;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -14,6 +16,7 @@ public class GuiUsageRecipe extends GuiRecipe<IUsageHandler> {
|
||||
|
||||
public static ArrayList<IUsageHandler> usagehandlers = new ArrayList<>();
|
||||
public static ArrayList<IUsageHandler> serialUsageHandlers = new ArrayList<>();
|
||||
private static Set<String> existingHandlers = new HashSet<>();
|
||||
|
||||
public static boolean openRecipeGui(String inputId, Object... ingredients) {
|
||||
|
||||
@@ -65,12 +68,25 @@ public class GuiUsageRecipe extends GuiRecipe<IUsageHandler> {
|
||||
|
||||
public static void registerUsageHandler(IUsageHandler handler) {
|
||||
final String handlerId = handler.getHandlerId();
|
||||
if (usagehandlers.stream().anyMatch(h -> h.getHandlerId().equals(handlerId))
|
||||
|| serialUsageHandlers.stream().anyMatch(h -> h.getHandlerId().equals(handlerId)))
|
||||
return;
|
||||
|
||||
if (NEIClientConfig.serialHandlers.contains(handlerId)) serialUsageHandlers.add(handler);
|
||||
else usagehandlers.add(handler);
|
||||
if (existingHandlers.contains(handlerId)) {
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (existingHandlers) {
|
||||
existingHandlers.add(handlerId);
|
||||
}
|
||||
|
||||
if (NEIClientConfig.serialHandlers.contains(handlerId)) {
|
||||
synchronized (serialUsageHandlers) {
|
||||
serialUsageHandlers.add(handler);
|
||||
}
|
||||
} else {
|
||||
synchronized (usagehandlers) {
|
||||
usagehandlers.add(handler);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static IUsageHandler getUsageOrCatalystHandler(IUsageHandler handler, String inputId,
|
||||
|
||||
@@ -1,15 +1,8 @@
|
||||
package codechicken.nei.recipe;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
@@ -20,10 +13,8 @@ import net.minecraftforge.fluids.FluidContainerRegistry;
|
||||
import net.minecraftforge.fluids.FluidStack;
|
||||
import net.minecraftforge.fluids.IFluidContainerItem;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
|
||||
import codechicken.nei.ClientHandler;
|
||||
import codechicken.nei.ItemStackMap;
|
||||
import codechicken.nei.NEIClientConfig;
|
||||
import codechicken.nei.api.IStackStringifyHandler;
|
||||
import codechicken.nei.recipe.stackinfo.DefaultStackStringifyHandler;
|
||||
import codechicken.nei.recipe.stackinfo.GTFluidStackStringifyHandler;
|
||||
@@ -187,37 +178,9 @@ public class StackInfo {
|
||||
}
|
||||
|
||||
public static void loadGuidFilters() {
|
||||
|
||||
guidfilters.clear();
|
||||
|
||||
final File guidFlitersFile = new File(NEIClientConfig.configDir, "guidfilters.cfg");
|
||||
List<String> itemStrings = new ArrayList<>();
|
||||
|
||||
if (guidFlitersFile.exists()) {
|
||||
|
||||
try (FileReader reader = new FileReader(guidFlitersFile)) {
|
||||
NEIClientConfig.logger.info("Loading guid filters from file {}", guidFlitersFile);
|
||||
itemStrings = IOUtils.readLines(reader);
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.error("Failed to load bookmarks from file {}", guidFlitersFile, e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
} else {
|
||||
final URL filterUrl = StackInfo.class.getResource("/assets/nei/guidfilters.cfg");
|
||||
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(filterUrl.openStream()))) {
|
||||
itemStrings = IOUtils.readLines(reader);
|
||||
} catch (IOException e) {
|
||||
NEIClientConfig.logger.info("Error parsing guid filters");
|
||||
e.printStackTrace();
|
||||
} catch (Exception e) {
|
||||
NEIClientConfig.logger.info("Error parsing guid filters");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
for (String guidStr : itemStrings) {
|
||||
ClientHandler.loadSettingsFile("guidfilters.cfg", lines -> lines.forEach(guidStr -> {
|
||||
final String[] parts = guidStr.split(",");
|
||||
final HashMap<String, String[]> rules = new HashMap<>();
|
||||
|
||||
@@ -226,7 +189,7 @@ public class StackInfo {
|
||||
}
|
||||
|
||||
guidfilters.put(parts[0], rules);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
public static ItemStack getItemStackWithMinimumDamage(ItemStack[] stacks) {
|
||||
|
||||
@@ -432,7 +432,7 @@ public abstract class TemplateRecipeHandler implements ICraftingHandler, IUsageH
|
||||
|
||||
public static ItemFilter getItemFilter() {
|
||||
return new AllMultiItemFilter(
|
||||
item -> !ItemInfo.hiddenItems.contains(item),
|
||||
item -> !ItemInfo.isHidden(item),
|
||||
PresetsList.getItemFilter(),
|
||||
GuiRecipe.searchField != null ? GuiRecipe.searchField.getFilter() : null);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
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;
|
||||
|
||||
@@ -58,14 +56,13 @@ public class TooltipFilter implements ItemFilter {
|
||||
}
|
||||
|
||||
public static void populateSearchMap() {
|
||||
/* Create a snapshot of the current keys in the cache */
|
||||
HashSet<ItemStackKey> oldItems = new HashSet<>(itemSearchNames.keySet());
|
||||
new Thread("NEI populate Tooltip Filter") {
|
||||
|
||||
for (ItemStack stack : ItemList.items) {
|
||||
oldItems.remove(new ItemStackKey(stack));
|
||||
}
|
||||
|
||||
itemSearchNames.keySet().removeAll(oldItems);
|
||||
@Override
|
||||
public void run() {
|
||||
ItemList.items.parallelStream().forEach(TooltipFilter::getSearchTooltip);
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
protected static String getSearchTooltip(ItemStack stack) {
|
||||
@@ -74,14 +71,7 @@ public class TooltipFilter implements ItemFilter {
|
||||
|
||||
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());
|
||||
return EnumChatFormatting.getTextWithoutFormattingCodes(String.join("\n", list.subList(1, list.size())));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
package codechicken.nei.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.IntPredicate;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.nbt.NBTTagCompound;
|
||||
import net.minecraft.nbt.NBTTagList;
|
||||
import net.minecraftforge.oredict.OreDictionary;
|
||||
|
||||
import codechicken.nei.ItemList.AllMultiItemFilter;
|
||||
import codechicken.nei.ItemList.AnyMultiItemFilter;
|
||||
import codechicken.nei.ItemList.NegatedItemFilter;
|
||||
import codechicken.nei.api.ItemFilter;
|
||||
import cpw.mods.fml.common.registry.FMLControlledNamespacedRegistry;
|
||||
import cpw.mods.fml.common.registry.GameData;
|
||||
|
||||
/**
|
||||
* @formatter:off
|
||||
*
|
||||
* parts:
|
||||
* modname:itemid - identify
|
||||
* $orename - ore dictionary
|
||||
* tag.color=red - tag
|
||||
* 0 or 0-12 - damage
|
||||
*
|
||||
* modifiers:
|
||||
* ! - logical not. exclude items that match the following expression (!minecraft:portal)
|
||||
* r/.../ - standard java regex (r/^m\w{6}ft$/ = minecraft)
|
||||
* , - logical or in token (minecraft:potion 16384-16462,!16386)
|
||||
* | - logical or multi-item search (wrench|hammer)
|
||||
*
|
||||
*
|
||||
* example: minecraft:potion 16384-16462,!16386 | $oreiron | tag.color=red
|
||||
*/
|
||||
public class ItemStackFilterParser {
|
||||
|
||||
private ItemStackFilterParser() {}
|
||||
|
||||
public static ItemFilter parse(String filterText) {
|
||||
final List<ItemFilter> searchTokens = new ArrayList<>();
|
||||
filterText = filterText.trim();
|
||||
|
||||
if (!filterText.isEmpty()) {
|
||||
for (String part : filterText.split("\\s*\\|\\s*")) {
|
||||
AllMultiItemFilter filter = parsePart(part);
|
||||
if (!filter.filters.isEmpty()) {
|
||||
searchTokens.add(filter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (searchTokens.isEmpty()) {
|
||||
return null;
|
||||
} else if (searchTokens.size() == 1) {
|
||||
return searchTokens.get(0);
|
||||
} else {
|
||||
return new AnyMultiItemFilter(searchTokens);
|
||||
}
|
||||
}
|
||||
|
||||
private static AllMultiItemFilter parsePart(String part) {
|
||||
final AllMultiItemFilter searchTokens = new AllMultiItemFilter();
|
||||
|
||||
for (String token : part.split("\\s+")) {
|
||||
ItemFilter ruleFilter = parseRules(token);
|
||||
|
||||
if (ruleFilter != null) {
|
||||
searchTokens.filters.add(ruleFilter);
|
||||
}
|
||||
}
|
||||
|
||||
return searchTokens;
|
||||
}
|
||||
|
||||
protected static ItemFilter parseRules(String token) {
|
||||
final AnyMultiItemFilter orFilter = new AnyMultiItemFilter();
|
||||
final AnyMultiItemFilter orNotFilter = new AnyMultiItemFilter();
|
||||
final AllMultiItemFilter ruleFilter = new AllMultiItemFilter();
|
||||
|
||||
for (String rule : token.split(",")) {
|
||||
boolean ignore = rule.startsWith("!");
|
||||
ItemFilter filter = null;
|
||||
|
||||
if (ignore) {
|
||||
rule = rule.substring(1);
|
||||
}
|
||||
|
||||
if (rule.startsWith("$")) {
|
||||
filter = getOreDictFilter(rule.substring(1));
|
||||
} else if (rule.startsWith("tag.")) {
|
||||
filter = getTagFilter(rule.substring(4));
|
||||
} else if (Pattern.matches("^\\d+(-\\d+)?$", rule)) {
|
||||
filter = getDamageFilter(rule);
|
||||
} else {
|
||||
filter = getStringIdentifierFilter(rule);
|
||||
}
|
||||
|
||||
if (filter == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ignore) {
|
||||
orNotFilter.filters.add(filter);
|
||||
} else {
|
||||
orFilter.filters.add(filter);
|
||||
}
|
||||
}
|
||||
|
||||
if (!orFilter.filters.isEmpty()) {
|
||||
ruleFilter.filters.add(orFilter);
|
||||
}
|
||||
|
||||
if (!orNotFilter.filters.isEmpty()) {
|
||||
ruleFilter.filters.add(new NegatedItemFilter(orNotFilter));
|
||||
}
|
||||
|
||||
return ruleFilter.filters.isEmpty() ? null : ruleFilter;
|
||||
}
|
||||
|
||||
protected static Predicate<String> getMatcher(String searchText) {
|
||||
|
||||
if (searchText.length() >= 3 && searchText.startsWith("r/") && searchText.endsWith("/")) {
|
||||
|
||||
try {
|
||||
Pattern pattern = Pattern.compile(
|
||||
searchText.substring(2, searchText.length() - 1),
|
||||
Pattern.MULTILINE | Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
|
||||
return value -> pattern.matcher(value).find();
|
||||
} catch (PatternSyntaxException ignored) {}
|
||||
|
||||
} else if (!searchText.isEmpty()) {
|
||||
final String lowerCase = searchText.toLowerCase();
|
||||
return value -> value.toLowerCase().contains(lowerCase);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static ItemFilter getOreDictFilter(String rule) {
|
||||
final Predicate<String> matcher = getMatcher(rule);
|
||||
|
||||
if (matcher == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return stack -> IntStream.of(OreDictionary.getOreIDs(stack))
|
||||
.anyMatch(id -> matcher.test(OreDictionary.getOreName(id)));
|
||||
}
|
||||
|
||||
protected static ItemFilter getTagFilter(String rule) {
|
||||
final String[] parts = rule.split("=", 2);
|
||||
final String[] path = parts[0].split("\\.");
|
||||
final Predicate<String> value = getMatcher(parts[1]);
|
||||
|
||||
return stack -> {
|
||||
Object tag = stack.getTagCompound();
|
||||
|
||||
for (int i = 0; i < path.length && tag != null; i++) {
|
||||
if (tag instanceof NBTTagCompound) {
|
||||
tag = ((NBTTagCompound) tag).getTag(path[i]);
|
||||
} else if (tag instanceof NBTTagList) {
|
||||
tag = ((NBTTagList) tag).tagList.get(Integer.parseInt(path[i]));
|
||||
} else {
|
||||
tag = null;
|
||||
}
|
||||
}
|
||||
|
||||
return tag == null ? value == null : value != null && value.test(tag.toString());
|
||||
};
|
||||
}
|
||||
|
||||
protected static ItemFilter getDamageFilter(String rule) {
|
||||
final String[] range = rule.split("-");
|
||||
final IntPredicate matcher;
|
||||
|
||||
if (range.length == 1) {
|
||||
final int damage = Integer.parseInt(range[0]);
|
||||
matcher = dmg -> dmg == damage;
|
||||
} else {
|
||||
final int damageStart = Integer.parseInt(range[0]);
|
||||
final int damageEnd = Integer.parseInt(range[1]);
|
||||
matcher = dmg -> dmg >= damageStart && dmg <= damageEnd;
|
||||
}
|
||||
|
||||
return stack -> matcher.test(stack.getItemDamage());
|
||||
}
|
||||
|
||||
protected static ItemFilter getStringIdentifierFilter(String rule) {
|
||||
final FMLControlledNamespacedRegistry<Item> iItemRegistry = GameData.getItemRegistry();
|
||||
final Predicate<String> matcher = getMatcher(rule);
|
||||
|
||||
return stack -> {
|
||||
String name = iItemRegistry.getNameForObject(stack.getItem());
|
||||
return name != null && !name.isEmpty() && matcher.test(name);
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -2,15 +2,22 @@
|
||||
#
|
||||
# One line - one group
|
||||
# Item added in first valid group
|
||||
# | - logical or. multi-item search (wrench|hammer)
|
||||
# $ - search by ore dictionary ($ore)
|
||||
# ! - logical not. exclude items that match the following expression (-@minecraft)
|
||||
# r/.../ - standard java regex (@r/m\w{6}ft/ = @minecraft)
|
||||
# 0 - damage filter
|
||||
# 0-12 - damage range filter
|
||||
# , - logical or in token
|
||||
#
|
||||
#
|
||||
# parts:
|
||||
# modname:itemid - identify
|
||||
# $orename - ore dictionary
|
||||
# tag.color=red - tag
|
||||
# 0 or 0-12 - damage
|
||||
#
|
||||
# modifiers:
|
||||
# ! - logical not. exclude items that match the following expression (!minecraft:portal)
|
||||
# r/.../ - standard java regex (r/^m\w{6}ft$/ = minecraft)
|
||||
# , - logical or in token (minecraft:potion 16384-16462,!16386)
|
||||
# | - logical or multi-item search (wrench|hammer)
|
||||
#
|
||||
# example: minecraft:potion 16384-16462,!16386 | $oreiron | tag.color=red
|
||||
#
|
||||
minecraft:spawn_egg
|
||||
minecraft:mob_spawner
|
||||
minecraft:record_
|
||||
|
||||
+2
-1
@@ -53,4 +53,5 @@ miscutils:particleIon,Damage
|
||||
miscutils:personalHealingDevice
|
||||
tectech:item.em.debugContainer,tag.symbols
|
||||
tinkersdefense:Heater Shield,tag.InfiTool
|
||||
tinkersdefense:Round Shield,tag.InfiTool
|
||||
tinkersdefense:Round Shield,tag.InfiTool
|
||||
miscutils:itemCustomMetaCover.miscutils.GtMachineCasings,Damage
|
||||
@@ -0,0 +1,24 @@
|
||||
# Hidden Items Filters
|
||||
#
|
||||
# parts:
|
||||
# modname:itemid - identify
|
||||
# $orename - ore dictionary
|
||||
# tag.color=red - tag
|
||||
# 0 or 0-12 - damage
|
||||
#
|
||||
# modifiers:
|
||||
# ! - logical not. exclude items that match the following expression (!minecraft:portal)
|
||||
# r/.../ - standard java regex (r/^m\w{6}ft$/ = minecraft)
|
||||
# , - logical or in token (minecraft:potion 16384-16462,!16386)
|
||||
# | - logical or multi-item search (wrench|hammer)
|
||||
#
|
||||
# example: minecraft:potion 16384-16462,!16386 | $oreiron | tag.color=red
|
||||
#
|
||||
minecraft:portal
|
||||
minecraft:end_portal
|
||||
minecraft:fire
|
||||
minecraft:lava
|
||||
minecraft:mob_spawner
|
||||
minecraft:anvil !0
|
||||
minecraft:flowing_water
|
||||
minecraft:flowing_lava
|
||||
@@ -104,6 +104,26 @@ 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.search.modNameSearchMode=Modname Suchmodus
|
||||
nei.options.inventory.search.modNameSearchMode.0=Immer
|
||||
nei.options.inventory.search.modNameSearchMode.1=Präfix: %s
|
||||
nei.options.inventory.search.modNameSearchMode.2=Nie
|
||||
nei.options.inventory.search.tooltipSearchMode=Tooltip Suchmodus
|
||||
nei.options.inventory.search.tooltipSearchMode.0=Immer
|
||||
nei.options.inventory.search.tooltipSearchMode.1=Präfix: %s
|
||||
nei.options.inventory.search.tooltipSearchMode.2=Nie
|
||||
nei.options.inventory.search.identifierSearchMode=Identifikator Suchmodus
|
||||
nei.options.inventory.search.identifierSearchMode.0=Immer
|
||||
nei.options.inventory.search.identifierSearchMode.1=Präfix: %s
|
||||
nei.options.inventory.search.identifierSearchMode.2=Nie
|
||||
nei.options.inventory.search.oreDictSearchMode=OreDict Suchmodus
|
||||
nei.options.inventory.search.oreDictSearchMode.0=Immer
|
||||
nei.options.inventory.search.oreDictSearchMode.1=Präfix: %s
|
||||
nei.options.inventory.search.oreDictSearchMode.2=Nie
|
||||
nei.options.inventory.search.subsetsSearchMode=Item-SubSet Suchmodus
|
||||
nei.options.inventory.search.subsetsSearchMode.0=Immer
|
||||
nei.options.inventory.search.subsetsSearchMode.1=Präfix: %s
|
||||
nei.options.inventory.search.subsetsSearchMode.2=Nie
|
||||
nei.options.inventory.utilities=Nützliches
|
||||
nei.options.inventory.utilities.tip=Wähle Inhalte für den Mehrzweckmodus
|
||||
nei.options.inventory.utilities.time=Zeit
|
||||
|
||||
@@ -190,9 +190,6 @@ nei.options.inventory.bookmarks.ignorePotionOverlap.false=No
|
||||
nei.options.inventory.bookmarks.worldSpecific=World Specific Bookmarks
|
||||
nei.options.inventory.bookmarks.worldSpecific.true=Yes
|
||||
nei.options.inventory.bookmarks.worldSpecific.false=No
|
||||
nei.options.inventory.worldSpecificPresets=World Specific Presets
|
||||
nei.options.inventory.worldSpecificPresets.true=Yes
|
||||
nei.options.inventory.worldSpecificPresets.false=No
|
||||
nei.options.inventory.guirecipe=Recipes GUI
|
||||
nei.options.inventory.guirecipe.jeiStyleTabs=JEI Style Tabs
|
||||
nei.options.inventory.guirecipe.jeiStyleTabs.true=Yes
|
||||
|
||||
@@ -190,9 +190,6 @@ nei.options.inventory.bookmarks.ignorePotionOverlap.false=Нет
|
||||
nei.options.inventory.bookmarks.worldSpecific=Закладки для конкретного мира
|
||||
nei.options.inventory.bookmarks.worldSpecific.true=Да
|
||||
nei.options.inventory.bookmarks.worldSpecific.false=Нет
|
||||
nei.options.inventory.worldSpecificPresets=Пресеты для конкретного мира
|
||||
nei.options.inventory.worldSpecificPresets.true=Да
|
||||
nei.options.inventory.worldSpecificPresets.false=Нет
|
||||
nei.options.inventory.guirecipe=Интерфейс рецептов
|
||||
nei.options.inventory.guirecipe.jeiStyleTabs=Вкладки в стиле JEI
|
||||
nei.options.inventory.guirecipe.jeiStyleTabs.true=Да
|
||||
|
||||
@@ -131,9 +131,6 @@ nei.options.inventory=物品栏
|
||||
nei.options.inventory.bookmarks.worldSpecific=书签存储位置
|
||||
nei.options.inventory.bookmarks.worldSpecific.true=存档内
|
||||
nei.options.inventory.bookmarks.worldSpecific.false=全局
|
||||
nei.options.inventory.worldSpecificPresets=预设存储位置
|
||||
nei.options.inventory.worldSpecificPresets.true=存档内
|
||||
nei.options.inventory.worldSpecificPresets.false=全局
|
||||
nei.options.inventory.bookmarks.enabled=显示/隐藏书签页
|
||||
nei.options.inventory.bookmarks.enabled.true=显示
|
||||
nei.options.inventory.bookmarks.enabled.false=隐藏
|
||||
|
||||
Reference in new issue
Block a user