Serialization Help Please! (Config.yml)

Discussion in 'Plugin Development' started by MrTwiggy, Jul 14, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    MrTwiggy

    EDIT: Solved, my plugin was loading before Multiverse plugin was loaded, so the code that relied on Multiverse stuff was being called and borking.

    Hey there. So, I'm writing an arena-esque plugin, and I need (want) the ability to create maps (levels) on the fly, by declaring the different spawns and variables for each level, such as team sizes, minimum players to start the game, what world it is in, the red team spawn, blue team spawn, etc. And I need to save the list of all these levels to the config.yml, and then be able to load them.

    So basically, I have a class 'Level', that holds data such as 'redSpawn' for the red team spawn, 'teamSize' for the max team sizes, and 'levelWorld' for the world the arena/level is located in. My first step was to serialize this class with 'ConfigurationSerialization'. However, I quickly ran into the problem in that I have Locations (such as 'redspawn') inside this class, so I had to create another class 'SerializableLocations' that is essentially that, a class that has methods for inputting and getting a Location from this serializable class. which is starting to confuse me already lol.

    It was working for a little while, and the SaveLevels() function seems to be working alright, but when I run LoadLevels(), I get a HUGE massive amount of errors (literally cannot even see all of the errors because the console can't scroll up that far).

    Basic recap: I have a List of the class 'Level', and I need to be able to save this List to file, and load it from file. The file, in this case, being config.yml.


    Relevant code:

    Save/Load functions
    Code:
    //'levels' is the List<Level> variable that I need to save/load.
    //Used for saving the levels to harddrive
        public void SaveLevels()
        {
            getConfig().set("Level", levels);
            saveConfig();
            getLogger().info("Levels have been successfully saved!");
        }
     
        @SuppressWarnings("unchecked")
        public void LoadLevels()
        {
            levels = (List<Level>) getConfig().get("Level");
            getLogger().info("Levels have been successfully loaded!");
        }
    Level Serialization-Related Stuff
    Code:
    //Heading of the class
    @SerializableAs("Level")
    public class Level implements ConfigurationSerializable
    {
     
    //................
    //Level Serialization------------------------------
     
        //Constructor for deserialization
        public Level(Map<String, Object> map)
        {
            this.name = (String) map.get("name");
            //this.levelWorld =  (World) serializationMap.get("levelWorld");
            this.redSpawn = ((SerializableLocation)map.get("redSpawn")).getLocation();
            this.redShopSpawn = ((SerializableLocation)map.get("redShopSpawn")).getLocation();
            this.blueSpawn = ((SerializableLocation)map.get("blueSpawn")).getLocation();
            this.blueShopSpawn = ((SerializableLocation)map.get("blueShopSpawn")).getLocation();
            this.spectatorSpawn = ((SerializableLocation)map.get("spectatorSpawn")).getLocation();
            this.teamSize = (Integer) map.get("teamSize");
            this.minPlayers = (Integer) map.get("minPlayers");
            this.rounds = (Integer) map.get("rounds");
       
            //TEMP WAY TO LOAD WORLD
            this.levelWorld = redSpawn.getWorld();
        }
     
        //Returns serialization map of class variables
        @Override
        public Map<String, Object> serialize()
        {
     
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("name", this.name);
            map.put("redSpawn", new SerializableLocation(this.redSpawn));
            map.put("redShopSpawn", new SerializableLocation(this.redShopSpawn));
            map.put("blueSpawn", new SerializableLocation(this.blueSpawn));
            map.put("blueShopSpawn", new SerializableLocation(this.blueShopSpawn));
            map.put("spectatorSpawn", new SerializableLocation(this.spectatorSpawn));
            map.put("teamSize", this.teamSize);
            map.put("minPlayers", this.minPlayers);
            map.put("rounds", this.rounds);
     
            return map;
        }
     
    
    And then the SerializableLocation class
    Code:
    @SerializableAs("SerializableLocation")
    public class SerializableLocation implements ConfigurationSerializable
    {
        private double x,y,z;
        private String world;
     
     
        //Constructor for creating manually
        public SerializableLocation(Location loc)
        {
            x=loc.getX();
            y=loc.getY();
            z=loc.getZ();
            world=loc.getWorld().getName();
        }
     
        //Constructor for deserialization
        public SerializableLocation(Map<String, Object> map)
        {
            x = (Double) map.get("x");
            y = (Double) map.get("y");
            z = (Double) map.get("z");
     
            world = (String) map.get("world");
        }
     
        //Function for getting the Location location of this class
        public Location getLocation()
        {
            World w = Bukkit.getWorld(world);
            if(w==null)
                return null;
            Location toRet = new Location(w,x,y,z);
            return toRet;
        }
     
     
        @Override
        public Map<String, Object> serialize() {
            // TODO Auto-generated method stub
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("x", x);
            map.put("y", y);
            map.put("z", z);
            map.put("world", world);
            return map;
        }
    }

    It was working alright for a while, but then everything went haywire and bam bam huge major errors. I would really really appreciate any help!

    Oh, and incase it is relevant, here is what the saved file looked like on a test example of my save (it seems to save fine, it's just the loading that messes everything up)
    Code:
    Level:
    - ==: Level
      blueSpawn:
        ==: SerializableLocation
        z: -176.58313694693612
        world: TehTestWorld
        y: 208.0
        x: -230.00281527362333
      teamSize: 4
      spectatorSpawn:
        ==: SerializableLocation
        z: -176.40320195753944
        world: TehTestWorld
        y: 221.0
        x: -206.41364764311825
      redShopSpawn:
        ==: SerializableLocation
        z: -176.55977998042846
        world: TehTestWorld
        y: 204.0
        x: -180.26890594822038
      name: BattleArena
      minPlayers: 1
      rounds: 5
      blueShopSpawn:
        ==: SerializableLocation
        z: -176.55605467182383
        world: TehTestWorld
        y: 204.0
        x: -232.30000001192093
      redSpawn:
        ==: SerializableLocation
        z: -176.5525996756925
        world: TehTestWorld
        y: 208.0
        x: -183.14052871241265
    
     
  2. Offline

    ferrybig

    try using
    (new SerializableLocation(map.get("redSpawn")).getLocation());
    instead of
    ((SerializableLocation)map.get("redSpawn")).getLocation();
     
  3. Offline

    MrTwiggy

    I've isolated the problem even further. It doesn't even seem to be a problem with the serialization, but rather with using Multiverse Worlds with my plugin.

    I need a substitute for:
    World w = Bukkit.getWorld(world);

    I was passing in the name of a Multiverse world, and Bukkit.getWorld("MVWorldName"); was returning null. How can I make it so that passing it the String name of a Multiverse world will return the 'World' object, so that I can use that in locations?


    EDIT: Alright, I've isolated the problem even further! It's not that Bukkit.getWorld doesn't return Multiverse worlds, but my plugin calls the LoadWorlds() function BEFORE Multiverse Plugin is loaded, so the worlds aren't loaded yet. How can I make it so that Multiverse plugin loads before mine does?
     
  4. Offline

    ferrybig

    add an softdepend
     
Thread Status:
Not open for further replies.

Share This Page