WorldGuard Api getting a region name from a location

Discussion in 'Plugin Development' started by Drew1080, Jun 26, 2012.

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

    Drew1080

    Hi,

    I'm trying to get a a worldguard region name from where a player is standing. I know how to hook into wordguard itself, but worldguards javadocs doesnt seem to explain this very well.

    Could anyone please explain how you would do something like this.

    I've seen it been done before like in SimpleRegionMarket
     
  2. Offline

    Paul O'Reilly

    I've just done this for a plugin I'm working on. For what I needed, I was after a list of regions from a location, that didn't include the names of any parent regions (So just "Kitchen", rather then "Street"->"House"->"Kitchen")

    Worldguard regions can overlap, so you need to allow for multiple results to be returned. My needs were only for the names, so you may want to alter this to return the region's themselves if that's what you need. "plugin" refers to the worlguard plugin (like is shown in the docs), and assumes you have done sanity checks to make sure plugin != null first.

    "location" is a bukkit Location object.

    Code:
    // get the list of regions that contain the given location
    RegionManager regionManager = plugin.getRegionManager( location.getWorld());
    ApplicableRegionSet set = regionManager.getApplicableRegions( location );
    LinkedList< String > parentNames = new LinkedList< String >();
    LinkedList< String > regions = new LinkedList< String >();
    for ( ProtectedRegion region : set ) {
    String id = region.getId();
    regions.add( id );
    ProtectedRegion parent = region.getParent();
    while ( parent != null ) {
    parentNames.add( parent.getId());
    parent = parent.getParent();
    }
    }
    // before we return, we remove any area's that are 'parent' to an existing area
    for ( String name : parentNames )
    regions.remove( name );
    
     
    Drew1080 likes this.
  3. Offline

    Drew1080

    thx heaps :D

    Would this code also work to get the worldguard region's name from text on a sign?
    Because the plugin I'm making I need to get it form a sign as well.
    If you could help me do that, I would greatly appreciate it.

    Could anyone help with the getting a regions name form text on a sign?

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 26, 2016
  4. Offline

    Paul O'Reilly

    I'm not quite sure what you mean...

    If you are meaning to get both the sign text, and the worldguard regions when a player clicks on a sign, that can be done easily. When a player clicks on a sign, a PlayerInteractEvent is generated.

    From there, you can check the type of block being interacted with ( event.getClickedBlock().getTypeID() ) to see if it's one of the sign ID's - 63 and 68 in vanilla minecraft. If so, (and assuming the event isn't cancelled - event.isCancelled()), you can get the location of the sign with event.getClickedBlock().getLocation(). The location returned is what you'd feed into the example above to find the worldguard regions that the sign is inside of.

    Last, to get the text on the sign, here's a debug example from some of my current code:


    Code:
            Player player = event.getPlayer();
            BlockState block = event.getClickedBlock().getState();
         
            if ( block instanceof Sign ) {
                Sign sign = (Sign) block;
                PermitMe.log.info("DEBUG: Sign info is " + StringUtils.join( sign.getLines(), "|"));
                int count;
                try {
                    count = Integer.parseInt( sign.getLine(3));
                } catch ( NumberFormatException e ) {
                    count = 0;
                }
                sign.setLine(3, Integer.toString(count + 1));
                sign.update( true );
            }
            player.sendMessage("Sign interaction tracked");
    That debug code doesn't do much, it's a placeholder - but if the 3rd line contains a number, it will increase the number each time the sign is clicked.

    Last useful thing - you can treat left clicks and right clicks differently in a PlayerInteractionEvent, by checking event.getAction() (which could be Action.RIGHT_CLICK_BLOCK for example)
     
  5. Offline

    Drew1080

    Paul O'Reilly
    No I meant how do you use the SignChangeEvent to see if a line on the sign matches an existing worldguard region?
     
  6. Offline

    primo

    I've just done this for a plugin I'm working on. [​IMG]
     
  7. Offline

    Drew1080

    Could you shows me how to do it then please?

    I want to know how you can see if the region exists by getting the region name of a sign.
     
  8. Offline

    Paul O'Reilly

    Ah...

    So, first order of business, is getting the text from a sign. So from your SignChangeEvent event, event.getLines() will take care of that. Most plugins will reserve a line or more for data to make it easier (so maybe only using line 2, or 3). To test you are picking up the right line, and getting useful data, I'd suggest you pull the text out of getLines() that you want, and send a message back to yourself with event.getPlayer().sendMessage("DEBUG: My text is [whatever]")

    Next, you need to match the sign name with a list of all the worldguard regions.. which means you need a big list from worldguard. Best to do this when your plugin is enabled, rather then on every sign interaction.

    First step - get a list of worlds from the server.
    Your main class (that extends JavaPlugin) can use getServer() to get the server object, and getserver().getWorlds() will give you a List< World > with all the worlds of the server in it.

    Code:
    List< World> worlds = [plugin].getServer().getWorlds();
    Second step - get the region manager from worldguard for each world. (From worldguards tutorial, you should already know how to get a reference to the worlguard plugin). Easiest way to do that is to loop over each world that the server reported, get the name of it, and ask worldguard for the regionmanager of that world....

    Code:
    for ( World world : worlds ) {
                String worldName = world.getName();
                RegionManager regionManager = plugin.getRegionManager( world );
    Third step - the easy part, getting a list from the region manager of all the worldguard regions for that world.

    Code:
    Map< String, ProtectedRegion > worldRegions = regionManager.getRegions(); 
    Last step - You can get the name of each region, and now you'll have all the data you need. I assume the keys you get in the above code are also the names, but just in case...

    Code:
    for ( ProtectedRegion region : worldRegions.values()) {
    String regionName = region.getId();
     
  9. Offline

    jay911144

    How would I do this if I wanted get a region name from a player location, but get only one region(not a list) that contains the player name in the name of the region, and no parents?
     
Thread Status:
Not open for further replies.

Share This Page