Store the entire player's list of groups instead of primary group

This commit is contained in:
Gabriele C 2017-07-01 19:18:42 +02:00
parent 1fde9bf534
commit c758e15cd7
13 changed files with 136 additions and 69 deletions

View File

@ -72,7 +72,7 @@ class LimboPlayerViewer implements DebugSection {
.sendEntry("Location", p -> formatLocation(p.getLocation()), l -> formatLocation(l.getLocation())) .sendEntry("Location", p -> formatLocation(p.getLocation()), l -> formatLocation(l.getLocation()))
.sendEntry("Prim. group", .sendEntry("Prim. group",
p -> permissionsManager.hasGroupSupport() ? permissionsManager.getPrimaryGroup(p) : "N/A", p -> permissionsManager.hasGroupSupport() ? permissionsManager.getPrimaryGroup(p) : "N/A",
LimboPlayer::getGroup); LimboPlayer::getGroups);
} }
@Override @Override

View File

@ -9,6 +9,8 @@ import org.bukkit.entity.Player;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.Collection;
import java.util.Collections;
/** /**
* Changes the permission group according to the auth status of the player and the configuration. * Changes the permission group according to the auth status of the player and the configuration.
@ -48,24 +50,28 @@ class AuthGroupHandler implements Reloadable {
return; return;
} }
String primaryGroup = limbo == null ? "" : limbo.getGroup(); Collection<String> previousGroups = limbo == null ? Collections.emptyList() : limbo.getGroups();
switch (groupType) { switch (groupType) {
// Implementation note: some permission systems don't support players not being in any group, // Implementation note: some permission systems don't support players not being in any group,
// so add the new group before removing the old ones // so add the new group before removing the old ones
case UNREGISTERED: case UNREGISTERED:
permissionsManager.addGroup(player, unregisteredGroup); permissionsManager.addGroup(player, unregisteredGroup);
permissionsManager.removeGroups(player, registeredGroup, primaryGroup); permissionsManager.removeGroup(player, registeredGroup);
permissionsManager.removeGroups(player, previousGroups);
break; break;
case REGISTERED_UNAUTHENTICATED: case REGISTERED_UNAUTHENTICATED:
permissionsManager.addGroup(player, registeredGroup); permissionsManager.addGroup(player, registeredGroup);
permissionsManager.removeGroups(player, unregisteredGroup, primaryGroup); permissionsManager.removeGroup(player, unregisteredGroup);
permissionsManager.removeGroups(player, previousGroups);
break; break;
case LOGGED_IN: case LOGGED_IN:
permissionsManager.addGroup(player, primaryGroup); permissionsManager.addGroups(player, previousGroups);
permissionsManager.removeGroups(player, unregisteredGroup, registeredGroup); permissionsManager.removeGroup(player, unregisteredGroup);
permissionsManager.removeGroup(player, registeredGroup);
break; break;
default: default:

View File

@ -4,6 +4,9 @@ import fr.xephi.authme.task.MessageTask;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
import java.util.Collection;
import java.util.List;
/** /**
* Represents a player which is not logged in and keeps track of certain states (like OP status, flying) * Represents a player which is not logged in and keeps track of certain states (like OP status, flying)
* which may be revoked from the player until he has logged in or registered. * which may be revoked from the player until he has logged in or registered.
@ -15,17 +18,17 @@ public class LimboPlayer {
private final boolean canFly; private final boolean canFly;
private final boolean operator; private final boolean operator;
private final String group; private Collection<String> groups;
private final Location loc; private final Location loc;
private final float walkSpeed; private final float walkSpeed;
private final float flySpeed; private final float flySpeed;
private BukkitTask timeoutTask = null; private BukkitTask timeoutTask = null;
private MessageTask messageTask = null; private MessageTask messageTask = null;
public LimboPlayer(Location loc, boolean operator, String group, boolean fly, float walkSpeed, float flySpeed) { public LimboPlayer(Location loc, boolean operator, Collection<String> groups, boolean fly, float walkSpeed, float flySpeed) {
this.loc = loc; this.loc = loc;
this.operator = operator; this.operator = operator;
this.group = group; this.groups = groups;
this.canFly = fly; this.canFly = fly;
this.walkSpeed = walkSpeed; this.walkSpeed = walkSpeed;
this.flySpeed = flySpeed; this.flySpeed = flySpeed;
@ -50,12 +53,12 @@ public class LimboPlayer {
} }
/** /**
* Return the player's permissions group. * Return the player's permissions groups.
* *
* @return The permissions group the player belongs to * @return The permissions groups the player belongs to
*/ */
public String getGroup() { public Collection<String> getGroups() {
return group; return groups;
} }
public boolean isCanFly() { public boolean isCanFly() {

View File

@ -9,6 +9,8 @@ import org.bukkit.Location;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.Collection;
import java.util.Collections;
/** /**
* Helper class for the LimboService. * Helper class for the LimboService.
@ -38,11 +40,11 @@ class LimboServiceHelper {
boolean flyEnabled = player.getAllowFlight(); boolean flyEnabled = player.getAllowFlight();
float walkSpeed = player.getWalkSpeed(); float walkSpeed = player.getWalkSpeed();
float flySpeed = player.getFlySpeed(); float flySpeed = player.getFlySpeed();
String playerGroup = permissionsManager.hasGroupSupport() Collection<String> playerGroups = permissionsManager.hasGroupSupport()
? permissionsManager.getPrimaryGroup(player) : ""; ? permissionsManager.getGroups(player) : Collections.emptyList();
ConsoleLogger.debug("Player `{0}` has primary group `{1}`", player.getName(), playerGroup); ConsoleLogger.debug("Player `{0}` has groups `{1}`", player.getName(), String.join(", ", playerGroups));
return new LimboPlayer(location, isOperator, playerGroup, flyEnabled, walkSpeed, flySpeed); return new LimboPlayer(location, isOperator, playerGroups, flyEnabled, walkSpeed, flySpeed);
} }
/** /**
@ -86,18 +88,10 @@ class LimboServiceHelper {
boolean canFly = newLimbo.isCanFly() || oldLimbo.isCanFly(); boolean canFly = newLimbo.isCanFly() || oldLimbo.isCanFly();
float flySpeed = Math.max(newLimbo.getFlySpeed(), oldLimbo.getFlySpeed()); float flySpeed = Math.max(newLimbo.getFlySpeed(), oldLimbo.getFlySpeed());
float walkSpeed = Math.max(newLimbo.getWalkSpeed(), oldLimbo.getWalkSpeed()); float walkSpeed = Math.max(newLimbo.getWalkSpeed(), oldLimbo.getWalkSpeed());
String group = firstNotEmpty(newLimbo.getGroup(), oldLimbo.getGroup()); Collection<String> groups = newLimbo.getGroups();
Location location = firstNotNull(oldLimbo.getLocation(), newLimbo.getLocation()); Location location = firstNotNull(oldLimbo.getLocation(), newLimbo.getLocation());
return new LimboPlayer(location, isOperator, group, canFly, walkSpeed, flySpeed); return new LimboPlayer(location, isOperator, groups, canFly, walkSpeed, flySpeed);
}
private static String firstNotEmpty(String newGroup, String oldGroup) {
ConsoleLogger.debug("Limbo merge: new and old perm groups are `{0}` and `{1}`", newGroup, oldGroup);
if ("".equals(oldGroup)) {
return newGroup;
}
return oldGroup;
} }
private static Location firstNotNull(Location first, Location second) { private static Location firstNotNull(Location first, Location second) {

View File

@ -1,5 +1,6 @@
package fr.xephi.authme.data.limbo.persistence; package fr.xephi.authme.data.limbo.persistence;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer; import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
@ -10,11 +11,15 @@ import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Function; import java.util.function.Function;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.CAN_FLY; import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.CAN_FLY;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.FLY_SPEED; import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.FLY_SPEED;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.GROUP; import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.GROUPS;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.IS_OP; import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.IS_OP;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.LOCATION; import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.LOCATION;
import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.LOC_PITCH; import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.LOC_PITCH;
@ -45,12 +50,13 @@ class LimboPlayerDeserializer implements JsonDeserializer<LimboPlayer> {
Location loc = deserializeLocation(jsonObject); Location loc = deserializeLocation(jsonObject);
boolean operator = getBoolean(jsonObject, IS_OP); boolean operator = getBoolean(jsonObject, IS_OP);
String group = getString(jsonObject, GROUP);
Collection<String> groups = getStringList(jsonObject, GROUPS);
boolean canFly = getBoolean(jsonObject, CAN_FLY); boolean canFly = getBoolean(jsonObject, CAN_FLY);
float walkSpeed = getFloat(jsonObject, WALK_SPEED, LimboPlayer.DEFAULT_WALK_SPEED); float walkSpeed = getFloat(jsonObject, WALK_SPEED, LimboPlayer.DEFAULT_WALK_SPEED);
float flySpeed = getFloat(jsonObject, FLY_SPEED, LimboPlayer.DEFAULT_FLY_SPEED); float flySpeed = getFloat(jsonObject, FLY_SPEED, LimboPlayer.DEFAULT_FLY_SPEED);
return new LimboPlayer(loc, operator, group, canFly, walkSpeed, flySpeed); return new LimboPlayer(loc, operator, groups, canFly, walkSpeed, flySpeed);
} }
private Location deserializeLocation(JsonObject jsonObject) { private Location deserializeLocation(JsonObject jsonObject) {
@ -75,6 +81,19 @@ class LimboPlayerDeserializer implements JsonDeserializer<LimboPlayer> {
return element != null ? element.getAsString() : ""; return element != null ? element.getAsString() : "";
} }
private static List<String> getStringList(JsonObject jsonObject, String memberName) {
JsonElement element = jsonObject.get(memberName);
if (element == null) {
return Collections.emptyList();
}
List<String> result = new ArrayList<>();
JsonArray jsonArray = element.getAsJsonArray();
for (JsonElement arrayElement : jsonArray) {
result.add(arrayElement.getAsString());
}
return result;
}
private static boolean getBoolean(JsonObject jsonObject, String memberName) { private static boolean getBoolean(JsonObject jsonObject, String memberName) {
JsonElement element = jsonObject.get(memberName); JsonElement element = jsonObject.get(memberName);
return element != null && element.getAsBoolean(); return element != null && element.getAsBoolean();
@ -95,10 +114,11 @@ class LimboPlayerDeserializer implements JsonDeserializer<LimboPlayer> {
/** /**
* Gets a number from the given JsonElement safely. * Gets a number from the given JsonElement safely.
* *
* @param jsonElement the element to retrieve the number from * @param jsonElement the element to retrieve the number from
* @param numberFunction the function to get the number from the element * @param numberFunction the function to get the number from the element
* @param defaultValue the value to return if the element is null or the number cannot be retrieved * @param defaultValue the value to return if the element is null or the number cannot be retrieved
* @param <N> the number type * @param <N> the number type
*
* @return the number from the given JSON element, or the default value * @return the number from the given JSON element, or the default value
*/ */
private static <N extends Number> N getNumberFromElement(JsonElement jsonElement, private static <N extends Number> N getNumberFromElement(JsonElement jsonElement,

View File

@ -1,5 +1,7 @@
package fr.xephi.authme.data.limbo.persistence; package fr.xephi.authme.data.limbo.persistence;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonSerializationContext; import com.google.gson.JsonSerializationContext;
@ -8,6 +10,7 @@ import fr.xephi.authme.data.limbo.LimboPlayer;
import org.bukkit.Location; import org.bukkit.Location;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.Collection;
/** /**
* Converts a LimboPlayer to a JsonElement. * Converts a LimboPlayer to a JsonElement.
@ -22,7 +25,7 @@ class LimboPlayerSerializer implements JsonSerializer<LimboPlayer> {
static final String LOC_YAW = "yaw"; static final String LOC_YAW = "yaw";
static final String LOC_PITCH = "pitch"; static final String LOC_PITCH = "pitch";
static final String GROUP = "group"; static final String GROUPS = "groups";
static final String IS_OP = "operator"; static final String IS_OP = "operator";
static final String CAN_FLY = "can-fly"; static final String CAN_FLY = "can-fly";
static final String WALK_SPEED = "walk-speed"; static final String WALK_SPEED = "walk-speed";
@ -42,7 +45,8 @@ class LimboPlayerSerializer implements JsonSerializer<LimboPlayer> {
JsonObject obj = new JsonObject(); JsonObject obj = new JsonObject();
obj.add(LOCATION, locationObject); obj.add(LOCATION, locationObject);
obj.addProperty(GROUP, limboPlayer.getGroup()); obj.add(GROUPS, new Gson().toJsonTree(limboPlayer.getGroups()).getAsJsonArray()); //TODO: maybe we should store the GSON instance somewhere. -sg
obj.addProperty(IS_OP, limboPlayer.isOperator()); obj.addProperty(IS_OP, limboPlayer.isOperator());
obj.addProperty(CAN_FLY, limboPlayer.isCanFly()); obj.addProperty(CAN_FLY, limboPlayer.isCanFly());
obj.addProperty(WALK_SPEED, limboPlayer.getWalkSpeed()); obj.addProperty(WALK_SPEED, limboPlayer.getWalkSpeed());

View File

@ -19,8 +19,10 @@ import org.bukkit.plugin.PluginManager;
import javax.annotation.PostConstruct; import javax.annotation.PostConstruct;
import javax.inject.Inject; import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List;
/** /**
* PermissionsManager. * PermissionsManager.
@ -303,6 +305,33 @@ public class PermissionsManager implements Reloadable {
return handler.addToGroup(player, groupName); return handler.addToGroup(player, groupName);
} }
/**
* Add the permission groups of a player, if supported.
*
* @param player The player
* @param groupNames The name of the groups to add.
*
* @return True if at least one group was added, false otherwise.
* False is also returned if this feature isn't supported for the current permissions system.
*/
public boolean addGroups(Player player, Collection<String> groupNames) {
// If no permissions system is used, return false
if (!isEnabled()) {
return false;
}
// Add each group to the user
boolean result = false;
for (String groupName : groupNames) {
if (!groupName.isEmpty()) {
result |= handler.addToGroup(player, groupName);
}
}
// Return the result
return result;
}
/** /**
* Remove the permission group of a player, if supported. * Remove the permission group of a player, if supported.
* *
@ -312,7 +341,7 @@ public class PermissionsManager implements Reloadable {
* @return True if succeed, false otherwise. * @return True if succeed, false otherwise.
* False is also returned if this feature isn't supported for the current permissions system. * False is also returned if this feature isn't supported for the current permissions system.
*/ */
public boolean removeGroups(Player player, String groupName) { public boolean removeGroup(Player player, String groupName) {
return isEnabled() && handler.removeFromGroup(player, groupName); return isEnabled() && handler.removeFromGroup(player, groupName);
} }
@ -320,12 +349,12 @@ public class PermissionsManager implements Reloadable {
* Remove the permission groups of a player, if supported. * Remove the permission groups of a player, if supported.
* *
* @param player The player * @param player The player
* @param groupNames The name of the groups to add. * @param groupNames The name of the groups to remove.
* *
* @return True if at least one group was removed, false otherwise. * @return True if at least one group was removed, false otherwise.
* False is also returned if this feature isn't supported for the current permissions system. * False is also returned if this feature isn't supported for the current permissions system.
*/ */
public boolean removeGroups(Player player, String... groupNames) { public boolean removeGroups(Player player, Collection<String> groupNames) {
// If no permissions system is used, return false // If no permissions system is used, return false
if (!isEnabled()) { if (!isEnabled()) {
return false; return false;
@ -377,6 +406,6 @@ public class PermissionsManager implements Reloadable {
Collection<String> groupNames = getGroups(player); Collection<String> groupNames = getGroups(player);
// Remove each group // Remove each group
return removeGroups(player, groupNames.toArray(new String[groupNames.size()])); return removeGroups(player, groupNames);
} }
} }

View File

@ -6,6 +6,8 @@ import org.hamcrest.Description;
import org.hamcrest.Matcher; import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher; import org.hamcrest.TypeSafeMatcher;
import java.util.Collection;
import static java.lang.String.format; import static java.lang.String.format;
/** /**
@ -17,29 +19,29 @@ public final class LimboPlayerMatchers {
} }
public static Matcher<LimboPlayer> isLimbo(LimboPlayer limbo) { public static Matcher<LimboPlayer> isLimbo(LimboPlayer limbo) {
return isLimbo(limbo.isOperator(), limbo.getGroup(), limbo.isCanFly(), return isLimbo(limbo.isOperator(), limbo.getGroups(), limbo.isCanFly(),
limbo.getWalkSpeed(), limbo.getFlySpeed()); limbo.getWalkSpeed(), limbo.getFlySpeed());
} }
public static Matcher<LimboPlayer> isLimbo(boolean isOp, String group, boolean canFly, public static Matcher<LimboPlayer> isLimbo(boolean isOp, Collection<String> groups, boolean canFly,
float walkSpeed, float flySpeed) { float walkSpeed, float flySpeed) {
return new TypeSafeMatcher<LimboPlayer>() { return new TypeSafeMatcher<LimboPlayer>() {
@Override @Override
protected boolean matchesSafely(LimboPlayer item) { protected boolean matchesSafely(LimboPlayer item) {
return item.isOperator() == isOp && item.getGroup().equals(group) && item.isCanFly() == canFly return item.isOperator() == isOp && item.getGroups().equals(groups) && item.isCanFly() == canFly
&& walkSpeed == item.getWalkSpeed() && flySpeed == item.getFlySpeed(); && walkSpeed == item.getWalkSpeed() && flySpeed == item.getFlySpeed();
} }
@Override @Override
public void describeTo(Description description) { public void describeTo(Description description) {
description.appendText(format("Limbo with isOp=%s, group=%s, canFly=%s, walkSpeed=%f, flySpeed=%f", description.appendText(format("Limbo with isOp=%s, groups={%s}, canFly=%s, walkSpeed=%f, flySpeed=%f",
isOp, group, canFly, walkSpeed, flySpeed)); isOp, String.join(" ,", groups), canFly, walkSpeed, flySpeed));
} }
@Override @Override
public void describeMismatchSafely(LimboPlayer item, Description description) { public void describeMismatchSafely(LimboPlayer item, Description description) {
description.appendText(format("Limbo with isOp=%s, group=%s, canFly=%s, walkSpeed=%f, flySpeed=%f", description.appendText(format("Limbo with isOp=%s, groups={%s}, canFly=%s, walkSpeed=%f, flySpeed=%f",
item.isOperator(), item.getGroup(), item.isCanFly(), item.getWalkSpeed(), item.getFlySpeed())); item.isOperator(), String.join(" ,", item.getGroups()), item.isCanFly(), item.getWalkSpeed(), item.getFlySpeed()));
} }
}; };
} }

View File

@ -19,6 +19,9 @@ import org.mockito.InjectMocks;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.Collections;
import static fr.xephi.authme.service.BukkitService.TICKS_PER_SECOND; import static fr.xephi.authme.service.BukkitService.TICKS_PER_SECOND;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not; import static org.hamcrest.Matchers.not;
@ -98,7 +101,7 @@ public class LimboPlayerTaskManagerTest {
public void shouldCancelExistingMessageTask() { public void shouldCancelExistingMessageTask() {
// given // given
Player player = mock(Player.class); Player player = mock(Player.class);
LimboPlayer limboPlayer = new LimboPlayer(null, true, "grp", false, 0.1f, 0.0f); LimboPlayer limboPlayer = new LimboPlayer(null, true, Collections.singletonList("grp"), false, 0.1f, 0.0f);
MessageTask existingMessageTask = mock(MessageTask.class); MessageTask existingMessageTask = mock(MessageTask.class);
limboPlayer.setMessageTask(existingMessageTask); limboPlayer.setMessageTask(existingMessageTask);
given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(8); given(settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)).willReturn(8);
@ -149,7 +152,7 @@ public class LimboPlayerTaskManagerTest {
public void shouldCancelExistingTimeoutTask() { public void shouldCancelExistingTimeoutTask() {
// given // given
Player player = mock(Player.class); Player player = mock(Player.class);
LimboPlayer limboPlayer = new LimboPlayer(null, false, "", true, 0.3f, 0.1f); LimboPlayer limboPlayer = new LimboPlayer(null, false, Collections.emptyList(), true, 0.3f, 0.1f);
BukkitTask existingTask = mock(BukkitTask.class); BukkitTask existingTask = mock(BukkitTask.class);
limboPlayer.setTimeoutTask(existingTask); limboPlayer.setTimeoutTask(existingTask);
given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(18); given(settings.getProperty(RestrictionSettings.TIMEOUT)).willReturn(18);

View File

@ -6,6 +6,8 @@ import org.junit.runner.RunWith;
import org.mockito.InjectMocks; import org.mockito.InjectMocks;
import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import java.util.Collections;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue; import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
@ -27,9 +29,9 @@ public class LimboServiceHelperTest {
public void shouldMergeLimboPlayers() { public void shouldMergeLimboPlayers() {
// given // given
Location newLocation = mock(Location.class); Location newLocation = mock(Location.class);
LimboPlayer newLimbo = new LimboPlayer(newLocation, false, "grp-new", false, 0.0f, 0.0f); LimboPlayer newLimbo = new LimboPlayer(newLocation, false, Collections.singletonList("grp-new"), false, 0.0f, 0.0f);
Location oldLocation = mock(Location.class); Location oldLocation = mock(Location.class);
LimboPlayer oldLimbo = new LimboPlayer(oldLocation, true, "grp-old", true, 0.1f, 0.8f); LimboPlayer oldLimbo = new LimboPlayer(oldLocation, true, Collections.singletonList("grp-old"), true, 0.1f, 0.8f);
// when // when
LimboPlayer result = limboServiceHelper.merge(newLimbo, oldLimbo); LimboPlayer result = limboServiceHelper.merge(newLimbo, oldLimbo);
@ -37,7 +39,7 @@ public class LimboServiceHelperTest {
// then // then
assertThat(result.getLocation(), equalTo(oldLocation)); assertThat(result.getLocation(), equalTo(oldLocation));
assertThat(result.isOperator(), equalTo(true)); assertThat(result.isOperator(), equalTo(true));
assertThat(result.getGroup(), equalTo("grp-old")); assertThat(result.getGroups(), equalTo(Collections.singletonList("grp-new")));
assertThat(result.isCanFly(), equalTo(true)); assertThat(result.isCanFly(), equalTo(true));
assertThat(result.getWalkSpeed(), equalTo(0.1f)); assertThat(result.getWalkSpeed(), equalTo(0.1f));
assertThat(result.getFlySpeed(), equalTo(0.8f)); assertThat(result.getFlySpeed(), equalTo(0.8f));
@ -47,8 +49,8 @@ public class LimboServiceHelperTest {
public void shouldFallBackToNewLimboForMissingData() { public void shouldFallBackToNewLimboForMissingData() {
// given // given
Location newLocation = mock(Location.class); Location newLocation = mock(Location.class);
LimboPlayer newLimbo = new LimboPlayer(newLocation, false, "grp-new", true, 0.3f, 0.0f); LimboPlayer newLimbo = new LimboPlayer(newLocation, false, Collections.singletonList("grp-new"), true, 0.3f, 0.0f);
LimboPlayer oldLimbo = new LimboPlayer(null, false, "", false, 0.1f, 0.1f); LimboPlayer oldLimbo = new LimboPlayer(null, false, Collections.emptyList(), false, 0.1f, 0.1f);
// when // when
LimboPlayer result = limboServiceHelper.merge(newLimbo, oldLimbo); LimboPlayer result = limboServiceHelper.merge(newLimbo, oldLimbo);
@ -56,7 +58,7 @@ public class LimboServiceHelperTest {
// then // then
assertThat(result.getLocation(), equalTo(newLocation)); assertThat(result.getLocation(), equalTo(newLocation));
assertThat(result.isOperator(), equalTo(false)); assertThat(result.isOperator(), equalTo(false));
assertThat(result.getGroup(), equalTo("grp-new")); assertThat(result.getGroups(), equalTo(Collections.singletonList("grp-new")));
assertThat(result.isCanFly(), equalTo(true)); assertThat(result.isCanFly(), equalTo(true));
assertThat(result.getWalkSpeed(), equalTo(0.3f)); assertThat(result.getWalkSpeed(), equalTo(0.3f));
assertThat(result.getFlySpeed(), equalTo(0.1f)); assertThat(result.getFlySpeed(), equalTo(0.1f));

View File

@ -19,6 +19,9 @@ import org.junit.runner.RunWith;
import org.mockito.Mock; import org.mockito.Mock;
import org.mockito.Mockito; import org.mockito.Mockito;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Map; import java.util.Map;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
@ -81,7 +84,7 @@ public class LimboServiceTest {
Location playerLoc = mock(Location.class); Location playerLoc = mock(Location.class);
given(spawnLoader.getPlayerLocationOrSpawn(player)).willReturn(playerLoc); given(spawnLoader.getPlayerLocationOrSpawn(player)).willReturn(playerLoc);
given(permissionsManager.hasGroupSupport()).willReturn(true); given(permissionsManager.hasGroupSupport()).willReturn(true);
given(permissionsManager.getPrimaryGroup(player)).willReturn("permgrwp"); given(permissionsManager.getGroups(player)).willReturn(Collections.singletonList("permgrwp"));
// when // when
limboService.createLimboPlayer(player, true); limboService.createLimboPlayer(player, true);
@ -102,7 +105,7 @@ public class LimboServiceTest {
assertThat(limbo.isCanFly(), equalTo(false)); assertThat(limbo.isCanFly(), equalTo(false));
assertThat(limbo.getFlySpeed(), equalTo(0.2f)); assertThat(limbo.getFlySpeed(), equalTo(0.2f));
assertThat(limbo.getLocation(), equalTo(playerLoc)); assertThat(limbo.getLocation(), equalTo(playerLoc));
assertThat(limbo.getGroup(), equalTo("permgrwp")); assertThat(limbo.getGroups(), equalTo(Collections.singletonList("permgrwp")));
} }
@Test @Test
@ -132,7 +135,7 @@ public class LimboServiceTest {
assertThat(limbo.isCanFly(), equalTo(true)); assertThat(limbo.isCanFly(), equalTo(true));
assertThat(limbo.getFlySpeed(), equalTo(0.4f)); assertThat(limbo.getFlySpeed(), equalTo(0.4f));
assertThat(limbo.getLocation(), equalTo(playerLoc)); assertThat(limbo.getLocation(), equalTo(playerLoc));
assertThat(limbo.getGroup(), equalTo("")); assertThat(limbo.getGroups(), equalTo(Collections.emptyList()));
} }
@Test @Test
@ -157,7 +160,7 @@ public class LimboServiceTest {
public void shouldRestoreData() { public void shouldRestoreData() {
// given // given
LimboPlayer limbo = Mockito.spy(convertToLimboPlayer( LimboPlayer limbo = Mockito.spy(convertToLimboPlayer(
newPlayer("John", true, 0.4f, false, 0.0f), null, "")); newPlayer("John", true, 0.4f, false, 0.0f), null, Collections.emptyList()));
getLimboMap().put("john", limbo); getLimboMap().put("john", limbo);
Player player = newPlayer("John", false, 0.2f, false, 0.7f); Player player = newPlayer("John", false, 0.2f, false, 0.7f);
@ -236,8 +239,8 @@ public class LimboServiceTest {
return player; return player;
} }
private static LimboPlayer convertToLimboPlayer(Player player, Location location, String group) { private static LimboPlayer convertToLimboPlayer(Player player, Location location, Collection<String> groups) {
return new LimboPlayer(location, player.isOp(), group, player.getAllowFlight(), return new LimboPlayer(location, player.isOp(), groups, player.getAllowFlight(),
player.getWalkSpeed(), player.getFlySpeed()); player.getWalkSpeed(), player.getFlySpeed());
} }

View File

@ -23,6 +23,7 @@ import org.mockito.Mock;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Collections;
import java.util.UUID; import java.util.UUID;
import static fr.xephi.authme.data.limbo.LimboPlayerMatchers.hasLocation; import static fr.xephi.authme.data.limbo.LimboPlayerMatchers.hasLocation;
@ -45,22 +46,22 @@ public class DistributedFilesPersistenceHandlerTest {
/** Player is in seg32-10110 and should be migrated into seg16-f. */ /** Player is in seg32-10110 and should be migrated into seg16-f. */
private static final UUID MIGRATED_UUID = fromString("f6a97c88-7c8f-c12e-4931-6206d4ca067d"); private static final UUID MIGRATED_UUID = fromString("f6a97c88-7c8f-c12e-4931-6206d4ca067d");
private static final Matcher<LimboPlayer> MIGRATED_LIMBO_MATCHER = private static final Matcher<LimboPlayer> MIGRATED_LIMBO_MATCHER =
isLimbo(false, "noob", true, 0.2f, 0.1f); isLimbo(false, Collections.singletonList("noob"), true, 0.2f, 0.1f);
/** Existing player in seg16-f. */ /** Existing player in seg16-f. */
private static final UUID UUID_FAB69 = fromString("fab69c88-2cd0-1fed-f00d-dead14ca067d"); private static final UUID UUID_FAB69 = fromString("fab69c88-2cd0-1fed-f00d-dead14ca067d");
private static final Matcher<LimboPlayer> FAB69_MATCHER = private static final Matcher<LimboPlayer> FAB69_MATCHER =
isLimbo(false, "", false, 0.2f, 0.1f); isLimbo(false, Collections.emptyList(), false, 0.2f, 0.1f);
/** Player in seg16-8. */ /** Player in seg16-8. */
private static final UUID UUID_STAFF = fromString("88897c88-7c8f-c12e-4931-6206d4ca067d"); private static final UUID UUID_STAFF = fromString("88897c88-7c8f-c12e-4931-6206d4ca067d");
private static final Matcher<LimboPlayer> STAFF_MATCHER = private static final Matcher<LimboPlayer> STAFF_MATCHER =
isLimbo(true, "staff", false, 0.3f, 0.1f); isLimbo(true, Collections.singletonList("staff"), false, 0.3f, 0.1f);
/** Player in seg16-8. */ /** Player in seg16-8. */
private static final UUID UUID_8C679 = fromString("8c679491-1234-abcd-9102-1fa6e0cc3f81"); private static final UUID UUID_8C679 = fromString("8c679491-1234-abcd-9102-1fa6e0cc3f81");
private static final Matcher<LimboPlayer> SC679_MATCHER = private static final Matcher<LimboPlayer> SC679_MATCHER =
isLimbo(false, "primary", true, 0.1f, 0.0f); isLimbo(false, Collections.singletonList("primary"), true, 0.1f, 0.0f);
/** UUID for which no data is stored (belongs to a segment file that does not exist, seg16-4). */ /** UUID for which no data is stored (belongs to a segment file that does not exist, seg16-4). */
private static final UUID UNKNOWN_UUID = fromString("42d1cc0b-8f12-d04a-e7ba-a067d05cdc39"); private static final UUID UNKNOWN_UUID = fromString("42d1cc0b-8f12-d04a-e7ba-a067d05cdc39");
@ -153,10 +154,10 @@ public class DistributedFilesPersistenceHandlerTest {
// given // given
Player uuidToAdd1 = mockPlayerWithUuid(UNKNOWN_UUID); Player uuidToAdd1 = mockPlayerWithUuid(UNKNOWN_UUID);
Location location1 = new Location(mockWorldWithName("1world"), 120, 60, -80, 0.42345f, 120.32f); Location location1 = new Location(mockWorldWithName("1world"), 120, 60, -80, 0.42345f, 120.32f);
LimboPlayer limbo1 = new LimboPlayer(location1, false, "group-1", true, 0.1f, 0.2f); LimboPlayer limbo1 = new LimboPlayer(location1, false, Collections.singletonList("group-1"), true, 0.1f, 0.2f);
Player uuidToAdd2 = mockPlayerWithUuid(UNKNOWN_UUID2); Player uuidToAdd2 = mockPlayerWithUuid(UNKNOWN_UUID2);
Location location2 = new Location(mockWorldWithName("2world"), -40, 20, 33, 4.235f, 8.32299f); Location location2 = new Location(mockWorldWithName("2world"), -40, 20, 33, 4.235f, 8.32299f);
LimboPlayer limbo2 = new LimboPlayer(location2, true, "", false, 0.0f, 0.25f); LimboPlayer limbo2 = new LimboPlayer(location2, true, Collections.emptyList(), false, 0.0f, 0.25f);
// when // when
persistenceHandler.saveLimboPlayer(uuidToAdd1, limbo1); persistenceHandler.saveLimboPlayer(uuidToAdd1, limbo1);

View File

@ -20,6 +20,7 @@ import org.mockito.Mock;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.util.Collections;
import java.util.UUID; import java.util.UUID;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
@ -78,7 +79,7 @@ public class IndividualFilesPersistenceHandlerTest {
assertThat(data.isCanFly(), equalTo(true)); assertThat(data.isCanFly(), equalTo(true));
assertThat(data.getWalkSpeed(), equalTo(0.2f)); assertThat(data.getWalkSpeed(), equalTo(0.2f));
assertThat(data.getFlySpeed(), equalTo(0.1f)); assertThat(data.getFlySpeed(), equalTo(0.1f));
assertThat(data.getGroup(), equalTo("players")); assertThat(data.getGroups(), equalTo(Collections.singletonList("players")));
Location location = data.getLocation(); Location location = data.getLocation();
assertThat(location.getX(), equalTo(-113.219)); assertThat(location.getX(), equalTo(-113.219));
assertThat(location.getY(), equalTo(72.0)); assertThat(location.getY(), equalTo(72.0));
@ -112,8 +113,7 @@ public class IndividualFilesPersistenceHandlerTest {
World world = mock(World.class); World world = mock(World.class);
given(world.getName()).willReturn("player-world"); given(world.getName()).willReturn("player-world");
Location location = new Location(world, 0.2, 102.25, -89.28, 3.02f, 90.13f); Location location = new Location(world, 0.2, 102.25, -89.28, 3.02f, 90.13f);
String group = "primary-grp"; LimboPlayer limbo = new LimboPlayer(location, true, Collections.singletonList("primary-grp"), true, 1.2f, 0.8f);
LimboPlayer limbo = new LimboPlayer(location, true, group, true, 1.2f, 0.8f);
// when // when
handler.saveLimboPlayer(player, limbo); handler.saveLimboPlayer(player, limbo);