Compare commits

...
Author SHA1 Message Date
sk89q ee2ed762c2 Added a better and more complete implementation for attributes with sane class names. 2013-02-07 12:11:25 -08:00
sk89q a0dceaa713 Added StringAttr.
The name of the class could be better.
2013-02-06 17:29:48 -08:00
sk89q 4b15855b2f Revert "Removed parents from regions."
Removal of parents will make upgrading extremely difficult and so consider them pending for the itme being.

This reverts commit df54d4de91.
2013-02-06 17:19:09 -08:00
sk89q 7acfb3586c Cleanup Attribute Javadocs. 2013-02-06 17:17:28 -08:00
sk89q a841aa7215 Added Stereotypes for group support for flags/attributes.
They are not yet functional because they require some extra mechanics not yet written (access to factories and whatnot).
2013-02-06 17:17:12 -08:00
sk89q f752c305d7 Made ApplicationRegionSet implement Collection<Region>, and made it keep the given list sorted. 2013-02-05 20:39:13 -08:00
sk89q 840700b719 Might as well make ApplicableRegionSet implement Collection<Region>. 2013-02-05 20:32:33 -08:00
sk89q 8f73a15ba3 Gutted ApplicableRegionSet. 2013-02-05 20:29:11 -08:00
sk89q 4e008f6c52 Made the class Javadoc of AbstractRegionQueryCache sane. 2013-02-05 20:20:31 -08:00
sk89q df54d4de91 Removed parents from regions.
After a minor discussion, parent-child relationships are being removed because they:
(1) confuse users
(2) make everything much more difficult to program
(3) do not allow for a use case that is not already doable with priorities
2013-02-05 20:06:11 -08:00
sk89q 0768e08e71 Minor cleanup. 2013-02-05 20:04:19 -08:00
sk89q 040e35f65b Added some misisng methods to DataValuedAttribute and added a test. 2013-02-05 16:25:59 -08:00
sk89q 919c03a57b Made Attribute abstract, rewrote Javadocs. 2013-02-05 16:16:45 -08:00
sk89q a13f556c7b Added AttributeTest. 2013-02-05 13:30:59 -08:00
sk89q 5bfb9e48f4 RegionTest cleanup. 2013-02-05 13:30:41 -08:00
sk89q ff209abb8c Added support for attributes to Region. 2013-02-05 13:18:46 -08:00
sk89q 7987258fe2 Added equals(), hashCode(), and toString() to Attribute. 2013-02-05 13:04:04 -08:00
sk89q 4cba9d01ec Replaced flags with attributes. 2013-02-05 13:00:44 -08:00
sk89q e703999c8f Added a simple test for com.sk89q.worldguard.region.Region. Flags are not yet tested. 2013-02-03 23:46:39 -08:00
sk89q bfc8691118 Added org.mockito:mockito-all v1.9.5 as test dependency. 2013-02-03 23:46:14 -08:00
sk89q 061b303faa Removed old broken unit tests.
We may look at them in the future once those tests are needed again.
2013-02-03 23:45:38 -08:00
sk89q 3b985f7eab Fixed potential resource leak in LegacyMySqlStoreFactory.getSql(). 2013-02-03 23:26:26 -08:00
sk89q a027721f37 Renamed RegionIndex.queryOverlapping() -> queryIntersects() and added an implementation under AbstractRegionIndex using IndexableShape.intersectsEdges(). 2013-02-03 23:24:32 -08:00
sk89q 129412ba79 Canning isOwnerOfAll() and isMemberOfAll() of ApplicableRegionSet. 2012-11-17 16:46:31 -08:00
sk89q e0ab79bd36 Canning RegionUtil, which is now completely useless. 2012-11-17 16:45:37 -08:00
sk89q 28a1f225ee Removed very broken and now irrelevant regions migration code. 2012-11-17 16:41:17 -08:00
sk89q 355168a3ac Removed isMember()/isOwner() as it is no longer relevant (to be placed with FlagResolvers). 2012-11-17 16:37:38 -08:00
sk89q 27c6819df9 Removed /claim. To be rewritten very differently. 2012-11-17 16:37:02 -08:00
sk89q 122c1aa003 Removed some left over CommandBook listener registration in WorldGuardPlugin. 2012-11-17 16:36:04 -08:00
sk89q 644d6ee512 Commented out regions-related code in ReportWriter as it is no longer valid. 2012-11-17 16:35:48 -08:00
sk89q 58cc4392c8 Removing RegionQueryUtil, which might not be needed anymore. 2012-11-17 16:35:24 -08:00
sk89q e228315dfd Removed CommandBook integration for /whois for now. 2012-11-17 16:35:03 -08:00
sk89q 8a308cd521 Remove old pre-5.x migration routines from WorldGuardPlugin. 2012-11-17 16:34:28 -08:00
sk89q c3d3c1812f Removing migration support for WorldGuard 4.x and below. 2012-11-17 16:33:37 -08:00
sk89q cc5958bc2f Removed FlagStateManager for now. To be added later. 2012-11-17 16:32:15 -08:00
sk89q 2d8911c9ce Added LegacyMySqlStoreFactory, moved .sql files to src/main/resources/sql. 2012-11-17 16:29:20 -08:00
sk89q c6a0c61028 Made LegacyMySqlStore compile. Domain not yet supported. 2012-11-17 16:28:54 -08:00
sk89q 0c0cbcc1b0 Added com.jolnox:bonecp as dependency. 2012-11-17 16:28:24 -08:00
sk89q 5882e30357 Add initialize() to RegionStoreFactory to allow some setup actions. 2012-11-17 16:27:50 -08:00
sk89q 4faf0a9b2e YamlStore needs to call reindex() after loading. 2012-11-17 16:27:25 -08:00
sk89q 2e4093e953 Removed FatalConfigurationLoadingException and InvalidTableFormatException. 2012-11-16 17:00:50 -08:00
sk89q 1a9a3274a6 YamlStoreFactory added.
Example usage:
StoreFactory factory = new YamlStoreFactory(new File("regions"), "worlds/%s/regions.yml"));
2012-11-16 16:42:37 -08:00
sk89q 8671fbc396 Implemented YamlStore.close(), which does nothing. 2012-11-16 16:41:05 -08:00
sk89q 50c4b3c738 RegionStore and RegionStoreFactory now extend Closeable. 2012-11-16 16:40:29 -08:00
sk89q 23f0791231 Changed MySQLStore to LegacyMySqlStore.
We're going to need a new MySqlStore that is not so poorly written. This is going to need a lot of work.
2012-11-16 16:07:34 -08:00
sk89q fa11dd6d62 Made YamlStore fit its interfaces so that there are no more compile errors.
It is, however, not yet ready, because it doesn't yet support custom flags or load in the old domain data.
2012-11-16 16:05:51 -08:00
sk89q 58fa6d1c0b Extracted RegionStore.save(Collection<Region> added, Collection<Region> updated, Collection<Region> removed) into PartiallyUpdatableStore.
This is necessary because some stores need to always save the entire database at a time (namely the YAML store), and adding an "all" parameter to the partial save method would mean that partial stores could not be supported in the future.
2012-11-16 15:52:37 -08:00
sk89q 723f17b782 Region indices now implement Collection<Region>.
In addition, PriorityRTreeIndex now extends FlatIndex! That should reduce some code duplication.
2012-11-16 15:40:09 -08:00
sk89q fe2e399451 RegionIndex now extends Iterable<Region>. 2012-11-16 13:49:33 -08:00
sk89q 6fa7faad12 Removed ProtectionDatabaseException and AbstractProtectionDatabase. 2012-11-16 13:43:14 -08:00
sk89q c864a1c252 RegionStore.save(Region added[], Region updated[], Region removed[]) throws IOException as well. 2012-11-16 13:42:59 -08:00
sk89q 386288b89a RegionStore's load() and save() methods can now throw IOExceptions.
ProtectionDatabaseException will be removed shortly.
2012-11-16 13:42:23 -08:00
sk89q b3425b2630 Region is no longer abstract, added Region.setFlagUnsafe(). 2012-11-16 13:39:26 -08:00
sk89q f8105c3de0 Fixed Javadocs for shapes. 2012-11-16 13:38:44 -08:00
sk89q bcf35085ed Indices now have a separate reindex() method because large changes to the index have to be supported.
Therefore, indices are no longer thread-safe. They don't need to be.
2012-11-16 13:36:26 -08:00
sk89q b7064cb102 Removed LegacyCsvStore and RegionDBUtil. 2012-11-16 10:12:59 -08:00
sk89q 6c282cfe0a Moved Region's package to com.sk89q.worldguard.region. 2012-11-16 10:11:08 -08:00
sk89q f8e0410d23 Finished com.sk89q.worldguard.region.shapes. 2012-11-16 09:28:46 -08:00
sk89q e8274e76ca Moved ProtectedRegion forward with some changes. 2012-11-15 17:17:56 -08:00
sk89q 393b15ac7a Added IndexableShape and its abstract brother. 2012-11-13 23:19:11 -08:00
sk89q 38f40908ee Say bye to com.sk89q.worldguard.domains.*. 2012-11-13 23:17:34 -08:00
sk89q caee1df596 Moved MySQLToYAMLMigrator to com.sk89q.worldguard.migration. 2012-11-13 01:03:24 -08:00
sk89q d9d655b6b2 Added RegionStore and RegionStoreFactory. 2012-11-13 01:02:41 -08:00
sk89q cc9bbec1c9 Added support for RegionIndexFactories. 2012-11-13 00:57:29 -08:00
sk89q 2a504ffbde Moved migration classes to com.sk89q.worldguard.migration. 2012-11-13 00:51:19 -08:00
sk89q 5f11c5710b Changed RegionIndex.{add|remove} to take in multiple regions to update, which may be faster for some index types. 2012-11-12 21:33:05 -08:00
sk89q 5d3409be57 Moved region.indexes package to region.indices. 2012-11-12 21:29:02 -08:00
sk89q ad921a2111 Updated the existing index code to work with the new RegionIndex interface. 2012-11-12 21:28:27 -08:00
sk89q 50ec8e5875 Added commons-lang:commons-lang:2.3 dependency. 2012-11-12 21:27:59 -08:00
sk89q fc9e28ddb9 Started with defining the new RegionIndex.
This definitely no longer compiles.
2012-11-12 20:08:34 -08:00
sk89q 35e02459ea Moved region classes to com.sk89q.worldguard.region. Preparing for some big changes.
The new classes will not (and should not) be backwards compatible, so the classes might as well be changed all around.
2012-11-12 01:24:34 -08:00
sk89q 0781ebc289 Added ?in-region and ?has-flag, and added the support to make protection models work. 2012-11-11 16:27:31 -08:00
sk89q 915e332a6b Fixed issue with block-place RL event not being given a source entity. 2012-11-11 16:26:34 -08:00
sk89q 19859164ab Moved settings loading in WorldConfiguration to loadSettings(), add preliminary loading of protection models. 2012-11-10 23:32:40 -08:00
sk89q bb7f972897 Added resource models/ to distributed JAR. 2012-11-10 23:32:12 -08:00
sk89q e355bb0055 Fixed missing exception message for an unknown action/criteria class in RuleEntryLoader. 2012-11-10 23:31:43 -08:00
sk89q 9b1b665da7 Removed some chest protection code, which will be replaced with RuleLists. 2012-11-10 22:35:57 -08:00
sk89q 6daf80229d Fixed condition issue in EntityCriteria that broke entity type checking. 2012-11-10 21:29:31 -08:00
sk89q dc1f3f54b1 Redesigned how RuleLists were compiled and created to be less roundabout. 2012-11-10 21:29:00 -08:00
sk89q 579143a5dd Added support for the region query cache on Bukkit's side and added it to BukkitContext. 2012-11-10 10:48:25 -08:00
sk89q f4e52f5cd7 Added Javadocs to BukkitContext. 2012-11-10 00:31:50 -08:00
sk89q abea9689cb Removed blacklist/region code for now, to be converted to RuleLists.
Additionally, a chat rule list event was added, the vehicle destruction event was routed to rule lists, and so was the bed enter event.
2012-11-09 14:49:45 -08:00
144 changed files with 6149 additions and 11146 deletions

No files matched your search

+27
View File
@@ -95,6 +95,24 @@
<version>4.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.3</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.jolbox</groupId>
<artifactId>bonecp</artifactId>
<version>0.7.1.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
</dependencies>
<distributionManagement>
<site>
@@ -133,6 +151,15 @@
<include>rulelist.yml</include>
</includes>
</resource>
<resource>
<targetPath></targetPath>
<filtering>false</filtering>
<directory>${basedir}/src/main/resources/</directory>
<includes>
<include>models/</include>
<include>sql/</include>
</includes>
</resource>
</resources>
<plugins>
@@ -5,11 +5,11 @@
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
@@ -19,22 +19,57 @@
package com.sk89q.rulelists;
/**
* An object that can learn rules and possibly implement them. Attachments can be
* analogous to events that occur in the game. An attachment, for example, would be
* a block break event.
* An attachment is analogous to an event.
*/
public interface Attachment {
public final class Attachment {
private static int NEXT_ID = 0;
private final int id;
private final String alias;
/**
* Learn a rule.
* Create a new attachment with the given alias. The alias is used in rule list
* files.
*
* @param rule rule
* @param alias alias name
*/
public void learn(Rule<?> rule);
public Attachment(String alias) {
this.alias = alias;
// No internal ID
id = -1;
}
/**
* Forget all previously learned rules.
* Create a new attachment with the given alias. The alias is used in rule list
* files.
*
* @param alias alias name
* @param isInternal true to assign this attachment a standard internal ID
*/
public void forgetRules();
Attachment(String alias, boolean isInternal) {
this.alias = alias;
id = isInternal ? NEXT_ID++ : -1;
}
/**
* Get the internal ID.
*
* @return ID number, possibly -1 for no internal ID
*/
int getId() {
return id;
}
/**
* Get the alias used inside rule list files.
*
* @return alias
*/
public String getAlias() {
return alias;
}
}
@@ -5,11 +5,11 @@
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
@@ -19,44 +19,59 @@
package com.sk89q.rulelists;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import com.sk89q.rebar.config.Loader;
import com.sk89q.rebar.config.LoaderBuilderException;
/**
* Manages known attachment points.
*
* @see Attachment
* A database of valid attachments.
*/
public class AttachmentManager {
public final class AttachmentManager implements Loader<Attachment> {
private final Map<String, Attachment> attachments = new HashMap<String, Attachment>();
private Set<Attachment> attachments = new HashSet<Attachment>();
private Map<String, Attachment> aliasMap = new HashMap<String, Attachment>();
/**
* Register an {@link Attachment}.
*
* @param name name of the attachment (used in a rule's 'when' clause) (case insensitive)
* @param attachment attachment
*/
public void register(String name, Attachment attachment) {
attachments.put(name.toLowerCase(), attachment);
public AttachmentManager() {
}
/**
* Get an attachment.
* Register an attachment.
*
* @param name name of the attachment (case insensitive)
* @return attachment
* @param attachment the attachment
*/
public Attachment get(String name) {
return attachments.get(name.toLowerCase());
}
/**
* Forget all the rules in the registered attachments.
*/
public void forgetRules() {
for (Attachment attachment : attachments.values()) {
attachment.forgetRules();
public synchronized void register(Attachment attachment) {
if (attachments.contains(attachment)
|| aliasMap.containsKey(attachment.getAlias().toLowerCase())) {
throw new IllegalArgumentException("Attachment '" + attachment + "' already registered.");
}
attachments.add(attachment);
aliasMap.put(attachment.getAlias().toLowerCase(), attachment);
}
/**
* Get an attachment by its alias.
*
* @param alias alias, case in-sensitive
* @return an attachment or null
*/
public synchronized Attachment lookup(String alias) {
return aliasMap.get(alias.toLowerCase());
}
@Override
public Attachment read(Object value) throws LoaderBuilderException {
String id = String.valueOf(value);
Attachment attachment = lookup(id);
if (attachment == null) {
throw new LoaderBuilderException("Unknown RuleList attachment: " + id);
}
return attachment;
}
}
@@ -0,0 +1,80 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY), without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.rulelists;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
/**
* Contains names of standard attachments.
*/
public final class DefaultAttachments {
public final static Attachment BLOCK_BREAK = new Attachment("block-break", true);
public final static Attachment BLOCK_PLACE = new Attachment("block-place", true);
public final static Attachment BLOCK_SPREAD = new Attachment("block-spread", true);
public final static Attachment BLOCK_PHYSICS = new Attachment("block-physics", true);
public final static Attachment BLOCK_INTERACT = new Attachment("block-interact", true);
public final static Attachment BLOCK_FADE = new Attachment("block-fade", true);
public final static Attachment BLOCK_FORM = new Attachment("block-form", true);
public final static Attachment PLAYER_JOIN = new Attachment("player-join", true);
public final static Attachment PLAYER_RESPAWN = new Attachment("player-respawn", true);
public final static Attachment PLAYER_QUIT = new Attachment("player-quit", true);
public final static Attachment ENTITY_EXPLODE = new Attachment("entity-explode", true);
public final static Attachment ENTITY_DAMAGE = new Attachment("entity-damage", true);
public final static Attachment ENTITY_DEATH = new Attachment("entity-death", true);
public final static Attachment ENTITY_IGNITE = new Attachment("entity-ignite", true);
public final static Attachment ENTITY_SPAWN = new Attachment("entity-spawn", true);
public final static Attachment ENTITY_STRIKE = new Attachment("entity-strike", true);
public final static Attachment ENTITY_INTERACT = new Attachment("entity-interact", true);
public final static Attachment CHAT = new Attachment("chat", true);
public final static Attachment ITEM_DROP = new Attachment("item-drop", true);
public final static Attachment ITEM_PICKUP = new Attachment("item-pickup", true);
public final static Attachment ITEM_USE = new Attachment("item-use", true);
public final static Attachment WEATHER_PHENOMENON = new Attachment("weather-phenomenon", true);
public final static Attachment WEATHER_TRANSITION = new Attachment("weather-transition", true);
public final static Attachment WORLD_LOAD = new Attachment("world-load", true);
public final static Attachment WORLD_UNLOAD = new Attachment("world-unload", true);
public final static Attachment WORLD_SAVE = new Attachment("world-save", true);
private DefaultAttachments() {
}
/**
* Register the attachments in this class with the given manager.
*
* @param manager the manager
*/
public static void registerWith(AttachmentManager manager) {
for (Field field : DefaultAttachments.class.getFields()) {
if (Modifier.isStatic(field.getModifiers())
&& Attachment.class.isAssignableFrom(field.getType())) {
try {
manager.register((Attachment) field.get(null));
} catch (IllegalArgumentException e) {
throw new RuntimeException("Failed to register default attachment", e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to register default attachment", e);
}
}
}
}
}
@@ -1,89 +0,0 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY), without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.rulelists;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
/**
* Contains names of standard attachments.
*/
public enum KnownAttachment {
BLOCK_BREAK("block-break"),
BLOCK_PLACE("block-place"),
BLOCK_SPREAD("block-spread"),
BLOCK_PHYSICS("block-physics"),
BLOCK_INTERACT("block-interact"),
BLOCK_FADE("block-fade"),
BLOCK_FORM("block-form"),
PLAYER_JOIN("player-join"),
PLAYER_RESPAWN("player-respawn"),
PLAYER_QUIT("player-quit"),
ENTITY_EXPLODE("entity-explode"),
ENTITY_DAMAGE("entity-damage"),
ENTITY_DEATH("entity-death"),
ENTITY_IGNITE("entity-ignite"),
ENTITY_SPAWN("entity-spawn"),
ENTITY_STRIKE("entity-strike"),
ENTITY_INTERACT("entity-interact"),
ITEM_DROP("item-drop"),
ITEM_PICKUP("item-pickup"),
ITEM_USE("item-use"),
WEATHER_PHENOMENON("weather-phenomenon"),
WEATHER_TRANSITION("weather-transition"),
WORLD_LOAD("world-load"),
WORLD_UNLOAD("world-unload"),
WORLD_SAVE("world-save");
private final static Map<String, KnownAttachment> ids = new HashMap<String, KnownAttachment>();
static {
for (KnownAttachment attachment : EnumSet.allOf(KnownAttachment.class)) {
ids.put(attachment.getId().toLowerCase(), attachment);
}
}
private final String id;
KnownAttachment(String id) {
this.id = id;
}
/**
* Get the attachment's string ID.
*
* @return string ID
*/
public String getId() {
return id;
}
/**
* Get an attachment from a given string ID. Not case sensitive.
*
* @param id string ID
* @return attachment name
*/
public static KnownAttachment fromId(String id) {
return ids.get(id.toLowerCase());
}
}
@@ -1,52 +0,0 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.rulelists;
import java.util.EnumMap;
import java.util.Map;
/**
* Holds known attachment rule sets for every {@link KnownAttachment}.
*/
public class KnownAttachmentRules {
private Map<KnownAttachment, RuleSet> ruleSets =
new EnumMap<KnownAttachment, RuleSet>(KnownAttachment.class);
/**
* Build a new instance, with every attachment having an empty {@link RuleSet}
* defined for it.
*/
public KnownAttachmentRules() {
for (KnownAttachment attachment : KnownAttachment.values()) {
ruleSets.put(attachment, new RuleSet());
}
}
/**
* Get a rule set for a given attachment.
*
* @param attachment the attachment
* @return the rule set
*/
public RuleSet get(KnownAttachment attachment) {
return ruleSets.get(attachment);
}
}
@@ -5,11 +5,11 @@
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
@@ -21,36 +21,36 @@ package com.sk89q.rulelists;
import java.util.List;
/**
* A pair of attachment/event names a rule.
* A pair of attachments and a rule.
*/
public class RuleEntry {
private final List<String> attachmentNames;
private final List<Attachment> attachments;
private final Rule<?> rule;
/**
* Construct the rule entry with the list of attachment names and rules.
*
* @param attachmentNames attachment names
* Construct the rule entry with the list of attachments and rules.
*
* @param attachments attachment names
* @param rule rules
*/
public RuleEntry(List<String> attachmentNames, Rule<?> rule) {
this.attachmentNames = attachmentNames;
public RuleEntry(List<Attachment> attachments, Rule<?> rule) {
this.attachments = attachments;
this.rule = rule;
}
/**
* Get the list of attachment names.
*
* @return attachment names
* Get the list of attachments.
*
* @return attachment
*/
public List<String> getAttachmentNames() {
return attachmentNames;
public List<Attachment> getAttachments() {
return attachments;
}
/**
* Get the rule.
*
*
* @return rule
*/
public Rule<?> getRule() {
@@ -18,7 +18,6 @@
package com.sk89q.rulelists;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
@@ -34,8 +33,10 @@ import com.sk89q.rebar.util.LoggerUtils;
public class RuleEntryLoader extends AbstractNodeLoader<RuleEntry> {
public static final String INLINE = "_";
private static Logger logger = LoggerUtils.getLogger(RuleEntryLoader.class, "[WorldGuard] RuleList: ");
private static final Logger logger = LoggerUtils.getLogger(RuleEntryLoader.class);
private final AttachmentManager attachmentManager;
private final DefinitionLoader<Criteria<?>> criteriaLoader;
private final DefinitionLoader<Action<?>> actionLoader;
@@ -45,6 +46,7 @@ public class RuleEntryLoader extends AbstractNodeLoader<RuleEntry> {
* @param ruleListsManager the action lists manager
*/
public RuleEntryLoader(RuleListsManager ruleListsManager) {
attachmentManager = ruleListsManager.getAttachments();
criteriaLoader = new DefinitionLoader<Criteria<?>>(ruleListsManager.getCriterion(), true);
actionLoader = new DefinitionLoader<Action<?>>(ruleListsManager.getActions(), false);
}
@@ -56,7 +58,7 @@ public class RuleEntryLoader extends AbstractNodeLoader<RuleEntry> {
return null;
}
List<String> when = node.getStringList("when", new ArrayList<String>());
List<Attachment> when = node.listOf("when", attachmentManager);
// Check to see if the rule has any events defined
if (when.size() == 0) {
@@ -150,17 +152,18 @@ public class RuleEntryLoader extends AbstractNodeLoader<RuleEntry> {
}
// No class defined!
logger.warning("EventListeners: Missing '?' parameter in definition " +
logger.warning("RuleList: Missing '?' parameter in definition " +
"(to define what kind of criteria/action it is)");
return null;
} catch (DefinitionException e) {
logger.warning("EventListeners: Invalid definition " +
logger.warning("RuleList: Invalid definition " +
"identified by type '" + id + "': " + e.getMessage());
// Throw an exception in strict mode
if (strict) {
throw new LoaderBuilderException();
throw new LoaderBuilderException("RuleList: Invalid definition " +
"identified by type '" + id + "': " + e.getMessage());
}
return null;
@@ -0,0 +1,83 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.rulelists;
import java.util.HashMap;
import java.util.Map;
/**
* Holds all the rules.
*/
public class RuleList {
private Map<Attachment, RuleSet> collections = new HashMap<Attachment, RuleSet>();
/**
* Build a new instance.
*/
public RuleList() {
}
/**
* Get a rule set for a given attachment. A rule set is guaranteed to be
* returned for all given attachments.
*
* @param attachment the attachment
* @return the rule set
*/
public synchronized RuleSet get(Attachment attachment) {
RuleSet collection = collections.get(attachment);
if (collection == null) {
collection = new RuleSet();
collections.put(attachment, collection);
}
return collection;
}
/**
* Register a rule with this rule list.
*
* @param entry entry
*/
public void learn(RuleEntry entry) {
Rule<?> rule = entry.getRule();
for (Attachment attachment : entry.getAttachments()) {
learn(attachment, rule);
}
}
/**
* Register a rule with this rule list.
*
* @param attachment the attachment for the rule
* @param rule the rule itself
*/
public void learn(Attachment attachment, Rule<?> rule) {
get(attachment).learn(rule);
}
/**
* Forget all rules.
*/
public void clear() {
collections.clear();
}
}
@@ -5,11 +5,11 @@
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
@@ -41,7 +41,7 @@ public class RuleListsManager {
/**
* Get the criterion manager.
*
* @return criteron manager
* @return criterion manager
*/
public DefinitionManager<Criteria<?>> getCriterion() {
return criterion;
+48 -16
View File
@@ -5,11 +5,11 @@
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
@@ -18,43 +18,75 @@
package com.sk89q.rulelists;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
public class RuleSet implements Attachment {
/**
* Holds a collection of rules that can be applied to a context.
*
* @see RuleList
*/
public class RuleSet {
private List<Rule<?>> rules = new LinkedList<Rule<?>>();
@Override
public void learn(Rule<?> rule) {
RuleSet() {
}
/**
* Add the given rule to this set.
*
* @param rule the rule
*/
public synchronized void learn(Rule<?> rule) {
rules.add(rule);
}
@Override
public void forgetRules() {
/**
* Forget all rules.
*/
public synchronized void clear() {
rules.clear();
}
public boolean hasRules() {
/**
* Return whether this set has rules.
*
* @return true if there are rules
*/
public synchronized boolean hasRules() {
return rules.size() > 0;
}
public List<Rule<?>> getRules() {
return rules;
/**
* Get the list of rules. The returned list cannot be modified.
*
* @return rule list
*/
public synchronized List<Rule<?>> getRules() {
return Collections.unmodifiableList(rules);
}
/**
* Apply this rule set onto the given context. Only one thread should call
* this method at a given time.
*
* @param context the context
* @return true if the event has been cancelled
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public boolean process(Context context) {
if (context.isCancelled()) {
return true; // Ignore cancelled events for now
}
for (Rule rule : rules) {
if (rule.matches(context)) {
rule.apply(context);
}
}
return context.isCancelled();
}
@@ -0,0 +1,26 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY), without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard;
/**
* A user, group, or other object that describes a set of users.
*/
public interface Classifier {
}
@@ -24,10 +24,19 @@ import org.bukkit.event.Event;
import org.bukkit.inventory.ItemStack;
import com.sk89q.rulelists.Context;
import com.sk89q.worldguard.region.ApplicableRegionSet;
/**
* An implementation of a {@link Context} for Bukkit. This object is thread-safe, but
* the underlying objects returned by this class may not be.
*
* @see Context
*/
public class BukkitContext extends Context {
private final RegionQueryCache regionCache;
private final Event event;
private RegionQuery regionQuery;
private String message;
private Entity sourceEntity;
private Entity targetEntity;
@@ -35,69 +44,195 @@ public class BukkitContext extends Context {
private BlockState sourceBlock;
private BlockState targetBlock;
private BlockState replacedTargetBlock;
private ApplicableRegionSet lastApplRegionSet;
public BukkitContext(Event event) {
/**
* Construct a context linked to the given event.
*
* @param plugin the WorldGuard plugin
* @param event the event
*/
BukkitContext(WorldGuardPlugin plugin, Event event) {
this.regionCache = plugin.getRegionCache();
this.event = event;
}
/**
* Get the message attribute of this context.
*
* @return message or null
*/
public String getMessage() {
return message;
}
/**
* Set the message attribute of this context.
*
* @param message or null
*/
public void setMessage(String message) {
this.message = message;
}
/**
* Get the source entity for this context. The source entity is the 'cause' of
* this context, if it is available.
*
* @return entity or null
*/
public Entity getSourceEntity() {
return sourceEntity;
}
/**
* Set the source entity for this context. The source entity is the 'cause' of
* this context, if it is available.
*
* @param sourceEntity entity or null
*/
public void setSourceEntity(Entity sourceEntity) {
this.sourceEntity = sourceEntity;
}
/**
* Get the target entity for this context. The target entity is the 'subject'
* of this context, if it is available.
*
* @return entity or null
*/
public Entity getTargetEntity() {
return targetEntity;
}
/**
* Set the target entity for this context. The target entity is the 'subject'
* of this context, if it is available.
*
* @param targetEntity entity or null
*/
public void setTargetEntity(Entity targetEntity) {
this.targetEntity = targetEntity;
}
/**
* Get the primary item related to this context. Only events that are oriented
* around an item have this property set.
*
* @return item or null
*/
public ItemStack getItem() {
return item;
}
/**
* Set the primary item related to this context. Only events that are oriented
* around an item have this property set.
*
* @param item item or null
*/
public void setItem(ItemStack item) {
this.item = item;
}
/**
* Get the source block for this context. The source block is the 'cause'
* of this context, if it is available.
*
* @return block or null
*/
public BlockState getSourceBlock() {
return sourceBlock;
}
/**
* Set the source block for this context. The source block is the 'cause'
* of this context, if it is available.
*
* @param block block or null
*/
public void setSourceBlock(BlockState block) {
this.sourceBlock = block;
}
/**
* Get a target block for this context. The target block is the 'subject' of
* this context, if it is available.
*
* @return block or null
*/
public BlockState getTargetBlock() {
return targetBlock;
}
/**
* Set a target block for this context. The target block is the 'subject' of
* this context, if it is available.
*
* @param targetBlock block or null
*/
public void setTargetBlock(BlockState targetBlock) {
this.targetBlock = targetBlock;
}
/**
* Get the placed block for this context. The placed block is the 'new' block
* that will replace the existing block in this context, if it is available.
*
* @return block or null
*/
public BlockState getPlacedBlock() {
return replacedTargetBlock;
}
/**
* Set the placed block for this context. The placed block is the 'new' block
* that will replace the existing block in this context, if it is available.
*
* @param replacedTargetBlock block or null
*/
public void setPlacedBlock(BlockState replacedTargetBlock) {
this.replacedTargetBlock = replacedTargetBlock;
}
/**
* Get the last {@link ApplicableRegionSet}. This can be set by a rule and used
* within one, but it cannot be guaranteed to exist across rules.
*
* @return an {@link ApplicableRegionSet} or null
*/
public ApplicableRegionSet getApplicableRegionSet() {
return lastApplRegionSet;
}
/**
* Set the last {@link ApplicableRegionSet}.
*
* @param set an {@link ApplicableRegionSet} or null
*/
public void setApplicableRegionSet(ApplicableRegionSet set) {
this.lastApplRegionSet = set;
}
/**
* Get the underlying event object.
*
* @return event object
*/
public Event getEvent() {
return event;
}
/**
* Get the region query object.
*
* @return region query object
*/
public synchronized RegionQuery getRegionQuery() {
if (regionQuery == null) {
regionQuery = regionCache.against(event);
}
return regionQuery;
}
}
@@ -257,4 +257,19 @@ public class BukkitUtil {
return null;
}
static void checkAndDestroy(World world, int x, int y, int z, int required) {
if (world.getBlockTypeIdAt(x, y, z) == required) {
world.getBlockAt(x, y, z).setTypeId(BlockID.AIR);
}
}
static void checkAndDestroyAround(World world, int x, int y, int z, int required) {
checkAndDestroy(world, x, y, z + 1, required);
checkAndDestroy(world, x, y, z - 1, required);
checkAndDestroy(world, x, y + 1, z, required);
checkAndDestroy(world, x, y - 1, z, required);
checkAndDestroy(world, x + 1, y, z, required);
checkAndDestroy(world, x - 1, y, z, required);
}
}
@@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.events;
package com.sk89q.worldguard.bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
@@ -1,237 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.GameMode;
import org.bukkit.World;
import org.bukkit.entity.Player;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
/**
* This processes per-player state information and is also meant to be used
* as a scheduled task.
*
* @author sk89q
*/
public class FlagStateManager implements Runnable {
public static final int RUN_DELAY = 20;
private WorldGuardPlugin plugin;
private Map<String, PlayerFlagState> states;
/**
* Construct the object.
*
* @param plugin The plugin instance
*/
public FlagStateManager(WorldGuardPlugin plugin) {
this.plugin = plugin;
states = new HashMap<String, PlayerFlagState>();
}
/**
* Run the task.
*/
@Override
public void run() {
Player[] players = plugin.getServer().getOnlinePlayers();
ConfigurationManager config = plugin.getGlobalStateManager();
for (Player player : players) {
WorldConfiguration worldConfig = config.get(player.getWorld());
if (!worldConfig.useRegions) {
continue;
}
PlayerFlagState state;
synchronized (this) {
state = states.get(player.getName());
if (state == null) {
state = new PlayerFlagState();
states.put(player.getName(), state);
}
}
Vector playerLocation = toVector(player.getLocation());
RegionManager regionManager = plugin.getGlobalRegionManager()
.get(player.getWorld());
ApplicableRegionSet applicable = regionManager
.getApplicableRegions(playerLocation);
if (!RegionQueryUtil.isInvincible(plugin, player, applicable)
&& !plugin.getGlobalStateManager().hasGodMode(player)
&& !(player.getGameMode() == GameMode.CREATIVE)) {
processHeal(applicable, player, state);
processFeed(applicable, player, state);
}
}
}
/**
* Process healing for a player.
*
* @param applicable The set of applicable regions
* @param player The player to process healing flags on
* @param state The player's state
*/
private void processHeal(ApplicableRegionSet applicable, Player player,
PlayerFlagState state) {
if (player.getHealth() <= 0) {
return;
}
long now = System.currentTimeMillis();
Integer healAmount = applicable.getFlag(DefaultFlag.HEAL_AMOUNT);
Integer healDelay = applicable.getFlag(DefaultFlag.HEAL_DELAY);
Integer minHealth = applicable.getFlag(DefaultFlag.MIN_HEAL);
Integer maxHealth = applicable.getFlag(DefaultFlag.MAX_HEAL);
if (healAmount == null || healDelay == null || healAmount == 0 || healDelay < 0) {
return;
}
if (minHealth == null) minHealth = 0;
if (maxHealth == null) maxHealth = 20;
if (player.getHealth() >= maxHealth && healAmount > 0) {
return;
}
if (healDelay <= 0) {
player.setHealth(healAmount > 0 ? maxHealth : minHealth); // this will insta-kill if the flag is unset
state.lastHeal = now;
} else if (now - state.lastHeal > healDelay * 1000) {
// clamp health between minimum and maximum
player.setHealth(Math.min(maxHealth, Math.max(minHealth, player.getHealth() + healAmount)));
state.lastHeal = now;
}
}
/**
* Process restoring hunger for a player.
*
* @param applicable The set of applicable regions
* @param player The player to process hunger flags on
* @param state The player's state
*/
private void processFeed(ApplicableRegionSet applicable, Player player,
PlayerFlagState state) {
long now = System.currentTimeMillis();
Integer feedAmount = applicable.getFlag(DefaultFlag.FEED_AMOUNT);
Integer feedDelay = applicable.getFlag(DefaultFlag.FEED_DELAY);
Integer minHunger = applicable.getFlag(DefaultFlag.MIN_FOOD);
Integer maxHunger = applicable.getFlag(DefaultFlag.MAX_FOOD);
if (feedAmount == null || feedDelay == null || feedAmount == 0 || feedDelay < 0) {
return;
}
if (minHunger == null) minHunger = 0;
if (maxHunger == null) maxHunger = 20;
if (player.getFoodLevel() >= maxHunger && feedAmount > 0) {
return;
}
if (feedDelay <= 0) {
player.setFoodLevel(feedAmount > 0 ? maxHunger : minHunger);
state.lastFeed = now;
} else if (now - state.lastFeed > feedDelay * 1000) {
// clamp health between minimum and maximum
player.setFoodLevel(Math.min(maxHunger, Math.max(minHunger, player.getFoodLevel() + feedAmount)));
state.lastFeed = now;
}
}
/**
* Forget a player.
*
* @param player The player to forget
*/
public synchronized void forget(Player player) {
states.remove(player.getName());
}
/**
* Forget all managed players. Use with caution.
*/
public synchronized void forgetAll() {
states.clear();
}
/**
* Get a player's flag state. A new state will be created if there is no existing
* state for the player.
*
* @param player The player to get a state for
* @return The {@code player}'s state
*/
public synchronized PlayerFlagState getState(Player player) {
PlayerFlagState state = states.get(player.getName());
if (state == null) {
state = new PlayerFlagState();
states.put(player.getName(), state);
}
return state;
}
/**
* Keeps state per player.
*/
public static class PlayerFlagState {
public long lastHeal;
public long lastFeed;
public String lastGreeting;
public String lastFarewell;
public Boolean lastExitAllowed = null;
public Boolean notifiedForLeave = false;
public Boolean notifiedForEnter = false;
public GameMode lastGameMode;
public World lastWorld;
public int lastBlockX;
public int lastBlockY;
public int lastBlockZ;
/* Used to cache invincibility status */
public World lastInvincibleWorld;
public int lastInvincibleX;
public int lastInvincibleY;
public int lastInvincibleZ;
public boolean wasInvincible;
}
}
@@ -1,154 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.bukkit.World;
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
import com.sk89q.worldguard.protection.databases.CSVDatabase;
import com.sk89q.worldguard.protection.managers.RegionManager;
/**
* Utility methods for porting from legacy versions.
*
* @author sk89q
*/
public class LegacyWorldGuardMigration {
/**
* Port over the blacklist.
*
* @param plugin The plugin instance
*/
public static void migrateBlacklist(WorldGuardPlugin plugin) {
World mainWorld = plugin.getServer().getWorlds().get(0);
String mainWorldName = mainWorld.getName();
String newPath = "worlds/" + mainWorldName + "/blacklist.txt";
File oldFile = new File(plugin.getDataFolder(), "blacklist.txt");
File newFile = new File(plugin.getDataFolder(), newPath);
if (!newFile.exists() && oldFile.exists()) {
plugin.getLogger().warning("WorldGuard will now update your blacklist "
+ "from an older version of WorldGuard.");
// Need to make root directories
newFile.getParentFile().mkdirs();
if (copyFile(oldFile, newFile)) {
oldFile.renameTo(new File(plugin.getDataFolder(),
"blacklist.txt.old"));
} else {
plugin.getLogger().warning("blacklist.txt has been converted " +
"for the main world at " + newPath + "");
plugin.getLogger().warning("Your other worlds currently have no " +
"blacklist defined!");
}
}
}
/**
* Migrate region settings.
*
* @param plugin The plugin instance
*/
public static void migrateRegions(WorldGuardPlugin plugin) {
try {
File oldDatabase = new File(plugin.getDataFolder(), "regions.txt");
if (!oldDatabase.exists()) return;
plugin.getLogger().info("The regions database has changed in 5.x. "
+ "Your old regions database will be converted to the new format "
+ "and set as your primary world's database.");
World w = plugin.getServer().getWorlds().get(0);
RegionManager mgr = plugin.getGlobalRegionManager().get(w);
// First load up the old database using the CSV loader
CSVDatabase db = new CSVDatabase(oldDatabase, plugin.getLogger());
db.load();
// Then save the new database
mgr.setRegions(db.getRegions());
mgr.save();
oldDatabase.renameTo(new File(plugin.getDataFolder(), "regions.txt.old"));
plugin.getLogger().info("Regions database converted!");
} catch (ProtectionDatabaseException e) {
plugin.getLogger().warning("Failed to load regions: "
+ e.getMessage());
}
}
/**
* Copies a file.
*
* @param from The source file
* @param to The destination file
* @return true if successful
*/
private static boolean copyFile(File from, File to) {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(from);
out = new FileOutputStream(to);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
return true;
} catch (FileNotFoundException ignore) {
} catch (IOException ignore) {
} finally {
if (in != null) {
try {
in.close();
} catch (IOException ignore) {
}
}
if (out != null) {
try {
out.close();
} catch (IOException ignore) {
}
}
}
return false;
}
}
@@ -22,28 +22,28 @@ import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.event.Event;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.GlobalRegionManager;
import com.sk89q.worldguard.protection.RegionQueryCache;
import com.sk89q.worldguard.region.ApplicableRegionSet;
import com.sk89q.worldguard.region.RegionManager;
import com.sk89q.worldguard.region.RegionQueryCacheEntry;
/**
* An implementation of {@link RegionQueryCache} for Bukkit. This implementation is
* thread-safe.
* A class that will cache all region queries. Instances of this class are created
* via an instance of {@link RegionQueryCache} and represent a point in time.
*/
public class BukkitRegionQueryCache extends RegionQueryCache {
public final class RegionQuery {
private final WorldGuardPlugin plugin;
private final RegionQueryCacheEntry entry;
/**
* Construct the cache with the given plugin instance.
* Construct the instance with the underlying cache entry.
*
* @param plugin plugin instance
* @param entry
*/
public BukkitRegionQueryCache(WorldGuardPlugin plugin) {
RegionQuery(WorldGuardPlugin plugin, RegionQueryCacheEntry entry) {
this.plugin = plugin;
this.entry = entry;
}
/**
@@ -51,23 +51,22 @@ public class BukkitRegionQueryCache extends RegionQueryCache {
* temporarily cached for the given event, or null if region protection has
* been disabled for the the world of the given location.
*
* @param event the event to cache against
* @param location the location to check
* @return the set, or null if region protection is disabled for the given location
*/
public ApplicableRegionSet lookup(Event event, Location location) {
public ApplicableRegionSet lookup(Location location) {
World world = location.getWorld();
Vector vector = BukkitUtil.toVector(location);
ConfigurationManager config = plugin.getGlobalStateManager();
WorldConfiguration worldConfig = config.get(world);
GlobalRegionManager regionManager = plugin.getGlobalRegionManager();
RegionManager regionManager = plugin.getGlobalRegionManager();
if (!worldConfig.useRegions) {
return null;
}
return get(event).lookup(regionManager.get(world), vector);
return entry.lookup(regionManager.get(world), vector);
}
/**
@@ -75,12 +74,11 @@ public class BukkitRegionQueryCache extends RegionQueryCache {
* temporarily cached for the given event, or null if region protection has
* been disabled for the the world of the given block.
*
* @param event the event to cache against
* @param block the block to check
* @return the set, or null if region protection is disabled for the given block
*/
public ApplicableRegionSet lookup(Event event, Block block) {
return lookup(event, block.getLocation());
public ApplicableRegionSet lookup(Block block) {
return lookup(block.getLocation());
}
/**
@@ -88,12 +86,11 @@ public class BukkitRegionQueryCache extends RegionQueryCache {
* temporarily cached for the given event, or null if region protection has
* been disabled for the the world of the given entity.
*
* @param event the event to cache against
* @param entity the entity to check
* @return the set, or null if region protection is disabled for the given entity
*/
public ApplicableRegionSet lookup(Event event, Entity entity) {
return lookup(event, entity.getLocation());
public ApplicableRegionSet lookup(Entity entity) {
return lookup(entity.getLocation());
}
}
@@ -0,0 +1,53 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
import org.bukkit.event.Event;
import com.sk89q.worldguard.region.AbstractRegionQueryCache;
/**
* An implementation of {@link AbstractRegionQueryCache} for Bukkit. This implementation
* is thread-safe.
*/
public final class RegionQueryCache extends AbstractRegionQueryCache {
private final WorldGuardPlugin plugin;
/**
* Construct the cache with the given plugin instance.
*
* @param plugin plugin instance
*/
public RegionQueryCache(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
/**
* Get a {@link RegionQuery} object that can cache region queries. The object
* returned by this method does not need to be cached. It is merely a proxy class.
*
* @param event the event to cache against
* @return an object to perform lookups against
*/
public RegionQuery against(Event event) {
return new RegionQuery(plugin, get(event));
}
}
@@ -1,83 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Player;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
public class RegionQueryUtil {
public static boolean isInvincible(WorldGuardPlugin plugin, Player player) {
return isInvincible(plugin, player, null);
}
public static boolean isInvincible(WorldGuardPlugin plugin, Player player,
ApplicableRegionSet set) {
Location loc = player.getLocation();
World world = player.getWorld();
FlagStateManager.PlayerFlagState state = plugin.getFlagStateManager().getState(player);
if (state.lastInvincibleWorld == null ||
!state.lastInvincibleWorld.equals(world) ||
state.lastInvincibleX != loc.getBlockX() ||
state.lastInvincibleY != loc.getBlockY() ||
state.lastInvincibleZ != loc.getBlockZ()) {
state.lastInvincibleX = loc.getBlockX();
state.lastInvincibleY = loc.getBlockY();
state.lastInvincibleZ = loc.getBlockZ();
state.lastInvincibleWorld = world;
if (set == null) {
Vector vec = new Vector(state.lastInvincibleX,
state.lastInvincibleY, state.lastInvincibleZ);
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
set = mgr.getApplicableRegions(vec);
}
state.wasInvincible = set.allows(DefaultFlag.INVINCIBILITY, plugin.wrapPlayer(player));
}
return state.wasInvincible;
}
public static Boolean isAllowedInvinciblity(WorldGuardPlugin plugin, Player player) {
World world = player.getWorld();
FlagStateManager.PlayerFlagState state = plugin.getFlagStateManager().getState(player);
Vector vec = new Vector(state.lastInvincibleX, state.lastInvincibleY, state.lastInvincibleZ);
StateFlag.State regionState = plugin.getGlobalRegionManager().get(world).
getApplicableRegions(vec).getFlag(DefaultFlag.INVINCIBILITY, plugin.wrapPlayer(player));
if (regionState == StateFlag.State.ALLOW) {
return Boolean.TRUE;
} else if (regionState == StateFlag.State.DENY) {
return Boolean.FALSE;
} else {
return null;
}
}
}
@@ -35,22 +35,17 @@ import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.plugin.Plugin;
import com.sk89q.worldguard.protection.GlobalRegionManager;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.region.RegionManager;
import com.sk89q.worldguard.util.LogListBlock;
public class ReportWriter {
private static final SimpleDateFormat dateFmt =
new SimpleDateFormat("yyyy-MM-dd kk:mm Z");
private Date date = new Date();
private StringBuilder output = new StringBuilder();
public ReportWriter(WorldGuardPlugin plugin) {
appendReportHeader(plugin);
appendServerInformation(plugin.getServer());
@@ -63,38 +58,38 @@ public class ReportWriter {
appendln("END OF REPORT");
appendln();
}
protected static String repeat(String str, int n) {
if(str == null) {
return null;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
sb.append(str);
}
return sb.toString();
}
protected void appendln(String text) {
output.append(text);
output.append("\r\n");
}
protected void appendln(String text, Object ... args) {
output.append(String.format(text, args));
output.append("\r\n");
}
protected void append(LogListBlock log) {
output.append(log.toString());
}
protected void appendln() {
output.append("\r\n");
}
protected void appendHeader(String text) {
String rule = repeat("-", text.length());
output.append(rule);
@@ -104,7 +99,7 @@ public class ReportWriter {
output.append("\r\n");
appendln();
}
private void appendReportHeader(WorldGuardPlugin plugin) {
appendln("WorldGuard Configuration Report");
appendln("Generated " + dateFmt.format(date));
@@ -112,13 +107,13 @@ public class ReportWriter {
appendln("Version: " + plugin.getDescription().getVersion());
appendln();
}
private void appendGlobalConfiguration(ConfigurationManager config) {
appendHeader("Global Configuration");
LogListBlock log = new LogListBlock();
LogListBlock configLog = log.putChild("Configuration");
Class<? extends ConfigurationManager> cls = config.getClass();
for (Field field : cls.getFields()) {
try {
@@ -130,16 +125,16 @@ public class ReportWriter {
} catch (IllegalAccessException ignore) {
}
}
append(log);
appendln();
}
private void appendServerInformation(Server server) {
appendHeader("Server Information");
LogListBlock log = new LogListBlock();
Runtime runtime = Runtime.getRuntime();
log.put("Java", "%s %s (%s)",
@@ -164,23 +159,23 @@ public class ReportWriter {
append(log);
appendln();
}
private void appendPluginInformation(Plugin[] plugins) {
appendHeader("Plugins (" + plugins.length + ")");
LogListBlock log = new LogListBlock();
for (Plugin plugin : plugins) {
log.put(plugin.getDescription().getName(), plugin.getDescription().getVersion());
}
append(log);
appendln();
/*appendHeader("Plugin Information");
log = new LogListBlock();
for (Plugin plugin : plugins) {
log.putChild(plugin.getDescription().getName())
.put("Data folder", plugin.getDataFolder())
@@ -191,20 +186,20 @@ public class ReportWriter {
append(log);
appendln();*/
}
private void appendWorldInformation(List<World> worlds) {
appendHeader("Worlds");
LogListBlock log = new LogListBlock();
int i = 0;
for (World world : worlds) {
int loadedChunkCount = world.getLoadedChunks().length;
LogListBlock worldLog = log.putChild(world.getName() + " (" + i + ")");
LogListBlock infoLog = worldLog.putChild("Information");
LogListBlock entitiesLog = worldLog.putChild("Entities");
infoLog.put("Seed", world.getSeed());
infoLog.put("Environment", world.getEnvironment().toString());
infoLog.put("Player count", world.getPlayers().size());
@@ -212,21 +207,21 @@ public class ReportWriter {
infoLog.put("Loaded chunk count", loadedChunkCount);
infoLog.put("Spawn location", world.getSpawnLocation());
infoLog.put("Raw time", world.getFullTime());
Map<Class<? extends Entity>, Integer> entityCounts =
new HashMap<Class<? extends Entity>, Integer>();
// Collect entities
for (Entity entity : world.getEntities()) {
Class<? extends Entity> cls = entity.getClass();
if (entityCounts.containsKey(cls)) {
entityCounts.put(cls, entityCounts.get(cls) + 1);
} else {
entityCounts.put(cls, 1);
}
}
// Print entities
for (Map.Entry<Class<? extends Entity>, Integer> entry
: entityCounts.entrySet()) {
@@ -235,18 +230,18 @@ public class ReportWriter {
entry.getValue(),
(float) (entry.getValue() / (double) loadedChunkCount));
}
i++;
}
append(log);
appendln();
}
private void appendWorldConfigurations(WorldGuardPlugin plugin, List<World> worlds,
GlobalRegionManager regionMgr, ConfigurationManager mgr) {
RegionManager regionMgr, ConfigurationManager mgr) {
appendHeader("World Configurations");
LogListBlock log = new LogListBlock();
int i = 0;
@@ -264,9 +259,9 @@ public class ReportWriter {
+ world.getName() + "/blacklist.txt")).getAbsoluteFile());
infoLog.put("Regions file", (new File(plugin.getDataFolder(), "worlds/"
+ world.getName() + "/regions.yml")).getAbsoluteFile());
WorldConfiguration config = mgr.get(world);
Class<? extends WorldConfiguration> cls = config.getClass();
for (Field field : cls.getFields()) {
try {
@@ -277,7 +272,7 @@ public class ReportWriter {
} catch (IllegalAccessException ignore) {
}
}
if (config.getBlacklist() == null) {
blacklistLog.put("State", "DISABLED");
} else {
@@ -288,13 +283,13 @@ public class ReportWriter {
config.getBlacklist().isWhitelist());
}
RegionManager worldRegions = regionMgr.get(world);
/*RegionIndex worldRegions = regionMgr.get(world);
regionsLog.put("Type", worldRegions.getClass().getCanonicalName());
regionsLog.put("Number of regions", worldRegions.getRegions().size());
LogListBlock globalRegionLog = regionsLog.putChild("Global region");
ProtectedRegion globalRegion = worldRegions.getRegion("__global__");
Region globalRegion = worldRegions.getRegion("__global__");
if (globalRegion == null) {
globalRegionLog.put("Status", "UNDEFINED");
} else {
@@ -304,17 +299,17 @@ public class ReportWriter {
globalRegion.getFlag(flag));
}
}
}
}*/
}
append(log);
appendln();
}
public void write(File file) throws IOException {
FileWriter writer = null;
BufferedWriter out;
try {
writer = new FileWriter(file);
out = new BufferedWriter(writer);
@@ -329,7 +324,7 @@ public class ReportWriter {
}
}
}
@Override
public String toString() {
return output.toString();
@@ -22,21 +22,24 @@ package com.sk89q.worldguard.bukkit;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import com.sk89q.rebar.config.ConfigurationException;
import com.sk89q.rebar.config.ConfigurationNode;
import com.sk89q.rebar.config.YamlConfiguration;
import com.sk89q.rebar.config.YamlConfigurationFile;
import com.sk89q.rebar.config.YamlConfigurationResource;
import com.sk89q.rebar.config.YamlStyle;
import com.sk89q.rebar.util.LoggerUtils;
import com.sk89q.rulelists.KnownAttachment;
import com.sk89q.rulelists.KnownAttachmentRules;
import com.sk89q.rulelists.RuleList;
import com.sk89q.rulelists.RuleEntry;
import com.sk89q.rulelists.RuleEntryLoader;
import com.sk89q.rulelists.RuleTemplateEntryLoader;
@@ -45,8 +48,6 @@ import com.sk89q.worldguard.blacklist.BlacklistLogger;
import com.sk89q.worldguard.blacklist.loggers.ConsoleLoggerHandler;
import com.sk89q.worldguard.blacklist.loggers.DatabaseLoggerHandler;
import com.sk89q.worldguard.blacklist.loggers.FileLoggerHandler;
import com.sk89q.worldguard.chest.ChestProtection;
import com.sk89q.worldguard.chest.SignChestProtection;
/**
* Holds the configuration for individual worlds.
@@ -61,8 +62,7 @@ public class WorldConfiguration {
private final String worldName;
private Blacklist blacklist;
private KnownAttachmentRules ruleList = new KnownAttachmentRules();
private ChestProtection chestProtection = new SignChestProtection();
private RuleList ruleList = new RuleList();
private SpongeApplicator spongeApplicator = null;
/* Configuration data start */
@@ -113,47 +113,11 @@ public class WorldConfiguration {
loadConfig();
// Load rule lists
ruleList.clear();
loadBuiltInRules();
loadUserRules();
loadBlacklist();
// Load other rules
opPermissions = config.getBoolean("op-permissions", true);
boolean simulateSponge = config.getBoolean("simulation.sponge.enable", true);
int spongeRadius = Math.max(1, config.getInt("simulation.sponge.radius", 3)) - 1;
boolean redstoneSponges = config.getBoolean("simulation.sponge.redstone", false);
boolean refillArea = config.getBoolean("simulation.sponge.refill-area", false);
if (simulateSponge) {
spongeApplicator = new SpongeApplicator(spongeRadius, redstoneSponges, refillArea);
}
signChestProtection = config.getBoolean("chest-protection.enable", false);
disableSignChestProtectionCheck = config.getBoolean("chest-protection.disable-off-check", false);
useRegions = config.getBoolean("regions.enable", true);
regionInvinciblityRemovesMobs = config.getBoolean("regions.invincibility-removes-mobs", false);
highFreqFlags = config.getBoolean("regions.high-frequency-flags", false);
regionWand = config.getInt("regions.wand", 287);
maxClaimVolume = config.getInt("regions.max-claim-volume", 30000);
claimOnlyInsideExistingRegions = config.getBoolean("regions.claim-only-inside-existing-regions", false);
maxRegionCountPerPlayer = config.getInt("regions.max-region-count-per-player.default", 7);
maxRegionCounts = new HashMap<String, Integer>();
maxRegionCounts.put(null, maxRegionCountPerPlayer);
for (String key : config.getKeys("regions.max-region-count-per-player")) {
if (!key.equalsIgnoreCase("default")) {
Object val = config.get("regions.max-region-count-per-player." + key);
if (val != null && val instanceof Number) {
maxRegionCounts.put(key, ((Number) val).intValue());
}
}
}
// useiConomy = getBoolean("iconomy.enable", false);
// buyOnClaim = getBoolean("iconomy.buy-on-claim", false);
// buyOnClaimPrice = getDouble("iconomy.buy-on-claim-price", 1.0);
loadSettings();
saveConfig();
}
@@ -204,7 +168,7 @@ public class WorldConfiguration {
for (List<RuleEntry> entries : plugin.getBuiltInRules().listOf("", loader)) {
for (RuleEntry entry : entries) {
learnRule(entry);
ruleList.learn(entry);
}
}
} catch (IOException e) {
@@ -227,7 +191,7 @@ public class WorldConfiguration {
rulesConfig.load();
for (RuleEntry entry : rulesConfig.listOf(ConfigurationNode.ROOT, entryLoader)) {
learnRule(entry);
ruleList.learn(entry);
}
} catch (IOException e) {
logger.log(Level.SEVERE, "Failed to load " + rulesFile.getAbsolutePath(), e);
@@ -292,60 +256,116 @@ public class WorldConfiguration {
}
}
public Blacklist getBlacklist() {
/**
* Load the settings.
*/
private void loadSettings() {
opPermissions = config.getBoolean("op-permissions", true);
boolean simulateSponge = config.getBoolean("simulation.sponge.enable", true);
int spongeRadius = Math.max(1, config.getInt("simulation.sponge.radius", 3)) - 1;
boolean redstoneSponges = config.getBoolean("simulation.sponge.redstone", false);
boolean refillArea = config.getBoolean("simulation.sponge.refill-area", false);
if (simulateSponge) {
spongeApplicator = new SpongeApplicator(spongeRadius, redstoneSponges, refillArea);
}
signChestProtection = config.getBoolean("chest-protection.enable", false);
disableSignChestProtectionCheck = config.getBoolean("chest-protection.disable-off-check", false);
useRegions = config.getBoolean("regions.enable", true);
regionInvinciblityRemovesMobs = config.getBoolean("regions.invincibility-removes-mobs", false);
highFreqFlags = config.getBoolean("regions.high-frequency-flags", false);
regionWand = config.getInt("regions.wand", 287);
maxClaimVolume = config.getInt("regions.max-claim-volume", 30000);
claimOnlyInsideExistingRegions = config.getBoolean("regions.claim-only-inside-existing-regions", false);
maxRegionCountPerPlayer = config.getInt("regions.max-region-count-per-player.default", 7);
maxRegionCounts = new HashMap<String, Integer>();
maxRegionCounts.put(null, maxRegionCountPerPlayer);
for (String key : config.getKeys("regions.max-region-count-per-player")) {
if (!key.equalsIgnoreCase("default")) {
Object val = config.get("regions.max-region-count-per-player." + key);
if (val != null && val instanceof Number) {
maxRegionCounts.put(key, ((Number) val).intValue());
}
}
}
// Very important part for protection!
if (useRegions) {
loadRegionModels();
}
// useiConomy = getBoolean("iconomy.enable", false);
// buyOnClaim = getBoolean("iconomy.buy-on-claim", false);
// buyOnClaimPrice = getDouble("iconomy.buy-on-claim-price", 1.0);
}
/**
* Load region protection model.
*/
private void loadRegionModels() {
List<String> filenames;
RuleEntryLoader entryLoader = new RuleEntryLoader(plugin.getRulesListManager());
// Make a default protection model list
List<String> defaultProtectionModels = new ArrayList<String>();
defaultProtectionModels.add("minimal");
// Load protection model
filenames = config.getStringList("regions.protection-models", defaultProtectionModels);
for (YamlConfiguration config : readFiles(filenames, "/models/protection/",
new File(plugin.getDataFolder(), "models/protection"))) {
for (RuleEntry entry : config.listOf(ConfigurationNode.ROOT, entryLoader)) {
ruleList.learn(entry);
}
}
}
/**
* Get the blacklist.
*
* @return the blacklist
*/
Blacklist getBlacklist() {
return blacklist;
}
/**
* Get the RuleList.
*
* @return the rule list
*/
RuleList getRuleList() {
return ruleList;
}
/**
* Get the sponge applicator.
*
* @return sponge applicator
*/
SpongeApplicator getSpongeApplicator() {
return spongeApplicator;
}
/**
* Get the world name of this configuration.
*
* @return the world name
*/
public String getWorldName() {
return this.worldName;
}
public boolean isChestProtected(Block block, Player player) {
if (!signChestProtection) {
return false;
}
if (plugin.hasPermission(player, "worldguard.chest-protection.override")
|| plugin.hasPermission(player, "worldguard.override.chest-protection")) {
return false;
}
return chestProtection.isProtected(block, player);
}
public boolean isChestProtected(Block block) {
return signChestProtection && chestProtection.isProtected(block, null);
}
public boolean isChestProtectedPlacement(Block block, Player player) {
if (!signChestProtection) {
return false;
}
if (plugin.hasPermission(player, "worldguard.chest-protection.override")
|| plugin.hasPermission(player, "worldguard.override.chest-protection")) {
return false;
}
return chestProtection.isProtectedPlacement(block, player);
}
public boolean isAdjacentChestProtected(Block block, Player player) {
if (!signChestProtection) {
return false;
}
if (plugin.hasPermission(player, "worldguard.chest-protection.override")
|| plugin.hasPermission(player, "worldguard.override.chest-protection")) {
return false;
}
return chestProtection.isAdjacentChestProtected(block, player);
}
public ChestProtection getChestProtection() {
return chestProtection;
}
/**
* Get the maximum region count for a given player.
*
* @param player player
* @return number of regions
*/
public int getMaxRegionCount(Player player) {
int max = -1;
for (String group : plugin.getGroups(player)) {
@@ -360,23 +380,55 @@ public class WorldConfiguration {
return max;
}
public KnownAttachmentRules getRuleList() {
return ruleList;
}
/**
* Register a rule with this rule list.
* Read a list of files, either from the .jar (preferred) or from disk.
*
* @param entry entry
* @param filenames list of filenames
* @param internalDir the base path for the JAR files
* @param externalDir the base dir for the disk files
* @return a list of {@link YamlConfiguration}s
*/
public void learnRule(RuleEntry entry) {
for (String name : entry.getAttachmentNames()) {
KnownAttachment attachment = KnownAttachment.fromId(name);
if (attachment != null) {
ruleList.get(attachment).learn(entry.getRule());
} else {
logger.warning("Don't know what the RuleList event '" + name + "' is");
private static List<YamlConfiguration> readFiles(Collection<String> filenames,
String internalDir, File externalDir) {
List<YamlConfiguration> configs = new ArrayList<YamlConfiguration>();
for (String filename : filenames) {
YamlConfiguration config;
// External file path
File file = new File(externalDir, filename);
file.getParentFile().mkdirs();
// Try loading from the .jar first
String path = internalDir + filename + ".yml";
config = new YamlConfigurationResource(WorldGuardPlugin.class, path);
try {
config.load();
configs.add(config);
continue; // Found!
} catch (FileNotFoundException e) {
// Do nothing
} catch (IOException e) {
logger.log(Level.SEVERE, "Failed to internal path " + path, e);
} catch (ConfigurationException e) {
logger.log(Level.SEVERE, "Failed to internal path " + path, e);
}
// Try loading from disk
config = new YamlConfigurationFile(file, new YamlStyle(), false);
try {
config.load();
configs.add(config);
continue; // Found!
} catch (FileNotFoundException e) {
logger.log(Level.SEVERE, "Failed to load " + file.getAbsolutePath());
} catch (IOException e) {
logger.log(Level.SEVERE, "Failed to load " + file.getAbsolutePath(), e);
} catch (ConfigurationException e) {
logger.log(Level.SEVERE, "Failed to load " + file.getAbsolutePath(), e);
}
}
return configs;
}
}
@@ -19,10 +19,7 @@
package com.sk89q.worldguard.bukkit;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
@@ -41,37 +38,35 @@ import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockIgniteEvent;
import org.bukkit.event.block.BlockIgniteEvent.IgniteCause;
import org.bukkit.event.block.BlockPhysicsEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.BlockSpreadEvent;
import org.bukkit.event.block.LeavesDecayEvent;
import org.bukkit.event.block.SignChangeEvent;
import com.sk89q.rulelists.KnownAttachment;
import com.sk89q.rulelists.DefaultAttachments;
import com.sk89q.rulelists.RuleSet;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.blacklist.events.BlockBreakBlacklistEvent;
import com.sk89q.worldguard.blacklist.events.BlockPlaceBlacklistEvent;
import com.sk89q.worldguard.blacklist.events.DestroyWithBlacklistEvent;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
/**
* The listener for block events.
*/
public class WorldGuardBlockListener implements Listener {
class WorldGuardBlockListener implements Listener {
private WorldGuardPlugin plugin;
public WorldGuardBlockListener(WorldGuardPlugin plugin) {
/**
* Construct the listener.
*
* @param plugin WorldGuard plugin
*/
WorldGuardBlockListener(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
public void registerEvents() {
/**
* Register the events.
*/
void registerEvents() {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@@ -86,16 +81,9 @@ public class WorldGuardBlockListener implements Listener {
// Cake are damaged and not broken when they are eaten, so we must
// handle them a bit separately
if (blockDamaged.getTypeId() == BlockID.CAKE_BLOCK) {
// Regions
if (!plugin.getGlobalRegionManager().canBuild(player, blockDamaged)) {
player.sendMessage(ChatColor.DARK_RED + "You're not invited to this tea party!");
event.setCancelled(true);
return;
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.BLOCK_INTERACT);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_INTERACT);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(player);
context.setTargetBlock(event.getBlock().getState());
if (rules.process(context)) {
@@ -113,43 +101,9 @@ public class WorldGuardBlockListener implements Listener {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
// Regions
if (!plugin.getGlobalRegionManager().canBuild(player, event.getBlock())
|| !plugin.getGlobalRegionManager().canConstruct(player, event.getBlock())) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
event.setCancelled(true);
return;
}
// Blacklist
if (wcfg.getBlacklist() != null) {
if (!wcfg.getBlacklist().check(
new BlockBreakBlacklistEvent(plugin.wrapPlayer(player),
toVector(event.getBlock()),
event.getBlock().getTypeId()), false, false)) {
event.setCancelled(true);
return;
}
if (!wcfg.getBlacklist().check(
new DestroyWithBlacklistEvent(plugin.wrapPlayer(player),
toVector(event.getBlock()),
player.getItemInHand().getTypeId()), false, false)) {
event.setCancelled(true);
return;
}
}
// Chest protection
if (wcfg.isChestProtected(event.getBlock(), player)) {
player.sendMessage(ChatColor.DARK_RED + "The chest is protected.");
event.setCancelled(true);
return;
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.BLOCK_BREAK);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_BREAK);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(player);
context.setTargetBlock(event.getBlock().getState());
if (rules.process(context)) {
@@ -174,26 +128,10 @@ public class WorldGuardBlockListener implements Listener {
Block blockTo = event.getToBlock();
boolean isWater = blockFrom.getTypeId() == 8 || blockFrom.getTypeId() == 9;
boolean isLava = blockFrom.getTypeId() == 10 || blockFrom.getTypeId() == 11;
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
// Regions
if (wcfg.highFreqFlags && isWater
&& !plugin.getGlobalRegionManager().allows(DefaultFlag.WATER_FLOW,
blockFrom.getLocation())) {
event.setCancelled(true);
return;
}
if (wcfg.highFreqFlags && isLava
&& !plugin.getGlobalRegionManager().allows(DefaultFlag.LAVA_FLOW,
blockFrom.getLocation())) {
event.setCancelled(true);
return;
}
// Sponges
SpongeApplicator spongeAppl = wcfg.getSpongeApplicator();
if (spongeAppl != null && isWater) {
@@ -204,8 +142,8 @@ public class WorldGuardBlockListener implements Listener {
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.BLOCK_SPREAD);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_SPREAD);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceBlock(event.getBlock().getState());
context.setTargetBlock(event.getToBlock().getState());
if (rules.process(context)) {
@@ -230,47 +168,6 @@ public class WorldGuardBlockListener implements Listener {
return;
}
// Regions
if (wcfg.useRegions) {
Vector pt = toVector(block);
Player player = event.getPlayer();
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
if (player != null && !plugin.getGlobalRegionManager().hasBypass(player, world)) {
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (cause == IgniteCause.FLINT_AND_STEEL || cause == IgniteCause.FIREBALL) {
if (!set.canBuild(localPlayer)) {
event.setCancelled(true);
return;
}
if (!set.allows(DefaultFlag.LIGHTER, localPlayer)
&& !plugin.hasPermission(player, "worldguard.override.lighter")) {
event.setCancelled(true);
return;
}
}
}
if (wcfg.highFreqFlags && isFireSpread
&& !set.allows(DefaultFlag.FIRE_SPREAD)) {
event.setCancelled(true);
return;
}
if (wcfg.highFreqFlags && cause == IgniteCause.LAVA
&& !set.allows(DefaultFlag.LAVA_FIRE)) {
event.setCancelled(true);
return;
}
if (cause == IgniteCause.LIGHTNING && !set.allows(DefaultFlag.LIGHTNING)) {
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules;
BukkitContext context;
@@ -279,8 +176,8 @@ public class WorldGuardBlockListener implements Listener {
switch (event.getCause()) {
case FLINT_AND_STEEL:
// Consider flint and steel as an item use
rules = wcfg.getRuleList().get(KnownAttachment.ITEM_USE);
context = new BukkitContext(event);
rules = wcfg.getRuleList().get(DefaultAttachments.ITEM_USE);
context = new BukkitContext(plugin, event);
context.setSourceEntity(event.getPlayer());
context.setTargetBlock(event.getBlock().getState());
context.setItem(event.getPlayer().getItemInHand()); // Should be flint and steel
@@ -298,8 +195,8 @@ public class WorldGuardBlockListener implements Listener {
case LAVA:
case SPREAD:
// Consider everything else as a block spread
rules = wcfg.getRuleList().get(KnownAttachment.BLOCK_SPREAD);
context = new BukkitContext(event);
rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_SPREAD);
context = new BukkitContext(plugin, event);
context.setTargetBlock(event.getBlock().getState());
// Make a virtual source state
@@ -320,8 +217,8 @@ public class WorldGuardBlockListener implements Listener {
case FIREBALL:
case LIGHTNING:
// Consider everything else as a block spread
rules = wcfg.getRuleList().get(KnownAttachment.BLOCK_PLACE);
context = new BukkitContext(event);
rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_PLACE);
context = new BukkitContext(plugin, event);
context.setTargetBlock(event.getBlock().getState());
// Make a virtual new state
@@ -346,36 +243,14 @@ public class WorldGuardBlockListener implements Listener {
if (wcfg.fireSpreadDisableToggle) {
Block block = event.getBlock();
event.setCancelled(true);
checkAndDestroyAround(block.getWorld(), block.getX(), block.getY(), block.getZ(), BlockID.FIRE);
BukkitUtil.checkAndDestroyAround(block.getWorld(), block.getX(),
block.getY(), block.getZ(), BlockID.FIRE);
return;
}
// Chest protection
if (wcfg.isChestProtected(event.getBlock())) {
event.setCancelled(true);
return;
}
// Regions
if (wcfg.useRegions) {
Block block = event.getBlock();
int x = block.getX();
int y = block.getY();
int z = block.getZ();
Vector pt = toVector(block);
RegionManager mgr = plugin.getGlobalRegionManager().get(block.getWorld());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
if (!set.allows(DefaultFlag.FIRE_SPREAD)) {
checkAndDestroyAround(block.getWorld(), x, y, z, BlockID.FIRE);
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.BLOCK_BREAK);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_BREAK);
BukkitContext context = new BukkitContext(plugin, event);
BlockState virtualFireState = event.getBlock().getState();
virtualFireState.setType(Material.FIRE);
context.setSourceBlock(virtualFireState);
@@ -386,21 +261,6 @@ public class WorldGuardBlockListener implements Listener {
}
}
private void checkAndDestroyAround(World world, int x, int y, int z, int required) {
checkAndDestroy(world, x, y, z + 1, required);
checkAndDestroy(world, x, y, z - 1, required);
checkAndDestroy(world, x, y + 1, z, required);
checkAndDestroy(world, x, y - 1, z, required);
checkAndDestroy(world, x + 1, y, z, required);
checkAndDestroy(world, x - 1, y, z, required);
}
private void checkAndDestroy(World world, int x, int y, int z, int required) {
if (world.getBlockTypeIdAt(x, y, z) == required) {
world.getBlockAt(x, y, z).setTypeId(BlockID.AIR);
}
}
@EventHandler(ignoreCancelled = true)
public void onBlockPhysics(BlockPhysicsEvent event) {
Block block = event.getBlock();
@@ -409,8 +269,8 @@ public class WorldGuardBlockListener implements Listener {
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.BLOCK_PHYSICS);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_PHYSICS);
BukkitContext context = new BukkitContext(plugin, event);
context.setTargetBlock(event.getBlock().getState());
if (rules.process(context)) {
event.setCancelled(true);
@@ -433,42 +293,11 @@ public class WorldGuardBlockListener implements Listener {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockPlace(BlockPlaceEvent event) {
Block blockPlaced = event.getBlock();
Player player = event.getPlayer();
World world = blockPlaced.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
// Regions
if (wcfg.useRegions) {
final Location location = blockPlaced.getLocation();
if (!plugin.getGlobalRegionManager().canBuild(player, location)
|| !plugin.getGlobalRegionManager().canConstruct(player, location)) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
event.setCancelled(true);
return;
}
}
// Blacklist
if (wcfg.getBlacklist() != null) {
if (!wcfg.getBlacklist().check(
new BlockPlaceBlacklistEvent(plugin.wrapPlayer(player), toVector(blockPlaced),
blockPlaced.getTypeId()), false, false)) {
event.setCancelled(true);
return;
}
}
// Chest protection
if (wcfg.signChestProtection && wcfg.getChestProtection().isChest(blockPlaced.getTypeId())) {
if (wcfg.isAdjacentChestProtected(event.getBlock(), player)) {
player.sendMessage(ChatColor.DARK_RED + "This spot is for a chest that you don't have permission for.");
event.setCancelled(true);
return;
}
}
// Sponges
SpongeApplicator spongeAppl = wcfg.getSpongeApplicator();
if (spongeAppl != null && spongeAppl.isActiveSponge(blockPlaced)) {
@@ -476,8 +305,9 @@ public class WorldGuardBlockListener implements Listener {
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.BLOCK_PLACE);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_PLACE);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(event.getPlayer());
context.setTargetBlock(event.getBlock().getState());
context.setPlacedBlock(event.getBlockReplacedState());
if (rules.process(context)) {
@@ -493,16 +323,18 @@ public class WorldGuardBlockListener implements Listener {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
// RuleLists
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_INTERACT);
BukkitContext context = new BukkitContext(plugin, event);
context.setTargetBlock(event.getBlock().getState());
if (rules.process(context)) {
event.setCancelled(true);
return;
}
// Chest protection
if (wcfg.signChestProtection) {
if (event.getLine(0).equalsIgnoreCase("[Lock]")) {
if (wcfg.isChestProtectedPlacement(event.getBlock(), player)) {
player.sendMessage(ChatColor.DARK_RED + "You do not own the adjacent chest.");
event.getBlock().breakNaturally();
event.setCancelled(true);
return;
}
if (event.getBlock().getTypeId() != BlockID.SIGN_POST) {
player.sendMessage(ChatColor.RED
+ "The [Lock] sign must be a sign post, not a wall sign.");
@@ -547,21 +379,6 @@ public class WorldGuardBlockListener implements Listener {
return;
}
}
if (!plugin.getGlobalRegionManager().canBuild(player, event.getBlock())) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
event.setCancelled(true);
return;
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.BLOCK_INTERACT);
BukkitContext context = new BukkitContext(event);
context.setTargetBlock(event.getBlock().getState());
if (rules.process(context)) {
event.setCancelled(true);
return;
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
@@ -569,18 +386,9 @@ public class WorldGuardBlockListener implements Listener {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
// Regions
if (wcfg.useRegions) {
if (!plugin.getGlobalRegionManager().allows(DefaultFlag.LEAF_DECAY,
event.getBlock().getLocation())) {
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.BLOCK_FADE);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_FADE);
BukkitContext context = new BukkitContext(plugin, event);
context.setTargetBlock(event.getBlock().getState());
if (rules.process(context)) {
event.setCancelled(true);
@@ -590,31 +398,12 @@ public class WorldGuardBlockListener implements Listener {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockForm(BlockFormEvent event) {
int type = event.getNewState().getTypeId();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
// Regions
if (type == BlockID.ICE) {
if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows(
DefaultFlag.ICE_FORM, event.getBlock().getLocation())) {
event.setCancelled(true);
return;
}
}
if (type == BlockID.SNOW) {
if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows(
DefaultFlag.SNOW_FALL, event.getBlock().getLocation())) {
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.BLOCK_FORM);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_FORM);
BukkitContext context = new BukkitContext(plugin, event);
context.setTargetBlock(event.getBlock().getState());
context.setPlacedBlock(event.getNewState());
if (rules.process(context)) {
@@ -625,31 +414,12 @@ public class WorldGuardBlockListener implements Listener {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockSpread(BlockSpreadEvent event) {
int fromType = event.getSource().getTypeId();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
// Regions
if (fromType == BlockID.RED_MUSHROOM || fromType == BlockID.BROWN_MUSHROOM) {
if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows(
DefaultFlag.MUSHROOMS, event.getBlock().getLocation())) {
event.setCancelled(true);
return;
}
}
if (fromType == BlockID.GRASS) {
if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows(
DefaultFlag.GRASS_SPREAD, event.getBlock().getLocation())) {
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.BLOCK_SPREAD);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_SPREAD);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceBlock(event.getSource().getState());
context.setTargetBlock(event.getBlock().getState());
context.setPlacedBlock(event.getNewState());
@@ -661,31 +431,12 @@ public class WorldGuardBlockListener implements Listener {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockFade(BlockFadeEvent event) {
int type = event.getBlock().getTypeId();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
// regions
if (type == BlockID.ICE) {
if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows(
DefaultFlag.ICE_MELT, event.getBlock().getLocation())) {
event.setCancelled(true);
return;
}
}
if (type == BlockID.SNOW) {
if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows(
DefaultFlag.SNOW_MELT, event.getBlock().getLocation())) {
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.BLOCK_FADE);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_FADE);
BukkitContext context = new BukkitContext(plugin, event);
context.setTargetBlock(event.getBlock().getState());
context.setPlacedBlock(event.getNewState());
if (rules.process(context)) {
@@ -694,50 +445,14 @@ public class WorldGuardBlockListener implements Listener {
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockPistonExtend(BlockPistonExtendEvent event) {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
// Regions
if (wcfg.useRegions) {
if (!plugin.getGlobalRegionManager().allows(DefaultFlag.PISTONS, event.getBlock().getLocation())) {
event.setCancelled(true);
return;
}
for (Block block : event.getBlocks()) {
if (!plugin.getGlobalRegionManager().allows(DefaultFlag.PISTONS, block.getLocation())) {
event.setCancelled(true);
return;
}
}
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockPistonRetract(BlockPistonRetractEvent event) {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
// Regions
if (wcfg.useRegions && event.isSticky()) {
if (!(plugin.getGlobalRegionManager().allows(DefaultFlag.PISTONS, event.getRetractLocation()))
|| !(plugin.getGlobalRegionManager().allows(DefaultFlag.PISTONS, event.getBlock().getLocation()))) {
event.setCancelled(true);
return;
}
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onBlockDispense(BlockDispenseEvent event) {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getBlock().getWorld());
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ITEM_DROP);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ITEM_DROP);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceBlock(event.getBlock().getState());
context.setItem(event.getItem());
if (rules.process(context)) {
@@ -1,75 +0,0 @@
/*
* WorldGuard
* Copyright (C) 2012 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit;
import com.sk89q.commandbook.InfoComponent;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
/**
* @author zml2008
*/
public class WorldGuardCommandBookListener implements Listener {
private final WorldGuardPlugin plugin;
public WorldGuardCommandBookListener(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
@EventHandler
public void onPlayerWhois(InfoComponent.PlayerWhoisEvent event) {
if (event.getPlayer() instanceof Player) {
Player player = (Player) event.getPlayer();
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (plugin.getGlobalStateManager().get(player.getWorld()).useRegions) {
ApplicableRegionSet regions = plugin.getGlobalRegionManager()
.get(player.getWorld()).getApplicableRegions(player.getLocation());
// Current regions
StringBuilder regionStr = new StringBuilder();
boolean first = true;
for (ProtectedRegion region : regions) {
if (!first) {
regionStr.append(", ");
}
if (region.isOwner(localPlayer)) {
regionStr.append("+");
} else if (region.isMemberOnly(localPlayer)) {
regionStr.append("-");
}
regionStr.append(region.getId());
first = false;
}
if (regions.size() > 0) {
event.addWhoisInformation("Current Regions", regionStr);
}
event.addWhoisInformation("Can build", regions.canBuild(localPlayer));
}
}
}
}
@@ -18,29 +18,15 @@
*/
package com.sk89q.worldguard.bukkit;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
import java.util.Iterator;
import java.util.Set;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.EnderDragon;
import org.bukkit.entity.EnderPearl;
import org.bukkit.entity.Enderman;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Fireball;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.entity.TNTPrimed;
import org.bukkit.entity.Tameable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
@@ -52,39 +38,37 @@ import org.bukkit.event.entity.EntityDamageByBlockEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityDeathEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.entity.EntityInteractEvent;
import org.bukkit.event.entity.ExplosionPrimeEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.entity.PigZapEvent;
import org.bukkit.event.entity.PotionSplashEvent;
import org.bukkit.inventory.ItemStack;
import com.sk89q.rulelists.KnownAttachment;
import com.sk89q.rulelists.DefaultAttachments;
import com.sk89q.rulelists.RuleSet;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.blacklist.events.ItemUseBlacklistEvent;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.GlobalRegionManager;
import com.sk89q.worldguard.protection.events.DisallowedPVPEvent;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.region.RegionManager;
import com.sk89q.worldguard.region.flags.DefaultFlag;
/**
* The listener for entity events.
*/
public class WorldGuardEntityListener implements Listener {
class WorldGuardEntityListener implements Listener {
private WorldGuardPlugin plugin;
public WorldGuardEntityListener(WorldGuardPlugin plugin) {
/**
* Construct the listener.
*
* @param plugin WorldGuard plugin
*/
WorldGuardEntityListener(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
public void registerEvents() {
/**
* Register the events.
*/
void registerEvents() {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@@ -94,8 +78,8 @@ public class WorldGuardEntityListener implements Listener {
WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld());
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.BLOCK_INTERACT);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_INTERACT);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(event.getEntity());
context.setTargetBlock(event.getBlock().getState());
if (rules.process(context)) {
@@ -109,9 +93,11 @@ public class WorldGuardEntityListener implements Listener {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld());
/* --- No short-circuit returns below this line --- */
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_DEATH);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ENTITY_DEATH);
BukkitContext context = new BukkitContext(plugin, event);
context.setTargetEntity(event.getEntity());
// Set a message if it's a death from a player
@@ -134,11 +120,9 @@ public class WorldGuardEntityListener implements Listener {
// Redirect damage done by an entity
if (event instanceof EntityDamageByEntityEvent) {
this.onEntityDamageByEntity((EntityDamageByEntityEvent) event);
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_DAMAGE);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ENTITY_DAMAGE);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(((EntityDamageByEntityEvent) event).getDamager());
context.setTargetEntity(event.getEntity());
if (rules.process(context)) {
@@ -148,21 +132,9 @@ public class WorldGuardEntityListener implements Listener {
// Redirect damage done by blocks
} else if (event instanceof EntityDamageByBlockEvent) {
Entity defender = event.getEntity();
// God-mode/amphibious mode
if (defender instanceof Player) {
Player player = (Player) defender;
if (isInvincible(player)) {
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_DAMAGE);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ENTITY_DAMAGE);
BukkitContext context = new BukkitContext(plugin, event);
Block damager = ((EntityDamageByBlockEvent) event).getDamager();
if (damager != null) { // Should NOT be null!
context.setSourceBlock(damager.getState());
@@ -175,29 +147,9 @@ public class WorldGuardEntityListener implements Listener {
// Other damage
} else {
Entity defender = event.getEntity();
DamageCause type = event.getCause();
// God-mode/amphibious mode
if (defender instanceof Player) {
Player player = (Player) defender;
if (isInvincible(player)) {
event.setCancelled(true);
player.setFireTicks(0);
return;
}
if (type == DamageCause.DROWNING && cfg.hasAmphibiousMode(player)) {
player.setRemainingAir(player.getMaximumAir());
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_DAMAGE);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ENTITY_DAMAGE);
BukkitContext context = new BukkitContext(plugin, event);
context.setTargetEntity(event.getEntity());
if (rules.process(context)) {
event.setCancelled(true);
@@ -206,179 +158,6 @@ public class WorldGuardEntityListener implements Listener {
}
}
/**
* Handle a damage by entity event.
*
* @param event event
*/
private void onEntityDamageByEntity(EntityDamageByEntityEvent event) {
if (event.getDamager() instanceof Projectile) {
onEntityDamageByProjectile(event);
return;
}
Entity attacker = event.getDamager();
Entity defender = event.getEntity();
if (attacker instanceof Player) {
Player player = (Player) attacker;
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
ItemStack held = player.getInventory().getItemInHand();
if (held != null) {
if (wcfg.getBlacklist() != null) {
if (!wcfg.getBlacklist().check(
new ItemUseBlacklistEvent(plugin.wrapPlayer(player),
toVector(player.getLocation()), held.getTypeId()), false, false)) {
event.setCancelled(true);
return;
}
}
}
}
if (defender instanceof Player) {
Player player = (Player) defender;
LocalPlayer localPlayer = plugin.wrapPlayer(player);
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
if (isInvincible(player)) {
if (wcfg.regionInvinciblityRemovesMobs
&& attacker instanceof LivingEntity && !(attacker instanceof Player)
&& !(attacker instanceof Tameable && ((Tameable) attacker).isTamed())) {
attacker.remove();
}
event.setCancelled(true);
return;
}
if (attacker != null && attacker instanceof Player) {
if (wcfg.useRegions) {
Vector pt = toVector(defender.getLocation());
Vector pt2 = toVector(attacker.getLocation());
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
if (!mgr.getApplicableRegions(pt2).allows(DefaultFlag.PVP, plugin.wrapPlayer((Player) attacker))) {
tryCancelPVPEvent((Player) attacker, player, event, true);
} else if (!mgr.getApplicableRegions(pt).allows(DefaultFlag.PVP ,localPlayer)) {
tryCancelPVPEvent((Player) attacker, player, event, false);
}
}
}
if (attacker != null && attacker instanceof TNTPrimed) {
if (wcfg.useRegions) {
Vector pt = toVector(defender.getLocation());
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
if (!set.allows(DefaultFlag.TNT, localPlayer)) {
event.setCancelled(true);
return;
}
}
}
if (attacker != null && attacker instanceof Fireball) {
if (wcfg.useRegions) {
Fireball fireball = (Fireball) attacker;
Vector pt = toVector(defender.getLocation());
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
if (fireball.getShooter() instanceof Player) {
Vector pt2 = toVector(fireball.getShooter().getLocation());
if (!mgr.getApplicableRegions(pt2).allows(DefaultFlag.PVP, plugin.wrapPlayer((Player) fireball.getShooter()))) {
tryCancelPVPEvent((Player) fireball.getShooter(), player, event, true);
} else if (!set.allows(DefaultFlag.PVP, localPlayer)) {
tryCancelPVPEvent((Player) fireball.getShooter(), player, event, false);
}
} else {
if (!set.allows(DefaultFlag.GHAST_FIREBALL, localPlayer)) {
event.setCancelled(true);
return;
}
}
}
}
if (attacker != null && attacker instanceof LivingEntity && !(attacker instanceof Player)) {
if (wcfg.useRegions) {
Vector pt = toVector(defender.getLocation());
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
if (!set.allows(DefaultFlag.MOB_DAMAGE, localPlayer)) {
event.setCancelled(true);
return;
}
if (attacker instanceof Creeper) {
if (!set.allows(DefaultFlag.CREEPER_EXPLOSION, localPlayer)) {
event.setCancelled(true);
return;
}
}
}
}
}
}
private void onEntityDamageByProjectile(EntityDamageByEntityEvent event) {
Entity defender = event.getEntity();
Entity attacker = ((Projectile) event.getDamager()).getShooter();
if (defender instanceof Player) {
Player player = (Player) defender;
LocalPlayer localPlayer = plugin.wrapPlayer(player);
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
// Check Invincible
if (isInvincible(player)) {
event.setCancelled(true);
return;
}
// Check Mob
if (attacker != null && attacker instanceof LivingEntity && !(attacker instanceof Player)) {
if (wcfg.useRegions) {
Vector pt = toVector(defender.getLocation());
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
if (!mgr.getApplicableRegions(pt).allows(DefaultFlag.MOB_DAMAGE, localPlayer)) {
event.setCancelled(true);
return;
}
}
}
// Check Player
if (event.getDamager() instanceof EnderPearl) return;
if (attacker != null && attacker instanceof Player) {
if (wcfg.useRegions) {
Vector pt = toVector(defender.getLocation());
Vector pt2 = toVector(attacker.getLocation());
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
if (!mgr.getApplicableRegions(pt2).allows(DefaultFlag.PVP, plugin.wrapPlayer((Player) attacker))) {
tryCancelPVPEvent((Player) attacker, player, event, true);
} else if (!mgr.getApplicableRegions(pt).allows(DefaultFlag.PVP, localPlayer)) {
tryCancelPVPEvent((Player) attacker, player, event, false);
}
}
}
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onEntityCombust(EntityCombustEvent event) {
Entity entity = event.getEntity();
@@ -386,19 +165,9 @@ public class WorldGuardEntityListener implements Listener {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(entity.getWorld());
// God mode and regions
if (entity instanceof Player) {
Player player = (Player) entity;
if (cfg.hasGodMode(player) || (wcfg.useRegions && RegionQueryUtil.isInvincible(plugin, player))) {
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_IGNITE);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ENTITY_IGNITE);
BukkitContext context = new BukkitContext(plugin, event);
context.setTargetEntity(entity);
if (rules.process(context)) {
event.setCancelled(true);
@@ -412,11 +181,10 @@ public class WorldGuardEntityListener implements Listener {
Location l = event.getLocation();
World world = l.getWorld();
WorldConfiguration wcfg = cfg.get(world);
Entity ent = event.getEntity();
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_EXPLODE);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ENTITY_EXPLODE);
BukkitContext context = new BukkitContext(plugin, event);
context.setTargetEntity(event.getEntity());
if (rules.process(context)) {
event.setCancelled(true);
@@ -425,71 +193,13 @@ public class WorldGuardEntityListener implements Listener {
/* --- No short-circuit returns below this line --- */
// Regions
if (ent instanceof Creeper) {
if (wcfg.useRegions) {
if (wcfg.useRegions) {
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
for (Block block : event.blockList()) {
if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.CREEPER_EXPLOSION)) {
event.blockList().clear();
return;
}
}
}
}
} else if (ent instanceof EnderDragon) {
if (wcfg.useRegions) {
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
for (Block block : event.blockList()) {
if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.ENDERDRAGON_BLOCK_DAMAGE)) {
event.blockList().clear();
return;
}
}
}
} else if (ent instanceof TNTPrimed) {
if (wcfg.useRegions) {
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
for (Block block : event.blockList()) {
if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.TNT)) {
event.blockList().clear();
return;
}
}
}
} else if (ent instanceof Fireball) {
if (wcfg.useRegions) {
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
for (Block block : event.blockList()) {
if (!mgr.getApplicableRegions(toVector(block)).allows(DefaultFlag.GHAST_FIREBALL)) {
event.blockList().clear();
return;
}
}
}
}
if (wcfg.signChestProtection) {
for (Block block : event.blockList()) {
if (wcfg.isChestProtected(block)) {
event.blockList().clear();
return;
}
}
}
// Now apply RuleLists for each block
Iterator<Block> iter = event.blockList().iterator();
while (iter.hasNext()) {
Block block = iter.next();
rules = wcfg.getRuleList().get(KnownAttachment.BLOCK_BREAK);
context = new BukkitContext(event);
rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_BREAK);
context = new BukkitContext(plugin, event);
context.setSourceEntity(event.getEntity());
context.setTargetBlock(block.getState());
rules.process(context);
@@ -505,8 +215,8 @@ public class WorldGuardEntityListener implements Listener {
WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld());
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_EXPLODE);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ENTITY_EXPLODE);
BukkitContext context = new BukkitContext(plugin, event);
context.setTargetEntity(event.getEntity());
if (rules.process(context)) {
event.setCancelled(true);
@@ -516,35 +226,12 @@ public class WorldGuardEntityListener implements Listener {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onCreatureSpawn(CreatureSpawnEvent event) {
EntityType entityType = event.getEntityType();
Location eventLoc = event.getLocation();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld());
// Regions
if (wcfg.useRegions && cfg.useRegionsCreatureSpawnEvent) {
Vector pt = toVector(eventLoc);
RegionManager mgr = plugin.getGlobalRegionManager().get(eventLoc.getWorld());
// @TODO get victims' stacktraces and find out why it's null anyway
if (mgr == null) return;
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
if (!set.allows(DefaultFlag.MOB_SPAWNING)) {
event.setCancelled(true);
return;
}
Set<EntityType> entityTypes = set.getFlag(DefaultFlag.DENY_SPAWN);
if (entityTypes != null && entityTypes.contains(entityType)) {
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_SPAWN);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ENTITY_SPAWN);
BukkitContext context = new BukkitContext(plugin, event);
context.setTargetEntity(event.getEntity());
if (rules.process(context)) {
event.setCancelled(true);
@@ -558,10 +245,13 @@ public class WorldGuardEntityListener implements Listener {
WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld());
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_STRIKE);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ENTITY_STRIKE);
BukkitContext context = new BukkitContext(plugin, event);
context.setTargetEntity(event.getEntity());
rules.process(context);
if (rules.process(context)) {
event.setCancelled(true);
return;
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
@@ -570,8 +260,8 @@ public class WorldGuardEntityListener implements Listener {
WorldConfiguration wcfg = cfg.get(event.getEntity().getWorld());
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_STRIKE);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ENTITY_STRIKE);
BukkitContext context = new BukkitContext(plugin, event);
context.setTargetEntity(event.getEntity());
if (rules.process(context)) {
event.setCancelled(true);
@@ -581,39 +271,16 @@ public class WorldGuardEntityListener implements Listener {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onEntityChangeBlock(EntityChangeBlockEvent event) {
Entity ent = event.getEntity();
Block block = event.getBlock();
Location location = block.getLocation();
Entity entity = event.getEntity();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(ent.getWorld());
if (ent instanceof Enderman) {
if (event.getTo() == Material.AIR) { // Pickup
// Blacklist
if (wcfg.useRegions) {
if (!plugin.getGlobalRegionManager().allows(DefaultFlag.ENDER_BUILD, location)) {
event.setCancelled(true);
return;
}
}
// Place
} else {
if (wcfg.useRegions) {
if (!plugin.getGlobalRegionManager().allows(DefaultFlag.ENDER_BUILD, location)) {
event.setCancelled(true);
return;
}
}
}
}
WorldConfiguration wcfg = cfg.get(entity.getWorld());
// RuleLists
RuleSet rules = wcfg.getRuleList().get(event.getTo() == Material.AIR ?
KnownAttachment.BLOCK_BREAK : KnownAttachment.BLOCK_PLACE);
BukkitContext context = new BukkitContext(event);
context.setSourceEntity(ent);
DefaultAttachments.BLOCK_BREAK : DefaultAttachments.BLOCK_PLACE);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(entity);
BlockState newState = event.getBlock().getState(); // This event is lame
newState.setType(event.getTo()); // Need to construct our own BlockState
context.setTargetBlock(event.getBlock().getState());
@@ -624,20 +291,12 @@ public class WorldGuardEntityListener implements Listener {
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onFoodLevelChange(FoodLevelChangeEvent event) {
if (event.getEntity() instanceof Player) {
Player player = (Player) event.getEntity();
if (event.getFoodLevel() < player.getFoodLevel() && isInvincible(player)) {
event.setCancelled(true);
return;
}
}
}
@EventHandler(ignoreCancelled = true)
public void onPotionSplash(PotionSplashEvent event) {
GlobalRegionManager global = plugin.getGlobalRegionManager();
RegionManager global = plugin.getGlobalRegionManager();
/* --- No short-circuit returns below this line --- */
int blockedEntities = 0;
for (LivingEntity e : event.getAffectedEntities()) {
@@ -652,61 +311,4 @@ public class WorldGuardEntityListener implements Listener {
event.setCancelled(true);
}
}
/**
* Check if a player is invincible, via either god mode or region flag. If
* the region denies invincibility, the player must have an extra permission
* to override it. (worldguard.god.override-regions)
*
* @param player The player to check
* @return Whether {@code player} is invincible
*/
private boolean isInvincible(Player player) {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
boolean god = cfg.hasGodMode(player);
if (wcfg.useRegions) {
Boolean flag = RegionQueryUtil.isAllowedInvinciblity(plugin, player);
boolean allowed = flag == null || flag;
boolean invincible = RegionQueryUtil.isInvincible(plugin, player);
if (allowed) {
return god || invincible;
} else {
return (god && plugin.hasPermission(player, "worldguard.god.override-regions"))
|| invincible;
}
} else {
return god;
}
}
/**
* Using a DisallowedPVPEvent, notifies other plugins that WorldGuard
* wants to cancel a PvP damage event.
*
* <p>If this event is not cancelled, the attacking player is notified that
* PvP is disabled and WorldGuard cancels the damage event.
*
* @param attackingPlayer The attacker
* @param defendingPlayer The defender
* @param event The event that caused WorldGuard to act
* @param aggressorTriggered whether the aggressor triggered the incident.
*/
public void tryCancelPVPEvent(final Player attackingPlayer, final Player defendingPlayer, EntityDamageByEntityEvent event, boolean aggressorTriggered) {
final DisallowedPVPEvent disallowedPVPEvent = new DisallowedPVPEvent(attackingPlayer, defendingPlayer, event);
plugin.getServer().getPluginManager().callEvent(disallowedPVPEvent);
if (!disallowedPVPEvent.isCancelled()) {
if (aggressorTriggered) {
attackingPlayer.sendMessage(ChatColor.DARK_RED
+ "You are in a no-PvP area.");
} else {
attackingPlayer.sendMessage(ChatColor.DARK_RED
+ "That player is in a no-PvP area.");
}
event.setCancelled(true);
}
}
}
@@ -19,119 +19,55 @@
package com.sk89q.worldguard.bukkit;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Hanging;
import org.bukkit.entity.ItemFrame;
import org.bukkit.entity.Painting;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.hanging.HangingBreakEvent;
import org.bukkit.event.hanging.HangingPlaceEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import com.sk89q.rulelists.KnownAttachment;
import com.sk89q.rulelists.DefaultAttachments;
import com.sk89q.rulelists.RuleSet;
import com.sk89q.worldedit.blocks.ItemID;
import com.sk89q.worldguard.blacklist.events.BlockBreakBlacklistEvent;
import com.sk89q.worldguard.blacklist.events.ItemUseBlacklistEvent;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
/**
* Listener for painting related events.
*
* @author BangL <henno.rickowski@gmail.com>
* Listener for hanging entity events.
*/
public class WorldGuardHangingListener implements Listener {
class WorldGuardHangingListener implements Listener {
private WorldGuardPlugin plugin;
/**
* Construct the object;
* Construct the listener.
*
* @param plugin The plugin instance
* @param plugin WorldGuard plugin
*/
public WorldGuardHangingListener(WorldGuardPlugin plugin) {
WorldGuardHangingListener(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
/**
* Register events.
*/
public void registerEvents() {
void registerEvents() {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onHangingingBreak(HangingBreakEvent breakEvent) {
if (!(breakEvent instanceof HangingBreakByEntityEvent)) {
return;
}
HangingBreakByEntityEvent event = (HangingBreakByEntityEvent) breakEvent;
public void onHangingingBreak(HangingBreakEvent event) {
Hanging hanging = event.getEntity();
World world = hanging.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (event.getRemover() instanceof Player) {
Player player = (Player) event.getRemover();
if (wcfg.getBlacklist() != null) {
if (hanging instanceof Painting
&& !wcfg.getBlacklist().check(
new BlockBreakBlacklistEvent(plugin.wrapPlayer(player),
toVector(player.getLocation()), ItemID.PAINTING), false, false)) {
event.setCancelled(true);
return;
} else if (hanging instanceof ItemFrame
&& !wcfg.getBlacklist().check(
new BlockBreakBlacklistEvent(plugin.wrapPlayer(player),
toVector(player.getLocation()), ItemID.ITEM_FRAME), false, false)) {
event.setCancelled(true);
return;
}
}
if (wcfg.useRegions) {
if (!plugin.getGlobalRegionManager().canBuild(player, hanging.getLocation())) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
event.setCancelled(true);
return;
}
}
} else {
if (event.getRemover() instanceof Creeper) {
if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows(DefaultFlag.CREEPER_EXPLOSION, hanging.getLocation())) {
event.setCancelled(true);
return;
}
}
if (hanging instanceof Painting
&& ((wcfg.useRegions && !plugin.getGlobalRegionManager().allows(
DefaultFlag.ENTITY_PAINTING_DESTROY, hanging.getLocation())))) {
event.setCancelled(true);
} else if (hanging instanceof ItemFrame
&& ((wcfg.useRegions && !plugin.getGlobalRegionManager()
.allows(DefaultFlag.ENTITY_ITEM_FRAME_DESTROY,
hanging.getLocation())))) {
event.setCancelled(true);
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_DAMAGE);
BukkitContext context = new BukkitContext(event);
context.setSourceEntity(event.getRemover());
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ENTITY_DAMAGE);
BukkitContext context = new BukkitContext(plugin, event);
if (event instanceof HangingBreakByEntityEvent) {
context.setSourceEntity(((HangingBreakByEntityEvent) event).getRemover());
}
context.setTargetEntity(event.getEntity());
if (rules.process(context)) {
event.setCancelled(true);
@@ -142,40 +78,14 @@ public class WorldGuardHangingListener implements Listener {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onHangingPlace(HangingPlaceEvent event) {
Block placedOn = event.getBlock();
Player player = event.getPlayer();
World world = placedOn.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (wcfg.getBlacklist() != null) {
if (event.getEntity() instanceof Painting
&& !wcfg.getBlacklist().check(
new ItemUseBlacklistEvent(plugin.wrapPlayer(player),
toVector(player.getLocation()), ItemID.PAINTING), false, false)) {
event.setCancelled(true);
return;
} else if (event.getEntity() instanceof ItemFrame
&& !wcfg.getBlacklist().check(
new ItemUseBlacklistEvent(plugin.wrapPlayer(player),
toVector(player.getLocation()), ItemID.ITEM_FRAME), false, false)) {
event.setCancelled(true);
return;
}
}
if (wcfg.useRegions) {
if (!plugin.getGlobalRegionManager().canBuild(player, placedOn.getLocation())) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_SPAWN);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ENTITY_SPAWN);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(event.getPlayer());
context.setTargetEntity(event.getEntity());
if (rules.process(context)) {
@@ -183,43 +93,4 @@ public class WorldGuardHangingListener implements Listener {
return;
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onEntityInteract(PlayerInteractEntityEvent event) {
Player player = event.getPlayer();
Entity entity = event.getRightClicked();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(entity.getWorld());
if (wcfg.useRegions && (entity instanceof ItemFrame || entity instanceof Painting)) {
if (!plugin.getGlobalRegionManager().canBuild(player, entity.getLocation())) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
event.setCancelled(true);
return;
}
if (entity instanceof ItemFrame
&& ((!plugin.getGlobalRegionManager().allows(
DefaultFlag.ENTITY_ITEM_FRAME_DESTROY, entity.getLocation())))) {
event.setCancelled(true);
return;
} else if (entity instanceof Painting
&& ((!plugin.getGlobalRegionManager().allows(
DefaultFlag.ENTITY_PAINTING_DESTROY, entity.getLocation())))) {
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_INTERACT);
BukkitContext context = new BukkitContext(event);
context.setSourceEntity(player);
context.setTargetEntity(entity);
if (rules.process(context)) {
event.setCancelled(true);
return;
}
}
}
@@ -19,142 +19,75 @@
package com.sk89q.worldguard.bukkit;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
import org.bukkit.ChatColor;
import org.bukkit.Warning;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Creeper;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Painting;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.painting.PaintingBreakByEntityEvent;
import org.bukkit.event.painting.PaintingBreakEvent;
import org.bukkit.event.painting.PaintingPlaceEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import com.sk89q.rulelists.KnownAttachment;
import com.sk89q.rulelists.DefaultAttachments;
import com.sk89q.rulelists.RuleSet;
import com.sk89q.worldedit.blocks.ItemID;
import com.sk89q.worldguard.blacklist.events.BlockBreakBlacklistEvent;
import com.sk89q.worldguard.blacklist.events.ItemUseBlacklistEvent;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
/**
* Listener for painting related events.
*
* @author sk89q
* @deprecated Use {@link com.sk89q.worldguard.bukkit.WorldGuardHangingListener} instead.
* Listener for painting related events. This event is deprecated and it is provided for
* compatibility with older versions of Bukkit.
*/
@Deprecated
@Warning(reason="This listener has been replaced by WorldGuardHangingListener")
public class WorldGuardPaintingListener implements Listener {
private WorldGuardPlugin plugin;
/**
* Construct the object;
* Construct the listener.
*
* @param plugin The plugin instance
* @param plugin WorldGuard plugin
*/
public WorldGuardPaintingListener(WorldGuardPlugin plugin) {
WorldGuardPaintingListener(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
/**
* Register events.
*/
public void registerEvents() {
void registerEvents() {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onPaintingBreak(PaintingBreakEvent breakEvent) {
if (!(breakEvent instanceof PaintingBreakByEntityEvent)) {
return;
}
PaintingBreakByEntityEvent event = (PaintingBreakByEntityEvent) breakEvent;
public void onPaintingBreak(PaintingBreakEvent event) {
Painting painting = event.getPainting();
World world = painting.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (event.getRemover() instanceof Player) {
Player player = (Player) event.getRemover();
if (wcfg.getBlacklist() != null) {
if (!wcfg.getBlacklist().check(
new BlockBreakBlacklistEvent(plugin.wrapPlayer(player),
toVector(player.getLocation()), ItemID.PAINTING), false, false)) {
event.setCancelled(true);
return;
}
}
if (wcfg.useRegions) {
if (!plugin.getGlobalRegionManager().canBuild(player, painting.getLocation())) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
event.setCancelled(true);
return;
}
}
} else {
if (event.getRemover() instanceof Creeper) {
if (wcfg.useRegions && !plugin.getGlobalRegionManager().allows(DefaultFlag.CREEPER_EXPLOSION, painting.getLocation())) {
event.setCancelled(true);
return;
}
}
if ((wcfg.useRegions && !plugin.getGlobalRegionManager().allows(
DefaultFlag.ENTITY_PAINTING_DESTROY, painting.getLocation()))) {
event.setCancelled(true);
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_DAMAGE);
BukkitContext context = new BukkitContext(event);
context.setSourceEntity(event.getRemover());
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ENTITY_DAMAGE);
BukkitContext context = new BukkitContext(plugin, event);
if (event instanceof PaintingBreakByEntityEvent) {
context.setSourceEntity(((PaintingBreakByEntityEvent) event).getRemover());
}
context.setTargetEntity(event.getPainting());
rules.process(context);
if (rules.process(context)) {
event.setCancelled(true);
return;
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onPaintingPlace(PaintingPlaceEvent event) {
Block placedOn = event.getBlock();
Player player = event.getPlayer();
World world = placedOn.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (wcfg.getBlacklist() != null) {
if (!wcfg.getBlacklist().check(
new ItemUseBlacklistEvent(plugin.wrapPlayer(player),
toVector(player.getLocation()), ItemID.PAINTING), false, false)) {
event.setCancelled(true);
return;
}
}
if (wcfg.useRegions) {
if (!plugin.getGlobalRegionManager().canBuild(player, placedOn.getLocation())) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_SPAWN);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ENTITY_SPAWN);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(event.getPlayer());
context.setTargetEntity(event.getPainting());
if (rules.process(context)) {
@@ -162,38 +95,4 @@ public class WorldGuardPaintingListener implements Listener {
return;
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onEntityInteract(PlayerInteractEntityEvent event) {
Player player = event.getPlayer();
Entity entity = event.getRightClicked();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(entity.getWorld());
if (wcfg.useRegions && entity instanceof Painting) {
if (!plugin.getGlobalRegionManager().canBuild(player, entity.getLocation())) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
event.setCancelled(true);
return;
}
if (entity instanceof Painting
&& ((!plugin.getGlobalRegionManager().allows(
DefaultFlag.ENTITY_PAINTING_DESTROY, entity.getLocation())))) {
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_INTERACT);
BukkitContext context = new BukkitContext(event);
context.setSourceEntity(player);
context.setTargetEntity(entity);
if (rules.process(context)) {
event.setCancelled(true);
return;
}
}
}
@@ -18,31 +18,20 @@
*/
package com.sk89q.worldguard.bukkit;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
import java.util.Iterator;
import java.util.Set;
import org.bukkit.ChatColor;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Item;
import org.bukkit.entity.Player;
import org.bukkit.event.Event.Result;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.Action;
import org.bukkit.event.entity.PlayerDeathEvent;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.event.player.PlayerBedEnterEvent;
import org.bukkit.event.player.PlayerBucketEmptyEvent;
import org.bukkit.event.player.PlayerBucketFillEvent;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import org.bukkit.event.player.PlayerDropItemEvent;
import org.bukkit.event.player.PlayerGameModeChangeEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent;
@@ -53,37 +42,29 @@ import org.bukkit.event.player.PlayerRespawnEvent;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.PluginManager;
import com.sk89q.rulelists.KnownAttachment;
import com.sk89q.rulelists.DefaultAttachments;
import com.sk89q.rulelists.RuleSet;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.blocks.BlockType;
import com.sk89q.worldedit.blocks.ItemID;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.blacklist.events.BlockBreakBlacklistEvent;
import com.sk89q.worldguard.blacklist.events.BlockInteractBlacklistEvent;
import com.sk89q.worldguard.blacklist.events.BlockPlaceBlacklistEvent;
import com.sk89q.worldguard.blacklist.events.ItemAcquireBlacklistEvent;
import com.sk89q.worldguard.blacklist.events.ItemDropBlacklistEvent;
import com.sk89q.worldguard.blacklist.events.ItemUseBlacklistEvent;
import com.sk89q.worldguard.bukkit.FlagStateManager.PlayerFlagState;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
/**
* Listener for player events.
*/
public class WorldGuardPlayerListener implements Listener {
class WorldGuardPlayerListener implements Listener {
private WorldGuardPlugin plugin;
public WorldGuardPlayerListener(WorldGuardPlugin plugin) {
/**
* Construct the listener.
*
* @param plugin WorldGuard plugin
*/
WorldGuardPlayerListener(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
public void registerEvents() {
/**
* Register the events.
*/
void registerEvents() {
final PluginManager pm = plugin.getServer().getPluginManager();
pm.registerEvents(this, plugin);
@@ -97,161 +78,8 @@ public class WorldGuardPlayerListener implements Listener {
* registered for performance reasons.
*/
class PlayerMoveHandler implements Listener {
@EventHandler(priority = EventPriority.HIGH)
public void onPlayerMove(PlayerMoveEvent event) {
Player player = event.getPlayer();
World world = player.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (player.getVehicle() != null) return; // handled in vehicle listener
if (wcfg.useRegions) {
// Did we move a block?
if (event.getFrom().getBlockX() != event.getTo().getBlockX()
|| event.getFrom().getBlockY() != event.getTo().getBlockY()
|| event.getFrom().getBlockZ() != event.getTo().getBlockZ()) {
PlayerFlagState state = plugin.getFlagStateManager().getState(player);
//Flush states in multiworld scenario
if (state.lastWorld != null && !state.lastWorld.equals(world)) {
plugin.getFlagStateManager().forget(player);
state = plugin.getFlagStateManager().getState(player);
}
LocalPlayer localPlayer = plugin.wrapPlayer(player);
boolean hasBypass = plugin.getGlobalRegionManager().hasBypass(player, world);
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
Vector pt = new Vector(event.getTo().getBlockX(), event.getTo().getBlockY(), event.getTo().getBlockZ());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
boolean entryAllowed = set.allows(DefaultFlag.ENTRY, localPlayer);
if (!hasBypass && !entryAllowed) {
player.sendMessage(ChatColor.DARK_RED + "You are not permitted to enter this area.");
Location newLoc = event.getFrom();
newLoc.setX(newLoc.getBlockX() + 0.5);
newLoc.setY(newLoc.getBlockY());
newLoc.setZ(newLoc.getBlockZ() + 0.5);
event.setTo(newLoc);
return;
}
// Have to set this state
if (state.lastExitAllowed == null) {
state.lastExitAllowed = mgr.getApplicableRegions(toVector(event.getFrom()))
.allows(DefaultFlag.EXIT, localPlayer);
}
boolean exitAllowed = set.allows(DefaultFlag.EXIT, localPlayer);
if (!hasBypass && exitAllowed && !state.lastExitAllowed) {
player.sendMessage(ChatColor.DARK_RED + "You are not permitted to leave this area.");
Location newLoc = event.getFrom();
newLoc.setX(newLoc.getBlockX() + 0.5);
newLoc.setY(newLoc.getBlockY());
newLoc.setZ(newLoc.getBlockZ() + 0.5);
event.setTo(newLoc);
return;
}
String greeting = set.getFlag(DefaultFlag.GREET_MESSAGE);//, localPlayer);
String farewell = set.getFlag(DefaultFlag.FAREWELL_MESSAGE);//, localPlayer);
Boolean notifyEnter = set.getFlag(DefaultFlag.NOTIFY_ENTER);//, localPlayer);
Boolean notifyLeave = set.getFlag(DefaultFlag.NOTIFY_LEAVE);//, localPlayer);
GameMode gameMode = set.getFlag(DefaultFlag.GAME_MODE);
if (state.lastFarewell != null && (farewell == null
|| !state.lastFarewell.equals(farewell))) {
String replacedFarewell = plugin.replaceMacros(
player, BukkitUtil.replaceColorMacros(state.lastFarewell));
for (String line : replacedFarewell.split("\n")) {
player.sendMessage(ChatColor.AQUA + " ** " + line);
}
}
if (greeting != null && (state.lastGreeting == null
|| !state.lastGreeting.equals(greeting))) {
String replacedGreeting = plugin.replaceMacros(
player, BukkitUtil.replaceColorMacros(greeting));
for (String line : replacedGreeting.split("\n")) {
player.sendMessage(ChatColor.AQUA + " ** " + line);
}
}
if ((notifyLeave == null || !notifyLeave)
&& state.notifiedForLeave != null && state.notifiedForLeave) {
plugin.broadcastNotification(ChatColor.GRAY + "WG: "
+ ChatColor.LIGHT_PURPLE + player.getName()
+ ChatColor.GOLD + " left NOTIFY region");
}
if (notifyEnter != null && notifyEnter && (state.notifiedForEnter == null
|| !state.notifiedForEnter)) {
StringBuilder regionList = new StringBuilder();
for (ProtectedRegion region : set) {
if (regionList.length() != 0) {
regionList.append(", ");
}
regionList.append(region.getId());
}
plugin.broadcastNotification(ChatColor.GRAY + "WG: "
+ ChatColor.LIGHT_PURPLE + player.getName()
+ ChatColor.GOLD + " entered NOTIFY region: "
+ ChatColor.WHITE
+ regionList);
}
if (!hasBypass && gameMode != null) {
if (player.getGameMode() != gameMode) {
state.lastGameMode = player.getGameMode();
player.setGameMode(gameMode);
} else if (state.lastGameMode == null) {
state.lastGameMode = player.getServer().getDefaultGameMode();
}
} else {
if (state.lastGameMode != null) {
GameMode mode = state.lastGameMode;
state.lastGameMode = null;
player.setGameMode(mode);
}
}
state.lastGreeting = greeting;
state.lastFarewell = farewell;
state.notifiedForEnter = notifyEnter;
state.notifiedForLeave = notifyLeave;
state.lastExitAllowed = exitAllowed;
state.lastWorld = event.getTo().getWorld();
state.lastBlockX = event.getTo().getBlockX();
state.lastBlockY = event.getTo().getBlockY();
state.lastBlockZ = event.getTo().getBlockZ();
}
}
}
}
@EventHandler
public void onPlayerGameModeChange(PlayerGameModeChangeEvent event) {
Player player = event.getPlayer();
WorldConfiguration wcfg = plugin.getGlobalStateManager().get(player.getWorld());
// Regions
if (wcfg.useRegions && !plugin.getGlobalRegionManager().hasBypass(player, player.getWorld())) {
GameMode gameMode = plugin.getGlobalRegionManager().get(player.getWorld())
.getApplicableRegions(player.getLocation()).getFlag(DefaultFlag.GAME_MODE);
if (plugin.getFlagStateManager().getState(player).lastGameMode != null
&& gameMode != null && event.getNewGameMode() != gameMode) {
event.setCancelled(true);
player.sendMessage(ChatColor.RED + "Your game mode is locked to "
+ gameMode + "in this region!");
}
}
}
@EventHandler
public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer();
@@ -267,23 +95,9 @@ public class WorldGuardPlayerListener implements Listener {
+ "Fire spread is currently globally disabled for this world.");
}
if (plugin.inGroup(player, "wg-amphibious")) {
cfg.enableAmphibiousMode(player);
}
// Regions
if (wcfg.useRegions) {
PlayerFlagState state = plugin.getFlagStateManager().getState(player);
Location loc = player.getLocation();
state.lastWorld = loc.getWorld();
state.lastBlockX = loc.getBlockX();
state.lastBlockY = loc.getBlockY();
state.lastBlockZ = loc.getBlockZ();
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.PLAYER_JOIN);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.PLAYER_JOIN);
BukkitContext context = new BukkitContext(plugin, event);
context.setTargetEntity(player);
rules.process(context);
}
@@ -293,24 +107,19 @@ public class WorldGuardPlayerListener implements Listener {
Player player = event.getPlayer();
WorldConfiguration wcfg = plugin.getGlobalStateManager().get(player.getWorld());
// Regions
if (wcfg.useRegions) {
if (!plugin.getGlobalRegionManager().allows(DefaultFlag.SEND_CHAT, player.getLocation())) {
player.sendMessage(ChatColor.RED + "You don't have permission to chat in this region!");
event.setCancelled(true);
return;
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.CHAT);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(event.getPlayer());
context.setMessage(event.getMessage());
for (Iterator<Player> i = event.getRecipients().iterator(); i.hasNext();) {
if (!plugin.getGlobalRegionManager().allows(DefaultFlag.RECEIVE_CHAT, i.next().getLocation())) {
i.remove();
}
}
if (event.getRecipients().size() == 0) {
event.setCancelled(true);
}
if (rules.process(context)) {
event.setCancelled(true);
return;
}
// Put back the chat
event.setMessage(context.getMessage());
}
@EventHandler(ignoreCancelled = true)
@@ -335,7 +144,6 @@ public class WorldGuardPlayerListener implements Listener {
plugin.getLogger().warning("WorldGuard host key check: " +
player.getName() + " joined with '" + hostname +
"' but '" + hostKey + "' was expected. Kicked!");
return;
}
}
}
@@ -350,40 +158,9 @@ public class WorldGuardPlayerListener implements Listener {
/* --- No short-circuit returns below this line --- */
// Regions
// This is to make the enter/exit flags accurate -- move events are not
// sent constantly, so it is possible to move just a little enough to
// not trigger the event and then rejoin so that you are then considered
// outside the border. This should work around that.
if (wcfg.useRegions) {
boolean hasBypass = plugin.getGlobalRegionManager().hasBypass(player, world);
PlayerFlagState state = plugin.getFlagStateManager().getState(player);
if (state.lastWorld != null && !hasBypass) {
LocalPlayer localPlayer = plugin.wrapPlayer(player);
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
Location loc = player.getLocation();
Vector pt = new Vector(loc.getBlockX(), loc.getBlockY(), loc.getBlockZ());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
if (state.lastExitAllowed == null) {
state.lastExitAllowed = set.allows(DefaultFlag.EXIT, localPlayer);
}
if (!state.lastExitAllowed || !set.allows(DefaultFlag.ENTRY, localPlayer)) {
// Only if we have the last location cached
if (state.lastWorld.equals(world)) {
Location newLoc = new Location(world, state.lastBlockX + 0.5,
state.lastBlockY, state.lastBlockZ + 0.5);
player.teleport(newLoc);
}
}
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.PLAYER_QUIT);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.PLAYER_QUIT);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(player);
rules.process(context);
@@ -399,17 +176,7 @@ public class WorldGuardPlayerListener implements Listener {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
if (event.getAction() == Action.RIGHT_CLICK_BLOCK) {
handleBlockRightClick(event);
} else if (event.getAction() == Action.RIGHT_CLICK_AIR) {
handleAirRightClick(event);
} else if (event.getAction() == Action.LEFT_CLICK_BLOCK) {
handleBlockLeftClick(event);
} else if (event.getAction() == Action.LEFT_CLICK_AIR) {
handleAirLeftClick(event);
} else if (event.getAction() == Action.PHYSICAL) {
handlePhysicalInteract(event);
}
/* --- No short-circuit returns below this line --- */
// RuleLists
RuleSet rules;
@@ -418,8 +185,8 @@ public class WorldGuardPlayerListener implements Listener {
// Send one for the block
Block block = event.getClickedBlock();
if (block != null) {
rules = wcfg.getRuleList().get(KnownAttachment.BLOCK_INTERACT);
context = new BukkitContext(event);
rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_INTERACT);
context = new BukkitContext(plugin, event);
context.setSourceEntity(player);
context.setTargetBlock(event.getClickedBlock().getState());
if (rules.process(context)) {
@@ -430,8 +197,8 @@ public class WorldGuardPlayerListener implements Listener {
// Send one for the item in the end
ItemStack heldItem = event.getPlayer().getItemInHand();
if (heldItem != null) {
rules = wcfg.getRuleList().get(KnownAttachment.ITEM_USE);
context = new BukkitContext(event);
rules = wcfg.getRuleList().get(DefaultAttachments.ITEM_USE);
context = new BukkitContext(plugin, event);
context.setSourceEntity(event.getPlayer());
context.setItem(heldItem);
if (rules.process(context)) {
@@ -440,388 +207,15 @@ public class WorldGuardPlayerListener implements Listener {
}
}
/**
* Called when a player left clicks air.
*
* @param event Thrown event
*/
private void handleAirLeftClick(PlayerInteractEvent event) {
// I don't think we have to do anything here yet.
return;
}
/**
* Called when a player left clicks a block.
*
* @param event Thrown event
*/
private void handleBlockLeftClick(PlayerInteractEvent event) {
Player player = event.getPlayer();
Block block = event.getClickedBlock();
int type = block.getTypeId();
World world = player.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (wcfg.useRegions) {
Vector pt = toVector(block);
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (type == BlockID.STONE_BUTTON
|| type == BlockID.LEVER
|| type == BlockID.WOODEN_DOOR
|| type == BlockID.TRAP_DOOR
|| type == BlockID.NOTE_BLOCK) {
if (!plugin.getGlobalRegionManager().hasBypass(player, world)
&& !set.allows(DefaultFlag.USE, localPlayer)
&& !set.canBuild(localPlayer)) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission to use that in this area.");
event.setUseInteractedBlock(Result.DENY);
event.setCancelled(true);
return;
}
}
if (block.getRelative(event.getBlockFace()).getTypeId() == BlockID.FIRE) {
if (!plugin.getGlobalRegionManager().hasBypass(player, world)
&& !set.canBuild(localPlayer)) {
event.setUseInteractedBlock(Result.DENY);
event.setCancelled(true);
return;
}
}
}
if (type == BlockID.TNT && player.getItemInHand().getTypeId() == ItemID.FLINT_AND_TINDER) {
if (wcfg.getBlacklist() != null) {
if (!wcfg.getBlacklist().check(
new BlockBreakBlacklistEvent(plugin.wrapPlayer(player),
toVector(event.getClickedBlock()),
event.getClickedBlock().getTypeId()), false, false)) {
event.setUseInteractedBlock(Result.DENY);
event.setUseItemInHand(Result.DENY);
event.setCancelled(true);
return;
}
}
}
}
/**
* Called when a player right clicks air.
*
* @param event Thrown event
*/
private void handleAirRightClick(PlayerInteractEvent event) {
Player player = event.getPlayer();
World world = player.getWorld();
ItemStack item = player.getItemInHand();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
if (wcfg.getBlacklist() != null) {
if (!wcfg.getBlacklist().check(
new ItemUseBlacklistEvent(plugin.wrapPlayer(player),
toVector(player.getLocation()),
item.getTypeId()), false, false)) {
event.setCancelled(true);
event.setUseItemInHand(Result.DENY);
return;
}
}
}
/**
* Called when a player right clicks a block.
*
* @param event Thrown event
*/
private void handleBlockRightClick(PlayerInteractEvent event) {
Block block = event.getClickedBlock();
World world = block.getWorld();
int type = block.getTypeId();
Player player = event.getPlayer();
ItemStack item = player.getItemInHand();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
// Infinite stack removal
if ((type == BlockID.CHEST
|| type == BlockID.JUKEBOX
|| type == BlockID.DISPENSER
|| type == BlockID.FURNACE
|| type == BlockID.BURNING_FURNACE
|| type == BlockID.BREWING_STAND
|| type == BlockID.ENCHANTMENT_TABLE
|| type == BlockID.CAULDRON)
&& !plugin.hasPermission(player, "worldguard.override.infinite-stack")) {
for (int slot = 0; slot < 40; slot++) {
ItemStack heldItem = player.getInventory().getItem(slot);
if (heldItem != null && heldItem.getAmount() < 0) {
player.getInventory().setItem(slot, null);
player.sendMessage(ChatColor.RED + "Infinite stack in slot #" + slot + " removed.");
}
}
}
if (wcfg.useRegions) {
Vector pt = toVector(block);
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (item.getTypeId() == wcfg.regionWand && plugin.hasPermission(player, "worldguard.region.wand")) {
if (set.size() > 0) {
player.sendMessage(ChatColor.YELLOW + "Can you build? "
+ (set.canBuild(localPlayer) ? "Yes" : "No"));
StringBuilder str = new StringBuilder();
for (Iterator<ProtectedRegion> it = set.iterator(); it.hasNext();) {
str.append(it.next().getId());
if (it.hasNext()) {
str.append(", ");
}
}
player.sendMessage(ChatColor.YELLOW + "Applicable regions: " + str.toString());
} else {
player.sendMessage(ChatColor.YELLOW + "WorldGuard: No defined regions here!");
}
event.setCancelled(true);
return;
}
if (item.getTypeId() == BlockID.TNT) {
Block placedOn = block.getRelative(event.getBlockFace());
if (!plugin.getGlobalRegionManager().hasBypass(player, world)
&& !plugin.getGlobalRegionManager().allows(
DefaultFlag.TNT, placedOn.getLocation(), localPlayer)) {
event.setUseItemInHand(Result.DENY);
event.setCancelled(true);
}
}
if (item.getTypeId() == ItemID.INK_SACK
&& item.getData() != null
&& item.getData().getData() == 15 // bonemeal
&& type == BlockID.GRASS) {
if (!plugin.getGlobalRegionManager().hasBypass(player, world)
&& !set.canBuild(localPlayer)) {
event.setCancelled(true);
event.setUseItemInHand(Result.DENY);
}
}
if (type == BlockID.BED) {
if (!plugin.getGlobalRegionManager().hasBypass(player, world)
&& !set.allows(DefaultFlag.SLEEP, localPlayer)) {
player.sendMessage(ChatColor.DARK_RED + "You're not allowed to use that bed.");
event.setUseInteractedBlock(Result.DENY);
event.setCancelled(true);
return;
}
}
if (type == BlockID.CHEST
|| type == BlockID.JUKEBOX //stores the (arguably) most valuable item
|| type == BlockID.DISPENSER
|| type == BlockID.FURNACE
|| type == BlockID.BURNING_FURNACE
|| type == BlockID.BREWING_STAND) {
if (!plugin.getGlobalRegionManager().hasBypass(player, world)
&& !set.canBuild(localPlayer)
&& !set.allows(DefaultFlag.CHEST_ACCESS, localPlayer)) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission to open that in this area.");
event.setUseInteractedBlock(Result.DENY);
event.setCancelled(true);
return;
}
}
if (type == BlockID.LEVER
|| type == BlockID.STONE_BUTTON
|| type == BlockID.NOTE_BLOCK
|| type == BlockID.REDSTONE_REPEATER_OFF
|| type == BlockID.REDSTONE_REPEATER_ON
|| type == BlockID.WOODEN_DOOR
|| type == BlockID.TRAP_DOOR
|| type == BlockID.FENCE_GATE
|| type == BlockID.JUKEBOX //stores the (arguably) most valuable item
|| type == BlockID.DISPENSER
|| type == BlockID.FURNACE
|| type == BlockID.BURNING_FURNACE
|| type == BlockID.WORKBENCH
|| type == BlockID.BREWING_STAND
|| type == BlockID.ENCHANTMENT_TABLE
|| type == BlockID.CAULDRON
|| type == BlockID.DRAGON_EGG) {
if (!plugin.getGlobalRegionManager().hasBypass(player, world)
&& !set.canBuild(localPlayer)
&& !set.allows(DefaultFlag.USE, localPlayer)) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission to use that in this area.");
event.setUseInteractedBlock(Result.DENY);
event.setCancelled(true);
return;
}
}
if (type == BlockID.CAKE_BLOCK) {
if (!plugin.getGlobalRegionManager().hasBypass(player, world)
&& !set.canBuild(localPlayer)
&& !set.allows(DefaultFlag.USE, localPlayer)) {
player.sendMessage(ChatColor.DARK_RED + "You're not invited to this tea party!");
event.setUseInteractedBlock(Result.DENY);
event.setCancelled(true);
return;
}
}
if (BlockType.isRailBlock(type) && item.getTypeId() == ItemID.MINECART) {
if (!plugin.getGlobalRegionManager().hasBypass(player, world)
&& !set.canBuild(localPlayer)
&& !set.allows(DefaultFlag.PLACE_VEHICLE, localPlayer)) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission to place vehicles here.");
event.setUseItemInHand(Result.DENY);
event.setCancelled(true);
return;
}
}
if (item.getTypeId() == ItemID.WOOD_BOAT) {
if (!plugin.getGlobalRegionManager().hasBypass(player, world)
&& !set.canBuild(localPlayer)
&& !set.allows(DefaultFlag.PLACE_VEHICLE, localPlayer)) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission to place vehicles here.");
event.setUseItemInHand(Result.DENY);
event.setCancelled(true);
return;
}
}
}
if (wcfg.getBlacklist() != null) {
if(type != BlockID.CHEST
&& type != BlockID.DISPENSER
&& type != BlockID.FURNACE
&& type != BlockID.BURNING_FURNACE
&& type != BlockID.BREWING_STAND
&& type != BlockID.ENCHANTMENT_TABLE
&& type != BlockID.CAULDRON) {
if (!wcfg.getBlacklist().check(
new ItemUseBlacklistEvent(plugin.wrapPlayer(player), toVector(block),
item.getTypeId()), false, false)) {
event.setUseItemInHand(Result.DENY);
event.setCancelled(true);
return;
}
}
if (!wcfg.getBlacklist().check(
new BlockInteractBlacklistEvent(plugin.wrapPlayer(player), toVector(block),
block.getTypeId()), false, false)) {
event.setUseInteractedBlock(Result.DENY);
event.setCancelled(true);
return;
}
// Workaround for http://leaky.bukkit.org/issues/1034
if (item.getTypeId() == BlockID.TNT) {
Block placedOn = block.getRelative(event.getBlockFace());
if (!wcfg.getBlacklist().check(
new BlockPlaceBlacklistEvent(plugin.wrapPlayer(player), toVector(placedOn),
item.getTypeId()), false, false)) {
event.setUseItemInHand(Result.DENY);
event.setCancelled(true);
return;
}
}
}
if ((type == BlockID.CHEST
|| type == BlockID.DISPENSER
|| type == BlockID.FURNACE
|| type == BlockID.BURNING_FURNACE
|| type == BlockID.ENCHANTMENT_TABLE
|| type == BlockID.BREWING_STAND)) {
if (wcfg.isChestProtected(block, player)) {
player.sendMessage(ChatColor.DARK_RED + "The chest is protected.");
event.setUseInteractedBlock(Result.DENY);
event.setCancelled(true);
return;
}
}
}
/**
* Called when a player steps on a pressure plate or tramples crops.
*
* @param event Thrown event
*/
private void handlePhysicalInteract(PlayerInteractEvent event) {
Player player = event.getPlayer();
Block block = event.getClickedBlock(); //not actually clicked but whatever
int type = block.getTypeId();
World world = player.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
// Regions
if (wcfg.useRegions) {
Vector pt = toVector(block);
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (type == BlockID.STONE_PRESSURE_PLATE || type == BlockID.WOODEN_PRESSURE_PLATE) {
if (!plugin.getGlobalRegionManager().hasBypass(player, world)
&& !set.canBuild(localPlayer)
&& !set.allows(DefaultFlag.USE, localPlayer)) {
event.setUseInteractedBlock(Result.DENY);
event.setCancelled(true);
return;
}
}
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onPlayerDropItem(PlayerDropItemEvent event) {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getPlayer().getWorld());
Player player = event.getPlayer();
// Regions
if (wcfg.useRegions) {
if (!plugin.getGlobalRegionManager().allows(DefaultFlag.ITEM_DROP, player.getLocation())) {
event.setCancelled(true);
player.sendMessage(ChatColor.RED + "You don't have permission to do that in this area.");
}
}
// Blacklists
if (wcfg.getBlacklist() != null) {
Item ci = event.getItemDrop();
if (!wcfg.getBlacklist().check(
new ItemDropBlacklistEvent(plugin.wrapPlayer(event.getPlayer()),
toVector(ci.getLocation()), ci.getItemStack().getTypeId()), false, false)) {
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ITEM_DROP);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ITEM_DROP);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(player);
context.setItem(event.getItemDrop().getItemStack());
if (rules.process(context)) {
@@ -835,21 +229,9 @@ public class WorldGuardPlayerListener implements Listener {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getPlayer().getWorld());
// Blacklist
if (wcfg.getBlacklist() != null) {
Item ci = event.getItem();
if (!wcfg.getBlacklist().check(
new ItemAcquireBlacklistEvent(plugin.wrapPlayer(event.getPlayer()),
toVector(ci.getLocation()), ci.getItemStack().getTypeId()), false, true)) {
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ITEM_PICKUP);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ITEM_PICKUP);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(event.getPlayer());
context.setItem(event.getItem().getItemStack());
if (rules.process(context)) {
@@ -865,9 +247,11 @@ public class WorldGuardPlayerListener implements Listener {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
/* --- No short-circuit returns below this line --- */
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ENTITY_DEATH);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ENTITY_DEATH);
BukkitContext context = new BukkitContext(plugin, event);
context.setTargetEntity(player);
rules.process(context);
}
@@ -880,27 +264,9 @@ public class WorldGuardPlayerListener implements Listener {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
// Regions
if (!plugin.getGlobalRegionManager().canBuild(
player, event.getBlockClicked().getRelative(event.getBlockFace()))) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
event.setCancelled(true);
return;
}
// Blacklist
if (wcfg.getBlacklist() != null) {
if (!wcfg.getBlacklist().check(
new ItemUseBlacklistEvent(plugin.wrapPlayer(player),
toVector(player.getLocation()), event.getBucket().getId()), false, false)) {
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ITEM_USE);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ITEM_USE);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(event.getPlayer());
context.setItem(event.getItemStack());
if (rules.process(context)) {
@@ -917,27 +283,9 @@ public class WorldGuardPlayerListener implements Listener {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
// Regions
if (!plugin.getGlobalRegionManager().canBuild(
player, event.getBlockClicked().getRelative(event.getBlockFace()))) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission for this area.");
event.setCancelled(true);
return;
}
// Blacklist
if (wcfg.getBlacklist() != null) {
if (!wcfg.getBlacklist().check(
new ItemUseBlacklistEvent(plugin.wrapPlayer(player),
toVector(player.getLocation()), event.getBucket().getId()), false, false)) {
event.setCancelled(true);
return;
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.ITEM_USE);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ITEM_USE);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(event.getPlayer());
context.setItem(event.getItemStack());
if (rules.process(context)) {
@@ -949,28 +297,15 @@ public class WorldGuardPlayerListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void onPlayerRespawn(PlayerRespawnEvent event) {
Player player = event.getPlayer();
Location location = player.getLocation();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
// Regions
if (wcfg.useRegions) {
Vector pt = toVector(location);
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
LocalPlayer localPlayer = plugin.wrapPlayer(player);
com.sk89q.worldedit.Location spawn = set.getFlag(DefaultFlag.SPAWN_LOC, localPlayer);
if (spawn != null) {
event.setRespawnLocation(com.sk89q.worldedit.bukkit.BukkitUtil.toLocation(spawn));
}
}
/* --- No short-circuit returns below this line --- */
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.PLAYER_RESPAWN);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.PLAYER_RESPAWN);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(event.getPlayer());
rules.process(context);
}
@@ -978,61 +313,18 @@ public class WorldGuardPlayerListener implements Listener {
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onPlayerBedEnter(PlayerBedEnterEvent event) {
Player player = event.getPlayer();
Location location = player.getLocation();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(player.getWorld());
// Regions
if (wcfg.useRegions) {
Vector pt = toVector(location);
RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
if (!plugin.getGlobalRegionManager().hasBypass(player, player.getWorld())
&& !set.allows(DefaultFlag.SLEEP, plugin.wrapPlayer(player))) {
event.setCancelled(true);
player.sendMessage("This bed doesn't belong to you!");
return;
}
}
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
Player player = event.getPlayer();
LocalPlayer localPlayer = plugin.wrapPlayer(player);
World world = player.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
// Regions
if (wcfg.useRegions && !plugin.getGlobalRegionManager().hasBypass(player, world)) {
Vector pt = toVector(player.getLocation());
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
String[] parts = event.getMessage().split(" ");
String lowerCommand = parts[0].toLowerCase();
Set<String> allowedCommands = set.getFlag(DefaultFlag.ALLOWED_CMDS, localPlayer);
Set<String> blockedCommands = set.getFlag(DefaultFlag.BLOCKED_CMDS, localPlayer);
if (allowedCommands != null && !allowedCommands.contains(lowerCommand)
&& (blockedCommands == null || blockedCommands.contains(lowerCommand))) {
player.sendMessage(ChatColor.RED + lowerCommand + " is not allowed in this area.");
event.setMessage("/"); // Make sure that it's disabled
event.setCancelled(true);
return;
}
if (blockedCommands != null && blockedCommands.contains(lowerCommand)
&& (allowedCommands == null || !allowedCommands.contains(lowerCommand))) {
player.sendMessage(ChatColor.RED + lowerCommand + " is blocked in this area.");
event.setMessage("/"); // Make sure that it's disabled
event.setCancelled(true);
return;
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.BLOCK_INTERACT);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(player);
context.setTargetBlock(event.getBed().getState());
if (rules.process(context)) {
event.setCancelled(true);
return;
}
}
}
@@ -30,8 +30,6 @@ import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World;
@@ -60,6 +58,7 @@ import com.sk89q.rebar.config.YamlConfiguration;
import com.sk89q.rebar.config.YamlConfigurationResource;
import com.sk89q.rulelists.Action;
import com.sk89q.rulelists.Criteria;
import com.sk89q.rulelists.DefaultAttachments;
import com.sk89q.rulelists.DefinitionManager;
import com.sk89q.rulelists.ResolverManager;
import com.sk89q.rulelists.RuleListsManager;
@@ -73,9 +72,11 @@ import com.sk89q.worldguard.bukkit.definitions.BlockCriteriaLoader;
import com.sk89q.worldguard.bukkit.definitions.CancelActionLoader;
import com.sk89q.worldguard.bukkit.definitions.DamageCriteriaLoader;
import com.sk89q.worldguard.bukkit.definitions.EntityCriteriaLoader;
import com.sk89q.worldguard.bukkit.definitions.FlagCriteriaLoader;
import com.sk89q.worldguard.bukkit.definitions.ItemCriteriaLoader;
import com.sk89q.worldguard.bukkit.definitions.PermissionCriteriaLoader;
import com.sk89q.worldguard.bukkit.definitions.PhenomenonCriteriaLoader;
import com.sk89q.worldguard.bukkit.definitions.RegionCriteriaLoader;
import com.sk89q.worldguard.bukkit.definitions.SetBlockActionLoader;
import com.sk89q.worldguard.bukkit.definitions.SetDropActionLoader;
import com.sk89q.worldguard.bukkit.definitions.SpawnCriteriaLoader;
@@ -95,9 +96,8 @@ import com.sk89q.worldguard.bukkit.resolvers.SourceBlockResolver;
import com.sk89q.worldguard.bukkit.resolvers.SourceEntityResolver;
import com.sk89q.worldguard.bukkit.resolvers.TargetBlockResolver;
import com.sk89q.worldguard.bukkit.resolvers.TargetEntityResolver;
import com.sk89q.worldguard.protection.GlobalRegionManager;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.util.FatalConfigurationLoadingException;
import com.sk89q.worldguard.region.RegionManager;
import com.sk89q.worldguard.region.indices.RegionIndex;
/**
* The main class for WorldGuard as a Bukkit plugin.
@@ -105,10 +105,10 @@ import com.sk89q.worldguard.util.FatalConfigurationLoadingException;
public class WorldGuardPlugin extends JavaPlugin {
private final CommandsManager<CommandSender> commands;
private final GlobalRegionManager globalRegionManager;
private final RegionManager globalRegionManager;
private final ConfigurationManager configuration;
private FlagStateManager flagStateManager;
private RuleListsManager ruleListsManager;
private RegionQueryCache regionCache;
private final LagStopMode lagStopper;
private WorldGuardWorldListener worldListener;
@@ -119,7 +119,7 @@ public class WorldGuardPlugin extends JavaPlugin {
*/
public WorldGuardPlugin() {
configuration = new ConfigurationManager(this);
globalRegionManager = new GlobalRegionManager(this);
globalRegionManager = new RegionManager(this);
lagStopper = new LagStopMode(this);
final WorldGuardPlugin plugin = this;
@@ -141,6 +141,9 @@ public class WorldGuardPlugin extends JavaPlugin {
ruleListsManager = new RuleListsManager();
registerRuleList();
// Setup the cache
regionCache = new RegionQueryCache(this);
// Set the proper command injector
commands.setInjector(new SimpleInjector(this));
@@ -163,27 +166,9 @@ public class WorldGuardPlugin extends JavaPlugin {
PermissionsResolverManager.initialize(this);
// This must be done before configuration is loaded
LegacyWorldGuardMigration.migrateBlacklist(this);
try {
// Load the configuration
configuration.load();
globalRegionManager.preload();
} catch (FatalConfigurationLoadingException e) {
getLogger().log(Level.SEVERE, "Fatal error encountered", e);
getServer().shutdown();
}
// Migrate regions after the regions were loaded because
// the migration code reuses the loaded region managers
LegacyWorldGuardMigration.migrateRegions(this);
flagStateManager = new FlagStateManager(this);
if (configuration.useRegionsScheduler) {
getServer().getScheduler().scheduleAsyncRepeatingTask(this, flagStateManager, FlagStateManager.RUN_DELAY, FlagStateManager.RUN_DELAY);
}
// Load the configuration
configuration.load();
globalRegionManager.preload();
// Register events
(new WorldGuardPlayerListener(this)).registerEvents();
@@ -204,10 +189,6 @@ public class WorldGuardPlugin extends JavaPlugin {
(new WorldGuardPaintingListener(this)).registerEvents();
}
configuration.updateCommandBookGodMode();
if (getServer().getPluginManager().isPluginEnabled("CommandBook")) {
getServer().getPluginManager().registerEvents(new WorldGuardCommandBookListener(this), this);
}
}
@Override
@@ -258,7 +239,7 @@ public class WorldGuardPlugin extends JavaPlugin {
*
* @return The plugin's global region manager
*/
public GlobalRegionManager getGlobalRegionManager() {
public RegionManager getGlobalRegionManager() {
return globalRegionManager;
}
@@ -273,15 +254,6 @@ public class WorldGuardPlugin extends JavaPlugin {
return getGlobalStateManager();
}
/**
* Gets the flag state manager.
*
* @return The flag state manager
*/
public FlagStateManager getFlagStateManager() {
return flagStateManager;
}
/**
* Get the global ConfigurationManager.
* USe this to access global configuration values and per-world configuration values.
@@ -300,14 +272,21 @@ public class WorldGuardPlugin extends JavaPlugin {
return ruleListsManager;
}
/**
* Get the region query cache.
*
* @return region query cache
*/
public RegionQueryCache getRegionCache() {
return regionCache;
}
/**
* Get the built-in rules.
*
* @return built-in rules
* @throws ConfigurationException
* on config error
* @throws IOException
* on I/O exception
* @throws ConfigurationException on config error
* @throws IOException on I/O exception
*/
public YamlConfiguration getBuiltInRules() throws IOException, ConfigurationException {
YamlConfiguration rules = new YamlConfigurationResource(getClass(),
@@ -320,6 +299,8 @@ public class WorldGuardPlugin extends JavaPlugin {
* Register RuleList resolvers, criterion, and actions.
*/
private void registerRuleList() {
DefaultAttachments.registerWith(ruleListsManager.getAttachments());
// Subject resolvers
ResolverManager resolvers = ruleListsManager.getResolvers();
@@ -345,6 +326,8 @@ public class WorldGuardPlugin extends JavaPlugin {
criterion.register("match-spawn", new SpawnCriteriaLoader());
criterion.register("match-phenomenon", new PhenomenonCriteriaLoader());
criterion.register("match-weather", new WeatherCriteriaLoader());
criterion.register("region-of", new RegionCriteriaLoader(ruleListsManager));
criterion.register("has-flag", new FlagCriteriaLoader(this, ruleListsManager));
criterion.register("has-permission", new PermissionCriteriaLoader(this, ruleListsManager));
// Actions
@@ -864,7 +847,6 @@ public class WorldGuardPlugin extends JavaPlugin {
* @param player The player to remove state information for
*/
public void forgetPlayer(Player player) {
flagStateManager.forget(player);
}
/**
@@ -873,7 +855,7 @@ public class WorldGuardPlugin extends JavaPlugin {
*
* @param player The player to check.
* @param loc The location to check at.
* @see GlobalRegionManager#canBuild(org.bukkit.entity.Player, org.bukkit.Location)
* @see RegionManager#canBuild(org.bukkit.entity.Player, org.bukkit.Location)
* @return whether {@code player} can build at {@code loc}
*/
public boolean canBuild(Player player, Location loc) {
@@ -886,7 +868,7 @@ public class WorldGuardPlugin extends JavaPlugin {
*
* @param player The player to check
* @param block The block to check at.
* @see GlobalRegionManager#canBuild(org.bukkit.entity.Player, org.bukkit.block.Block)
* @see RegionManager#canBuild(org.bukkit.entity.Player, org.bukkit.block.Block)
* @return whether {@code player} can build at {@code block}'s location
*/
public boolean canBuild(Player player, Block block) {
@@ -899,7 +881,7 @@ public class WorldGuardPlugin extends JavaPlugin {
* @param world world to get the region manager for
* @return the region manager or null if regions are not enabled
*/
public RegionManager getRegionManager(World world) {
public RegionIndex getRegionManager(World world) {
if (!getGlobalStateManager().get(world).useRegions) {
return null;
}
@@ -9,15 +9,23 @@ import org.bukkit.plugin.PluginManager;
/**
* Listener for server events.
*/
public class WorldGuardServerListener implements Listener {
class WorldGuardServerListener implements Listener {
private final WorldGuardPlugin plugin;
public WorldGuardServerListener(WorldGuardPlugin plugin) {
/**
* Construct the listener.
*
* @param plugin WorldGuard plugin
*/
WorldGuardServerListener(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
public void registerEvents() {
/**
* Register events.
*/
void registerEvents() {
PluginManager pm = plugin.getServer().getPluginManager();
pm.registerEvents(this, plugin);
}
@@ -5,38 +5,34 @@
*/
package com.sk89q.worldguard.bukkit;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Vehicle;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.vehicle.VehicleDestroyEvent;
import org.bukkit.event.vehicle.VehicleMoveEvent;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.bukkit.FlagStateManager.PlayerFlagState;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.rulelists.DefaultAttachments;
import com.sk89q.rulelists.RuleSet;
/**
* Listener for vehicle events.
*/
public class WorldGuardVehicleListener implements Listener {
class WorldGuardVehicleListener implements Listener {
private WorldGuardPlugin plugin;
public WorldGuardVehicleListener(WorldGuardPlugin plugin) {
/**
* Construct the listener.
*
* @param plugin WorldGuard plugin
*/
WorldGuardVehicleListener(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
public void registerEvents() {
/**
* Register the events.
*/
void registerEvents() {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@@ -45,133 +41,17 @@ public class WorldGuardVehicleListener implements Listener {
Vehicle vehicle = event.getVehicle();
Entity destroyer = event.getAttacker();
if (!(destroyer instanceof Player)) return; // don't care
Player player = (Player) destroyer;
World world = vehicle.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
WorldConfiguration wcfg = cfg.get(vehicle.getWorld());
// Regions
if (wcfg.useRegions) {
Vector pt = toVector(vehicle.getLocation());
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (!plugin.getGlobalRegionManager().hasBypass(player, world)
&& !set.canBuild(localPlayer)
&& !set.allows(DefaultFlag.DESTROY_VEHICLE, localPlayer)) {
player.sendMessage(ChatColor.DARK_RED + "You don't have permission to destroy vehicles here.");
event.setCancelled(true);
return;
}
}
}
@EventHandler
public void onVehicleMove(VehicleMoveEvent event) {
Vehicle vehicle = event.getVehicle();
if (vehicle.getPassenger() == null
|| !(vehicle.getPassenger() instanceof Player)) return;
Player player = (Player) vehicle.getPassenger();
World world = vehicle.getWorld();
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(world);
// Regions
// unfortunate code duplication
if (wcfg.useRegions) {
// Did we move a block?
if (event.getFrom().getBlockX() != event.getTo().getBlockX()
|| event.getFrom().getBlockY() != event.getTo().getBlockY()
|| event.getFrom().getBlockZ() != event.getTo().getBlockZ()) {
PlayerFlagState state = plugin.getFlagStateManager().getState(player);
LocalPlayer localPlayer = plugin.wrapPlayer(player);
boolean hasBypass = plugin.getGlobalRegionManager().hasBypass(player, world);
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
Vector pt = new Vector(event.getTo().getBlockX(), event.getTo().getBlockY(), event.getTo().getBlockZ());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
boolean entryAllowed = set.allows(DefaultFlag.ENTRY, localPlayer);
if (!hasBypass && !entryAllowed) {
vehicle.setVelocity(new org.bukkit.util.Vector(0,0,0));
vehicle.teleport(event.getFrom());
return;
}
// Have to set this state
if (state.lastExitAllowed == null) {
state.lastExitAllowed = mgr.getApplicableRegions(toVector(event.getFrom()))
.allows(DefaultFlag.EXIT, localPlayer);
}
boolean exitAllowed = set.allows(DefaultFlag.EXIT, localPlayer);
if (!hasBypass && exitAllowed && !state.lastExitAllowed) {
player.sendMessage(ChatColor.DARK_RED + "You are not permitted to leave this area.");
vehicle.setVelocity(new org.bukkit.util.Vector(0,0,0));
vehicle.teleport(event.getFrom());
return;
}
String greeting = set.getFlag(DefaultFlag.GREET_MESSAGE, localPlayer);
String farewell = set.getFlag(DefaultFlag.FAREWELL_MESSAGE, localPlayer);
Boolean notifyEnter = set.getFlag(DefaultFlag.NOTIFY_ENTER, localPlayer);
Boolean notifyLeave = set.getFlag(DefaultFlag.NOTIFY_LEAVE, localPlayer);
if (state.lastFarewell != null && (farewell == null
|| !state.lastFarewell.equals(farewell))) {
String replacedFarewell = plugin.replaceMacros(
player, BukkitUtil.replaceColorMacros(state.lastFarewell));
player.sendMessage(ChatColor.AQUA + " ** " + replacedFarewell);
}
if (greeting != null && (state.lastGreeting == null
|| !state.lastGreeting.equals(greeting))) {
String replacedGreeting = plugin.replaceMacros(
player, BukkitUtil.replaceColorMacros(greeting));
player.sendMessage(ChatColor.AQUA + " ** " + replacedGreeting);
}
if ((notifyLeave == null || !notifyLeave)
&& state.notifiedForLeave != null && state.notifiedForLeave) {
plugin.broadcastNotification(ChatColor.GRAY + "WG: "
+ ChatColor.LIGHT_PURPLE + player.getName()
+ ChatColor.GOLD + " left NOTIFY region");
}
if (notifyEnter != null && notifyEnter && (state.notifiedForEnter == null
|| !state.notifiedForEnter)) {
StringBuilder regionList = new StringBuilder();
for (ProtectedRegion region : set) {
if (regionList.length() != 0) {
regionList.append(", ");
}
regionList.append(region.getId());
}
plugin.broadcastNotification(ChatColor.GRAY + "WG: "
+ ChatColor.LIGHT_PURPLE + player.getName()
+ ChatColor.GOLD + " entered NOTIFY region: "
+ ChatColor.WHITE
+ regionList);
}
state.lastGreeting = greeting;
state.lastFarewell = farewell;
state.notifiedForEnter = notifyEnter;
state.notifiedForLeave = notifyLeave;
state.lastExitAllowed = exitAllowed;
state.lastWorld = event.getTo().getWorld();
state.lastBlockX = event.getTo().getBlockX();
state.lastBlockY = event.getTo().getBlockY();
state.lastBlockZ = event.getTo().getBlockZ();
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.ENTITY_DAMAGE);
BukkitContext context = new BukkitContext(plugin, event);
context.setSourceEntity(destroyer);
context.setTargetEntity(vehicle);
if (rules.process(context)) {
event.setCancelled(true);
return;
}
}
}
@@ -18,8 +18,6 @@
*/
package com.sk89q.worldguard.bukkit;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
import org.bukkit.Location;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@@ -28,25 +26,29 @@ import org.bukkit.event.weather.LightningStrikeEvent;
import org.bukkit.event.weather.ThunderChangeEvent;
import org.bukkit.event.weather.WeatherChangeEvent;
import com.sk89q.rulelists.KnownAttachment;
import com.sk89q.rulelists.DefaultAttachments;
import com.sk89q.rulelists.RuleSet;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
/**
* Listener for weather events.
*/
public class WorldGuardWeatherListener implements Listener {
class WorldGuardWeatherListener implements Listener {
private WorldGuardPlugin plugin;
public WorldGuardWeatherListener(WorldGuardPlugin plugin) {
/**
* Construct the listener.
*
* @param plugin WorldGuard plugin
*/
WorldGuardWeatherListener(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
public void registerEvents() {
/**
* Register the events.
*/
void registerEvents() {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@@ -56,8 +58,8 @@ public class WorldGuardWeatherListener implements Listener {
WorldConfiguration wcfg = cfg.get(event.getWorld());
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.WEATHER_TRANSITION);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.WEATHER_TRANSITION);
BukkitContext context = new BukkitContext(plugin, event);
if (rules.process(context)) {
event.setCancelled(true);
return;
@@ -70,8 +72,8 @@ public class WorldGuardWeatherListener implements Listener {
WorldConfiguration wcfg = cfg.get(event.getWorld());
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.WEATHER_TRANSITION);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.WEATHER_TRANSITION);
BukkitContext context = new BukkitContext(plugin, event);
if (rules.process(context)) {
event.setCancelled(true);
return;
@@ -85,20 +87,9 @@ public class WorldGuardWeatherListener implements Listener {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getWorld());
// Regions
if (wcfg.useRegions) {
Vector pt = toVector(loc);
RegionManager mgr = plugin.getGlobalRegionManager().get(loc.getWorld());
ApplicableRegionSet set = mgr.getApplicableRegions(pt);
if (!set.allows(DefaultFlag.LIGHTNING)) {
event.setCancelled(true);
}
}
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.WEATHER_PHENOMENON);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.WEATHER_PHENOMENON);
BukkitContext context = new BukkitContext(plugin, event);
context.setTargetBlock(loc.getBlock().getState());
if (rules.process(context)) {
event.setCancelled(true);
@@ -11,7 +11,7 @@ import org.bukkit.event.world.WorldLoadEvent;
import org.bukkit.event.world.WorldSaveEvent;
import org.bukkit.event.world.WorldUnloadEvent;
import com.sk89q.rulelists.KnownAttachment;
import com.sk89q.rulelists.DefaultAttachments;
import com.sk89q.rulelists.RuleSet;
/**
@@ -21,10 +21,18 @@ public class WorldGuardWorldListener implements Listener {
private WorldGuardPlugin plugin;
/**
* Construct the listener.
*
* @param plugin WorldGuard plugin
*/
public WorldGuardWorldListener(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
/**
* Register the events.
*/
public void registerEvents() {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@@ -34,9 +42,11 @@ public class WorldGuardWorldListener implements Listener {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getWorld());
/* --- No short-circuit returns below this line --- */
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.WORLD_LOAD);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.WORLD_LOAD);
BukkitContext context = new BukkitContext(plugin, event);
rules.process(context);
}
@@ -46,8 +56,8 @@ public class WorldGuardWorldListener implements Listener {
WorldConfiguration wcfg = cfg.get(event.getWorld());
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.WORLD_UNLOAD);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.WORLD_UNLOAD);
BukkitContext context = new BukkitContext(plugin, event);
if (rules.process(context)) {
event.setCancelled(true);
return;
@@ -59,9 +69,11 @@ public class WorldGuardWorldListener implements Listener {
ConfigurationManager cfg = plugin.getGlobalStateManager();
WorldConfiguration wcfg = cfg.get(event.getWorld());
/* --- No short-circuit returns below this line --- */
// RuleLists
RuleSet rules = wcfg.getRuleList().get(KnownAttachment.WORLD_SAVE);
BukkitContext context = new BukkitContext(event);
RuleSet rules = wcfg.getRuleList().get(DefaultAttachments.WORLD_SAVE);
BukkitContext context = new BukkitContext(plugin, event);
rules.process(context);
}
}
@@ -31,20 +31,12 @@ import com.sk89q.worldedit.bukkit.selections.Selection;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
import com.sk89q.worldguard.protection.databases.RegionDBUtil;
import com.sk89q.worldguard.protection.databases.migrators.AbstractDatabaseMigrator;
import com.sk89q.worldguard.protection.databases.migrators.MigrationException;
import com.sk89q.worldguard.protection.databases.migrators.MigratorKey;
import com.sk89q.worldguard.protection.flags.*;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
import com.sk89q.worldguard.region.ApplicableRegionSet;
import com.sk89q.worldguard.region.Region;
import com.sk89q.worldguard.region.flags.*;
import com.sk89q.worldguard.region.indices.RegionIndex;
import com.sk89q.worldguard.region.shapes.Cuboid;
import com.sk89q.worldguard.region.shapes.ExtrudedPolygon;
import org.bukkit.ChatColor;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
@@ -58,52 +50,52 @@ public class RegionCommands {
private MigratorKey migrateDBRequest;
private Date migrateDBRequestDate;
public RegionCommands(WorldGuardPlugin plugin) {
this.plugin = plugin;
}
@Command(aliases = {"define", "def", "d"}, usage = "<id> [<owner1> [<owner2> [<owners...>]]]",
desc = "Defines a region", min = 1)
@CommandPermissions({"worldguard.region.define"})
public void define(CommandContext args, CommandSender sender) throws CommandException {
Player player = plugin.checkPlayer(sender);
WorldEditPlugin worldEdit = plugin.getWorldEdit();
String id = args.getString(0);
if (!ProtectedRegion.isValidId(id)) {
if (!Region.isValidId(id)) {
throw new CommandException("Invalid region ID specified!");
}
if (id.equalsIgnoreCase("__global__")) {
throw new CommandException("A region cannot be named __global__");
}
// Attempt to get the player's selection from WorldEdit
Selection sel = worldEdit.getSelection(player);
if (sel == null) {
throw new CommandException("Select a region with WorldEdit first.");
}
RegionManager mgr = plugin.getGlobalRegionManager().get(sel.getWorld());
RegionIndex mgr = plugin.getGlobalRegionManager().get(sel.getWorld());
if (mgr.hasRegion(id)) {
throw new CommandException("That region is already defined. Use redefine instead.");
}
ProtectedRegion region;
Region region;
// Detect the type of region from WorldEdit
if (sel instanceof Polygonal2DSelection) {
Polygonal2DSelection polySel = (Polygonal2DSelection) sel;
int minY = polySel.getNativeMinimumPoint().getBlockY();
int maxY = polySel.getNativeMaximumPoint().getBlockY();
region = new ProtectedPolygonalRegion(id, polySel.getNativePoints(), minY, maxY);
region = new ExtrudedPolygon(id, polySel.getNativePoints(), minY, maxY);
} else if (sel instanceof CuboidSelection) {
BlockVector min = sel.getNativeMinimumPoint().toBlockVector();
BlockVector max = sel.getNativeMaximumPoint().toBlockVector();
region = new ProtectedCuboidRegion(id, min, max);
region = new Cuboid(id, min, max);
} else {
throw new CommandException(
"The type of region selected in WorldEdit is unsupported in WorldGuard!");
@@ -113,9 +105,9 @@ public class RegionCommands {
if (args.argsLength() > 1) {
region.setOwners(RegionDBUtil.parseDomainString(args.getSlice(1), 1));
}
mgr.addRegion(region);
try {
mgr.save();
sender.sendMessage(ChatColor.YELLOW + "Region saved as " + id + ".");
@@ -124,23 +116,23 @@ public class RegionCommands {
+ e.getMessage());
}
}
@Command(aliases = {"redefine", "update", "move"}, usage = "<id>",
desc = "Re-defines the shape of a region", min = 1, max = 1)
public void redefine(CommandContext args, CommandSender sender) throws CommandException {
Player player = plugin.checkPlayer(sender);
World world = player.getWorld();
WorldEditPlugin worldEdit = plugin.getWorldEdit();
LocalPlayer localPlayer = plugin.wrapPlayer(player);
String id = args.getString(0);
if (id.equalsIgnoreCase("__global__")) {
throw new CommandException("The region cannot be named __global__");
}
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ProtectedRegion existing = mgr.getRegionExact(id);
RegionIndex mgr = plugin.getGlobalRegionManager().get(world);
Region existing = mgr.getRegionExact(id);
if (existing == null) {
throw new CommandException("Could not find a region by that ID.");
@@ -152,27 +144,27 @@ public class RegionCommands {
plugin.checkPermission(sender, "worldguard.region.redefine.member");
} else {
plugin.checkPermission(sender, "worldguard.region.redefine");
}
}
// Attempt to get the player's selection from WorldEdit
Selection sel = worldEdit.getSelection(player);
if (sel == null) {
throw new CommandException("Select a region with WorldEdit first.");
}
ProtectedRegion region;
Region region;
// Detect the type of region from WorldEdit
if (sel instanceof Polygonal2DSelection) {
Polygonal2DSelection polySel = (Polygonal2DSelection) sel;
int minY = polySel.getNativeMinimumPoint().getBlockY();
int maxY = polySel.getNativeMaximumPoint().getBlockY();
region = new ProtectedPolygonalRegion(id, polySel.getNativePoints(), minY, maxY);
region = new ExtrudedPolygon(id, polySel.getNativePoints(), minY, maxY);
} else if (sel instanceof CuboidSelection) {
BlockVector min = sel.getNativeMinimumPoint().toBlockVector();
BlockVector max = sel.getNativeMaximumPoint().toBlockVector();
region = new ProtectedCuboidRegion(id, min, max);
region = new Cuboid(id, min, max);
} else {
throw new CommandException(
"The type of region selected in WorldEdit is unsupported in WorldGuard!");
@@ -186,11 +178,11 @@ public class RegionCommands {
region.setParent(existing.getParent());
} catch (CircularInheritanceException ignore) {
}
mgr.addRegion(region);
sender.sendMessage(ChatColor.YELLOW + "Region updated with new area.");
try {
mgr.save();
} catch (ProtectionDatabaseException e) {
@@ -198,137 +190,6 @@ public class RegionCommands {
+ e.getMessage());
}
}
@Command(aliases = {"claim"}, usage = "<id> [<owner1> [<owner2> [<owners...>]]]",
desc = "Claim a region", min = 1)
@CommandPermissions({"worldguard.region.claim"})
public void claim(CommandContext args, CommandSender sender) throws CommandException {
Player player = plugin.checkPlayer(sender);
LocalPlayer localPlayer = plugin.wrapPlayer(player);
WorldEditPlugin worldEdit = plugin.getWorldEdit();
String id = args.getString(0);
if (!ProtectedRegion.isValidId(id)) {
throw new CommandException("Invalid region ID specified!");
}
if (id.equalsIgnoreCase("__global__")) {
throw new CommandException("A region cannot be named __global__");
}
// Attempt to get the player's selection from WorldEdit
Selection sel = worldEdit.getSelection(player);
if (sel == null) {
throw new CommandException("Select a region with WorldEdit first.");
}
RegionManager mgr = plugin.getGlobalRegionManager().get(sel.getWorld());
if (mgr.hasRegion(id)) {
throw new CommandException("That region already exists. Please choose a different name.");
}
ProtectedRegion region;
// Detect the type of region from WorldEdit
if (sel instanceof Polygonal2DSelection) {
Polygonal2DSelection polySel = (Polygonal2DSelection) sel;
int minY = polySel.getNativeMinimumPoint().getBlockY();
int maxY = polySel.getNativeMaximumPoint().getBlockY();
region = new ProtectedPolygonalRegion(id, polySel.getNativePoints(), minY, maxY);
} else if (sel instanceof CuboidSelection) {
BlockVector min = sel.getNativeMinimumPoint().toBlockVector();
BlockVector max = sel.getNativeMaximumPoint().toBlockVector();
region = new ProtectedCuboidRegion(id, min, max);
} else {
throw new CommandException(
"The type of region selected in WorldEdit is unsupported in WorldGuard!");
}
// Get the list of region owners
if (args.argsLength() > 1) {
region.setOwners(RegionDBUtil.parseDomainString(args.getSlice(1), 1));
}
WorldConfiguration wcfg = plugin.getGlobalStateManager().get(player.getWorld());
if (!plugin.hasPermission(sender, "worldguard.region.unlimited")) {
// Check whether the player has created too many regions
int maxRegionCount = wcfg.getMaxRegionCount(player);
if (maxRegionCount >= 0
&& mgr.getRegionCountOfPlayer(localPlayer) >= maxRegionCount) {
throw new CommandException("You own too many regions, delete one first to claim a new one.");
}
}
ProtectedRegion existing = mgr.getRegionExact(id);
// Check for an existing region
if (existing != null) {
if (!existing.getOwners().contains(localPlayer)) {
throw new CommandException("This region already exists and you don't own it.");
}
}
ApplicableRegionSet regions = mgr.getApplicableRegions(region);
// Check if this region overlaps any other region
if (regions.size() > 0) {
if (!regions.isOwnerOfAll(localPlayer)) {
throw new CommandException("This region overlaps with someone else's region.");
}
} else {
if (wcfg.claimOnlyInsideExistingRegions) {
throw new CommandException("You may only claim regions inside " +
"existing regions that you or your group own.");
}
}
/*if (plugin.getGlobalConfiguration().getiConomy() != null && wcfg.useiConomy && wcfg.buyOnClaim) {
if (iConomy.getBank().hasAccount(player.getName())) {
Account account = iConomy.getBank().getAccount(player.getName());
double balance = account.getBalance();
double regionCosts = region.countBlocks() * wcfg.buyOnClaimPrice;
if (balance >= regionCosts) {
account.subtract(regionCosts);
player.sendMessage(ChatColor.YELLOW + "You have bought that region for "
+ iConomy.getBank().format(regionCosts));
account.save();
} else {
player.sendMessage(ChatColor.RED + "You have not enough money.");
player.sendMessage(ChatColor.RED + "The region you want to claim costs "
+ iConomy.getBank().format(regionCosts));
player.sendMessage(ChatColor.RED + "You have " + iConomy.getBank().format(balance));
return;
}
} else {
player.sendMessage(ChatColor.YELLOW + "You have not enough money.");
return;
}
}*/
if (!plugin.hasPermission(sender, "worldguard.region.unlimited")) {
if (region.volume() > wcfg.maxClaimVolume) {
player.sendMessage(ChatColor.RED + "This region is too large to claim.");
player.sendMessage(ChatColor.RED +
"Max. volume: " + wcfg.maxClaimVolume + ", your volume: " + region.volume());
return;
}
}
region.getOwners().addPlayer(player.getName());
mgr.addRegion(region);
try {
mgr.save();
sender.sendMessage(ChatColor.YELLOW + "Region saved as " + id + ".");
} catch (ProtectionDatabaseException e) {
throw new CommandException("Failed to write regions: "
+ e.getMessage());
}
}
@Command(aliases = {"select", "sel", "s"}, usage = "[id]",
desc = "Load a region as a WorldEdit selection", min = 0, max = 1)
@@ -338,7 +199,7 @@ public class RegionCommands {
final World world = player.getWorld();
final LocalPlayer localPlayer = plugin.wrapPlayer(player);
final RegionManager mgr = plugin.getGlobalRegionManager().get(world);
final RegionIndex mgr = plugin.getGlobalRegionManager().get(world);
final String id;
if (args.argsLength() == 0) {
@@ -354,7 +215,7 @@ public class RegionCommands {
id = args.getString(0);
}
final ProtectedRegion region = mgr.getRegion(id);
final Region region = mgr.getRegion(id);
if (region == null) {
throw new CommandException("Could not find a region by that ID.");
@@ -363,7 +224,7 @@ public class RegionCommands {
selectRegion(player, localPlayer, region);
}
public void selectRegion(Player player, LocalPlayer localPlayer, ProtectedRegion region) throws CommandException, CommandPermissionsException {
public void selectRegion(Player player, LocalPlayer localPlayer, Region region) throws CommandException, CommandPermissionsException {
final WorldEditPlugin worldEdit = plugin.getWorldEdit();
final String id = region.getId();
@@ -376,19 +237,19 @@ public class RegionCommands {
}
final World world = player.getWorld();
if (region instanceof ProtectedCuboidRegion) {
final ProtectedCuboidRegion cuboid = (ProtectedCuboidRegion) region;
final Vector pt1 = cuboid.getMinimumPoint();
final Vector pt2 = cuboid.getMaximumPoint();
if (region instanceof Cuboid) {
final Cuboid cuboid = (Cuboid) region;
final Vector pt1 = cuboid.getAABBMin();
final Vector pt2 = cuboid.getAABBMax();
final CuboidSelection selection = new CuboidSelection(world, pt1, pt2);
worldEdit.setSelection(player, selection);
player.sendMessage(ChatColor.YELLOW + "Region selected as a cuboid.");
} else if (region instanceof ProtectedPolygonalRegion) {
final ProtectedPolygonalRegion poly2d = (ProtectedPolygonalRegion) region;
} else if (region instanceof ExtrudedPolygon) {
final ExtrudedPolygon poly2d = (ExtrudedPolygon) region;
final Polygonal2DSelection selection = new Polygonal2DSelection(
world, poly2d.getPoints(),
poly2d.getMinimumPoint().getBlockY(),
poly2d.getMaximumPoint().getBlockY()
poly2d.getAABBMin().getBlockY(),
poly2d.getAABBMax().getBlockY()
);
worldEdit.setSelection(player, selection);
player.sendMessage(ChatColor.YELLOW + "Region selected as a polygon.");
@@ -416,7 +277,7 @@ public class RegionCommands {
world = plugin.matchWorld(sender, args.getString(0));
}
final RegionManager mgr = plugin.getGlobalRegionManager().get(world);
final RegionIndex mgr = plugin.getGlobalRegionManager().get(world);
final String id;
@@ -444,10 +305,10 @@ public class RegionCommands {
id = args.getString(1).toLowerCase();
}
final ProtectedRegion region = mgr.getRegion(id);
final Region region = mgr.getRegion(id);
if (region == null) {
if (!ProtectedRegion.isValidId(id)) {
if (!Region.isValidId(id)) {
throw new CommandException("Invalid region ID specified!");
}
throw new CommandException("A region with ID '" + id + "' doesn't exist.");
@@ -460,7 +321,7 @@ public class RegionCommands {
}
}
public void displayRegionInfo(CommandSender sender, final LocalPlayer localPlayer, ProtectedRegion region) throws CommandPermissionsException {
public void displayRegionInfo(CommandSender sender, final LocalPlayer localPlayer, Region region) throws CommandPermissionsException {
if (localPlayer == null) {
plugin.checkPermission(sender, "worldguard.region.info");
} else if (region.isOwner(localPlayer)) {
@@ -519,8 +380,8 @@ public class RegionCommands {
sender.sendMessage(ChatColor.LIGHT_PURPLE + "Members: " + members.toUserFriendlyString());
}
final BlockVector min = region.getMinimumPoint();
final BlockVector max = region.getMaximumPoint();
final BlockVector min = region.getAABBMin();
final BlockVector max = region.getAABBMax();
sender.sendMessage(ChatColor.LIGHT_PURPLE + "Bounds:"
+ " (" + min.getBlockX() + "," + min.getBlockY() + "," + min.getBlockZ() + ")"
+ " (" + max.getBlockX() + "," + max.getBlockY() + "," + max.getBlockZ() + ")"
@@ -604,8 +465,8 @@ public class RegionCommands {
world = plugin.checkPlayer(sender).getWorld();
}
final RegionManager mgr = plugin.getGlobalRegionManager().get(world);
final Map<String, ProtectedRegion> regions = mgr.getRegions();
final RegionIndex mgr = plugin.getGlobalRegionManager().get(world);
final Map<String, Region> regions = mgr.getRegions();
List<RegionEntry> regionEntries = new ArrayList<RegionEntry>();
int index = 0;
@@ -652,11 +513,11 @@ public class RegionCommands {
@Command(aliases = {"flag", "f"}, usage = "<id> <flag> [-g group] [value]", flags = "g:",
desc = "Set flags", min = 2)
public void flag(CommandContext args, CommandSender sender) throws CommandException {
Player player = plugin.checkPlayer(sender);
World world = player.getWorld();
LocalPlayer localPlayer = plugin.wrapPlayer(player);
String id = args.getString(0);
String flagName = args.getString(1);
String value = null;
@@ -666,8 +527,8 @@ public class RegionCommands {
value = args.getJoinedStrings(2);
}
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ProtectedRegion region = mgr.getRegion(id);
RegionIndex mgr = plugin.getGlobalRegionManager().get(world);
Region region = mgr.getRegion(id);
if (region == null) {
if (id.equalsIgnoreCase("__global__")) {
@@ -691,9 +552,9 @@ public class RegionCommands {
else if (plugin.hasPermission(sender, "worldguard.region.flag.regions." + id.toLowerCase())) hasPerm = true;
}
if (!hasPerm) throw new CommandPermissionsException();
Flag<?> foundFlag = null;
// Now time to find the flag!
for (Flag<?> flag : DefaultFlag.getFlags()) {
// Try to detect the flag
@@ -702,10 +563,10 @@ public class RegionCommands {
break;
}
}
if (foundFlag == null) {
StringBuilder list = new StringBuilder();
// Need to build a list
for (Flag<?> flag : DefaultFlag.getFlags()) {
if (list.length() > 0) {
@@ -730,8 +591,8 @@ public class RegionCommands {
+ flag.getName() + "." + id.toLowerCase())) {
continue;
}
}
}
list.append(flag.getName());
}
@@ -817,29 +678,29 @@ public class RegionCommands {
+ e.getMessage());
}
}
public <V> void setFlag(ProtectedRegion region,
public <V> void setFlag(Region region,
Flag<V> flag, CommandSender sender, String value)
throws InvalidFlagFormat {
region.setFlag(flag, flag.parseInput(plugin, sender, value));
}
@Command(aliases = {"setpriority", "priority", "pri"}, usage = "<id> <priority>",
desc = "Set the priority of a region", min = 2, max = 2)
public void setPriority(CommandContext args, CommandSender sender) throws CommandException {
Player player = plugin.checkPlayer(sender);
World world = player.getWorld();
LocalPlayer localPlayer = plugin.wrapPlayer(player);
String id = args.getString(0);
int priority = args.getInteger(1);
if (id.equalsIgnoreCase("__global__")) {
throw new CommandException("The region cannot be named __global__");
}
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ProtectedRegion region = mgr.getRegion(id);
RegionIndex mgr = plugin.getGlobalRegionManager().get(world);
Region region = mgr.getRegion(id);
if (region == null) {
throw new CommandException("Could not find a region by that ID.");
}
@@ -852,14 +713,14 @@ public class RegionCommands {
plugin.checkPermission(sender, "worldguard.region.setpriority.member." + id.toLowerCase());
} else {
plugin.checkPermission(sender, "worldguard.region.setpriority." + id.toLowerCase());
}
}
region.setPriority(priority);
sender.sendMessage(ChatColor.YELLOW
+ "Priority of '" + region.getId() + "' set to "
+ priority + ".");
try {
mgr.save();
} catch (ProtectionDatabaseException e) {
@@ -867,22 +728,22 @@ public class RegionCommands {
+ e.getMessage());
}
}
@Command(aliases = {"setparent", "parent", "par"}, usage = "<id> [parent-id]",
desc = "Set the parent of a region", min = 1, max = 2)
public void setParent(CommandContext args, CommandSender sender) throws CommandException {
Player player = plugin.checkPlayer(sender);
World world = player.getWorld();
LocalPlayer localPlayer = plugin.wrapPlayer(player);
String id = args.getString(0);
if (id.equalsIgnoreCase("__global__")) {
throw new CommandException("The region cannot be named __global__");
}
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ProtectedRegion region = mgr.getRegion(id);
RegionIndex mgr = plugin.getGlobalRegionManager().get(world);
Region region = mgr.getRegion(id);
if (region == null) {
throw new CommandException("Could not find a target region by that ID.");
}
@@ -894,25 +755,25 @@ public class RegionCommands {
region.setParent(null);
} catch (CircularInheritanceException ignore) {
}
sender.sendMessage(ChatColor.YELLOW
+ "Parent of '" + region.getId() + "' cleared.");
} else {
String parentId = args.getString(1);
ProtectedRegion parent = mgr.getRegion(parentId);
Region parent = mgr.getRegion(parentId);
if (parent == null) {
throw new CommandException("Could not find the parent region by that ID.");
}
if (region.isOwner(localPlayer)) {
plugin.checkPermission(sender, "worldguard.region.setparent.own." + id.toLowerCase());
} else if (region.isMember(localPlayer)) {
plugin.checkPermission(sender, "worldguard.region.setparent.member." + id.toLowerCase());
} else {
plugin.checkPermission(sender, "worldguard.region.setparent." + id.toLowerCase());
}
}
if (parent.isOwner(localPlayer)) {
plugin.checkPermission(sender, "worldguard.region.setparent.own." + parentId.toLowerCase());
} else if (parent.isMember(localPlayer)) {
@@ -920,18 +781,18 @@ public class RegionCommands {
} else {
plugin.checkPermission(sender, "worldguard.region.setparent." + parentId.toLowerCase());
}
try {
region.setParent(parent);
} catch (CircularInheritanceException e) {
throw new CommandException("Circular inheritance detected!");
}
sender.sendMessage(ChatColor.YELLOW
+ "Parent of '" + region.getId() + "' set to '"
+ parent.getId() + "'.");
}
try {
mgr.save();
} catch (ProtectionDatabaseException e) {
@@ -939,24 +800,24 @@ public class RegionCommands {
+ e.getMessage());
}
}
@Command(aliases = {"remove", "delete", "del", "rem"}, usage = "<id>",
desc = "Remove a region", min = 1, max = 1)
public void remove(CommandContext args, CommandSender sender) throws CommandException {
Player player = plugin.checkPlayer(sender);
World world = player.getWorld();
LocalPlayer localPlayer = plugin.wrapPlayer(player);
String id = args.getString(0);
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ProtectedRegion region = mgr.getRegionExact(id);
RegionIndex mgr = plugin.getGlobalRegionManager().get(world);
Region region = mgr.getRegionExact(id);
if (region == null) {
throw new CommandException("Could not find a region by that ID.");
}
if (region.isOwner(localPlayer)) {
plugin.checkPermission(sender, "worldguard.region.remove.own." + id.toLowerCase());
} else if (region.isMember(localPlayer)) {
@@ -964,12 +825,12 @@ public class RegionCommands {
} else {
plugin.checkPermission(sender, "worldguard.region.remove." + id.toLowerCase());
}
mgr.removeRegion(id);
sender.sendMessage(ChatColor.YELLOW
+ "Region '" + id + "' removed.");
try {
mgr.save();
} catch (ProtectionDatabaseException e) {
@@ -977,21 +838,21 @@ public class RegionCommands {
+ e.getMessage());
}
}
@Command(aliases = {"load", "reload"}, usage = "[world]",
desc = "Reload regions from file", max = 1)
@CommandPermissions({"worldguard.region.load"})
public void load(CommandContext args, CommandSender sender) throws CommandException {
World world = null;
if (args.argsLength() > 0) {
world = plugin.matchWorld(sender, args.getString(0));
}
if (world != null) {
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
RegionIndex mgr = plugin.getGlobalRegionManager().get(world);
try {
mgr.load();
sender.sendMessage(ChatColor.YELLOW
@@ -1002,8 +863,8 @@ public class RegionCommands {
}
} else {
for (World w : plugin.getServer().getWorlds()) {
RegionManager mgr = plugin.getGlobalRegionManager().get(w);
RegionIndex mgr = plugin.getGlobalRegionManager().get(w);
try {
mgr.load();
} catch (ProtectionDatabaseException e) {
@@ -1011,26 +872,26 @@ public class RegionCommands {
+ e.getMessage());
}
}
sender.sendMessage(ChatColor.YELLOW
+ "Region databases loaded.");
}
}
@Command(aliases = {"save", "write"}, usage = "[world]",
desc = "Re-save regions to file", max = 1)
@CommandPermissions({"worldguard.region.save"})
public void save(CommandContext args, CommandSender sender) throws CommandException {
World world = null;
if (args.argsLength() > 0) {
world = plugin.matchWorld(sender, args.getString(0));
}
if (world != null) {
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
RegionIndex mgr = plugin.getGlobalRegionManager().get(world);
try {
mgr.save();
sender.sendMessage(ChatColor.YELLOW
@@ -1041,8 +902,8 @@ public class RegionCommands {
}
} else {
for (World w : plugin.getServer().getWorlds()) {
RegionManager mgr = plugin.getGlobalRegionManager().get(w);
RegionIndex mgr = plugin.getGlobalRegionManager().get(w);
try {
mgr.save();
} catch (ProtectionDatabaseException e) {
@@ -1050,74 +911,24 @@ public class RegionCommands {
+ e.getMessage());
}
}
sender.sendMessage(ChatColor.YELLOW
+ "Region databases saved.");
}
}
@Command(aliases = {"migratedb"}, usage = "<from> <to>",
desc = "Migrate from one Protection Database to another.", min = 1)
@CommandPermissions({"worldguard.region.migratedb"})
public void migratedb(CommandContext args, CommandSender sender) throws CommandException {
String from = args.getString(0).toLowerCase().trim();
String to = args.getString(1).toLowerCase().trim();
if (from.equals(to)) {
throw new CommandException("Will not migrate with common source and target.");
}
Map<MigratorKey, Class<? extends AbstractDatabaseMigrator>> migrators = AbstractDatabaseMigrator.getMigrators();
MigratorKey key = new MigratorKey(from,to);
if (!migrators.containsKey(key)) {
throw new CommandException("No migrator found for that combination and direction.");
}
long lastRequest = 10000000;
if (this.migrateDBRequestDate != null) {
lastRequest = new Date().getTime() - this.migrateDBRequestDate.getTime();
}
if (this.migrateDBRequest == null || lastRequest > 60000) {
this.migrateDBRequest = key;
this.migrateDBRequestDate = new Date();
throw new CommandException("This command is potentially dangerous.\n" +
"Please ensure you have made a backup of your data, and then re-enter the command exactly to procede.");
}
Class<? extends AbstractDatabaseMigrator> cls = migrators.get(key);
try {
AbstractDatabaseMigrator migrator = cls.getConstructor(WorldGuardPlugin.class).newInstance(plugin);
migrator.migrate();
} catch (IllegalArgumentException ignore) {
} catch (SecurityException ignore) {
} catch (InstantiationException ignore) {
} catch (IllegalAccessException ignore) {
} catch (InvocationTargetException ignore) {
} catch (NoSuchMethodException ignore) {
} catch (MigrationException e) {
throw new CommandException("Error migrating database: " + e.getMessage());
}
sender.sendMessage(ChatColor.YELLOW + "Regions have been migrated successfully.\n" +
"If you wish to use the destination format as your new backend, please update your config and reload WorldGuard.");
}
@Command(aliases = {"teleport", "tp"}, usage = "<id>", flags = "s",
desc = "Teleports you to the location associated with the region.", min = 1, max = 1)
@CommandPermissions({"worldguard.region.teleport"})
public void teleport(CommandContext args, CommandSender sender) throws CommandException {
final Player player = plugin.checkPlayer(sender);
final RegionManager mgr = plugin.getGlobalRegionManager().get(player.getWorld());
final RegionIndex mgr = plugin.getGlobalRegionManager().get(player.getWorld());
String id = args.getString(0);
final ProtectedRegion region = mgr.getRegion(id);
final Region region = mgr.getRegion(id);
if (region == null) {
if (!ProtectedRegion.isValidId(id)) {
if (!Region.isValidId(id)) {
throw new CommandException("Invalid region ID specified!");
}
throw new CommandException("A region with ID '" + id + "' doesn't exist.");
@@ -30,11 +30,11 @@ import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
import com.sk89q.worldguard.protection.databases.RegionDBUtil;
import com.sk89q.worldguard.region.Region;
import com.sk89q.worldguard.region.flags.DefaultFlag;
import com.sk89q.worldguard.region.indices.RegionIndex;
import com.sk89q.worldguard.region.stores.ProtectionDatabaseException;
import com.sk89q.worldguard.region.stores.RegionDBUtil;
// @TODO: A lot of code duplication here! Need to fix.
@@ -55,8 +55,8 @@ public class RegionMemberCommands {
String id = args.getString(0);
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ProtectedRegion region = mgr.getRegion(id);
RegionIndex mgr = plugin.getGlobalRegionManager().get(world);
Region region = mgr.getRegion(id);
if (region == null) {
throw new CommandException("Could not find a region by that ID.");
@@ -95,8 +95,8 @@ public class RegionMemberCommands {
String id = args.getString(0);
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ProtectedRegion region = mgr.getRegion(id);
RegionIndex mgr = plugin.getGlobalRegionManager().get(world);
Region region = mgr.getRegion(id);
if (region == null) {
throw new CommandException("Could not find a region by that ID.");
@@ -148,8 +148,8 @@ public class RegionMemberCommands {
String id = args.getString(0);
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ProtectedRegion region = mgr.getRegion(id);
RegionIndex mgr = plugin.getGlobalRegionManager().get(world);
Region region = mgr.getRegion(id);
if (region == null) {
throw new CommandException("Could not find a region by that ID.");
@@ -189,8 +189,8 @@ public class RegionMemberCommands {
String id = args.getString(0);
RegionManager mgr = plugin.getGlobalRegionManager().get(world);
ProtectedRegion region = mgr.getRegion(id);
RegionIndex mgr = plugin.getGlobalRegionManager().get(world);
Region region = mgr.getRegion(id);
if (region == null) {
throw new CommandException("Could not find a region by that ID.");
@@ -123,7 +123,7 @@ public class EntityCriteria implements Criteria<BukkitContext> {
}
}
if (types.size() == 0) {
if (types.size() != 0) {
matched = types.contains(entity.getType());
if (!matched) {
@@ -0,0 +1,113 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.definitions;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import com.sk89q.rulelists.Criteria;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.bukkit.BukkitContext;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.resolvers.BlockResolver;
import com.sk89q.worldguard.bukkit.resolvers.EntityResolver;
import com.sk89q.worldguard.region.ApplicableRegionSet;
import com.sk89q.worldguard.region.flags.DefaultFlag;
import com.sk89q.worldguard.region.flags.StateFlag;
public class FlagCriteria implements Criteria<BukkitContext> {
private final WorldGuardPlugin plugin;
private final StateFlag flag;
private BlockResolver blockResolver;
private EntityResolver entityResolver;
public FlagCriteria(WorldGuardPlugin plugin, StateFlag flag) {
this.plugin = plugin;
this.flag = flag;
}
public BlockResolver getBlockResolver() {
return blockResolver;
}
public void setBlockResolver(BlockResolver blockResolver) {
this.blockResolver = blockResolver;
}
public EntityResolver getEntityResolver() {
return entityResolver;
}
public void setEntityResolver(EntityResolver entityResolver) {
this.entityResolver = entityResolver;
}
@Override
public boolean matches(BukkitContext context) {
boolean matches = false;
ApplicableRegionSet set = context.getApplicableRegionSet();
if (set == null) {
return false;
}
if (blockResolver != null) {
BlockState block = blockResolver.resolve(context);
if (block == null) {
return false;
}
if (flag == DefaultFlag.BUILD) {
matches = false;
} else {
matches = set.allows(flag);
}
if (!matches) {
return false;
}
}
if (entityResolver != null) {
Entity entity = entityResolver.resolve(context);
if (entity == null) {
return false;
}
LocalPlayer localPlayer = null;
if (entity instanceof Player) {
localPlayer = plugin.wrapPlayer((Player) entity);
}
if (flag == DefaultFlag.BUILD) {
matches = localPlayer != null && set.canBuild(localPlayer);
} else {
matches = set.allows(flag, localPlayer);
}
}
return matches;
}
}
@@ -0,0 +1,83 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.definitions;
import com.sk89q.rebar.config.AbstractNodeLoader;
import com.sk89q.rebar.config.ConfigurationNode;
import com.sk89q.rebar.config.LoaderBuilderException;
import com.sk89q.rebar.config.types.StaticFieldLoaderBuilder;
import com.sk89q.rebar.util.LoggerUtils;
import com.sk89q.rulelists.DefinitionException;
import com.sk89q.rulelists.RuleListUtils;
import com.sk89q.rulelists.RuleListsManager;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.bukkit.resolvers.BlockResolver;
import com.sk89q.worldguard.bukkit.resolvers.EntityResolver;
import com.sk89q.worldguard.region.flags.DefaultFlag;
import com.sk89q.worldguard.region.flags.StateFlag;
public class FlagCriteriaLoader extends AbstractNodeLoader<FlagCriteria> {
private final WorldGuardPlugin plugin;
private final RuleListsManager manager;
private final StaticFieldLoaderBuilder<StateFlag> stateFlagLoader =
new StaticFieldLoaderBuilder<StateFlag>(DefaultFlag.class, StateFlag.class);
public FlagCriteriaLoader(WorldGuardPlugin plugin, RuleListsManager manager) {
this.plugin = plugin;
this.manager = manager;
}
@Override
public FlagCriteria read(ConfigurationNode node)
throws DefinitionException {
BlockResolver blockResolver = null;
EntityResolver entityResolver = null;
String entity = node.getString("entity");
String block = node.getString("block");
if (block != null) {
blockResolver = manager.getResolvers().get(BlockResolver.class, block);
}
if (entity != null) {
entityResolver = manager.getResolvers().get(EntityResolver.class, entity);
}
if (block == null && entity == null) {
throw new LoaderBuilderException("Flag criteria needs either a block resolver or an entity resolver");
}
StateFlag flag = node.getOf("flag", stateFlagLoader);
if (flag == null) {
throw new LoaderBuilderException("A flag must be specified");
}
FlagCriteria criteria = new FlagCriteria(plugin, flag);
criteria.setBlockResolver(blockResolver);
criteria.setEntityResolver(entityResolver);
RuleListUtils.warnUnknown(node, LoggerUtils.getLogger(getClass()),
"flag", "block", "entity");
return criteria;
}
}
@@ -0,0 +1,92 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.definitions;
import org.bukkit.block.BlockState;
import org.bukkit.entity.Entity;
import com.sk89q.rulelists.Criteria;
import com.sk89q.worldguard.bukkit.BukkitContext;
import com.sk89q.worldguard.bukkit.resolvers.BlockResolver;
import com.sk89q.worldguard.bukkit.resolvers.EntityResolver;
import com.sk89q.worldguard.region.ApplicableRegionSet;
public class RegionCriteria implements Criteria<BukkitContext> {
private BlockResolver blockResolver;
private EntityResolver entityResolver;
public BlockResolver getBlockResolver() {
return blockResolver;
}
public void setBlockResolver(BlockResolver blockResolver) {
this.blockResolver = blockResolver;
}
public EntityResolver getEntityResolver() {
return entityResolver;
}
public void setEntityResolver(EntityResolver entityResolver) {
this.entityResolver = entityResolver;
}
@Override
public boolean matches(BukkitContext context) {
boolean matches = false;
if (blockResolver != null) {
BlockState block = blockResolver.resolve(context);
if (block == null) {
return false;
}
ApplicableRegionSet set = context.getRegionQuery().lookup(block.getBlock());
if (set == null) {
return false;
}
context.setApplicableRegionSet(set);
matches = true;
}
if (entityResolver != null) {
Entity entity = entityResolver.resolve(context);
if (entity == null) {
return false;
}
ApplicableRegionSet set = context.getRegionQuery().lookup(entity);
if (set == null) {
return false;
}
context.setApplicableRegionSet(set);
matches = true;
}
return matches;
}
}
@@ -0,0 +1,70 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.bukkit.definitions;
import com.sk89q.rebar.config.AbstractNodeLoader;
import com.sk89q.rebar.config.ConfigurationNode;
import com.sk89q.rebar.config.LoaderBuilderException;
import com.sk89q.rebar.util.LoggerUtils;
import com.sk89q.rulelists.DefinitionException;
import com.sk89q.rulelists.RuleListUtils;
import com.sk89q.rulelists.RuleListsManager;
import com.sk89q.worldguard.bukkit.resolvers.BlockResolver;
import com.sk89q.worldguard.bukkit.resolvers.EntityResolver;
public class RegionCriteriaLoader extends AbstractNodeLoader<RegionCriteria> {
private final RuleListsManager manager;
public RegionCriteriaLoader(RuleListsManager manager) {
this.manager = manager;
}
@Override
public RegionCriteria read(ConfigurationNode node)
throws DefinitionException {
BlockResolver blockResolver = null;
EntityResolver entityResolver = null;
String entity = node.getString("entity");
String block = node.getString("block");
if (block != null) {
blockResolver = manager.getResolvers().get(BlockResolver.class, block);
}
if (entity != null) {
entityResolver = manager.getResolvers().get(EntityResolver.class, entity);
}
if (block == null && entity == null) {
throw new LoaderBuilderException("Region criteria needs either a block resolver or an entity resolver");
}
RegionCriteria criteria = new RegionCriteria();
criteria.setBlockResolver(blockResolver);
criteria.setEntityResolver(entityResolver);
RuleListUtils.warnUnknown(node, LoggerUtils.getLogger(getClass()),
"block", "entity");
return criteria;
}
}
@@ -1,77 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.chest;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
/**
* Interface for chest protection.
*/
public interface ChestProtection {
/**
* Returns whether a block is protected.
*
* @param block The block to check
* @param player The player to check
* @return Whether the block is protected for player
*/
public boolean isProtected(Block block, Player player);
/**
* Returns whether a location where a chest block is trying to be created
* is protected.
*
* @param block The block to check
* @param player The player to check
* @return Whether {@code player} can place a block at the specified block
*/
public boolean isProtectedPlacement(Block block, Player player);
/**
* Returns whether an adjacent chest is protected.
*
* @param searchBlock The block to check
* @param player The player to check
* @return Whether {@code searchBlock} is protected from access by {@code player}
*/
public boolean isAdjacentChestProtected(Block searchBlock, Player player);
/**
* Returns whether a material is a chest.
*
* @param material The material to check
* @deprecated see {@link #isChest(int)}
* @return {@link #isChest(int)}
*/
@Deprecated
public boolean isChest(Material material);
/**
* Returns whether a material is a chest.
*
* @param type The type to check
* @return Whether type is a 'chest' (block that can be protected)
*/
public boolean isChest(int type);
}
@@ -1,159 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.chest;
import com.sk89q.worldedit.blocks.BlockID;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.bukkit.block.Sign;
import org.bukkit.entity.Player;
/**
* Sign-based chest protection.
*
* @author sk89q
*/
public class SignChestProtection implements ChestProtection {
public boolean isProtected(Block block, Player player) {
if (isChest(block.getTypeId())) {
Block below = block.getRelative(0, -1, 0);
return isProtectedSignAround(below, player);
} else if (block.getTypeId() == BlockID.SIGN_POST) {
return isProtectedSignAndChestBinary(block, player);
} else {
Block above = block.getRelative(0, 1, 0);
Boolean res = isProtectedSign(above, player);
if (res != null) return res;
return false;
}
}
public boolean isProtectedPlacement(Block block, Player player) {
return isProtectedSignAround(block, player);
}
private boolean isProtectedSignAround(Block searchBlock, Player player) {
Block side;
Boolean res;
side = searchBlock;
res = isProtectedSign(side, player);
if (res != null && res) return res;
side = searchBlock.getRelative(-1, 0, 0);
res = isProtectedSignAndChest(side, player);
if (res != null && res) return res;
side = searchBlock.getRelative(1, 0, 0);
res = isProtectedSignAndChest(side, player);
if (res != null && res) return res;
side = searchBlock.getRelative(0, 0, -1);
res = isProtectedSignAndChest(side, player);
if (res != null && res) return res;
side = searchBlock.getRelative(0, 0, 1);
res = isProtectedSignAndChest(side, player);
if (res != null && res) return res;
return false;
}
private Boolean isProtectedSign(Sign sign, Player player) {
if (sign.getLine(0).equalsIgnoreCase("[Lock]")) {
if (player == null) { // No player, no access
return true;
}
String name = player.getName();
if (name.equalsIgnoreCase(sign.getLine(1).trim())
|| name.equalsIgnoreCase(sign.getLine(2).trim())
|| name.equalsIgnoreCase(sign.getLine(3).trim())) {
return false;
}
// No access!
return true;
}
return null;
}
private Boolean isProtectedSign(Block block, Player player) {
BlockState state = block.getState();
if (state == null || !(state instanceof Sign)) {
return null;
}
return isProtectedSign((Sign) state, player);
}
private Boolean isProtectedSignAndChest(Block block, Player player) {
if (!isChest(block.getRelative(0, 1, 0).getTypeId())) {
return null;
}
return isProtectedSign(block, player);
}
private boolean isProtectedSignAndChestBinary(Block block, Player player) {
Boolean res = isProtectedSignAndChest(block, player);
return !(res == null || !res);
}
public boolean isAdjacentChestProtected(Block searchBlock, Player player) {
Block side;
Boolean res;
side = searchBlock;
res = isProtected(side, player);
if (res != null && res) return res;
side = searchBlock.getRelative(-1, 0, 0);
res = isProtected(side, player);
if (res != null && res) return res;
side = searchBlock.getRelative(1, 0, 0);
res = isProtected(side, player);
if (res != null && res) return res;
side = searchBlock.getRelative(0, 0, -1);
res = isProtected(side, player);
if (res != null && res) return res;
side = searchBlock.getRelative(0, 0, 1);
res = isProtected(side, player);
if (res != null && res) return res;
return false;
}
@Deprecated
public boolean isChest(Material material) {
return isChest(material.getId());
}
public boolean isChest(int type) {
return type == BlockID.CHEST
|| type == BlockID.DISPENSER
|| type == BlockID.FURNACE
|| type == BlockID.BURNING_FURNACE;
}
}
@@ -1,138 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.domains;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import com.sk89q.worldguard.LocalPlayer;
public class DefaultDomain implements Domain {
private Set<String> groups;
private Set<String> players;
public DefaultDomain() {
this.groups = new LinkedHashSet<String>();
this.players = new HashSet<String>();
}
public void addPlayer(String name) {
players.add(name.toLowerCase());
}
public void addPlayer(LocalPlayer player) {
players.add(player.getName().toLowerCase());
}
public void removePlayer(String name) {
players.remove(name.toLowerCase());
}
public void removePlayer(LocalPlayer player) {
players.remove(player.getName().toLowerCase());
}
public void addGroup(String name) {
groups.add(name.toLowerCase());
}
public void removeGroup(String name) {
groups.remove(name.toLowerCase());
}
public Set<String> getGroups() {
return groups;
}
public Set<String> getPlayers() {
return players;
}
@Override
public boolean contains(LocalPlayer player) {
if (contains(player.getName())) {
return true;
}
for (String group : groups) {
if (player.hasGroup(group)) {
return true;
}
}
return false;
}
@Override
public boolean contains(String playerName) {
return players.contains(playerName.toLowerCase());
}
public int size() {
return groups.size() + players.size();
}
public String toPlayersString() {
StringBuilder str = new StringBuilder();
List<String> output = new ArrayList<String>(players);
Collections.sort(output, String.CASE_INSENSITIVE_ORDER);
for (Iterator<String> it = output.iterator(); it.hasNext();) {
str.append(it.next());
if (it.hasNext()) {
str.append(", ");
}
}
return str.toString();
}
public String toGroupsString() {
StringBuilder str = new StringBuilder();
for (Iterator<String> it = groups.iterator(); it.hasNext(); ) {
str.append("*");
str.append(it.next());
if (it.hasNext()) {
str.append(", ");
}
}
return str.toString();
}
public String toUserFriendlyString() {
StringBuilder str = new StringBuilder();
if (players.size() > 0) {
str.append(toPlayersString());
}
if (groups.size() > 0) {
if (str.length() > 0) {
str.append("; ");
}
str.append(toGroupsString());
}
return str.toString();
}
}
@@ -1,22 +0,0 @@
package com.sk89q.worldguard.domains;
import com.sk89q.worldguard.LocalPlayer;
public interface Domain {
/**
* Returns true if a domain contains a player.
*
* @param player The player to check
* @return whether this domain contains {@code player}
*/
boolean contains(LocalPlayer player);
/**
* Returns true if a domain contains a player.<br />
* This method doesn't check for groups!
*
* @param playerName The name of the player to check
* @return whether this domain contains a player by that name
*/
boolean contains(String playerName);
}
@@ -1,67 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.domains;
import java.util.LinkedHashSet;
import java.util.Set;
import com.sk89q.worldguard.LocalPlayer;
public class DomainCollection implements Domain {
private Set<Domain> domains;
public DomainCollection() {
domains = new LinkedHashSet<Domain>();
}
public void add(Domain domain) {
domains.add(domain);
}
public void remove(Domain domain) {
domains.remove(domain);
}
public int size() {
return domains.size();
}
@Override
public boolean contains(LocalPlayer player) {
for (Domain domain : domains) {
if (domain.contains(player)) {
return true;
}
}
return false;
}
@Override
public boolean contains(String playerName) {
for (Domain domain : domains) {
if (domain.contains(playerName)) {
return true;
}
}
return false;
}
}
@@ -1,61 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.domains;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import com.sk89q.worldguard.LocalPlayer;
public class GroupDomain implements Domain {
private Set<String> groups;
public GroupDomain() {
this.groups = new LinkedHashSet<String>();
}
public GroupDomain(String[] groups) {
this.groups = new LinkedHashSet<String>(Arrays.asList(groups));
}
public void addGroup(String name) {
groups.add(name);
}
public boolean contains(LocalPlayer player) {
for (String group : groups) {
if (player.hasGroup(group)) {
return true;
}
}
return false;
}
@Override
public boolean contains(String playerName) {
return false; // GroupDomains can't contain player names.
}
public int size() {
return groups.size();
}
}
@@ -1,58 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.domains;
import java.util.HashSet;
import java.util.Set;
import com.sk89q.worldguard.LocalPlayer;
public class PlayerDomain implements Domain {
private Set<String> players;
public PlayerDomain() {
this.players = new HashSet<String>();
}
public PlayerDomain(String[] players) {
this.players = new HashSet<String>();
for (String name : players) {
this.players.add(name.toLowerCase());
}
}
public void addPlayer(String name) {
players.add(name.toLowerCase());
}
public boolean contains(LocalPlayer player) {
return contains(player.getName());
}
@Override
public boolean contains(String playerName) {
return players.contains(playerName.toLowerCase());
}
public int size() {
return players.size();
}
}
@@ -1,402 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.flags.*;
import com.sk89q.worldguard.protection.flags.StateFlag.State;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import java.util.*;
/**
* Represents a set of regions for a particular point or area and the rules
* that are represented by that set. An instance of this can be used to
* query the value of a flag or check if a player can build in the respective
* region or point. This object contains the list of applicable regions and so
* the expensive search of regions that are in the desired area has already
* been completed.
*
* @author sk89q
*/
public class ApplicableRegionSet implements Iterable<ProtectedRegion> {
private Collection<ProtectedRegion> applicable;
private ProtectedRegion globalRegion;
/**
* Construct the object.
*
* @param applicable The regions contained in this set
* @param globalRegion The global region, set aside for special handling.
*/
public ApplicableRegionSet(Collection<ProtectedRegion> applicable,
ProtectedRegion globalRegion) {
this.applicable = applicable;
this.globalRegion = globalRegion;
}
/**
* Checks if a player can build in an area.
*
* @param player The player to chec
* @return build ability
*/
public boolean canBuild(LocalPlayer player) {
return internalGetState(DefaultFlag.BUILD, player, null);
}
public boolean canConstruct(LocalPlayer player) {
final RegionGroup flag = getFlag(DefaultFlag.CONSTRUCT, player);
return RegionGroupFlag.isMember(this, flag, player);
}
/**
* Checks if a player can use buttons and such in an area.
*
* @param player The player to check
* @return able to use items
* @deprecated This method seems to be the opposite of its name
*/
@Deprecated
public boolean canUse(LocalPlayer player) {
return !allows(DefaultFlag.USE, player)
&& !canBuild(player);
}
/**
* Gets the state of a state flag. This cannot be used for the build flag.
*
* @param flag flag to check
* @return whether it is allowed
* @throws IllegalArgumentException if the build flag is given
*/
public boolean allows(StateFlag flag) {
if (flag == DefaultFlag.BUILD) {
throw new IllegalArgumentException("Can't use build flag with allows()");
}
return internalGetState(flag, null, null);
}
/**
* Gets the state of a state flag. This cannot be used for the build flag.
*
* @param flag flag to check
* @param player player (used by some flags)
* @return whether the state is allows for it
* @throws IllegalArgumentException if the build flag is given
*/
public boolean allows(StateFlag flag, LocalPlayer player) {
if (flag == DefaultFlag.BUILD) {
throw new IllegalArgumentException("Can't use build flag with allows()");
}
return internalGetState(flag, null, player);
}
/**
* Indicates whether a player is an owner of all regions in this set.
*
* @param player player
* @return whether the player is an owner of all regions
*/
public boolean isOwnerOfAll(LocalPlayer player) {
for (ProtectedRegion region : applicable) {
if (!region.isOwner(player)) {
return false;
}
}
return true;
}
/**
* Indicates whether a player is an owner or member of all regions in
* this set.
*
* @param player player
* @return whether the player is a member of all regions
*/
public boolean isMemberOfAll(LocalPlayer player) {
for (ProtectedRegion region : applicable) {
if (!region.isMember(player)) {
return false;
}
}
return true;
}
/**
* Checks to see if a flag is permitted.
*
* @param flag flag to check
* @param player null to not check owners and members
* @param groupPlayer player to use for the group flag check
* @return the allow/deny state for the flag
*/
private boolean internalGetState(StateFlag flag, LocalPlayer player,
LocalPlayer groupPlayer) {
boolean found = false;
boolean hasFlagDefined = false;
boolean allowed = false; // Used for ALLOW override
boolean def = flag.getDefault();
// Handle defaults
if (globalRegion != null) {
State globalState = globalRegion.getFlag(flag);
// The global region has this flag set
if (globalState != null) {
// Build flag is very special
if (player != null && globalRegion.hasMembersOrOwners()) {
def = globalRegion.isMember(player) && (globalState == State.ALLOW);
} else {
def = (globalState == State.ALLOW);
}
} else {
// Build flag is very special
if (player != null && globalRegion.hasMembersOrOwners()) {
def = globalRegion.isMember(player);
}
}
}
// The player argument is used if and only if the flag is the build
// flag -- in which case, if there are any regions in this area, we
// default to FALSE, otherwise true if there are no defined regions.
// However, other flags are different -- if there are regions defined,
// we default to the global region value.
if (player == null) {
allowed = def;
}
int lastPriority = Integer.MIN_VALUE;
// The algorithm is as follows:
// While iterating through the list of regions, if an entry disallows
// the flag, then put it into the needsClear set. If an entry allows
// the flag and it has a parent, then its parent is put into hasCleared.
// In the situation that the child is reached before the parent, upon
// the parent being reached, even if the parent disallows, because the
// parent will be in hasCleared, permission will be allowed. In the
// other case, where the parent is reached first, if it does not allow
// permissions, it will be placed into needsClear. If a child of
// the parent is reached later, the parent will be removed from
// needsClear. At the end, if needsClear is not empty, that means that
// permission should not be given. If a parent has multiple children
// and one child does not allow permissions, then it will be placed into
// needsClear just like as if was a parent.
Set<ProtectedRegion> needsClear = new HashSet<ProtectedRegion>();
Set<ProtectedRegion> hasCleared = new HashSet<ProtectedRegion>();
for (ProtectedRegion region : applicable) {
// Ignore lower priority regions
if (hasFlagDefined && region.getPriority() < lastPriority) {
break;
}
lastPriority = region.getPriority();
// Ignore non-build regions
if (player != null
&& region.getFlag(DefaultFlag.PASSTHROUGH) == State.ALLOW) {
continue;
}
// Check group permissions
if (groupPlayer != null && flag.getRegionGroupFlag() != null) {
RegionGroup group = region.getFlag(flag.getRegionGroupFlag());
if (group == null) {
group = flag.getRegionGroupFlag().getDefault();
}
if (!RegionGroupFlag.isMember(region, group, groupPlayer)) {
continue;
}
}
State v = region.getFlag(flag);
// Allow DENY to override everything
if (v == State.DENY) {
return false;
}
// Forget about regions that allow it, although make sure the
// default state is now to allow
if (v == State.ALLOW) {
allowed = true;
found = true;
hasFlagDefined = true;
continue;
}
// For the build flag, the flags are conditional and are based
// on membership, so we have to check for parent-child
// relationships
if (player != null) {
hasFlagDefined = true;
if (hasCleared.contains(region)) {
// Already cleared, so do nothing
} else {
if (!region.isMember(player)) {
needsClear.add(region);
} else {
// Need to clear all parents
clearParents(needsClear, hasCleared, region);
}
}
}
found = true;
}
return !found ? def :
(allowed || (player != null && needsClear.size() == 0));
}
/**
* Clear a region's parents for isFlagAllowed().
*
* @param needsClear The regions that should be cleared
* @param hasCleared The regions already cleared
* @param region The region to start from
*/
private void clearParents(Set<ProtectedRegion> needsClear,
Set<ProtectedRegion> hasCleared, ProtectedRegion region) {
ProtectedRegion parent = region.getParent();
while (parent != null) {
if (!needsClear.remove(parent)) {
hasCleared.add(parent);
}
parent = parent.getParent();
}
}
/**
* @see #getFlag(com.sk89q.worldguard.protection.flags.Flag, com.sk89q.worldguard.LocalPlayer)
* @param flag flag to check
* @return value of the flag
*/
public <T extends Flag<V>, V> V getFlag(T flag) {
return getFlag(flag, null);
}
/**
* Gets the value of a flag. Do not use this for state flags
* (use {@link #allows(StateFlag, LocalPlayer)} for that).
*
* @param flag flag to check
* @param groupPlayer player to check {@link RegionGroup}s against
* @return value of the flag
* @throws IllegalArgumentException if a StateFlag is given
*/
public <T extends Flag<V>, V> V getFlag(T flag, LocalPlayer groupPlayer) {
/*
if (flag instanceof StateFlag) {
throw new IllegalArgumentException("Cannot use StateFlag with getFlag()");
}
*/
int lastPriority = 0;
boolean found = false;
Map<ProtectedRegion, V> needsClear = new HashMap<ProtectedRegion, V>();
Set<ProtectedRegion> hasCleared = new HashSet<ProtectedRegion>();
for (ProtectedRegion region : applicable) {
// Ignore lower priority regions
if (found && region.getPriority() < lastPriority) {
break;
}
// Check group permissions
if (groupPlayer != null && flag.getRegionGroupFlag() != null) {
RegionGroup group = region.getFlag(flag.getRegionGroupFlag());
if (group == null) {
group = flag.getRegionGroupFlag().getDefault();
}
if (!RegionGroupFlag.isMember(region, group, groupPlayer)) {
continue;
}
}
if (hasCleared.contains(region)) {
// Already cleared, so do nothing
} else if (region.getFlag(flag) != null) {
clearParents(needsClear, hasCleared, region);
needsClear.put(region, region.getFlag(flag));
found = true;
}
lastPriority = region.getPriority();
}
try {
return needsClear.values().iterator().next();
} catch (NoSuchElementException e) {
if (globalRegion != null) {
V gFlag = globalRegion.getFlag(flag);
if (gFlag != null) return gFlag;
}
return null;
}
}
/**
* Clear a region's parents for getFlag().
*
* @param needsClear The regions that should be cleared
* @param hasCleared The regions already cleared
* @param region The region to start from
*/
private void clearParents(Map<ProtectedRegion, ?> needsClear,
Set<ProtectedRegion> hasCleared, ProtectedRegion region) {
ProtectedRegion parent = region.getParent();
while (parent != null) {
if (needsClear.remove(parent) == null) {
hasCleared.add(parent);
}
parent = parent.getParent();
}
}
/**
* Get the number of regions that are included.
*
* @return the size of this ApplicbleRegionSet
*/
public int size() {
return applicable.size();
}
/**
* Get an iterator of affected regions.
*/
public Iterator<ProtectedRegion> iterator() {
return applicable.iterator();
}
}
@@ -1,62 +0,0 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection;
import java.util.WeakHashMap;
/**
* To facilitate performing regions-containing-point lookups from multiple stack frames
* but within the same context (the same event), a cache is important in preventing the
* need for redundant lookups made for the same point. This class serves as such a cache.
* <p>
* A key needs to be selected to store cache entries against. The best key is one that
* is highly temporal, and would represent a certain "snapshot in time," such as
* an event object. The event objects are indexed in this class using weak references,
* and they will be removed by the garbage collector automatically. Because it
* <em>is</em> a weak reference, the key object needs to be held somewhere with a strong
* reference until the "snapshot" ends.
* <p>
* This class is abstract because implementing class should provide methods to check
* against a standard key object. This cache itself is thread-safe.
*/
public abstract class RegionQueryCache {
private final WeakHashMap<Object, RegionQueryCacheEntry> cache =
new WeakHashMap<Object, RegionQueryCacheEntry>();
public RegionQueryCache() {
}
/**
* Get the {@link RegionQueryCacheEntry} object that will cache the
* {@link ApplicableRegionSet}s for this context.
*
* @param key a standard key to store by
* @return an existing QueryCacheEntry or a new one
*/
protected synchronized RegionQueryCacheEntry get(Object key) {
RegionQueryCacheEntry entry = cache.get(key);
if (entry == null) {
entry = new RegionQueryCacheEntry();
cache.put(key, entry);
}
return entry;
}
}
@@ -1,46 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.databases;
import com.sk89q.worldguard.protection.managers.RegionManager;
public abstract class AbstractProtectionDatabase implements ProtectionDatabase {
/**
* Load the list of regions into a region manager.
*
* @throws ProtectionDatabaseException
*/
public void load(RegionManager manager) throws ProtectionDatabaseException {
load();
manager.setRegions(getRegions());
}
/**
* Save the list of regions from a region manager.
*
* @throws ProtectionDatabaseException
*/
public void save(RegionManager manager) throws ProtectionDatabaseException {
setRegions(manager.getRegions());
save();
}
}
@@ -1,357 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.databases;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import au.com.bytecode.opencsv.CSVReader;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.flags.StateFlag.State;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
import com.sk89q.worldguard.util.ArrayReader;
/**
* Represents a protected area database that uses CSV files.
*
* @author sk89q
*/
public class CSVDatabase extends AbstractProtectionDatabase {
private static final Map<String, StateFlag> legacyFlagCodes = new HashMap<String, StateFlag>();
static {
legacyFlagCodes.put("z", DefaultFlag.PASSTHROUGH);
legacyFlagCodes.put("b", DefaultFlag.BUILD);
legacyFlagCodes.put("p", DefaultFlag.PVP);
legacyFlagCodes.put("m", DefaultFlag.MOB_DAMAGE);
legacyFlagCodes.put("c", DefaultFlag.CREEPER_EXPLOSION);
legacyFlagCodes.put("t", DefaultFlag.TNT);
legacyFlagCodes.put("l", DefaultFlag.LIGHTER);
legacyFlagCodes.put("f", DefaultFlag.FIRE_SPREAD);
legacyFlagCodes.put("F", DefaultFlag.LAVA_FIRE);
legacyFlagCodes.put("C", DefaultFlag.CHEST_ACCESS);
}
private final Logger logger;
/**
* References the CSV file.
*/
private final File file;
/**
* Holds the list of regions.
*/
private Map<String,ProtectedRegion> regions;
/**
* Construct the database with a path to a file. No file is read or
* written at this time.
*
* @param file The file in CSV format containing the region database
* @param logger The logger to log errors to
*/
public CSVDatabase(File file, Logger logger) {
this.file = file;
this.logger = logger;
}
/**
* Saves the database.
*/
public void save() throws ProtectionDatabaseException {
throw new UnsupportedOperationException("CSV format is no longer implemented");
}
public void load() throws ProtectionDatabaseException {
Map<String,ProtectedRegion> regions =
new HashMap<String,ProtectedRegion>();
Map<ProtectedRegion,String> parentSets =
new LinkedHashMap<ProtectedRegion, String>();
CSVReader reader = null;
try {
reader = new CSVReader(new FileReader(file));
String[] line;
while ((line = reader.readNext()) != null) {
if (line.length < 2) {
logger.warning("Invalid region definition: " + line);
continue;
}
String id = line[0].toLowerCase().replace(".", "");
String type = line[1];
ArrayReader<String> entries = new ArrayReader<String>(line);
if (type.equalsIgnoreCase("cuboid")) {
if (line.length < 8) {
logger.warning("Invalid region definition: " + line);
continue;
}
Vector pt1 = new Vector(
Integer.parseInt(line[2]),
Integer.parseInt(line[3]),
Integer.parseInt(line[4]));
Vector pt2 = new Vector(
Integer.parseInt(line[5]),
Integer.parseInt(line[6]),
Integer.parseInt(line[7]));
BlockVector min = Vector.getMinimum(pt1, pt2).toBlockVector();
BlockVector max = Vector.getMaximum(pt1, pt2).toBlockVector();
int priority = entries.get(8) == null ? 0 : Integer.parseInt(entries.get(8));
String ownersData = entries.get(9);
String flagsData = entries.get(10);
//String enterMessage = nullEmptyString(entries.get(11));
ProtectedRegion region = new ProtectedCuboidRegion(id, min, max);
region.setPriority(priority);
parseFlags(region, flagsData);
region.setOwners(this.parseDomains(ownersData));
regions.put(id, region);
} else if (type.equalsIgnoreCase("cuboid.2")) {
Vector pt1 = new Vector(
Integer.parseInt(line[2]),
Integer.parseInt(line[3]),
Integer.parseInt(line[4]));
Vector pt2 = new Vector(
Integer.parseInt(line[5]),
Integer.parseInt(line[6]),
Integer.parseInt(line[7]));
BlockVector min = Vector.getMinimum(pt1, pt2).toBlockVector();
BlockVector max = Vector.getMaximum(pt1, pt2).toBlockVector();
int priority = entries.get(8) == null ? 0 : Integer.parseInt(entries.get(8));
String parentId = entries.get(9);
String ownersData = entries.get(10);
String membersData = entries.get(11);
String flagsData = entries.get(12);
//String enterMessage = nullEmptyString(entries.get(13));
//String leaveMessage = nullEmptyString(entries.get(14));
ProtectedRegion region = new ProtectedCuboidRegion(id, min, max);
region.setPriority(priority);
parseFlags(region, flagsData);
region.setOwners(this.parseDomains(ownersData));
region.setMembers(this.parseDomains(membersData));
regions.put(id, region);
// Link children to parents later
if (parentId.length() > 0) {
parentSets.put(region, parentId);
}
}
}
} catch (IOException e) {
throw new ProtectionDatabaseException(e);
} finally {
try {
reader.close();
} catch (IOException ignored) {
}
}
for (Map.Entry<ProtectedRegion, String> entry : parentSets.entrySet()) {
ProtectedRegion parent = regions.get(entry.getValue());
if (parent != null) {
try {
entry.getKey().setParent(parent);
} catch (CircularInheritanceException e) {
logger.warning("Circular inheritance detect with '"
+ entry.getValue() + "' detected as a parent");
}
} else {
logger.warning("Unknown region parent: " + entry.getValue());
}
}
this.regions = regions;
}
/**
* Used to parse the specified domain in the CSV file.
*
* @param data The domain data as a string
* @return The domain data as a DefaultDomain
*/
private DefaultDomain parseDomains(String data) {
if (data == null) {
return new DefaultDomain();
}
DefaultDomain domain = new DefaultDomain();
Pattern pattern = Pattern.compile("^([A-Za-z]):(.*)$");
String[] parts = data.split(",");
for (String part : parts) {
if (part.trim().length() == 0) {
continue;
}
Matcher matcher = pattern.matcher(part);
if (!matcher.matches()) {
logger.warning("Invalid owner specification: " + part);
continue;
}
String type = matcher.group(1);
String id = matcher.group(2);
if (type.equals("u")) {
domain.addPlayer(id);
} else if (type.equals("g")) {
domain.addGroup(id);
} else {
logger.warning("Unknown owner specification: " + type);
}
}
return domain;
}
/**
* Used to parse the list of flags.
*
* @param data The flag data in string format
*/
private void parseFlags(ProtectedRegion region, String data) {
if (data == null) {
return;
}
State curState = State.ALLOW;
for (int i = 0; i < data.length(); i++) {
char k = data.charAt(i);
if (k == '+') {
curState = State.ALLOW;
} else if (k == '-') {
curState = State.DENY;
} else {
String flagStr;
if (k == '_') {
if (i == data.length() - 1) {
logger.warning("_ read ahead fail");
break;
}
flagStr = "_" + data.charAt(i + 1);
i++;
logger.warning("_? custom flags are no longer supported");
continue;
} else {
flagStr = String.valueOf(k);
}
StateFlag flag = legacyFlagCodes.get(flagStr);
if (flag != null) {
region.setFlag(flag, curState);
} else {
logger.warning("Legacy flag '" + flagStr + "' is unsupported");
}
}
}
}
/**
* Used to write the list of domains.
*
* @param domain
* @return
*/
/* private String writeDomains(DefaultDomain domain) {
StringBuilder str = new StringBuilder();
for (String player : domain.getPlayers()) {
str.append("u:" + player + ",");
}
for (String group : domain.getGroups()) {
str.append("g:" + group + ",");
}
return str.length() > 0 ?
str.toString().substring(0, str.length() - 1) : "";
}*/
/**
* Helper method to prepend '+' or '-' in front of a flag according
* to the flag's state.
*
* @param state
* @param flag
* @return
*/
/*
private String writeFlag(State state, String flag) {
if (state == State.ALLOW) {
return "+" + flag;
} else if (state == State.DENY) {
return "-" + flag;
}
return "";
}
*/
/**
* Returns a null if a string is null or empty.
*
* @param str The string to format
* @return null if the string is empty or null, otherwise the provided string
*/
protected String nullEmptyString(String str) {
if (str == null) {
return null;
} else if (str.length() == 0) {
return null;
} else {
return str;
}
}
public Map<String,ProtectedRegion> getRegions() {
return regions;
}
public void setRegions(Map<String,ProtectedRegion> regions) {
this.regions = regions;
}
}
@@ -1,20 +0,0 @@
package com.sk89q.worldguard.protection.databases;
import com.sk89q.worldguard.util.FatalConfigurationLoadingException;
public class InvalidTableFormatException extends FatalConfigurationLoadingException {
private static final long serialVersionUID = 1L;
protected String updateFile;
public InvalidTableFormatException(String updateFile) {
super();
this.updateFile = updateFile;
}
public String toString() {
return "You need to update your database to the latest version.\n" +
"\t\tPlease see " + this.updateFile;
}
}
File diff suppressed because it is too large. Load diff
@@ -1,72 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.databases;
import java.util.Map;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
/**
* Represents a database to read and write lists of regions from and to.
*
* @author sk89q
*/
public interface ProtectionDatabase {
/**
* Load the list of regions. The method should not modify the list returned
* by getRegions() unless the load finishes successfully.
*
* @throws ProtectionDatabaseException when an error occurs
*/
public void load() throws ProtectionDatabaseException;
/**
* Save the list of regions.
*
* @throws ProtectionDatabaseException when an error occurs
*/
public void save() throws ProtectionDatabaseException;
/**
* Load the list of regions into a region manager.
*
* @param manager The manager to load regions into
* @throws ProtectionDatabaseException when an error occurs
*/
public void load(RegionManager manager) throws ProtectionDatabaseException;
/**
* Save the list of regions from a region manager.
*
* @param manager The manager to load regions into
* @throws ProtectionDatabaseException when an error occurs
*/
public void save(RegionManager manager) throws ProtectionDatabaseException;
/**
* Get a list of regions.
*
* @return the regions loaded by this ProtectionDatabase
*/
public Map<String,ProtectedRegion> getRegions();
/**
* Set the list of regions.
*
* @param regions The regions to be applied to this ProtectionDatabase
*/
public void setRegions(Map<String,ProtectedRegion> regions);
}
@@ -1,42 +0,0 @@
// $Id$
/*
* WorldGuard ProtectionDatabaseException
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.databases;
import java.lang.Exception;
public class ProtectionDatabaseException extends Exception {
private static final long serialVersionUID = 1L;
public ProtectionDatabaseException() {
super();
}
public ProtectionDatabaseException(String message) {
super(message);
}
public ProtectionDatabaseException(String message, Throwable cause) {
super(message, cause);
}
public ProtectionDatabaseException(Throwable cause) {
super(cause);
}
}
@@ -1,133 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.databases;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.sk89q.worldguard.domains.DefaultDomain;
/**
* Various utility functions for parsing region databases.
*
* @author sk89q
*/
public class RegionDBUtil {
private static Pattern groupPattern = Pattern.compile("(?i)^[G]:(.+)$");
private RegionDBUtil() {
}
/**
* Add the given names to {@code domain}
*
* @param domain The domain to add to
* @param split The {@link String[]} containing names to add to {@code domain}
* @param startIndex The beginning index in the array
*/
public static void addToDomain(DefaultDomain domain, String[] split,
int startIndex) {
for (int i = startIndex; i < split.length; i++) {
String s = split[i];
Matcher m = groupPattern.matcher(s);
if (m.matches()) {
domain.addGroup(m.group(1));
} else {
domain.addPlayer(s);
}
}
}
/**
* Remove the given names from {@code domain}
*
* @param domain The domain to remove from
* @param split The {@link String[]} containing names to remove from {@code domain}
* @param startIndex The beginning index in the array
*/
public static void removeFromDomain(DefaultDomain domain, String[] split,
int startIndex) {
for (int i = startIndex; i < split.length; i++) {
String s = split[i];
Matcher m = groupPattern.matcher(s);
if (m.matches()) {
domain.removeGroup(m.group(1));
} else {
domain.removePlayer(s);
}
}
}
/**
* Parse a group/player DefaultDomain specification for areas.
*
* @param split The array of names to add
* @param startIndex The beginning index in the array
* @return The resulting DefaultDomain
*/
public static DefaultDomain parseDomainString(String[] split, int startIndex) {
DefaultDomain domain = new DefaultDomain();
for (int i = startIndex; i < split.length; i++) {
String s = split[i];
Matcher m = groupPattern.matcher(s);
if (m.matches()) {
domain.addGroup(m.group(1));
} else {
domain.addPlayer(s);
}
}
return domain;
}
/**
* Creates a comma separated list of PreparedStatement place holders
*
* @param length The number of wildcards to create
* @return A string with {@code length} wildcards for usage in a PreparedStatement
*/
public static String preparePlaceHolders(int length) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < length;) {
builder.append("?");
if (++i < length) {
builder.append(",");
}
}
return builder.toString();
}
/**
* Adds all of the parsed values to the PreparedStatement
*
* @param preparedStatement The preparedStanement to add to
* @param values The values to set
* @throws SQLException see {@link PreparedStatement#setString(int, String)}
*/
public static void setValues(PreparedStatement preparedStatement, String... values) throws SQLException {
for (int i = 0; i < values.length; i++) {
preparedStatement.setString(i + 1, values[i]);
}
}
}
@@ -1,315 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.databases;
import java.io.File;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import com.sk89q.util.yaml.YAMLFormat;
import com.sk89q.util.yaml.YAMLNode;
import com.sk89q.util.yaml.YAMLProcessor;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.flags.DefaultFlag;
import com.sk89q.worldguard.protection.flags.Flag;
import com.sk89q.worldguard.protection.regions.GlobalProtectedRegion;
import com.sk89q.worldguard.protection.regions.ProtectedCuboidRegion;
import com.sk89q.worldguard.protection.regions.ProtectedPolygonalRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegion.CircularInheritanceException;
public class YAMLDatabase extends AbstractProtectionDatabase {
private YAMLProcessor config;
private Map<String, ProtectedRegion> regions;
private final Logger logger;
public YAMLDatabase(File file, Logger logger) throws ProtectionDatabaseException, FileNotFoundException {
this.logger = logger;
if (!file.exists()) { // shouldn't be necessary, but check anyways
try {
file.createNewFile();
} catch (IOException e) {
throw new FileNotFoundException(file.getAbsolutePath());
}
}
config = new YAMLProcessor(file, false, YAMLFormat.COMPACT);
}
public void load() throws ProtectionDatabaseException {
try {
config.load();
} catch (IOException e) {
throw new ProtectionDatabaseException(e);
}
Map<String, YAMLNode> regionData = config.getNodes("regions");
// No regions are even configured
if (regionData == null) {
this.regions = new HashMap<String, ProtectedRegion>();
return;
}
Map<String,ProtectedRegion> regions =
new HashMap<String,ProtectedRegion>();
Map<ProtectedRegion,String> parentSets =
new LinkedHashMap<ProtectedRegion, String>();
for (Map.Entry<String, YAMLNode> entry : regionData.entrySet()) {
String id = entry.getKey().toLowerCase().replace(".", "");
YAMLNode node = entry.getValue();
String type = node.getString("type");
ProtectedRegion region;
try {
if (type == null) {
logger.warning("Undefined region type for region '" + id + '"');
continue;
} else if (type.equals("cuboid")) {
Vector pt1 = checkNonNull(node.getVector("min"));
Vector pt2 = checkNonNull(node.getVector("max"));
BlockVector min = Vector.getMinimum(pt1, pt2).toBlockVector();
BlockVector max = Vector.getMaximum(pt1, pt2).toBlockVector();
region = new ProtectedCuboidRegion(id, min, max);
} else if (type.equals("poly2d")) {
Integer minY = checkNonNull(node.getInt("min-y"));
Integer maxY = checkNonNull(node.getInt("max-y"));
List<BlockVector2D> points = node.getBlockVector2dList("points", null);
region = new ProtectedPolygonalRegion(id, points, minY, maxY);
} else if (type.equals("global")) {
region = new GlobalProtectedRegion(id);
} else {
logger.warning("Unknown region type for region '" + id + '"');
continue;
}
Integer priority = checkNonNull(node.getInt("priority"));
region.setPriority(priority);
setFlags(region, node.getNode("flags"));
region.setOwners(parseDomain(node.getNode("owners")));
region.setMembers(parseDomain(node.getNode("members")));
regions.put(id, region);
String parentId = node.getString("parent");
if (parentId != null) {
parentSets.put(region, parentId);
}
} catch (NullPointerException e) {
logger.warning("Missing data for region '" + id + '"');
}
}
// Relink parents
for (Map.Entry<ProtectedRegion, String> entry : parentSets.entrySet()) {
ProtectedRegion parent = regions.get(entry.getValue());
if (parent != null) {
try {
entry.getKey().setParent(parent);
} catch (CircularInheritanceException e) {
logger.warning("Circular inheritance detect with '"
+ entry.getValue() + "' detected as a parent");
}
} else {
logger.warning("Unknown region parent: " + entry.getValue());
}
}
this.regions = regions;
}
private <V> V checkNonNull(V val) throws NullPointerException {
if (val == null) {
throw new NullPointerException();
}
return val;
}
private void setFlags(ProtectedRegion region, YAMLNode flagsData) {
if (flagsData == null) {
return;
}
// @TODO: Make this better
for (Flag<?> flag : DefaultFlag.getFlags()) {
Object o = flagsData.getProperty(flag.getName());
if (o != null) {
setFlag(region, flag, o);
}
if (flag.getRegionGroupFlag() != null) {
Object o2 = flagsData.getProperty(flag.getRegionGroupFlag().getName());
if (o2 != null) {
setFlag(region, flag.getRegionGroupFlag(), o2);
}
}
}
}
private <T> void setFlag(ProtectedRegion region, Flag<T> flag, Object rawValue) {
T val = flag.unmarshal(rawValue);
if (val == null) {
logger.warning("Failed to parse flag '" + flag.getName()
+ "' with value '" + rawValue.toString() + "'");
return;
}
region.setFlag(flag, val);
}
private DefaultDomain parseDomain(YAMLNode node) {
if (node == null) {
return new DefaultDomain();
}
DefaultDomain domain = new DefaultDomain();
for (String name : node.getStringList("players", null)) {
domain.addPlayer(name);
}
for (String name : node.getStringList("groups", null)) {
domain.addGroup(name);
}
return domain;
}
public void save() throws ProtectionDatabaseException {
config.clear();
for (Map.Entry<String, ProtectedRegion> entry : regions.entrySet()) {
ProtectedRegion region = entry.getValue();
YAMLNode node = config.addNode("regions." + entry.getKey());
if (region instanceof ProtectedCuboidRegion) {
ProtectedCuboidRegion cuboid = (ProtectedCuboidRegion) region;
node.setProperty("type", "cuboid");
node.setProperty("min", cuboid.getMinimumPoint());
node.setProperty("max", cuboid.getMaximumPoint());
} else if (region instanceof ProtectedPolygonalRegion) {
ProtectedPolygonalRegion poly = (ProtectedPolygonalRegion) region;
node.setProperty("type", "poly2d");
node.setProperty("min-y", poly.getMinimumPoint().getBlockY());
node.setProperty("max-y", poly.getMaximumPoint().getBlockY());
List<Map<String, Object>> points = new ArrayList<Map<String,Object>>();
for (BlockVector2D point : poly.getPoints()) {
Map<String, Object> data = new HashMap<String, Object>();
data.put("x", point.getBlockX());
data.put("z", point.getBlockZ());
points.add(data);
}
node.setProperty("points", points);
} else if (region instanceof GlobalProtectedRegion) {
node.setProperty("type", "global");
} else {
node.setProperty("type", region.getClass().getCanonicalName());
}
node.setProperty("priority", region.getPriority());
node.setProperty("flags", getFlagData(region));
node.setProperty("owners", getDomainData(region.getOwners()));
node.setProperty("members", getDomainData(region.getMembers()));
ProtectedRegion parent = region.getParent();
if (parent != null) {
node.setProperty("parent", parent.getId());
}
}
config.setHeader("#\r\n" +
"# WorldGuard regions file\r\n" +
"#\r\n" +
"# WARNING: THIS FILE IS AUTOMATICALLY GENERATED. If you modify this file by\r\n" +
"# hand, be aware that A SINGLE MISTYPED CHARACTER CAN CORRUPT THE FILE. If\r\n" +
"# WorldGuard is unable to parse the file, your regions will FAIL TO LOAD and\r\n" +
"# the contents of this file will reset. Please use a YAML validator such as\r\n" +
"# http://yaml-online-parser.appspot.com (for smaller files).\r\n" +
"#\r\n" +
"# REMEMBER TO KEEP PERIODICAL BACKUPS.\r\n" +
"#");
config.save();
}
private Map<String, Object> getFlagData(ProtectedRegion region) {
Map<String, Object> flagData = new HashMap<String, Object>();
for (Map.Entry<Flag<?>, Object> entry : region.getFlags().entrySet()) {
Flag<?> flag = entry.getKey();
addMarshalledFlag(flagData, flag, entry.getValue());
}
return flagData;
}
@SuppressWarnings("unchecked")
private <V> void addMarshalledFlag(Map<String, Object> flagData,
Flag<V> flag, Object val) {
if (val == null) {
return;
}
flagData.put(flag.getName(), flag.marshal((V) val));
}
private Map<String, Object> getDomainData(DefaultDomain domain) {
Map<String, Object> domainData = new HashMap<String, Object>();
setDomainData(domainData, "players", domain.getPlayers());
setDomainData(domainData, "groups", domain.getGroups());
return domainData;
}
private void setDomainData(Map<String, Object> domainData,
String key, Set<String> domain) {
if (domain.size() == 0) {
return;
}
List<String> list = new ArrayList<String>();
for (String str : domain) {
list.add(str);
}
domainData.put(key, list);
}
public Map<String, ProtectedRegion> getRegions() {
return regions;
}
public void setRegions(Map<String, ProtectedRegion> regions) {
this.regions = regions;
}
}
@@ -1,62 +0,0 @@
// $Id$
/*
* MySQL WordGuard Region Database
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.databases.migrators;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
public abstract class AbstractDatabaseMigrator implements DatabaseMigrator {
private static HashMap<MigratorKey, Class<? extends AbstractDatabaseMigrator>> migrators =
new HashMap<MigratorKey, Class<? extends AbstractDatabaseMigrator>>();
public static Map<MigratorKey, Class<? extends AbstractDatabaseMigrator>> getMigrators() {
if (!migrators.isEmpty()) return migrators;
AbstractDatabaseMigrator.migrators.put(new MigratorKey("mysql", "yaml"), MySQLToYAMLMigrator.class);
AbstractDatabaseMigrator.migrators.put(new MigratorKey("yaml", "mysql"), YAMLToMySQLMigrator.class);
return migrators;
}
protected abstract Set<String> getWorldsFromOld() throws MigrationException;
protected abstract Map<String, ProtectedRegion> getRegionsForWorldFromOld(String world) throws MigrationException;
protected abstract ProtectionDatabase getNewWorldStorage(String world) throws MigrationException;
public void migrate() throws MigrationException {
for (String world : this.getWorldsFromOld()) {
ProtectionDatabase database = this.getNewWorldStorage(world);
database.setRegions(this.getRegionsForWorldFromOld(world));
try {
database.save();
} catch (ProtectionDatabaseException e) {
throw new MigrationException(e);
}
}
}
}
@@ -1,31 +0,0 @@
// $Id$
/*
* MySQL WordGuard Region Database
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.databases.migrators;
/**
* Represents a method of converting from one database to another.
*
* @author Nicholas Steicke
*/
public interface DatabaseMigrator {
public void migrate() throws MigrationException;
}
@@ -1,40 +0,0 @@
// $Id$
/*
* MySQL WordGuard Region Database
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.databases.migrators;
public class MigrationException extends Exception {
private static final long serialVersionUID = 1L;
public MigrationException() {
super();
}
public MigrationException(String message) {
super(message);
}
public MigrationException(String message, Throwable cause) {
super(message, cause);
}
public MigrationException(Throwable cause) {
super(cause);
}
}
@@ -1,43 +0,0 @@
// $Id$
/*
* MySQL WordGuard Region Database
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.databases.migrators;
public class MigratorKey {
public final String from;
public final String to;
public MigratorKey(String from, String to) {
this.from = from;
this.to = to;
}
public boolean equals(Object o) {
MigratorKey other = (MigratorKey) o;
return other.from.equals(this.from) && other.to.equals(this.to);
}
public int hashCode() {
int hash = 17;
hash = hash * 31 + this.from.hashCode();
hash = hash * 31 + this.to.hashCode();
return hash;
}
}
@@ -1,97 +0,0 @@
// $Id$
/*
* MySQL WordGuard Region Database
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.databases.migrators;
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.databases.MySQLDatabase;
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
import com.sk89q.worldguard.protection.databases.YAMLDatabase;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import java.io.File;
import java.io.FileNotFoundException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class MySQLToYAMLMigrator extends AbstractDatabaseMigrator {
private WorldGuardPlugin plugin;
private Set<String> worlds;
public MySQLToYAMLMigrator(WorldGuardPlugin plugin) throws MigrationException {
this.plugin = plugin;
this.worlds = new HashSet<String>();
ConfigurationManager config = plugin.getGlobalStateManager();
try {
Connection conn = DriverManager.getConnection(config.sqlDsn, config.sqlUsername, config.sqlPassword);
ResultSet worlds = conn.prepareStatement("SELECT `name` FROM `world`;").executeQuery();
while(worlds.next()) {
this.worlds.add(worlds.getString(1));
}
conn.close();
} catch (SQLException e) {
throw new MigrationException(e);
}
}
@Override
protected Set<String> getWorldsFromOld() {
return this.worlds;
}
@Override
protected Map<String, ProtectedRegion> getRegionsForWorldFromOld(String world) throws MigrationException {
ProtectionDatabase oldDatabase;
try {
oldDatabase = new MySQLDatabase(plugin.getGlobalStateManager(), world, plugin.getLogger());
oldDatabase.load();
} catch (ProtectionDatabaseException e) {
throw new MigrationException(e);
}
return oldDatabase.getRegions();
}
@Override
protected ProtectionDatabase getNewWorldStorage(String world) throws MigrationException {
try {
File file = new File(plugin.getDataFolder(),
"worlds" + File.separator + world + File.separator + "regions.yml");
return new YAMLDatabase(file, plugin.getLogger());
} catch (FileNotFoundException e) {
throw new MigrationException(e);
} catch (ProtectionDatabaseException e) {
throw new MigrationException(e);
}
}
}
@@ -1,86 +0,0 @@
// $Id$
/*
* MySQL WordGuard Region Database
* Copyright (C) 2011 Nicholas Steicke <http://narthollis.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.databases.migrators;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.databases.MySQLDatabase;
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
import com.sk89q.worldguard.protection.databases.YAMLDatabase;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class YAMLToMySQLMigrator extends AbstractDatabaseMigrator {
private WorldGuardPlugin plugin;
private HashMap<String,File> regionYamlFiles;
public YAMLToMySQLMigrator(WorldGuardPlugin plugin) {
this.plugin = plugin;
this.regionYamlFiles = new HashMap<String,File>();
File files[] = new File(plugin.getDataFolder(), "worlds" + File.separator).listFiles();
for (File item : files) {
if (item.isDirectory()) {
for (File subItem : item.listFiles()) {
if (subItem.getName().equals("regions.yml")) {
this.regionYamlFiles.put(item.getName(), subItem);
}
}
}
}
}
@Override
protected Set<String> getWorldsFromOld() {
return this.regionYamlFiles.keySet();
}
@Override
protected Map<String, ProtectedRegion> getRegionsForWorldFromOld(String world) throws MigrationException {
ProtectionDatabase oldDatabase;
try {
oldDatabase = new YAMLDatabase(this.regionYamlFiles.get(world), plugin.getLogger());
oldDatabase.load();
} catch (FileNotFoundException e) {
throw new MigrationException(e);
} catch (ProtectionDatabaseException e) {
throw new MigrationException(e);
}
return oldDatabase.getRegions();
}
@Override
protected ProtectionDatabase getNewWorldStorage(String world) throws MigrationException {
try {
return new MySQLDatabase(plugin.getGlobalStateManager(), world, plugin.getLogger());
} catch (ProtectionDatabaseException e) {
throw new MigrationException(e);
}
}
}
@@ -1,71 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import org.bukkit.command.CommandSender;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
/**
*
* @author sk89q
*/
public class BooleanFlag extends Flag<Boolean> {
public BooleanFlag(String name, RegionGroup defaultGroup) {
super(name, defaultGroup);
}
public BooleanFlag(String name) {
super(name);
}
@Override
public Boolean parseInput(WorldGuardPlugin plugin, CommandSender sender,
String input) throws InvalidFlagFormat {
input = input.trim();
if (input.equalsIgnoreCase("true") || input.equalsIgnoreCase("yes")
|| input.equalsIgnoreCase("on")
|| input.equalsIgnoreCase("1")) {
return true;
} else if (input.equalsIgnoreCase("false") || input.equalsIgnoreCase("no")
|| input.equalsIgnoreCase("off")
|| input.equalsIgnoreCase("0")) {
return false;
} else {
throw new InvalidFlagFormat("Not a yes/no value: " + input);
}
}
@Override
public Boolean unmarshal(Object o) {
if (o instanceof Boolean) {
return (Boolean) o;
} else {
return null;
}
}
@Override
public Object marshal(Boolean o) {
return o;
}
}
@@ -1,63 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import org.bukkit.command.CommandSender;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
/**
*
* @author sk89q
*/
public class CommandStringFlag extends Flag<String> {
public CommandStringFlag(String name, RegionGroup defaultGroup) {
super(name, defaultGroup);
}
public CommandStringFlag(String name) {
super(name);
}
@Override
public String parseInput(WorldGuardPlugin plugin, CommandSender sender,
String input) throws InvalidFlagFormat {
input = input.trim();
if (!input.startsWith("/")) {
input = "/" + input;
}
return input.toLowerCase();
}
@Override
public String unmarshal(Object o) {
if (o instanceof String) {
return (String) o;
} else {
return null;
}
}
@Override
public Object marshal(String o) {
return o;
}
}
@@ -1,116 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import org.bukkit.GameMode;
import org.bukkit.entity.EntityType;
/**
*
* @author sk89q
*/
public final class DefaultFlag {
public static final StateFlag PASSTHROUGH = new StateFlag("passthrough", false, RegionGroup.ALL);
public static final StateFlag BUILD = new StateFlag("build", true, RegionGroup.NON_MEMBERS);
public static final RegionGroupFlag CONSTRUCT = new RegionGroupFlag("construct", RegionGroup.MEMBERS);
public static final StateFlag PVP = new StateFlag("pvp", true, RegionGroup.ALL);
public static final StateFlag MOB_DAMAGE = new StateFlag("mob-damage", true, RegionGroup.ALL);
public static final StateFlag MOB_SPAWNING = new StateFlag("mob-spawning", true, RegionGroup.ALL);
public static final StateFlag CREEPER_EXPLOSION = new StateFlag("creeper-explosion", true, RegionGroup.ALL);
public static final StateFlag ENDERDRAGON_BLOCK_DAMAGE = new StateFlag("enderdragon-block-damage", true);
public static final StateFlag GHAST_FIREBALL = new StateFlag("ghast-fireball", true, RegionGroup.ALL);
public static final StateFlag SLEEP = new StateFlag("sleep", true);
public static final StateFlag TNT = new StateFlag("tnt", true, RegionGroup.ALL);
public static final StateFlag LIGHTER = new StateFlag("lighter", true, RegionGroup.ALL);
public static final StateFlag FIRE_SPREAD = new StateFlag("fire-spread", true);
public static final StateFlag LAVA_FIRE = new StateFlag("lava-fire", true);
public static final StateFlag LIGHTNING = new StateFlag("lightning", true);
public static final StateFlag CHEST_ACCESS = new StateFlag("chest-access", false);
public static final StateFlag WATER_FLOW = new StateFlag("water-flow", true);
public static final StateFlag LAVA_FLOW = new StateFlag("lava-flow", true);
public static final StateFlag USE = new StateFlag("use", true);
public static final StateFlag PLACE_VEHICLE = new StateFlag("vehicle-place", false);
public static final StateFlag DESTROY_VEHICLE = new StateFlag("vehicle-destroy", false);
public static final StateFlag PISTONS = new StateFlag("pistons", true);
public static final StateFlag SNOW_FALL = new StateFlag("snow-fall", true);
public static final StateFlag SNOW_MELT = new StateFlag("snow-melt", true);
public static final StateFlag ICE_FORM = new StateFlag("ice-form", true);
public static final StateFlag ICE_MELT = new StateFlag("ice-melt", true);
public static final StateFlag MUSHROOMS = new StateFlag("mushroom-growth", true);
public static final StateFlag LEAF_DECAY = new StateFlag("leaf-decay", true);
public static final StateFlag GRASS_SPREAD = new StateFlag("grass-growth", true);
public static final StateFlag ENDER_BUILD = new StateFlag("enderman-grief", true);
public static final StateFlag INVINCIBILITY = new StateFlag("invincible", false, RegionGroup.ALL);
public static final StateFlag EXP_DROPS = new StateFlag("exp-drops", true, RegionGroup.ALL);
public static final StateFlag SEND_CHAT = new StateFlag("send-chat", true);
public static final StateFlag RECEIVE_CHAT = new StateFlag("receive-chat", true);
public static final StateFlag ENTRY = new StateFlag("entry", true);
public static final StateFlag EXIT = new StateFlag("exit", true);
public static final StateFlag ITEM_DROP = new StateFlag("item-drop", true);
public static final StateFlag ENTITY_PAINTING_DESTROY = new StateFlag("entity-painting-destroy", true);
public static final StateFlag ENTITY_ITEM_FRAME_DESTROY = new StateFlag("entity-item-frame-destroy", true);
public static final StateFlag POTION_SPLASH = new StateFlag("potion-splash", true);
public static final StringFlag GREET_MESSAGE = new StringFlag("greeting", RegionGroup.ALL);
public static final StringFlag FAREWELL_MESSAGE = new StringFlag("farewell", RegionGroup.ALL);
public static final BooleanFlag NOTIFY_ENTER = new BooleanFlag("notify-enter", RegionGroup.ALL);
public static final BooleanFlag NOTIFY_LEAVE = new BooleanFlag("notify-leave", RegionGroup.ALL);
public static final SetFlag<EntityType> DENY_SPAWN = new SetFlag<EntityType>("deny-spawn", RegionGroup.ALL, new EntityTypeFlag(null));
public static final EnumFlag<GameMode> GAME_MODE = new EnumFlag<GameMode>("game-mode", GameMode.class, RegionGroup.ALL);
public static final IntegerFlag HEAL_DELAY = new IntegerFlag("heal-delay", RegionGroup.ALL);
public static final IntegerFlag HEAL_AMOUNT = new IntegerFlag("heal-amount", RegionGroup.ALL);
public static final IntegerFlag MIN_HEAL = new IntegerFlag("heal-min-health", RegionGroup.ALL);
public static final IntegerFlag MAX_HEAL = new IntegerFlag("heal-max-health", RegionGroup.ALL);
public static final IntegerFlag FEED_DELAY = new IntegerFlag("feed-delay", RegionGroup.ALL);
public static final IntegerFlag FEED_AMOUNT = new IntegerFlag("feed-amount", RegionGroup.ALL);
public static final IntegerFlag MIN_FOOD = new IntegerFlag("feed-min-hunger", RegionGroup.ALL);
public static final IntegerFlag MAX_FOOD = new IntegerFlag("feed-max-hunger", RegionGroup.ALL);
public static final LocationFlag TELE_LOC = new LocationFlag("teleport", RegionGroup.MEMBERS);
public static final LocationFlag SPAWN_LOC = new LocationFlag("spawn", RegionGroup.MEMBERS);
public static final BooleanFlag BUYABLE = new BooleanFlag("buyable");
public static final DoubleFlag PRICE = new DoubleFlag("price");
public static final SetFlag<String> BLOCKED_CMDS = new SetFlag<String>("blocked-cmds", RegionGroup.ALL, new CommandStringFlag(null));
public static final SetFlag<String> ALLOWED_CMDS = new SetFlag<String>("allowed-cmds", RegionGroup.ALL, new CommandStringFlag(null));
public static final Flag<?>[] flagsList = new Flag<?>[] {
PASSTHROUGH, BUILD, CONSTRUCT, PVP, CHEST_ACCESS, PISTONS,
TNT, LIGHTER, USE, PLACE_VEHICLE, DESTROY_VEHICLE, SLEEP,
MOB_DAMAGE, MOB_SPAWNING, DENY_SPAWN, INVINCIBILITY, EXP_DROPS,
CREEPER_EXPLOSION, ENDERDRAGON_BLOCK_DAMAGE, GHAST_FIREBALL, ENDER_BUILD,
GREET_MESSAGE, FAREWELL_MESSAGE, NOTIFY_ENTER, NOTIFY_LEAVE,
EXIT, ENTRY, LIGHTNING, ENTITY_PAINTING_DESTROY,
ENTITY_ITEM_FRAME_DESTROY, ITEM_DROP,
HEAL_AMOUNT, HEAL_DELAY, MIN_HEAL, MAX_HEAL,
FEED_DELAY, FEED_AMOUNT, MIN_FOOD, MAX_FOOD,
SNOW_FALL, SNOW_MELT, ICE_FORM, ICE_MELT, GAME_MODE,
MUSHROOMS, LEAF_DECAY, GRASS_SPREAD, SEND_CHAT, RECEIVE_CHAT,
FIRE_SPREAD, LAVA_FIRE, LAVA_FLOW, WATER_FLOW,
TELE_LOC, SPAWN_LOC, POTION_SPLASH,
BLOCKED_CMDS, ALLOWED_CMDS, PRICE, BUYABLE,
};
private DefaultFlag() {
}
public static Flag<?>[] getFlags() {
return flagsList;
}
}
@@ -1,64 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import org.bukkit.command.CommandSender;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
/**
*
* @author sk89q
*/
public class DoubleFlag extends Flag<Double> {
public DoubleFlag(String name, RegionGroup defaultGroup) {
super(name, defaultGroup);
}
public DoubleFlag(String name) {
super(name);
}
@Override
public Double parseInput(WorldGuardPlugin plugin, CommandSender sender,
String input) throws InvalidFlagFormat {
input = input.trim();
try {
return Double.parseDouble(input);
} catch (NumberFormatException e) {
throw new InvalidFlagFormat("Not a number: " + input);
}
}
@Override
public Double unmarshal(Object o) {
if (o instanceof Double) {
return (Double) o;
} else {
return null;
}
}
@Override
public Object marshal(Double o) {
return o;
}
}
@@ -1,54 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import org.bukkit.entity.EntityType;
/**
* Represents an entity type.
*
* @author sk89q
*/
public class EntityTypeFlag extends EnumFlag<EntityType> {
public EntityTypeFlag(String name, RegionGroup defaultGroup) {
super(name, EntityType.class, defaultGroup);
}
public EntityTypeFlag(String name) {
super(name, EntityType.class);
}
@Override
public EntityType detectValue(String input) {
EntityType lowMatch = null;
for (EntityType type : EntityType.values()) {
if (type.name().equalsIgnoreCase(input.trim())) {
return type;
}
if (type.name().toLowerCase().startsWith(input.toLowerCase().trim())) {
lowMatch = type;
}
}
return lowMatch;
}
}
@@ -1,96 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import org.bukkit.command.CommandSender;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
/**
*
* @author sk89q
*/
public class EnumFlag<T extends Enum<T>> extends Flag<T> {
private Class<T> enumClass;
public EnumFlag(String name, Class<T> enumClass, RegionGroup defaultGroup) {
super(name, defaultGroup);
this.enumClass = enumClass;
}
public EnumFlag(String name, Class<T> enumClass) {
super(name);
this.enumClass = enumClass;
}
private T findValue(String input) throws IllegalArgumentException {
if (input != null) {
input = input.toUpperCase();
}
try {
return Enum.valueOf(enumClass, input);
} catch (IllegalArgumentException e) {
T val = detectValue(input);
if (val != null) {
return val;
}
throw e;
}
}
/**
* Fuzzy detect the value if the value is not found.
*
* @param input string input
* @return value or null
*/
public T detectValue(String input) {
return null;
}
@Override
public T parseInput(WorldGuardPlugin plugin, CommandSender sender,
String input) throws InvalidFlagFormat {
try {
return findValue(input);
} catch (IllegalArgumentException e) {
throw new InvalidFlagFormat("Unknown value '" + input + "' in "
+ enumClass.getName());
}
}
@Override
public T unmarshal(Object o) {
try {
return Enum.valueOf(enumClass, String.valueOf(o));
} catch (IllegalArgumentException e) {
return null;
}
}
@Override
public Object marshal(T o) {
return o.name();
}
}
@@ -1,61 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import org.bukkit.command.CommandSender;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
/**
*
* @author sk89q
* @param <T>
*/
public abstract class Flag<T> {
private String name;
private RegionGroupFlag regionGroup;
public Flag(String name, RegionGroup defaultGroup) {
this.name = name;
if (defaultGroup != null) {
this.regionGroup = new RegionGroupFlag(name + "-group", defaultGroup);
}
}
public Flag(String name) {
this(name, RegionGroup.NON_MEMBERS);
}
public String getName() {
return name;
}
public RegionGroupFlag getRegionGroupFlag() {
return regionGroup;
}
public abstract T parseInput(WorldGuardPlugin plugin, CommandSender sender,
String input) throws InvalidFlagFormat;
public abstract T unmarshal(Object o);
public abstract Object marshal(T o);
}
@@ -1,64 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import org.bukkit.command.CommandSender;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
/**
*
* @author sk89q
*/
public class IntegerFlag extends Flag<Integer> {
public IntegerFlag(String name, RegionGroup defaultGroup) {
super(name, defaultGroup);
}
public IntegerFlag(String name) {
super(name);
}
@Override
public Integer parseInput(WorldGuardPlugin plugin, CommandSender sender,
String input) throws InvalidFlagFormat {
input = input.trim();
try {
return Integer.parseInt(input);
} catch (NumberFormatException e) {
throw new InvalidFlagFormat("Not a number: " + input);
}
}
@Override
public Integer unmarshal(Object o) {
if (o instanceof Integer) {
return (Integer) o;
} else {
return null;
}
}
@Override
public Object marshal(Integer o) {
return o;
}
}
@@ -1,29 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
public class InvalidFlagFormat extends Exception {
private static final long serialVersionUID = 8101615074524004172L;
public InvalidFlagFormat(String msg) {
super(msg);
}
}
@@ -1,149 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.Bukkit;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.Location;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
/**
*
* @author sk89q
*/
public class LocationFlag extends Flag<Location> {
public LocationFlag(String name, RegionGroup defaultGroup) {
super(name, defaultGroup);
}
public LocationFlag(String name) {
super(name);
}
@Override
public Location parseInput(WorldGuardPlugin plugin, CommandSender sender, String input) throws InvalidFlagFormat {
input = input.trim();
final Player player;
try {
player = plugin.checkPlayer(sender);
} catch (CommandException e) {
throw new InvalidFlagFormat(e.getMessage());
}
if ("here".equalsIgnoreCase(input)) {
return BukkitUtil.toLocation(player.getLocation());
} else if ("none".equalsIgnoreCase(input)) {
return null;
} else {
String[] split = input.split(",");
if (split.length >= 3) {
try {
final World world = player.getWorld();
final double x = Double.parseDouble(split[0]);
final double y = Double.parseDouble(split[1]);
final double z = Double.parseDouble(split[2]);
final float yaw = split.length < 4 ? 0 : Float.parseFloat(split[3]);
final float pitch = split.length < 5 ? 0 : Float.parseFloat(split[4]);
return new Location(
BukkitUtil.getLocalWorld(world),
new Vector(
x,
y,
z
),
yaw, pitch
);
} catch (NumberFormatException ignored) {
}
}
throw new InvalidFlagFormat("Expected 'here' or x,y,z.");
}
}
@Override
public Location unmarshal(Object o) {
if (o instanceof Map<?, ?>) {
Map<?, ?> map = (Map<?, ?>) o;
Object rawWorld = map.get("world");
if (rawWorld == null) return null;
Object rawX = map.get("x");
if (rawX == null) return null;
Object rawY = map.get("y");
if (rawY == null) return null;
Object rawZ = map.get("z");
if (rawZ == null) return null;
Object rawYaw = map.get("yaw");
if (rawYaw == null) return null;
Object rawPitch = map.get("pitch");
if (rawPitch == null) return null;
World bukkitWorld = Bukkit.getServer().getWorld((String) rawWorld);
LocalWorld world = BukkitUtil.getLocalWorld(bukkitWorld);
Vector position = new Vector(toNumber(rawX), toNumber(rawY), toNumber(rawZ));
float yaw = (float) toNumber(rawYaw);
float pitch = (float) toNumber(rawPitch);
return new Location(world, position, yaw, pitch);
}
return null;
}
@Override
public Object marshal(Location o) {
Vector position = o.getPosition();
Map<String, Object> vec = new HashMap<String, Object>();
vec.put("world", o.getWorld().getName());
vec.put("x", position.getX());
vec.put("y", position.getY());
vec.put("z", position.getZ());
vec.put("yaw", o.getYaw());
vec.put("pitch", o.getPitch());
return vec;
}
private double toNumber(Object o) {
if (o instanceof Number) {
return ((Number) o).doubleValue();
} else {
return 0;
}
}
}
@@ -1,31 +0,0 @@
/*
* WorldGuard
* Copyright (C) 2012 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
/**
* A grouping of region membership types
*/
public enum RegionGroup {
MEMBERS,
OWNERS,
NON_MEMBERS,
NON_OWNERS,
ALL,
NONE
}
@@ -1,112 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
/**
*
* @author sk89q
*/
public class RegionGroupFlag extends EnumFlag<RegionGroup> {
private RegionGroup def;
public RegionGroupFlag(String name, RegionGroup def) {
super(name, RegionGroup.class, null);
this.def = def;
}
public RegionGroup getDefault() {
return def;
}
@Override
public RegionGroup detectValue(String input) {
input = input.trim();
if (input.equalsIgnoreCase("members") || input.equalsIgnoreCase("member")) {
return RegionGroup.MEMBERS;
} else if (input.equalsIgnoreCase("owners") || input.equalsIgnoreCase("owner")) {
return RegionGroup.OWNERS;
} else if (input.equalsIgnoreCase("nonowners") || input.equalsIgnoreCase("nonowner")) {
return RegionGroup.NON_OWNERS;
} else if (input.equalsIgnoreCase("nonmembers") || input.equalsIgnoreCase("nonmember")) {
return RegionGroup.NON_MEMBERS;
} else if (input.equalsIgnoreCase("everyone") || input.equalsIgnoreCase("anyone") || input.equalsIgnoreCase("all")) {
return RegionGroup.ALL;
} else if (input.equalsIgnoreCase("none") || input.equalsIgnoreCase("noone") || input.equalsIgnoreCase("deny")) {
return RegionGroup.NONE;
} else {
return null;
}
}
public static boolean isMember(ProtectedRegion region, RegionGroup group, LocalPlayer player) {
if (group == null || group == RegionGroup.ALL) {
return true;
} else if (group == RegionGroup.OWNERS) {
if (region.isOwner(player)) {
return true;
}
} else if (group == RegionGroup.MEMBERS) {
if (region.isMember(player)) {
return true;
}
} else if (group == RegionGroup.NON_OWNERS) {
if (!region.isOwner(player)) {
return true;
}
} else if (group == RegionGroup.NON_MEMBERS) {
if (!region.isMember(player)) {
return true;
}
}
return false;
}
public static boolean isMember(ApplicableRegionSet set,
RegionGroup group, LocalPlayer player) {
if (group == null || group == RegionGroup.ALL) {
return true;
} else if (group == RegionGroup.OWNERS) {
if (set.isOwnerOfAll(player)) {
return true;
}
} else if (group == RegionGroup.MEMBERS) {
if (set.isMemberOfAll(player)) {
return true;
}
} else if (group == RegionGroup.NON_OWNERS) {
if (!set.isOwnerOfAll(player)) {
return true;
}
} else if (group == RegionGroup.NON_MEMBERS) {
if (!set.isMemberOfAll(player)) {
return true;
}
}
return false;
}
}
@@ -1,91 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.bukkit.command.CommandSender;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
/**
* Represents a flag that consists of a set.
*
* @author sk89q
*/
public class SetFlag<T> extends Flag<Set<T>> {
private Flag<T> subFlag;
public SetFlag(String name, RegionGroup defaultGroup, Flag<T> subFlag) {
super(name, defaultGroup);
this.subFlag = subFlag;
}
public SetFlag(String name, Flag<T> subFlag) {
super(name);
this.subFlag = subFlag;
}
@Override
public Set<T> parseInput(WorldGuardPlugin plugin, CommandSender sender,
String input) throws InvalidFlagFormat {
Set<T> items = new HashSet<T>();
for (String str : input.split(",")) {
items.add(subFlag.parseInput(plugin, sender, str.trim()));
}
return new HashSet<T>(items);
}
@Override
public Set<T> unmarshal(Object o) {
if (o instanceof Collection<?>) {
Collection<?> collection = (Collection<?>) o;
Set<T> items = new HashSet<T>();
for (Object sub : collection) {
T item = subFlag.unmarshal(sub);
if (item != null) {
items.add(item);
}
}
return items;
} else {
return null;
}
}
@Override
public Object marshal(Set<T> o) {
List<Object> list = new ArrayList<Object>();
for (T item : o) {
list.add(subFlag.marshal(item));
}
return list;
}
}
@@ -1,91 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import org.bukkit.command.CommandSender;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
/**
*
* @author sk89q
*/
public class StateFlag extends Flag<StateFlag.State> {
public enum State {
ALLOW,
DENY
}
private boolean def;
public StateFlag(String name, boolean def, RegionGroup defaultGroup) {
super(name, defaultGroup);
this.def = def;
}
public StateFlag(String name, boolean def) {
super(name);
this.def = def;
}
public boolean getDefault() {
return def;
}
@Override
public State parseInput(WorldGuardPlugin plugin, CommandSender sender,
String input) throws InvalidFlagFormat {
input = input.trim();
if (input.equalsIgnoreCase("allow")) {
return State.ALLOW;
} else if (input.equalsIgnoreCase("deny")) {
return State.DENY;
} else if (input.equalsIgnoreCase("none")) {
return null;
} else {
throw new InvalidFlagFormat("Expected none/allow/deny but got '" + input + "'");
}
}
@Override
public State unmarshal(Object o) {
String str = o.toString();
if (str.equalsIgnoreCase("allow")) {
return State.ALLOW;
} else if (str.equalsIgnoreCase("deny")) {
return State.DENY;
} else {
return null;
}
}
@Override
public Object marshal(State o) {
if (o == State.ALLOW) {
return "allow";
} else if (o == State.DENY) {
return "deny";
} else {
return null;
}
}
}
@@ -1,59 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import org.bukkit.command.CommandSender;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
/**
*
* @author sk89q
*/
public class StringFlag extends Flag<String> {
public StringFlag(String name, RegionGroup defaultGroup) {
super(name, defaultGroup);
}
public StringFlag(String name) {
super(name);
}
@Override
public String parseInput(WorldGuardPlugin plugin, CommandSender sender,
String input) throws InvalidFlagFormat {
return input.replaceAll("(?!\\\\)\\\\n", "\n").replaceAll("\\\\\\\\n", "\\n");
}
@Override
public String unmarshal(Object o) {
if (o instanceof String) {
return (String) o;
} else {
return null;
}
}
@Override
public Object marshal(String o) {
return o;
}
}
@@ -1,113 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.flags;
import java.util.HashMap;
import java.util.Map;
import org.bukkit.command.CommandSender;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
/**
*
* @author sk89q
*/
public class VectorFlag extends Flag<Vector> {
public VectorFlag(String name, RegionGroup defaultGroup) {
super(name, defaultGroup);
}
public VectorFlag(String name) {
super(name);
}
@Override
public Vector parseInput(WorldGuardPlugin plugin, CommandSender sender, String input) throws InvalidFlagFormat {
input = input.trim();
if ("here".equalsIgnoreCase(input)) {
try {
return BukkitUtil.toVector(plugin.checkPlayer(sender).getLocation());
} catch (CommandException e) {
throw new InvalidFlagFormat(e.getMessage());
}
} else {
String[] split = input.split(",");
if (split.length == 3) {
try {
return new Vector(
Double.parseDouble(split[0]),
Double.parseDouble(split[1]),
Double.parseDouble(split[2])
);
} catch (NumberFormatException ignored) {
}
}
throw new InvalidFlagFormat("Expected 'here' or x,y,z.");
}
}
@Override
public Vector unmarshal(Object o) {
if (o instanceof Map<?, ?>) {
Map<?, ?> map = (Map<?, ?>) o;
Object rawX = map.get("x");
Object rawY = map.get("y");
Object rawZ = map.get("z");
if (rawX == null || rawY == null || rawZ == null) {
return null;
}
return new Vector(toNumber(rawX), toNumber(rawY), toNumber(rawZ));
}
return null;
}
@Override
public Object marshal(Vector o) {
Map<String, Object> vec = new HashMap<String, Object>();
vec.put("x", o.getX());
vec.put("y", o.getY());
vec.put("z", o.getZ());
return vec;
}
private double toNumber(Object o) {
if (o instanceof Integer) {
return (Integer) o;
} else if (o instanceof Long) {
return (Long) o;
} else if (o instanceof Float) {
return (Float) o;
} else if (o instanceof Double) {
return (Double) o;
} else {
return 0;
}
}
}
@@ -1,207 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.managers;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.UnsupportedIntersectionException;
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import java.util.*;
/**
* A very simple implementation of the region manager that uses a flat list
* and iterates through the list to identify applicable regions. This method
* is not very efficient.
*
* @author sk89q
*/
public class FlatRegionManager extends RegionManager {
/**
* List of protected regions.
*/
private Map<String, ProtectedRegion> regions;
/**
* Construct the manager.
*
* @param regionLoader The loader for regions
*/
public FlatRegionManager(ProtectionDatabase regionLoader) {
super(regionLoader);
regions = new TreeMap<String, ProtectedRegion>();
}
@Override
public Map<String, ProtectedRegion> getRegions() {
return regions;
}
@Override
public void setRegions(Map<String, ProtectedRegion> regions) {
this.regions = new TreeMap<String, ProtectedRegion>(regions);
}
@Override
public void addRegion(ProtectedRegion region) {
regions.put(region.getId().toLowerCase(), region);
}
@Override
public void removeRegion(String id) {
ProtectedRegion region = regions.get(id.toLowerCase());
regions.remove(id.toLowerCase());
if (region != null) {
List<String> removeRegions = new ArrayList<String>();
for (ProtectedRegion curRegion : regions.values()) {
if (curRegion.getParent() == region) {
removeRegions.add(curRegion.getId().toLowerCase());
}
}
for (String remId : removeRegions) {
removeRegion(remId);
}
}
}
@Override
public boolean hasRegion(String id) {
return regions.containsKey(id.toLowerCase());
}
@Override
public ApplicableRegionSet getApplicableRegions(Vector pt) {
TreeSet<ProtectedRegion> appRegions =
new TreeSet<ProtectedRegion>();
for (ProtectedRegion region : regions.values()) {
if (region.contains(pt)) {
appRegions.add(region);
ProtectedRegion parent = region.getParent();
while (parent != null) {
if (!appRegions.contains(parent)) {
appRegions.add(parent);
}
parent = parent.getParent();
}
}
}
return new ApplicableRegionSet(appRegions, regions.get("__global__"));
}
/**
* Get an object for a region for rules to be applied with.
*
* @return
*/
/*@Override
public ApplicableRegionSet getApplicableRegions(ProtectedRegion checkRegion) {
List<ProtectedRegion> appRegions = new ArrayList<ProtectedRegion>();
appRegions.addAll(regions.values());
List<ProtectedRegion> intersectRegions;
try {
intersectRegions = checkRegion.getIntersectingRegions(appRegions);
} catch (Exception e) {
intersectRegions = new ArrayList<ProtectedRegion>();
}
return new ApplicableRegionSet(intersectRegions, regions.get("__global__"));
}*/
@Override
public List<String> getApplicableRegionsIDs(Vector pt) {
List<String> applicable = new ArrayList<String>();
for (Map.Entry<String, ProtectedRegion> entry : regions.entrySet()) {
if (entry.getValue().contains(pt)) {
applicable.add(entry.getKey());
}
}
return applicable;
}
@Override
public ApplicableRegionSet getApplicableRegions(ProtectedRegion checkRegion) {
List<ProtectedRegion> appRegions = new ArrayList<ProtectedRegion>();
appRegions.addAll(regions.values());
List<ProtectedRegion> intersectRegions;
try {
intersectRegions = checkRegion.getIntersectingRegions(appRegions);
} catch (Exception e) {
intersectRegions = new ArrayList<ProtectedRegion>();
}
return new ApplicableRegionSet(intersectRegions, regions.get("__global__"));
}
@Override
public boolean overlapsUnownedRegion(ProtectedRegion checkRegion, LocalPlayer player) {
List<ProtectedRegion> appRegions = new ArrayList<ProtectedRegion>();
for (ProtectedRegion other : regions.values()) {
if (other.getOwners().contains(player)) {
continue;
}
appRegions.add(other);
}
List<ProtectedRegion> intersectRegions;
try {
intersectRegions = checkRegion.getIntersectingRegions(appRegions);
} catch (UnsupportedIntersectionException e) {
intersectRegions = new ArrayList<ProtectedRegion>();
}
return intersectRegions.size() > 0;
}
@Override
public int size() {
return regions.size();
}
@Override
public int getRegionCountOfPlayer(LocalPlayer player) {
int count = 0;
for (ProtectedRegion region : regions.values()) {
if (region.getOwners().contains(player)) {
count++;
}
}
return count;
}
}
@@ -1,220 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.managers;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.protection.regions.ProtectedRegionMBRConverter;
import org.khelekore.prtree.MBR;
import org.khelekore.prtree.MBRConverter;
import org.khelekore.prtree.PRTree;
import org.khelekore.prtree.SimpleMBR;
import java.util.*;
public class PRTreeRegionManager extends RegionManager {
private static final int BRANCH_FACTOR = 30;
/**
* List of protected regions.
*/
private Map<String, ProtectedRegion> regions;
/**
* Converter to get coordinates of the tree.
*/
private MBRConverter<ProtectedRegion> converter = new ProtectedRegionMBRConverter();
/**
* Priority R-tree.
*/
private PRTree<ProtectedRegion> tree;
/**
* Construct the manager.
*
* @param regionLoader The region loader to use
*/
public PRTreeRegionManager(ProtectionDatabase regionLoader) {
super(regionLoader);
regions = new TreeMap<String, ProtectedRegion>();
tree = new PRTree<ProtectedRegion>(converter, BRANCH_FACTOR);
}
@Override
public Map<String, ProtectedRegion> getRegions() {
return regions;
}
@Override
public void setRegions(Map<String, ProtectedRegion> regions) {
this.regions = new TreeMap<String, ProtectedRegion>(regions);
tree = new PRTree<ProtectedRegion>(converter, BRANCH_FACTOR);
tree.load(regions.values());
}
@Override
public void addRegion(ProtectedRegion region) {
regions.put(region.getId().toLowerCase(), region);
tree = new PRTree<ProtectedRegion>(converter, BRANCH_FACTOR);
tree.load(regions.values());
}
@Override
public boolean hasRegion(String id) {
return regions.containsKey(id.toLowerCase());
}
@Override
public void removeRegion(String id) {
ProtectedRegion region = regions.get(id.toLowerCase());
regions.remove(id.toLowerCase());
if (region != null) {
List<String> removeRegions = new ArrayList<String>();
for (ProtectedRegion curRegion : regions.values()) {
if (curRegion.getParent() == region) {
removeRegions.add(curRegion.getId().toLowerCase());
}
}
for (String remId : removeRegions) {
removeRegion(remId);
}
}
tree = new PRTree<ProtectedRegion>(converter, BRANCH_FACTOR);
tree.load(regions.values());
}
@Override
public ApplicableRegionSet getApplicableRegions(Vector pt) {
// Floor the vector to ensure we get accurate points
pt = pt.floor();
List<ProtectedRegion> appRegions = new ArrayList<ProtectedRegion>();
MBR pointMBR = new SimpleMBR(pt.getX(), pt.getX(), pt.getY(), pt.getY(), pt.getZ(), pt.getZ());
for (ProtectedRegion region : tree.find(pointMBR)) {
if (region.contains(pt) && !appRegions.contains(region)) {
appRegions.add(region);
ProtectedRegion parent = region.getParent();
while (parent != null) {
if (!appRegions.contains(parent)) {
appRegions.add(parent);
}
parent = parent.getParent();
}
}
}
Collections.sort(appRegions);
return new ApplicableRegionSet(appRegions, regions.get("__global__"));
}
@Override
public ApplicableRegionSet getApplicableRegions(ProtectedRegion checkRegion) {
List<ProtectedRegion> appRegions = new ArrayList<ProtectedRegion>();
appRegions.addAll(regions.values());
List<ProtectedRegion> intersectRegions;
try {
intersectRegions = checkRegion.getIntersectingRegions(appRegions);
} catch (Exception e) {
intersectRegions = new ArrayList<ProtectedRegion>();
}
return new ApplicableRegionSet(intersectRegions, regions.get("__global__"));
}
@Override
public List<String> getApplicableRegionsIDs(Vector pt) {
// Floor the vector to ensure we get accurate points
pt = pt.floor();
List<String> applicable = new ArrayList<String>();
MBR pointMBR = new SimpleMBR(pt.getX(), pt.getX(), pt.getY(), pt.getY(), pt.getZ(), pt.getZ());
for (ProtectedRegion region : tree.find(pointMBR)) {
if (region.contains(pt) && !applicable.contains(region.getId())) {
applicable.add(region.getId());
ProtectedRegion parent = region.getParent();
while (parent != null) {
if (!applicable.contains(parent.getId())) {
applicable.add(parent.getId());
}
parent = parent.getParent();
}
}
}
return applicable;
}
@Override
public boolean overlapsUnownedRegion(ProtectedRegion checkRegion, LocalPlayer player) {
List<ProtectedRegion> appRegions = new ArrayList<ProtectedRegion>();
for (ProtectedRegion other : regions.values()) {
if (other.getOwners().contains(player)) {
continue;
}
appRegions.add(other);
}
List<ProtectedRegion> intersectRegions;
try {
intersectRegions = checkRegion.getIntersectingRegions(appRegions);
} catch (Exception e) {
intersectRegions = new ArrayList<ProtectedRegion>();
}
return intersectRegions.size() > 0;
}
@Override
public int size() {
return regions.size();
}
@Override
public int getRegionCountOfPlayer(LocalPlayer player) {
int count = 0;
for (Map.Entry<String, ProtectedRegion> entry : regions.entrySet()) {
if (entry.getValue().getOwners().contains(player)) {
count++;
}
}
return count;
}
}
@@ -1,210 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.managers;
import java.util.List;
import java.util.Map;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.protection.ApplicableRegionSet;
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
/**
* An abstract class for getting, setting, and looking up regions. The most
* simple implementation uses a flat list and iterates through the entire list
* to look for applicable regions, but a more complicated (and more efficient)
* implementation may use space partitioning techniques.
*
* @author sk89q
*/
public abstract class RegionManager {
protected ProtectionDatabase loader;
/**
* Construct the object.
*
* @param loader The loader for this region
*/
public RegionManager(ProtectionDatabase loader) {
this.loader = loader;
}
/**
* Load the list of regions. If the regions do not load properly, then
* the existing list should be used (as stored previously).
*
* @throws ProtectionDatabaseException when an error occurs
*/
public void load() throws ProtectionDatabaseException {
loader.load(this);
}
/**
* Save the list of regions.
*
* @throws ProtectionDatabaseException when an error occurs while saving
*/
public void save() throws ProtectionDatabaseException {
loader.save(this);
}
/**
* Get a map of protected regions. Use one of the region manager methods
* if possible if working with regions.
*
* @return map of regions, with keys being region IDs (lowercase)
*/
public abstract Map<String, ProtectedRegion> getRegions();
/**
* Set a list of protected regions. Keys should be lowercase in the given
* map fo regions.
*
* @param regions map of regions
*/
public abstract void setRegions(Map<String, ProtectedRegion> regions);
/**
* Adds a region. If a region by the given name already exists, then
* the existing region will be replaced.
*
* @param region region to add
*/
public abstract void addRegion(ProtectedRegion region);
/**
* Return whether a region exists by an ID.
*
* @param id id of the region, can be mixed-case
* @return whether the region exists
*/
public abstract boolean hasRegion(String id);
/**
* Get a region by its ID. Includes symbolic names like #&lt;index&gt;
*
* @param id id of the region, can be mixed-case
* @return region or null if it doesn't exist
*/
public ProtectedRegion getRegion(String id) {
if (id.startsWith("#")) {
int index;
try {
index = Integer.parseInt(id.substring(1)) - 1;
} catch (NumberFormatException e) {
return null;
}
for (ProtectedRegion region : getRegions().values()) {
if (index == 0) {
return region;
}
--index;
}
return null;
}
return getRegionExact(id);
}
/**
* Get a region by its ID.
*
* @param id id of the region, can be mixed-case
* @return region or null if it doesn't exist
*/
public ProtectedRegion getRegionExact(String id) {
return getRegions().get(id.toLowerCase());
}
/**
* Removes a region, including inheriting children.
*
* @param id id of the region, can be mixed-case
*/
public abstract void removeRegion(String id);
/**
* Get an object for a point for rules to be applied with. Use this in order
* to query for flag data or membership data for a given point.
*
* @param loc Bukkit location
* @return applicable region set
*/
public ApplicableRegionSet getApplicableRegions(org.bukkit.Location loc) {
return getApplicableRegions(com.sk89q.worldedit.bukkit.BukkitUtil.toVector(loc));
}
/**
* Get an object for a point for rules to be applied with. Use this in order
* to query for flag data or membership data for a given point.
*
* @param pt point
* @return applicable region set
*/
public abstract ApplicableRegionSet getApplicableRegions(Vector pt);
/**
* Get an object for a point for rules to be applied with. This gets
* a set for the given reason.
*
* @param region region
* @return regino set
*/
public abstract ApplicableRegionSet getApplicableRegions(
ProtectedRegion region);
/**
* Get a list of region IDs that contain a point.
*
* @param pt point
* @return list of region Ids
*/
public abstract List<String> getApplicableRegionsIDs(Vector pt);
/**
* Returns true if the provided region overlaps with any other region that
* is not owned by the player.
*
* @param region region to check
* @param player player to check against
* @return whether there is an overlap
*/
public abstract boolean overlapsUnownedRegion(ProtectedRegion region,
LocalPlayer player);
/**
* Get the number of regions.
*
* @return number of regions
*/
public abstract int size();
/**
* Get the number of regions for a player.
*
* @param player player
* @return name number of regions that a player owns
*/
public abstract int getRegionCountOfPlayer(LocalPlayer player);
}
@@ -1,66 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.regions;
import java.util.ArrayList;
import java.util.List;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.protection.UnsupportedIntersectionException;
public class GlobalProtectedRegion extends ProtectedRegion {
public GlobalProtectedRegion(String id) {
super(id);
min = new BlockVector(0, 0, 0);
max = new BlockVector(0, 0, 0);
}
public List<BlockVector2D> getPoints() {
List<BlockVector2D> pts = new ArrayList<BlockVector2D>();
pts.add(new BlockVector2D(min.getBlockX(),min.getBlockZ()));
return pts;
}
@Override
public int volume() {
return 0;
}
@Override
public boolean contains(Vector pt) {
return false;
}
@Override
public String getTypeName() {
return "global";
}
@Override
public List<ProtectedRegion> getIntersectingRegions(
List<ProtectedRegion> regions)
throws UnsupportedIntersectionException {
return new ArrayList<ProtectedRegion>();
}
}
@@ -1,170 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.regions;
import java.util.ArrayList;
import java.util.List;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.protection.UnsupportedIntersectionException;
/**
* Represents a cuboid region that can be protected.
*
* @author sk89q
*/
public class ProtectedCuboidRegion extends ProtectedRegion {
/**
* Construct a new instance of this cuboid region.
*
* @param id The region id
* @param pt1 The first point of this region
* @param pt2 The second point of this region
*/
public ProtectedCuboidRegion(String id, BlockVector pt1, BlockVector pt2) {
super(id);
setMinMaxPoints(pt1, pt2);
}
/**
* Given any two points, sets the minimum and maximum points
*
* @param pt1 The first point of this region
* @param pt2 The second point of this region
*/
private void setMinMaxPoints(BlockVector pt1, BlockVector pt2) {
List<Vector> points = new ArrayList<Vector>();
points.add(pt1);
points.add(pt2);
setMinMaxPoints(points);
}
/**
* Set the lower point of the cuboid.
*
* @param pt The point to set as the minimum point
*/
public void setMinimumPoint(BlockVector pt) {
setMinMaxPoints(pt, max);
}
/**
* Set the upper point of the cuboid.
*
* @param pt The point to set as the maximum point
*/
public void setMaximumPoint(BlockVector pt) {
setMinMaxPoints(min, pt);
}
public List<BlockVector2D> getPoints() {
List<BlockVector2D> pts = new ArrayList<BlockVector2D>();
int x1 = min.getBlockX();
int x2 = max.getBlockX();
int z1 = min.getBlockZ();
int z2 = max.getBlockZ();
pts.add(new BlockVector2D(x1, z1));
pts.add(new BlockVector2D(x2, z1));
pts.add(new BlockVector2D(x1, z2));
pts.add(new BlockVector2D(x2, z2));
return pts;
}
@Override
public boolean contains(Vector pt) {
final double x = pt.getX();
final double y = pt.getY();
final double z = pt.getZ();
return x >= min.getBlockX() && x < max.getBlockX()+1
&& y >= min.getBlockY() && y < max.getBlockY()+1
&& z >= min.getBlockZ() && z < max.getBlockZ()+1;
}
/*
public boolean intersectsWith(ProtectedRegion region) throws UnsupportedIntersectionException {
if (region instanceof ProtectedCuboidRegion) {
ProtectedCuboidRegion r1 = (ProtectedCuboidRegion) this;
ProtectedCuboidRegion r2 = (ProtectedCuboidRegion) region;
BlockVector min1 = r1.getMinimumPoint();
BlockVector max1 = r1.getMaximumPoint();
BlockVector min2 = r2.getMinimumPoint();
BlockVector max2 = r2.getMaximumPoint();
return !(min1.getBlockX() > max2.getBlockX()
|| min1.getBlockY() > max2.getBlockY()
|| min1.getBlockZ() > max2.getBlockZ()
|| max1.getBlockX() < min2.getBlockX()
|| max1.getBlockY() < min2.getBlockY()
|| max1.getBlockZ() < min2.getBlockZ());
} else if (region instanceof ProtectedPolygonalRegion) {
throw new UnsupportedIntersectionException();
} else {
throw new UnsupportedIntersectionException();
}
}
*/
@Override
public List<ProtectedRegion> getIntersectingRegions(List<ProtectedRegion> regions) throws UnsupportedIntersectionException {
List<ProtectedRegion> intersectingRegions = new ArrayList<ProtectedRegion>();
for (ProtectedRegion region : regions) {
if (!intersectsBoundingBox(region)) continue;
// If both regions are Cuboids and their bounding boxes intersect, they intersect
if (region instanceof ProtectedCuboidRegion) {
intersectingRegions.add(region);
continue;
} else if (region instanceof ProtectedPolygonalRegion) {
// If either region contains the points of the other,
// or if any edges intersect, the regions intersect
if (containsAny(region.getPoints())
|| region.containsAny(getPoints())
|| intersectsEdges(region)) {
intersectingRegions.add(region);
continue;
}
} else {
throw new UnsupportedOperationException("Not supported yet.");
}
}
return intersectingRegions;
}
@Override
public String getTypeName() {
return "cuboid";
}
@Override
public int volume() {
int xLength = max.getBlockX() - min.getBlockX() + 1;
int yLength = max.getBlockY() - min.getBlockY() + 1;
int zLength = max.getBlockZ() - min.getBlockZ() + 1;
return xLength * yLength * zLength;
}
}
@@ -1,198 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.regions;
import java.util.ArrayList;
import java.util.List;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.protection.UnsupportedIntersectionException;
public class ProtectedPolygonalRegion extends ProtectedRegion {
protected List<BlockVector2D> points;
protected int minY;
protected int maxY;
public ProtectedPolygonalRegion(String id, List<BlockVector2D> points, int minY, int maxY) {
super(id);
this.points = points;
setMinMaxPoints(points, minY, maxY);
this.minY = min.getBlockY();
this.maxY = max.getBlockY();
}
/**
* Sets the min and max points from all the 2d points and the min/max Y values
*
* @param points2D A {@link List} of points that this region should contain
* @param minY The minimum y coordinate
* @param maxY The maximum y coordinate
*/
private void setMinMaxPoints(List<BlockVector2D> points2D, int minY, int maxY) {
List<Vector> points = new ArrayList<Vector>();
int y = minY;
for (BlockVector2D point2D : points2D) {
points.add(new Vector(point2D.getBlockX(), y, point2D.getBlockZ()));
y = maxY;
}
setMinMaxPoints(points);
}
public List<BlockVector2D> getPoints() {
return points;
}
/**
* Checks to see if a point is inside this region.
*/
@Override
public boolean contains(Vector pt) {
int targetX = pt.getBlockX(); //wide
int targetY = pt.getBlockY(); //height
int targetZ = pt.getBlockZ(); //depth
if (targetY < minY || targetY > maxY) {
return false;
}
//Quick and dirty check.
if (targetX < min.getBlockX() || targetX > max.getBlockX() || targetZ < min.getBlockZ() || targetZ > max.getBlockZ()) {
return false;
}
boolean inside = false;
int npoints = points.size();
int xNew, zNew;
int xOld, zOld;
int x1, z1;
int x2, z2;
long crossproduct;
int i;
xOld = points.get(npoints - 1).getBlockX();
zOld = points.get(npoints - 1).getBlockZ();
for (i = 0; i < npoints; i++) {
xNew = points.get(i).getBlockX();
zNew = points.get(i).getBlockZ();
//Check for corner
if (xNew == targetX && zNew == targetZ) {
return true;
}
if (xNew > xOld) {
x1 = xOld;
x2 = xNew;
z1 = zOld;
z2 = zNew;
} else {
x1 = xNew;
x2 = xOld;
z1 = zNew;
z2 = zOld;
}
if (x1 <= targetX && targetX <= x2) {
crossproduct = ((long) targetZ - (long) z1) * (long) (x2 - x1)
- ((long) z2 - (long) z1) * (long) (targetX - x1);
if (crossproduct == 0) {
if ((z1 <= targetZ) == (targetZ <= z2)) return true; // on edge
} else if (crossproduct < 0 && (x1 != targetX)) {
inside = !inside;
}
}
xOld = xNew;
zOld = zNew;
}
return inside;
}
@Override
public List<ProtectedRegion> getIntersectingRegions(List<ProtectedRegion> regions) throws UnsupportedIntersectionException {
List<ProtectedRegion> intersectingRegions = new ArrayList<ProtectedRegion>();
for (ProtectedRegion region : regions) {
if (!intersectsBoundingBox(region)) continue;
if (region instanceof ProtectedPolygonalRegion || region instanceof ProtectedCuboidRegion) {
// If either region contains the points of the other,
// or if any edges intersect, the regions intersect
if (containsAny(region.getPoints())
|| region.containsAny(getPoints())
|| intersectsEdges(region)) {
intersectingRegions.add(region);
continue;
}
} else {
throw new UnsupportedOperationException("Not supported yet.");
}
}
return intersectingRegions;
}
/**
* Return the type of region as a user-friendly name.
*
* @return type of region
*/
@Override
public String getTypeName() {
return "polygon";
}
@Override
public int volume() {
int volume = 0;
// TODO: Fix this
/*int numPoints = points.size();
if (numPoints < 3) {
return 0;
}
double area = 0;
int xa, z1, z2;
for (int i = 0; i < numPoints; i++) {
xa = points.get(i).getBlockX();
//za = points.get(i).getBlockZ();
if (points.get(i + 1) == null) {
z1 = points.get(0).getBlockZ();
} else {
z1 = points.get(i + 1).getBlockZ();
}
if (points.get(i - 1) == null) {
z2 = points.get(numPoints - 1).getBlockZ();
} else {
z2 = points.get(i - 1).getBlockZ();
}
area = area + (xa * (z1 - z2));
}
xa = points.get(0).getBlockX();
//za = points.get(0).getBlockZ();
area = area + (xa * (points.get(1).getBlockZ() - points.get(numPoints - 1).getBlockZ()));
volume = (Math.abs(maxY - minY) + 1) * (int) Math.ceil((Math.abs(area) / 2));*/
return volume;
}
}
@@ -1,603 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.regions;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.LocalPlayer;
import com.sk89q.worldguard.domains.DefaultDomain;
import com.sk89q.worldguard.protection.UnsupportedIntersectionException;
import com.sk89q.worldguard.protection.flags.Flag;
import java.awt.geom.Line2D;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
/**
* Represents a region of any shape and size that can be protected.
*
* @author sk89q
*/
public abstract class ProtectedRegion implements Comparable<ProtectedRegion> {
protected BlockVector min;
protected BlockVector max;
private static final Pattern idPattern = Pattern.compile("^[A-Za-z0-9_,'\\-\\+/]{1,}$");
/**
* Holds the region's ID.
*/
private String id;
/**
* Priority.
*/
private int priority = 0;
/**
* Holds the curParent.
*/
private ProtectedRegion parent;
/**
* List of owners.
*/
private DefaultDomain owners = new DefaultDomain();
/**
* List of members.
*/
private DefaultDomain members = new DefaultDomain();
/**
* List of flags.
*/
private Map<Flag<?>, Object> flags = new HashMap<Flag<?>, Object>();
/**
* Construct a new instance of this region.
*
* @param id The id (name) of this region.
*/
public ProtectedRegion(String id) {
this.id = id;
}
/**
* Sets the minimum and maximum points of the bounding box for a region
*
* @param points The points to set. Must have at least one element.
*/
protected void setMinMaxPoints(List<Vector> points) {
int minX = points.get(0).getBlockX();
int minY = points.get(0).getBlockY();
int minZ = points.get(0).getBlockZ();
int maxX = minX;
int maxY = minY;
int maxZ = minZ;
for (Vector v : points) {
int x = v.getBlockX();
int y = v.getBlockY();
int z = v.getBlockZ();
if (x < minX) minX = x;
if (y < minY) minY = y;
if (z < minZ) minZ = z;
if (x > maxX) maxX = x;
if (y > maxY) maxY = y;
if (z > maxZ) maxZ = z;
}
min = new BlockVector(minX, minY, minZ);
max = new BlockVector(maxX, maxY, maxZ);
}
/**
* Gets the id of this region
*
* @return the id
*/
public String getId() {
return id;
}
/**
* Get the lower point of the cuboid.
*
* @return min point
*/
public BlockVector getMinimumPoint() {
return min;
}
/**
* Get the upper point of the cuboid.
*
* @return max point
*/
public BlockVector getMaximumPoint() {
return max;
}
/**
* @return the priority
*/
public int getPriority() {
return priority;
}
/**
* @param priority the priority to setFlag
*/
public void setPriority(int priority) {
this.priority = priority;
}
/**
* @return the curParent
*/
public ProtectedRegion getParent() {
return parent;
}
/**
* Set the curParent. This checks to make sure that it will not result
* in circular inheritance.
*
* @param parent the curParent to setFlag
* @throws CircularInheritanceException when circular inheritance is detected
*/
public void setParent(ProtectedRegion parent) throws CircularInheritanceException {
if (parent == null) {
this.parent = null;
return;
}
if (parent == this) {
throw new CircularInheritanceException();
}
ProtectedRegion p = parent.getParent();
while (p != null) {
if (p == this) {
throw new CircularInheritanceException();
}
p = p.getParent();
}
this.parent = parent;
}
/**
* @return the owners
*/
public DefaultDomain getOwners() {
return owners;
}
/**
* @param owners the owners to setFlag
*/
public void setOwners(DefaultDomain owners) {
this.owners = owners;
}
/**
* @return the members
*/
public DefaultDomain getMembers() {
return members;
}
/**
* @param members the members to setFlag
*/
public void setMembers(DefaultDomain members) {
this.members = members;
}
/**
* Checks whether a region has members or owners.
*
* @return whether there are members or owners
*/
public boolean hasMembersOrOwners() {
return owners.size() > 0 || members.size() > 0;
}
/**
* Checks whether a player is an owner of region or any of its parents.
*
* @param player player to check
* @return whether an owner
*/
public boolean isOwner(LocalPlayer player) {
if (owners.contains(player)) {
return true;
}
ProtectedRegion curParent = getParent();
while (curParent != null) {
if (curParent.getOwners().contains(player)) {
return true;
}
curParent = curParent.getParent();
}
return false;
}
/**
* Checks whether a player is an owner of region or any of its parents.
*
* @param playerName player name to check
* @return whether an owner
*/
public boolean isOwner(String playerName) {
if (owners.contains(playerName)) {
return true;
}
ProtectedRegion curParent = getParent();
while (curParent != null) {
if (curParent.getOwners().contains(playerName)) {
return true;
}
curParent = curParent.getParent();
}
return false;
}
/**
* Checks whether a player is a member OR OWNER of the region
* or any of its parents.
*
* @param player player to check
* @return whether an owner or member
*/
public boolean isMember(LocalPlayer player) {
if (isOwner(player)) {
return true;
}
if (members.contains(player)) {
return true;
}
ProtectedRegion curParent = getParent();
while (curParent != null) {
if (curParent.getMembers().contains(player)) {
return true;
}
curParent = curParent.getParent();
}
return false;
}
/**
* Checks whether a player is a member OR OWNER of the region
* or any of its parents.
*
* @param playerName player name to check
* @return whether an owner or member
*/
public boolean isMember(String playerName) {
if (isOwner(playerName)) {
return true;
}
if (members.contains(playerName)) {
return true;
}
ProtectedRegion curParent = getParent();
while (curParent != null) {
if (curParent.getMembers().contains(playerName)) {
return true;
}
curParent = curParent.getParent();
}
return false;
}
/**
* Checks whether a player is a member of the region
* or any of its parents.
*
* @param player player to check
* @return whether an member
*/
public boolean isMemberOnly(LocalPlayer player) {
if (members.contains(player)) {
return true;
}
ProtectedRegion curParent = getParent();
while (curParent != null) {
if (curParent.getMembers().contains(player)) {
return true;
}
curParent = curParent.getParent();
}
return false;
}
/**
* Get a flag's value.
*
* @param <T> The flag type
* @param <V> The type of the flag's value
* @param flag The flag to check
* @return value or null if isn't defined
*/
@SuppressWarnings("unchecked")
public <T extends Flag<V>, V> V getFlag(T flag) {
Object obj = flags.get(flag);
V val;
if (obj != null) {
val = (V) obj;
} else {
return null;
}
return val;
}
/**
* Set a flag's value.
*
* @param <T> The flag type
* @param <V> The type of the flag's value
* @param flag The flag to check
* @param val The value to set
*/
public <T extends Flag<V>, V> void setFlag(T flag, V val) {
if (val == null) {
flags.remove(flag);
} else {
flags.put(flag, val);
}
}
/**
* Get the map of flags.
*
* @return The map of flags currently used for this region
*/
public Map<Flag<?>, Object> getFlags() {
return flags;
}
/**
* Get the map of flags.
*
* @param flags The flags to set
*/
public void setFlags(Map<Flag<?>, Object> flags) {
this.flags = flags;
}
/**
* Gets the 2D points for this region
*
* @return The points for this region as (x, z) coordinates
*/
public abstract List<BlockVector2D> getPoints();
/**
* Get the number of blocks in this region
*
* @return the volume of this region in blocks
*/
public abstract int volume();
/**
* Check to see if a point is inside this region.
*
* @param pt The point to check
* @return Whether {@code pt} is in this region
*/
public abstract boolean contains(Vector pt);
/**
* Check to see if a point is inside this region.
*
* @param pt The point to check
* @return Whether {@code pt} is in this region
*/
public boolean contains(BlockVector2D pt) {
return contains(new Vector(pt.getBlockX(), min.getBlockY(), pt.getBlockZ()));
}
/**
* Check to see if a point is inside this region.
*
* @param x The x coordinate to check
* @param y The y coordinate to check
* @param z The z coordinate to check
* @return Whether this region contains the points at the given coordinate
*/
public boolean contains(int x, int y, int z) {
return contains(new Vector(x, y, z));
}
/**
* Check to see if any of the 2D points are inside this region.
*
* @param pts
* @return
*/
public boolean containsAny(List<BlockVector2D> pts) {
for (BlockVector2D pt : pts) {
if (contains(pt)) {
return true;
}
}
return false;
}
/**
* Compares to another region.<br>
*<br>
* Orders primarily by the priority, descending<br>
* Orders secondarily by the id, ascending
*
* @param other The region to compare to
*/
public int compareTo(ProtectedRegion other) {
if (priority > other.priority) {
return -1;
} else if (priority < other.priority) {
return 1;
}
return id.compareTo(other.id);
}
/**
* Return the type of region as a user-friendly, lowercase name.
*
* @return type of region
*/
public abstract String getTypeName();
/**
* Get a list of intersecting regions.
*
* @param regions The list of regions to source from
* @return The elements of {@code regions} that intersect with this region
* @throws UnsupportedIntersectionException if an invalid intersection is detected
*/
public abstract List<ProtectedRegion> getIntersectingRegions(
List<ProtectedRegion> regions)
throws UnsupportedIntersectionException;
/**
* Checks if the bounding box of a region intersects with with the bounding
* box of this region
*
* @param region The region to check
* @return whether the given region intersects
*/
protected boolean intersectsBoundingBox(ProtectedRegion region) {
BlockVector rMaxPoint = region.getMaximumPoint();
BlockVector min = getMinimumPoint();
if (rMaxPoint.getBlockX() < min.getBlockX()) return false;
if (rMaxPoint.getBlockY() < min.getBlockY()) return false;
if (rMaxPoint.getBlockZ() < min.getBlockZ()) return false;
BlockVector rMinPoint = region.getMinimumPoint();
BlockVector max = getMaximumPoint();
if (rMinPoint.getBlockX() > max.getBlockX()) return false;
if (rMinPoint.getBlockY() > max.getBlockY()) return false;
if (rMinPoint.getBlockZ() > max.getBlockZ()) return false;
return true;
}
/**
* Compares all edges of two regions to see if any of them intersect
*
* @param region The region to check
* @return whether any edges of a region intersect
*/
protected boolean intersectsEdges(ProtectedRegion region) {
List<BlockVector2D> pts1 = getPoints();
List<BlockVector2D> pts2 = region.getPoints();
BlockVector2D lastPt1 = pts1.get(pts1.size() - 1);
BlockVector2D lastPt2 = pts2.get(pts2.size() - 1);
for (BlockVector2D aPts1 : pts1) {
for (BlockVector2D aPts2 : pts2) {
Line2D line1 = new Line2D.Double(
lastPt1.getBlockX(),
lastPt1.getBlockZ(),
aPts1.getBlockX(),
aPts1.getBlockZ());
if (line1.intersectsLine(
lastPt2.getBlockX(),
lastPt2.getBlockZ(),
aPts2.getBlockX(),
aPts2.getBlockZ())) {
return true;
}
lastPt2 = aPts2;
}
lastPt1 = aPts1;
}
return false;
}
/**
* Checks to see if the given ID is accurate.
*
* @param id The id to check
* @see #idPattern
* @return Whether the region id given is valid
*/
public static boolean isValidId(String id) {
return idPattern.matcher(id).matches();
}
@Override
public int hashCode(){
return id.hashCode();
}
/**
* Returns whether this region has the same ID as another region.
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof ProtectedRegion)) {
return false;
}
ProtectedRegion other = (ProtectedRegion) obj;
return other.getId().equals(getId());
}
/**
* Thrown when setting a curParent would create a circular inheritance
* situation.
*/
public static class CircularInheritanceException extends Exception {
private static final long serialVersionUID = 7479613488496776022L;
}
}
@@ -1,56 +0,0 @@
// $Id$
/*
* WorldGuard
* Copyright (C) 2010 sk89q <http://www.sk89q.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection.regions;
import org.khelekore.prtree.MBRConverter;
public class ProtectedRegionMBRConverter implements MBRConverter<ProtectedRegion> {
@Override
public int getDimensions() {
return 3;
}
@Override
public double getMax(int dimension, ProtectedRegion region) {
switch (dimension) {
case 0:
return region.getMaximumPoint().getBlockX();
case 1:
return region.getMaximumPoint().getBlockY();
case 2:
return region.getMaximumPoint().getBlockZ();
}
return 0;
}
@Override
public double getMin(int dimension, ProtectedRegion region) {
switch (dimension) {
case 0:
return region.getMinimumPoint().getBlockX();
case 1:
return region.getMinimumPoint().getBlockY();
case 2:
return region.getMinimumPoint().getBlockZ();
}
return 0;
}
}
@@ -0,0 +1,78 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.region;
import java.util.WeakHashMap;
/**
* A simple cache to reduce hits to the region manager when region information
* is needed for the same location in the same event context.
* <p>
* If two or more pieces of code (such as from different programs or plugins)
* need to ask the question of "which regions contain this point" within the
* same event (such as when a player breaks a block), it is ideal that a query
* is only performed once and a cached answer is returned for the subsequent
* requests for this information (but only within the same context or event!).
* This is because queries to the region manager are often demanding and it
* would be taxing to perform the same search more than once. The purpose of
* this class is to facilitate exactly that.
* <p>
* In order for this cache to work, a key must be generated for each query to
* this cache. If two pieces of code need to execute the same region query
* during the same event (consider this at time A), both pieces of code must
* give the instance of this class the exact same 'key' object in order for the
* second calling piece of code to receive the cached result. However, once that
* event has been processed and time has moved on (proceeding to time X+1), that
* previously chosen key object must not ever be used again, otherwise it may
* return the results that were found at time X, which may be out of date.
* <p>
* Weak references are used to refer to that key object, and so whatever key
* object is chosen can be properly garbage collected once it is no longer
* needed outside the context of this cache.
* <p>
* This cache itself is thread-safe.
*/
public abstract class AbstractRegionQueryCache {
private final WeakHashMap<Object, RegionQueryCacheEntry> cache =
new WeakHashMap<Object, RegionQueryCacheEntry>();
/**
* Construct a copy of this cache.
*/
public AbstractRegionQueryCache() {
}
/**
* Get the {@link RegionQueryCacheEntry} object that will cache the
* {@link ApplicableRegionSet}s for this context.
*
* @param key a standard key to store by
* @return an existing QueryCacheEntry or a new one
*/
protected synchronized RegionQueryCacheEntry get(Object key) {
RegionQueryCacheEntry entry = cache.get(key);
if (entry == null) {
entry = new RegionQueryCacheEntry();
cache.put(key, entry);
}
return entry;
}
}
@@ -0,0 +1,125 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* GNU General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.region;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang.Validate;
import com.sk89q.worldguard.region.indices.RegionIndex;
/**
* Container for the results of region queries issued to {@link RegionIndex}es.
* <p>
* The list of regions in this object are sorted according to
* {@link Region#compareTo(Region)}, so the highest priority regions will
* be emitted by the iterator first.
*/
public class ApplicableRegionSet implements Iterable<Region>, Collection<Region> {
private List<Region> regions;
/**
* Construct the object.
* <p>
* The given list does not have to be sorted as this set will do the
* sorting in-place. Once the region set is constructed, the list given
* to it must not be modified outside the instance of this class.
*
* @param regions the regions to be contained by this set
*/
public ApplicableRegionSet(List<Region> regions) {
Validate.notNull(regions);
Collections.sort(regions);
this.regions = regions;
}
/**
* Get the number of regions that are included.
*
* @return the size of this set
*/
public int size() {
return regions.size();
}
@Override
public Iterator<Region> iterator() {
return regions.iterator();
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public boolean contains(Object o) {
return regions.contains(o);
}
@Override
public Object[] toArray() {
return regions.toArray();
}
@Override
public <T> T[] toArray(T[] a) {
return regions.toArray(a);
}
@Override
public boolean add(Region e) {
throw new UnsupportedOperationException("Cannot modify ApplicableRegionSets");
}
@Override
public boolean remove(Object o) {
throw new UnsupportedOperationException("Cannot modify ApplicableRegionSets");
}
@Override
public boolean containsAll(Collection<?> c) {
return regions.containsAll(c);
}
@Override
public boolean addAll(Collection<? extends Region> c) {
throw new UnsupportedOperationException("Cannot modify ApplicableRegionSets");
}
@Override
public boolean removeAll(Collection<?> c) {
throw new UnsupportedOperationException("Cannot modify ApplicableRegionSets");
}
@Override
public boolean retainAll(Collection<?> c) {
throw new UnsupportedOperationException("Cannot modify ApplicableRegionSets");
}
@Override
public void clear() {
throw new UnsupportedOperationException("Cannot modify ApplicableRegionSets");
}
}
@@ -0,0 +1,289 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY), without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.region;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang.Validate;
import com.sk89q.worldguard.region.attribute.Attribute;
import com.sk89q.worldguard.region.shapes.IndexableShape;
/**
* A region that has an ID, shape, priority, parent, and attributes assigned to
* it. It is used for defining areas on a world.
* <p>
* The casing of region IDs are maintained, but they are case insensitive for
* the purposes of indexing.
* <p>
* If changes are made to this region, and it is contained within a region
* index, the index must be notified of the change.
*/
public class Region implements Comparable<Region> {
private final String id;
private IndexableShape shape;
private int priority = 0;
private Region parent;
private Map<String, Attribute> attributes = new HashMap<String, Attribute>();
/**
* Construct a new instance of this region.
*
* @param id the ID of the region
* @param shape the shape of the region
*/
public Region(String id, IndexableShape shape) {
Validate.notNull(id, "Region ID cannot be null");
Validate.notNull(shape, "Shape parameter cannot be null");
this.id = id;
this.shape = shape;
}
/**
* Gets the ID of this region. IDs maintain casing but are case insensitive
* during comparison.
*
* @return the id
*/
public String getId() {
return id;
}
/**
* Get the shape defining this region.
*
* @return a shape
*/
public IndexableShape getShape() {
return shape;
}
/**
* Set a shape defining this region.
*
* @param shape a shape
*/
public void setShape(IndexableShape shape) {
Validate.notNull(shape, "Shape parameter cannot be null");
this.shape = shape;
}
/**
* Get the priority of the region. Priorities determine the resolution order of
* flags, where greater numbers indicate higher precedence. The default priority
* of a newly created region is 0, and negative priorities are also supported.
*
* @return the priority
*/
public int getPriority() {
return priority;
}
/**
* Set the priority of the region.
*
* @see #getPriority() for an explanation of priorities
* @param priority the priority
*/
public void setPriority(int priority) {
this.priority = priority;
}
/**
* Get the parent of the region. Parents can determine how multiple overlapping
* regions are handled in regards to some flags, but it is dependent on the flag.
*
* @return parent region or null
*/
public Region getParent() {
return parent;
}
/**
* Set the parent of this region.
*
* @see #getParent() for an explanation of parents
* @param parent the new parent, or null
* @throws IllegalArgumentException when circular inheritance is detected
*/
public synchronized void setParent(Region parent) throws IllegalArgumentException {
if (parent == null) {
this.parent = null;
} else {
if (parent == this) {
throw new IllegalArgumentException(
"Circular region inheritance detected");
}
Region p = parent.getParent();
while (p != null) {
if (p == this) {
throw new IllegalArgumentException(
"Circular region inheritance detected");
}
p = p.getParent();
}
this.parent = parent;
}
}
/**
* Set an attribute to this region.
* <p>
* While more than one region can share an attribute object, this is not
* recommended. On region index save and then load, the attribute would
* be re-created individually for each region.
* <p>
* If an attribute of the same name already exists on this region, the
* existing attribute will be replaced with the given one. Attribute
* names are case-sensitive.
* <p>
* This method is thread-safe.
*
* @param attribute the attribute
*/
public synchronized void set(Attribute attribute) {
attributes.put(attribute.getName(), attribute);
}
/**
* Remove an attribute with the same name from this region.
* <p>
* Attribute names are case-sensitive. This method is thread-safe.
*
* @param attribute the attribute
*/
public synchronized void remove(Attribute attribute) {
attributes.remove(attribute.getName());
}
/**
* Returns whether this region contains this attribute.
* <p>
* Recall that {@link Attribute#equals(Object)} is true if two attributes
* have the same name, and so this merely checks whether an attribute
* of the same name exists on this region. Attribute names are
* case-sensitive.
* <p>
* This method is thread-safe.
*
* @param attribute the attribute
* @return true if this region contains the attribute
*/
public synchronized boolean contains(Attribute attribute) {
return attributes.containsKey(attribute.getName());
}
/**
* Get the actual stored attribute on this region based on the attribute
* type given as a parameter.
* <p>
* The returned object may or may not be the same as the given object,
* but the returned attribute will definitely have the same name. Attribute
* names are case-sensitive.
* <p>
* At the moment, if the attribute stored on this region is of a different
* type than the given attribute, that is an undefined situation and
* bad things will occur.
*
* @param attribute attribute to get
* @return the attribute stored on this region or null otherwise
*/
@SuppressWarnings("unchecked")
public synchronized <E extends Attribute> E get(E attribute) {
return (E) attributes.get(attribute.getName());
}
/**
* Rename the given attribute to a new name, and add the attribute to
* this region if doesn't already exist on this region.
* <p>
* This is the only safe way to rename an attribute, assuming that the
* given attribute is not being used across several regions
* (not good!). Attribute names are also case-sensitive. Attempting
* to rename an attribute to the same name does nothing.
* <p>
* While this method is thread safe, the given attribute must not change
* in another thread in the process of the rename operation.
*
* @param attribute attribute to rename
* @param newName new attribute name to use
*/
public synchronized void rename(Attribute attribute, String newName) {
if (attribute.getName().equals(newName)) return;
remove(attribute);
attribute.setName(newName);
set(attribute);
}
/**
* Compares to another region.
* <ul>
* <li>Orders primarily by the priority, descending</li>
* <li>Orders secondarily by the id, ascending</li>
* </ul>
*
* @param other the region to compare to
*/
@Override
public int compareTo(Region other) {
if (priority > other.priority) {
return -1;
} else if (priority < other.priority) {
return 1;
}
return id.compareTo(other.id);
}
/**
* Returns whether this is a high frequency region that should be placed in a
* faster index for frequent access. Indices may or may not adhere to the
* return value of this method.
*
* @return true if this is a high frequency region.
*/
public boolean shouldCache() {
return false;
}
/**
* Returns whether this region has the same ID as another region.
*/
@Override
public boolean equals(Object obj) {
if (!(obj instanceof Region)) {
return false;
}
Region other = (Region) obj;
return other.getId().equals(getId());
}
@Override
public int hashCode(){
return id.hashCode();
}
}
@@ -16,7 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection;
package com.sk89q.worldguard.region;
import static com.sk89q.worldguard.bukkit.BukkitUtil.toVector;
@@ -24,6 +24,7 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.RunnableFuture;
import java.util.logging.Level;
import org.bukkit.Location;
@@ -36,14 +37,13 @@ import com.sk89q.worldguard.bukkit.BukkitUtil;
import com.sk89q.worldguard.bukkit.ConfigurationManager;
import com.sk89q.worldguard.bukkit.WorldConfiguration;
import com.sk89q.worldguard.bukkit.WorldGuardPlugin;
import com.sk89q.worldguard.protection.databases.ProtectionDatabaseException;
import com.sk89q.worldguard.protection.databases.ProtectionDatabase;
import com.sk89q.worldguard.protection.databases.YAMLDatabase;
import com.sk89q.worldguard.protection.databases.MySQLDatabase;
import com.sk89q.worldguard.protection.flags.StateFlag;
import com.sk89q.worldguard.protection.managers.FlatRegionManager;
import com.sk89q.worldguard.protection.managers.PRTreeRegionManager;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.region.flags.StateFlag;
import com.sk89q.worldguard.region.indices.PriorityRTreeIndex;
import com.sk89q.worldguard.region.indices.RegionIndex;
import com.sk89q.worldguard.region.stores.LegacyMySqlStore;
import com.sk89q.worldguard.region.stores.ProtectionDatabaseException;
import com.sk89q.worldguard.region.stores.RegionStore;
import com.sk89q.worldguard.region.stores.YamlStore;
/**
* This class keeps track of region information for every world. It loads
@@ -52,7 +52,7 @@ import com.sk89q.worldguard.protection.managers.RegionManager;
* @author sk89q
* @author Redecouverte
*/
public class GlobalRegionManager {
public class RegionManager {
/**
* Reference to the plugin.
@@ -67,7 +67,7 @@ public class GlobalRegionManager {
/**
* Map of managers per-world.
*/
private ConcurrentHashMap<String, RegionManager> managers;
private ConcurrentHashMap<String, RegionIndex> managers;
/**
* Stores the list of modification dates for the world files. This allows
@@ -80,10 +80,10 @@ public class GlobalRegionManager {
*
* @param plugin The plugin instance
*/
public GlobalRegionManager(WorldGuardPlugin plugin) {
public RegionManager(WorldGuardPlugin plugin) {
this.plugin = plugin;
config = plugin.getGlobalStateManager();
managers = new ConcurrentHashMap<String, RegionManager>();
managers = new ConcurrentHashMap<String, RegionIndex>();
lastModified = new HashMap<String, Long>();
}
@@ -112,7 +112,7 @@ public class GlobalRegionManager {
* @param name The name of the world to unload
*/
public void unload(String name) {
RegionManager manager = managers.remove(name);
RegionIndex manager = managers.remove(name);
if (manager != null) {
lastModified.remove(name);
@@ -127,8 +127,8 @@ public class GlobalRegionManager {
lastModified.clear();
}
public RegionManager load(World world) {
RegionManager manager = create(world);
public RegionIndex load(World world) {
RegionIndex manager = create(world);
managers.put(world.getName(), manager);
return manager;
}
@@ -139,25 +139,25 @@ public class GlobalRegionManager {
* @param world The world to load a RegionManager for
* @return the loaded RegionManager
*/
public RegionManager create(World world) {
public RegionIndex create(World world) {
String name = world.getName();
boolean sql = config.useSqlDatabase;
ProtectionDatabase database;
RegionStore database;
File file = null;
try {
if (!sql) {
file = getPath(name);
database = new YAMLDatabase(file, plugin.getLogger());
database = new YamlStore(file, plugin.getLogger());
// Store the last modification date so we can track changes
lastModified.put(name, file.lastModified());
} else {
database = new MySQLDatabase(config, name, plugin.getLogger());
database = new LegacyMySqlStore(config, name, plugin.getLogger());
}
// Create a manager
RegionManager manager = new PRTreeRegionManager(database);
RegionIndex manager = new PriorityRTreeIndex(database);
manager.load();
plugin.getLogger().info(manager.getRegions().size()
@@ -229,9 +229,9 @@ public class GlobalRegionManager {
* @param world The world to get a RegionManager for
* @return The region manager.
*/
public RegionManager get(World world) {
RegionManager manager = managers.get(world.getName());
RegionManager newManager = null;
public RegionIndex get(World world) {
RegionIndex manager = managers.get(world.getName());
RegionIndex newManager = null;
while (manager == null) {
if (newManager == null) {
@@ -297,7 +297,7 @@ public class GlobalRegionManager {
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (!hasBypass(player, world)) {
RegionManager mgr = get(world);
RegionIndex mgr = get(world);
if (!mgr.getApplicableRegions(BukkitUtil.toVector(loc))
.canBuild(localPlayer)) {
@@ -323,7 +323,7 @@ public class GlobalRegionManager {
LocalPlayer localPlayer = plugin.wrapPlayer(player);
if (!hasBypass(player, world)) {
RegionManager mgr = get(world);
RegionIndex mgr = get(world);
final ApplicableRegionSet applicableRegions = mgr.getApplicableRegions(BukkitUtil.toVector(loc));
if (!applicableRegions.canBuild(localPlayer)) {
@@ -340,7 +340,7 @@ public class GlobalRegionManager {
/**
* Checks to see whether a flag is allowed.
*
* @see #allows(com.sk89q.worldguard.protection.flags.StateFlag, org.bukkit.Location, com.sk89q.worldguard.LocalPlayer)
* @see #allows(com.sk89q.worldguard.region.flags.StateFlag, org.bukkit.Location, com.sk89q.worldguard.LocalPlayer)
* @param flag The flag to check
* @param loc The location to check the flag at
* @return Whether the flag is allowed
@@ -354,7 +354,7 @@ public class GlobalRegionManager {
*
* @param flag The flag to check
* @param loc The location to check the flag at
* @param player The player to check for the flag's {@link com.sk89q.worldguard.protection.flags.RegionGroup}
* @param player The player to check for the flag's {@link com.sk89q.worldguard.region.flags.RegionGroup}
* @return Whether the flag is allowed
*/
public boolean allows(StateFlag flag, Location loc, LocalPlayer player) {
@@ -365,7 +365,11 @@ public class GlobalRegionManager {
return true;
}
RegionManager mgr = get(world);
RegionIndex mgr = get(world);
return mgr.getApplicableRegions(toVector(loc)).allows(flag, player);
}
public void queue(RunnableFuture<?> future) {
}
}
@@ -16,23 +16,22 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection;
package com.sk89q.worldguard.region;
import java.util.HashMap;
import java.util.Map;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldguard.protection.managers.RegionManager;
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
import com.sk89q.worldguard.region.indices.RegionIndex;
/**
* An object to cache a list of {@link ApplicableRegionSet}s. This class is
* thread-safe.
*
* @see RegionQueryCache
* @see AbstractRegionQueryCache
*/
public class RegionQueryCacheEntry {
public final class RegionQueryCacheEntry {
private final Map<BlockVector, ApplicableRegionSet> cachedPoints =
new HashMap<BlockVector, ApplicableRegionSet>();
@@ -48,7 +47,7 @@ public class RegionQueryCacheEntry {
* @param location the location to lookup
* @return the applicable region set
*/
public synchronized ApplicableRegionSet lookup(RegionManager manager, Vector location) {
public synchronized ApplicableRegionSet lookup(RegionIndex manager, Vector location) {
BlockVector hashableLocation = location.toBlockVector();
ApplicableRegionSet set = cachedPoints.get(hashableLocation);
if (set == null) {
@@ -68,8 +67,8 @@ public class RegionQueryCacheEntry {
* the area to lookup
* @return the applicable region set
*/
public synchronized ApplicableRegionSet lookup(RegionManager manager,
ProtectedRegion region) {
public synchronized ApplicableRegionSet lookup(RegionIndex manager,
Region region) {
return manager.getApplicableRegions(region);
}
@@ -17,7 +17,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.protection;
package com.sk89q.worldguard.region;
public class UnsupportedIntersectionException extends Exception {
private static final long serialVersionUID = 6423189392345575148L;
@@ -0,0 +1,182 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY), without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.region.attribute;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.commons.lang.Validate;
import com.sk89q.worldguard.region.Region;
/**
* Attributes can be attached to regions to store all sorts of data.
* <p>
* Example attributes include:</p>
* <ul>
* <li>PvP allow/denial flag</li>
* <li>Owner of the region</li>
* <li>Faction of the region</li>
* <li>A picture of your crush</li>
* </ul>
* <p>
* Asking for attributes from a region will return a subclass of
* this class, which can be either an instance of {@link ByteArray}
* or a custom overriding attribute class available in WorldGuard or
* from another project.
* <p>
* Creating your attributes to store any type of data is easy. The most
* important decision to make is whether to use {@link ByteArray}
* or your own subclass. The latter lets you store the attribute data
* in a structure more native to your software (using primitive data types and
* your own objects), but it may be not be necessary if your payload does
* consist of raw binary data, which is what {@link ByteArray} does.
* <p>
* When you make a subclass, you must define the
* {@link #read(DataInputStream, int)} and
* {@link #write(DataOutputStream)} methods so that the incoming data
* can be deserialized and the outgoing data can be serialized. The reason is
* because whatever is storing the region data has to ultimately store the
* data as a series of ones and zeros, and rather than using Java's native
* serialization routines (which may be subject to change), we instead
* delegate that task explicitly to each attribute. Remember that is important
* to choose a format that can be changed in the future and still maintain
* backwards compatibility.
* <p>
* During loading, subclasses will automatically be found by searching
* the classpath, as the canonical name of each attribute's class is saved
* during saving. The process involved here is outlined more closely on
* the WorldGuard wiki. If worse comes to worse, and the subclass cannot
* be found, then the data will be loaded as an {@link ByteArray},
* which prevents loss of the raw binary data, but it will render the
* data unusuable during runtime unless explicitly deserialization is
* conducted when recalling the attribute.
*/
public abstract class Attribute {
private String name = "unnamed";
/**
* A constructor required for automatic instantiation of attributes.
* <p>
* If you are overriding this class, you must provide this constructor.
* Be aware that the default name of attributes is 'unnamed'.
*/
public Attribute() {
}
/**
* Construct an instance and set the name.
* <p>
* Subclasses do not have to provide this constructor but it is helpful
* to do so.
*
* @param name the name to set
* @see #setName(String)
*/
public Attribute(String name) {
setName(name);
}
/**
* Get the name of this attribute.
* <p>
* Attribute names allow for distinguishing different attributes (such as
* between a PvP flag and an image storage attribute). A region cannot have
* two attributes with the same name.
*
* @return the name of the attribute
*/
public String getName() {
return name;
}
/**
* Set the name of an attribute.
* <p>
* Remember that the corresponding {@link Region} must be made aware of this
* change or very bad things may happen.
* <p>
* All valid non-empty Unicode strings are supported for names.
*
* @param name
* new name to use
* @see Region#rename(Attribute, String)
*/
public void setName(String name) {
Validate.notNull(name);
Validate.notEmpty(name);
this.name = name;
}
/**
* Read the input data stream and do something with the incoming data.
* <p>
* This method is called whenever the attribute is being unserialized
* from persistent storage.
*
* @param in input data stream
* @param len length of the data
* @throw IOException thrown on read error, which would cause the instance
* of this class to fail, causing the region index to
* fall back to {@link ByteArray}
*/
public abstract void read(DataInputStream in, int len) throws IOException;
/**
* Write out this attribute's data.
* <p>
* This method is called whenever the attribute is being serialized.
*
* @param out output data stream
* @throw IOException thrown on write error, which is really bad and would
* cause data loss
*/
public abstract void write(DataOutputStream out) throws IOException;
/**
* Hash codes are based on attribute name.
*/
@Override
public int hashCode() {
return getName().hashCode();
}
/**
* Two attributes are equal if they have the same name.
*/
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (!(obj instanceof Attribute)) {
return false;
}
return getName().equals(((Attribute) obj).getName());
}
@Override
public String toString() {
return "Attribute(" + getName() + ")";
}
}
@@ -0,0 +1,102 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY), without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.region.attribute;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.commons.lang.Validate;
/**
* Stores raw byte array data.
* <p>
* If no more accurate {@link Attribute} class is found during deserialization,
* this class is used because it would maintain the data. If you wish to create
* your own {@link Attribute}s, consider subclassing that class rather than
* using this class.
*
* @see Managed another way to store byte arrays (with more memory cost and null
* support)
*/
public final class ByteArray extends Attribute {
private byte[] value;
/**
* Construct the attribute with a default name.
*/
public ByteArray() {
super();
}
/**
* Construct the attribute with a given name.
*/
public ByteArray(String name) {
super(name);
}
/**
* Get the raw byte array.
* <p>
* Modifying the returned byte array directly modifies the byte
* array stored within the instance of this class.
*
* @return data
*/
public byte[] getValue() {
return value;
}
/**
* Set the raw byte array.
* <p>
* The given byte array is stored as a reference within this instance.
*
* @param data new data
*/
public void setValue(byte[] value) {
Validate.notNull(value);
this.value = value;
}
/**
* Get the size in bytes of the data.
*
* @return length in bytes of data
*/
public int size() {
return value.length;
}
@Override
public void read(DataInputStream in, int len) throws IOException {
byte[] buffer = new byte[len];
in.read(buffer, 0, len);
this.value = buffer;
}
@Override
public void write(DataOutputStream out) throws IOException {
out.write(value);
}
}
@@ -0,0 +1,85 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY), without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.region.attribute;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
/**
* An attribute that stores two states (booleans).
*
* @see Managed another way to store booleans (with more memory cost and null
* support)
*/
public class Flag extends Attribute {
private boolean value;
/**
* Construct an instance and assign a default name.
*
* @see Attribute#Attribute() for basic mechanics
*/
public Flag() {
}
/**
* Construct an instance and specify an attribute name.
*
* @param name name of the attribute
*/
public Flag(String name) {
super(name);
}
/**
* Get the value.
*
* @return the value
*/
public boolean getValue() {
return value;
}
/**
* Set the value.
*
* @param value the new value
*/
public void setValue(boolean value) {
this.value = value;
}
@Override
public void read(DataInputStream in, int len) throws IOException {
value = in.readBoolean();
}
@Override
public void write(DataOutputStream out) throws IOException {
out.writeBoolean(value);
}
@Override
public String toString() {
return String.valueOf(value);
}
}
@@ -0,0 +1,85 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY), without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.region.attribute;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
/**
* An attribute that stores doubles.
*
* @see Managed another way to store numbers (with more memory cost and null
* support)
*/
public class Fraction extends Attribute {
private double value;
/**
* Construct an instance and assign a default name.
*
* @see Attribute#Attribute() for basic mechanics
*/
public Fraction() {
}
/**
* Construct an instance and specify an attribute name.
*
* @param name name of the attribute
*/
public Fraction(String name) {
super(name);
}
/**
* Get the value.
*
* @return the value
*/
public double getValue() {
return value;
}
/**
* Set the value.
*
* @param value the new value
*/
public void setValue(double value) {
this.value = value;
}
@Override
public void read(DataInputStream in, int len) throws IOException {
value = in.readDouble();
}
@Override
public void write(DataOutputStream out) throws IOException {
out.writeDouble(value);
}
@Override
public String toString() {
return String.valueOf(value);
}
}
@@ -0,0 +1,96 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY), without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.region.attribute;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* An attribute that serializes and de-serializes objects automatically
* using Java's serialization methods.
* <p>
* This class allows for null values.
*/
public class Managed<T> extends Attribute {
private T value;
/**
* Construct an instance and assign a default name.
*
* @see Attribute#Attribute() for basic mechanics
*/
public Managed() {
}
/**
* Construct an instance and specify an attribute name.
*
* @param name name of the attribute
*/
public Managed(String name) {
super(name);
}
/**
* Get the value.
*
* @return the value or null
*/
public T getValue() {
return value;
}
/**
* Set the value.
*
* @param value the new value or null
*/
public void setValue(T value) {
this.value = value;
}
@SuppressWarnings("unchecked")
@Override
public void read(DataInputStream in, int len) throws IOException {
ObjectInputStream objIn = new ObjectInputStream(in);
try {
value = (T) objIn.readObject();
} catch (ClassCastException e) {
throw new IOException("Deserialized object was something else", e);
} catch (ClassNotFoundException e) {
throw new IOException("Deserialized object uses class not found", e);
}
}
@Override
public void write(DataOutputStream out) throws IOException {
ObjectOutputStream objOut = new ObjectOutputStream(out);
objOut.writeObject(out);
}
@Override
public String toString() {
return String.valueOf(value);
}
}
@@ -0,0 +1,93 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY), without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.region.attribute;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import org.apache.commons.lang.Validate;
/**
* An attribute that stores strings.
* <p>
* Compared to {@link Managed}, strings stored with this class use less
* space and memory. Be aware that strings stored with this class
* are limited to the size of an unsigned short.
*
* @see Managed another way to store strings (with more memory cost and null
* support)
*/
public class Message extends Attribute {
private String value = "";
/**
* Construct an instance and assign a default name.
*
* @see Attribute#Attribute() for basic mechanics
*/
public Message() {
}
/**
* Construct an instance and specify an attribute name.
*
* @param name name of the attribute
*/
public Message(String name) {
super(name);
}
/**
* Get the value.
*
* @return the value
*/
public String getValue() {
return value;
}
/**
* Set the value.
*
* @param value the new value (cannot be null)
*/
public void setValue(String value) {
Validate.notNull(value);
this.value = value;
}
@Override
public void read(DataInputStream in, int len) throws IOException {
value = in.readUTF();
}
@Override
public void write(DataOutputStream out) throws IOException {
out.writeUTF(value);
}
@Override
public String toString() {
return String.valueOf(value);
}
}
@@ -0,0 +1,86 @@
// $Id$
/*
* This file is a part of WorldGuard.
* Copyright (c) sk89q <http://www.sk89q.com>
* Copyright (c) the WorldGuard team and contributors
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY), without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldguard.region.attribute;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
/**
* An attribute that stores whole numbers (integers) with a range of
* {@link Integer#MIN_VALUE} to {@link Integer#MAX_VALUE}.
*
* @see Managed another way to store numbers (with more memory cost and null
* support)
*/
public class Number extends Attribute {
private int value;
/**
* Construct an instance and assign a default name.
*
* @see Attribute#Attribute() for basic mechanics
*/
public Number() {
}
/**
* Construct an instance and specify an attribute name.
*
* @param name name of the attribute
*/
public Number(String name) {
super(name);
}
/**
* Get the value.
*
* @return the value
*/
public int getValue() {
return value;
}
/**
* Set the value.
*
* @param value the new value
*/
public void setValue(int value) {
this.value = value;
}
@Override
public void read(DataInputStream in, int len) throws IOException {
value = in.readInt();
}
@Override
public void write(DataOutputStream out) throws IOException {
out.write(value);
}
@Override
public String toString() {
return String.valueOf(value);
}
}
Loaded 100 of 144 files, more files were not shown because too many files have changed in this diff. Show more