Add feature to save history like bookmarks (#1011)

Co-authored-by: slprime <31038811+slprime@users.noreply.github.com>
This commit is contained in:
vcwdfcaandslprime authored and GitHub committed 2026-08-26 13:40:18 +03:00
1 parent 4c74a01930
commit bd595f739c
4 files changed
+153

No files matched your search

@@ -1,17 +1,34 @@
package codechicken.nei;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import org.apache.commons.io.IOUtils;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import codechicken.core.CommonUtils;
import codechicken.nei.ItemsGrid.ItemsGridSlot;
import codechicken.nei.ItemsGrid.MouseContext;
import codechicken.nei.recipe.Recipe.RecipeId;
import codechicken.nei.recipe.StackInfo;
import codechicken.nei.util.NBTJson;
public class ItemHistoryPanel extends AbstractSubpanel<ItemsGrid<ItemHistoryPanel.HistoryGridSlot, MouseContext>> {
protected File historyFile = null;
public static class HistoryGridSlot extends ItemsGridSlot {
public HistoryGridSlot(int slotIndex, int itemIndex, ItemStack item) {
@@ -115,4 +132,107 @@ public class ItemHistoryPanel extends AbstractSubpanel<ItemsGrid<ItemHistoryPane
}
}
public void load() {
if (!NEIClientConfig.getBooleanSetting("inventory.history.save")) {
return;
}
String worldPath = "global";
if (NEIClientConfig.getBooleanSetting("inventory.history.worldSpecific")) {
worldPath = NEIClientConfig.getWorldPath();
}
final File dir = new File(CommonUtils.getMinecraftDir(), "saves/NEI/" + worldPath);
if (!dir.exists()) {
dir.mkdirs();
}
final File historyFile = new File(dir, "history.ini");
if (historyFile.equals(this.historyFile)) {
return;
}
List<String> itemStrings = Collections.emptyList();
if (historyFile.exists()) {
try (FileInputStream reader = new FileInputStream(historyFile)) {
NEIClientConfig.logger.info("Loading history from file {}", historyFile);
itemStrings = IOUtils.readLines(reader, StandardCharsets.UTF_8);
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to load history from file {}", historyFile, e);
return;
}
}
final JsonParser parser = new JsonParser();
final int maxSize = Math.max(50, this.grid.rows * this.grid.columns);
this.grid.realItems.clear();
for (String itemStr : itemStrings) {
if (itemStr.isEmpty()) {
continue;
}
if (this.grid.realItems.size() >= maxSize) {
break;
}
try {
JsonObject row = parser.parse(itemStr).getAsJsonObject();
NBTTagCompound itemStackNBT = (NBTTagCompound) NBTJson.toNbt(row.get("item"));
ItemStack itemStack = StackInfo.loadFromNBT(itemStackNBT);
if (itemStack != null) {
this.grid.realItems.add(itemStack);
} else {
NEIClientConfig.logger.warn(
"Failed to load history ItemStack from json string, the item no longer exists:\n{}",
itemStr);
}
} catch (Exception e) {
NEIClientConfig.logger.error("Failed to load history ItemStack from json string:\n{}", itemStr);
}
}
this.grid.onItemsChanged();
this.historyFile = historyFile;
}
public void save() {
if (!NEIClientConfig.getBooleanSetting("inventory.history.save")) {
return;
}
if (this.historyFile == null) {
return;
}
final List<String> strings = new ArrayList<>();
for (ItemStack stack : this.grid.realItems) {
try {
final JsonObject row = new JsonObject();
row.add("item", NBTJson.toJsonObject(StackInfo.itemStackToNBT(stack)));
strings.add(NBTJson.toJson(row));
} catch (JsonSyntaxException e) {
NEIClientConfig.logger.error("Failed to stringify history ItemStack to json string");
}
}
try (FileOutputStream output = new FileOutputStream(this.historyFile)) {
IOUtils.writeLines(strings, "\n", output, StandardCharsets.UTF_8);
} catch (IOException e) {
NEIClientConfig.logger.error("Failed to save history list to file {}", this.historyFile, e);
}
}
}
@@ -293,6 +293,7 @@ public class ItemListLoader {
updateFilter.restart();
warmTooltips.restart();
loadBookmarks.restart();
loadHistory.restart();
}
};
@@ -319,6 +320,14 @@ public class ItemListLoader {
}
};
public static final RestartableTask loadHistory = new RestartableTask("NEI History Loading") {
@Override
public void execute() {
ItemPanels.itemPanel.historyPanel.load();
}
};
public static final RestartableTask refreshItems = new RestartableTask("NEI Item Reordering") {
@Override
@@ -340,6 +349,7 @@ public class ItemListLoader {
SubsetWidget.updateHiddenItems();
updateFilter.restart();
loadBookmarks.restart();
loadHistory.restart();
}
};
@@ -288,6 +288,22 @@ public class NEIClientConfig {
tag.getTag("inventory.history.useRows").setComment("Rows used in historical areas").getIntValue(2);
API.addOption(new OptionIntegerField("inventory.history.useRows", 1, 5));
tag.getTag("inventory.history.worldSpecific").setComment("Global or world specific history")
.getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.history.worldSpecific", true) {
@Override
public boolean onClick(int button) {
super.onClick(button);
ItemPanels.itemPanel.historyPanel.save();
ItemPanels.itemPanel.historyPanel.load();
return true;
}
});
tag.getTag("inventory.history.save").setComment("Enable/disable History save").getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.history.save", true));
tag.getTag("inventory.craftables.enabled").setComment("Enable/disable Craftables Panel").getBooleanValue(false);
API.addOption(new OptionToggleButton("inventory.craftables.enabled", true));
@@ -927,6 +943,7 @@ public class NEIClientConfig {
}
ItemPanels.bookmarkPanel.save();
ItemPanels.itemPanel.historyPanel.save();
SubsetWidget.saveHidden();
FavoriteRecipes.save();
@@ -439,6 +439,12 @@ nei.options.inventory.history.enabled.true=Enabled
nei.options.inventory.history.enabled.false=Disabled
nei.options.inventory.history.color=Color
nei.options.inventory.history.useRows=Rows
nei.options.inventory.history.worldSpecific=World Specific
nei.options.inventory.history.worldSpecific.true=Yes
nei.options.inventory.history.worldSpecific.false=No
nei.options.inventory.history.save=Save
nei.options.inventory.history.save.true=Enabled
nei.options.inventory.history.save.false=Disabled
nei.options.inventory.craftables=Craftables Panel
nei.options.inventory.craftables.enabled=Craftables Panel Visibility
nei.options.inventory.craftables.enabled.true=Enabled