Information Handler (#695)

This commit is contained in:
koolkrafter5 authored and GitHub committed 2025-08-16 18:24:40 +07:00
1 parent ef8706ae38
commit aeb59081d9
11 files changed
+302 -59

No files matched your search

+4 -1
View File
@@ -28,6 +28,7 @@ import codechicken.nei.ThreadOperationTimer.TimeoutException;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.api.ItemFilter.ItemFilterProvider;
import codechicken.nei.api.ItemInfo;
import codechicken.nei.recipe.InformationHandler;
import codechicken.nei.search.TooltipFilter;
public class ItemList {
@@ -289,7 +290,7 @@ public class ItemList {
.collect(Collectors.toList());
}
// For optimization it generate itemslist, permutations, orders & collapsibleitems
// Generate itemlist, permutations, orders, collapsibleitems, and informationhandler stacks
@Override
@SuppressWarnings("unchecked")
public void execute() {
@@ -303,6 +304,7 @@ public class ItemList {
ItemSorter.instance.ordering.clear();
CollapsibleItems.clearCache();
TooltipFilter.clearCache();
InformationHandler.clearCache();
List<ItemStack> items = new ArrayList<>();
ListMultimap<Item, ItemStack> itemMap = ArrayListMultimap.create();
@@ -329,6 +331,7 @@ public class ItemList {
CollapsibleItems.putItem(stack);
TooltipFilter.getSearchTooltip(stack);
InformationHandler.populateStacks(stack);
}
}
@@ -58,6 +58,7 @@ import codechicken.nei.config.preset.GuiPresetList;
import codechicken.nei.event.NEIConfigsLoadedEvent;
import codechicken.nei.recipe.GuiRecipeTab;
import codechicken.nei.recipe.IRecipeHandler;
import codechicken.nei.recipe.InformationHandler;
import codechicken.nei.recipe.RecipeCatalysts;
import codechicken.nei.recipe.RecipeInfo;
import codechicken.nei.util.NEIKeyboardUtils;
@@ -899,6 +900,7 @@ public class NEIClientConfig {
LayoutManager.load();
NEIController.load();
BookmarkContainerInfo.load();
InformationHandler.load();
mainNEIConfigLoaded = true;
new Thread("NEI Plugin Loader") {
@@ -1,13 +1,13 @@
package codechicken.nei.config;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
import codechicken.core.CommonUtils;
import codechicken.nei.NEIClientConfig;
@@ -15,6 +15,7 @@ import codechicken.nei.NEIServerUtils;
import codechicken.nei.recipe.CatalystInfo;
import codechicken.nei.recipe.GuiRecipeTab;
import codechicken.nei.recipe.HandlerInfo;
import codechicken.nei.recipe.InformationHandler;
import codechicken.nei.recipe.RecipeCatalysts;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
@@ -33,18 +34,11 @@ public class IMCHandler {
if (type == null || type.isEmpty()) continue;
if (CommonUtils.isClient()) {
switch (type) {
case "registerHandlerInfo":
handleRegisterHandlerInfo(message);
break;
case "removeHandlerInfo":
handleRemoveHandlerInfo(message);
break;
case "registerCatalystInfo":
handleRegisterCatalystInfo(message);
break;
case "removeCatalystInfo":
handleRemoveCatalystInfo(message);
break;
case "registerHandlerInfo" -> handleRegisterHandlerInfo(message);
case "removeHandlerInfo" -> handleRemoveHandlerInfo(message);
case "registerCatalystInfo" -> handleRegisterCatalystInfo(message);
case "removeCatalystInfo" -> handleRemoveCatalystInfo(message);
case "addItemInfo" -> handleAddItemInfo(message);
}
}
}
@@ -57,7 +51,7 @@ public class IMCHandler {
}
final NBTTagCompound tag = message.getNBTValue();
final String handler = tag.getString("handler");
NEIClientConfig.logger.info("Processing registerHandlerInfo `" + handler + "` from " + message.getSender());
NEIClientConfig.logger.info("Processing registerHandlerInfo `{}` from {}", handler, message.getSender());
final String modName = tag.getString("modName");
final String modId = tag.getString("modId");
@@ -100,7 +94,7 @@ public class IMCHandler {
: HandlerInfo.DEFAULT_MAX_PER_PAGE;
info.setHandlerDimensions(imageHeight, imageWidth, maxRecipesPerPage);
} catch (NumberFormatException ignored) {
NEIClientConfig.logger.info("Error setting handler dimensions for " + handler);
NEIClientConfig.logger.info("Error setting handler dimensions for {}", handler);
}
// true if not set to false
@@ -118,7 +112,7 @@ public class IMCHandler {
}
final NBTTagCompound tag = message.getNBTValue();
final String handler = tag.getString("handler");
NEIClientConfig.logger.info("Processing removeHandlerInfo `" + handler + "` from " + message.getSender());
NEIClientConfig.logger.info("Processing removeHandlerInfo `{}` from {}", handler, message.getSender());
GuiRecipeTab.handlerRemoverFromIMC.add(handler);
}
@@ -130,7 +124,7 @@ public class IMCHandler {
}
if (!processedCatalystSenders.contains(message.getSender())) {
NEIClientConfig.logger.info("Processing registerCatalystInfo from " + message.getSender());
NEIClientConfig.logger.info("Processing registerCatalystInfo from {}", message.getSender());
processedCatalystSenders.add(message.getSender());
}
final NBTTagCompound tag = message.getNBTValue();
@@ -139,23 +133,14 @@ public class IMCHandler {
NEIClientConfig.logger.warn("Missing handlerID for registerCatalystInfo!");
return;
}
final String itemName = tag.getString("itemName");
final String nbtInfo = tag.hasKey("nbtInfo") ? tag.getString("nbtInfo") : null;
if (itemName.isEmpty()) {
NEIClientConfig.logger.warn(String.format("Missing itemName for registerCatalystInfo in `%s`!", handlerID));
return;
}
final ItemStack itemStack = NEIServerUtils.getModdedItem(itemName, nbtInfo);
final ItemStack itemStack = getItemStackFromIMC(message, "registerCatalystInfo");
if (itemStack == null) {
NEIClientConfig.logger.warn(String.format("Cannot find item `%s`!", itemName));
return;
}
final int priority = tag.getInteger("priority");
RecipeCatalysts
.addOrPut(RecipeCatalysts.catalystsAdderFromIMC, handlerID, new CatalystInfo(itemStack, priority));
NEIClientConfig.logger
.info(String.format("Added catalyst `%s` to handler %s", itemStack.getDisplayName(), handlerID));
NEIClientConfig.logger.info("Added catalyst `{}` to handler {}", itemStack.getDisplayName(), handlerID);
}
private static void handleRemoveCatalystInfo(IMCMessage message) {
@@ -164,33 +149,62 @@ public class IMCHandler {
return;
}
NEIClientConfig.logger.info("Processing removeCatalystInfo from " + message.getSender());
final NBTTagCompound tag = message.getNBTValue();
final String handlerID = tag.getString("handlerID");
if (handlerID.isEmpty()) {
NEIClientConfig.logger.warn("Missing handlerID for registerCatalystInfo!");
NEIClientConfig.logger.warn("Missing handlerID for removeCatalystInfo!");
return;
}
final String itemName = tag.getString("itemName");
final String nbtInfo = tag.hasKey("nbtInfo") ? tag.getString("nbtInfo") : null;
if (itemName.isEmpty()) {
NEIClientConfig.logger.warn(String.format("Missing itemName for registerCatalystInfo in `%s`!", handlerID));
return;
}
final ItemStack itemStack = NEIServerUtils.getModdedItem(itemName, nbtInfo);
final ItemStack itemStack = getItemStackFromIMC(message, "removeCatalystInfo");
if (itemStack == null) {
NEIClientConfig.logger.warn(String.format("Cannot find item `%s`!", itemName));
return;
}
if (RecipeCatalysts.catalystsRemoverFromIMC.containsKey(handlerID)) {
RecipeCatalysts.catalystsRemoverFromIMC.get(handlerID).add(itemStack);
} else {
RecipeCatalysts.catalystsRemoverFromIMC
.put(handlerID, new ArrayList<>(Collections.singletonList(itemStack)));
RecipeCatalysts.catalystsRemoverFromIMC.computeIfAbsent(handlerID, k -> new ArrayList<>()).add(itemStack);
NEIClientConfig.logger.info("Removed catalyst `{}` from handler {}", itemStack.getDisplayName(), handlerID);
}
private static void handleAddItemInfo(IMCMessage message) {
if (!message.isNBTMessage()) {
logInvalidMessage(message, "NBT");
return;
}
NEIClientConfig.logger
.info(String.format("Removed catalyst `%s` from handler %s", itemStack.getDisplayName(), handlerID));
final NBTTagCompound tag = message.getNBTValue();
if (tag.hasKey("pages")) addMultipleInfoPages(message);
if (tag.hasKey("page")) addSingleInfoPage(message);
}
private static void addMultipleInfoPages(IMCMessage message) {
final NBTTagCompound tag = message.getNBTValue();
final String filter = tag.getString("filter");
final NBTTagList pages = tag.getTagList("pages", 8); // 8 = TAG_String
for (int i = 0; i < pages.tagCount(); i++) {
String page = pages.getStringTagAt(i);
InformationHandler.addInformationPage(filter, page);
}
}
private static void addSingleInfoPage(IMCMessage message) {
final NBTTagCompound tag = message.getNBTValue();
String filter = tag.getString("filter");
String page = tag.getString("page");
InformationHandler.addInformationPage(filter, page);
}
private static ItemStack getItemStackFromIMC(IMCMessage message, String logAction) {
final NBTTagCompound tag = message.getNBTValue();
final String itemName = tag.getString("itemName");
final String nbtInfo = tag.hasKey("nbtInfo") ? tag.getString("nbtInfo") : null;
NEIClientConfig.logger.info("Processing {} for item `{}` from {}", logAction, itemName, message.getSender());
final ItemStack itemStack = NEIServerUtils.getModdedItem(itemName, nbtInfo);
if (itemStack == null) {
NEIClientConfig.logger.warn("Cannot find item `{}`!", itemName);
}
return itemStack;
}
private static void logInvalidMessage(FMLInterModComms.IMCMessage message, String type) {
@@ -0,0 +1,150 @@
package codechicken.nei.recipe;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.FontRenderer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.StatCollector;
import codechicken.nei.ClientHandler;
import codechicken.nei.NEIClientConfig;
import codechicken.nei.NEIClientUtils;
import codechicken.nei.PositionedStack;
import codechicken.nei.api.ItemFilter;
import codechicken.nei.util.ItemStackFilterParser;
public class InformationHandler extends TemplateRecipeHandler {
private static final List<InformationPage> ITEM_INFO = new ArrayList<>();
public static void addInformationPage(String filter, String description) {
if (filter.isEmpty() || description.isEmpty()) return;
ITEM_INFO.add(new InformationPage(filter, description));
}
public static void populateStacks(ItemStack stack) {
for (InformationPage page : ITEM_INFO) {
page.addItem(stack);
}
}
@Override
public void drawExtras(int recipe) {
CachedInfoPage page = (CachedInfoPage) this.arecipes.get(recipe);
drawWrappedText(StatCollector.translateToLocal(page.getPage().info).replace("\\n", "\n"), 4, 24);
}
private void drawWrappedText(String text, int x, int y) {
FontRenderer font = Minecraft.getMinecraft().fontRenderer;
List<String> lines = font.listFormattedStringToWidth(text, 156);
for (String line : lines) {
font.drawString(line, x, y, 0);
y += 10;
}
}
public static void clearCache() {
for (InformationPage page : ITEM_INFO) {
page.items.clear();
}
}
@Override
public String getRecipeName() {
return NEIClientUtils.translate("recipe.information");
}
@Override
public String getOverlayIdentifier() {
return "information";
}
@Override
public void loadCraftingRecipes(ItemStack result) {
for (InformationPage page : ITEM_INFO) {
if (page.filter.matches(result)) {
arecipes.add(new CachedInfoPage(page));
}
}
}
@Override
public void loadUsageRecipes(ItemStack ingredient) {
loadCraftingRecipes(ingredient);
}
@Override
public String getGuiTexture() {
return "nei:textures/gui/recipebg.png";
}
private class CachedInfoPage extends CachedRecipe {
private final InformationPage page;
private final PositionedStack stack;
public CachedInfoPage(InformationPage page) {
this.page = page;
stack = new PositionedStack(page.items, 75, 2);
}
@Override
public PositionedStack getResult() {
return null;
}
@Override
public List<PositionedStack> getIngredients() {
return getCycledIngredients(cycleticks / 20, Collections.singletonList(this.stack));
}
public InformationPage getPage() {
return page;
}
}
private static class InformationPage {
final List<ItemStack> items = new ArrayList<>();
final String info;
final ItemFilter filter;
public InformationPage(String filter, String info) {
this.filter = ItemStackFilterParser.parse(filter.trim());
this.info = info;
}
/**
* Adds the item stack if it matches the filter.
*/
public void addItem(ItemStack stack) {
if (filter.matches(stack)) items.add(stack);
}
}
public static void load() {
ClientHandler.loadSettingsFile(
"informationpages.cfg",
lines -> parseFile(lines.collect(Collectors.toCollection(ArrayList::new))));
}
private static void parseFile(List<String> lines) {
for (String rawLine : lines) {
String line = rawLine.trim();
int sepIndex = line.indexOf('=');
if (sepIndex == -1) {
NEIClientConfig.logger.warn("[NEI Info] Invalid line (no '=') in config: {}", line);
continue;
}
String filter = line.substring(0, sepIndex).trim();
String description = line.substring(sepIndex + 1).trim();
addInformationPage(filter, description);
}
}
}
@@ -101,6 +101,8 @@ public class RecipeInfo {
API.registerUsageHandler(new BrewingRecipeHandler());
API.registerRecipeHandler(new FuelRecipeHandler());
API.registerUsageHandler(new FuelRecipeHandler());
API.registerRecipeHandler(new InformationHandler());
API.registerUsageHandler(new InformationHandler());
API.registerGuiOverlay(GuiCrafting.class, "crafting");
API.registerGuiOverlay(GuiInventory.class, "crafting2x2", 63, 20);