Developer Information

Here is how to use WorldGuard Custom Flags as a developer:

Basic

Creating a reference to WorldGuard Custom Flags

import com.mewin.WGCustomFlags.WGCustomFlagsPlugin;
import org.bukkit.Plugin;

private WGCustomFlagsPlugin getWGCustomFlags()
{
  Plugin plugin = getServer().getPluginManager().getPlugin("WGCustomFlags");
  
  if (plugin == null || !(plugin instanceof WGCustomFlagsPlugin))
  {
    return null;
  }

  return (WGCustomFlagsPlugin) plugin;
}

Creating a flag

import com.sk89q.worldguard.protection.flags.StateFlag;

public static StateFlag FLAG_NAME = new StateFlag("flag-name", true);

public void onEnable()
{
  wgCustomFlagsPlugin.addCustomFlag(FLAG_NAME);
}

if you did so it can be used with WorldGuard as every normal flag.

Advanced

Creating Custom Flags

Since 1.2.1 you can create custom flags that save custom values from your own classes. Your marshal method should return a type that can be saved in databases, otherwise WorldGuard will send errors. As it does not affect the function of the mod it does not look very nice and could irritate the user First you have to create a class for the flag that extends CustomFlag:

import com.mewin.WGCustomFlags.flags.CustomFlag;
//you will need these imports later
import com.sk89q.worldguard.protection.flags.RegionGroup;
import org.bukkit.command.CommandSender;
import com.sk89q.worldguard.protection.flags.InvalidFlagFormat;

public class SampleFlag extends CustomFlag<SampleClass>
{ ...

The class between the "<" and ">" define the type of the flag. It can be any class.

After that you have to implement the abstract methods and the constructor:

  public SampleFlag(String name, RegionGroup regionGroup)
  {
    super(name, regionGroup);
  }

  public SampleFlag(String name)
  {
    super(name);
  }
  
  /**
  * the marshal method creates a YAML compatible value to save the flag
  * possible data types are String, Integer, Double, Boolean, Map and List
  * if you use Map or List WorldGuard will give you errors, but still work correct
  * Map and List produce error message if WorldGuard has the database activated
  * @param object the instance of the class to save
  * @return an YAML compatible value to save the flag
  */
  public Object marshal(SampleClass object)
  {
    return object.toString(); //can be anything that helps you to recreate the class later
  }

  /**
  * the unmarshal method recreates the class from the value you saved
  * the data type of object is the same as when you saved the flag
  * @param object the saved value
  * @return an instance of the class representing the value
  */
  public SampleClass unmarshal(Object object)
  {
    return new SampleClass((String) object);
  }

  /**
  * this method parses the input that is given from the user by /region flag
  * @param plugin the instance of WorldGuardPlugin
  * @param sender the CommandSender (player or console by default) who tries to set the value
  * @param input the String value that the sender uses to set the flag
  * @return an instance of the object that represents the input string
  */
  public SampleClass parseInput(WorldGuardPlugin plugin, CommandSender sender, String input)
    throws InvalidFlagFormat
  {
    if (SampleClass.isValid(input))
    {
      return new SampleClass(input);
    }
    else
    {
      throw new InvalidFlagFormat("The input format is not valid: " + input);
      //you can throw an InvalidFlagFormat to give the user a feedback why the flag has not been set
    }
  }

  /**
  * The method loadFromDb is basically the same as the unmarshal method, but it is used to save your flag to the
  * WorldGuard database. The only difference is that the parameter is always a String
  * @param string the string that has been saved in the database
  * @return an instance of the class representing the string
  */
  public SampleClass loadFromDb(String string)
  {
    return new SampleClass(string);
  }

  /**
  * as loadFromDb is basically the unmarshal method, saveToDb is basically the marshal method
  * it gives a string that can be saved to the database to represent the object
  * @param object the object that should be saved
  * @return a string that represents the object
  */
  public String saveToDb(SampleClass object)
  {
    return object.toString();
  }

Now you just have to create an instance of this flag and use it as every other flag.

The utility class

You can use the Util class to check if something is allowed at a location. It requires two CustomSetFlags, one for the values to be allowed and one for the values that are denied in a region. Additionally you can give it a value that represents any value. If the allow- or the deny-flag contains this value it will be allowed/denied every time.

Example:

import com.mewin.util.Util;

public class InteractListener implents Listener
{
  private static final StringFlag PLAYER_NAME_FLAG = new StringFlag("player-name");
  private static final CustomSetFlag INTERACT_ALLOW_FLAG = new CustomSetFlag("interact-allow", PLAYER_NAME_FLAG);
  private static final CustomSetFlag INTERACT_DENY_FLAG = new CustomSetFlag("interact-deny", PLAYER_NAME_FLAG);
...
  @EventHandler
  public void onPlayerInteract(PlayerInteractEvent e)
  {
    if (!Util.flagAllowedAtLocation(wgPlugin, e.getPlayer().getName(), e.getPlayer().getLocation(), INTERACT_ALLOW_FLAG, INTERACT_DENY_FLAG, "*"))
      {
      e.setCancelled(true);
      e.getPlayer().sendMessage(ChatColor.RED + "You may not use this here.");
    }
  }
...
}

The flagAllowedAtLocation method in detail

The flagAllowedAtLocation method requires the following parameters:

parametertypedescription
1.wgpWorldGuardPluginan instance of WorldGuard
2.flagValueObjectthe value to be checked
3.locLocationthe location where the flag should be checked
4.allowFlagCustomSetFlagthe flag that contains the allowed values
5.denyFlagCustomSetFlagthe flag that contains the denied values
6.anyValueObjectthe value used as placeholder for any value, can be null

It returns true if flagValue is allowed at the location, else false. (Source)