From 418b8ff6a7eb45c025abb2791d9b25a047b8cf49 Mon Sep 17 00:00:00 2001 From: sk89q Date: Fri, 1 Aug 2014 17:36:56 -0700 Subject: [PATCH] Add support for UUIDs in domains. --- .../com/sk89q/worldguard/LocalPlayer.java | 29 ++- .../sk89q/worldguard/bukkit/BukkitPlayer.java | 18 +- .../worldguard/domains/DefaultDomain.java | 176 ++++++++++++------ .../com/sk89q/worldguard/domains/Domain.java | 38 +++- .../worldguard/domains/DomainCollection.java | 30 ++- .../sk89q/worldguard/domains/GroupDomain.java | 73 +++++++- .../worldguard/domains/PlayerDomain.java | 134 +++++++++++-- .../java/com/sk89q/worldguard/TestPlayer.java | 16 +- .../worldguard/domains/DefaultDomainTest.java | 120 ++++++++++++ 9 files changed, 536 insertions(+), 98 deletions(-) create mode 100644 src/test/java/com/sk89q/worldguard/domains/DefaultDomainTest.java diff --git a/src/main/java/com/sk89q/worldguard/LocalPlayer.java b/src/main/java/com/sk89q/worldguard/LocalPlayer.java index 45ea8cf3..b1964aa9 100644 --- a/src/main/java/com/sk89q/worldguard/LocalPlayer.java +++ b/src/main/java/com/sk89q/worldguard/LocalPlayer.java @@ -21,16 +21,26 @@ import com.sk89q.worldedit.Vector; +import java.util.UUID; + public abstract class LocalPlayer { + /** - * Get a player's name. + * Get this player's name. * * @return The player's name */ public abstract String getName(); + + /** + * Get this player's unique ID. + * + * @return a UUID + */ + public abstract UUID getUniqueId(); /** - * Returns true if the player is inside a group. + * Returns true if this player is inside a group. * * @param group The group to check * @return Whether this player is in {@code group} @@ -38,42 +48,42 @@ public abstract class LocalPlayer { public abstract boolean hasGroup(String group); /** - * Get the player's position. + * Get this player's position. * * @return The player's position */ public abstract Vector getPosition(); /** - * Kick the player. + * Kick this player. * * @param msg The message to kick the player with */ public abstract void kick(String msg); /** - * Ban the player. + * Ban this player. * * @param msg The message to ban the player with */ public abstract void ban(String msg); /** - * Send the player a message; + * Send this player a message. * * @param msg The message to send to the player */ public abstract void printRaw(String msg); /** - * Get the player's list of groups. + * Get this player's list of groups. * * @return The groups this player is in */ public abstract String[] getGroups(); /** - * Returns whether a player has permission. + * Returns whether this player has permission. * * @param perm The permission to check * @return Whether this player has {@code perm} @@ -82,13 +92,12 @@ public abstract class LocalPlayer { @Override public boolean equals(Object obj) { - return obj instanceof LocalPlayer && ((LocalPlayer) obj).getName().equals(getName()); - } @Override public int hashCode() { return getName().hashCode(); } + } diff --git a/src/main/java/com/sk89q/worldguard/bukkit/BukkitPlayer.java b/src/main/java/com/sk89q/worldguard/bukkit/BukkitPlayer.java index b6587797..8bcd56f5 100644 --- a/src/main/java/com/sk89q/worldguard/bukkit/BukkitPlayer.java +++ b/src/main/java/com/sk89q/worldguard/bukkit/BukkitPlayer.java @@ -25,11 +25,19 @@ import com.sk89q.worldedit.Vector; import com.sk89q.worldguard.LocalPlayer; +import java.util.UUID; + +import static com.google.common.base.Preconditions.checkNotNull; + public class BukkitPlayer extends LocalPlayer { - private Player player; - private WorldGuardPlugin plugin; + + private final WorldGuardPlugin plugin; + private final Player player; public BukkitPlayer(WorldGuardPlugin plugin, Player player) { + checkNotNull(plugin); + checkNotNull(player); + this.plugin = plugin; this.player = player; } @@ -39,6 +47,11 @@ public String getName() { return player.getName(); } + @Override + public UUID getUniqueId() { + return player.getUniqueId(); + } + @Override public boolean hasGroup(String group) { return plugin.inGroup(player, group); @@ -75,4 +88,5 @@ public void printRaw(String msg) { public boolean hasPermission(String perm) { return plugin.hasPermission(player, perm); } + } diff --git a/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java b/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java index 6ba5befa..e8093784 100644 --- a/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java +++ b/src/main/java/com/sk89q/worldguard/domains/DefaultDomain.java @@ -26,76 +26,151 @@ import java.util.Iterator; import java.util.List; import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; +import java.util.UUID; +/** + * A combination of a {@link PlayerDomain} and a {@link GroupDomain}. + */ public class DefaultDomain implements Domain { - private final Set groups; - private final Set players; - - public DefaultDomain() { - this.groups = new CopyOnWriteArraySet(); - this.players = new CopyOnWriteArraySet(); - } - + + private final PlayerDomain playerDomain = new PlayerDomain(); + private final GroupDomain groupDomain = new GroupDomain(); + + /** + * Add the given player to the domain, identified by the player's name. + * + * @param name the name of the player + * @deprecated names are deprecated in favor of UUIDs in MC 1.7+ + */ + @Deprecated public void addPlayer(String name) { - players.add(name.toLowerCase()); + playerDomain.addPlayer(name); } - - public void addPlayer(LocalPlayer player) { - players.add(player.getName().toLowerCase()); - } - + + /** + * Remove the given player from the domain, identified by the player's name. + * + * @param name the name of the player + * @deprecated names are deprecated in favor of UUIDs in MC 1.7+ + */ + @Deprecated public void removePlayer(String name) { - players.remove(name.toLowerCase()); + playerDomain.removePlayer(name); } - + + /** + * Add the given player to the domain, identified by the player's UUID. + * + * @param uniqueId the UUID of the player + */ + public void addPlayer(UUID uniqueId) { + playerDomain.addPlayer(uniqueId); + } + + /** + * Remove the given player from the domain, identified by either the + * player's name, the player's unique ID, or both. + * + * @param player the player + */ public void removePlayer(LocalPlayer player) { - players.remove(player.getName().toLowerCase()); + playerDomain.removePlayer(player); } - - public void addGroup(String name) { - groups.add(name.toLowerCase()); + + /** + * Add the given player to the domain, identified by the player's UUID. + * + * @param player the player + */ + public void addPlayer(LocalPlayer player) { + playerDomain.addPlayer(player); } - - public void removeGroup(String name) { - groups.remove(name.toLowerCase()); - } - - public Set getGroups() { - return groups; - } - + + /** + * Get the set of player names. + * + * @return the set of player names + * @deprecated names are deprecated in favor of UUIDs in MC 1.7+ + */ + @Deprecated public Set getPlayers() { - return players; + return playerDomain.getPlayers(); + } + + /** + * Get the set of player UUIDs. + * + * @return the set of player UUIDs + */ + public Set getUniqueIds() { + return playerDomain.getUniqueIds(); + } + + /** + * Add the name of the group to the domain. + * + * @param name the name of the group. + */ + public void addGroup(String name) { + groupDomain.addGroup(name); + } + + /** + * Remove the given group from the domain. + * + * @param name the name of the group + */ + public void removeGroup(String name) { + groupDomain.removeGroup(name); + } + + /** + * Get the set of group names. + * + * @return the set of group names + */ + public Set getGroups() { + return groupDomain.getGroups(); } @Override public boolean contains(LocalPlayer player) { - if (contains(player.getName())) { - return true; - } + return playerDomain.contains(player) || groupDomain.contains(player); + } - for (String group : groups) { - if (player.hasGroup(group)) { - return true; - } - } - - return false; + @Override + public boolean contains(UUID uniqueId) { + return playerDomain.contains(uniqueId); } @Override public boolean contains(String playerName) { - return players.contains(playerName.toLowerCase()); + return playerDomain.contains(playerName); } + @Override public int size() { - return groups.size() + players.size(); + return groupDomain.size() + playerDomain.size(); } - + + @Override + public void clear() { + playerDomain.clear(); + groupDomain.clear(); + } + + public void removeAll() { + clear(); + } + + @SuppressWarnings("deprecation") public String toPlayersString() { StringBuilder str = new StringBuilder(); - List output = new ArrayList(players); + List output = new ArrayList(); + output.addAll(playerDomain.getPlayers()); + for (UUID uuid : playerDomain.getUniqueIds()) { + output.add("uuid:" + uuid); + } Collections.sort(output, String.CASE_INSENSITIVE_ORDER); for (Iterator it = output.iterator(); it.hasNext();) { str.append(it.next()); @@ -108,7 +183,7 @@ public String toPlayersString() { public String toGroupsString() { StringBuilder str = new StringBuilder(); - for (Iterator it = groups.iterator(); it.hasNext(); ) { + for (Iterator it = groupDomain.getGroups().iterator(); it.hasNext(); ) { str.append("*"); str.append(it.next()); if (it.hasNext()) { @@ -120,11 +195,12 @@ public String toGroupsString() { public String toUserFriendlyString() { StringBuilder str = new StringBuilder(); - if (players.size() > 0) { + + if (playerDomain.size() > 0) { str.append(toPlayersString()); } - if (groups.size() > 0) { + if (groupDomain.size() > 0) { if (str.length() > 0) { str.append("; "); } @@ -135,8 +211,4 @@ public String toUserFriendlyString() { return str.toString(); } - public void removeAll() { - groups.clear(); - players.clear(); - } } diff --git a/src/main/java/com/sk89q/worldguard/domains/Domain.java b/src/main/java/com/sk89q/worldguard/domains/Domain.java index 7eaca201..0d9c3f5a 100644 --- a/src/main/java/com/sk89q/worldguard/domains/Domain.java +++ b/src/main/java/com/sk89q/worldguard/domains/Domain.java @@ -21,21 +21,53 @@ import com.sk89q.worldguard.LocalPlayer; +import java.util.UUID; + +/** + * A domain contains a list of memberships. + */ public interface Domain { + /** * Returns true if a domain contains a player. * - * @param player The player to check + * @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.
- * This method doesn't check for groups! + * Returns true if a domain contains a player. + * + *

This method doesn't check for groups!

+ * + * @param uniqueId the UUID of the user + * @return whether this domain contains a player by that name + */ + boolean contains(UUID uniqueId); + + /** + * Returns true if a domain contains a player. + * + *

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 + * @deprecated names are deprecated in MC 1.7+ in favor of UUIDs */ + @Deprecated boolean contains(String playerName); + + /** + * Get the number of entries. + * + * @return the number of entries + */ + int size(); + + /** + * Remove all entries. + */ + void clear(); + } diff --git a/src/main/java/com/sk89q/worldguard/domains/DomainCollection.java b/src/main/java/com/sk89q/worldguard/domains/DomainCollection.java index f34ec5f7..f149e24a 100644 --- a/src/main/java/com/sk89q/worldguard/domains/DomainCollection.java +++ b/src/main/java/com/sk89q/worldguard/domains/DomainCollection.java @@ -19,12 +19,18 @@ package com.sk89q.worldguard.domains; -import java.util.LinkedHashSet; -import java.util.Set; - import com.sk89q.worldguard.LocalPlayer; +import java.util.LinkedHashSet; +import java.util.Set; +import java.util.UUID; + +/** + * @deprecated not used by WorldGuard and not maintained + */ +@Deprecated public class DomainCollection implements Domain { + private Set domains; public DomainCollection() { @@ -39,10 +45,16 @@ public void remove(Domain domain) { domains.remove(domain); } + @Override public int size() { return domains.size(); } + @Override + public void clear() { + domains.clear(); + } + @Override public boolean contains(LocalPlayer player) { for (Domain domain : domains) { @@ -54,6 +66,17 @@ public boolean contains(LocalPlayer player) { return false; } + @Override + public boolean contains(UUID uniqueId) { + for (Domain domain : domains) { + if (domain.contains(uniqueId)) { + return true; + } + } + + return false; + } + @Override public boolean contains(String playerName) { for (Domain domain : domains) { @@ -64,4 +87,5 @@ public boolean contains(String playerName) { return false; } + } diff --git a/src/main/java/com/sk89q/worldguard/domains/GroupDomain.java b/src/main/java/com/sk89q/worldguard/domains/GroupDomain.java index c5edb7d7..5118d762 100644 --- a/src/main/java/com/sk89q/worldguard/domains/GroupDomain.java +++ b/src/main/java/com/sk89q/worldguard/domains/GroupDomain.java @@ -19,28 +19,62 @@ package com.sk89q.worldguard.domains; -import java.util.Arrays; -import java.util.LinkedHashSet; -import java.util.Set; - import com.sk89q.worldguard.LocalPlayer; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.CopyOnWriteArraySet; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Contains groups in a domain. + */ public class GroupDomain implements Domain { - private Set groups; + private final Set groups = new CopyOnWriteArraySet(); + + /** + * Create a new instance. + */ public GroupDomain() { - this.groups = new LinkedHashSet(); } - public GroupDomain(String[] groups) { - this.groups = new LinkedHashSet(Arrays.asList(groups)); + /** + * Create a new instance. + * + * @param groupsy an array of groups + */ + public GroupDomain(String[] groupsy) { + checkNotNull(groupsy); + for (String group : groupsy) { + addGroup(group); + } } + /** + * Add the name of the group to the domain. + * + * @param name the name of the group. + */ public void addGroup(String name) { - groups.add(name); + checkNotNull(name); + groups.add(name.toLowerCase()); } + /** + * Remove the given group from the domain. + * + * @param name the name of the group + */ + public void removeGroup(String name) { + checkNotNull(name); + groups.remove(name.toLowerCase()); + } + + @Override public boolean contains(LocalPlayer player) { + checkNotNull(player); for (String group : groups) { if (player.hasGroup(group)) { return true; @@ -50,12 +84,33 @@ public boolean contains(LocalPlayer player) { return false; } + /** + * Get the set of group names. + * + * @return the set of group names + */ + public Set getGroups() { + return groups; + } + + @Override + public boolean contains(UUID uniqueId) { + return false; // GroupDomains can't contain UUIDs + } + @Override public boolean contains(String playerName) { return false; // GroupDomains can't contain player names. } + @Override public int size() { return groups.size(); } + + @Override + public void clear() { + groups.clear(); + } + } diff --git a/src/main/java/com/sk89q/worldguard/domains/PlayerDomain.java b/src/main/java/com/sk89q/worldguard/domains/PlayerDomain.java index 0c50a338..d7ae0d60 100644 --- a/src/main/java/com/sk89q/worldguard/domains/PlayerDomain.java +++ b/src/main/java/com/sk89q/worldguard/domains/PlayerDomain.java @@ -19,40 +19,144 @@ 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 players; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.CopyOnWriteArraySet; +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Stores players (only) in a domain. + */ +public class PlayerDomain implements Domain { + + private final Set uniqueIds = new CopyOnWriteArraySet(); + private final Set names = new CopyOnWriteArraySet(); + + /** + * Create a new instance. + */ public PlayerDomain() { - this.players = new HashSet(); } - public PlayerDomain(String[] players) { - this.players = new HashSet(); - - for (String name : players) { - this.players.add(name.toLowerCase()); + /** + * Create a new instance with the given names. + * + * @param names an array of names + * @deprecated names are deprecated in favor of UUIDs in MC 1.7+ + */ + @Deprecated + public PlayerDomain(String[] names) { + for (String name : names) { + addPlayer(name); } } + /** + * Add the given player to the domain, identified by the player's name. + * + * @param name the name of the player + * @deprecated names are deprecated in favor of UUIDs in MC 1.7+ + */ + @Deprecated public void addPlayer(String name) { - players.add(name.toLowerCase()); + checkNotNull(name); + names.add(name.toLowerCase()); } + /** + * Add the given player to the domain, identified by the player's UUID. + * + * @param uniqueId the UUID of the player + */ + public void addPlayer(UUID uniqueId) { + checkNotNull(uniqueId); + uniqueIds.add(uniqueId); + } + + /** + * Add the given player to the domain, identified by the player's UUID. + * + * @param player the player + */ + public void addPlayer(LocalPlayer player) { + checkNotNull(player); + addPlayer(player.getUniqueId()); + } + + /** + * Remove the given player from the domain, identified by the player's name. + * + * @param name the name of the player + * @deprecated names are deprecated in favor of UUIDs in MC 1.7+ + */ + @Deprecated + public void removePlayer(String name) { + checkNotNull(name); + names.remove(name.toLowerCase()); + } + + /** + * Remove the given player from the domain, identified by either the + * player's name, the player's unique ID, or both. + * + * @param player the player + */ + public void removePlayer(LocalPlayer player) { + checkNotNull(player); + names.remove(player.getName().toLowerCase()); + uniqueIds.remove(player.getUniqueId()); + } + + @Override public boolean contains(LocalPlayer player) { - return contains(player.getName()); + checkNotNull(player); + return contains(player.getName()) || contains(player.getUniqueId()); + } + + /** + * Get the set of player names. + * + * @return the set of player names + * @deprecated names are deprecated in favor of UUIDs in MC 1.7+ + */ + @Deprecated + public Set getPlayers() { + return names; + } + + /** + * Get the set of player UUIDs. + * + * @return the set of player UUIDs + */ + public Set getUniqueIds() { + return uniqueIds; + } + + @Override + public boolean contains(UUID uniqueId) { + checkNotNull(uniqueId); + return uniqueIds.contains(uniqueId); } @Override public boolean contains(String playerName) { - return players.contains(playerName.toLowerCase()); + checkNotNull(playerName); + return names.contains(playerName.toLowerCase()); } + @Override public int size() { - return players.size(); + return names.size() + uniqueIds.size(); } + + @Override + public void clear() { + uniqueIds.clear(); + names.clear(); + } + } diff --git a/src/test/java/com/sk89q/worldguard/TestPlayer.java b/src/test/java/com/sk89q/worldguard/TestPlayer.java index 041796b9..21ac0f6a 100644 --- a/src/test/java/com/sk89q/worldguard/TestPlayer.java +++ b/src/test/java/com/sk89q/worldguard/TestPlayer.java @@ -19,15 +19,18 @@ package com.sk89q.worldguard; +import com.sk89q.worldedit.Vector; + import java.util.HashSet; import java.util.Set; - -import com.sk89q.worldedit.Vector; +import java.util.UUID; @org.junit.Ignore public class TestPlayer extends LocalPlayer { - private String name; - private Set groups = new HashSet(); + + private final UUID uuid = UUID.randomUUID(); + private final String name; + private final Set groups = new HashSet(); public TestPlayer(String name) { this.name = name; @@ -42,6 +45,11 @@ public String getName() { return name; } + @Override + public UUID getUniqueId() { + return uuid; + } + @Override public boolean hasGroup(String group) { return groups.contains(group.toLowerCase()); diff --git a/src/test/java/com/sk89q/worldguard/domains/DefaultDomainTest.java b/src/test/java/com/sk89q/worldguard/domains/DefaultDomainTest.java new file mode 100644 index 00000000..f1b24cfb --- /dev/null +++ b/src/test/java/com/sk89q/worldguard/domains/DefaultDomainTest.java @@ -0,0 +1,120 @@ +/* + * WorldGuard, a suite of tools for Minecraft + * Copyright (C) sk89q + * Copyright (C) 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 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 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 . + */ + +package com.sk89q.worldguard.domains; + +import com.sk89q.worldguard.TestPlayer; +import junit.framework.TestCase; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +public class DefaultDomainTest extends TestCase { + + public void testContains() throws Exception { + TestPlayer player1 = new TestPlayer("test1"); + TestPlayer player2 = new TestPlayer("test2"); + player2.addGroup("group1"); + player2.addGroup("group2"); + TestPlayer player3 = new TestPlayer("test3"); + player3.addGroup("group1"); + player3.addGroup("group3"); + + DefaultDomain domain; + + domain = new DefaultDomain(); + domain.addGroup("group1"); + assertThat(domain.contains(player1), is(false)); + assertThat(domain.contains(player2), is(true)); + assertThat(domain.contains(player3), is(true)); + + domain = new DefaultDomain(); + domain.addGroup("group1"); + domain.addGroup("group2"); + assertThat(domain.contains(player1), is(false)); + assertThat(domain.contains(player2), is(true)); + assertThat(domain.contains(player3), is(true)); + + domain = new DefaultDomain(); + domain.addGroup("group1"); + domain.addGroup("group3"); + assertThat(domain.contains(player1), is(false)); + assertThat(domain.contains(player2), is(true)); + assertThat(domain.contains(player3), is(true)); + + domain = new DefaultDomain(); + domain.addGroup("group3"); + assertThat(domain.contains(player1), is(false)); + assertThat(domain.contains(player2), is(false)); + assertThat(domain.contains(player3), is(true)); + + domain = new DefaultDomain(); + domain.addPlayer(player1.getName()); + assertThat(domain.contains(player1), is(true)); + assertThat(domain.contains(player2), is(false)); + assertThat(domain.contains(player3), is(false)); + + domain = new DefaultDomain(); + domain.addGroup("group3"); + domain.addPlayer(player1.getName()); + assertThat(domain.contains(player1), is(true)); + assertThat(domain.contains(player2), is(false)); + assertThat(domain.contains(player3), is(true)); + + domain = new DefaultDomain(); + domain.addGroup("group3"); + domain.addPlayer(player1.getUniqueId()); + assertThat(domain.contains(player1), is(true)); + assertThat(domain.contains(player2), is(false)); + assertThat(domain.contains(player3), is(true)); + + domain = new DefaultDomain(); + domain.addGroup("group3"); + domain.addPlayer(player1.getName()); + domain.addPlayer(player1.getUniqueId()); + assertThat(domain.contains(player1), is(true)); + assertThat(domain.contains(player2), is(false)); + assertThat(domain.contains(player3), is(true)); + + domain = new DefaultDomain(); + domain.addGroup("group3"); + domain.addPlayer(player1); + assertThat(domain.contains(player1), is(true)); + assertThat(domain.contains(player2), is(false)); + assertThat(domain.contains(player3), is(true)); + + domain = new DefaultDomain(); + domain.addPlayer(player1); + assertThat(domain.contains(player1), is(true)); + assertThat(domain.contains(player2), is(false)); + assertThat(domain.contains(player3), is(false)); + + domain = new DefaultDomain(); + domain.addPlayer(player2); + domain.addPlayer(player3); + assertThat(domain.contains(player1), is(false)); + assertThat(domain.contains(player2), is(true)); + assertThat(domain.contains(player3), is(true)); + } + + public void testSize() throws Exception { + + } + +} \ No newline at end of file