Solved New object has wrong information passed to it.

Discussion in 'Spigot Plugin Development' started by thecamzone, Jul 19, 2021.

Thread Status:
Not open for further replies.
  1. Hello everyone,
    I'm trying to create a region object that stores a minimum location, a maximum location, so you can detect if a block is broken in that region. I don't want to use WorldGuard as this is a plugin for a client.

    I load the information from a yml file. I have checks after the information is loaded from the file, and its all correct until you retrieve the information from the object.

    Heres the config section I'm trying to load:
    Code (YAML):
    regions:
      test
    :
        corner1
    : test, -236.0, 64.0, -47.0
        corner2
    : test, -238.0, 64.0, -45.0
        breakableBlocks
    :
          IRON_ORE
    :
            turnsInto
    :
           - STONE
            time
    : 5
      test2
    :
        corner1
    : test, -236.0, 64.0, -51.0
        corner2
    : test, -238.0, 64.0, -49.0
        breakableBlocks
    :
          IRON_ORE
    :
            turnsInto
    :
           - STONE
            time
    : 5

    Heres the code that loads the information from the file into a new object:
    Code (Java):
    for(String region : RegionsFile.get().getConfigurationSection("regions").getKeys(false)) {
               
                String location1 = RegionsFile.get().getString("regions." + region + ".corner1");
                List<String> coordinates1 = Arrays.asList(location1.split(",[ ]*"));
               
                String location2 = RegionsFile.get().getString("regions." + region + ".corner2");
                List<String> coordinates2 = Arrays.asList(location2.split(",[ ]*"));

                Location _loc1 = new Location(Bukkit.getWorld(coordinates1.get(0)), Double.parseDouble(coordinates1.get(1)), Double.parseDouble(coordinates1.get(2)), Double.parseDouble(coordinates1.get(3)));
                Location _loc2 = new Location(Bukkit.getWorld(coordinates2.get(0)), Double.parseDouble(coordinates2.get(1)), Double.parseDouble(coordinates2.get(2)), Double.parseDouble(coordinates2.get(3)));
               
                if(regions.containsKey(region)) {
                    Bukkit.getConsoleSender().sendMessage("Overwriting " + region);
                }
               
                regions.put(region, new Region(_loc1.getWorld().getName(), _loc1, _loc2, region));
               
            }

    This is the code with my debugging messages for the console:
    Code (Java):
    for(String region : RegionsFile.get().getConfigurationSection("regions").getKeys(false)) {
               
                String location1 = RegionsFile.get().getString("regions." + region + ".corner1");
                List<String> coordinates1 = Arrays.asList(location1.split(",[ ]*"));
                Bukkit.getConsoleSender().sendMessage("Coordinates1 returns: " + coordinates1.get(0) + ", " + coordinates1.get(1) + ", " + coordinates1.get(2) + ", " + coordinates1.get(3));
               
                String location2 = RegionsFile.get().getString("regions." + region + ".corner2");
                List<String> coordinates2 = Arrays.asList(location2.split(",[ ]*"));
                Bukkit.getConsoleSender().sendMessage("Coordinates2 returns: " + coordinates2.get(0) + ", " + coordinates2.get(1) + ", " + coordinates2.get(2) + ", " + coordinates2.get(3));

                Location _loc1 = new Location(Bukkit.getWorld(coordinates1.get(0)), Double.parseDouble(coordinates1.get(1)), Double.parseDouble(coordinates1.get(2)), Double.parseDouble(coordinates1.get(3)));
                Bukkit.getConsoleSender().sendMessage("Loc1 returns: " + _loc1.getWorld().getName() + ", " + _loc1.getX() + ", " + _loc1.getY() + ", " + _loc1.getZ());
                Location _loc2 = new Location(Bukkit.getWorld(coordinates2.get(0)), Double.parseDouble(coordinates2.get(1)), Double.parseDouble(coordinates2.get(2)), Double.parseDouble(coordinates2.get(3)));
                Bukkit.getConsoleSender().sendMessage("Loc2 returns: " + _loc2.getWorld().getName() + ", " + _loc2.getX() + ", " + _loc2.getY() + ", " + _loc2.getZ());
               
                if(regions.containsKey(region)) {
                    Bukkit.getConsoleSender().sendMessage("Overwriting " + region);
                }
               
                regions.put(region, new Region(_loc1.getWorld().getName(), _loc1, _loc2, region));
               
            }

    Here is the constructor for the Region object:
    Code (Java):
        public Region(String world, Location min, Location max, String name) {
            this.world = world;
            this.loc1 = min;
            this.loc2 = max;
            this.name = name;
           
            if(RegionsFile.get().getConfigurationSection("regions").getKeys(false) != null) {
                loadRegions();
            }
           
            getInfo();
        }

        public void getInfo() {
            Bukkit.getConsoleSender().sendMessage("-------------------");
            Bukkit.getConsoleSender().sendMessage("Name: " + name);
            Bukkit.getConsoleSender().sendMessage("World: " + world);
            Bukkit.getConsoleSender().sendMessage("Loc1: " + loc1.getX() + ", " + loc1.getY() + ", " + loc1.getZ());
            Bukkit.getConsoleSender().sendMessage("Loc2: " + loc2.getX() + ", " + loc2.getY() + ", " + loc2.getZ());
            Bukkit.getConsoleSender().sendMessage("-------------------");
        }

    and finally, heres the console output verifying the information loaded into the Region object:
    Code (Text):
    [18:49:12 INFO]: Coordinates1 returns: test, -236.0, 64.0, -47.0
    [18:49:12 INFO]: Coordinates2 returns: test, -238.0, 64.0, -45.0
    [18:49:12 INFO]: Loc1 returns: test, -236.0, 64.0, -47.0
    [18:49:12 INFO]: Loc2 returns: test, -238.0, 64.0, -45.0
    [18:49:12 INFO]: -------------------
    [18:49:12 INFO]: Name: test
    [18:49:12 INFO]: World: test
    [18:49:12 INFO]: Loc1: -236.0, 64.0, -51.0
    [18:49:12 INFO]: Loc2: -238.0, 64.0, -49.0
    [18:49:12 INFO]: -------------------
    [18:49:12 INFO]: Coordinates1 returns: test, -236.0, 64.0, -51.0
    [18:49:12 INFO]: Coordinates2 returns: test, -238.0, 64.0, -49.0
    [18:49:12 INFO]: Loc1 returns: test, -236.0, 64.0, -51.0
    [18:49:12 INFO]: Loc2 returns: test, -238.0, 64.0, -49.0
    [18:49:12 INFO]: -------------------
    [18:49:12 INFO]: Name: test2
    [18:49:12 INFO]: World: test
    [18:49:12 INFO]: Loc1: -236.0, 64.0, -51.0
    [18:49:12 INFO]: Loc2: -238.0, 64.0, -49.0
    [18:49:12 INFO]: -------------------

    Specifically look at the Z-axis of the console output. The first region that is loaded has -47 and -45 all the way up until its loaded into memory. (The section surrounded by the lines is what is being read from the Region object which has already been loaded. The method is #getInfo() in the region constructor spoiler.). Then it changes to -51 and -49, which is the same as the second region loaded.

    There are no error messages in the console.

    I'm not sure how the information is being changed from outputting the correct coordinates a line before it is loaded as a new object.

    Any help would be appreciated. I'm not even sure what to google to help solve this issue.
     
  2. I am not certain, but I think that you have confused yourself with changing min to loc1, and max to loc2?
    Surely you need to asses the minX(), the minY() and the minZ() of both locations in order to obtain the actual loc1 minimum location.
    And the same for the maxX(), maxY(), and maxZ() to obtain the maximum location for loc2.
    Edit:
    You should also do this for the 'Y' location.
    A block location has 3 dimensions.
     
    #2 Goldentoenail, Jul 20, 2021
    Last edited: Jul 20, 2021
    • Agree Agree x 1
  3. You have a couple of weird things:
    1. You're calling two methods inside your region constructor - every time you construct a new region object you are loading ALL the regions from your regions file, I can understand wanting to debug the values that are going into the object, but you shouldn't be calling loadRegions() or getInfo() there.
      Region r = new Region(_loc1.getWorld().getName(), _loc1, _loc2, region);
      r.getInfo() // debug
      regions.put(region, r);
    2. In your loader you are creating a List from an array for no reason - just access the array directly:
      String[] c1 = location1.split(",[ ]*");
      Location loc1 = new Location(Bukkit.getWorld(c1[0]), Double.parseDouble(c1[1]), Double.parseDouble(c1[2]), Double.parseDouble(c1[3]));
     
  4. You only need String name for the region name and 2 location points for your reference, the Location object already have a reference for the world.
     
  5. Alright. I was being really dumb (old reply outlined in the spoiler below). I accidentally reset the location in my loadRegion method. I thought I tested without that method but it turns out I didn't. Thanks for helping me clean up my code everyone. Made it much easier to debug.

    Thank you all for the responses.

    I did realize that the code was severely more complicated than it needed to be. Thanks @eccentric for helping me see the much better path to take for that. I also fixed what @PandaDevX said with the names. Really dumb way of handling that on my part.

    @Goldentoenail I handle the actual minimum and maximum coordinates after the object is created and is actually being used. In my opinion, that makes it easier for the end-user not to have to worry about Min and Max coordinates, just define the 2 points around the object. Thank you for that suggestion.

    My gut feeling tells me there's something going on with the for loop that is loading information from the file.
    Code (Java):
    for(String region : RegionsFile.get().getConfigurationSection("regions").getKeys(false))
    The first object has the second objects information after being loaded. I have a check for if the information is getting overwritten in the createRegionObject method. I just am at my wit's end for debugging that.

    Now with the simplified code, I'm still getting the same error.

    Heres the method that loads the information from the file.
    Code (Java):
    public void setup() {
            if(RegionsFile.get().getConfigurationSection("regions") == null) {
                Bukkit.getConsoleSender().sendMessage("[OreRegeneration] No regions to load.");
                return;
            }
     
            for(String region : RegionsFile.get().getConfigurationSection("regions").getKeys(false)) {
         
                String location1 = RegionsFile.get().getString("regions." + region + ".corner1");
                String[] c1 = location1.split(",[ ]*");
                Location loc1 = new Location(Bukkit.getWorld(c1[0]), Double.parseDouble(c1[1]), Double.parseDouble(c1[2]), Double.parseDouble(c1[3]));
         
                String location2 = RegionsFile.get().getString("regions." + region + ".corner2");
                String[] c2 = location2.split(",[ ]*");
                Location loc2 = new Location(Bukkit.getWorld(c2[0]), Double.parseDouble(c2[1]), Double.parseDouble(c2[2]), Double.parseDouble(c2[3]));
         
                Region r = createRegionObject(c1[0], loc1, loc2, region);
                r.getInfo();
         
                regions.put(region, r);
            }
     
        }
     
        public Region createRegionObject(String world, Location min, Location max, String name) {
            if(regions.containsKey(name)) {
                Bukkit.getConsoleSender().sendMessage("Overwriting " + name);
            }
     
            Bukkit.getConsoleSender().sendMessage("-------------------");
            Bukkit.getConsoleSender().sendMessage("Info used to create new object:");
            Bukkit.getConsoleSender().sendMessage("Name: " + name);
            Bukkit.getConsoleSender().sendMessage("World: " + world);
            Bukkit.getConsoleSender().sendMessage("Loc1: " + min.getX() + ", " + min.getY() + ", " + min.getZ());
            Bukkit.getConsoleSender().sendMessage("Loc2: " + max.getX() + ", " + max.getY() + ", " + max.getZ());
            Bukkit.getConsoleSender().sendMessage("-------------------");
     
            return new Region(world, min, max, name);
        }

    Here's a simplified console output.
    Code (Text):
    [10:45:00 INFO]: -------------------
    [10:45:00 INFO]: Info used to create new object:
    [10:45:00 INFO]: Name: test
    [10:45:00 INFO]: World: test
    [10:45:00 INFO]: Loc1: -236.0, 64.0, -47.0
    [10:45:00 INFO]: Loc2: -238.0, 64.0, -45.0
    [10:45:00 INFO]: -------------------
    [10:45:00 INFO]: -------------------
    [10:45:00 INFO]: Info inside of object:
    [10:45:00 INFO]: Name: test
    [10:45:00 INFO]: World: test
    [10:45:00 INFO]: Loc1: -236.0, 64.0, -51.0
    [10:45:00 INFO]: Loc2: -238.0, 64.0, -49.0
    [10:45:00 INFO]: -------------------
    [10:45:00 INFO]: -------------------
    [10:45:00 INFO]: Info used to create new object:
    [10:45:00 INFO]: Name: test2
    [10:45:00 INFO]: World: test
    [10:45:00 INFO]: Loc1: -236.0, 64.0, -51.0
    [10:45:00 INFO]: Loc2: -238.0, 64.0, -49.0
    [10:45:00 INFO]: -------------------
    [10:45:00 INFO]: -------------------
    [10:45:00 INFO]: Info inside of object:
    [10:45:00 INFO]: Name: test2
    [10:45:00 INFO]: World: test
    [10:45:00 INFO]: Loc1: -236.0, 64.0, -51.0
    [10:45:00 INFO]: Loc2: -238.0, 64.0, -49.0
    [10:45:00 INFO]: -------------------

    And here's the configuration file for reference.
    Code (YAML):
    regions:
      test
    :
        corner1
    : test, -236.0, 64.0, -47.0
        corner2
    : test, -238.0, 64.0, -45.0
        breakableBlocks
    :
          IRON_ORE
    :
            turnsInto
    :
           - STONE
            time
    : 5
      test2
    :
        corner1
    : test, -236.0, 64.0, -51.0
        corner2
    : test, -238.0, 64.0, -49.0
        breakableBlocks
    :
          IRON_ORE
    :
            turnsInto
    :
           - STONE
            time
    : 5

    Is there another more streamlined way of going about this that could be easier to debug? I'm having a hard time thinking of a better implementation.

    EDIT: I forgot to mention that the loadRegion method is called to load the blocks in the region into memory after it has been created.
     
    #5 thecamzone, Jul 21, 2021
    Last edited: Jul 21, 2021
Thread Status:
Not open for further replies.