Solved How can I get location from config

Discussion in 'Spigot Plugin Development' started by YunusGG, Jun 14, 2018 at 7:59 PM.

  1. Hey, I coded a Shop plugin and I need help.
    How can I save location of a block to config like that:
    Code (Text):
    Shops:
         [<LOCATION HERE>] :
              Item: DIAMOND_BLOCK
              Amount: 5
              Price: 100
     
    and How can I get location from config when I need. I tried pl.getConfig().set("Shops." + block.getLocation()) but it doesn't work.
    Help pls.
     
  2. Instead of setting the Location in the config with block.getLocation(), You can just save the X, Y and the Z of the Location, and I believe you know what to do from there.
     
  3. You could do it like this:

    Code (Text):

    To save
    plugin.getConfig().set("Shop.Location", block.getLocation());
    plugin.saveConfig();

    To Load
    Location loc = (Location) plugin.getConfig().get("Shop.Location");
     
    or you could save each value of the location like:
    Code (Text):

     To Load  
     double x, y, z;
     String world = plugin.getConfig().getString("Shop.Location.World");
     x = plugin.getConfig().getDouble("Shop.Location.X");
     y = plugin.getConfig().getDouble("Shop.Location.Y");
     z = plugin.getConfig().getDouble("Shop.Location.Z");
     Location loc = new Location(Bukkit.getWorld(world), x, y, z);

     To Save
     plugin.getConfig().set("Shop.Location.World", block.getLocation().getWorld().getName());
     plugin.getConfig().set("Shop.Location.X", block.getLocation().getX());
     plugin.getConfig().set("Shop.Location.Y", block.getLocation().getY());
     plugin.getConfig().set("Shop.Location.Z", block.getLocation().getZ());
     plugin.saveConfig();
     
     
  4. I said I tried that already
    and
    Code (Text):
     plugin.getConfig().set("Shop.Location.World", block.getLocation().getWorld().getName());
    plugin.getConfig().set("Shop.Location.X", block.getLocation().getX());
    plugin.getConfig().set("Shop.Location.Y", block.getLocation().getY());
    plugin.getConfig().set("Shop.Location.Z", block.getLocation().getZ());
    this isn't suitable to saving like that:
    Code (Text):
    Shops:
         [<LOCATION HERE>] :
              Item: DIAMOND_BLOCK
              Amount: 5
              Price: 100
     
    #4 YunusGG, Jun 14, 2018 at 8:56 PM
    Last edited: Jun 14, 2018 at 9:07 PM
  5. You cannot save the location itself in a config. (A location is like a collection of lots of things: X, Y, Z, Pitch, Yaw, World..)
    This is what getLocation() returns: (In my case)

    [​IMG]
     
    #5 Pladetor, Jun 14, 2018 at 9:05 PM
    Last edited: Jun 14, 2018 at 9:16 PM
  6. I know right. This is why I ask to you...
     
  7. Location implements ConfigurationSerializable so yes it can be saved in a config file
     
  8. When I try to get it like that:
    Code (Java):
    if(pl.getConfig().getList("Shops.").contains(clickedblock.getLocation())) {
    }
    it doesn't work.
     
  9. I tried coding something to make it kind of work:
    Code (Java):
    //Save
            this.getConfig().set("Shops.Location", block.getWorld() + "," + block.getLocation().getBlockX() + "," + block.getLocation().getBlockY() + "," + block.getLocation().getBlockZ());
            this.saveConfig();
            this.reloadConfig();
       
            //Load
            String[] locArgs = this.getConfig().getString("Shops.Location").split(",");
       
            World w = Bukkit.getWorld(locArgs[0]);
       
            double x = this.getConfig().getDouble(locArgs[1]);
            double y = this.getConfig().getDouble(locArgs[2]);
            double z = this.getConfig().getDouble(locArgs[3]);
       
            Location blockLoc = new Location(w, x, y, z);
    Keep in mind that I'm very tired and I also haven't tested it, so it may not work.
    However, it should work so give it a shot.
     
  10. Config become this:
    Code (Text):
    Shops:
      Location: CraftWorld{name=world},83,72,-36
      LocationCraftWorld{name=world},84,72,-33:
        Amount: 1
        Price: 150
        Item: !!org.bukkit.Material 'DIAMOND_SWORD'
      LocationCraftWorld{name=world},83,72,-36:
        Amount: 15
        Price: 100
        Item: !!org.bukkit.Material 'DIAMOND'
     
     
  11. Why not just store it like this:
    Code (Text):
    Shops:
      1:
         Location:
         Amount:
         Price:
         Item:
      2:
         Location:
         Amount:
         Price:
         Item:
     
    • Agree Agree x 1
  12. Change block.getWorld() to block.getWorld().getName()

    Edit: to clarify why it shows up as LocationCraftWorld{name=world},x,y,z:
    is because block.getWorld() being concatenated is just calling the .toString() method of the world object. Get the name with .getName() and it'll just be "world,x,y,z:" which is probably what you want.
     
  13. that structure WILL NOT WORK! (with yml)

    heres a new one :
    Code (Text):
    Shops:
         SHOPNAME OR ID OR SOEMTHING:
              Location:
                  x: #
                  y: #
                  z: #
                  world: world
                  (any other data important to the shop like rotation for example)
              Item: DIAMOND_BLOCK
              Amount: 5
              Price: 100
    alernatively if you want shops to have multiple items
    Code (Text):
    Shops:
        SHOPNAME:
            Location:
                  x: #
                  y: #
                  z: #
                  world: world
            stock:
                 0:
                    itemname: axe
                    amount : 4
                     price: 2
                    quantity: 2
                 1:
                    itemname: axe
                    amount : 4
                     price: 2
                    quantity: 2
    PS there is no way around this, you cannot save a LOCATION in itself. You need to save its components and reload them into a new location when you read it.
     
  14. Yes you can save a Location just like getConfig().set("SomeRandomPath", Location);

    @Op in my opinion in your situation i think it would be best to give each shop it's own ID instead of using the location as it's ID in the config
     
    #14 Bobcatsss, Jun 14, 2018 at 10:48 PM
    Last edited: Jun 14, 2018 at 11:32 PM
    • Agree Agree x 1
  15. #15 Nosma_Stew, Jun 14, 2018 at 10:55 PM
    Last edited: Jun 14, 2018 at 11:05 PM
    • Like Like x 1
  16. Why would that structure not work, you can get the keys of a config file and then parse the key back into location data..
     
  17. My method does save a location correctly. Your way works aswell just differently. Mine saves small amounts of memory and can be argued in terms of performance
     
  18. what you are trying to do is create a configurationsection that has the same name as a location in string form. Every here is suggesting you do something that makes it look like this
    Code (Text):
    somerandonthing: locationasstring
    what you need to do is ConfigurationSection section = config.createConfigureationsection(locationturnedintoastring) then you can do section.set("item", "diamon_block") and it will appear like this
    Code (Text):
    locationasastring:
      item: Diamond_Block
    and you can add whatever else you need to. To turn locations to strings then back to locations I use the following methods
    Code (Text):
    public static Location stringToLocation(final Plugin p, final String s) {
            if (p == null || s == null || s.isEmpty())
                return null;
            final String[] args = s.split(",");
            try {
                return new Location(p.getServer().getWorld(args[0].trim()), Double.parseDouble(args[1].trim()),
                        Double.parseDouble(args[2].trim()), Double.parseDouble(args[3].trim()),
                        (float) Double.parseDouble(args[4].trim()), (float) Double.parseDouble(args[5].trim()));
            } catch (final NullPointerException e) {
                return new Location(
                        p.getServer().getWorlds().stream().filter(w -> w.getEnvironment() == Environment.NORMAL).findFirst()
                                .get(),
                        Double.parseDouble(args[1].trim()), Double.parseDouble(args[2].trim()),
                        Double.parseDouble(args[3].trim()), (float) Double.parseDouble(args[4].trim()),
                        (float) Double.parseDouble(args[5].trim()));
            } catch (final NumberFormatException | ArrayIndexOutOfBoundsException e) {
                return null;
            }
        }

        public static String locationToString(final Location l) {
            try {
                return l.getWorld().getName() + "," + round(l.getX()) + "," + round(l.getY()) + "," + round(l.getZ()) + ","
                        + round(l.getYaw()) + "," + round(l.getPitch());
            } catch (final NullPointerException e) {
                return "";
            }
        }
     
  19. Mine saves directly the location and can also be loaded with the same way without any farther issues or complications since OP only wants to save a location and get it.

    Also, if you want to save an item in the location, make sure the item is not inside the location itself because it will never work.
     
  20. Strahan

    Benefactor

    Uhhh what?? You most certainly can. It's better than these x/y/z writing methods as it saves an exact location.

    See above. How can you guys seriously think this? Have you never even tried to write a Location to the config? lol

    Any memory/performance savings due to less data is infinitesimal - the "savings" are nowhere near to balancing the work of manual serialization.
     
    • Like Like x 1

Share This Page