I can't figure out how to save a hashmap

Discussion in 'Plugin Development' started by Sgt_Tailor, Dec 27, 2011.

Thread Status:
Not open for further replies.
  1. Hello,
    I am writing a plugin for my server, setting homes and the spawn on the server. I figured out how to create a hashmap, but after a reload all the hashmaps get a reset as well. I know there is a way to save and load the data inside the hashmaps. I have read about SLAPI but I don't understand where to put in in my code.

    Code:
    package spawn;
    
    import java.util.HashMap;
    import java.util.logging.Logger;
    import org.bukkit.ChatColor;
    import org.bukkit.Location;
    import org.bukkit.World;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    
    
    
    public class SpawnCommandExecutor implements CommandExecutor {
        public static spawn plugin;
        public final Logger logger = Logger.getLogger("Minecraft");
        public HashMap<String, Location> homes = new HashMap<String, Location>();
        public HashMap<World, Location> spawn = new HashMap<World, Location>();
    
        public SpawnCommandExecutor(spawn instance) {
        plugin = instance;
    
        }
    
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String[] arg){
    
            if(cmd.getName().equalsIgnoreCase("setspawn")){
                if(sender instanceof Player){
                    if(sender.hasPermission("spawn.setspawn")){
                        World worldspawn = ((Player) sender).getWorld();
                        spawn.put(worldspawn, ((Player) sender).getLocation());
                        sender.sendMessage(ChatColor.GREEN + "The spawn has been set to your location");
                        return true;
                    }
                    else{
                        sender.sendMessage(ChatColor.RED + "You do not have permissions to set the spawn location");
                        return true;
                    }
                }
                else{
                    sender.sendMessage(ChatColor.RED + "This command can ony be run as a player");
                }
            }
    
            if(cmd.getName().equalsIgnoreCase("spawn")){
                if(sender instanceof Player){
    
                    World worldspawn = ((Player) sender).getWorld();
                        if(!spawn.containsKey(worldspawn)){
                            sender.sendMessage(ChatColor.RED + "There is no spawn set for this world");
                            return true;
                        }
                    ((Player) sender).teleport(spawn.get(worldspawn));
                    sender.sendMessage(ChatColor.GREEN + "You have been teleported to spawn");
                    return true;
                }
    
            }
    
            if(cmd.getName().equalsIgnoreCase("sethome")){
                if(sender instanceof Player){
                    Player p = (Player) sender;
    
                homes.put(sender.getName(), p.getLocation());
                //Location home = homes.get(sender.getName()); <<<------ this needs to be saved
                sender.sendMessage(ChatColor.GREEN + "Your home has been set to this location");
                return true;
                }
            }
            if(cmd.getName().equalsIgnoreCase("home")){
                if(sender instanceof Player){
                    if (homes.containsKey(sender.getName())){
    
                        Location home = homes.get(sender.getName());
                        ((Player) sender).teleport(home);
                        sender.sendMessage(ChatColor.GREEN + "You have been teleported to your home");
                        return true;
                    }
                    else{
                        sender.sendMessage(ChatColor.RED + "You have not created a home yet, to do so type /sethome");
                        return true;
                    }
    
                }
                return false;
            }
    
            return false;
     
        }
     
    
    }
    [/MYCODE]
    
    Please help me
     
  2. Offline

    Father Of Time

    Look into "Serializable", java serialization.

    HashMaps aren't naturally persistent, you need to serialize (save) data to a flat file (or some other long term data storage medium) upon program termination, and deserialize (load) the data on program launch.

    This is a very basic explination, but the process is extremely easy as long as your hashmap contains basic java variables types (string, integer, double, etc).

    Remember, bukkit variables like "Location" aren't basic java variables, and theirfore cannot be saved. Instead you will need to make your own custom class that stores the same values and mark it as serializable and use that:

    The following is pseudo code:
    Code:
    class CustomLoc implements Serializable
    Double LocX
    Double LocY
    Double LocZ
    String WorldName
    
    Map<String, CustomLoc > tosave = new HashMap<String, CustomLoc>();
    
    I hope this helps!
     
  3. so I need to create this class :
    Code:
    class CustomLoc implements Serializable
    Double LocX
    Double LocY
    Double LocZ
    String WorldName
    
    Map<String, CustomLoc > tosave = new HashMap<String, CustomLoc>();
    but how to I save the data into a file and load it when the plugin is enables?
    How i I do that in my CommandExecutor

    I have zero experience at saving data to a file
     
  4. can you show me how to put this in my code
     
  5. Offline

    Father Of Time

    That is why I said you should read up on Serializable, its an entire process.

    In short, you make a class you want to save as I stated above (with basic variable types) then you create a collection (like a hashmap ) and store instances of your custom class in it.

    Then when you want to save you take your hashmap, serialize the count of the hashmap (so you know how many records were recorded at load time) and then you iterate through the hashmap and save each instance of your cusotm class. The beauty of java serializable is if you set your class up as I stated before with basic variable types you dont need to tell it what to save within your class, your can just send it the entire custom class and it will save all the data stored within it!

    Then, on load you simple grab that save.dat file, read the first object (the size of the collection we saved earlier) then do a loop iteration that many times, each time creating a new instance of your custom class and setting the data in that new instance with the data from your save file.

    As far has how to handle all of this? you want to create a DataHandler, create serialize and deserialize methods within it and call the deserialize (load) function on plug-in enable, and call the serialize (save) function on plug-in disable. Also it might be smart to start a timer and do periodic saves just to be safe.

    This is an overview of the entire process, however I am not going to go into greater detail until I am sure you are able to understand what I am saying. Please do some research on java serializable interface and give it your best attempt, then when and if you have problems return with specific questions and sample code, and from that we can further assist you.

    Good luck with your project, it may sounds like a lot but trust me, serializing in java is one of the easiest languages to do it in.
     
  6. Thanks for the reply, I will do some research and will post my questions here:cool:
     
  7. Offline

    Father Of Time

    Fantastic, I wish you luck with your project; and if you hit a wall tag me and I will do what I can to help you break it down. :D
     
Thread Status:
Not open for further replies.

Share This Page