[Solved] Save and load an ArrayList of Locations

Discussion in 'Plugin Development' started by sargunster, Apr 3, 2012.

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

    sargunster

    My plugin needs to save and load an ArrayList of Locations. I've been trying to do this using the FileConfiguration API, but I can't figure out how to use an ArrayList for this. Could someone show me an example of saving and loading an ArrayList?
     
  2. Offline

    acuddlyheadcrab

    Well you can put lists in where other objects go when you use config.set("path", string_list);. But the list needs to be of a primitive data type (int, double, other number types, boolean, or string) otherwise you'll probably get an InvalidConfigurationException.

    It's sometimes not the best way, but I've used methods to create and parse location keys in configs before. And I just save it as a String in the file. (it looked like "x0.0y0.0z0.0wWorld" and I used regex to parse the x, y, z, coords and world from it)
     
  3. Offline

    sargunster

    Ugh, I was trying to avoid parsing strings. :)
    I'll try that then. Thanks for the help.
     
  4. Offline

    acuddlyheadcrab

    Yeah it seems... wrong lol. You could use a database, but I dont know how to do that.
     
  5. Offline

    Double0negative

    use ObjectOutputStream and ObjectInputStream

    Code:
      File      f = new File(this.getDataFolder()+"\\arraylist.dat");
      try{
              if(!f.exists())
                  f.createNewFile();
       
              arraylist =  (ArrayList<Type>) new ObjectInputStream( new FileInputStream(f)).readObject();
       
            }catch(Exception e){e.printStackTrace();}
            

    Code:
    try{
                new ObjectOutputStream(new FileOutputStream(f)).writeObject(arraylist);
            }catch(Exception e){e.printStackTrace();}
     
    

    EDIT: you may want to clear the file after you load it too or you will end up with a whole bunch of arraylist being saved and loaded
     
  6. Offline

    acuddlyheadcrab

    Aww thats awesome. I've never really gotten into File handling and IO.
     
  7. Offline

    sargunster

    I tried using your code, and after fixing a few errors, I'm getting this error:
    Code:
    java.io.NotSerializableException: org.bukkit.Location
    I think I'll convert it to a list of Strings instead of Locations when saving and loading, similar to what acuddlyheadcrab suggested.
     
  8. Offline

    acuddlyheadcrab

    Well if you want to let users edit it, got with yml, but if it were me, i'd prefer a dat file.
     
  9. Offline

    Double0negative

    ahh yes i forgot about that, locations probably isn't serizlizable, although you could create a warpper class
     
  10. Offline

    sargunster

    That's what I'm doing now. :)
    How did you use regex to parse the string? I've never used regex, but I think it might be simpler than what I was planning to do.
     
  11. Offline

    acuddlyheadcrab

    Well.... I basically used the replaceAll(String regex, String replacement). There's no way that I know of to simply select the matching regex value, so I had to make my own kind of chunky method that compares 2 strings...


    Show Spoiler
    EDIT: These methods only works for how I use it in this case. regexSelectOne() is the method I was talking about:
    Code:java
    1. public static String toLocKey(Location loc) {
    2. double x = loc.getX(), y = loc.getY(), z = loc.getZ();
    3. String world = loc.getWorld().getName();
    4. String key = (String.format("x%1$sy%2$sz%3$sw%4$s", x, y, z, world));
    5. return key;
    6. }
    7.  
    8. public static Location parseLocKey(String spawnkey) {
    9. double
    10. x = Double.parseDouble(regexSelectOne(spawnkey, "(?<=x).+(?=y)")),
    11. y = Double.parseDouble(regexSelectOne(spawnkey, "(?<=y).+(?=z)")),
    12. z = Double.parseDouble(regexSelectOne(spawnkey, "(?<=z).+(?=w)"))
    13. ;
    14. World world = Bukkit.getWorld(regexSelectOne(spawnkey, "(?<=w).+"));
    15. return new Location(world, x, y, z);
    16. }
    17.  
    18. public static String regexSelectOne(String sample, String regex) {
    19.  
    20. /***
    21. * @return the matching string from regex
    22. */
    23.  
    24. // How it works...
    25. // String sample = "aksjgbaiderpalkgnakg"; String derp = regexSelectOne(sample, "derp");
    26. // "aksjgbai", "alkgnakg" <- split into array between the matching regex
    27. // ^ that and ^that are removed from original string
    28. // leaving only the thing between them, or the matching regex
    29. // However, this only works for one matching regex in the sample. if there were 2 (sample = "aksjgbai derpalkgnakg derp", it would return "derpderp"
    30.  
    31. String[] newstring_arr = sample.split(regex);
    32. for (String temp_string : newstring_arr)
    33. sample = sample.replaceAll(temp_string, "");
    34. return sample;
    35. }



    Also, this is a really good way to test regex: http://gskinner.com/RegExr/

    EDIT2: This way though.... It just feels so wrong to suggest someone should use it! Just keep in mind it's not the most efficient way and It could yield a couple bugs. There may be a method included in java (like replaceAll()) that already does it, but this works for now.


    Edit: Yeah ↓ that way works too. It's basically how I do it, just a whole lot simpler
     
  12. Offline

    Double0negative

    if you store your data into the file in world,x,y,z format you can use the split method of strings to split it up then use Double.parseDouble() on them to extract the data

    locations:
    - world,92.23213,64,819.213123
    - world2,0,64,19.23123123

    Code:
    list<String> s =  this.getConfig().getStringList("locations");
    for(String loc:s){
        String [] arg = loc.split(",");
        Double [] parsed = new Double[3];
            for(int a = 0;a<3;a++){
                  parsed[a] = Double.parseDouble(arg[a+1]);
            }
     
      Location location =  new Location  (arg[0],parsed[1],parsed[2],parsed[3]);
    }
    
     
  13. Offline

    sargunster

    Thanks for all the help! I'll try this tomorrow and edit with the results.

    EDIT: It works!
     
    acuddlyheadcrab likes this.
  14. Offline

    imaboy321

    Can someone please explain how you did all of this :( I am really stuck with this also and I cant figure it out. The way you did it is the way I need to but I cant figure out what you are doing in the code! sargunster Double0negative acuddlyheadcrab
     
  15. Offline

    acuddlyheadcrab

    What do you need help with exactly? I'm re-reading this thread since it was so long ago

    EDIT:

    (Sorry, it's been a while since I've used the FileConfiguration class by itself, I wrote a library class for it and I've been using that instead for a while now. I'm looking it up though)
     
  16. Offline

    imaboy321

    acuddlyheadcrab How im supposed to save the file. Where do I put the try,catch methods?
     
Thread Status:
Not open for further replies.

Share This Page