diff --git a/src/main/java/noppes/npcs/config/ConfigMain.java b/src/main/java/noppes/npcs/config/ConfigMain.java index 7e6e6bed7..c35a6f668 100644 --- a/src/main/java/noppes/npcs/config/ConfigMain.java +++ b/src/main/java/noppes/npcs/config/ConfigMain.java @@ -60,6 +60,9 @@ public class ConfigMain public static Property SoulStoneFriendlyNPCsProperty; public static boolean SoulStoneFriendlyNPCs = false; + public static Property DatFormatProperty; + public static boolean DatFormat = false; + /** * General NPC Properties **/ @@ -143,6 +146,8 @@ public class ConfigMain SoulStoneFriendlyNPCsProperty = config.get(GENERAL, "Normal playes can use soulstone on Friendly NPCs", false); SoulStoneFriendlyNPCs = SoulStoneFriendlyNPCsProperty.getBoolean(false); + DatFormatProperty = config.get(GENERAL, "Dat Format for PlayerData", false, "This will convert all existing JSON PlayerData files to (.dat). Huge Performance Boost."); + DatFormat = DatFormatProperty.getBoolean(false); // NPC NpcNavRangeProperty = config.get(NPC, "NPC Navigation Range", 32, "Navigation search range for NPCs. Not recommended to increase if you have a slow pc or on a server. Minimum of 16, maximum of 96."); diff --git a/src/main/java/noppes/npcs/controllers/PlayerDataController.java b/src/main/java/noppes/npcs/controllers/PlayerDataController.java index 1ce1846c3..81680762f 100644 --- a/src/main/java/noppes/npcs/controllers/PlayerDataController.java +++ b/src/main/java/noppes/npcs/controllers/PlayerDataController.java @@ -11,7 +11,9 @@ import net.minecraft.server.MinecraftServer; import net.minecraft.util.ChatComponentText; import noppes.npcs.CustomNpcs; import noppes.npcs.LogWriter; +import noppes.npcs.config.ConfigMain; import noppes.npcs.controllers.data.*; +import noppes.npcs.util.CustomNPCsThreader; import noppes.npcs.util.NBTJsonUtil; import java.io.*; @@ -47,12 +49,20 @@ public class PlayerDataController { // Load the files in parallel using a stream for(int i = 0; i < length; i++){ File file = files[i]; - if(file.isDirectory() || !file.getName().endsWith(".json")) + if(file.isDirectory() || (!file.getName().endsWith(".json") && !file.getName().endsWith(".dat"))) continue; try { - NBTTagCompound compound = NBTJsonUtil.LoadFile(file); - if(compound.hasKey("PlayerName")){ - map.put(compound.getString("PlayerName"), file.getName().substring(0, file.getName().length() - 5)); + if(file.getName().endsWith(".json")){ + NBTTagCompound compound = NBTJsonUtil.LoadFile(file); + if(compound.hasKey("PlayerName")){ + map.put(compound.getString("PlayerName"), file.getName().substring(0, file.getName().length() - 5)); + } + } + if(file.getName().endsWith(".dat")){ + NBTTagCompound compound = loadNBTData(file); + if(compound.hasKey("PlayerName")){ + map.put(compound.getString("PlayerName"), file.getName().substring(0, file.getName().length() - 4)); + } } } catch (Exception e) { LogWriter.error("Error loading: " + file.getAbsolutePath(), e); @@ -75,65 +85,9 @@ public class PlayerDataController { LogWriter.info("Done loading PlayerData"); } - public void generatePlayerMap(EntityPlayerMP sender){ - ExecutorService executor = Executors.newSingleThreadExecutor(); - executor.execute(() -> { - if(sender != null){ - LogWriter.info("PlayerMap regeneration queued by " + sender.getCommandSenderName()); - sender.addChatMessage(new ChatComponentText("You have initiated PlayerMap regeneration")); - } - nameUUIDs.clear(); - - File dir = getSaveDir(); - LogWriter.info("Generating PlayerData map file..."); - File[] files = dir.listFiles(); // Get an array of all files in the directory - HashMap map = new HashMap(); - if(files != null){ - int length = files.length; - if(length != 0){ - if(length > 100){ - LogWriter.info("Found " + length + " PlayerData files... This may take a few minutes"); - } - int tenPercent = (int) ((double) length * 0.1); - int progress = 0; - // Load the files in parallel using a stream - for(int i = 0; i < length; i++){ - File file = files[i]; - if(file.isDirectory() || !file.getName().endsWith(".json")) - continue; - try { - NBTTagCompound compound = NBTJsonUtil.LoadFile(file); - if(compound.hasKey("PlayerName")){ - map.put(compound.getString("PlayerName"), file.getName().substring(0, file.getName().length() - 5)); - } - } catch (Exception e) { - LogWriter.error("Error loading: " + file.getAbsolutePath(), e); - } - if(tenPercent != 0 ){ - if(progress != 100){ - if (i % tenPercent == 0) { - progress += 10; - LogWriter.info("Creating PlayerMap: Progress: " + progress + "%"); - } - } - } - } - } - } - nameUUIDs = map; - savePlayerDataMap(); - - if(sender != null){ - sender.addChatMessage(new ChatComponentText("PlayerMap regeneration complete")); - } - }); - - executor.shutdown(); - } - public boolean getPlayerDataMap(){ try { - File file = new File(getSaveDir(), "___playermap.dat"); + File file = new File(CustomNpcs.getWorldSaveDirectory(), "playerdatamap.dat"); if(file.exists()){ loadPlayerDataMap(file); return true; @@ -142,7 +96,7 @@ public class PlayerDataController { LogWriter.except(e); } try { - File file = new File(getSaveDir(), "___playermap.dat_old"); + File file = new File(CustomNpcs.getWorldSaveDirectory(), "playerdatamap.dat_old"); if(file.exists()){ loadPlayerDataMap(file); return true; @@ -207,6 +161,19 @@ public class PlayerDataController { } } + public File getNewSaveDir(){ + try{ + File file = new File(CustomNpcs.getWorldSaveDirectory(),"playerdata_new"); + if(!file.exists()) + file.mkdir(); + return file; + } + catch (Exception e) { + e.printStackTrace(); + return null; + } + } + public NBTTagCompound loadPlayerDataOld(String player){ File saveDir = getSaveDir(); String filename = player; @@ -244,11 +211,20 @@ public class PlayerDataController { String filename = player; if(filename.isEmpty()) filename = "noplayername"; - filename += ".json"; + + if(ConfigMain.DatFormat){ + filename += ".dat"; + } else { + filename += ".json"; + } try { File file = new File(saveDir, filename); if(file.exists()){ - return NBTJsonUtil.LoadFile(file); + if(ConfigMain.DatFormat){ + return loadNBTData(file); + } else { + return NBTJsonUtil.LoadFile(file); + } } } catch (Exception e) { LogWriter.error("Error loading: " + filename, e); @@ -257,6 +233,15 @@ public class PlayerDataController { return new NBTTagCompound(); } + public NBTTagCompound loadNBTData(File file){ + try { + return CompressedStreamTools.readCompressed(new FileInputStream(file)); + } catch (Exception e) { + LogWriter.error("Error loading: " + file.getName(), e); + } + return new NBTTagCompound(); + } + public PlayerBankData getBankData(EntityPlayer player, int bankId) { Bank bank = BankController.getInstance().getBank(bankId); PlayerBankData data = getPlayerData(player).bankData; @@ -364,4 +349,161 @@ public class PlayerDataController { nbt.setTag("PlayerDataMap", playerList); return nbt; } + + public void generatePlayerMap(EntityPlayerMP sender){ + ExecutorService executor = Executors.newSingleThreadExecutor(); + executor.execute(() -> { + if(sender != null){ + LogWriter.info("PlayerMap regeneration queued by " + sender.getCommandSenderName()); + sender.addChatMessage(new ChatComponentText("You have initiated PlayerMap regeneration")); + } + nameUUIDs.clear(); + + File dir = getSaveDir(); + LogWriter.info("Generating PlayerData map file..."); + File[] files = dir.listFiles(); // Get an array of all files in the directory + HashMap map = new HashMap(); + if(files != null){ + int length = files.length; + if(length != 0){ + if(length > 100){ + LogWriter.info("Found " + length + " PlayerData files... This may take a few minutes"); + } + int tenPercent = (int) ((double) length * 0.1); + int progress = 0; + // Load the files in parallel using a stream + for(int i = 0; i < length; i++){ + File file = files[i]; + if(file.isDirectory() || (!file.getName().endsWith(".json") && !file.getName().endsWith(".dat"))) + continue; + try { + if(file.getName().endsWith(".json")){ + NBTTagCompound compound = NBTJsonUtil.LoadFile(file); + if(compound.hasKey("PlayerName")){ + map.put(compound.getString("PlayerName"), file.getName().substring(0, file.getName().length() - 5)); + } + } + if(file.getName().endsWith(".dat")){ + NBTTagCompound compound = loadNBTData(file); + if(compound.hasKey("PlayerName")){ + map.put(compound.getString("PlayerName"), file.getName().substring(0, file.getName().length() - 4)); + } + } + } catch (Exception e) { + LogWriter.error("Error loading: " + file.getAbsolutePath(), e); + } + if(tenPercent != 0 ){ + if(progress != 100){ + if (i % tenPercent == 0) { + progress += 10; + LogWriter.info("Creating PlayerMap: Progress: " + progress + "%"); + } + } + } + } + } + } + nameUUIDs = map; + savePlayerDataMap(); + if(sender != null){ + sender.addChatMessage(new ChatComponentText("PlayerMap regeneration complete")); + } + }); + + executor.shutdown(); + } + + public void convertPlayerFiles(final EntityPlayerMP sender, final boolean type){ + ExecutorService executor = Executors.newSingleThreadExecutor(); + executor.execute(() -> { + String fileType; + if(type){ + fileType = ".dat"; + } + else { + fileType = ".json"; + } + + if(sender != null){ + LogWriter.info("PlayerData Conversion queued by " + sender.getCommandSenderName()); + sender.addChatMessage(new ChatComponentText("PlayerData Conversion to " + fileType + " format")); + } + + File dir = getSaveDir(); + LogWriter.info("Converting PlayerData to " + fileType + " format"); + File[] files = dir.listFiles(); // Get an array of all files in the directory + if(files != null){ + int length = files.length; + if(length != 0){ + if(length > 100){ + LogWriter.info("Found " + length + " PlayerData files... This may take a few minutes"); + } + int tenPercent = (int) ((double) length * 0.1); + int progress = 0; + // Load the files in parallel using a stream + for(int i = 0; i < length; i++){ + File file = files[i]; + if(file.isDirectory() || (!file.getName().endsWith(".json") && !file.getName().endsWith(".dat"))) + continue; + try { + String filename = "error"; + boolean valid = false; + NBTTagCompound compound = new NBTTagCompound(); + if(type){ + if(file.getName().endsWith(".json")){ + compound = NBTJsonUtil.LoadFile(file); + if(compound.hasKey("PlayerName")) { + filename = file.getName().substring(0, file.getName().length() - 5); + valid = true; + } + } + } else { + if(file.getName().endsWith(".dat")){ + compound = loadNBTData(file); + if(compound.hasKey("PlayerName")){ + filename = file.getName().substring(0, file.getName().length() - 4); + valid = true; + } + } + } + if(valid){ + try { + File saveDir = PlayerDataController.instance.getNewSaveDir(); + File newFile = new File(saveDir, filename + "_new"); + File oldFile = new File(saveDir, filename); + if(type){ + CompressedStreamTools.writeCompressed(compound, new FileOutputStream(newFile)); + } else { + NBTJsonUtil.SaveFile(newFile, compound); + } + if(oldFile.exists()){ + oldFile.delete(); + } + newFile.renameTo(oldFile); + } catch (Exception e) { + LogWriter.except(e); + } + } + } catch (Exception e) { + LogWriter.error("Error loading: " + file.getAbsolutePath(), e); + } + if(tenPercent != 0 ){ + if(progress != 100){ + if (i % tenPercent == 0) { + progress += 10; + LogWriter.info("Converting PlayerData: Progress: " + progress + "%"); + } + } + } + } + } + } + if(sender != null){ + sender.addChatMessage(new ChatComponentText("PlayerData Conversion complete")); + } + LogWriter.info("PlayerData Converted - Please rename the playerdata_new folder to playerdata"); + }); + + executor.shutdown(); + } } \ No newline at end of file diff --git a/src/main/java/noppes/npcs/controllers/data/PlayerData.java b/src/main/java/noppes/npcs/controllers/data/PlayerData.java index ba9deab99..60897d337 100644 --- a/src/main/java/noppes/npcs/controllers/data/PlayerData.java +++ b/src/main/java/noppes/npcs/controllers/data/PlayerData.java @@ -2,6 +2,7 @@ package noppes.npcs.controllers.data; import net.minecraft.entity.Entity; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.CompressedStreamTools; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.world.World; import net.minecraftforge.common.IExtendedEntityProperties; @@ -10,6 +11,7 @@ import noppes.npcs.CustomNpcs; import noppes.npcs.LogWriter; import noppes.npcs.api.entity.ICustomNpc; import noppes.npcs.api.handler.*; +import noppes.npcs.config.ConfigMain; import noppes.npcs.constants.EnumRoleType; import noppes.npcs.controllers.PlayerDataController; import noppes.npcs.entity.EntityCustomNpc; @@ -22,6 +24,7 @@ import noppes.npcs.util.CustomNPCsThreader; import noppes.npcs.util.NBTJsonUtil; import java.io.File; +import java.io.FileOutputStream; public class PlayerData implements IExtendedEntityProperties, IPlayerData { public PlayerDialogData dialogData = new PlayerDialogData(this); @@ -230,13 +233,22 @@ public class PlayerData implements IExtendedEntityProperties, IPlayerData { public synchronized void save() { final NBTTagCompound compound = getNBT(); - final String filename = uuid + ".json"; + final String filename; + if(ConfigMain.DatFormat){ + filename = uuid + ".json"; + } else { + filename = uuid + ".dat"; + } CustomNPCsThreader.playerDataThread.execute(() -> { try { File saveDir = PlayerDataController.instance.getSaveDir(); File file = new File(saveDir, filename + "_new"); File file1 = new File(saveDir, filename); - NBTJsonUtil.SaveFile(file, compound); + if(ConfigMain.DatFormat){ + CompressedStreamTools.writeCompressed(compound, new FileOutputStream(file)); + } else { + NBTJsonUtil.SaveFile(file, compound); + } if(file1.exists()){ file1.delete(); }