mirror of
https://github.com/LuckPerms/LuckPerms.git
synced 2024-12-27 11:37:35 +01:00
Implement locks to hopefully resolve race conditions with I/O - experimental
This commit is contained in:
parent
b5ece8b5bd
commit
4787361e66
@ -47,7 +47,7 @@ public class BukkitUserManager extends UserManager implements ContextListener<Pl
|
||||
Player player = plugin.getServer().getPlayer(plugin.getUuidCache().getExternalUUID(u.getUuid()));
|
||||
if (player != null) {
|
||||
if (u.getLpPermissible() != null) {
|
||||
Injector.unInject(player);
|
||||
Injector.unInject(player); // TODO is this needed?
|
||||
u.setLpPermissible(null);
|
||||
}
|
||||
|
||||
@ -66,18 +66,17 @@ public class BukkitUserManager extends UserManager implements ContextListener<Pl
|
||||
}
|
||||
|
||||
@Override
|
||||
public User make(UUID uuid) {
|
||||
return new BukkitUser(uuid, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User make(UUID uuid, String username) {
|
||||
return new BukkitUser(uuid, username, plugin);
|
||||
public User apply(UserIdentifier id) {
|
||||
BukkitUser user = id.getUsername() == null ?
|
||||
new BukkitUser(id.getUuid(), plugin) :
|
||||
new BukkitUser(id.getUuid(), id.getUsername(), plugin);
|
||||
giveDefaultIfNeeded(user, false);
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateAllUsers() {
|
||||
// Sometimes called async, so we need to get the players on the Bukkit thread.
|
||||
// Sometimes called async, as we need to get the players on the Bukkit thread.
|
||||
plugin.doSync(() -> {
|
||||
Set<UUID> players = plugin.getServer().getOnlinePlayers().stream()
|
||||
.map(p -> plugin.getUuidCache().getUUID(p.getUniqueId()))
|
||||
|
@ -45,13 +45,12 @@ public class BungeeUserManager extends UserManager implements ContextListener<Pr
|
||||
}
|
||||
|
||||
@Override
|
||||
public User make(UUID uuid) {
|
||||
return new BungeeUser(uuid, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User make(UUID uuid, String username) {
|
||||
return new BungeeUser(uuid, username, plugin);
|
||||
public User apply(UserIdentifier id) {
|
||||
BungeeUser user = id.getUsername() == null ?
|
||||
new BungeeUser(id.getUuid(), plugin) :
|
||||
new BungeeUser(id.getUuid(), id.getUsername(), plugin);
|
||||
giveDefaultIfNeeded(user, false);
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -32,6 +32,7 @@ import me.lucko.luckperms.api.context.IContextCalculator;
|
||||
import me.lucko.luckperms.api.event.LPEvent;
|
||||
import me.lucko.luckperms.api.event.LPListener;
|
||||
import me.lucko.luckperms.api.implementation.internal.*;
|
||||
import me.lucko.luckperms.users.UserIdentifier;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
@ -149,7 +150,7 @@ public class ApiProvider implements LuckPermsApi {
|
||||
|
||||
@Override
|
||||
public boolean isUserLoaded(@NonNull UUID uuid) {
|
||||
return plugin.getUserManager().isLoaded(uuid);
|
||||
return plugin.getUserManager().isLoaded(UserIdentifier.of(uuid, null));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -63,7 +63,7 @@ public class GroupClone extends SubCommand<Group> {
|
||||
return CommandResult.LOADING_ERROR;
|
||||
}
|
||||
|
||||
plugin.getGroupManager().copy(group, newGroup);
|
||||
newGroup.setNodes(group.getNodes());
|
||||
|
||||
Message.CLONE_SUCCESS.send(sender, group.getName(), newGroup.getName());
|
||||
LogEntry.build().actor(sender).acted(group).action("clone " + newGroup.getName()).build().submit(plugin, sender);
|
||||
|
@ -68,7 +68,7 @@ public class GroupRename extends SubCommand<Group> {
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
plugin.getGroupManager().copy(group, newGroup);
|
||||
newGroup.setNodes(group.getNodes());
|
||||
|
||||
Message.RENAME_SUCCESS.send(sender, group.getName(), newGroup.getName());
|
||||
LogEntry.build().actor(sender).acted(group).action("rename " + newGroup.getName()).build().submit(plugin, sender);
|
||||
|
@ -63,7 +63,7 @@ public class TrackClone extends SubCommand<Track> {
|
||||
return CommandResult.LOADING_ERROR;
|
||||
}
|
||||
|
||||
plugin.getTrackManager().copy(track, newTrack);
|
||||
newTrack.setGroups(track.getGroups());
|
||||
|
||||
Message.CLONE_SUCCESS.send(sender, track.getName(), newTrack.getName());
|
||||
LogEntry.build().actor(sender).acted(track).action("clone " + newTrack.getName()).build().submit(plugin, sender);
|
||||
|
@ -68,7 +68,7 @@ public class TrackRename extends SubCommand<Track> {
|
||||
return CommandResult.FAILURE;
|
||||
}
|
||||
|
||||
plugin.getTrackManager().copy(track, newTrack);
|
||||
newTrack.setGroups(track.getGroups());
|
||||
|
||||
Message.RENAME_SUCCESS.send(sender, track.getName(), newTrack.getName());
|
||||
LogEntry.build().actor(sender).acted(track).action("rename " + newTrack.getName()).build().submit(plugin, sender);
|
||||
|
@ -40,6 +40,8 @@ import me.lucko.luckperms.groups.Group;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
@ -74,6 +76,9 @@ public abstract class PermissionHolder {
|
||||
@Getter
|
||||
private Set<Node> transientNodes = ConcurrentHashMap.newKeySet();
|
||||
|
||||
@Getter
|
||||
private final Lock ioLock = new ReentrantLock();
|
||||
|
||||
/**
|
||||
* Returns a Set of nodes in priority order
|
||||
* @return the holders transient and permanent nodes
|
||||
|
@ -30,18 +30,13 @@ import me.lucko.luckperms.utils.AbstractManager;
|
||||
public class GroupManager extends AbstractManager<String, Group> {
|
||||
private final LuckPermsPlugin plugin;
|
||||
|
||||
@Override
|
||||
public void copy(Group from, Group to) {
|
||||
to.setNodes(from.getNodes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a new group object
|
||||
* @param name The name of the group
|
||||
* @return a new {@link Group} object
|
||||
*/
|
||||
@Override
|
||||
public Group make(String name) {
|
||||
public Group apply(String name) {
|
||||
return new Group(name, plugin);
|
||||
}
|
||||
}
|
@ -28,11 +28,15 @@ import lombok.Cleanup;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.core.Node;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.groups.GroupManager;
|
||||
import me.lucko.luckperms.tracks.Track;
|
||||
import me.lucko.luckperms.tracks.TrackManager;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.users.UserIdentifier;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static me.lucko.luckperms.core.PermissionHolder.exportToLegacy;
|
||||
@ -73,138 +77,157 @@ public class JSONDatastore extends FlatfileDatastore {
|
||||
|
||||
@Override
|
||||
public boolean loadUser(UUID uuid, String username) {
|
||||
User user = plugin.getUserManager().make(uuid, username);
|
||||
boolean success = false;
|
||||
|
||||
File userFile = new File(usersDir, uuid.toString() + ".json");
|
||||
if (userFile.exists()) {
|
||||
final String[] name = new String[1];
|
||||
success = doRead(userFile, reader -> {
|
||||
reader.beginObject();
|
||||
reader.nextName(); // uuid record
|
||||
reader.nextString(); // uuid
|
||||
reader.nextName(); // name record
|
||||
name[0] = reader.nextString(); // name
|
||||
reader.nextName(); // primaryGroup record
|
||||
user.setPrimaryGroup(reader.nextString()); // primaryGroup
|
||||
reader.nextName(); //perms
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
String node = reader.nextName();
|
||||
boolean b = reader.nextBoolean();
|
||||
user.getNodes().add(Node.fromSerialisedNode(node, b));
|
||||
}
|
||||
|
||||
reader.endObject();
|
||||
reader.endObject();
|
||||
return true;
|
||||
});
|
||||
|
||||
if (user.getName().equalsIgnoreCase("null")) {
|
||||
user.setName(name[0]);
|
||||
} else {
|
||||
if (!name[0].equals(user.getName())) {
|
||||
doWrite(userFile, writer -> {
|
||||
writer.beginObject();
|
||||
writer.name("uuid").value(user.getUuid().toString());
|
||||
writer.name("name").value(user.getName());
|
||||
writer.name("primaryGroup").value(user.getPrimaryGroup());
|
||||
writer.name("perms");
|
||||
writer.beginObject();
|
||||
for (Map.Entry<String, Boolean> e : exportToLegacy(user.getNodes()).entrySet()) {
|
||||
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||
User user = plugin.getUserManager().getOrMake(UserIdentifier.of(uuid, username));
|
||||
user.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File userFile = new File(usersDir, uuid.toString() + ".json");
|
||||
if (userFile.exists()) {
|
||||
return doRead(userFile, reader -> {
|
||||
reader.beginObject();
|
||||
reader.nextName(); // uuid record
|
||||
reader.nextString(); // uuid
|
||||
reader.nextName(); // name record
|
||||
String name1 = reader.nextString(); // name
|
||||
reader.nextName(); // primaryGroup record
|
||||
user.setPrimaryGroup(reader.nextString()); // primaryGroup
|
||||
reader.nextName(); // perms
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
String node = reader.nextName();
|
||||
boolean b = reader.nextBoolean();
|
||||
user.getNodes().add(Node.fromSerialisedNode(node, b));
|
||||
}
|
||||
reader.endObject();
|
||||
reader.endObject();
|
||||
|
||||
boolean save = plugin.getUserManager().giveDefaultIfNeeded(user, false);
|
||||
|
||||
if (user.getName().equalsIgnoreCase("null")) {
|
||||
user.setName(name1);
|
||||
} else {
|
||||
if (!name1.equals(user.getName())) {
|
||||
save = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (save) {
|
||||
doWrite(userFile, writer -> {
|
||||
writer.beginObject();
|
||||
writer.name("uuid").value(user.getUuid().toString());
|
||||
writer.name("name").value(user.getName());
|
||||
writer.name("primaryGroup").value(user.getPrimaryGroup());
|
||||
writer.name("perms");
|
||||
writer.beginObject();
|
||||
for (Map.Entry<String, Boolean> e : exportToLegacy(user.getNodes()).entrySet()) {
|
||||
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||
}
|
||||
writer.endObject();
|
||||
writer.endObject();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
writer.endObject();
|
||||
writer.endObject();
|
||||
return true;
|
||||
});
|
||||
} else {
|
||||
if (plugin.getUserManager().shouldSave(user)) {
|
||||
user.clearNodes();
|
||||
user.setPrimaryGroup(null);
|
||||
plugin.getUserManager().giveDefaultIfNeeded(user, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
success = true;
|
||||
}, false);
|
||||
} finally {
|
||||
user.getIoLock().unlock();
|
||||
}
|
||||
|
||||
if (success) plugin.getUserManager().updateOrSet(user);
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveUser(User user) {
|
||||
File userFile = new File(usersDir, user.getUuid().toString() + ".json");
|
||||
if (!plugin.getUserManager().shouldSave(user)) {
|
||||
if (userFile.exists()) {
|
||||
userFile.delete();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
user.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File userFile = new File(usersDir, user.getUuid().toString() + ".json");
|
||||
if (!plugin.getUserManager().shouldSave(user)) {
|
||||
if (userFile.exists()) {
|
||||
userFile.delete();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!userFile.exists()) {
|
||||
try {
|
||||
userFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!userFile.exists()) {
|
||||
try {
|
||||
userFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return doWrite(userFile, writer -> {
|
||||
writer.beginObject();
|
||||
writer.name("uuid").value(user.getUuid().toString());
|
||||
writer.name("name").value(user.getName());
|
||||
writer.name("primaryGroup").value(user.getPrimaryGroup());
|
||||
writer.name("perms");
|
||||
writer.beginObject();
|
||||
for (Map.Entry<String, Boolean> e : exportToLegacy(user.getNodes()).entrySet()) {
|
||||
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||
}
|
||||
writer.endObject();
|
||||
writer.endObject();
|
||||
return true;
|
||||
});
|
||||
return doWrite(userFile, writer -> {
|
||||
writer.beginObject();
|
||||
writer.name("uuid").value(user.getUuid().toString());
|
||||
writer.name("name").value(user.getName());
|
||||
writer.name("primaryGroup").value(user.getPrimaryGroup());
|
||||
writer.name("perms");
|
||||
writer.beginObject();
|
||||
for (Map.Entry<String, Boolean> e : exportToLegacy(user.getNodes()).entrySet()) {
|
||||
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||
}
|
||||
writer.endObject();
|
||||
writer.endObject();
|
||||
return true;
|
||||
});
|
||||
}, false);
|
||||
} finally {
|
||||
user.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cleanupUsers() {
|
||||
File[] files = usersDir.listFiles((dir, name) -> name.endsWith(".json"));
|
||||
if (files == null) return false;
|
||||
return call(() -> {
|
||||
File[] files = usersDir.listFiles((dir, name1) -> name1.endsWith(".json"));
|
||||
if (files == null) return false;
|
||||
|
||||
for (File file : files) {
|
||||
Map<String, Boolean> nodes = new HashMap<>();
|
||||
doRead(file, reader -> {
|
||||
reader.beginObject();
|
||||
reader.nextName(); // uuid record
|
||||
reader.nextString(); // uuid
|
||||
reader.nextName(); // name record
|
||||
reader.nextString(); // name
|
||||
reader.nextName(); // primaryGroup record
|
||||
reader.nextString(); // primaryGroup
|
||||
reader.nextName(); //perms
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
String node = reader.nextName();
|
||||
boolean b = reader.nextBoolean();
|
||||
nodes.put(node, b);
|
||||
for (File file : files) {
|
||||
Map<String, Boolean> nodes = new HashMap<>();
|
||||
doRead(file, reader -> {
|
||||
reader.beginObject();
|
||||
reader.nextName(); // uuid record
|
||||
reader.nextString(); // uuid
|
||||
reader.nextName(); // name record
|
||||
reader.nextString(); // name
|
||||
reader.nextName(); // primaryGroup record
|
||||
reader.nextString(); // primaryGroup
|
||||
reader.nextName(); //perms
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
String node = reader.nextName();
|
||||
boolean b = reader.nextBoolean();
|
||||
nodes.put(node, b);
|
||||
}
|
||||
|
||||
reader.endObject();
|
||||
reader.endObject();
|
||||
return true;
|
||||
});
|
||||
|
||||
boolean shouldDelete = false;
|
||||
if (nodes.size() == 1) {
|
||||
for (Map.Entry<String, Boolean> e : nodes.entrySet()) {
|
||||
// There's only one
|
||||
shouldDelete = e.getKey().equalsIgnoreCase("group.default") && e.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
reader.endObject();
|
||||
reader.endObject();
|
||||
return true;
|
||||
});
|
||||
|
||||
boolean shouldDelete = false;
|
||||
if (nodes.size() == 1) {
|
||||
for (Map.Entry<String, Boolean> e : nodes.entrySet()) {
|
||||
// There's only one
|
||||
shouldDelete = e.getKey().equalsIgnoreCase("group.default") && e.getValue();
|
||||
if (shouldDelete) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldDelete) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return true;
|
||||
}, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -219,82 +242,81 @@ public class JSONDatastore extends FlatfileDatastore {
|
||||
|
||||
@Override
|
||||
public boolean createAndLoadGroup(String name) {
|
||||
Group group = plugin.getGroupManager().make(name);
|
||||
Group group = plugin.getGroupManager().getOrMake(name);
|
||||
group.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File groupFile = new File(groupsDir, name + ".json");
|
||||
if (groupFile.exists()) {
|
||||
return doRead(groupFile, reader -> {
|
||||
reader.beginObject();
|
||||
reader.nextName(); // name record
|
||||
reader.nextString(); // name
|
||||
reader.nextName(); //perms
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
String node = reader.nextName();
|
||||
boolean b = reader.nextBoolean();
|
||||
group.getNodes().add(Node.fromSerialisedNode(node, b));
|
||||
}
|
||||
|
||||
File groupFile = new File(groupsDir, name + ".json");
|
||||
if (!groupFile.exists()) {
|
||||
try {
|
||||
groupFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
reader.endObject();
|
||||
reader.endObject();
|
||||
return true;
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
groupFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean success = doWrite(groupFile, writer -> {
|
||||
writer.beginObject();
|
||||
writer.name("name").value(group.getName());
|
||||
writer.name("perms");
|
||||
writer.beginObject();
|
||||
for (Map.Entry<String, Boolean> e : exportToLegacy(group.getNodes()).entrySet()) {
|
||||
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||
return doWrite(groupFile, writer -> {
|
||||
writer.beginObject();
|
||||
writer.name("name").value(group.getName());
|
||||
writer.name("perms");
|
||||
writer.beginObject();
|
||||
for (Map.Entry<String, Boolean> e : exportToLegacy(group.getNodes()).entrySet()) {
|
||||
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||
}
|
||||
writer.endObject();
|
||||
writer.endObject();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
writer.endObject();
|
||||
writer.endObject();
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!success) return false;
|
||||
}, false);
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
|
||||
boolean success = doRead(groupFile, reader -> {
|
||||
reader.beginObject();
|
||||
reader.nextName(); // name record
|
||||
reader.nextString(); // name
|
||||
reader.nextName(); //perms
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
String node = reader.nextName();
|
||||
boolean b = reader.nextBoolean();
|
||||
group.getNodes().add(Node.fromSerialisedNode(node, b));
|
||||
}
|
||||
|
||||
reader.endObject();
|
||||
reader.endObject();
|
||||
return true;
|
||||
});
|
||||
|
||||
if (success) plugin.getGroupManager().updateOrSet(group);
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadGroup(String name) {
|
||||
Group group = plugin.getGroupManager().make(name);
|
||||
|
||||
File groupFile = new File(groupsDir, name + ".json");
|
||||
if (!groupFile.exists()) {
|
||||
return false;
|
||||
Group group = plugin.getGroupManager().getOrMake(name);
|
||||
group.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File groupFile = new File(groupsDir, name + ".json");
|
||||
return groupFile.exists() && doRead(groupFile, reader -> {
|
||||
reader.beginObject();
|
||||
reader.nextName(); // name record
|
||||
reader.nextString(); // name
|
||||
reader.nextName(); // perms
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
String node = reader.nextName();
|
||||
boolean b = reader.nextBoolean();
|
||||
group.getNodes().add(Node.fromSerialisedNode(node, b));
|
||||
}
|
||||
reader.endObject();
|
||||
reader.endObject();
|
||||
return true;
|
||||
});
|
||||
}, false);
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
|
||||
boolean success = doRead(groupFile, reader -> {
|
||||
reader.beginObject();
|
||||
reader.nextName(); // name record
|
||||
reader.nextString(); // name
|
||||
reader.nextName(); //perms
|
||||
reader.beginObject();
|
||||
while (reader.hasNext()) {
|
||||
String node = reader.nextName();
|
||||
boolean b = reader.nextBoolean();
|
||||
group.getNodes().add(Node.fromSerialisedNode(node, b));
|
||||
}
|
||||
|
||||
reader.endObject();
|
||||
reader.endObject();
|
||||
return true;
|
||||
});
|
||||
|
||||
if (success) plugin.getGroupManager().updateOrSet(group);
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -305,122 +327,141 @@ public class JSONDatastore extends FlatfileDatastore {
|
||||
.map(s -> s.substring(0, s.length() - 5))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
plugin.getGroupManager().unloadAll();
|
||||
groups.forEach(this::loadGroup);
|
||||
|
||||
GroupManager gm = plugin.getGroupManager();
|
||||
gm.getAll().values().stream()
|
||||
.filter(g -> !groups.contains(g.getName()))
|
||||
.forEach(gm::unload);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveGroup(Group group) {
|
||||
File groupFile = new File(groupsDir, group.getName() + ".json");
|
||||
if (!groupFile.exists()) {
|
||||
try {
|
||||
groupFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
group.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File groupFile = new File(groupsDir, group.getName() + ".json");
|
||||
if (!groupFile.exists()) {
|
||||
try {
|
||||
groupFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return doWrite(groupFile, writer -> {
|
||||
writer.beginObject();
|
||||
writer.name("name").value(group.getName());
|
||||
writer.name("perms");
|
||||
writer.beginObject();
|
||||
for (Map.Entry<String, Boolean> e : exportToLegacy(group.getNodes()).entrySet()) {
|
||||
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||
}
|
||||
writer.endObject();
|
||||
writer.endObject();
|
||||
return true;
|
||||
});
|
||||
return doWrite(groupFile, writer -> {
|
||||
writer.beginObject();
|
||||
writer.name("name").value(group.getName());
|
||||
writer.name("perms");
|
||||
writer.beginObject();
|
||||
for (Map.Entry<String, Boolean> e : exportToLegacy(group.getNodes()).entrySet()) {
|
||||
writer.name(e.getKey()).value(e.getValue().booleanValue());
|
||||
}
|
||||
writer.endObject();
|
||||
writer.endObject();
|
||||
return true;
|
||||
});
|
||||
}, false);
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteGroup(Group group) {
|
||||
File groupFile = new File(groupsDir, group.getName() + ".json");
|
||||
if (groupFile.exists()) {
|
||||
groupFile.delete();
|
||||
group.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File groupFile = new File(groupsDir, group.getName() + ".json");
|
||||
if (groupFile.exists()) {
|
||||
groupFile.delete();
|
||||
}
|
||||
return true;
|
||||
}, false);
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createAndLoadTrack(String name) {
|
||||
Track track = plugin.getTrackManager().make(name);
|
||||
List<String> groups = new ArrayList<>();
|
||||
Track track = plugin.getTrackManager().getOrMake(name);
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File trackFile = new File(tracksDir, name + ".json");
|
||||
if (trackFile.exists()) {
|
||||
return doRead(trackFile, reader -> {
|
||||
reader.beginObject();
|
||||
reader.nextName(); // name record
|
||||
reader.nextString(); // name
|
||||
reader.nextName(); // groups record
|
||||
reader.beginArray();
|
||||
List<String> groups = new ArrayList<>();
|
||||
while (reader.hasNext()) {
|
||||
groups.add(reader.nextString());
|
||||
}
|
||||
track.setGroups(groups);
|
||||
reader.endArray();
|
||||
reader.endObject();
|
||||
return true;
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
trackFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
File trackFile = new File(tracksDir, name + ".json");
|
||||
if (!trackFile.exists()) {
|
||||
try {
|
||||
trackFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean success = doWrite(trackFile, writer -> {
|
||||
writer.beginObject();
|
||||
writer.name("name").value(track.getName());
|
||||
writer.name("groups");
|
||||
writer.beginArray();
|
||||
for (String s : track.getGroups()) {
|
||||
writer.value(s);
|
||||
return doWrite(trackFile, writer -> {
|
||||
writer.beginObject();
|
||||
writer.name("name").value(track.getName());
|
||||
writer.name("groups");
|
||||
writer.beginArray();
|
||||
for (String s : track.getGroups()) {
|
||||
writer.value(s);
|
||||
}
|
||||
writer.endArray();
|
||||
writer.endObject();
|
||||
return true;
|
||||
});
|
||||
}
|
||||
writer.endArray();
|
||||
writer.endObject();
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!success) return false;
|
||||
}, false);
|
||||
} finally {
|
||||
track.getIoLock().unlock();
|
||||
}
|
||||
|
||||
boolean success = doRead(trackFile, reader -> {
|
||||
reader.beginObject();
|
||||
reader.nextName(); // name record
|
||||
reader.nextString(); // name
|
||||
reader.nextName(); // groups record
|
||||
reader.beginArray();
|
||||
while (reader.hasNext()) {
|
||||
groups.add(reader.nextString());
|
||||
}
|
||||
reader.endArray();
|
||||
reader.endObject();
|
||||
return true;
|
||||
});
|
||||
|
||||
track.setGroups(groups);
|
||||
if (success) plugin.getTrackManager().updateOrSet(track);
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadTrack(String name) {
|
||||
Track track = plugin.getTrackManager().make(name);
|
||||
List<String> groups = new ArrayList<>();
|
||||
Track track = plugin.getTrackManager().getOrMake(name);
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File trackFile = new File(tracksDir, name + ".json");
|
||||
return trackFile.exists() && doRead(trackFile, reader -> {
|
||||
reader.beginObject();
|
||||
reader.nextName(); // name record
|
||||
reader.nextString(); // name
|
||||
reader.nextName(); // groups
|
||||
reader.beginArray();
|
||||
List<String> groups = new ArrayList<>();
|
||||
while (reader.hasNext()) {
|
||||
groups.add(reader.nextString());
|
||||
}
|
||||
track.setGroups(groups);
|
||||
reader.endArray();
|
||||
reader.endObject();
|
||||
return true;
|
||||
});
|
||||
|
||||
File trackFile = new File(tracksDir, name + ".json");
|
||||
if (!trackFile.exists()) {
|
||||
return false;
|
||||
}, false);
|
||||
} finally {
|
||||
track.getIoLock().unlock();
|
||||
}
|
||||
|
||||
boolean success = doRead(trackFile, reader -> {
|
||||
reader.beginObject();
|
||||
reader.nextName(); // name record
|
||||
reader.nextString(); // name
|
||||
reader.nextName(); // groups record
|
||||
reader.beginArray();
|
||||
while (reader.hasNext()) {
|
||||
groups.add(reader.nextString());
|
||||
}
|
||||
reader.endArray();
|
||||
reader.endObject();
|
||||
return true;
|
||||
});
|
||||
|
||||
track.setGroups(groups);
|
||||
if (success) plugin.getTrackManager().updateOrSet(track);
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -431,44 +472,71 @@ public class JSONDatastore extends FlatfileDatastore {
|
||||
.map(s -> s.substring(0, s.length() - 5))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
plugin.getTrackManager().unloadAll();
|
||||
tracks.forEach(this::loadTrack);
|
||||
|
||||
TrackManager tm = plugin.getTrackManager();
|
||||
tm.getAll().values().stream()
|
||||
.filter(t -> !tracks.contains(t.getName()))
|
||||
.forEach(tm::unload);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveTrack(Track track) {
|
||||
File trackFile = new File(tracksDir, track.getName() + ".json");
|
||||
if (!trackFile.exists()) {
|
||||
try {
|
||||
trackFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File trackFile = new File(tracksDir, track.getName() + ".json");
|
||||
if (!trackFile.exists()) {
|
||||
try {
|
||||
trackFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return doWrite(trackFile, writer -> {
|
||||
writer.beginObject();
|
||||
writer.name("name").value(track.getName());
|
||||
writer.name("groups");
|
||||
writer.beginArray();
|
||||
for (String s : track.getGroups()) {
|
||||
writer.value(s);
|
||||
}
|
||||
writer.endArray();
|
||||
writer.endObject();
|
||||
return true;
|
||||
});
|
||||
return doWrite(trackFile, writer -> {
|
||||
writer.beginObject();
|
||||
writer.name("name").value(track.getName());
|
||||
writer.name("groups");
|
||||
writer.beginArray();
|
||||
for (String s : track.getGroups()) {
|
||||
writer.value(s);
|
||||
}
|
||||
writer.endArray();
|
||||
writer.endObject();
|
||||
return true;
|
||||
});
|
||||
}, false);
|
||||
} finally {
|
||||
track.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteTrack(Track track) {
|
||||
File trackFile = new File(tracksDir, track.getName() + ".json");
|
||||
if (trackFile.exists()) {
|
||||
trackFile.delete();
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File trackFile = new File(tracksDir, track.getName() + ".json");
|
||||
if (trackFile.exists()) {
|
||||
trackFile.delete();
|
||||
}
|
||||
return true;
|
||||
}, false);
|
||||
} finally {
|
||||
track.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> T call(Callable<T> c, T def) {
|
||||
try {
|
||||
return c.call();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return def;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
interface WriteOperation {
|
||||
|
@ -39,6 +39,7 @@ import me.lucko.luckperms.storage.DatastoreConfiguration;
|
||||
import me.lucko.luckperms.tracks.Track;
|
||||
import me.lucko.luckperms.tracks.TrackManager;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.users.UserIdentifier;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.util.*;
|
||||
@ -140,52 +141,77 @@ public class MongoDBDatastore extends Datastore {
|
||||
|
||||
@Override
|
||||
public boolean loadUser(UUID uuid, String username) {
|
||||
User user = plugin.getUserManager().make(uuid, username);
|
||||
boolean success = call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("users");
|
||||
User user = plugin.getUserManager().getOrMake(UserIdentifier.of(uuid, username));
|
||||
user.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("users");
|
||||
|
||||
try (MongoCursor<Document> cursor = c.find(new Document("_id", user.getUuid())).iterator()) {
|
||||
if (cursor.hasNext()) {
|
||||
Document d = cursor.next();
|
||||
user.setPrimaryGroup(d.getString("primaryGroup"));
|
||||
user.setNodes(revert((Map<String, Boolean>) d.get("perms")));
|
||||
try (MongoCursor<Document> cursor = c.find(new Document("_id", user.getUuid())).iterator()) {
|
||||
if (cursor.hasNext()) {
|
||||
// User exists, let's load.
|
||||
Document d = cursor.next();
|
||||
user.setNodes(revert((Map<String, Boolean>) d.get("perms")));
|
||||
user.setPrimaryGroup(d.getString("primaryGroup"));
|
||||
|
||||
if (user.getName().equalsIgnoreCase("null")) {
|
||||
user.setName(d.getString("name"));
|
||||
} else {
|
||||
if (!d.getString("name").equals(user.getName())) {
|
||||
boolean save = plugin.getUserManager().giveDefaultIfNeeded(user, false);
|
||||
|
||||
if (user.getName().equalsIgnoreCase("null")) {
|
||||
user.setName(d.getString("name"));
|
||||
} else {
|
||||
if (!d.getString("name").equals(user.getName())) {
|
||||
save = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (save) {
|
||||
c.replaceOne(new Document("_id", user.getUuid()), fromUser(user));
|
||||
}
|
||||
} else {
|
||||
if (plugin.getUserManager().shouldSave(user)) {
|
||||
user.clearNodes();
|
||||
user.setPrimaryGroup(null);
|
||||
plugin.getUserManager().giveDefaultIfNeeded(user, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}, false);
|
||||
|
||||
if (success) plugin.getUserManager().updateOrSet(user);
|
||||
return success;
|
||||
return true;
|
||||
}, false);
|
||||
} finally {
|
||||
user.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveUser(User user) {
|
||||
if (!plugin.getUserManager().shouldSave(user)) {
|
||||
return call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("users");
|
||||
return c.deleteOne(new Document("_id", user.getUuid())).wasAcknowledged();
|
||||
}, false);
|
||||
user.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("users");
|
||||
return c.deleteOne(new Document("_id", user.getUuid())).wasAcknowledged();
|
||||
}, false);
|
||||
} finally {
|
||||
user.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
return call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("users");
|
||||
try (MongoCursor<Document> cursor = c.find(new Document("_id", user.getUuid())).iterator()) {
|
||||
if (!cursor.hasNext()) {
|
||||
c.insertOne(fromUser(user));
|
||||
} else {
|
||||
c.replaceOne(new Document("_id", user.getUuid()), fromUser(user));
|
||||
user.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("users");
|
||||
try (MongoCursor<Document> cursor = c.find(new Document("_id", user.getUuid())).iterator()) {
|
||||
if (!cursor.hasNext()) {
|
||||
c.insertOne(fromUser(user));
|
||||
} else {
|
||||
c.replaceOne(new Document("_id", user.getUuid()), fromUser(user));
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}, false);
|
||||
return true;
|
||||
}, false);
|
||||
} finally {
|
||||
user.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -214,85 +240,103 @@ public class MongoDBDatastore extends Datastore {
|
||||
|
||||
@Override
|
||||
public boolean createAndLoadGroup(String name) {
|
||||
Group group = plugin.getGroupManager().make(name);
|
||||
boolean success = call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("groups");
|
||||
Group group = plugin.getGroupManager().getOrMake(name);
|
||||
group.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("groups");
|
||||
|
||||
try (MongoCursor<Document> cursor = c.find(new Document("_id", group.getName())).iterator()) {
|
||||
if (!cursor.hasNext()) {
|
||||
c.insertOne(fromGroup(group));
|
||||
} else {
|
||||
Document d = cursor.next();
|
||||
group.setNodes(revert((Map<String, Boolean>) d.get("perms")));
|
||||
try (MongoCursor<Document> cursor = c.find(new Document("_id", group.getName())).iterator()) {
|
||||
if (cursor.hasNext()) {
|
||||
// Group exists, let's load.
|
||||
Document d = cursor.next();
|
||||
group.setNodes(revert((Map<String, Boolean>) d.get("perms")));
|
||||
} else {
|
||||
c.insertOne(fromGroup(group));
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}, false);
|
||||
|
||||
if (success) plugin.getGroupManager().updateOrSet(group);
|
||||
return success;
|
||||
return true;
|
||||
}, false);
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadGroup(String name) {
|
||||
Group group = plugin.getGroupManager().make(name);
|
||||
boolean success = call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("groups");
|
||||
Group group = plugin.getGroupManager().getOrMake(name);
|
||||
group.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("groups");
|
||||
|
||||
try (MongoCursor<Document> cursor = c.find(new Document("_id", group.getName())).iterator()) {
|
||||
if (cursor.hasNext()) {
|
||||
Document d = cursor.next();
|
||||
group.setNodes(revert((Map<String, Boolean>) d.get("perms")));
|
||||
return true;
|
||||
try (MongoCursor<Document> cursor = c.find(new Document("_id", group.getName())).iterator()) {
|
||||
if (cursor.hasNext()) {
|
||||
Document d = cursor.next();
|
||||
group.setNodes(revert((Map<String, Boolean>) d.get("perms")));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}, false);
|
||||
|
||||
if (success) plugin.getGroupManager().updateOrSet(group);
|
||||
return success;
|
||||
}, false);
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadAllGroups() {
|
||||
List<Group> groups = new ArrayList<>();
|
||||
List<String> groups = new ArrayList<>();
|
||||
boolean success = call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("groups");
|
||||
|
||||
boolean b = true;
|
||||
try (MongoCursor<Document> cursor = c.find().iterator()) {
|
||||
while (cursor.hasNext()) {
|
||||
Document d = cursor.next();
|
||||
Group group = plugin.getGroupManager().make(d.getString("_id"));
|
||||
group.setNodes(revert((Map<String, Boolean>) d.get("perms")));
|
||||
groups.add(group);
|
||||
String name = cursor.next().getString("_id");
|
||||
if (!loadGroup(name)) {
|
||||
b = false;
|
||||
}
|
||||
groups.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return b;
|
||||
}, false);
|
||||
|
||||
if (success) {
|
||||
GroupManager gm = plugin.getGroupManager();
|
||||
gm.unloadAll();
|
||||
groups.forEach(gm::set);
|
||||
gm.getAll().values().stream()
|
||||
.filter(g -> !groups.contains(g.getName()))
|
||||
.forEach(gm::unload);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveGroup(Group group) {
|
||||
return call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("groups");
|
||||
return c.replaceOne(new Document("_id", group.getName()), fromGroup(group)).wasAcknowledged();
|
||||
}, false);
|
||||
group.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("groups");
|
||||
return c.replaceOne(new Document("_id", group.getName()), fromGroup(group)).wasAcknowledged();
|
||||
}, false);
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteGroup(Group group) {
|
||||
boolean success = call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("groups");
|
||||
return c.deleteOne(new Document("_id", group.getName())).wasAcknowledged();
|
||||
}, false);
|
||||
group.getIoLock().lock();
|
||||
boolean success;
|
||||
try {
|
||||
success = call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("groups");
|
||||
return c.deleteOne(new Document("_id", group.getName())).wasAcknowledged();
|
||||
}, false);
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
|
||||
if (success) plugin.getGroupManager().unload(group);
|
||||
return success;
|
||||
@ -300,85 +344,102 @@ public class MongoDBDatastore extends Datastore {
|
||||
|
||||
@Override
|
||||
public boolean createAndLoadTrack(String name) {
|
||||
Track track = plugin.getTrackManager().make(name);
|
||||
boolean success = call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("tracks");
|
||||
Track track = plugin.getTrackManager().getOrMake(name);
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("tracks");
|
||||
|
||||
try (MongoCursor<Document> cursor = c.find(new Document("_id", track.getName())).iterator()) {
|
||||
if (!cursor.hasNext()) {
|
||||
c.insertOne(fromTrack(track));
|
||||
} else {
|
||||
Document d = cursor.next();
|
||||
track.setGroups((List<String>) d.get("groups"));
|
||||
try (MongoCursor<Document> cursor = c.find(new Document("_id", track.getName())).iterator()) {
|
||||
if (!cursor.hasNext()) {
|
||||
c.insertOne(fromTrack(track));
|
||||
} else {
|
||||
Document d = cursor.next();
|
||||
track.setGroups((List<String>) d.get("groups"));
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}, false);
|
||||
|
||||
if (success) plugin.getTrackManager().updateOrSet(track);
|
||||
return success;
|
||||
return true;
|
||||
}, false);
|
||||
} finally {
|
||||
track.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadTrack(String name) {
|
||||
Track track = plugin.getTrackManager().make(name);
|
||||
boolean success = call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("tracks");
|
||||
Track track = plugin.getTrackManager().getOrMake(name);
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("tracks");
|
||||
|
||||
try (MongoCursor<Document> cursor = c.find(new Document("_id", track.getName())).iterator()) {
|
||||
if (cursor.hasNext()) {
|
||||
Document d = cursor.next();
|
||||
track.setGroups((List<String>) d.get("groups"));
|
||||
return true;
|
||||
try (MongoCursor<Document> cursor = c.find(new Document("_id", track.getName())).iterator()) {
|
||||
if (cursor.hasNext()) {
|
||||
Document d = cursor.next();
|
||||
track.setGroups((List<String>) d.get("groups"));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}, false);
|
||||
|
||||
if (success) plugin.getTrackManager().updateOrSet(track);
|
||||
return success;
|
||||
}, false);
|
||||
} finally {
|
||||
track.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadAllTracks() {
|
||||
List<Track> tracks = new ArrayList<>();
|
||||
List<String> tracks = new ArrayList<>();
|
||||
boolean success = call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("tracks");
|
||||
|
||||
boolean b = true;
|
||||
try (MongoCursor<Document> cursor = c.find().iterator()) {
|
||||
while (cursor.hasNext()) {
|
||||
Document d = cursor.next();
|
||||
Track track = plugin.getTrackManager().make(d.getString("_id"));
|
||||
track.setGroups((List<String>) d.get("groups"));
|
||||
tracks.add(track);
|
||||
String name = cursor.next().getString("_id");
|
||||
if (!loadTrack(name)) {
|
||||
b = false;
|
||||
}
|
||||
tracks.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return b;
|
||||
}, false);
|
||||
|
||||
if (success) {
|
||||
TrackManager tm = plugin.getTrackManager();
|
||||
tm.unloadAll();
|
||||
tracks.forEach(tm::set);
|
||||
tm.getAll().values().stream()
|
||||
.filter(t -> !tracks.contains(t.getName()))
|
||||
.forEach(tm::unload);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveTrack(Track track) {
|
||||
return call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("tracks");
|
||||
return c.replaceOne(new Document("_id", track.getName()), fromTrack(track)).wasAcknowledged();
|
||||
}, false);
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("tracks");
|
||||
return c.replaceOne(new Document("_id", track.getName()), fromTrack(track)).wasAcknowledged();
|
||||
}, false);
|
||||
} finally {
|
||||
track.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteTrack(Track track) {
|
||||
boolean success = call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("tracks");
|
||||
return c.deleteOne(new Document("_id", track.getName())).wasAcknowledged();
|
||||
}, false);
|
||||
track.getIoLock().lock();
|
||||
boolean success;
|
||||
try {
|
||||
success = call(() -> {
|
||||
MongoCollection<Document> c = database.getCollection("tracks");
|
||||
return c.deleteOne(new Document("_id", track.getName())).wasAcknowledged();
|
||||
}, false);
|
||||
} finally {
|
||||
track.getIoLock().unlock();
|
||||
}
|
||||
|
||||
if (success) plugin.getTrackManager().unload(track);
|
||||
return success;
|
||||
|
@ -33,6 +33,7 @@ import me.lucko.luckperms.storage.Datastore;
|
||||
import me.lucko.luckperms.tracks.Track;
|
||||
import me.lucko.luckperms.tracks.TrackManager;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.users.UserIdentifier;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.sql.Connection;
|
||||
@ -142,20 +143,29 @@ abstract class SQLDatastore extends Datastore {
|
||||
|
||||
@Override
|
||||
public boolean loadUser(UUID uuid, String username) {
|
||||
User user = plugin.getUserManager().make(uuid, username);
|
||||
boolean success = runQuery(USER_SELECT,
|
||||
preparedStatement -> preparedStatement.setString(1, user.getUuid().toString()),
|
||||
resultSet -> {
|
||||
if (resultSet.next()) {
|
||||
// User exists, let's load.
|
||||
Map<String, Boolean> nodes = gson.fromJson(resultSet.getString("perms"), NM_TYPE);
|
||||
user.setNodes(nodes);
|
||||
user.setPrimaryGroup(resultSet.getString("primary_group"));
|
||||
User user = plugin.getUserManager().getOrMake(UserIdentifier.of(uuid, username));
|
||||
user.getIoLock().lock();
|
||||
try {
|
||||
return runQuery(USER_SELECT,
|
||||
preparedStatement -> preparedStatement.setString(1, user.getUuid().toString()),
|
||||
resultSet -> {
|
||||
if (resultSet.next()) {
|
||||
// User exists, let's load.
|
||||
Map<String, Boolean> nodes = gson.fromJson(resultSet.getString("perms"), NM_TYPE);
|
||||
user.setNodes(nodes);
|
||||
user.setPrimaryGroup(resultSet.getString("primary_group"));
|
||||
|
||||
if (user.getName().equalsIgnoreCase("null")) {
|
||||
user.setName(resultSet.getString("name"));
|
||||
} else {
|
||||
if (!resultSet.getString("name").equals(user.getName())) {
|
||||
boolean save = plugin.getUserManager().giveDefaultIfNeeded(user, false);
|
||||
|
||||
if (user.getName().equalsIgnoreCase("null")) {
|
||||
user.setName(resultSet.getString("name"));
|
||||
} else {
|
||||
if (!resultSet.getString("name").equals(user.getName())) {
|
||||
save = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (save) {
|
||||
runQuery(USER_UPDATE, preparedStatement -> {
|
||||
preparedStatement.setString(1, user.getName());
|
||||
preparedStatement.setString(2, user.getPrimaryGroup());
|
||||
@ -163,47 +173,62 @@ abstract class SQLDatastore extends Datastore {
|
||||
preparedStatement.setString(4, user.getUuid().toString());
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (plugin.getUserManager().shouldSave(user)) {
|
||||
user.clearNodes();
|
||||
user.setPrimaryGroup(null);
|
||||
plugin.getUserManager().giveDefaultIfNeeded(user, false);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
);
|
||||
|
||||
if (success) plugin.getUserManager().updateOrSet(user);
|
||||
return success;
|
||||
);
|
||||
} finally {
|
||||
user.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveUser(User user) {
|
||||
if (!plugin.getUserManager().shouldSave(user)) {
|
||||
return runQuery(USER_DELETE, preparedStatement -> {
|
||||
preparedStatement.setString(1, user.getUuid().toString());
|
||||
});
|
||||
user.getIoLock().lock();
|
||||
try {
|
||||
return runQuery(USER_DELETE, preparedStatement -> {
|
||||
preparedStatement.setString(1, user.getUuid().toString());
|
||||
});
|
||||
} finally {
|
||||
user.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
return runQuery(USER_SELECT,
|
||||
preparedStatement -> preparedStatement.setString(1, user.getUuid().toString()),
|
||||
resultSet -> {
|
||||
if (!resultSet.next()) {
|
||||
// Doesn't already exist, let's insert.
|
||||
return runQuery(USER_INSERT, preparedStatement -> {
|
||||
preparedStatement.setString(1, user.getUuid().toString());
|
||||
preparedStatement.setString(2, user.getName());
|
||||
preparedStatement.setString(3, user.getPrimaryGroup());
|
||||
preparedStatement.setString(4, gson.toJson(exportToLegacy(user.getNodes())));
|
||||
});
|
||||
user.getIoLock().lock();
|
||||
try {
|
||||
return runQuery(USER_SELECT,
|
||||
preparedStatement -> preparedStatement.setString(1, user.getUuid().toString()),
|
||||
resultSet -> {
|
||||
if (!resultSet.next()) {
|
||||
// Doesn't already exist, let's insert.
|
||||
return runQuery(USER_INSERT, preparedStatement -> {
|
||||
preparedStatement.setString(1, user.getUuid().toString());
|
||||
preparedStatement.setString(2, user.getName());
|
||||
preparedStatement.setString(3, user.getPrimaryGroup());
|
||||
preparedStatement.setString(4, gson.toJson(exportToLegacy(user.getNodes())));
|
||||
});
|
||||
|
||||
} else {
|
||||
// User exists, let's update.
|
||||
return runQuery(USER_UPDATE, preparedStatement -> {
|
||||
preparedStatement.setString(1, user.getName());
|
||||
preparedStatement.setString(2, user.getPrimaryGroup());
|
||||
preparedStatement.setString(3, gson.toJson(exportToLegacy(user.getNodes())));
|
||||
preparedStatement.setString(4, user.getUuid().toString());
|
||||
});
|
||||
} else {
|
||||
// User exists, let's update.
|
||||
return runQuery(USER_UPDATE, preparedStatement -> {
|
||||
preparedStatement.setString(1, user.getName());
|
||||
preparedStatement.setString(2, user.getPrimaryGroup());
|
||||
preparedStatement.setString(3, gson.toJson(exportToLegacy(user.getNodes())));
|
||||
preparedStatement.setString(4, user.getUuid().toString());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
);
|
||||
} finally {
|
||||
user.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -230,80 +255,101 @@ abstract class SQLDatastore extends Datastore {
|
||||
|
||||
@Override
|
||||
public boolean createAndLoadGroup(String name) {
|
||||
Group group = plugin.getGroupManager().make(name);
|
||||
boolean success = runQuery(GROUP_SELECT,
|
||||
preparedStatement -> preparedStatement.setString(1, group.getName()),
|
||||
resultSet -> {
|
||||
if (!resultSet.next()) {
|
||||
return runQuery(GROUP_INSERT, preparedStatement -> {
|
||||
preparedStatement.setString(1, group.getName());
|
||||
preparedStatement.setString(2, gson.toJson(exportToLegacy(group.getNodes())));
|
||||
});
|
||||
} else {
|
||||
Map<String, Boolean> nodes = gson.fromJson(resultSet.getString("perms"), NM_TYPE);
|
||||
group.setNodes(nodes);
|
||||
return true;
|
||||
Group group = plugin.getGroupManager().getOrMake(name);
|
||||
group.getIoLock().lock();
|
||||
try {
|
||||
return runQuery(GROUP_SELECT,
|
||||
preparedStatement -> preparedStatement.setString(1, group.getName()),
|
||||
resultSet -> {
|
||||
if (resultSet.next()) {
|
||||
// Group exists, let's load.
|
||||
Map<String, Boolean> nodes = gson.fromJson(resultSet.getString("perms"), NM_TYPE);
|
||||
group.setNodes(nodes);
|
||||
return true;
|
||||
} else {
|
||||
return runQuery(GROUP_INSERT, preparedStatement -> {
|
||||
preparedStatement.setString(1, group.getName());
|
||||
preparedStatement.setString(2, gson.toJson(exportToLegacy(group.getNodes())));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (success) plugin.getGroupManager().updateOrSet(group);
|
||||
return success;
|
||||
);
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadGroup(String name) {
|
||||
Group group = plugin.getGroupManager().make(name);
|
||||
boolean success = runQuery(GROUP_SELECT,
|
||||
preparedStatement -> preparedStatement.setString(1, name),
|
||||
resultSet -> {
|
||||
if (resultSet.next()) {
|
||||
Map<String, Boolean> nodes = gson.fromJson(resultSet.getString("perms"), NM_TYPE);
|
||||
group.setNodes(nodes);
|
||||
return true;
|
||||
Group group = plugin.getGroupManager().getOrMake(name);
|
||||
group.getIoLock().lock();
|
||||
try {
|
||||
return runQuery(GROUP_SELECT,
|
||||
preparedStatement -> preparedStatement.setString(1, name),
|
||||
resultSet -> {
|
||||
if (resultSet.next()) {
|
||||
// Group exists, let's load.
|
||||
Map<String, Boolean> nodes = gson.fromJson(resultSet.getString("perms"), NM_TYPE);
|
||||
group.setNodes(nodes);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
);
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
|
||||
if (success) plugin.getGroupManager().updateOrSet(group);
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadAllGroups() {
|
||||
List<Group> groups = new ArrayList<>();
|
||||
List<String> groups = new ArrayList<>();
|
||||
boolean success = runQuery(GROUP_SELECT_ALL, resultSet -> {
|
||||
boolean b = true;
|
||||
while (resultSet.next()) {
|
||||
Group group = plugin.getGroupManager().make(resultSet.getString("name"));
|
||||
Map<String, Boolean> nodes = gson.fromJson(resultSet.getString("perms"), NM_TYPE);
|
||||
group.setNodes(nodes);
|
||||
groups.add(group);
|
||||
String name = resultSet.getString("name");
|
||||
if (!loadGroup(name)) {
|
||||
b = false;
|
||||
}
|
||||
groups.add(name);
|
||||
}
|
||||
return true;
|
||||
return b;
|
||||
});
|
||||
|
||||
if (success) {
|
||||
GroupManager gm = plugin.getGroupManager();
|
||||
gm.unloadAll();
|
||||
groups.forEach(gm::set);
|
||||
gm.getAll().values().stream()
|
||||
.filter(g -> !groups.contains(g.getName()))
|
||||
.forEach(gm::unload);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveGroup(Group group) {
|
||||
return runQuery(GROUP_UPDATE, preparedStatement -> {
|
||||
preparedStatement.setString(1, gson.toJson(exportToLegacy(group.getNodes())));
|
||||
preparedStatement.setString(2, group.getName());
|
||||
});
|
||||
group.getIoLock().lock();
|
||||
try {
|
||||
return runQuery(GROUP_UPDATE, preparedStatement -> {
|
||||
preparedStatement.setString(1, gson.toJson(exportToLegacy(group.getNodes())));
|
||||
preparedStatement.setString(2, group.getName());
|
||||
});
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteGroup(Group group) {
|
||||
boolean success = runQuery(GROUP_DELETE, preparedStatement -> {
|
||||
preparedStatement.setString(1, group.getName());
|
||||
});
|
||||
group.getIoLock().lock();
|
||||
boolean success;
|
||||
try {
|
||||
success = runQuery(GROUP_DELETE, preparedStatement -> {
|
||||
preparedStatement.setString(1, group.getName());
|
||||
});
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
|
||||
if (success) plugin.getGroupManager().unload(group);
|
||||
return success;
|
||||
@ -311,77 +357,97 @@ abstract class SQLDatastore extends Datastore {
|
||||
|
||||
@Override
|
||||
public boolean createAndLoadTrack(String name) {
|
||||
Track track = plugin.getTrackManager().make(name);
|
||||
boolean success = runQuery(TRACK_SELECT,
|
||||
preparedStatement -> preparedStatement.setString(1, track.getName()),
|
||||
resultSet -> {
|
||||
if (!resultSet.next()) {
|
||||
return runQuery(TRACK_INSERT, preparedStatement -> {
|
||||
preparedStatement.setString(1, track.getName());
|
||||
preparedStatement.setString(2, gson.toJson(track.getGroups()));
|
||||
});
|
||||
} else {
|
||||
track.setGroups(gson.fromJson(resultSet.getString("groups"), T_TYPE));
|
||||
return true;
|
||||
Track track = plugin.getTrackManager().getOrMake(name);
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
return runQuery(TRACK_SELECT,
|
||||
preparedStatement -> preparedStatement.setString(1, track.getName()),
|
||||
resultSet -> {
|
||||
if (resultSet.next()) {
|
||||
// Track exists, let's load.
|
||||
track.setGroups(gson.fromJson(resultSet.getString("groups"), T_TYPE));
|
||||
return true;
|
||||
} else {
|
||||
return runQuery(TRACK_INSERT, preparedStatement -> {
|
||||
preparedStatement.setString(1, track.getName());
|
||||
preparedStatement.setString(2, gson.toJson(track.getGroups()));
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if (success) plugin.getTrackManager().updateOrSet(track);
|
||||
return success;
|
||||
);
|
||||
} finally {
|
||||
track.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadTrack(String name) {
|
||||
Track track = plugin.getTrackManager().make(name);
|
||||
boolean success = runQuery(TRACK_SELECT,
|
||||
preparedStatement -> preparedStatement.setString(1, name),
|
||||
resultSet -> {
|
||||
if (resultSet.next()) {
|
||||
track.setGroups(gson.fromJson(resultSet.getString("groups"), T_TYPE));
|
||||
return true;
|
||||
Track track = plugin.getTrackManager().getOrMake(name);
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
return runQuery(TRACK_SELECT,
|
||||
preparedStatement -> preparedStatement.setString(1, name),
|
||||
resultSet -> {
|
||||
if (resultSet.next()) {
|
||||
track.setGroups(gson.fromJson(resultSet.getString("groups"), T_TYPE));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
);
|
||||
|
||||
if (success) plugin.getTrackManager().updateOrSet(track);
|
||||
return success;
|
||||
);
|
||||
} finally {
|
||||
track.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadAllTracks() {
|
||||
List<Track> tracks = new ArrayList<>();
|
||||
List<String> tracks = new ArrayList<>();
|
||||
boolean success = runQuery(TRACK_SELECT_ALL, resultSet -> {
|
||||
boolean b = true;
|
||||
while (resultSet.next()) {
|
||||
Track track = plugin.getTrackManager().make(resultSet.getString("name"));
|
||||
track.setGroups(gson.fromJson(resultSet.getString("groups"), T_TYPE));
|
||||
tracks.add(track);
|
||||
String name = resultSet.getString("name");
|
||||
if (!loadTrack(name)) {
|
||||
b = false;
|
||||
}
|
||||
tracks.add(name);
|
||||
}
|
||||
return true;
|
||||
return b;
|
||||
});
|
||||
|
||||
if (success) {
|
||||
TrackManager tm = plugin.getTrackManager();
|
||||
tm.unloadAll();
|
||||
tracks.forEach(tm::set);
|
||||
tm.getAll().values().stream()
|
||||
.filter(t -> !tracks.contains(t.getName()))
|
||||
.forEach(tm::unload);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveTrack(Track track) {
|
||||
return runQuery(TRACK_UPDATE, preparedStatement -> {
|
||||
preparedStatement.setString(1, gson.toJson(track.getGroups()));
|
||||
preparedStatement.setString(2, track.getName());
|
||||
});
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
return runQuery(TRACK_UPDATE, preparedStatement -> {
|
||||
preparedStatement.setString(1, gson.toJson(track.getGroups()));
|
||||
preparedStatement.setString(2, track.getName());
|
||||
});
|
||||
} finally {
|
||||
track.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteTrack(Track track) {
|
||||
boolean success = runQuery(TRACK_DELETE, preparedStatement -> {
|
||||
preparedStatement.setString(1, track.getName());
|
||||
});
|
||||
track.getIoLock().lock();
|
||||
boolean success;
|
||||
try {
|
||||
success = runQuery(TRACK_DELETE, preparedStatement -> {
|
||||
preparedStatement.setString(1, track.getName());
|
||||
});
|
||||
} finally {
|
||||
track.getIoLock().unlock();
|
||||
}
|
||||
|
||||
if (success) plugin.getTrackManager().unload(track);
|
||||
return success;
|
||||
|
@ -26,13 +26,17 @@ import lombok.Cleanup;
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
import me.lucko.luckperms.core.Node;
|
||||
import me.lucko.luckperms.groups.Group;
|
||||
import me.lucko.luckperms.groups.GroupManager;
|
||||
import me.lucko.luckperms.tracks.Track;
|
||||
import me.lucko.luckperms.tracks.TrackManager;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.users.UserIdentifier;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static me.lucko.luckperms.core.PermissionHolder.exportToLegacy;
|
||||
@ -76,96 +80,117 @@ public class YAMLDatastore extends FlatfileDatastore {
|
||||
|
||||
@Override
|
||||
public boolean loadUser(UUID uuid, String username) {
|
||||
User user = plugin.getUserManager().make(uuid, username);
|
||||
boolean success = false;
|
||||
User user = plugin.getUserManager().getOrMake(UserIdentifier.of(uuid, username));
|
||||
user.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File userFile = new File(usersDir, uuid.toString() + ".yml");
|
||||
if (userFile.exists()) {
|
||||
return doRead(userFile, values -> {
|
||||
// User exists, let's load.
|
||||
String name = (String) values.get("name");
|
||||
user.setPrimaryGroup((String) values.get("primary-group"));
|
||||
Map<String, Boolean> perms = (Map<String, Boolean>) values.get("perms");
|
||||
for (Map.Entry<String, Boolean> e : perms.entrySet()) {
|
||||
user.getNodes().add(Node.fromSerialisedNode(e.getKey(), e.getValue()));
|
||||
}
|
||||
|
||||
File userFile = new File(usersDir, uuid.toString() + ".yml");
|
||||
if (userFile.exists()) {
|
||||
final String[] name = {null};
|
||||
success = doRead(userFile, values -> {
|
||||
name[0] = (String) values.get("name");
|
||||
user.setPrimaryGroup((String) values.get("primary-group"));
|
||||
Map<String, Boolean> perms = (Map<String, Boolean>) values.get("perms");
|
||||
for (Map.Entry<String, Boolean> e : perms.entrySet()) {
|
||||
user.getNodes().add(Node.fromSerialisedNode(e.getKey(), e.getValue()));
|
||||
boolean save = plugin.getUserManager().giveDefaultIfNeeded(user, false);
|
||||
|
||||
if (user.getName().equalsIgnoreCase("null")) {
|
||||
user.setName(name);
|
||||
} else {
|
||||
if (!name.equals(user.getName())) {
|
||||
save = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (save) {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("uuid", user.getUuid().toString());
|
||||
data.put("name", user.getName());
|
||||
data.put("primary-group", user.getPrimaryGroup());
|
||||
data.put("perms", exportToLegacy(user.getNodes()));
|
||||
doWrite(userFile, data);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
} else {
|
||||
if (plugin.getUserManager().shouldSave(user)) {
|
||||
user.clearNodes();
|
||||
user.setPrimaryGroup(null);
|
||||
plugin.getUserManager().giveDefaultIfNeeded(user, false);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (user.getName().equalsIgnoreCase("null")) {
|
||||
user.setName(name[0]);
|
||||
} else {
|
||||
if (!name[0].equals(user.getName())) {
|
||||
Map<String, Object> values = new HashMap<>();
|
||||
values.put("uuid", user.getUuid().toString());
|
||||
values.put("name", user.getName());
|
||||
values.put("primary-group", user.getPrimaryGroup());
|
||||
values.put("perms", exportToLegacy(user.getNodes()));
|
||||
doWrite(userFile, values);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
success = true;
|
||||
}, false);
|
||||
} finally {
|
||||
user.getIoLock().unlock();
|
||||
}
|
||||
|
||||
if (success) plugin.getUserManager().updateOrSet(user);
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveUser(User user) {
|
||||
File userFile = new File(usersDir, user.getUuid().toString() + ".yml");
|
||||
if (!plugin.getUserManager().shouldSave(user)) {
|
||||
if (userFile.exists()) {
|
||||
userFile.delete();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
user.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File userFile = new File(usersDir, user.getUuid().toString() + ".yml");
|
||||
if (!plugin.getUserManager().shouldSave(user)) {
|
||||
if (userFile.exists()) {
|
||||
userFile.delete();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!userFile.exists()) {
|
||||
try {
|
||||
userFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!userFile.exists()) {
|
||||
try {
|
||||
userFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> values = new HashMap<>();
|
||||
values.put("uuid", user.getUuid().toString());
|
||||
values.put("name", user.getName());
|
||||
values.put("primary-group", user.getPrimaryGroup());
|
||||
values.put("perms", exportToLegacy(user.getNodes()));
|
||||
return doWrite(userFile, values);
|
||||
Map<String, Object> values = new HashMap<>();
|
||||
values.put("uuid", user.getUuid().toString());
|
||||
values.put("name", user.getName());
|
||||
values.put("primary-group", user.getPrimaryGroup());
|
||||
values.put("perms", exportToLegacy(user.getNodes()));
|
||||
return doWrite(userFile, values);
|
||||
}, false);
|
||||
} finally {
|
||||
user.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cleanupUsers() {
|
||||
File[] files = usersDir.listFiles((dir, name) -> name.endsWith(".yml"));
|
||||
if (files == null) return false;
|
||||
return call(() -> {
|
||||
File[] files = usersDir.listFiles((dir, name1) -> name1.endsWith(".yml"));
|
||||
if (files == null) return false;
|
||||
|
||||
for (File file : files) {
|
||||
Map<String, Boolean> nodes = new HashMap<>();
|
||||
doRead(file, values -> {
|
||||
Map<String, Boolean> perms = (Map<String, Boolean>) values.get("perms");
|
||||
nodes.putAll(perms);
|
||||
return true;
|
||||
});
|
||||
for (File file : files) {
|
||||
Map<String, Boolean> nodes = new HashMap<>();
|
||||
doRead(file, values -> {
|
||||
Map<String, Boolean> perms = (Map<String, Boolean>) values.get("perms");
|
||||
nodes.putAll(perms);
|
||||
return true;
|
||||
});
|
||||
|
||||
boolean shouldDelete = false;
|
||||
if (nodes.size() == 1) {
|
||||
for (Map.Entry<String, Boolean> e : nodes.entrySet()) {
|
||||
// There's only one
|
||||
shouldDelete = e.getKey().equalsIgnoreCase("group.default") && e.getValue();
|
||||
boolean shouldDelete = false;
|
||||
if (nodes.size() == 1) {
|
||||
for (Map.Entry<String, Boolean> e : nodes.entrySet()) {
|
||||
// There's only one
|
||||
shouldDelete = e.getKey().equalsIgnoreCase("group.default") && e.getValue();
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldDelete) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldDelete) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return true;
|
||||
}, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -180,57 +205,57 @@ public class YAMLDatastore extends FlatfileDatastore {
|
||||
|
||||
@Override
|
||||
public boolean createAndLoadGroup(String name) {
|
||||
Group group = plugin.getGroupManager().make(name);
|
||||
Group group = plugin.getGroupManager().getOrMake(name);
|
||||
group.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File groupFile = new File(groupsDir, name + ".yml");
|
||||
if (groupFile.exists()) {
|
||||
return doRead(groupFile, values -> {
|
||||
Map<String, Boolean> perms = (Map<String, Boolean>) values.get("perms");
|
||||
for (Map.Entry<String, Boolean> e : perms.entrySet()) {
|
||||
group.getNodes().add(Node.fromSerialisedNode(e.getKey(), e.getValue()));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
groupFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
File groupFile = new File(groupsDir, name + ".yml");
|
||||
if (!groupFile.exists()) {
|
||||
try {
|
||||
groupFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
Map<String, Object> values = new HashMap<>();
|
||||
values.put("name", group.getName());
|
||||
values.put("perms", exportToLegacy(group.getNodes()));
|
||||
|
||||
if (!doWrite(groupFile, values)) {
|
||||
return false;
|
||||
}
|
||||
Map<String, Object> values = new HashMap<>();
|
||||
values.put("name", group.getName());
|
||||
values.put("perms", exportToLegacy(group.getNodes()));
|
||||
return doWrite(groupFile, values);
|
||||
}
|
||||
}, false);
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
|
||||
boolean success = doRead(groupFile, values -> {
|
||||
Map<String, Boolean> perms = (Map<String, Boolean>) values.get("perms");
|
||||
for (Map.Entry<String, Boolean> e : perms.entrySet()) {
|
||||
group.getNodes().add(Node.fromSerialisedNode(e.getKey(), e.getValue()));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (success) plugin.getGroupManager().updateOrSet(group);
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadGroup(String name) {
|
||||
Group group = plugin.getGroupManager().make(name);
|
||||
Group group = plugin.getGroupManager().getOrMake(name);
|
||||
group.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File groupFile = new File(groupsDir, name + ".yml");
|
||||
return groupFile.exists() && doRead(groupFile, values -> {
|
||||
Map<String, Boolean> perms = (Map<String, Boolean>) values.get("perms");
|
||||
for (Map.Entry<String, Boolean> e : perms.entrySet()) {
|
||||
group.getNodes().add(Node.fromSerialisedNode(e.getKey(), e.getValue()));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
File groupFile = new File(groupsDir, name + ".yml");
|
||||
if (!groupFile.exists()) {
|
||||
return false;
|
||||
}, false);
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
|
||||
boolean success = doRead(groupFile, values -> {
|
||||
Map<String, Boolean> perms = (Map<String, Boolean>) values.get("perms");
|
||||
for (Map.Entry<String, Boolean> e : perms.entrySet()) {
|
||||
group.getNodes().add(Node.fromSerialisedNode(e.getKey(), e.getValue()));
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
if (success) plugin.getGroupManager().updateOrSet(group);
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -241,89 +266,103 @@ public class YAMLDatastore extends FlatfileDatastore {
|
||||
.map(s -> s.substring(0, s.length() - 4))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
plugin.getGroupManager().unloadAll();
|
||||
groups.forEach(this::loadGroup);
|
||||
|
||||
GroupManager gm = plugin.getGroupManager();
|
||||
gm.getAll().values().stream()
|
||||
.filter(g -> !groups.contains(g.getName()))
|
||||
.forEach(gm::unload);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveGroup(Group group) {
|
||||
File groupFile = new File(groupsDir, group.getName() + ".yml");
|
||||
if (!groupFile.exists()) {
|
||||
try {
|
||||
groupFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
group.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File groupFile = new File(groupsDir, group.getName() + ".yml");
|
||||
if (!groupFile.exists()) {
|
||||
try {
|
||||
groupFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> values = new HashMap<>();
|
||||
values.put("name", group.getName());
|
||||
values.put("perms", exportToLegacy(group.getNodes()));
|
||||
return doWrite(groupFile, values);
|
||||
Map<String, Object> values = new HashMap<>();
|
||||
values.put("name", group.getName());
|
||||
values.put("perms", exportToLegacy(group.getNodes()));
|
||||
return doWrite(groupFile, values);
|
||||
}, false);
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteGroup(Group group) {
|
||||
File groupFile = new File(groupsDir, group.getName() + ".yml");
|
||||
if (groupFile.exists()) {
|
||||
groupFile.delete();
|
||||
group.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File groupFile = new File(groupsDir, group.getName() + ".yml");
|
||||
if (groupFile.exists()) {
|
||||
groupFile.delete();
|
||||
}
|
||||
return true;
|
||||
}, false);
|
||||
} finally {
|
||||
group.getIoLock().unlock();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean createAndLoadTrack(String name) {
|
||||
Track track = plugin.getTrackManager().make(name);
|
||||
List<String> groups = new ArrayList<>();
|
||||
Track track = plugin.getTrackManager().getOrMake(name);
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File trackFile = new File(tracksDir, name + ".yml");
|
||||
if (trackFile.exists()) {
|
||||
return doRead(trackFile, values -> {
|
||||
track.setGroups((List<String>) values.get("groups"));
|
||||
return true;
|
||||
});
|
||||
} else {
|
||||
try {
|
||||
trackFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
|
||||
File trackFile = new File(tracksDir, name + ".yml");
|
||||
if (!trackFile.exists()) {
|
||||
try {
|
||||
trackFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
Map<String, Object> values = new HashMap<>();
|
||||
values.put("name", track.getName());
|
||||
values.put("groups", track.getGroups());
|
||||
|
||||
Map<String, Object> values = new HashMap<>();
|
||||
values.put("name", track.getName());
|
||||
values.put("groups", track.getGroups());
|
||||
|
||||
if (!doWrite(trackFile, values)) {
|
||||
return false;
|
||||
}
|
||||
return doWrite(trackFile, values);
|
||||
}
|
||||
}, false);
|
||||
} finally {
|
||||
track.getIoLock().unlock();
|
||||
}
|
||||
|
||||
boolean success = doRead(trackFile, values -> {
|
||||
groups.addAll((List<String>) values.get("groups"));
|
||||
return true;
|
||||
});
|
||||
|
||||
track.setGroups(groups);
|
||||
if (success) plugin.getTrackManager().updateOrSet(track);
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadTrack(String name) {
|
||||
Track track = plugin.getTrackManager().make(name);
|
||||
List<String> groups = new ArrayList<>();
|
||||
|
||||
File trackFile = new File(tracksDir, name + ".yml");
|
||||
if (!trackFile.exists()) {
|
||||
return false;
|
||||
Track track = plugin.getTrackManager().getOrMake(name);
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File trackFile = new File(tracksDir, name + ".yml");
|
||||
return trackFile.exists() && doRead(trackFile, values -> {
|
||||
track.setGroups((List<String>) values.get("groups"));
|
||||
return true;
|
||||
});
|
||||
}, false);
|
||||
} finally {
|
||||
track.getIoLock().unlock();
|
||||
}
|
||||
|
||||
boolean success = doRead(trackFile, values -> {
|
||||
groups.addAll((List<String>) values.get("groups"));
|
||||
return true;
|
||||
});
|
||||
|
||||
track.setGroups(groups);
|
||||
if (success) plugin.getTrackManager().updateOrSet(track);
|
||||
return success;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -334,36 +373,63 @@ public class YAMLDatastore extends FlatfileDatastore {
|
||||
.map(s -> s.substring(0, s.length() - 4))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
plugin.getTrackManager().unloadAll();
|
||||
tracks.forEach(this::loadTrack);
|
||||
|
||||
TrackManager tm = plugin.getTrackManager();
|
||||
tm.getAll().values().stream()
|
||||
.filter(t -> !tracks.contains(t.getName()))
|
||||
.forEach(tm::unload);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean saveTrack(Track track) {
|
||||
File trackFile = new File(tracksDir, track.getName() + ".yml");
|
||||
if (!trackFile.exists()) {
|
||||
try {
|
||||
trackFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File trackFile = new File(tracksDir, track.getName() + ".yml");
|
||||
if (!trackFile.exists()) {
|
||||
try {
|
||||
trackFile.createNewFile();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Object> values = new HashMap<>();
|
||||
values.put("name", track.getName());
|
||||
values.put("groups", track.getGroups());
|
||||
return doWrite(trackFile, values);
|
||||
Map<String, Object> values = new HashMap<>();
|
||||
values.put("name", track.getName());
|
||||
values.put("groups", track.getGroups());
|
||||
return doWrite(trackFile, values);
|
||||
}, false);
|
||||
} finally {
|
||||
track.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteTrack(Track track) {
|
||||
File trackFile = new File(tracksDir, track.getName() + ".yml");
|
||||
if (trackFile.exists()) {
|
||||
trackFile.delete();
|
||||
track.getIoLock().lock();
|
||||
try {
|
||||
return call(() -> {
|
||||
File trackFile = new File(tracksDir, track.getName() + ".yml");
|
||||
if (trackFile.exists()) {
|
||||
trackFile.delete();
|
||||
}
|
||||
return true;
|
||||
}, false);
|
||||
} finally {
|
||||
track.getIoLock().unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> T call(Callable<T> c, T def) {
|
||||
try {
|
||||
return c.call();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return def;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
interface ReadOperation {
|
||||
|
@ -34,6 +34,8 @@ import me.lucko.luckperms.utils.Identifiable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@ToString
|
||||
@EqualsAndHashCode(of = {"name"})
|
||||
@ -51,6 +53,9 @@ public class Track implements Identifiable<String> {
|
||||
*/
|
||||
private List<String> groups = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
@Getter
|
||||
private final Lock ioLock = new ReentrantLock();
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return name;
|
||||
|
@ -40,18 +40,13 @@ public class TrackManager extends AbstractManager<String, Track> {
|
||||
.collect(Collectors.toSet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copy(Track from, Track to) {
|
||||
to.setGroups(from.getGroups());
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a new track object
|
||||
* @param name The name of the track
|
||||
* @return a new {@link Track} object
|
||||
*/
|
||||
@Override
|
||||
public Track make(String name) {
|
||||
public Track apply(String name) {
|
||||
return new Track(name);
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ import java.util.UUID;
|
||||
|
||||
@ToString(of = {"uuid"})
|
||||
@EqualsAndHashCode(of = {"uuid"}, callSuper = false)
|
||||
public abstract class User extends PermissionHolder implements Identifiable<UUID> {
|
||||
public abstract class User extends PermissionHolder implements Identifiable<UserIdentifier> {
|
||||
|
||||
/**
|
||||
* The users Mojang UUID
|
||||
@ -75,8 +75,8 @@ public abstract class User extends PermissionHolder implements Identifiable<UUID
|
||||
}
|
||||
|
||||
@Override
|
||||
public UUID getId() {
|
||||
return uuid;
|
||||
public UserIdentifier getId() {
|
||||
return UserIdentifier.of(uuid, name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Lucko (Luck) <luck@lucko.me>
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
package me.lucko.luckperms.users;
|
||||
|
||||
import lombok.AccessLevel;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.ToString;
|
||||
import me.lucko.luckperms.utils.Identifiable;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@Getter
|
||||
@ToString
|
||||
@AllArgsConstructor(access = AccessLevel.PRIVATE)
|
||||
public class UserIdentifier implements Identifiable<UUID> {
|
||||
public static UserIdentifier of(UUID uuid, String username) {
|
||||
return new UserIdentifier(uuid, username);
|
||||
}
|
||||
|
||||
private final UUID uuid;
|
||||
private final String username;
|
||||
|
||||
@Override
|
||||
public UUID getId() {
|
||||
return getUuid();
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (o == this) return true;
|
||||
if (!(o instanceof UserIdentifier)) return false;
|
||||
final UserIdentifier other = (UserIdentifier) o;
|
||||
final Object thisUuid = this.getUuid();
|
||||
final Object otherUuid = other.getUuid();
|
||||
return thisUuid == null ? otherUuid == null : thisUuid.equals(otherUuid);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 59 + (this.getUuid() == null ? 43 : this.getUuid().hashCode());
|
||||
}
|
||||
}
|
@ -34,7 +34,7 @@ import java.util.NoSuchElementException;
|
||||
import java.util.UUID;
|
||||
|
||||
@RequiredArgsConstructor
|
||||
public abstract class UserManager extends AbstractManager<UUID, User> {
|
||||
public abstract class UserManager extends AbstractManager<UserIdentifier, User> {
|
||||
private final LuckPermsPlugin plugin;
|
||||
|
||||
/**
|
||||
@ -53,26 +53,15 @@ public abstract class UserManager extends AbstractManager<UUID, User> {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preSet(User u) {
|
||||
giveDefaultIfNeeded(u, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copy(User from, User to) {
|
||||
if (from.getPrimaryGroup() != null) {
|
||||
// This isn't just a black user. we shouldn't override in that case.
|
||||
to.setNodes(from.getNodes());
|
||||
to.setPrimaryGroup(from.getPrimaryGroup());
|
||||
}
|
||||
to.refreshPermissions();
|
||||
public User get(UUID uuid) {
|
||||
return get(UserIdentifier.of(uuid, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a user to the default group
|
||||
* @param user the user to give to
|
||||
*/
|
||||
public void giveDefaultIfNeeded(User user, boolean save) {
|
||||
public boolean giveDefaultIfNeeded(User user, boolean save) {
|
||||
boolean hasGroup = false;
|
||||
|
||||
if (user.getPrimaryGroup() != null && !user.getPrimaryGroup().isEmpty()) {
|
||||
@ -84,18 +73,22 @@ public abstract class UserManager extends AbstractManager<UUID, User> {
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasGroup) {
|
||||
user.setPrimaryGroup("default");
|
||||
try {
|
||||
user.setPermission("group.default", true);
|
||||
} catch (ObjectAlreadyHasException ignored) {
|
||||
ignored.printStackTrace();
|
||||
}
|
||||
|
||||
if (save) {
|
||||
plugin.getDatastore().saveUser(user, Callback.empty());
|
||||
}
|
||||
if (hasGroup) {
|
||||
return false;
|
||||
}
|
||||
|
||||
user.setPrimaryGroup("default");
|
||||
try {
|
||||
user.setPermission("group.default", true);
|
||||
} catch (ObjectAlreadyHasException ignored) {
|
||||
ignored.printStackTrace();
|
||||
}
|
||||
|
||||
if (save) {
|
||||
plugin.getDatastore().saveUser(user, Callback.empty());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean shouldSave(User user) {
|
||||
@ -132,14 +125,6 @@ public abstract class UserManager extends AbstractManager<UUID, User> {
|
||||
*/
|
||||
public abstract void cleanup(User user);
|
||||
|
||||
/**
|
||||
* Makes a new {@link User} object
|
||||
* @param uuid The UUID of the user
|
||||
* @param username The username of the user
|
||||
* @return a new {@link User} object
|
||||
*/
|
||||
public abstract User make(UUID uuid, String username);
|
||||
|
||||
/**
|
||||
* Reloads the data of all online users
|
||||
*/
|
||||
|
@ -26,18 +26,32 @@ import com.google.common.collect.ImmutableMap;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
* An abstract manager class
|
||||
* @param <I> the class used to identify each object held in this manager
|
||||
* @param <T> the class this manager is "managing"
|
||||
*/
|
||||
public abstract class AbstractManager<I, T extends Identifiable<I>> {
|
||||
public abstract class AbstractManager<I, T extends Identifiable<I>> implements Function<I, T> {
|
||||
private final Map<I, T> objects = new HashMap<>();
|
||||
|
||||
public final Map<I, T> getAll() {
|
||||
Map<I, T> map;
|
||||
synchronized (objects) {
|
||||
return ImmutableMap.copyOf(objects);
|
||||
map = ImmutableMap.copyOf(objects);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an object by id
|
||||
* @param id The id to search by
|
||||
* @return a {@link T} object if the object is loaded or makes and returns a new object
|
||||
*/
|
||||
public final T getOrMake(I id) {
|
||||
synchronized (objects) {
|
||||
return objects.computeIfAbsent(id, this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,38 +66,6 @@ public abstract class AbstractManager<I, T extends Identifiable<I>> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a object to the loaded objects map
|
||||
* @param t The object to add
|
||||
*/
|
||||
public final void set(T t) {
|
||||
preSet(t);
|
||||
synchronized (objects) {
|
||||
objects.put(t.getId(), t);
|
||||
}
|
||||
}
|
||||
|
||||
protected void preSet(T t) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates (or sets if the object wasn't already loaded) an object in the objects map
|
||||
* @param t The object to update or set
|
||||
*/
|
||||
public final void updateOrSet(T t) {
|
||||
synchronized (objects) {
|
||||
if (!isLoaded(t.getId())) {
|
||||
// The object isn't already loaded
|
||||
set(t);
|
||||
} else {
|
||||
copy(t, objects.get(t.getId()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void copy(T from, T to);
|
||||
|
||||
/**
|
||||
* Check to see if a object is loaded or not
|
||||
* @param id The id of the object
|
||||
@ -101,9 +83,11 @@ public abstract class AbstractManager<I, T extends Identifiable<I>> {
|
||||
*/
|
||||
public final void unload(T t) {
|
||||
if (t != null) {
|
||||
preUnload(t);
|
||||
synchronized (objects) {
|
||||
objects.remove(t.getId());
|
||||
objects.computeIfPresent(t.getId(), (i, t1) -> {
|
||||
preUnload(t1);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -117,15 +101,9 @@ public abstract class AbstractManager<I, T extends Identifiable<I>> {
|
||||
*/
|
||||
public final void unloadAll() {
|
||||
synchronized (objects) {
|
||||
objects.values().forEach(this::preUnload);
|
||||
objects.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a new object
|
||||
* @param id the id of the object
|
||||
* @return a new {@link T} object
|
||||
*/
|
||||
public abstract T make(I id);
|
||||
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import me.lucko.luckperms.api.sponge.LuckPermsService;
|
||||
import me.lucko.luckperms.api.sponge.LuckPermsUserSubject;
|
||||
import me.lucko.luckperms.api.sponge.simple.SimpleCollection;
|
||||
import me.lucko.luckperms.users.User;
|
||||
import me.lucko.luckperms.users.UserIdentifier;
|
||||
import me.lucko.luckperms.users.UserManager;
|
||||
import org.spongepowered.api.service.context.Context;
|
||||
import org.spongepowered.api.service.permission.PermissionService;
|
||||
@ -62,7 +63,7 @@ public class UserCollection implements SubjectCollection {
|
||||
|
||||
private void load(UUID uuid) {
|
||||
UUID internal = service.getPlugin().getUuidCache().getUUID(uuid);
|
||||
if (!manager.isLoaded(internal)) {
|
||||
if (!manager.isLoaded(UserIdentifier.of(uuid, null))) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -82,7 +83,7 @@ public class UserCollection implements SubjectCollection {
|
||||
return users.get(u);
|
||||
}
|
||||
|
||||
if (manager.isLoaded(u)) {
|
||||
if (manager.isLoaded(UserIdentifier.of(u, null))) {
|
||||
load(u);
|
||||
return users.get(u);
|
||||
}
|
||||
@ -108,7 +109,7 @@ public class UserCollection implements SubjectCollection {
|
||||
public boolean hasRegistered(@NonNull String id) {
|
||||
try {
|
||||
UUID u = UUID.fromString(id);
|
||||
return manager.isLoaded(service.getPlugin().getUuidCache().getUUID(u));
|
||||
return manager.isLoaded(UserIdentifier.of(service.getPlugin().getUuidCache().getUUID(u), null));
|
||||
} catch (IllegalArgumentException e) {
|
||||
User user = manager.get(id);
|
||||
return user != null;
|
||||
|
@ -46,13 +46,12 @@ public class SpongeUserManager extends UserManager implements ContextListener<Pl
|
||||
}
|
||||
|
||||
@Override
|
||||
public User make(UUID uuid) {
|
||||
return new SpongeUser(uuid, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User make(UUID uuid, String username) {
|
||||
return new SpongeUser(uuid, username, plugin);
|
||||
public User apply(UserIdentifier id) {
|
||||
SpongeUser user = id.getUsername() == null ?
|
||||
new SpongeUser(id.getUuid(), plugin) :
|
||||
new SpongeUser(id.getUuid(), id.getUsername(), plugin);
|
||||
giveDefaultIfNeeded(user, false);
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -24,8 +24,6 @@ package me.lucko.luckperms.users;
|
||||
|
||||
import me.lucko.luckperms.LuckPermsPlugin;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public class StandaloneUserManager extends UserManager {
|
||||
private final LuckPermsPlugin plugin;
|
||||
|
||||
@ -41,13 +39,12 @@ public class StandaloneUserManager extends UserManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public User make(UUID id) {
|
||||
return new StandaloneUser(id, plugin);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User make(UUID uuid, String username) {
|
||||
return new StandaloneUser(uuid, username, plugin);
|
||||
public User apply(UserIdentifier id) {
|
||||
StandaloneUser user = id.getUsername() == null ?
|
||||
new StandaloneUser(id.getUuid(), plugin) :
|
||||
new StandaloneUser(id.getUuid(), id.getUsername(), plugin);
|
||||
giveDefaultIfNeeded(user, false);
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user