Cleanup handling of unknown/null usernames for users

This commit is contained in:
Luck 2017-04-17 19:31:33 +01:00
parent 43450f6cc7
commit 67b5c72520
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
27 changed files with 126 additions and 79 deletions

View File

@ -93,13 +93,23 @@ public interface Storage {
* Loads a user's data from the main storage into the plugins local storage.
*
* @param uuid the uuid of the user to load
* @param username the users username. (if you want to specify <code>null</code> here, just input "null" as a
* string.)
* @param username the users username, or null if it is not known.
* @return if the operation completed successfully
* @throws NullPointerException if uuid or username is null
* @throws NullPointerException if uuid is null
*/
CompletableFuture<Boolean> loadUser(UUID uuid, String username);
/**
* Loads a user's data from the main storage into the plugins local storage.
*
* @param uuid the uuid of the user to load
* @return if the operation completed successfully
* @throws NullPointerException if uuid is null
*/
default CompletableFuture<Boolean> loadUser(UUID uuid) {
return loadUser(uuid, null);
}
/**
* Saves a user object back to storage. You should call this after you make any changes to a user.
*

View File

@ -43,7 +43,7 @@ public interface User extends PermissionHolder {
UUID getUuid();
/**
* Gets the users username
* Gets the users username, or null if no username is associated with this user
*
* @return the Users Username
*/

View File

@ -69,6 +69,6 @@ public class BukkitCalculatorFactory extends AbstractCalculatorFactory {
}
processors.add(new DefaultsProcessor(contexts.isOp(), plugin.getDefaultsProvider()));
return registerCalculator(new PermissionCalculator(plugin, user.getName(), processors.build()));
return registerCalculator(new PermissionCalculator(plugin, user.getFriendlyName(), processors.build()));
}
}

View File

@ -124,7 +124,7 @@ public class VaultChatHook extends Chat {
world = perms.isIgnoreWorld() ? null : world;
node = escapeCharacters(node);
perms.log("Getting meta: '" + node + "' for user " + user.getName() + " on world " + world + ", server " + perms.getServer());
perms.log("Getting meta: '" + node + "' for user " + user.getFriendlyName() + " on world " + world + ", server " + perms.getServer());
if (user.getUserData() == null) {
return defaultValue;
@ -142,7 +142,7 @@ public class VaultChatHook extends Chat {
if (user == null) return "";
world = perms.isIgnoreWorld() ? null : world;
perms.log("Getting " + (prefix ? "prefix" : "suffix") + " for user " + user.getName() + " on world " + world + ", server " + perms.getServer());
perms.log("Getting " + (prefix ? "prefix" : "suffix") + " for user " + user.getFriendlyName() + " on world " + world + ", server " + perms.getServer());
if (user.getUserData() == null) {
return "";

View File

@ -54,6 +54,6 @@ public class BungeeCalculatorFactory extends AbstractCalculatorFactory {
processors.add(new WildcardProcessor());
}
return registerCalculator(new PermissionCalculator(plugin, user.getName(), processors.build()));
return registerCalculator(new PermissionCalculator(plugin, user.getFriendlyName(), processors.build()));
}
}

View File

@ -88,12 +88,12 @@ public class StorageDelegate implements Storage {
}
@Override
public CompletableFuture<Boolean> loadUser(UUID uuid, String username) {
return handle.force().loadUser(uuid, checkUsername(username));
public CompletableFuture<Boolean> loadUser(@NonNull UUID uuid, String username) {
return handle.force().loadUser(uuid, username == null ? null : checkUsername(username));
}
@Override
public CompletableFuture<Boolean> saveUser(User user) {
public CompletableFuture<Boolean> saveUser(@NonNull User user) {
return handle.force().saveUser(UserDelegate.cast(user));
}
@ -113,12 +113,12 @@ public class StorageDelegate implements Storage {
}
@Override
public CompletableFuture<Boolean> createAndLoadGroup(String name) {
public CompletableFuture<Boolean> createAndLoadGroup(@NonNull String name) {
return handle.force().createAndLoadGroup(checkName(name), CreationCause.API);
}
@Override
public CompletableFuture<Boolean> loadGroup(String name) {
public CompletableFuture<Boolean> loadGroup(@NonNull String name) {
return handle.force().loadGroup(checkName(name));
}
@ -128,12 +128,12 @@ public class StorageDelegate implements Storage {
}
@Override
public CompletableFuture<Boolean> saveGroup(Group group) {
public CompletableFuture<Boolean> saveGroup(@NonNull Group group) {
return handle.force().saveGroup(GroupDelegate.cast(group));
}
@Override
public CompletableFuture<Boolean> deleteGroup(Group group) {
public CompletableFuture<Boolean> deleteGroup(@NonNull Group group) {
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().get(ConfigKeys.DEFAULT_GROUP_NAME))) {
throw new IllegalArgumentException("Cannot delete the default group.");
}
@ -146,12 +146,12 @@ public class StorageDelegate implements Storage {
}
@Override
public CompletableFuture<Boolean> createAndLoadTrack(String name) {
public CompletableFuture<Boolean> createAndLoadTrack(@NonNull String name) {
return handle.force().createAndLoadTrack(checkName(name), CreationCause.API);
}
@Override
public CompletableFuture<Boolean> loadTrack(String name) {
public CompletableFuture<Boolean> loadTrack(@NonNull String name) {
return handle.force().loadTrack(checkName(name));
}
@ -161,22 +161,22 @@ public class StorageDelegate implements Storage {
}
@Override
public CompletableFuture<Boolean> saveTrack(Track track) {
public CompletableFuture<Boolean> saveTrack(@NonNull Track track) {
return handle.force().saveTrack(TrackDelegate.cast(track));
}
@Override
public CompletableFuture<Boolean> deleteTrack(Track track) {
public CompletableFuture<Boolean> deleteTrack(@NonNull Track track) {
return handle.force().deleteTrack(TrackDelegate.cast(track), DeletionCause.API);
}
@Override
public CompletableFuture<Boolean> saveUUIDData(String username, UUID uuid) {
public CompletableFuture<Boolean> saveUUIDData(@NonNull String username, @NonNull UUID uuid) {
return handle.force().saveUUIDData(checkUsername(username), uuid);
}
@Override
public CompletableFuture<UUID> getUUID(String username) {
public CompletableFuture<UUID> getUUID(@NonNull String username) {
return handle.force().getUUID(checkUsername(username));
}

View File

@ -49,9 +49,9 @@ import static me.lucko.luckperms.common.api.ApiUtils.checkTime;
* Provides a link between {@link User} and {@link me.lucko.luckperms.common.core.model.User}
*/
public final class UserDelegate extends PermissionHolderDelegate implements User {
public static me.lucko.luckperms.common.core.model.User cast(User g) {
Preconditions.checkState(g instanceof UserDelegate, "Illegal instance " + g.getClass() + " cannot be handled by this implementation.");
return ((UserDelegate) g).getHandle();
public static me.lucko.luckperms.common.core.model.User cast(User u) {
Preconditions.checkState(u instanceof UserDelegate, "Illegal instance " + u.getClass() + " cannot be handled by this implementation.");
return ((UserDelegate) u).getHandle();
}
@Getter
@ -69,7 +69,7 @@ public final class UserDelegate extends PermissionHolderDelegate implements User
@Override
public String getName() {
return handle.getName();
return handle.getName().orElse(null);
}
@Override

View File

@ -73,12 +73,12 @@ public class CheckCommand extends SingleCommand {
UserCache data = user.getUserData();
if (data == null) {
Message.USER_NO_DATA.send(sender, user.getName());
Message.USER_NO_DATA.send(sender, user.getFriendlyName());
return CommandResult.STATE_ERROR;
}
Tristate tristate = data.getPermissionData(plugin.getContextForUser(user)).getPermissionValue(permission);
Message.CHECK_RESULT.send(sender, user.getName(), permission, Util.formatTristate(tristate));
Message.CHECK_RESULT.send(sender, user.getFriendlyName(), permission, Util.formatTristate(tristate));
return CommandResult.SUCCESS;
}
}

View File

@ -92,7 +92,7 @@ public class TreeCommand extends SingleCommand {
UserCache data = user.getUserData();
if (data == null) {
Message.USER_NO_DATA.send(sender, user.getName());
Message.USER_NO_DATA.send(sender, user.getFriendlyName());
return CommandResult.STATE_ERROR;
}
@ -106,7 +106,7 @@ public class TreeCommand extends SingleCommand {
Message.TREE_UPLOAD_START.send(sender);
String url = view.uploadPasteData(plugin.getVersion(), user.getName(), permissionData);
String url = view.uploadPasteData(plugin.getVersion(), user.getFriendlyName(), permissionData);
if (url == null) {
url = "null";
}

View File

@ -125,7 +125,7 @@ public class UserDemote extends SubCommand<User> {
user.unsetPermission(oldNode);
Message.USER_DEMOTE_ENDOFTRACK.send(sender, track.getName(), user.getName(), old);
Message.USER_DEMOTE_ENDOFTRACK.send(sender, track.getName(), user.getFriendlyName(), old);
LogEntry.build().actor(sender).acted(user)
.action("demote " + args.stream().collect(Collectors.joining(" ")))

View File

@ -54,7 +54,7 @@ public class UserInfo extends SubCommand<User> {
@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) throws CommandException {
Message.USER_INFO_GENERAL.send(sender,
user.getName(),
user.getName().orElse("Unknown"),
user.getUuid(),
plugin.getPlayerStatus(user.getUuid()),
user.getPrimaryGroup().getValue(),

View File

@ -106,13 +106,13 @@ public class UserPromote extends SubCommand<User> {
Group nextGroup = plugin.getGroupManager().getIfLoaded(first);
if (nextGroup == null) {
Message.USER_PROMOTE_ERROR_MALFORMED.send(sender, false);
Message.USER_PROMOTE_ERROR_MALFORMED.send(sender, first);
return CommandResult.LOADING_ERROR;
}
user.setPermission(NodeFactory.newBuilder("group." + first).withExtraContext(context).build());
Message.USER_TRACK_ADDED_TO_FIRST.send(sender, user.getName(), first, Util.contextSetToString(context));
Message.USER_TRACK_ADDED_TO_FIRST.send(sender, user.getFriendlyName(), first, Util.contextSetToString(context));
LogEntry.build().actor(sender).acted(user)
.action("promote " + args.stream().collect(Collectors.joining(" ")))
.build().submit(plugin, sender);

View File

@ -68,12 +68,12 @@ public class UserSwitchPrimaryGroup extends SubCommand<User> {
}
if (!user.inheritsGroup(group)) {
Message.USER_PRIMARYGROUP_ERROR_NOTMEMBER.send(sender, user.getName(), group.getName());
Message.USER_PRIMARYGROUP_ERROR_NOTMEMBER.send(sender, user.getFriendlyName(), group.getName());
user.setInheritGroup(group, ContextSet.empty());
}
user.getPrimaryGroup().setStoredValue(group.getName());
Message.USER_PRIMARYGROUP_SUCCESS.send(sender, user.getName(), group.getDisplayName());
Message.USER_PRIMARYGROUP_SUCCESS.send(sender, user.getFriendlyName(), group.getDisplayName());
LogEntry.build().actor(sender).acted(user)
.action("setprimarygroup " + group.getName())
.build().submit(plugin, sender);

View File

@ -33,20 +33,29 @@ import lombok.ToString;
import me.lucko.luckperms.common.utils.Identifiable;
import java.util.Optional;
import java.util.UUID;
@Getter
@ToString
@EqualsAndHashCode(of = "uuid")
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public final class UserIdentifier implements Identifiable<UUID> {
public static UserIdentifier of(UUID uuid, String username) {
if (username == null || username.equalsIgnoreCase("null") || username.isEmpty()) {
username = null;
}
return new UserIdentifier(uuid, username);
}
@Getter
private final UUID uuid;
private final String username;
public Optional<String> getUsername() {
return Optional.ofNullable(username);
}
@Override
public UUID getId() {
return getUuid();

View File

@ -27,7 +27,6 @@ package me.lucko.luckperms.common.core.model;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import me.lucko.luckperms.api.caching.UserData;
@ -42,6 +41,7 @@ import me.lucko.luckperms.common.primarygroup.PrimaryGroupHolder;
import me.lucko.luckperms.common.utils.BufferedRequest;
import me.lucko.luckperms.common.utils.Identifiable;
import java.util.Optional;
import java.util.UUID;
@ToString(of = {"uuid"})
@ -57,9 +57,7 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
/**
* The last known username of a player
*/
@Getter
@Setter
private String name;
private String name = null;
/**
* The users primary group
@ -88,14 +86,14 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
public User(UUID uuid, LuckPermsPlugin plugin) {
super(uuid.toString(), plugin);
this.uuid = uuid;
this.name = null;
this.primaryGroup = plugin.getConfiguration().get(ConfigKeys.PRIMARY_GROUP_CALCULATION).apply(this);
}
public User(UUID uuid, String name, LuckPermsPlugin plugin) {
super(uuid.toString(), plugin);
this.uuid = uuid;
this.name = name;
setName(name, true);
this.primaryGroup = plugin.getConfiguration().get(ConfigKeys.PRIMARY_GROUP_CALCULATION).apply(this);
}
@ -104,9 +102,49 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
return UserIdentifier.of(uuid, name);
}
public Optional<String> getName() {
return Optional.ofNullable(name);
}
public boolean setName(String name, boolean force) {
// if the value being set is null
if (name == null || name.equalsIgnoreCase("null") || name.isEmpty()) {
// only apply the change if it is being forced
if (force) {
// if the name is already null, return false
if (this.name == null) {
return false;
} else {
// set the new null value
this.name = null;
return true;
}
} else {
// we already have a non-null value, so return false
return false;
}
} else {
// the name being set is not null
if (this.name == null) {
this.name = name;
return true;
}
// update the capitalisation, but still return false
if (this.name.equalsIgnoreCase(name)) {
this.name = name;
return false;
}
// completely new value, just set & return true
this.name = name;
return true;
}
}
@Override
public String getFriendlyName() {
return name;
return name != null ? name : uuid.toString();
}
@Override

View File

@ -217,7 +217,7 @@ public class Exporter implements Runnable {
plugin.getStorage().loadUser(uuid, "null").join();
User user = plugin.getUserManager().get(uuid);
output.add("# Export user: " + user.getUuid().toString() + " - " + user.getName());
output.add("# Export user: " + user.getUuid().toString() + " - " + user.getName().orElse("unknown username"));
boolean inDefault = false;
for (Node node : user.getNodes().values()) {

View File

@ -116,7 +116,7 @@ public class LogEntry extends me.lucko.luckperms.api.LogEntry {
public LogEntryBuilder acted(PermissionHolder acted) {
if (acted instanceof User) {
super.actedName(((User) acted).getName());
super.actedName(((User) acted).getName().orElse("null"));
super.acted(((User) acted).getUuid());
super.type('U');
} else if (acted instanceof Group) {

View File

@ -35,6 +35,7 @@ import me.lucko.luckperms.common.managers.AbstractManager;
import me.lucko.luckperms.common.managers.UserManager;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
@ -105,15 +106,16 @@ public class GenericUserManager extends AbstractManager<UserIdentifier, User> im
@Override
public User apply(UserIdentifier id) {
return id.getUsername() == null ?
return !id.getUsername().isPresent() ?
new User(id.getUuid(), plugin) :
new User(id.getUuid(), id.getUsername(), plugin);
new User(id.getUuid(), id.getUsername().get(), plugin);
}
@Override
public User getByUsername(String name) {
for (User user : getAll().values()) {
if (user.getName().equalsIgnoreCase(name)) {
Optional<String> n = user.getName();
if (n.isPresent() && n.get().equalsIgnoreCase(name)) {
return user;
}
}

View File

@ -180,7 +180,7 @@ public abstract class FlatfileBacking extends AbstractBacking {
User u = plugin.getUserManager().get(uuid);
if (u != null) {
plugin.getLog().info("[FileWatcher] Refreshing user " + u.getName());
plugin.getLog().info("[FileWatcher] Refreshing user " + u.getFriendlyName());
plugin.getStorage().loadUser(uuid, "null");
}
});

View File

@ -176,12 +176,8 @@ public class JSONBacking extends FlatfileBacking {
boolean save = plugin.getUserManager().giveDefaultIfNeeded(user, false);
if (user.getName() == null || user.getName().equalsIgnoreCase("null")) {
user.setName(name);
} else {
if (!name.equalsIgnoreCase(user.getName())) {
save = true;
}
if (user.setName(name, false)) {
save = true;
}
if (save) {
@ -230,7 +226,7 @@ public class JSONBacking extends FlatfileBacking {
JsonObject data = new JsonObject();
data.addProperty("uuid", user.getUuid().toString());
data.addProperty("name", user.getName());
data.addProperty("name", user.getName().orElse("null"));
data.addProperty("primaryGroup", user.getPrimaryGroup().getStoredValue());
Set<NodeModel> nodes = user.getNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toCollection(LinkedHashSet::new));

View File

@ -98,7 +98,7 @@ public class MongoDBBacking extends AbstractBacking {
private static Document fromUser(User user) {
Document main = new Document("_id", user.getUuid())
.append("name", user.getName())
.append("name", user.getName().orElse("null"))
.append("primaryGroup", user.getPrimaryGroup().getStoredValue());
Document perms = new Document();
@ -325,12 +325,8 @@ public class MongoDBBacking extends AbstractBacking {
boolean save = plugin.getUserManager().giveDefaultIfNeeded(user, false);
if (user.getName() == null || user.getName().equalsIgnoreCase("null")) {
user.setName(d.getString("name"));
} else {
if (!d.getString("name").equalsIgnoreCase(user.getName())) {
save = true;
}
if (user.setName(name, false)) {
save = true;
}
if (save) {

View File

@ -349,9 +349,7 @@ public class SQLBacking extends AbstractBacking {
}
// Update their username to what was in the storage if the one in the local instance is null
if (user.getName() == null || user.getName().equalsIgnoreCase("null")) {
user.setName(name);
}
user.setName(name, false);
// If the user has any data in storage
if (!data.isEmpty()) {

View File

@ -179,12 +179,8 @@ public class YAMLBacking extends FlatfileBacking {
boolean save = plugin.getUserManager().giveDefaultIfNeeded(user, false);
if (user.getName() == null || user.getName().equalsIgnoreCase("null")) {
user.setName(name);
} else {
if (!name.equalsIgnoreCase(user.getName())) {
save = true;
}
if (user.setName(name, false)) {
save = true;
}
if (save) {
@ -231,7 +227,7 @@ public class YAMLBacking extends FlatfileBacking {
Map<String, Object> values = new LinkedHashMap<>();
values.put("uuid", user.getUuid().toString());
values.put("name", user.getName());
values.put("name", user.getName().orElse("null"));
values.put("primary-group", user.getPrimaryGroup().getStoredValue());
Set<NodeModel> data = user.getNodes().values().stream().map(NodeModel::fromNode).collect(Collectors.toCollection(LinkedHashSet::new));

View File

@ -76,7 +76,7 @@ public class BufferedOutputStorage implements Storage, Runnable {
private final Buffer<UserIdentifier, Boolean> uuidDataOutputBuffer = new Buffer<UserIdentifier, Boolean>() {
@Override
protected Boolean dequeue(UserIdentifier userIdentifier) {
return backing.saveUUIDData(userIdentifier.getUsername(), userIdentifier.getUuid()).join();
return backing.saveUUIDData(userIdentifier.getUsername().get(), userIdentifier.getUuid()).join();
}
};

View File

@ -58,6 +58,6 @@ public class SpongeCalculatorFactory extends AbstractCalculatorFactory {
}
processors.add(new DefaultsProcessor(plugin.getService(), contexts.getContexts()));
return registerCalculator(new PermissionCalculator(plugin, user.getName(), processors.build()));
return registerCalculator(new PermissionCalculator(plugin, user.getFriendlyName(), processors.build()));
}
}

View File

@ -56,6 +56,7 @@ import co.aikar.timings.Timing;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@ -115,9 +116,9 @@ public class SpongeUserManager implements UserManager, LPSubjectCollection {
@Override
public SpongeUser apply(UserIdentifier id) {
return id.getUsername() == null ?
return !id.getUsername().isPresent() ?
new SpongeUser(id.getUuid(), plugin) :
new SpongeUser(id.getUuid(), id.getUsername(), plugin);
new SpongeUser(id.getUuid(), id.getUsername().get(), plugin);
}
public void performCleanup() {
@ -182,7 +183,8 @@ public class SpongeUserManager implements UserManager, LPSubjectCollection {
@Override
public SpongeUser getByUsername(String name) {
for (SpongeUser user : getAll().values()) {
if (user.getName().equalsIgnoreCase(name)) {
Optional<String> n = user.getName();
if (n.isPresent() && n.get().equalsIgnoreCase(name)) {
return user;
}
}

View File

@ -98,7 +98,7 @@ public class SpongeUser extends User {
private synchronized void checkData() {
if (parent.getUserData() == null) {
plugin.getLog().warn("User " + parent.getName() + " - " + parent.getUuid() + " does not have any data loaded.");
plugin.getLog().warn("User " + parent.getName().orElse("unknown") + " - " + parent.getUuid() + " does not have any data loaded.");
parent.setupData(false);
}
}