I'm trying to save the "skill-level" of players into a config file, so when a player joins, a new line is created, for example when Balloonman joins, then this would be added into the config file: BalloonMan: 0 Then, I can fetch BalloonMan's value anywhere and change it anytime. How do I do this?
This is a method in the config API: Code:java getConfig().set("config.path.with.indents.separated.by.dots", value); So in this case, the config path (which is the term for the location of your "BalloonMan: 0" in your config hierarchy) would simply be "BalloonMan", and your value will be the number 0. Edit: Oh, and this is very important. Code:java saveConfig(); You must do this every time you finish editing a config file.
pookeythekid Thanks! It helped a lot. But is there a way to check if that path already exists? Right now I'm using p.hasPlayedBefore(), but I worry that players who have played the server before would not have this config created for them.
Hex_27 Yup. Code:java config.contains("config.path") // This is a boolean method Explanation in Bukkit JavaDocs: http://jd.bukkit.org/dev/apidocs/or...MemorySection.html#contains(java.lang.String)
pookeythekid This is my code. Somehow, when a new player joins, nothing happens. Code:java package me.leothepro555.random; import org.bukkit.entity.Player;import org.bukkit.event.EventHandler;import org.bukkit.event.Listener;import org.bukkit.event.player.PlayerJoinEvent; public class LeaveManager implements Listener{ public Main plugin; public LeaveManager(Main plugin) {this.plugin = plugin;}@EventHandlerpublic void onPlayerJoin(PlayerJoinEvent event){Player p = event.getPlayer();if(plugin.config.contains(p.getName())&&plugin.skill.contains(p.getName())){String playername = event.getPlayer().getName();plugin.config.set(playername, 0);plugin.saveLevels();plugin.skill.set(playername, "none");plugin.saveSkills();}} }
pookeythekid sure Code:java package me.leothepro555.random; import java.io.File;import java.io.IOException;import java.util.HashSet;import java.util.UUID; import org.bukkit.Bukkit;import org.bukkit.ChatColor;import org.bukkit.command.Command;import org.bukkit.command.CommandSender;import org.bukkit.configuration.file.FileConfiguration;import org.bukkit.configuration.file.YamlConfiguration;import org.bukkit.entity.Player;import org.bukkit.event.Listener;import org.bukkit.plugin.java.JavaPlugin; public class Main extends JavaPlugin implements Listener{ HashSet<UUID> weaponsmasters = new HashSet<UUID>(); HashSet<UUID> rangers = new HashSet<UUID>(); HashSet<UUID> mages = new HashSet<UUID>(); HashSet<UUID> pyros = new HashSet<UUID>(); HashSet<UUID> juggernauts = new HashSet<UUID>(); public File file = new File("plugins/Skills/levels.yml"); public FileConfiguration config = YamlConfiguration.loadConfiguration(this.file); public File anotherfile = new File("plugins/Skills/skills.yml"); public FileConfiguration skill = YamlConfiguration.loadConfiguration(this.anotherfile); public void saveLevels() { try { this.config.save(this.file); this.config = YamlConfiguration.loadConfiguration(this.file); } catch (IOException e) { e.printStackTrace(); } } public void saveSkills() { try { this.config.save(this.anotherfile); this.config = YamlConfiguration.loadConfiguration(this.anotherfile); } catch (IOException e) { e.printStackTrace(); } } public void onEnable(){ getConfig().options().copyDefaults(true); saveDefaultConfig(); config.options().copyDefaults(true); saveLevels(); skill.options().copyDefaults(true); saveSkills(); Bukkit.getServer().getPluginManager().registerEvents(new LeaveManager(this), this); } public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { if(cmd.getName().equalsIgnoreCase("skill")){ if(sender instanceof Player){ Player p = (Player) sender; if(args.length != 0){ if(args[0].equalsIgnoreCase("select")){ if(args.length == 2){ if(this.skill.getString(p.getName()) == "none"){ if(args[1].equalsIgnoreCase("pyro")){ skill.set(p.getName(), "pyro"); saveSkills(); p.sendMessage(ChatColor.BLUE + "You are now a " + args[1]); }else if(args[1].equalsIgnoreCase("juggernaut")){ skill.set(p.getName(), "juggernaut"); saveSkills(); p.sendMessage(ChatColor.BLUE + "You are now a " + args[1]); }else if(args[1].equalsIgnoreCase("ranger")){ skill.set(p.getName(), "ranger"); saveSkills(); p.sendMessage(ChatColor.BLUE + "You are now a " + args[1]); }else if(args[1].equalsIgnoreCase("weaponsmaster")){ skill.set(p.getName(), "weaponsmaster"); saveSkills(); p.sendMessage(ChatColor.BLUE + "You are now a " + args[1]); }else if(args[1].equalsIgnoreCase("mage")){ skill.set(p.getName(), "mage"); saveSkills(); p.sendMessage(ChatColor.BLUE + "You are now a " + args[1]); }else{ p.sendMessage(ChatColor.RED + "That skill doesn't exist! Valid skills: weaponsmaster, ranger, mage, pyro, juggernaut"); } }else{ p.sendMessage(ChatColor.RED + "You already have a skill!"); } }else{ p.sendMessage(ChatColor.RED + "Usage: /skill select [classname]"); } }else if(args[0].equalsIgnoreCase("list")){ p.sendMessage(ChatColor.BLUE + "=======Skill List======="); p.sendMessage(ChatColor.BLUE + "WeaponsMaster"); p.sendMessage(ChatColor.BLUE + "Ranger"); p.sendMessage(ChatColor.BLUE + "Mage"); p.sendMessage(ChatColor.BLUE + "Pyro"); p.sendMessage(ChatColor.BLUE + "Juggernaut"); p.sendMessage(ChatColor.BLUE + "Do /skill info [skill name] for more info"); }else if(args[0].equalsIgnoreCase("info")){ if(args.length == 2){ if(args[1].equalsIgnoreCase("pyro")){ p.sendMessage(ChatColor.GREEN + "============================================"); p.sendMessage(ChatColor.BLUE + "Pyros are immune to fire, and take significantly less damage from lava. When Pyros hit their target, they have a chance of their target catching fire"); p.sendMessage(ChatColor.DARK_PURPLE + "Each level you earn increases the chance"); p.sendMessage(ChatColor.RED + "Pyros are weak and slow when in water."); p.sendMessage(ChatColor.GREEN + "============================================"); }else if(args[1].equalsIgnoreCase("juggernaut")){ p.sendMessage(ChatColor.GREEN + "============================================"); p.sendMessage(ChatColor.BLUE + "Juggernauts are thick and very tough. Will reduce all incoming damage by an amount."); p.sendMessage(ChatColor.DARK_PURPLE + "Each level you earn increases the amount of hearts you have"); p.sendMessage(ChatColor.RED + "Juggernauts are weighed down by any armor other than leather"); p.sendMessage(ChatColor.GREEN + "============================================"); }else if(args[1].equalsIgnoreCase("ranger")){ p.sendMessage(ChatColor.GREEN + "============================================"); p.sendMessage(ChatColor.BLUE + "Rangers are quick, stealthy and specialize in light swords and bows. When armed with a bow, you gain speed. When armed with an iron sword or wooden sword, each hit gves you a small chance to become invisible."); p.sendMessage(ChatColor.DARK_PURPLE + "Each level you earn increases that chance."); p.sendMessage(ChatColor.RED + "Rangers are weighed down by diamond tools and armor"); p.sendMessage(ChatColor.GREEN + "============================================"); }else if(args[1].equalsIgnoreCase("weaponsmaster")){ p.sendMessage(ChatColor.GREEN + "============================================"); p.sendMessage(ChatColor.BLUE + "Weapons Masters are ruthless and skillful, effectively decimating all that dares to challenge him. Attacks cause a slow and some bonus damage based on a percentage of the damage you dealt."); p.sendMessage(ChatColor.DARK_PURPLE + "Each level you earn increases the bonus damage percentage."); p.sendMessage(ChatColor.RED + "Weapons masters deal less damage to nether mobs and endermen."); p.sendMessage(ChatColor.GREEN + "============================================"); }else if(args[1].equalsIgnoreCase("mage")){ p.sendMessage(ChatColor.GREEN + "============================================"); p.sendMessage(ChatColor.BLUE + "Mages are strong in the art of magic and dispatch their enemies with concoctions and a nice shiny staff. When fighting with hoes, slow enemies and and have a chance to heal for an amount."); p.sendMessage(ChatColor.DARK_PURPLE + "Each level you earn increases the chance you will be healed and the heal amount(Up to an extent)"); p.sendMessage(ChatColor.RED + "Mages deal less damage when armed with normal weapons, excluding bows."); p.sendMessage(ChatColor.GREEN + "============================================"); }else{ p.sendMessage(ChatColor.RED + "Invalid skill. Valid skills: weaponsmaster, ranger, mage, pyro, juggernaut"); } }else{ p.sendMessage(ChatColor.RED + "Usage: /skill info [skillname]"); } }else if(args[0].equalsIgnoreCase("level")){ if(this.skill.getString(p.getName()) == "none"){ p.sendMessage(ChatColor.RED + "You don't have a skill type! Choose one with /skill select"); }else{ if(this.skill.getString(p.getName()) == "weaponsmaster"){ p.sendMessage(ChatColor.BLUE + "You are a level " + this.config.getInt(p.getName()) + " Weapons Master"); }else if(this.skill.getString(p.getName()) == "ranger"){ p.sendMessage(ChatColor.BLUE + "You are a level " + this.config.getInt(p.getName()) + " Ranger"); }else if(this.skill.getString(p.getName()) == "mage"){ p.sendMessage(ChatColor.BLUE + "You are a level " + this.config.getInt(p.getName()) + " Mage"); }else if(this.skill.getString(p.getName()) == "pyro"){ p.sendMessage(ChatColor.BLUE + "You are a level " + this.config.getInt(p.getName()) + " Pyro"); }else if(this.skill.getString(p.getName()) == "juggernaut"){ p.sendMessage(ChatColor.BLUE + "You are a level " + this.config.getInt(p.getName()) + " Juggernaut"); } } }else { p.sendMessage(ChatColor.BLUE + "====Skill Commands===="); p.sendMessage(ChatColor.BLUE + "/skill select " + ChatColor.RED + "Choose a skill, if you don't have one"); p.sendMessage(ChatColor.BLUE + "/skill list " + ChatColor.RED + "List of all skill types"); p.sendMessage(ChatColor.BLUE + "/skill info " + ChatColor.RED + "Shows information about one skill type"); p.sendMessage(ChatColor.BLUE + "/skill level " + ChatColor.RED + "Shows your skill level, if you have a skill type"); } } }else{ sender.sendMessage("ERROR: Only players can use /skill"); } } return false; }}
Hex_27 Well I can't find anything wrong with it... There is this one method that I always used, before I found out about config.contains(path), which I actually haven't had the chance to implement yet. I did this: Code:java if (config.getString(path) == null /*or != null*/) I hear it's a pretty bad way to do it, but it's never failed me yet.
pookeythekid There's another problem now... I found out that doing /skill select [Classname] doesn't actually set the value for Playername.
Hex_27 Huh? I didn't know that command existed in your plugin. What is it supposed to do if it worked?
pookeythekid The command is in the Main.java It is supposed to set the PlayerName's value to a specific integer. I also changed my main a little, so here it is now: Code:java package me.leothepro555.random; import java.io.File;import java.io.IOException;import org.bukkit.Bukkit;import org.bukkit.ChatColor;import org.bukkit.command.Command;import org.bukkit.command.CommandSender;import org.bukkit.configuration.file.FileConfiguration;import org.bukkit.configuration.file.YamlConfiguration;import org.bukkit.entity.Player;import org.bukkit.event.Listener;import org.bukkit.plugin.PluginManager;import org.bukkit.plugin.java.JavaPlugin; public class Main extends JavaPlugin implements Listener{ public File file = new File("plugins/Skills/levels.yml"); public FileConfiguration config = YamlConfiguration.loadConfiguration(this.file); public File anotherfile = new File("plugins/Skills/skills.yml"); public FileConfiguration skill = YamlConfiguration.loadConfiguration(this.anotherfile); public void saveLevels() { try { this.config.save(this.file); this.config = YamlConfiguration.loadConfiguration(this.file); } catch (IOException e) { e.printStackTrace(); } } public void saveSkills() { try { this.config.save(this.anotherfile); this.config = YamlConfiguration.loadConfiguration(this.anotherfile); } catch (IOException e) { e.printStackTrace(); } } public void onEnable(){ getConfig().options().copyDefaults(true); saveDefaultConfig(); config.options().copyDefaults(false); saveLevels(); skill.options().copyDefaults(false); saveSkills(); PluginManager manager = Bukkit.getServer().getPluginManager(); manager.registerEvents(new LeaveManager(this), this); manager.registerEvents(new WeaponsMaster(this), this); manager.registerEvents(new Ranger(this), this); manager.registerEvents(new Mage(this), this); manager.registerEvents(new Pyro(this), this); manager.registerEvents(new Juggernaut(this), this); } public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { if(cmd.getName().equalsIgnoreCase("skill")){ if(sender instanceof Player){ Player p = (Player) sender; if(args.length != 0){ if(args[0].equalsIgnoreCase("select")){ if(args.length == 2){ //Weaponsmaster = 1 //Ranger = 2 //Mage = 3 //Pyro = 4 //Juggernaut = 5 if(this.skill.getInt(p.getName()) == 0){ if(args[1].equalsIgnoreCase("pyro")){ skill.set(p.getName(), 4); saveSkills(); p.sendMessage(ChatColor.BLUE + "You are now a " + args[1]); }else if(args[1].equalsIgnoreCase("juggernaut")){ skill.set(p.getName(), 5); saveSkills(); p.sendMessage(ChatColor.BLUE + "You are now a " + args[1]); }else if(args[1].equalsIgnoreCase("ranger")){ skill.set(p.getName(), 2); saveSkills(); p.sendMessage(ChatColor.BLUE + "You are now a " + args[1]); }else if(args[1].equalsIgnoreCase("weaponsmaster")){ skill.set(p.getName(), 1); saveSkills(); p.sendMessage(ChatColor.BLUE + "You are now a " + args[1]); }else if(args[1].equalsIgnoreCase("mage")){ skill.set(p.getName(), 3); saveSkills(); p.sendMessage(ChatColor.BLUE + "You are now a " + args[1]); }else{ p.sendMessage(ChatColor.RED + "That skill doesn't exist! Valid skills: weaponsmaster, ranger, mage, pyro, juggernaut"); } }else{ p.sendMessage(ChatColor.RED + "You already have a skill!"); } }else{ p.sendMessage(ChatColor.RED + "Usage: /skill select [classname]"); } }else if(args[0].equalsIgnoreCase("list")){ p.sendMessage(ChatColor.BLUE + "=======Skill List======="); p.sendMessage(ChatColor.BLUE + "WeaponsMaster"); p.sendMessage(ChatColor.BLUE + "Ranger"); p.sendMessage(ChatColor.BLUE + "Mage"); p.sendMessage(ChatColor.BLUE + "Pyro"); p.sendMessage(ChatColor.BLUE + "Juggernaut"); p.sendMessage(ChatColor.BLUE + "Do /skill info [skill name] for more info"); }else if(args[0].equalsIgnoreCase("info")){ if(args.length == 2){ if(args[1].equalsIgnoreCase("pyro")){ p.sendMessage(ChatColor.GREEN + "============================================"); p.sendMessage(ChatColor.BLUE + "Pyros are immune to fire, and take significantly less damage from lava. When Pyros hit their target, they have a chance of their target catching fire"); p.sendMessage(ChatColor.DARK_PURPLE + "Each level you earn increases the chance"); p.sendMessage(ChatColor.RED + "Pyros are weak and slow when in water."); p.sendMessage(ChatColor.GREEN + "============================================"); }else if(args[1].equalsIgnoreCase("juggernaut")){ p.sendMessage(ChatColor.GREEN + "============================================"); p.sendMessage(ChatColor.BLUE + "Juggernauts are thick and very tough. Will reduce all incoming damage by an amount."); p.sendMessage(ChatColor.DARK_PURPLE + "Each level you earn increases the amount of hearts you have"); p.sendMessage(ChatColor.RED + "Juggernauts can only do up to 4 damage at a time."); p.sendMessage(ChatColor.GREEN + "============================================"); }else if(args[1].equalsIgnoreCase("ranger")){ p.sendMessage(ChatColor.GREEN + "============================================"); p.sendMessage(ChatColor.BLUE + "Rangers are quick, stealthy and specialize in light swords and bows. When armed with a bow, you gain speed. When armed with an iron sword or wooden sword, each hit gves you a small chance to become invisible."); p.sendMessage(ChatColor.DARK_PURPLE + "Each level you earn increases that chance."); p.sendMessage(ChatColor.RED + "Rangers are weighed down by diamond tools and armor"); p.sendMessage(ChatColor.GREEN + "============================================"); }else if(args[1].equalsIgnoreCase("weaponsmaster")){ p.sendMessage(ChatColor.GREEN + "============================================"); p.sendMessage(ChatColor.BLUE + "Weapons Masters are ruthless and skillful, effectively decimating all that dares to challenge him. Attacks cause a slow and some bonus damage based on a percentage of the damage you dealt."); p.sendMessage(ChatColor.DARK_PURPLE + "Each level you earn increases the bonus damage percentage."); p.sendMessage(ChatColor.RED + "Weapons masters deal less damage to nether mobs and endermen."); p.sendMessage(ChatColor.GREEN + "============================================"); }else if(args[1].equalsIgnoreCase("mage")){ p.sendMessage(ChatColor.GREEN + "============================================"); p.sendMessage(ChatColor.BLUE + "Mages are strong in the art of magic and dispatch their enemies with concoctions and a nice shiny staff. When fighting with hoes, slow enemies and and have a chance to heal for an amount."); p.sendMessage(ChatColor.DARK_PURPLE + "Each level you earn increases the chance you will be healed and the heal amount(Up to an extent)"); p.sendMessage(ChatColor.RED + "Mages deal less damage when armed with normal weapons, excluding bows."); p.sendMessage(ChatColor.GREEN + "============================================"); }else{ p.sendMessage(ChatColor.RED + "Invalid skill. Valid skills: weaponsmaster, ranger, mage, pyro, juggernaut"); } }else{ p.sendMessage(ChatColor.RED + "Usage: /skill info [skillname]"); } }else if(args[0].equalsIgnoreCase("level")){ if(this.skill.getInt(p.getName()) == 0){ p.sendMessage(ChatColor.RED + "You don't have a skill type! Choose one with /skill select"); }else{ //Weaponsmaster = 1 //Ranger = 2 //Mage = 3 //Pyro = 4 //Juggernaut = 5 if(this.skill.getInt(p.getName()) == 1){ p.sendMessage(ChatColor.BLUE + "You are a level " + this.config.getInt(p.getName()) + " Weapons Master"); }else if(this.skill.getInt(p.getName()) == 2){ p.sendMessage(ChatColor.BLUE + "You are a level " + this.config.getInt(p.getName()) + " Ranger"); }else if(this.skill.getInt(p.getName()) == 3){ p.sendMessage(ChatColor.BLUE + "You are a level " + this.config.getInt(p.getName()) + " Mage"); }else if(this.skill.getInt(p.getName()) == 4){ p.sendMessage(ChatColor.BLUE + "You are a level " + this.config.getInt(p.getName()) + " Pyro"); }else if(this.skill.getInt(p.getName()) == 5){ p.sendMessage(ChatColor.BLUE + "You are a level " + this.config.getInt(p.getName()) + " Juggernaut"); } } }else { p.sendMessage(ChatColor.BLUE + "====Skill Commands===="); p.sendMessage(ChatColor.BLUE + "/skill select " + ChatColor.RED + "Choose a skill, if you don't have one"); p.sendMessage(ChatColor.BLUE + "/skill list " + ChatColor.RED + "List of all skill types"); p.sendMessage(ChatColor.BLUE + "/skill info " + ChatColor.RED + "Shows information about one skill type"); p.sendMessage(ChatColor.BLUE + "/skill level " + ChatColor.RED + "Shows your skill level, if you have a skill type"); } }else if(args.length == 0){ p.sendMessage(ChatColor.BLUE + "====Skill Commands===="); p.sendMessage(ChatColor.BLUE + "/skill select " + ChatColor.RED + "Choose a skill, if you don't have one"); p.sendMessage(ChatColor.BLUE + "/skill list " + ChatColor.RED + "List of all skill types"); p.sendMessage(ChatColor.BLUE + "/skill info " + ChatColor.RED + "Shows information about one skill type"); p.sendMessage(ChatColor.BLUE + "/skill level " + ChatColor.RED + "Shows your skill level, if you have a skill type"); } }else{ sender.sendMessage("ERROR: Only players can use /skill"); } } return false; }}
Hex_27 Code:java if(this.skill.getInt(p.getName()) == 0){ Doesn't the player not exist in the skill file at this point?
pookeythekid It would plant the variable there, set it to "0", but the /skill select does not change the variable's setting. For example when Hex_27 joins the server, the plugin would check if that variable exists, then it would set it to "0". But when I do /skill select Mage , which should set it to this: Hex_27: 3 But it remains as: Hex_27: 0 The only way to actually change it now is by going to the config and altering it manually.
i would NOT store all player data in a YAML file. It will totally lag your server out. Either use 1 file per user, or store it using SQL or FlatFile
lenis0012 I'm new to this config stuff. I have no idea what an sql file or a flat file is. So right now, I assume you're recommending me to generate a new PLAYERNAME.yml each time a new player joins..... right?
Where's your tests to back this data up? I, for one, feel SQL would be much slower with response times ~10-80 ms (and is non-determinant) whereas a YAML file, at least I would guess, would be around 1ms. There's no issue with storing the data in a YAML file. Also, define "flat file," as that can refer to almost anything that isn't a relational database (and even some relational databases, and including YAML). Hex_27 Don't bother with SQL unless you need the power, portability, or scalability of a relational database (99/100 plugins don't). It's much more difficult to use and generally more difficult for a server owner to set up too, for what generally amounts to a performance loss.
mythbusterma pookeythekid lenis0012 That isn't really the problem. How do I change the value of the things in a config? It stays as 0 the moment I make it!
go try and store 10,000 entries in 1 file. I tried it, 2s lag spikes Good thing is that sql and flatfile can both be handles and loaded in a async task. Im assuming you did it all wrong if you really get 10-80ms load time on the main thread. YAML is better for configuration, it is really slow compared to other storage types. Hex_27 Now lets actualy give you your answer: First of all, saveDefaults it not needed as your configuration files are most likely empty at the beginning, nor is your save method on enable. Use the following methdo to check if datat exists for a player: Code:java public boolean hasSkill(UUID player) { // I recommend UUID instead of player name storage return skill.contains(player.toString());} Getting the data: Code:java public int getSkill(UUID player) { return skill.getInt(player.toString());} Setting the data at any point: Code:java public void setSkill(UUID player, int skill) { skill.set(player.toString(), skill); saveSkills(); // Optional, if you want to apply changes straight after setting it, you could also do this on disable.}
lenis0012 For setSkill() theres an error in eclipse that says "Cannot invoke set(UUID, int) on the primitive type int" EDIT: Nevermind, turns out the plugin was confusing the skill config with the setSkill()'s skill I FINALLY LET IT WORK! Again, it was another dumb mistake that I didn't find for days. Old code: Code:java public File file = new File("plugins/Skills/levels.yml"); public FileConfiguration config = YamlConfiguration.loadConfiguration(this.file); public File anotherfile = new File("plugins/Skills/skills.yml"); public FileConfiguration skill = YamlConfiguration.loadConfiguration(this.anotherfile); public void saveLevels() { try { this.config.save(this.file); this.config = YamlConfiguration.loadConfiguration(this.file); } catch (IOException e) { e.printStackTrace(); } } public void saveSkills() { try {//HERE this.config.save(this.anotherfile); this.config = YamlConfiguration.loadConfiguration(this.anotherfile);//UP HERE } catch (IOException e) { e.printStackTrace(); } } New code: Code:java public File file = new File("plugins/Skills/levels.yml"); public FileConfiguration config = YamlConfiguration.loadConfiguration(this.file); public File anotherfile = new File("plugins/Skills/skills.yml"); public FileConfiguration skill = YamlConfiguration.loadConfiguration(this.anotherfile); public void saveLevels() { try { this.config.save(this.file); this.config = YamlConfiguration.loadConfiguration(this.file); } catch (IOException e) { e.printStackTrace(); } } public void saveSkills() { try {//CORRECTED VERSION this.skill.save(this.anotherfile); this.skill = YamlConfiguration.loadConfiguration(this.anotherfile); } catch (IOException e) { e.printStackTrace(); } } I'm starting to feel a bit sorry for wasting so much time from you guys. Thanks for trying though. EDIT by Moderator: merged posts, please use the edit button instead of double posting.
Hex_27 Aahaha. I love the feeling of stupidity when I find those errors in my code. xD Glad you worked it out.
lenis0012 It's not 10-80 ms on the main thread....that's the amount of time it takes to receive data (on average) from an SQL server. Of course when I do SQL I do it asynchronously. So then I challenge you, why doesn't PEX or GroupManager lag servers terribly? They have >10,000 entries stored in a YAML file and seem to have no issues loading them. YAML, in most cases that don't require the size or relational database features, is usually faster than the other options. Also, you still haven't defined "flat file," because that can literally refer to anything that isn't a relational database.
Caching. YAML is really slow. JSON is much faster ObjectOutputStreams are even faster, but cannot be modified by a text editor. SQL is slower, but has nice query support, and can be loaded in PHP very easily. NoSQL is a faster variant of MySQL SQLite, i use this oen for my own private plugins. If you do not agree, please let me know what i am saying wrong
lenis0012 Yes, SnakeYAML caches quite well. JSON is sometimes faster, but also less readable. NoSQL refers to any database system that behaves similar to SQL, but doesn't use relational databases for storage, things like Mongo.