The point of this plugin is to save a block broken count of each player inside a file. And then use it later So I have this class: Spoiler: User Class Code (Java): public final class User{ private UUID uuid; private String name; private int blockCount; public User(UUID uuid, String name, int blockCount){ this.name = name; this.uuid = uuid; this.blockCount = blockCount; } public UUID getUuid() { return uuid; } public void setName(String name) { this.name = name; } public String getName() { return name; } public int getBlockCount() { return blockCount; } public void setBlockCount(int blockCount) { this.blockCount = blockCount; } public void sendMessage(final String message){ Objects.requireNonNull(Bukkit.getPlayer(uuid)).sendMessage(ChatColor.translateAlternateColorCodes('&', message)); } And the user handler class Spoiler: User Handler Class Code (Java): public class UserHandler { public HashMap<UUID, User> users = new HashMap<>(); private final RevBlocks plugin; public UserHandler(RevBlocks plugin){ this.plugin = plugin; } public void register(final UUID uuid, String name, final int blocks){ users.put(uuid, new User(uuid, name, blocks)); } public boolean exists(final UUID uuid){ return users.containsKey(uuid);} public HashMap<UUID, User> getUsersMap(){ return users; } public User findUser(UUID uuid){ return users.get(uuid);} When a player joins I register the player to the hashmap. Code (Java): if (!userHandler.exists(uuid)) { userHandler.register(uuid, player.getName(), 1); Then to count the blocks broken I do this: Spoiler: BlockBreakEvent Code (Java): @EventHandler public void onBlockBreak(final BlockBreakEvent event){ // Get the player and the block broken. final Player player = event.getPlayer(); final Block block = event.getBlock(); // Get the user by UUID. final User user = userHandler.findUser(player.getUniqueId()); // Increment the user's blocks broken. user.setBlockCount(user.getBlockCount() + 1); user.sendMessage("&bBlocks Broken: " + user.getName() + user.getBlockCount()); } Now this is where I am stuck Could please someone guide me on how I should save the data to a file that is inside the Hashmap (HashMap<UUID,User>) And then get the data from a file, and use it after server reset so the data won't reset and the block count will keep going.
This can't be more simplier! Just loop Entries of map and save then to the file: Code (YAML): my-uuid-here: mined-blocks-count my-uuid-here2: mined-blocks-count my-uuid-here3: mined-blocks-count How to load? Same as above, just loop config keys -> dataFile.getConfigurationSection("").getKeys(false)
Hey! Thank you for the reply! That's what I do since this is how I save the data: Code (Java): // Loop through the map. for (UUID uuid : userHandler.getUsersMap().keySet()){ // Get the user. User user = userHandler.findUser(uuid); String name = user.getName(); // User's name. int blockCount = user.getBlockCount(); // User's block count. // Save the data. cs.set(name + ".uuid", user.getUuid().toString()); cs.set(name + ".blockCount", blockCount); // Save the config and debug. plugin.saveConfig(); Bukkit.broadcastMessage("Task saved, saved users"); It works very well, But when the server reset, the hashmap is empty, how do I populate the hashmap, and where exactly? Because the information is stored using a hashmap. user.setBlockCount(user.getBlockCount() + 1);
@CodedRed does a fantastic YouTube tutorial found here: This covers saving and loading HashMaps Hope this helps
You should be doing some null checks in there; you are blindly assuming data will be in the map. It almost always will be, but it's best to code for safety. Also it'd be easier to just make User#incBlockCount() to save you some typing, then have it increment the count in that method rather than set the get+1. Looks cleaner too. Lastly that should be like Map<xxx> var = HashMap<>() not HashMap<xxx> var = HashMap<>() per SOLID design.
Hey! The video helped me a lot! But I am still stuck. This is how save the data which works perfectly. Code (Java): @Override public void onDisable() { if (!userHandler.getUsersMap().isEmpty()) { for (Map.Entry<UUID, User> entry : userHandler.getUsersMap().entrySet()) { this.getConfig().set("data." + entry.getKey().toString(), entry.getValue()); } this.saveConfig(); } } The problem is the populate hashmap which throws me errors. Code (Java): public void restoreData(){ ConfigurationSection dataSection = this.getConfig().getConfigurationSection("data"); // Access the data: if (dataSection == null) return; // Null check // Loop through all the keys under data: for (String key : dataSection.getKeys(false)) { ConfigurationSection uniqueData = dataSection.getConfigurationSection(key); UUID uuid = UUID.fromString(uniqueData.getString(key)); // Each key is a uuid String name = uniqueData.getString("name"); int blockCount = uniqueData.getInt("blockCount"); User user = new User(uuid, name, blockCount); userHandler.getUsersMap().put(uuid, user); } } How its in the config: Code (YAML): data: de4b97ab-b9be-4c4a-8778-f9643d2a13: !!me.hyperburger.revblocks.user.User blockCount: 20 name: HyperBurger THE PROBLEM; Whenever I "populate" the hashmap it throws errors and doesn't work.
Hey! I solved the problem. I need to use this: UUID uuid = UUID.fromString(key); Instead of UUID uuid = UUID.fromString(uniqueData.getString(key)); Works like a charm. Thanks everyone for the help,thread solved.