Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LuckPerm: keep contexts active after reload of groups #2186

Merged
merged 14 commits into from
Aug 21, 2021
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package fr.xephi.authme.command.executable.authme.debug;

import fr.xephi.authme.data.limbo.UserGroup;
import fr.xephi.authme.permission.DebugSectionPermissions;
import fr.xephi.authme.permission.PermissionNode;
import fr.xephi.authme.permission.PermissionsManager;
Expand All @@ -11,6 +12,8 @@
import javax.inject.Inject;
import java.util.List;

import static java.util.stream.Collectors.toList;

/**
* Outputs the permission groups of a player.
*/
Expand All @@ -37,8 +40,11 @@ public void execute(CommandSender sender, List<String> arguments) {
if (player == null) {
sender.sendMessage("Player " + name + " could not be found");
} else {
sender.sendMessage("Player " + name + " has permission groups: "
+ String.join(", ", permissionsManager.getGroups(player)));
List<String> groupNames = permissionsManager.getGroups(player).stream()
.map(UserGroup::getGroupName)
.collect(toList());

sender.sendMessage("Player " + name + " has permission groups: " + String.join(", ", groupNames));
sender.sendMessage("Primary group is: " + permissionsManager.getGroups(player));
}
}
Expand Down
10 changes: 5 additions & 5 deletions src/main/java/fr/xephi/authme/data/limbo/AuthGroupHandler.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ class AuthGroupHandler implements Reloadable {
@Inject
private Settings settings;

private String unregisteredGroup;
private String registeredGroup;
private UserGroup unregisteredGroup;
private UserGroup registeredGroup;

AuthGroupHandler() {
}
Expand All @@ -53,7 +53,7 @@ void setGroup(Player player, LimboPlayer limbo, AuthGroupType groupType) {
return;
}

Collection<String> previousGroups = limbo == null ? Collections.emptyList() : limbo.getGroups();
Collection<UserGroup> previousGroups = limbo == null ? Collections.emptyList() : limbo.getGroups();

switch (groupType) {
// Implementation note: some permission systems don't support players not being in any group,
Expand Down Expand Up @@ -107,8 +107,8 @@ private boolean useAuthGroups() {
@Override
@PostConstruct
public void reload() {
unregisteredGroup = settings.getProperty(PluginSettings.UNREGISTERED_GROUP);
registeredGroup = settings.getProperty(PluginSettings.REGISTERED_GROUP);
unregisteredGroup = new UserGroup(settings.getProperty(PluginSettings.UNREGISTERED_GROUP));
registeredGroup = new UserGroup(settings.getProperty(PluginSettings.REGISTERED_GROUP));
}

}
6 changes: 3 additions & 3 deletions src/main/java/fr/xephi/authme/data/limbo/LimboPlayer.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ public class LimboPlayer {

private final boolean canFly;
private final boolean operator;
private final Collection<String> groups;
private final Collection<UserGroup> groups;
private final Location loc;
private final float walkSpeed;
private final float flySpeed;
private BukkitTask timeoutTask = null;
private MessageTask messageTask = null;
private LimboPlayerState state = LimboPlayerState.PASSWORD_REQUIRED;

public LimboPlayer(Location loc, boolean operator, Collection<String> groups, boolean fly, float walkSpeed,
public LimboPlayer(Location loc, boolean operator, Collection<UserGroup> groups, boolean fly, float walkSpeed,
float flySpeed) {
this.loc = loc;
this.operator = operator;
Expand Down Expand Up @@ -58,7 +58,7 @@ public boolean isOperator() {
*
* @return The permissions groups the player belongs to
*/
public Collection<String> getGroups() {
public Collection<UserGroup> getGroups() {
return groups;
}

Expand Down
19 changes: 13 additions & 6 deletions src/main/java/fr/xephi/authme/data/limbo/LimboServiceHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
import javax.inject.Inject;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

import static fr.xephi.authme.util.Utils.isCollectionEmpty;
import static java.util.stream.Collectors.toList;

/**
* Helper class for the LimboService.
Expand All @@ -31,9 +33,9 @@ class LimboServiceHelper {
/**
* Creates a LimboPlayer with the given player's details.
*
* @param player the player to process
* @param player the player to process
* @param isRegistered whether the player is registered
* @param location the player location
* @param location the player location
* @return limbo player with the player's data
*/
LimboPlayer createLimboPlayer(Player player, boolean isRegistered, Location location) {
Expand All @@ -42,10 +44,14 @@ LimboPlayer createLimboPlayer(Player player, boolean isRegistered, Location loca
boolean flyEnabled = player.getAllowFlight();
float walkSpeed = player.getWalkSpeed();
float flySpeed = player.getFlySpeed();
Collection<String> playerGroups = permissionsManager.hasGroupSupport()
Collection<UserGroup> playerGroups = permissionsManager.hasGroupSupport()
? permissionsManager.getGroups(player) : Collections.emptyList();
logger.debug("Player `{0}` has groups `{1}`", player.getName(), String.join(", ", playerGroups));

List<String> groupNames = playerGroups.stream()
.map(UserGroup::getGroupName)
.collect(toList());

logger.debug("Player `{0}` has groups `{1}`", player.getName(), String.join(", ", groupNames));
return new LimboPlayer(location, isOperator, playerGroups, flyEnabled, walkSpeed, flySpeed);
}

Expand Down Expand Up @@ -91,7 +97,7 @@ LimboPlayer merge(LimboPlayer newLimbo, LimboPlayer oldLimbo) {
boolean canFly = newLimbo.isCanFly() || oldLimbo.isCanFly();
float flySpeed = Math.max(newLimbo.getFlySpeed(), oldLimbo.getFlySpeed());
float walkSpeed = Math.max(newLimbo.getWalkSpeed(), oldLimbo.getWalkSpeed());
Collection<String> groups = getLimboGroups(oldLimbo.getGroups(), newLimbo.getGroups());
Collection<UserGroup> groups = getLimboGroups(oldLimbo.getGroups(), newLimbo.getGroups());
Location location = firstNotNull(oldLimbo.getLocation(), newLimbo.getLocation());

return new LimboPlayer(location, isOperator, groups, canFly, walkSpeed, flySpeed);
Expand All @@ -101,7 +107,8 @@ private static Location firstNotNull(Location first, Location second) {
return first == null ? second : first;
}

private Collection<String> getLimboGroups(Collection<String> oldLimboGroups, Collection<String> newLimboGroups) {
private Collection<UserGroup> getLimboGroups(Collection<UserGroup> oldLimboGroups,
Collection<UserGroup> newLimboGroups) {
logger.debug("Limbo merge: new and old groups are `{0}` and `{1}`", newLimboGroups, oldLimboGroups);
return isCollectionEmpty(oldLimboGroups) ? newLimboGroups : oldLimboGroups;
}
Expand Down
45 changes: 45 additions & 0 deletions src/main/java/fr/xephi/authme/data/limbo/UserGroup.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package fr.xephi.authme.data.limbo;

import java.util.Map;
import java.util.Objects;

public class UserGroup {

private String groupName;
private Map<String, String> contextMap;

public UserGroup(String groupName) {
this.groupName = groupName;
}

public UserGroup(String groupName, Map<String, String> contextMap) {
this.groupName = groupName;
this.contextMap = contextMap;
}

public String getGroupName() {
return groupName;
}

public Map<String, String> getContextMap() {
return contextMap;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
UserGroup userGroup = (UserGroup) o;
return Objects.equals(groupName, userGroup.groupName)
&& Objects.equals(contextMap, userGroup.contextMap);
}

@Override
public int hashCode() {
return Objects.hash(groupName, contextMap);
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package fr.xephi.authme.data.limbo.persistence;

import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import fr.xephi.authme.data.limbo.LimboPlayer;
import fr.xephi.authme.data.limbo.UserGroup;
import fr.xephi.authme.service.BukkitService;
import org.bukkit.Location;
import org.bukkit.World;
Expand All @@ -15,6 +18,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import static fr.xephi.authme.data.limbo.persistence.LimboPlayerSerializer.CAN_FLY;
Expand All @@ -37,6 +41,8 @@
class LimboPlayerDeserializer implements JsonDeserializer<LimboPlayer> {

private static final String GROUP_LEGACY = "group";
private static final String CONTEXT_MAP = "contextMap";
private static final String GROUP_NAME = "groupName";

private BukkitService bukkitService;

Expand All @@ -54,7 +60,7 @@ public LimboPlayer deserialize(JsonElement jsonElement, Type type, JsonDeseriali
Location loc = deserializeLocation(jsonObject);
boolean operator = getBoolean(jsonObject, IS_OP);

Collection<String> groups = getLimboGroups(jsonObject);
Collection<UserGroup> groups = getLimboGroups(jsonObject);
boolean canFly = getBoolean(jsonObject, CAN_FLY);
float walkSpeed = getFloat(jsonObject, WALK_SPEED, LimboPlayer.DEFAULT_WALK_SPEED);
float flySpeed = getFloat(jsonObject, FLY_SPEED, LimboPlayer.DEFAULT_FLY_SPEED);
Expand Down Expand Up @@ -84,16 +90,35 @@ private static String getString(JsonObject jsonObject, String memberName) {
return element != null ? element.getAsString() : "";
}

private static List<String> getLimboGroups(JsonObject jsonObject) {
/**
* @param jsonObject LimboPlayer represented as JSON
* @return The list of UserGroups create from JSON
*/
private static List<UserGroup> getLimboGroups(JsonObject jsonObject) {
JsonElement element = jsonObject.get(GROUPS);
if (element == null) {
String legacyGroup = ofNullable(jsonObject.get(GROUP_LEGACY)).map(JsonElement::getAsString).orElse(null);
return legacyGroup == null ? Collections.emptyList() : Collections.singletonList(legacyGroup);
return legacyGroup == null ? Collections.emptyList() :
Collections.singletonList(new UserGroup(legacyGroup, null));
}
List<String> result = new ArrayList<>();
List<UserGroup> result = new ArrayList<>();
JsonArray jsonArray = element.getAsJsonArray();
for (JsonElement arrayElement : jsonArray) {
result.add(arrayElement.getAsString());
if (!arrayElement.isJsonObject()) {
result.add(new UserGroup(arrayElement.getAsString(), null));
} else {
JsonObject jsonGroup = arrayElement.getAsJsonObject();
Map<String, String> contextMap = null;
if (jsonGroup.has(CONTEXT_MAP)) {
JsonElement contextMapJson = jsonGroup.get("contextMap");
Type type = new TypeToken<Map<String, String>>() {
}.getType();
contextMap = new Gson().fromJson(contextMapJson.getAsString(), type);
}

String groupName = jsonGroup.get(GROUP_NAME).getAsString();
result.add(new UserGroup(groupName, contextMap));
}
}
return result;
}
Expand Down Expand Up @@ -122,7 +147,6 @@ private static double getDouble(JsonObject jsonObject, String memberName) {
* @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 <N> the number type
*
* @return the number from the given JSON element, or the default value
*/
private static <N extends Number> N getNumberFromElement(JsonElement jsonElement,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import fr.xephi.authme.data.limbo.LimboPlayer;
import org.bukkit.Location;

import java.lang.reflect.Type;
import java.util.List;
import java.util.stream.Collectors;

/**
* Converts a LimboPlayer to a JsonElement.
Expand Down Expand Up @@ -47,11 +48,19 @@ public JsonElement serialize(LimboPlayer limboPlayer, Type type, JsonSerializati

JsonObject obj = new JsonObject();
obj.add(LOCATION, locationObject);
JsonArray groups = new JsonArray();
for (String group : limboPlayer.getGroups()) {
groups.add(new JsonPrimitive(group));
}
obj.add(GROUPS, groups);

List<JsonObject> groups = limboPlayer.getGroups().stream().map(g -> {
JsonObject jsonGroup = new JsonObject();
jsonGroup.addProperty("groupName", g.getGroupName());
if (g.getContextMap() != null) {
jsonGroup.addProperty("contextMap", GSON.toJson(g.getContextMap()));
}
return jsonGroup;
}).collect(Collectors.toList());

JsonArray jsonGroups = new JsonArray();
groups.forEach(jsonGroups::add);
obj.add(GROUPS, jsonGroups);

obj.addProperty(IS_OP, limboPlayer.isOperator());
obj.addProperty(CAN_FLY, limboPlayer.isCanFly());
Expand Down
Loading