diff --git a/src/main/java/kamkeel/command/CommandKamkeelBase.java b/src/main/java/kamkeel/command/CommandKamkeelBase.java index 0ebc6bf88..5249ce598 100644 --- a/src/main/java/kamkeel/command/CommandKamkeelBase.java +++ b/src/main/java/kamkeel/command/CommandKamkeelBase.java @@ -56,11 +56,11 @@ public abstract class CommandKamkeelBase extends CommandBase{ return !subcommands.isEmpty(); } - protected void sendMessage(ICommandSender sender, String message, Object... obs) { + protected static void sendMessage(ICommandSender sender, String message, Object... obs) { sender.addChatMessage(new ChatComponentTranslation(message, obs)); } - protected void sendResult(ICommandSender sender, String message, Object... obs) { + protected static void sendResult(ICommandSender sender, String message, Object... obs) { sender.addChatMessage(new ChatComponentTranslation("\u00A76[\u00A7eCNPC+\u00A76]\u00A77 " + message, obs)); } diff --git a/src/main/java/kamkeel/command/ConfigCommand.java b/src/main/java/kamkeel/command/ConfigCommand.java index b6765345d..780f2bcb4 100644 --- a/src/main/java/kamkeel/command/ConfigCommand.java +++ b/src/main/java/kamkeel/command/ConfigCommand.java @@ -13,6 +13,7 @@ import noppes.npcs.Server; import noppes.npcs.config.ConfigMain; import noppes.npcs.constants.EnumPacketClient; import noppes.npcs.controllers.ChunkController; +import noppes.npcs.controllers.PlayerDataController; import java.util.Arrays; import java.util.Set; @@ -172,6 +173,53 @@ public class ConfigCommand extends CommandKamkeelBase { sendResult(sender, "ChunkLoaders: \u00A7c" + ChunkController.instance.size() + "\u00A77/\u00A7c" + ConfigMain.ChunkLoaders); } } + + @SubCommand( + desc = "Generate PlayerData to JSON/DAT", + usage = "[fileType] [convert]", + permission = 4 + ) + public void playerdata(ICommandSender sender, String[] args) throws CommandException{ + String fileType; + if(ConfigMain.DatFormat){ + fileType = "DAT"; + } + else { + fileType = "JSON"; + } + if(args.length == 0){ + sendResult(sender, "PlayerData Filetype: \u00A7c" + fileType); + } + else if(args.length == 1){ + sendResult(sender, "Please write the word 'convert' at the end to confirm. \u00A7c convert"); + } + else{ + if(args.length != 2){ + sendError(sender, "Two many arguments"); + return; + } + String formatType = args[0].toLowerCase(); + if(!formatType.equals("dat") && !formatType.equals("json")){ + sendError(sender, "Invalid Format Type - Please use dat or json"); + return; + } + + String convert = args[1].toLowerCase(); + if(!convert.equals("convert")){ + sendError(sender, "Please enter the word 'convert' at the end"); + return; + } + + boolean convertToDat = formatType.equals("dat"); + EntityPlayerMP send = null; + if(sender instanceof EntityPlayerMP){ + send = (EntityPlayerMP) sender; + } + + sendResult(sender, "Started Conversion Process for PlayerData"); + PlayerDataController.instance.convertPlayerFiles(send, convertToDat); + } + } @SubCommand( desc = "Get/Set font", diff --git a/src/main/java/noppes/npcs/NoppesUtilServer.java b/src/main/java/noppes/npcs/NoppesUtilServer.java index f1df000c9..cf0643c95 100644 --- a/src/main/java/noppes/npcs/NoppesUtilServer.java +++ b/src/main/java/noppes/npcs/NoppesUtilServer.java @@ -25,6 +25,7 @@ import net.minecraft.util.DamageSource; import net.minecraft.util.MathHelper; import net.minecraft.world.World; import noppes.npcs.api.entity.IPlayer; +import noppes.npcs.config.ConfigMain; import noppes.npcs.constants.EnumGuiType; import noppes.npcs.constants.EnumPacketClient; import noppes.npcs.constants.EnumPlayerData; @@ -493,7 +494,11 @@ public class NoppesUtilServer { playerdata = PlayerDataController.instance.getPlayerData(pl); if(type == EnumPlayerData.Players){ - File file = new File(PlayerDataController.instance.getSaveDir(), playerdata.uuid + ".json"); + String fileType = ".json"; + if(ConfigMain.DatFormat){ + fileType = ".dat"; + } + File file = new File(PlayerDataController.instance.getSaveDir(), playerdata.uuid + fileType); if(file.exists()) file.delete(); if(pl != null){ 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..28204067c 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; @@ -169,10 +123,10 @@ public class PlayerDataController { public synchronized void savePlayerDataMap(){ playerDataThread.execute(() -> { try { - File saveDir = getSaveDir(); - File file = new File(saveDir, "___playermap.dat_new"); - File file1 = new File(saveDir, "___playermap.dat_old"); - File file2 = new File(saveDir, "___playermap.dat"); + File saveDir = CustomNpcs.getWorldSaveDirectory(); + File file = new File(saveDir, "playerdatamap.dat_new"); + File file1 = new File(saveDir, "playerdatamap.dat_old"); + File file2 = new File(saveDir, "playerdatamap.dat"); CompressedStreamTools.writeCompressed(writeNBT(), new FileOutputStream(file)); if(file1.exists()) { @@ -207,6 +161,21 @@ public class PlayerDataController { } } + public File getNewSaveDir(){ + try{ + File file = new File(CustomNpcs.getWorldSaveDirectory(),"playerdata_new"); + if(file.exists()){ + return null; + } + file.mkdir(); + return file; + } + catch (Exception e) { + e.printStackTrace(); + return null; + } + } + public NBTTagCompound loadPlayerDataOld(String player){ File saveDir = getSaveDir(); String filename = player; @@ -244,11 +213,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 +235,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; @@ -292,7 +279,7 @@ public class PlayerDataController { for(String name : nameUUIDs.keySet()){ if(name.equalsIgnoreCase(username)){ data = new PlayerData(); - data.setNBT(PlayerData.loadPlayerData(nameUUIDs.get(name))); + data.setNBT(PlayerDataController.instance.loadPlayerData(nameUUIDs.get(name))); break; } } @@ -364,4 +351,168 @@ 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; + File saveDir = PlayerDataController.instance.getNewSaveDir(); + if(saveDir == null){ + if(sender != null){ + sender.addChatMessage(new ChatComponentText("playerdata_new folder already exists please delete it or rename it")); + } + LogWriter.error("playerdata_new folder already exists please delete it or rename it"); + return; + } + // 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 newFile = new File(saveDir, filename + "_new" + fileType); + File oldFile = new File(saveDir, filename + fileType); + 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..8689c90c9 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); @@ -166,28 +169,6 @@ public class PlayerData implements IExtendedEntityProperties, IPlayerData { world.spawnEntityInWorld(npc); } - public static NBTTagCompound loadPlayerData(String player) { - File saveDir = CustomNpcs.getWorldSaveDirectory("playerdata"); - String filename = player; - if (player.isEmpty()) { - filename = "noplayername"; - } - - filename = filename + ".json"; - File file = null; - - try { - file = new File(saveDir, filename); - if (file.exists()) { - return NBTJsonUtil.LoadFile(file); - } - } catch (Exception var5) { - LogWriter.error("Error loading: " + file.getAbsolutePath(), var5); - } - - return new NBTTagCompound(); - } - public void setCompanion(ICustomNpc npc) { this.setCompanion((EntityNPCInterface) npc.getMCEntity()); } @@ -230,13 +211,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 + ".dat"; + } else { + filename = uuid + ".json"; + } 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(); }