Files
CustomNPC-Plus/src/main/java/noppes/npcs/controllers/LinkedItemController.java
T

390 lines
13 KiB
Java
Raw Normal View History

2025-02-13 18:11:58 -06:00
package noppes.npcs.controllers;
2025-02-15 19:37:25 -05:00
import net.minecraft.nbt.CompressedStreamTools;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagList;
2025-02-14 12:28:17 -06:00
import noppes.npcs.CustomNpcs;
2025-02-15 19:37:25 -05:00
import noppes.npcs.LogWriter;
2026-02-24 20:23:44 -03:00
import noppes.npcs.api.handler.ILinkedItemHandler;
2025-02-15 19:37:25 -05:00
import noppes.npcs.api.handler.data.ILinkedItem;
import noppes.npcs.api.item.IItemStack;
import noppes.npcs.controllers.data.IScriptHandler;
2025-02-20 21:40:39 -05:00
import noppes.npcs.controllers.data.LinkedItem;
import noppes.npcs.controllers.data.LinkedItemScript;
2025-02-15 19:37:25 -05:00
import noppes.npcs.util.NBTJsonUtil;
2025-02-13 18:11:58 -06:00
2025-07-23 14:22:52 -04:00
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
2025-02-13 18:11:58 -06:00
import java.util.HashMap;
import java.util.List;
import java.util.Map;
2025-02-15 19:37:25 -05:00
import java.util.zip.GZIPInputStream;
2025-02-13 18:11:58 -06:00
2026-02-24 20:23:44 -03:00
public class LinkedItemController implements ILinkedItemHandler {
2025-02-13 18:11:58 -06:00
private static LinkedItemController Instance;
2025-02-14 12:28:17 -06:00
private int lastUsedID = 0;
2025-02-15 22:59:51 -05:00
public HashMap<Integer, LinkedItem> linkedItems = new HashMap<>();
public HashMap<Integer, LinkedItemScript> linkedItemsScripts = new HashMap<>();
2025-02-13 18:11:58 -06:00
2025-02-15 19:37:25 -05:00
private HashMap<Integer, String> bootOrder;
public CategoryManager categoryManager = new CategoryManager();
2025-02-15 19:37:25 -05:00
2025-03-13 17:14:45 -04:00
private LinkedItemController() {
}
2025-02-13 18:11:58 -06:00
2025-02-16 04:54:21 -05:00
public static LinkedItemController getInstance() {
2025-02-13 18:11:58 -06:00
if (Instance == null) {
Instance = new LinkedItemController();
}
return Instance;
}
2025-03-13 17:14:45 -04:00
2026-02-24 20:23:44 -03:00
@Override
public ILinkedItem createItem(String name) {
2025-02-14 12:28:17 -06:00
return new LinkedItem(name);
}
2026-02-24 20:23:44 -03:00
@Override
public IItemStack createItemStack(int id) {
2026-02-24 20:23:44 -03:00
LinkedItem linkedItem = (LinkedItem) this.get(id);
if (linkedItem != null) {
return linkedItem.createStack();
}
return null;
}
2026-02-24 20:23:44 -03:00
@Override
public void add(ILinkedItem linkedItem) {
2025-02-13 18:11:58 -06:00
if (linkedItem != null) {
String name = linkedItem.getName();
if (name != null && !name.isEmpty()) {
2025-02-14 12:28:17 -06:00
int linkedItemId = linkedItem.getId();
int id = this.linkedItems.containsKey(linkedItemId) ? linkedItemId : this.getUnusedId();
2026-02-24 20:23:44 -03:00
this.linkedItems.put(id, (LinkedItem) linkedItem);
2025-02-14 12:28:17 -06:00
linkedItem.setId(id);
this.addScript(id);
2025-02-13 18:11:58 -06:00
}
}
}
2025-02-14 12:28:17 -06:00
private void addScript(int id) {
2025-02-15 19:37:25 -05:00
this.linkedItemsScripts.put(id, new LinkedItemScript());
2025-02-14 12:28:17 -06:00
}
2026-02-24 20:23:44 -03:00
@Override
2025-02-16 04:54:21 -05:00
public LinkedItem remove(int id) {
2025-02-14 12:28:17 -06:00
this.removeScript(id);
2025-02-16 04:54:21 -05:00
return this.linkedItems.remove(id);
2025-02-14 12:28:17 -06:00
}
private void removeScript(int id) {
this.linkedItemsScripts.remove(id);
}
2026-02-24 20:23:44 -03:00
@Override
2026-02-24 18:35:40 -05:00
public LinkedItem get(int id) {
2026-02-24 20:23:44 -03:00
return (LinkedItem) this.linkedItems.get(id);
2025-02-14 12:28:17 -06:00
}
2026-02-24 20:23:44 -03:00
@Override
2025-02-14 12:28:17 -06:00
public boolean contains(int id) {
return this.linkedItems.containsKey(id);
}
2026-02-24 20:23:44 -03:00
@Override
public boolean contains(ILinkedItem linkedItem) {
return this.linkedItems.containsValue((LinkedItem) linkedItem);
2025-02-14 12:28:17 -06:00
}
public IScriptHandler getScriptHandler(int id) {
2025-02-14 12:28:17 -06:00
return this.linkedItemsScripts.get(id);
2025-02-13 18:11:58 -06:00
}
2025-02-15 19:37:25 -05:00
/// /////////////////////////////////////////////////////
/// /////////////////////////////////////////////////////
2025-02-15 19:37:25 -05:00
2025-03-13 17:14:45 -04:00
public void load() {
2025-04-03 14:01:06 -04:00
lastUsedID = 0;
2025-02-15 19:37:25 -05:00
bootOrder = new HashMap<>();
linkedItems = new HashMap<>();
LogWriter.info("Loading linked items...");
readLinkedMap();
loadLinkedItems();
LogWriter.info("Done loading linked items.");
}
2025-03-13 17:14:45 -04:00
private void loadLinkedItems() {
2025-02-15 19:37:25 -05:00
linkedItems.clear();
File dir = getDir();
if (!dir.exists()) {
dir.mkdir();
return;
}
categoryManager.loadCategories(dir);
// Load uncategorized items (root level .json files)
loadItemsFromDir(dir, CategoryManager.UNCATEGORIZED_ID);
// Load categorized items (subdirectories)
for (Map.Entry<Integer, noppes.npcs.controllers.data.Category> entry : categoryManager.getCategories().entrySet()) {
File catDir = categoryManager.getCategoryDir(entry.getKey());
loadItemsFromDir(catDir, entry.getKey());
2025-02-15 19:37:25 -05:00
}
saveLinkedItemsMap();
}
private void loadItemsFromDir(File dir, int catId) {
File[] files = dir.listFiles();
if (files == null) return;
for (File file : files) {
if (!file.isFile() || !file.getName().endsWith(".json"))
continue;
try {
LinkedItem linkedItem = new LinkedItem();
linkedItem.readFromNBT(NBTJsonUtil.LoadFile(file));
linkedItem.name = file.getName().substring(0, file.getName().length() - 5);
if (linkedItem.id == -1) {
linkedItem.id = getUnusedId();
}
int originalID = linkedItem.id;
int setID = linkedItem.id;
while (bootOrder.containsKey(setID) || linkedItems.containsKey(setID)) {
if (bootOrder.containsKey(setID))
if (bootOrder.get(setID).equals(linkedItem.name))
break;
setID++;
}
linkedItem.id = setID;
if (originalID != setID) {
LogWriter.info("Found Linked Item ID Mismatch: " + linkedItem.name + ", New ID: " + setID);
linkedItem.save();
}
linkedItems.put(linkedItem.id, linkedItem);
categoryManager.registerItem(linkedItem.id, catId);
} catch (Exception e) {
LogWriter.error("Error loading: " + file.getAbsolutePath(), e);
}
}
}
2025-02-15 19:37:25 -05:00
private File getDir() {
return new File(CustomNpcs.getWorldSaveDirectory(), "linkeditems");
}
2025-03-13 17:14:45 -04:00
public int getUnusedId() {
if (lastUsedID == 0) {
for (int catid : linkedItems.keySet()) {
if (catid > lastUsedID)
2025-02-15 19:37:25 -05:00
lastUsedID = catid;
}
}
lastUsedID++;
return lastUsedID;
}
public boolean hasName(String newName) {
2025-03-13 17:14:45 -04:00
if (newName.trim().isEmpty())
2025-02-15 19:37:25 -05:00
return true;
2025-03-13 17:14:45 -04:00
for (LinkedItem linkedItem : linkedItems.values())
if (linkedItem.name.equals(newName))
2025-02-15 19:37:25 -05:00
return true;
return false;
}
2025-03-13 17:14:45 -04:00
public ILinkedItem saveLinkedItem(ILinkedItem linkedItem) {
2025-02-16 04:54:21 -05:00
if (linkedItem.getId() < 0) {
2025-02-15 19:37:25 -05:00
linkedItem.setId(getUnusedId());
2025-02-16 04:54:21 -05:00
while (hasName(linkedItem.getName()))
2025-02-15 19:37:25 -05:00
linkedItem.setName(linkedItem.getName() + "_");
}
2025-02-16 04:54:21 -05:00
while (hasOther(linkedItem.getName(), linkedItem.getId()))
linkedItem.setName(linkedItem.getName() + "_");
2025-02-15 19:37:25 -05:00
linkedItems.remove(linkedItem.getId());
linkedItems.put(linkedItem.getId(), (LinkedItem) linkedItem);
saveLinkedItemsMap();
// Save Linked Item File
File dir = categoryManager.getItemDir(linkedItem.getId());
2025-03-13 17:14:45 -04:00
if (!dir.exists())
2025-02-15 19:37:25 -05:00
dir.mkdirs();
File file = new File(dir, linkedItem.getName() + ".json_new");
2025-03-13 17:14:45 -04:00
File file2 = new File(dir, linkedItem.getName() + ".json");
2025-02-15 19:37:25 -05:00
try {
2025-03-13 17:14:45 -04:00
NBTJsonUtil.SaveFile(file, ((LinkedItem) linkedItem).writeToNBT(true));
if (file2.exists())
2025-02-15 19:37:25 -05:00
file2.delete();
file.renameTo(file2);
} catch (Exception e) {
LogWriter.except(e);
}
return linkedItems.get(linkedItem.getId());
}
2025-02-16 04:54:21 -05:00
private boolean hasOther(String name, int id) {
for (LinkedItem linkedItem : linkedItems.values()) {
if (linkedItem.getId() != id && linkedItem.getName().equalsIgnoreCase(name))
return true;
}
return false;
}
public void delete(int id) {
2026-02-24 20:23:44 -03:00
LinkedItem linkedItem = (LinkedItem) get(id);
2025-02-16 04:54:21 -05:00
if (linkedItem != null) {
LinkedItem foundItem = remove(id);
if (foundItem != null && foundItem.name != null) {
File dir = categoryManager.getItemDir(id);
File file = new File(dir, foundItem.name + ".json");
if (file.exists()) {
file.delete();
2025-02-16 04:54:21 -05:00
}
categoryManager.removeItem(id);
2025-02-16 04:54:21 -05:00
saveLinkedItemsMap();
}
}
}
public void deleteLinkedItemFile(String prevName) {
categoryManager.deleteFile(prevName + ".json");
2025-02-16 04:54:21 -05:00
}
2025-02-15 19:37:25 -05:00
/// /////////////////////////////////////////////////////
/// /////////////////////////////////////////////////////
2025-02-15 19:37:25 -05:00
// LINKED ITEMS MAP
2025-03-13 17:14:45 -04:00
public File getMapDir() {
2025-02-15 19:37:25 -05:00
File dir = CustomNpcs.getWorldSaveDirectory();
2025-03-13 17:14:45 -04:00
if (!dir.exists())
2025-02-15 19:37:25 -05:00
dir.mkdir();
return dir;
}
2025-03-13 17:14:45 -04:00
public void readLinkedMap() {
2025-02-15 19:37:25 -05:00
bootOrder.clear();
try {
File file = new File(getMapDir(), "linkeditems.dat");
2025-03-13 17:14:45 -04:00
if (file.exists()) {
2025-02-15 19:37:25 -05:00
loadLinkedMap(file);
}
} catch (Exception e) {
try {
File file = new File(getMapDir(), "linkeditems.dat_old");
2025-03-13 17:14:45 -04:00
if (file.exists()) {
2025-02-15 19:37:25 -05:00
loadLinkedMap(file);
}
2025-03-13 17:14:45 -04:00
} catch (Exception ignored) {
}
2025-02-15 19:37:25 -05:00
}
}
2025-03-13 17:14:45 -04:00
public NBTTagCompound writeMapNBT() {
2025-02-15 19:37:25 -05:00
NBTTagCompound nbt = new NBTTagCompound();
NBTTagList linkedList = new NBTTagList();
2025-03-13 17:14:45 -04:00
for (Integer key : linkedItems.keySet()) {
2025-02-15 19:37:25 -05:00
LinkedItem linkedItem = linkedItems.get(key);
2025-03-13 17:14:45 -04:00
if (!linkedItem.getName().isEmpty()) {
2025-02-15 19:37:25 -05:00
NBTTagCompound linkedCompound = new NBTTagCompound();
linkedCompound.setString("Name", linkedItem.getName());
linkedCompound.setInteger("ID", key);
linkedList.appendTag(linkedCompound);
}
}
nbt.setTag("LinkedItems", linkedList);
2025-04-03 14:01:06 -04:00
nbt.setInteger("lastID", lastUsedID);
2025-02-15 19:37:25 -05:00
return nbt;
}
2025-03-13 17:14:45 -04:00
public void readMapNBT(NBTTagCompound compound) {
2025-04-03 14:01:06 -04:00
lastUsedID = compound.getInteger("lastID");
2025-02-15 19:37:25 -05:00
NBTTagList list = compound.getTagList("LinkedItems", 10);
2025-03-13 17:14:45 -04:00
if (list != null) {
for (int i = 0; i < list.tagCount(); i++) {
2025-02-15 19:37:25 -05:00
NBTTagCompound nbttagcompound = list.getCompoundTagAt(i);
String linkedName = nbttagcompound.getString("Name");
Integer key = nbttagcompound.getInteger("ID");
bootOrder.put(key, linkedName);
}
}
}
private void loadLinkedMap(File file) throws IOException {
DataInputStream var1 = new DataInputStream(new BufferedInputStream(new GZIPInputStream(new FileInputStream(file))));
readLinkedMap(var1);
var1.close();
}
2025-03-13 17:14:45 -04:00
public void readLinkedMap(DataInputStream stream) throws IOException {
2025-02-15 19:37:25 -05:00
NBTTagCompound nbtCompound = CompressedStreamTools.read(stream);
this.readMapNBT(nbtCompound);
}
2025-03-13 17:14:45 -04:00
public void saveLinkedItemsMap() {
2025-02-15 19:37:25 -05:00
try {
File saveDir = getMapDir();
File file = new File(saveDir, "linkeditems.dat_new");
File file1 = new File(saveDir, "linkeditems.dat_old");
File file2 = new File(saveDir, "linkeditems.dat");
CompressedStreamTools.writeCompressed(this.writeMapNBT(), new FileOutputStream(file));
2025-03-13 17:14:45 -04:00
if (file1.exists()) {
2025-02-15 19:37:25 -05:00
file1.delete();
}
file2.renameTo(file1);
2025-03-13 17:14:45 -04:00
if (file2.exists()) {
2025-02-15 19:37:25 -05:00
file2.delete();
}
file.renameTo(file2);
2025-03-13 17:14:45 -04:00
if (file.exists()) {
2025-02-15 19:37:25 -05:00
file.delete();
}
} catch (Exception e) {
LogWriter.except(e);
}
}
////////////////////////////////////////////////////////
// CATEGORY HELPERS
2025-02-15 19:37:25 -05:00
////////////////////////////////////////////////////////
public Map<String, Integer> getCategoryScrollData() {
return categoryManager.getCategoryScrollData();
}
public void moveItemToCategory(int itemId, int catId) {
LinkedItem item = linkedItems.get(itemId);
if (item == null) return;
categoryManager.moveItem(itemId, item.name + ".json", catId);
saveLinkedItemsMap();
}
public Map<String, Integer> getItemsByCategoryScrollData(int catId) {
Map<String, Integer> map = new HashMap<>();
List<Integer> itemIds = categoryManager.getItemsInCategory(catId, linkedItems.keySet());
for (int itemId : itemIds) {
LinkedItem item = linkedItems.get(itemId);
if (item != null) {
map.put(item.name, item.id);
}
}
return map;
}
2025-02-13 18:11:58 -06:00
}