2014-04-29 10:54:20 +10:00
|
|
|
package codechicken.nei;
|
|
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
2025-09-04 16:59:51 +03:00
|
|
|
import java.util.Arrays;
|
2014-06-29 20:31:37 +10:00
|
|
|
import java.util.LinkedList;
|
2014-04-29 10:54:20 +10:00
|
|
|
import java.util.List;
|
2020-01-01 11:14:02 -08:00
|
|
|
import java.util.concurrent.ForkJoinPool;
|
2024-10-04 21:46:29 +02:00
|
|
|
import java.util.concurrent.ForkJoinWorkerThread;
|
2025-09-04 16:59:51 +03:00
|
|
|
import java.util.regex.Pattern;
|
2023-01-28 17:55:51 -08:00
|
|
|
|
2023-09-25 00:35:24 +02:00
|
|
|
import net.minecraft.item.Item;
|
|
|
|
|
import net.minecraft.item.ItemStack;
|
2025-09-04 16:59:51 +03:00
|
|
|
import net.minecraft.util.EnumChatFormatting;
|
2023-09-25 00:35:24 +02:00
|
|
|
|
|
|
|
|
import com.google.common.collect.ArrayListMultimap;
|
|
|
|
|
import com.google.common.collect.ListMultimap;
|
|
|
|
|
|
|
|
|
|
import codechicken.nei.api.ItemFilter;
|
|
|
|
|
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
|
2026-06-29 19:08:59 +03:00
|
|
|
import codechicken.nei.api.ItemInfo;
|
2025-09-17 15:42:35 +03:00
|
|
|
import codechicken.nei.util.ItemUntranslator;
|
2023-09-25 00:35:24 +02:00
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
public class ItemList {
|
2023-01-28 17:55:51 -08:00
|
|
|
|
2014-06-29 20:31:37 +10:00
|
|
|
/**
|
|
|
|
|
* Fields are replaced atomically and contents never modified.
|
|
|
|
|
*/
|
2022-06-24 12:32:13 +01:00
|
|
|
public static volatile List<ItemStack> items = new ArrayList<>();
|
2014-06-29 20:31:37 +10:00
|
|
|
/**
|
|
|
|
|
* Fields are replaced atomically and contents never modified.
|
|
|
|
|
*/
|
2014-07-25 14:45:45 +10:00
|
|
|
public static volatile ListMultimap<Item, ItemStack> itemMap = ArrayListMultimap.create();
|
2014-06-29 20:31:37 +10:00
|
|
|
/**
|
|
|
|
|
* Updates to this should be synchronised on this
|
|
|
|
|
*/
|
2019-12-30 20:19:16 -08:00
|
|
|
public static final List<ItemFilterProvider> itemFilterers = new LinkedList<>();
|
|
|
|
|
public static final List<ItemsLoadedCallback> loadCallbacks = new LinkedList<>();
|
2014-04-29 10:54:20 +10:00
|
|
|
|
2022-08-31 17:43:22 +09:00
|
|
|
/**
|
|
|
|
|
* Unlike {@link LayoutManager#itemsLoaded}, this indicates whether item loading is actually finished or not.
|
|
|
|
|
*/
|
|
|
|
|
public static boolean loadFinished;
|
2014-04-29 10:54:20 +10:00
|
|
|
|
2025-09-04 16:59:51 +03:00
|
|
|
public static class EverythingItemFilter implements ItemFilter {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean matches(ItemStack item) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static class NothingItemFilter implements ItemFilter {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean matches(ItemStack item) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
public PatternItemFilter(Pattern pattern) {
|
|
|
|
|
this.pattern = pattern;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean matches(ItemStack item) {
|
|
|
|
|
String displayName = EnumChatFormatting.getTextWithoutFormattingCodes(item.getDisplayName());
|
|
|
|
|
|
|
|
|
|
if (displayName != null && !displayName.isEmpty() && this.pattern.matcher(displayName).find()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-17 15:42:35 +03:00
|
|
|
displayName = ItemUntranslator.getInstance().getItemStackDisplayName(item);
|
|
|
|
|
|
|
|
|
|
if (!displayName.isEmpty() && this.pattern.matcher(displayName).find()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-04 16:59:51 +03:00
|
|
|
if (item.hasDisplayName()) {
|
|
|
|
|
displayName = EnumChatFormatting
|
|
|
|
|
.getTextWithoutFormattingCodes(item.getItem().getItemStackDisplayName(item));
|
|
|
|
|
|
2026-06-29 19:08:59 +03:00
|
|
|
if (displayName != null && !displayName.isEmpty() && this.pattern.matcher(displayName).find()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (String alias : ItemInfo.getAliases(item)) {
|
|
|
|
|
if (this.pattern.matcher(alias).find()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2025-09-04 16:59:51 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static class AllMultiItemFilter implements ItemFilter {
|
|
|
|
|
|
|
|
|
|
public List<ItemFilter> filters;
|
|
|
|
|
|
|
|
|
|
public AllMultiItemFilter(List<ItemFilter> filters) {
|
|
|
|
|
this.filters = filters;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public AllMultiItemFilter(ItemFilter... filters) {
|
|
|
|
|
this(new LinkedList<>(Arrays.asList(filters)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public AllMultiItemFilter() {
|
|
|
|
|
this(new LinkedList<>());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean matches(ItemStack item) {
|
|
|
|
|
for (ItemFilter filter : filters) try {
|
|
|
|
|
if (filter != null && !filter.matches(item)) return false;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
NEIClientConfig.logger
|
|
|
|
|
.error("Exception filtering " + item + " with " + filter + " (" + e.getMessage() + ")", e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static class AnyMultiItemFilter implements ItemFilter {
|
|
|
|
|
|
|
|
|
|
public List<ItemFilter> filters;
|
|
|
|
|
|
|
|
|
|
public AnyMultiItemFilter(List<ItemFilter> filters) {
|
|
|
|
|
this.filters = filters;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public AnyMultiItemFilter() {
|
|
|
|
|
this(new LinkedList<>());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public boolean matches(ItemStack item) {
|
|
|
|
|
for (ItemFilter filter : filters) try {
|
|
|
|
|
if (filter != null && filter.matches(item)) return true;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
NEIClientConfig.logger
|
|
|
|
|
.error("Exception filtering " + item + " with " + filter + " (" + e.getMessage() + ")", e);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-24 12:32:13 +01:00
|
|
|
public static interface ItemsLoadedCallback {
|
2023-01-28 17:55:51 -08:00
|
|
|
|
2014-06-29 20:31:37 +10:00
|
|
|
public void itemsLoaded();
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
|
2014-12-09 13:42:14 +10:00
|
|
|
public static boolean itemMatchesAll(ItemStack item, List<ItemFilter> filters) {
|
2022-06-24 12:32:13 +01:00
|
|
|
for (ItemFilter filter : filters) {
|
2014-12-09 13:42:14 +10:00
|
|
|
try {
|
2024-08-29 23:14:52 +03:00
|
|
|
if (filter != null && !filter.matches(item)) return false;
|
2014-12-09 13:42:14 +10:00
|
|
|
} catch (Exception e) {
|
2024-11-17 17:31:10 +02:00
|
|
|
NEIClientConfig.logger
|
|
|
|
|
.error("Exception filtering " + item + " with " + filter + " (" + e.getMessage() + ")", e);
|
2014-12-09 13:42:14 +10:00
|
|
|
}
|
|
|
|
|
}
|
2014-04-29 10:54:20 +10:00
|
|
|
|
2014-06-29 20:31:37 +10:00
|
|
|
return true;
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
|
2014-12-14 17:10:00 +10:00
|
|
|
/**
|
|
|
|
|
* @deprecated use getItemListFilter().matches(item)
|
|
|
|
|
*/
|
|
|
|
|
@Deprecated
|
2014-06-29 20:31:37 +10:00
|
|
|
public static boolean itemMatches(ItemStack item) {
|
2014-12-14 17:10:00 +10:00
|
|
|
return getItemListFilter().matches(item);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static ItemFilter getItemListFilter() {
|
|
|
|
|
return new AllMultiItemFilter(getItemFilters());
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
|
2014-06-29 20:31:37 +10:00
|
|
|
public static List<ItemFilter> getItemFilters() {
|
2019-12-30 20:19:16 -08:00
|
|
|
LinkedList<ItemFilter> filters = new LinkedList<>();
|
2014-06-29 20:31:37 +10:00
|
|
|
synchronized (itemFilterers) {
|
2024-06-27 18:03:50 +03:00
|
|
|
for (ItemFilterProvider p : itemFilterers) {
|
|
|
|
|
filters.add(p.getFilter());
|
|
|
|
|
}
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
2014-06-29 20:31:37 +10:00
|
|
|
return filters;
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
|
2024-10-04 21:46:29 +02:00
|
|
|
public static ForkJoinPool forkJoinPool;
|
2020-01-01 11:14:02 -08:00
|
|
|
|
2024-10-04 21:46:29 +02:00
|
|
|
static {
|
|
|
|
|
final ForkJoinPool.ForkJoinWorkerThreadFactory factory = new ForkJoinPool.ForkJoinWorkerThreadFactory() {
|
|
|
|
|
|
|
|
|
|
private int workerId;
|
2020-01-01 11:14:02 -08:00
|
|
|
|
2024-10-04 21:46:29 +02:00
|
|
|
@Override
|
|
|
|
|
public ForkJoinWorkerThread newThread(ForkJoinPool pool) {
|
|
|
|
|
final ForkJoinWorkerThread worker = ForkJoinPool.defaultForkJoinWorkerThreadFactory.newThread(pool);
|
|
|
|
|
worker.setName("NEI-worker-thread-" + workerId++);
|
|
|
|
|
return worker;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
int poolSize = Runtime.getRuntime().availableProcessors() * 2 / 3;
|
|
|
|
|
if (poolSize < 1) poolSize = 1;
|
|
|
|
|
forkJoinPool = new ForkJoinPool(poolSize, factory, null, false);
|
|
|
|
|
}
|
2020-01-01 11:14:02 -08:00
|
|
|
|
2026-06-26 21:25:07 +03:00
|
|
|
// The item list pipeline lives in ItemListLoader; these references are kept for backward compatibility.
|
|
|
|
|
public static final RestartableTask loadItems = ItemListLoader.loadItems;
|
2023-01-28 17:55:51 -08:00
|
|
|
|
2026-06-26 21:25:07 +03:00
|
|
|
public static final RestartableTask refreshItems = ItemListLoader.refreshItems;
|
2019-12-24 13:37:41 -08:00
|
|
|
|
2026-06-26 21:25:07 +03:00
|
|
|
public static final RestartableTask updateFilter = ItemListLoader.updateFilter;
|
2014-04-29 10:54:20 +10:00
|
|
|
|
2014-07-23 21:03:03 +10:00
|
|
|
/**
|
|
|
|
|
* @deprecated Use updateFilter.restart()
|
|
|
|
|
*/
|
|
|
|
|
@Deprecated
|
2014-06-29 20:31:37 +10:00
|
|
|
public static void updateFilter() {
|
2014-07-23 21:03:03 +10:00
|
|
|
updateFilter.restart();
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
|
2014-07-23 21:03:03 +10:00
|
|
|
/**
|
|
|
|
|
* @deprecated Use loadItems.restart()
|
|
|
|
|
*/
|
|
|
|
|
@Deprecated
|
2014-04-29 10:54:20 +10:00
|
|
|
public static void loadItems() {
|
2014-07-23 21:03:03 +10:00
|
|
|
loadItems.restart();
|
2014-04-29 10:54:20 +10:00
|
|
|
}
|
|
|
|
|
}
|