API 4.0 - this is a breaking change

This commit is contained in:
Luck
2017-11-07 22:05:44 +00:00
Unverified
parent a2801bff7c
commit 175a21c0e4
98 changed files with 2274 additions and 3747 deletions
@@ -25,6 +25,11 @@
package me.lucko.luckperms.common.actionlog;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.ToString;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
@@ -40,94 +45,269 @@ import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.DateUtil;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* An extended version of {@link LogEntry}, with helper methods for
* populating and using the entry using internal LuckPerms classes.
* An implementation of {@link LogEntry} and {@link LogEntry.Builder},
* with helper methods for populating and using the entry using internal
* LuckPerms classes.
*/
public class ExtendedLogEntry extends LogEntry {
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public class ExtendedLogEntry implements LogEntry {
private static final String FORMAT = "&8(&e%s&8) [&a%s&8] (&b%s&8) &7--> &f%s";
/**
* Compares two LogEntries
*
* @since 3.3
*/
public static final Comparator<LogEntry> COMPARATOR = Comparator
.comparingLong(LogEntry::getTimestamp)
.thenComparing(LogEntry::getActor)
.thenComparing(LogEntry::getActorName, String.CASE_INSENSITIVE_ORDER)
.thenComparing(LogEntry::getType)
.thenComparing(e -> {
UUID u = e.getActed().orElse(null);
return u == null ? "" : u.toString();
})
.thenComparing(LogEntry::getActedName, String.CASE_INSENSITIVE_ORDER)
.thenComparing(LogEntry::getAction);
/**
* Compares two LogEntries in reverse order
*
* @since 3.3
* @see #COMPARATOR
*/
public static final Comparator<LogEntry> REVERSE_ORDER = COMPARATOR.reversed();
/**
* Creates a new log entry builder
*
* @return a new builder
*/
public static ExtendedLogEntryBuilder build() {
return new ExtendedLogEntryBuilder();
}
public ExtendedLogEntry copy() {
return (ExtendedLogEntry) super.copy();
private final long timestamp;
private final UUID actor;
private final String actorName;
private final Type type;
private final UUID acted;
private final String actedName;
private final String action;
@Override
public long getTimestamp() {
return timestamp;
}
@Override
public UUID getActor() {
return actor;
}
@Override
public String getActorName() {
return actorName;
}
@Override
public Type getType() {
return type;
}
@Override
public Optional<UUID> getActed() {
return Optional.ofNullable(acted);
}
@Override
public String getActedName() {
return actedName;
}
@Override
public String getAction() {
return action;
}
@Override
public int compareTo(LogEntry other) {
Preconditions.checkNotNull(other, "other");
return COMPARATOR.compare(this, other);
}
public boolean matchesSearch(String query) {
query = Preconditions.checkNotNull(query, "query").toLowerCase();
return actorName.toLowerCase().contains(query) ||
actedName.toLowerCase().contains(query) ||
action.toLowerCase().contains(query);
}
public String getFormatted() {
return String.format(FORMAT,
String.valueOf(actorName).equals("null") ? actor.toString() : actorName,
Character.toString(type.getCode()),
String.valueOf(actedName).equals("null") && acted != null ? acted.toString() : actedName,
action
);
}
public void submit(LuckPermsPlugin plugin, Sender sender) {
plugin.getLogDispatcher().dispatch(this, sender);
}
public static JsonObject serializeWithId(UUID id, LogEntry entry) {
JsonObject data = new JsonObject();
data.add("id", new JsonPrimitive(id.toString()));
data.add("actor", new JsonPrimitive(entry.getActor().toString()));
data.add("actorName", new JsonPrimitive(entry.getActorName()));
data.add("type", new JsonPrimitive(entry.getEntryType().name()));
if (entry.getActed() != null) {
data.add("acted", new JsonPrimitive(entry.getActed().toString()));
}
data.add("actedName", new JsonPrimitive(entry.getActedName()));
data.add("action", new JsonPrimitive(entry.getAction()));
return data;
@Override
public String toString() {
return "LogEntry(" +
"timestamp=" + this.getTimestamp() + ", " +
"actor=" + this.getActor() + ", " +
"actorName=" + this.getActorName() + ", " +
"type=" + this.getType() + ", " +
"acted=" + this.getActed() + ", " +
"actedName=" + this.getActedName() + ", " +
"action=" + this.getAction() + ")";
}
public static Map.Entry<UUID, LogEntry> deserialize(JsonObject object) {
LogEntry.LogEntryBuilder builder = LogEntry.builder();
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof LogEntry)) return false;
final LogEntry other = (LogEntry) o;
UUID id = UUID.fromString(object.get("id").getAsString());
builder.actor(UUID.fromString(object.get("actor").getAsString()));
builder.actorName(object.get("actorName").getAsString());
builder.entryType(Type.valueOf(object.get("type").getAsString()));
if (object.has("acted")) {
builder.actor(UUID.fromString(object.get("acted").getAsString()));
}
builder.actedName(object.get("actedName").getAsString());
builder.action(object.get("action").getAsString());
return Maps.immutableEntry(id, builder.build());
return this.getTimestamp() == other.getTimestamp() &&
this.getActor().equals(other.getActor()) &&
this.getActorName().equals(other.getActorName()) &&
this.getType() == other.getType() &&
(this.getActed() == null ? other.getActed() == null : this.getActed().equals(other.getActed())) &&
this.getActedName().equals(other.getActedName()) &&
this.getAction().equals(other.getAction());
}
public static class ExtendedLogEntryBuilder extends AbstractLogEntryBuilder<ExtendedLogEntry, ExtendedLogEntryBuilder> {
@Override
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + (int) (this.getTimestamp() >>> 32 ^ this.getTimestamp());
result = result * PRIME + this.getActor().hashCode();
result = result * PRIME + this.getActorName().hashCode();
result = result * PRIME + this.getType().hashCode();
result = result * PRIME + (this.getActed() == null ? 43 : this.getActed().hashCode());
result = result * PRIME + this.getActedName().hashCode();
result = result * PRIME + this.getAction().hashCode();
return result;
}
@ToString
public static class ExtendedLogEntryBuilder implements LogEntry.Builder {
private long timestamp = 0L;
private UUID actor = null;
private String actorName = null;
private Type type = null;
private UUID acted = null;
private String actedName = null;
private String action = null;
@Override
protected ExtendedLogEntry createEmptyLog() {
return new ExtendedLogEntry();
}
@Override
protected ExtendedLogEntryBuilder getThisBuilder() {
public ExtendedLogEntryBuilder setTimestamp(long timestamp) {
this.timestamp = timestamp;
return this;
}
@Override
public ExtendedLogEntryBuilder setActor(UUID actor) {
this.actor = Preconditions.checkNotNull(actor, "actor");
return this;
}
@Override
public ExtendedLogEntryBuilder setActorName(String actorName) {
this.actorName = Preconditions.checkNotNull(actorName, "actorName");
return this;
}
@Override
public ExtendedLogEntryBuilder setType(Type type) {
this.type = Preconditions.checkNotNull(type, "type");
return this;
}
@Override
public ExtendedLogEntryBuilder setActed(UUID acted) {
this.acted = acted; // nullable
return this;
}
@Override
public ExtendedLogEntryBuilder setActedName(String actedName) {
this.actedName = Preconditions.checkNotNull(actedName, "actedName");
return this;
}
@Override
public ExtendedLogEntryBuilder setAction(String action) {
this.action = Preconditions.checkNotNull(action, "action");
return this;
}
public ExtendedLogEntryBuilder timestamp(long timestamp) {
return setTimestamp(timestamp);
}
public ExtendedLogEntryBuilder actor(UUID actor) {
return setActor(actor);
}
public ExtendedLogEntryBuilder actorName(String actorName) {
return setActorName(actorName);
}
public ExtendedLogEntryBuilder type(Type type) {
return setType(type);
}
public ExtendedLogEntryBuilder acted(UUID acted) {
return setActed(acted);
}
public ExtendedLogEntryBuilder actedName(String actedName) {
return setActedName(actedName);
}
public ExtendedLogEntryBuilder action(String action) {
return setAction(action);
}
public ExtendedLogEntryBuilder actor(Sender actor) {
super.actorName(actor.getNameWithLocation());
super.actor(actor.getUuid());
actorName(actor.getNameWithLocation());
actor(actor.getUuid());
return this;
}
public ExtendedLogEntryBuilder acted(PermissionHolder acted) {
if (acted instanceof User) {
super.actedName(((User) acted).getName().orElse("null"));
super.acted(((User) acted).getUuid());
super.entryType(Type.USER);
actedName(((User) acted).getName().orElse("null"));
acted(((User) acted).getUuid());
type(Type.USER);
} else if (acted instanceof Group) {
super.actedName(((Group) acted).getName());
super.entryType(Type.GROUP);
actedName(((Group) acted).getName());
type(Type.GROUP);
}
return this;
}
public ExtendedLogEntryBuilder acted(Track track) {
super.actedName(track.getName());
super.entryType(Type.TRACK);
actedName(track.getName());
type(Type.TRACK);
return this;
}
@@ -158,17 +338,56 @@ public class ExtendedLogEntry extends LogEntry {
}
}
super.action(parts.stream().collect(Collectors.joining(" ")));
action(parts.stream().collect(Collectors.joining(" ")));
return this;
}
@Override
public ExtendedLogEntry build() {
if (getTimestamp() == 0L) {
super.timestamp(DateUtil.unixSecondsNow());
if (timestamp == 0L) {
timestamp(DateUtil.unixSecondsNow());
}
return super.build();
Preconditions.checkNotNull(actor, "actor");
Preconditions.checkNotNull(actorName, "actorName");
Preconditions.checkNotNull(type, "type");
Preconditions.checkNotNull(actedName, "actedName");
Preconditions.checkNotNull(action, "action");
return new ExtendedLogEntry(timestamp, actor, actorName, type, acted, actedName, action);
}
}
public static JsonObject serializeWithId(UUID id, LogEntry entry) {
JsonObject data = new JsonObject();
data.add("id", new JsonPrimitive(id.toString()));
data.add("actor", new JsonPrimitive(entry.getActor().toString()));
data.add("actorName", new JsonPrimitive(entry.getActorName()));
data.add("type", new JsonPrimitive(entry.getType().name()));
if (entry.getActed() != null) {
data.add("acted", new JsonPrimitive(entry.getActed().toString()));
}
data.add("actedName", new JsonPrimitive(entry.getActedName()));
data.add("action", new JsonPrimitive(entry.getAction()));
return data;
}
public static Map.Entry<UUID, ExtendedLogEntry> deserialize(JsonObject object) {
ExtendedLogEntryBuilder builder = build();
UUID id = UUID.fromString(object.get("id").getAsString());
builder.actor(UUID.fromString(object.get("actor").getAsString()));
builder.actorName(object.get("actorName").getAsString());
builder.type(Type.valueOf(object.get("type").getAsString()));
if (object.has("acted")) {
builder.actor(UUID.fromString(object.get("acted").getAsString()));
}
builder.actedName(object.get("actedName").getAsString());
builder.action(object.get("action").getAsString());
return Maps.immutableEntry(id, builder.build());
}
}
@@ -46,7 +46,7 @@ public class Log {
return new Builder();
}
private static SortedMap<Integer, LogEntry> getPage(Set<LogEntry> set, int pageNo, int entries) {
private static SortedMap<Integer, ExtendedLogEntry> getPage(Set<ExtendedLogEntry> set, int pageNo, int entries) {
if (pageNo < 1) {
throw new IllegalArgumentException("pageNo cannot be less than 1: " + pageNo);
}
@@ -57,11 +57,11 @@ public class Log {
"Requested: " + minimumEntries + ", Log Count: " + set.size());
}
final SortedMap<Integer, LogEntry> out = new TreeMap<>();
final SortedMap<Integer, ExtendedLogEntry> out = new TreeMap<>();
final int max = minimumEntries + entries - 1;
int index = 0;
for (LogEntry e : set) {
for (ExtendedLogEntry e : set) {
index++;
if (index >= minimumEntries) {
out.put(index, e);
@@ -83,17 +83,17 @@ public class Log {
}
@Getter
private final SortedSet<LogEntry> content;
private final SortedSet<ExtendedLogEntry> content;
public Log(SortedSet<LogEntry> content) {
public Log(SortedSet<ExtendedLogEntry> content) {
this.content = ImmutableSortedSet.copyOfSorted(content);
}
public SortedSet<LogEntry> getRecent() {
public SortedSet<ExtendedLogEntry> getRecent() {
return content;
}
public SortedMap<Integer, LogEntry> getRecent(int pageNo) {
public SortedMap<Integer, ExtendedLogEntry> getRecent(int pageNo) {
return getPage(content, pageNo, PAGE_ENTRIES);
}
@@ -101,13 +101,13 @@ public class Log {
return getMaxPages(content.size(), PAGE_ENTRIES);
}
public SortedSet<LogEntry> getRecent(UUID actor) {
public SortedSet<ExtendedLogEntry> getRecent(UUID actor) {
return content.stream()
.filter(e -> e.getActor().equals(actor))
.collect(Collectors.toCollection(TreeSet::new));
}
public SortedMap<Integer, LogEntry> getRecent(int pageNo, UUID actor) {
public SortedMap<Integer, ExtendedLogEntry> getRecent(int pageNo, UUID actor) {
return getPage(getRecent(actor), pageNo, PAGE_ENTRIES);
}
@@ -117,69 +117,69 @@ public class Log {
.count(), PAGE_ENTRIES);
}
public SortedSet<LogEntry> getUserHistory(UUID uuid) {
public SortedSet<ExtendedLogEntry> getUserHistory(UUID uuid) {
return content.stream()
.filter(e -> e.getEntryType() == LogEntry.Type.USER)
.filter(e -> e.getType() == LogEntry.Type.USER)
.filter(e -> e.getActed() != null)
.filter(e -> e.getActed().equals(uuid))
.collect(Collectors.toCollection(TreeSet::new));
}
public SortedMap<Integer, LogEntry> getUserHistory(int pageNo, UUID uuid) {
public SortedMap<Integer, ExtendedLogEntry> getUserHistory(int pageNo, UUID uuid) {
return getPage(getUserHistory(uuid), pageNo, PAGE_ENTRIES);
}
public int getUserHistoryMaxPages(UUID uuid) {
return getMaxPages(content.stream()
.filter(e -> e.getEntryType() == LogEntry.Type.USER)
.filter(e -> e.getType() == LogEntry.Type.USER)
.filter(e -> e.getActed() != null)
.filter(e -> e.getActed().equals(uuid))
.count(), PAGE_ENTRIES);
}
public SortedSet<LogEntry> getGroupHistory(String name) {
public SortedSet<ExtendedLogEntry> getGroupHistory(String name) {
return content.stream()
.filter(e -> e.getEntryType() == LogEntry.Type.GROUP)
.filter(e -> e.getType() == LogEntry.Type.GROUP)
.filter(e -> e.getActedName().equals(name))
.collect(Collectors.toCollection(TreeSet::new));
}
public SortedMap<Integer, LogEntry> getGroupHistory(int pageNo, String name) {
public SortedMap<Integer, ExtendedLogEntry> getGroupHistory(int pageNo, String name) {
return getPage(getGroupHistory(name), pageNo, PAGE_ENTRIES);
}
public int getGroupHistoryMaxPages(String name) {
return getMaxPages(content.stream()
.filter(e -> e.getEntryType() == LogEntry.Type.GROUP)
.filter(e -> e.getType() == LogEntry.Type.GROUP)
.filter(e -> e.getActedName().equals(name))
.count(), PAGE_ENTRIES);
}
public SortedSet<LogEntry> getTrackHistory(String name) {
public SortedSet<ExtendedLogEntry> getTrackHistory(String name) {
return content.stream()
.filter(e -> e.getEntryType() == LogEntry.Type.TRACK)
.filter(e -> e.getType() == LogEntry.Type.TRACK)
.filter(e -> e.getActedName().equals(name))
.collect(Collectors.toCollection(TreeSet::new));
}
public SortedMap<Integer, LogEntry> getTrackHistory(int pageNo, String name) {
public SortedMap<Integer, ExtendedLogEntry> getTrackHistory(int pageNo, String name) {
return getPage(getTrackHistory(name), pageNo, PAGE_ENTRIES);
}
public int getTrackHistoryMaxPages(String name) {
return getMaxPages(content.stream()
.filter(e -> e.getEntryType() == LogEntry.Type.TRACK)
.filter(e -> e.getType() == LogEntry.Type.TRACK)
.filter(e -> e.getActedName().equals(name))
.count(), PAGE_ENTRIES);
}
public SortedSet<LogEntry> getSearch(String query) {
public SortedSet<ExtendedLogEntry> getSearch(String query) {
return content.stream()
.filter(e -> e.matchesSearch(query))
.collect(Collectors.toCollection(TreeSet::new));
}
public SortedMap<Integer, LogEntry> getSearch(int pageNo, String query) {
public SortedMap<Integer, ExtendedLogEntry> getSearch(int pageNo, String query) {
return getPage(getSearch(query), pageNo, PAGE_ENTRIES);
}
@@ -191,9 +191,9 @@ public class Log {
@SuppressWarnings("WeakerAccess")
public static class Builder {
private final SortedSet<LogEntry> content = new TreeSet<>();
private final SortedSet<ExtendedLogEntry> content = new TreeSet<>();
public Builder add(LogEntry e) {
public Builder add(ExtendedLogEntry e) {
content.add(e);
return this;
}
@@ -27,7 +27,6 @@ package me.lucko.luckperms.common.actionlog;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.log.LogBroadcastEvent;
import me.lucko.luckperms.common.commands.impl.log.LogNotify;
import me.lucko.luckperms.common.commands.sender.Sender;
@@ -43,7 +42,7 @@ import java.util.Optional;
public class LogDispatcher {
private final LuckPermsPlugin plugin;
public void dispatch(LogEntry entry, Sender sender) {
public void dispatch(ExtendedLogEntry entry, Sender sender) {
// set the event to cancelled if the sender is import
if (!plugin.getApiProvider().getEventFactory().handleLogPublish(sender.isImport(), entry)) {
plugin.getStorage().logAction(entry);
@@ -70,7 +69,7 @@ public class LogDispatcher {
}
}
public void dispatchFromRemote(LogEntry entry) {
public void dispatchFromRemote(ExtendedLogEntry entry) {
if (!plugin.getConfiguration().get(ConfigKeys.BROADCAST_RECEIVED_LOG_ENTRIES)) {
return;
}
@@ -25,80 +25,101 @@
package me.lucko.luckperms.common.api;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NonNull;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.api.LPConfiguration;
import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.api.MessagingService;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.NodeFactory;
import me.lucko.luckperms.api.PlatformType;
import me.lucko.luckperms.api.Storage;
import me.lucko.luckperms.api.Track;
import me.lucko.luckperms.api.User;
import me.lucko.luckperms.api.UuidCache;
import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.api.delegates.MetaStackFactoryDelegate;
import me.lucko.luckperms.common.api.delegates.NodeFactoryDelegate;
import me.lucko.luckperms.common.api.delegates.UserDelegate;
import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.api.context.ContextManager;
import me.lucko.luckperms.api.event.EventBus;
import me.lucko.luckperms.api.manager.GroupManager;
import me.lucko.luckperms.api.manager.TrackManager;
import me.lucko.luckperms.api.manager.UserManager;
import me.lucko.luckperms.api.metastacking.MetaStackFactory;
import me.lucko.luckperms.api.platform.PlatformInfo;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.api.delegates.manager.ApiContextManager;
import me.lucko.luckperms.common.api.delegates.manager.ApiGroupManager;
import me.lucko.luckperms.common.api.delegates.manager.ApiTrackManager;
import me.lucko.luckperms.common.api.delegates.manager.ApiUserManager;
import me.lucko.luckperms.common.api.delegates.misc.ApiMetaStackFactory;
import me.lucko.luckperms.common.api.delegates.misc.ApiNodeFactory;
import me.lucko.luckperms.common.api.delegates.misc.ApiPlatformInfo;
import me.lucko.luckperms.common.event.EventFactory;
import me.lucko.luckperms.common.event.LuckPermsEventBus;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.references.UserIdentifier;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* Implements the LuckPerms API using the plugin instance
*/
public class ApiProvider implements LuckPermsApi {
@Getter(AccessLevel.NONE)
private final LuckPermsPlugin plugin;
@Getter
private final PlatformInfo platformInfo;
private final UserManager userManager;
private final GroupManager groupManager;
private final TrackManager trackManager;
private final LuckPermsEventBus eventBus;
@Getter
private final ContextManager contextManager;
private final MetaStackFactory metaStackFactory;
private final EventFactory eventFactory;
@Getter
private final MetaStackFactoryDelegate metaStackFactory;
public ApiProvider(LuckPermsPlugin plugin) {
this.plugin = plugin;
this.platformInfo = new ApiPlatformInfo(plugin);
this.userManager = new ApiUserManager(plugin, plugin.getUserManager());
this.groupManager = new ApiGroupManager(plugin.getGroupManager());
this.trackManager = new ApiTrackManager(plugin.getTrackManager());
this.eventBus = new LuckPermsEventBus(plugin);
this.contextManager = new ApiContextManager(plugin, plugin.getContextManager());
this.metaStackFactory = new ApiMetaStackFactory(plugin);
this.eventFactory = new EventFactory(eventBus);
this.metaStackFactory = new MetaStackFactoryDelegate(plugin);
}
public EventFactory getEventFactory() {
return eventFactory;
}
@Override
public void runUpdateTask() {
plugin.getUpdateTaskBuffer().request();
public PlatformInfo getPlatformInfo() {
return platformInfo;
}
@Override
public double getApiVersion() {
return 3.4;
public UserManager getUserManager() {
return userManager;
}
@Override
public String getVersion() {
return plugin.getVersion();
public GroupManager getGroupManager() {
return groupManager;
}
@Override
public PlatformType getPlatformType() {
return plugin.getServerType();
public TrackManager getTrackManager() {
return trackManager;
}
@Override
public CompletableFuture<Void> runUpdateTask() {
return plugin.getUpdateTaskBuffer().request();
}
@Override
public EventBus getEventBus() {
return eventBus;
}
@Override
@@ -122,132 +143,22 @@ public class ApiProvider implements LuckPermsApi {
}
@Override
public Logger getLogger() {
return plugin.getLog();
}
@Override
public User getUser(@NonNull UUID uuid) {
final me.lucko.luckperms.common.model.User user = plugin.getUserManager().getIfLoaded(uuid);
return user == null ? null : user.getDelegate();
}
@Override
public Optional<User> getUserSafe(@NonNull UUID uuid) {
return Optional.ofNullable(getUser(uuid));
}
@Override
public User getUser(@NonNull String name) {
final me.lucko.luckperms.common.model.User user = plugin.getUserManager().getByUsername(name);
return user == null ? null : user.getDelegate();
}
@Override
public Optional<User> getUserSafe(@NonNull String name) {
return Optional.ofNullable(getUser(name));
}
@Override
public Set<User> getUsers() {
return plugin.getUserManager().getAll().values().stream().map(me.lucko.luckperms.common.model.User::getDelegate).collect(Collectors.toSet());
}
@Override
public boolean isUserLoaded(@NonNull UUID uuid) {
return plugin.getUserManager().isLoaded(UserIdentifier.of(uuid, null));
}
@Override
public void cleanupUser(@NonNull User user) {
plugin.getUserManager().scheduleUnload(plugin.getUuidCache().getExternalUUID(UserDelegate.cast(user).getUuid()));
}
@Override
public Group getGroup(@NonNull String name) {
final me.lucko.luckperms.common.model.Group group = plugin.getGroupManager().getIfLoaded(name);
return group == null ? null : group.getDelegate();
}
@Override
public Optional<Group> getGroupSafe(@NonNull String name) {
return Optional.ofNullable(getGroup(name));
}
@Override
public Set<Group> getGroups() {
return plugin.getGroupManager().getAll().values().stream().map(me.lucko.luckperms.common.model.Group::getDelegate).collect(Collectors.toSet());
}
@Override
public boolean isGroupLoaded(@NonNull String name) {
return plugin.getGroupManager().isLoaded(name);
}
@Override
public Track getTrack(@NonNull String name) {
final me.lucko.luckperms.common.model.Track track = plugin.getTrackManager().getIfLoaded(name);
return track == null ? null : track.getDelegate();
}
@Override
public Optional<Track> getTrackSafe(@NonNull String name) {
return Optional.ofNullable(getTrack(name));
}
@Override
public Set<Track> getTracks() {
return plugin.getTrackManager().getAll().values().stream().map(me.lucko.luckperms.common.model.Track::getDelegate).collect(Collectors.toSet());
}
@Override
public boolean isTrackLoaded(@NonNull String name) {
return plugin.getTrackManager().isLoaded(name);
public ContextManager getContextManager() {
return contextManager;
}
@Override
public NodeFactory getNodeFactory() {
return NodeFactoryDelegate.INSTANCE;
return ApiNodeFactory.INSTANCE;
}
@Override
public Node.Builder buildNode(@NonNull String permission) throws IllegalArgumentException {
return me.lucko.luckperms.common.node.NodeFactory.newBuilder(permission);
}
@SuppressWarnings("unchecked")
@Override
public void registerContextCalculator(@NonNull ContextCalculator<?> contextCalculator) {
ContextManager contextManager = plugin.getContextManager();
contextManager.registerCalculator(contextCalculator);
public MetaStackFactory getMetaStackFactory() {
return metaStackFactory;
}
@Override
public Optional<Contexts> getContextForUser(@NonNull User user) {
return Optional.ofNullable(plugin.getContextForUser(UserDelegate.cast(user)));
}
@SuppressWarnings("unchecked")
@Override
public ContextSet getContextForPlayer(@NonNull Object player) {
ContextManager contextManager = plugin.getContextManager();
return contextManager.getApplicableContext(player);
}
@SuppressWarnings("unchecked")
@Override
public Contexts getContextsForPlayer(@NonNull Object player) {
ContextManager contextManager = plugin.getContextManager();
return contextManager.getApplicableContexts(player);
}
@Override
public Set<UUID> getUniqueConnections() {
return Collections.unmodifiableSet(plugin.getUniqueConnections());
}
@Override
public long getStartTime() {
return plugin.getStartTime();
public LogEntry.Builder newLogEntryBuilder() {
return ExtendedLogEntry.build();
}
}
@@ -30,7 +30,7 @@ import me.lucko.luckperms.api.LuckPermsApi;
import java.lang.reflect.Method;
public class ApiHandler {
public class ApiSingletonUtils {
private static final Method REGISTER;
private static final Method UNREGISTER;
static {
@@ -50,9 +50,4 @@ public class ApiUtils {
return s.toLowerCase();
}
public static long checkTime(long l) {
Preconditions.checkArgument(DataConstraints.TIME_TEST.test(l), "Unix time '" + l + "' is invalid, as it has already passed.");
return l;
}
}
@@ -1,197 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* 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.common.api.delegates;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NonNull;
import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.node.NodeFactory;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
import java.util.OptionalInt;
import java.util.stream.Collectors;
import static me.lucko.luckperms.common.api.ApiUtils.checkTime;
/**
* Provides a link between {@link Group} and {@link me.lucko.luckperms.common.model.Group}
*/
public final class GroupDelegate extends PermissionHolderDelegate implements Group {
public static me.lucko.luckperms.common.model.Group cast(Group g) {
Preconditions.checkState(g instanceof GroupDelegate, "Illegal instance " + g.getClass() + " cannot be handled by this implementation.");
return ((GroupDelegate) g).getHandle();
}
@Getter(AccessLevel.PACKAGE)
private final me.lucko.luckperms.common.model.Group handle;
public GroupDelegate(@NonNull me.lucko.luckperms.common.model.Group handle) {
super(handle);
this.handle = handle;
}
@Override
public String getName() {
return handle.getName();
}
@Override
public boolean inheritsGroup(@NonNull Group group) {
return handle.inheritsGroup(cast(group));
}
@Override
public boolean inheritsGroup(@NonNull Group group, @NonNull ContextSet contextSet) {
return handle.inheritsGroup(cast(group), contextSet);
}
@Override
public boolean inheritsGroup(@NonNull Group group, @NonNull String server) {
return handle.inheritsGroup(cast(group), server);
}
@Override
public boolean inheritsGroup(@NonNull Group group, @NonNull String server, @NonNull String world) {
return handle.inheritsGroup(cast(group), server, world);
}
@Override
public void setInheritGroup(@NonNull Group group) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(cast(group))).throwException();
}
@Override
public void setInheritGroup(@NonNull Group group, @NonNull String server) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(cast(group), server)).throwException();
}
@Override
public void setInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(cast(group), server, world)).throwException();
}
@Override
public void setInheritGroup(@NonNull Group group, @NonNull long expireAt) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(cast(group), checkTime(expireAt))).throwException();
}
@Override
public void setInheritGroup(@NonNull Group group, @NonNull String server, @NonNull long expireAt) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(cast(group), server, checkTime(expireAt))).throwException();
}
@Override
public void setInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull long expireAt) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(cast(group), server, world, checkTime(expireAt))).throwException();
}
@Override
public void unsetInheritGroup(@NonNull Group group) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(cast(group))).throwException();
}
@Override
public void unsetInheritGroup(@NonNull Group group, @NonNull boolean temporary) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(cast(group), temporary)).throwException();
}
@Override
public void unsetInheritGroup(@NonNull Group group, @NonNull String server) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(cast(group), server)).throwException();
}
@Override
public void unsetInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(cast(group), server, world)).throwException();
}
@Override
public void unsetInheritGroup(@NonNull Group group, @NonNull String server, @NonNull boolean temporary) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(cast(group), server, temporary)).throwException();
}
@Override
public void unsetInheritGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull boolean temporary) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(cast(group), server, world, temporary)).throwException();
}
@Override
public void clearNodes() {
handle.clearNodes();
}
@Override
public List<String> getGroupNames() {
return handle.getOwnNodes().stream()
.filter(Node::isGroupNode)
.map(Node::getGroupName)
.collect(Collectors.toList());
}
@Override
public List<String> getLocalGroups(@NonNull String server, @NonNull String world) {
return handle.getOwnNodes().stream()
.filter(Node::isGroupNode)
.filter(n -> n.shouldApplyOnWorld(world, false, true))
.filter(n -> n.shouldApplyOnServer(server, false, true))
.map(Node::getGroupName)
.collect(Collectors.toList());
}
@Override
public OptionalInt getWeight() {
return handle.getWeight();
}
@Override
public List<String> getLocalGroups(@NonNull String server) {
return handle.getOwnNodes().stream()
.filter(Node::isGroupNode)
.filter(n -> n.shouldApplyOnServer(server, false, true))
.map(Node::getGroupName)
.collect(Collectors.toList());
}
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof GroupDelegate)) return false;
GroupDelegate other = (GroupDelegate) o;
return handle.equals(other.handle);
}
public int hashCode() {
return handle.hashCode();
}
}
@@ -1,463 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* 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.common.api.delegates;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.ImmutableSortedSet;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.DataMutateResult;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.PermissionHolder;
import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.MetaType;
import me.lucko.luckperms.common.node.NodeFactory;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.function.Predicate;
import static me.lucko.luckperms.common.api.ApiUtils.checkTime;
/**
* Provides a link between {@link PermissionHolder} and {@link me.lucko.luckperms.common.model.PermissionHolder}
*/
@AllArgsConstructor
public class PermissionHolderDelegate implements PermissionHolder {
private final me.lucko.luckperms.common.model.PermissionHolder handle;
@Override
public String getObjectName() {
return handle.getObjectName();
}
@Override
public String getFriendlyName() {
if (handle instanceof Group) {
Group group = (Group) this.handle;
return group.getDisplayName().orElse(group.getName());
}
return handle.getFriendlyName();
}
@Override
public ImmutableSetMultimap<ImmutableContextSet, Node> getNodes() {
return handle.getEnduringNodes();
}
@Override
public ImmutableSetMultimap<ImmutableContextSet, Node> getTransientNodes() {
return handle.getTransientNodes();
}
@Override
public List<Node> getOwnNodes() {
return handle.getOwnNodes();
}
@Override
public SortedSet<? extends Node> getPermissions() {
return ImmutableSortedSet.copyOfSorted(handle.getOwnNodesSorted());
}
@Override
public Set<Node> getEnduringPermissions() {
return ImmutableSet.copyOf(handle.getEnduringNodes().values());
}
@Override
public Set<Node> getTransientPermissions() {
return ImmutableSet.copyOf(handle.getTransientNodes().values());
}
@Override
public SortedSet<LocalizedNode> getAllNodes(@NonNull Contexts contexts) {
return new TreeSet<>(handle.resolveInheritancesAlmostEqual(contexts));
}
@Override
public SortedSet<LocalizedNode> getAllNodes() {
return new TreeSet<>(handle.resolveInheritancesAlmostEqual());
}
@Override
public Set<LocalizedNode> getAllNodesFiltered(@NonNull Contexts contexts) {
return new HashSet<>(handle.getAllNodes(contexts));
}
@Override
public Map<String, Boolean> exportNodes(Contexts contexts, boolean lowerCase) {
return new HashMap<>(handle.exportNodesAndShorthand(contexts, lowerCase));
}
@Override
public Tristate hasPermission(@NonNull Node node) {
return handle.hasPermission(node, false);
}
@Override
public Tristate hasTransientPermission(@NonNull Node node) {
return handle.hasPermission(node, true);
}
@Override
public boolean hasPermission(@NonNull String node, @NonNull boolean b) {
return handle.hasPermission(node, b);
}
@Override
public boolean hasPermission(@NonNull String node, @NonNull boolean b, @NonNull String server) {
return handle.hasPermission(node, b, server);
}
@Override
public boolean hasPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull String world) {
return handle.hasPermission(node, b, server, world);
}
@Override
public boolean hasPermission(@NonNull String node, @NonNull boolean b, @NonNull boolean temporary) {
return handle.hasPermission(node, b, temporary);
}
@Override
public boolean hasPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull boolean temporary) {
return handle.hasPermission(node, b, server, temporary);
}
@Override
public boolean hasPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull String world, @NonNull boolean temporary) {
return handle.hasPermission(node, b, server, world, temporary);
}
@Override
public Tristate inheritsPermission(@NonNull Node node) {
return handle.inheritsPermission(node);
}
@Override
public boolean inheritsPermission(@NonNull String node, @NonNull boolean b) {
return handle.inheritsPermission(node, b);
}
@Override
public boolean inheritsPermission(@NonNull String node, @NonNull boolean b, @NonNull String server) {
return handle.inheritsPermission(node, b, server);
}
@Override
public boolean inheritsPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull String world) {
return handle.inheritsPermission(node, b, server, world);
}
@Override
public boolean inheritsPermission(@NonNull String node, @NonNull boolean b, @NonNull boolean temporary) {
return handle.inheritsPermission(node, b, temporary);
}
@Override
public boolean inheritsPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull boolean temporary) {
return handle.inheritsPermission(node, b, server, temporary);
}
@Override
public boolean inheritsPermission(@NonNull String node, @NonNull boolean b, @NonNull String server, @NonNull String world, @NonNull boolean temporary) {
return handle.inheritsPermission(node, b, server, world, temporary);
}
@Override
public void setPermission(@NonNull Node node) throws ObjectAlreadyHasException {
handle.setPermission(node).throwException();
}
@Override
public DataMutateResult setPermissionUnchecked(Node node) {
return handle.setPermission(node);
}
@Override
public void setTransientPermission(@NonNull Node node) throws ObjectAlreadyHasException {
handle.setTransientPermission(node).throwException();
}
@Override
public DataMutateResult setTransientPermissionUnchecked(Node node) {
return handle.setTransientPermission(node);
}
@Override
public void setPermission(@NonNull String node, @NonNull boolean value) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(node, value)).throwException();
}
@Override
public void setPermission(@NonNull String node, @NonNull boolean value, @NonNull String server) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(node, value, server)).throwException();
}
@Override
public void setPermission(@NonNull String node, @NonNull boolean value, @NonNull String server, @NonNull String world) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(node, value, server, world)).throwException();
}
@Override
public void setPermission(@NonNull String node, @NonNull boolean value, @NonNull long expireAt) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(node, value, checkTime(expireAt))).throwException();
}
@Override
public void setPermission(@NonNull String node, @NonNull boolean value, @NonNull String server, @NonNull long expireAt) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(node, value, server, checkTime(expireAt))).throwException();
}
@Override
public void setPermission(@NonNull String node, @NonNull boolean value, @NonNull String server, @NonNull String world, @NonNull long expireAt) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(node, value, server, world, checkTime(expireAt))).throwException();
}
@Override
public void unsetPermission(@NonNull Node node) throws ObjectLacksException {
handle.unsetPermission(node).throwException();
}
@Override
public DataMutateResult unsetPermissionUnchecked(Node node) {
return handle.unsetPermission(node);
}
@Override
public void unsetTransientPermission(@NonNull Node node) throws ObjectLacksException {
handle.unsetTransientPermission(node).throwException();
}
@Override
public DataMutateResult unsetTransientPermissionUnchecked(Node node) {
return handle.unsetTransientPermission(node);
}
@Override
public void clearMatching(Predicate<Node> test) {
handle.removeIf(test);
if (handle instanceof User) {
handle.getPlugin().getUserManager().giveDefaultIfNeeded((User) handle, false);
}
}
@Override
public void clearMatchingTransient(Predicate<Node> test) {
handle.removeIfTransient(test);
}
@Override
public void unsetPermission(@NonNull String node, @NonNull boolean temporary) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(node, temporary)).throwException();
}
@Override
public void unsetPermission(@NonNull String node) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(node)).throwException();
}
@Override
public void unsetPermission(@NonNull String node, @NonNull String server) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(node, server)).throwException();
}
@Override
public void unsetPermission(@NonNull String node, @NonNull String server, @NonNull String world) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(node, server, world)).throwException();
}
@Override
public void unsetPermission(@NonNull String node, @NonNull String server, @NonNull boolean temporary) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(node, server, temporary)).throwException();
}
@Override
public void unsetPermission(@NonNull String node, @NonNull String server, @NonNull String world, @NonNull boolean temporary) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(node, server, world, temporary)).throwException();
}
@Override
public void clearNodes() {
handle.clearNodes();
}
@Override
public void clearNodes(@NonNull ContextSet contextSet) {
handle.clearNodes(contextSet);
}
@Override
public void clearNodes(String server) {
MutableContextSet set = new MutableContextSet();
if (server != null) {
set.add("server", server);
}
handle.clearNodes(set);
}
@Override
public void clearNodes(String server, String world) {
MutableContextSet set = new MutableContextSet();
if (server != null) {
set.add("server", server);
}
if (world != null) {
set.add("world", world);
}
handle.clearNodes(set);
}
@Override
public void clearParents() {
handle.clearParents(true);
}
@Override
public void clearParents(@NonNull ContextSet contextSet) {
handle.clearParents(contextSet, true);
}
@Override
public void clearParents(String server) {
MutableContextSet set = new MutableContextSet();
if (server != null) {
set.add("server", server);
}
handle.clearParents(set, true);
}
@Override
public void clearParents(String server, String world) {
MutableContextSet set = new MutableContextSet();
if (server != null) {
set.add("server", server);
}
if (world != null) {
set.add("world", world);
}
handle.clearParents(set, true);
}
@Override
public void clearMeta() {
handle.clearMeta(MetaType.ANY);
}
@Override
public void clearMeta(@NonNull ContextSet contextSet) {
handle.clearMeta(MetaType.ANY, contextSet);
}
@Override
public void clearMeta(String server) {
MutableContextSet set = new MutableContextSet();
if (server != null) {
set.add("server", server);
}
handle.clearMeta(MetaType.ANY, set);
}
@Override
public void clearMeta(String server, String world) {
MutableContextSet set = new MutableContextSet();
if (server != null) {
set.add("server", server);
}
if (world != null) {
set.add("world", world);
}
handle.clearMeta(MetaType.ANY, set);
}
@Override
public void clearMetaKeys(String key, String server, String world, boolean temporary) {
MutableContextSet set = new MutableContextSet();
if (server != null) {
set.add("server", server);
}
if (world != null) {
set.add("world", world);
}
handle.clearMetaKeys(key, set, temporary);
}
@Override
public void clearTransientNodes() {
handle.clearTransientNodes();
}
@Override
public Set<Node> getTemporaryPermissionNodes() {
return handle.getTemporaryNodes();
}
@Override
public List<LocalizedNode> resolveInheritances(Contexts contexts) {
return handle.resolveInheritances(contexts);
}
@Override
public List<LocalizedNode> resolveInheritances() {
return handle.resolveInheritances();
}
@Override
public Set<Node> getPermanentPermissionNodes() {
return handle.getPermanentNodes();
}
@Override
public void auditTemporaryPermissions() {
handle.auditTemporaryPermissions();
}
}
@@ -1,237 +0,0 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* 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.common.api.delegates;
import lombok.Getter;
import lombok.NonNull;
import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.User;
import me.lucko.luckperms.api.caching.UserData;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.node.NodeFactory;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Collectors;
import static me.lucko.luckperms.common.api.ApiUtils.checkTime;
/**
* Provides a link between {@link User} and {@link me.lucko.luckperms.common.model.User}
*/
public final class UserDelegate extends PermissionHolderDelegate implements User {
public static me.lucko.luckperms.common.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
private final me.lucko.luckperms.common.model.User handle;
public UserDelegate(@NonNull me.lucko.luckperms.common.model.User handle) {
super(handle);
this.handle = handle;
}
@Override
public UUID getUuid() {
return handle.getUuid();
}
@Override
public String getName() {
return handle.getName().orElse(null);
}
@Override
public String getPrimaryGroup() {
return handle.getPrimaryGroup().getValue();
}
@Override
public void setPrimaryGroup(@NonNull String s) throws ObjectAlreadyHasException {
if (getPrimaryGroup().equalsIgnoreCase(s)) {
throw new ObjectAlreadyHasException();
}
if (!getGroupNames().contains(s.toLowerCase())) {
throw new IllegalStateException("User is not a member of that group.");
}
handle.getPrimaryGroup().setStoredValue(s.toLowerCase());
}
@Override
public void refreshPermissions() {
handle.getRefreshBuffer().requestDirectly();
}
@Override
public UserData getCachedData() {
return handle.getUserData();
}
@Override
public Optional<UserData> getUserDataCache() {
return Optional.of(handle.getUserData());
}
@Override
public void setupDataCache() {
handle.preCalculateData();
}
@Override
public boolean isInGroup(@NonNull Group group) {
return handle.inheritsGroup(GroupDelegate.cast(group));
}
@Override
public boolean isInGroup(@NonNull Group group, @NonNull ContextSet contextSet) {
return handle.inheritsGroup(GroupDelegate.cast(group), contextSet);
}
@Override
public boolean isInGroup(@NonNull Group group, @NonNull String server) {
return handle.inheritsGroup(GroupDelegate.cast(group), server);
}
@Override
public boolean isInGroup(@NonNull Group group, @NonNull String server, @NonNull String world) {
return handle.inheritsGroup(GroupDelegate.cast(group), server, world);
}
@Override
public void addGroup(@NonNull Group group) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(GroupDelegate.cast(group))).throwException();
}
@Override
public void addGroup(@NonNull Group group, @NonNull String server) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(GroupDelegate.cast(group), server)).throwException();
}
@Override
public void addGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(GroupDelegate.cast(group), server, world)).throwException();
}
@Override
public void addGroup(@NonNull Group group, @NonNull long expireAt) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(GroupDelegate.cast(group), checkTime(expireAt))).throwException();
}
@Override
public void addGroup(@NonNull Group group, @NonNull String server, @NonNull long expireAt) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(GroupDelegate.cast(group), server, checkTime(expireAt))).throwException();
}
@Override
public void addGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull long expireAt) throws ObjectAlreadyHasException {
handle.setPermission(NodeFactory.make(GroupDelegate.cast(group), server, world, checkTime(expireAt))).throwException();
}
@Override
public void removeGroup(@NonNull Group group) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(GroupDelegate.cast(group))).throwException();
}
@Override
public void removeGroup(@NonNull Group group, @NonNull boolean temporary) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(GroupDelegate.cast(group), temporary)).throwException();
}
@Override
public void removeGroup(@NonNull Group group, @NonNull String server) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(GroupDelegate.cast(group), server)).throwException();
}
@Override
public void removeGroup(@NonNull Group group, @NonNull String server, @NonNull String world) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(GroupDelegate.cast(group), server, world)).throwException();
}
@Override
public void removeGroup(@NonNull Group group, @NonNull String server, @NonNull boolean temporary) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(GroupDelegate.cast(group), server, temporary)).throwException();
}
@Override
public void removeGroup(@NonNull Group group, @NonNull String server, @NonNull String world, @NonNull boolean temporary) throws ObjectLacksException {
handle.unsetPermission(NodeFactory.make(GroupDelegate.cast(group), server, world, temporary)).throwException();
}
@Override
public void clearNodes() {
handle.clearNodes();
}
@Override
public List<String> getGroupNames() {
return handle.getOwnNodes().stream()
.filter(Node::isGroupNode)
.map(Node::getGroupName)
.collect(Collectors.toList());
}
@Override
public List<String> getLocalGroups(@NonNull String server, @NonNull String world) {
return handle.getOwnNodes().stream()
.filter(Node::isGroupNode)
.filter(n -> n.shouldApplyOnWorld(world, false, true))
.filter(n -> n.shouldApplyOnServer(server, false, true))
.map(Node::getGroupName)
.collect(Collectors.toList());
}
@Override
public List<String> getLocalGroups(@NonNull String server) {
return handle.getOwnNodes().stream()
.filter(Node::isGroupNode)
.filter(n -> n.shouldApplyOnServer(server, false, true))
.map(Node::getGroupName)
.collect(Collectors.toList());
}
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof UserDelegate)) return false;
UserDelegate other = (UserDelegate) o;
return handle.equals(other.handle);
}
public int hashCode() {
return handle.hashCode();
}
}
@@ -0,0 +1,109 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* 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.common.api.delegates.manager;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.User;
import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.ContextManager;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.StaticContextCalculator;
import me.lucko.luckperms.common.api.delegates.model.ApiUser;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import java.util.Optional;
@AllArgsConstructor
@SuppressWarnings("unchecked")
public class ApiContextManager implements ContextManager {
private final LuckPermsPlugin plugin;
private final me.lucko.luckperms.common.contexts.ContextManager handle;
private Object checkType(Object subject) {
if (!handle.getSubjectClass().isAssignableFrom(subject.getClass())) {
throw new IllegalStateException("Subject class " + subject.getClass() + " is not assignable from " + handle.getSubjectClass());
}
return subject;
}
@Override
public ImmutableContextSet getApplicableContext(@NonNull Object subject) {
return handle.getApplicableContext(checkType(subject));
}
@Override
public Contexts getApplicableContexts(@NonNull Object subject) {
return handle.getApplicableContexts(checkType(subject));
}
@Override
public Optional<ImmutableContextSet> lookupApplicableContext(@NonNull User user) {
return Optional.ofNullable(plugin.getContextForUser(ApiUser.cast(user))).map(c -> c.getContexts().makeImmutable());
}
@Override
public Optional<Contexts> lookupApplicableContexts(@NonNull User user) {
return Optional.ofNullable(plugin.getContextForUser(ApiUser.cast(user)));
}
@Override
public ImmutableContextSet getStaticContext() {
return handle.getStaticContext();
}
@Override
public Contexts getStaticContexts() {
return handle.getStaticContexts();
}
@Override
public Contexts formContexts(@NonNull Object subject, @NonNull ImmutableContextSet contextSet) {
return handle.formContexts(checkType(subject), contextSet);
}
@Override
public Contexts formContexts(@NonNull ImmutableContextSet contextSet) {
return handle.formContexts(contextSet);
}
@Override
public void registerCalculator(@NonNull ContextCalculator<?> calculator) {
handle.registerCalculator(calculator);
}
@Override
public void registerStaticCalculator(@NonNull StaticContextCalculator calculator) {
handle.registerStaticCalculator(calculator);
}
@Override
public void invalidateCache(@NonNull Object subject) {
handle.invalidateCache(checkType(subject));
}
}
@@ -0,0 +1,56 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* 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.common.api.delegates.manager;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.api.manager.GroupManager;
import java.util.Set;
import java.util.stream.Collectors;
@AllArgsConstructor
public class ApiGroupManager implements GroupManager {
private final me.lucko.luckperms.common.managers.GroupManager handle;
@Override
public Group getGroup(@NonNull String name) {
me.lucko.luckperms.common.model.Group group = handle.getIfLoaded(name);
return group == null ? null : group.getDelegate();
}
@Override
public Set<Group> getLoadedGroups() {
return handle.getAll().values().stream().map(me.lucko.luckperms.common.model.Group::getDelegate).collect(Collectors.toSet());
}
@Override
public boolean isLoaded(@NonNull String name) {
return handle.isLoaded(name);
}
}
@@ -0,0 +1,56 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* 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.common.api.delegates.manager;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import me.lucko.luckperms.api.Track;
import me.lucko.luckperms.api.manager.TrackManager;
import java.util.Set;
import java.util.stream.Collectors;
@AllArgsConstructor
public class ApiTrackManager implements TrackManager {
private final me.lucko.luckperms.common.managers.TrackManager handle;
@Override
public Track getTrack(@NonNull String name) {
me.lucko.luckperms.common.model.Track track = handle.getIfLoaded(name);
return track == null ? null : track.getDelegate();
}
@Override
public Set<Track> getLoadedTracks() {
return handle.getAll().values().stream().map(me.lucko.luckperms.common.model.Track::getDelegate).collect(Collectors.toSet());
}
@Override
public boolean isLoaded(@NonNull String name) {
return handle.isLoaded(name);
}
}
@@ -0,0 +1,72 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* 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.common.api.delegates.manager;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import me.lucko.luckperms.api.User;
import me.lucko.luckperms.api.manager.UserManager;
import me.lucko.luckperms.common.api.delegates.model.ApiUser;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.references.UserIdentifier;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
@AllArgsConstructor
public class ApiUserManager implements UserManager {
private final LuckPermsPlugin plugin;
private final me.lucko.luckperms.common.managers.UserManager handle;
@Override
public User getUser(@NonNull UUID uuid) {
me.lucko.luckperms.common.model.User user = handle.getIfLoaded(uuid);
return user == null ? null : user.getDelegate();
}
@Override
public User getUser(@NonNull String name) {
me.lucko.luckperms.common.model.User user = handle.getByUsername(name);
return user == null ? null : user.getDelegate();
}
@Override
public Set<User> getLoadedUsers() {
return handle.getAll().values().stream().map(me.lucko.luckperms.common.model.User::getDelegate).collect(Collectors.toSet());
}
@Override
public boolean isLoaded(@NonNull UUID uuid) {
return handle.isLoaded(UserIdentifier.of(uuid, null));
}
@Override
public void cleanupUser(@NonNull User user) {
handle.scheduleUnload(plugin.getUuidCache().getExternalUUID(ApiUser.cast(user).getUuid()));
}
}
@@ -23,24 +23,20 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.api.delegates;
package me.lucko.luckperms.common.api.delegates.misc;
import me.lucko.luckperms.api.LPConfiguration;
import me.lucko.luckperms.api.data.DatastoreConfiguration;
import me.lucko.luckperms.common.config.ConfigKey;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
import java.util.Map;
/**
* Provides a link between {@link LPConfiguration} and {@link LuckPermsConfiguration}
*/
public class LPConfigurationDelegate implements LPConfiguration {
public class ApiConfiguration implements LPConfiguration {
private final LuckPermsConfiguration handle;
private final Unsafe unsafe;
public LPConfigurationDelegate(LuckPermsConfiguration handle) {
public ApiConfiguration(LuckPermsConfiguration handle) {
this.handle = handle;
this.unsafe = new UnsafeImpl();
}
@@ -50,11 +46,6 @@ public class LPConfigurationDelegate implements LPConfiguration {
return handle.get(ConfigKeys.SERVER);
}
@Override
public int getSyncTime() {
return handle.get(ConfigKeys.SYNC_TIME);
}
@Override
public boolean getIncludeGlobalPerms() {
return handle.get(ConfigKeys.INCLUDING_GLOBAL_PERMS);
@@ -75,61 +66,6 @@ public class LPConfigurationDelegate implements LPConfiguration {
return handle.get(ConfigKeys.APPLYING_GLOBAL_WORLD_GROUPS);
}
@Override
public boolean getOnlineMode() {
return handle.get(ConfigKeys.USE_SERVER_UUIDS);
}
@Override
public boolean getApplyWildcards() {
return handle.get(ConfigKeys.APPLYING_WILDCARDS);
}
@Override
public boolean getApplyRegex() {
return handle.get(ConfigKeys.APPLYING_REGEX);
}
@Override
public boolean getApplyShorthand() {
return handle.get(ConfigKeys.APPLYING_SHORTHAND);
}
@Override
public boolean getLogNotify() {
return handle.get(ConfigKeys.LOG_NOTIFY);
}
@Override
public boolean getEnableOps() {
return handle.get(ConfigKeys.OPS_ENABLED);
}
@Override
public boolean getCommandsAllowOp() {
return handle.get(ConfigKeys.COMMANDS_ALLOW_OP);
}
@Override
public boolean getAutoOp() {
return handle.get(ConfigKeys.AUTO_OP);
}
@Override
public String getVaultServer() {
return handle.get(ConfigKeys.VAULT_SERVER);
}
@Override
public boolean getVaultIncludeGlobal() {
return handle.get(ConfigKeys.VAULT_INCLUDING_GLOBAL);
}
@Override
public DatastoreConfiguration getDatastoreConfig() {
return handle.get(ConfigKeys.DATABASE_VALUES);
}
@Override
public String getStorageMethod() {
return handle.get(ConfigKeys.STORAGE_METHOD);
@@ -23,7 +23,7 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.api.delegates;
package me.lucko.luckperms.common.api.delegates.misc;
import lombok.AllArgsConstructor;
import lombok.NonNull;
@@ -41,7 +41,7 @@ import java.util.List;
import java.util.Optional;
@AllArgsConstructor
public class MetaStackFactoryDelegate implements MetaStackFactory {
public class ApiMetaStackFactory implements MetaStackFactory {
public final LuckPermsPlugin plugin;
@Override
@@ -23,21 +23,21 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.api.delegates;
package me.lucko.luckperms.common.api.delegates.misc;
import lombok.NonNull;
import me.lucko.luckperms.api.ChatMetaType;
import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.common.api.delegates.model.ApiGroup;
import me.lucko.luckperms.common.node.NodeFactory;
public class NodeFactoryDelegate implements me.lucko.luckperms.api.NodeFactory {
public static final NodeFactoryDelegate INSTANCE = new NodeFactoryDelegate();
public final class ApiNodeFactory implements me.lucko.luckperms.api.NodeFactory {
public static final ApiNodeFactory INSTANCE = new ApiNodeFactory();
private ApiNodeFactory() {
@Override
public Node fromSerialisedNode(@NonNull String serialisedPermission, boolean value) {
return NodeFactory.fromSerializedNode(serialisedPermission, value);
}
@Override
@@ -51,13 +51,13 @@ public class NodeFactoryDelegate implements me.lucko.luckperms.api.NodeFactory {
}
@Override
public Node.Builder newBuilderFromSerialisedNode(@NonNull String serialisedPermission, boolean value) {
return NodeFactory.builderFromLegacyString(serialisedPermission, value);
public Node.Builder makeGroupNode(Group group) {
return NodeFactory.newBuilder("group." + ApiGroup.cast(group).getName());
}
@Override
public Node.Builder makeGroupNode(Group group) {
return NodeFactory.newBuilder("group." + GroupDelegate.cast(group).getName());
public Node.Builder makeGroupNode(String groupName) {
return NodeFactory.newBuilder("group." + groupName);
}
@Override
@@ -0,0 +1,66 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* 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.common.api.delegates.misc;
import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.platform.PlatformInfo;
import me.lucko.luckperms.api.platform.PlatformType;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import java.util.Collections;
import java.util.Set;
import java.util.UUID;
@RequiredArgsConstructor
public class ApiPlatformInfo implements PlatformInfo {
private final LuckPermsPlugin plugin;
@Override
public String getVersion() {
return plugin.getVersion();
}
@Override
public double getApiVersion() {
return 4.0;
}
@Override
public PlatformType getType() {
return plugin.getServerType();
}
@Override
public Set<UUID> getUniqueConnections() {
return Collections.unmodifiableSet(plugin.getUniqueConnections());
}
@Override
public long getStartTime() {
return plugin.getStartTime();
}
}
@@ -23,7 +23,7 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.api.delegates;
package me.lucko.luckperms.common.api.delegates.misc;
import lombok.AllArgsConstructor;
import lombok.NonNull;
@@ -32,11 +32,8 @@ import me.lucko.luckperms.api.UuidCache;
import java.util.UUID;
/**
* Provides a link between {@link UuidCache} and {@link me.lucko.luckperms.common.utils.UuidCache}
*/
@AllArgsConstructor
public class UuidCacheDelegate implements UuidCache {
public class ApiUuidCache implements UuidCache {
private final me.lucko.luckperms.common.utils.UuidCache handle;
@Override
@@ -0,0 +1,84 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* 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.common.api.delegates.model;
import lombok.AccessLevel;
import lombok.Getter;
import lombok.NonNull;
import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.api.context.ContextSet;
import java.util.OptionalInt;
public final class ApiGroup extends ApiPermissionHolder implements Group {
public static me.lucko.luckperms.common.model.Group cast(Group g) {
Preconditions.checkState(g instanceof ApiGroup, "Illegal instance " + g.getClass() + " cannot be handled by this implementation.");
return ((ApiGroup) g).getHandle();
}
@Getter(AccessLevel.PACKAGE)
private final me.lucko.luckperms.common.model.Group handle;
public ApiGroup(@NonNull me.lucko.luckperms.common.model.Group handle) {
super(handle);
this.handle = handle;
}
@Override
public String getName() {
return handle.getName();
}
@Override
public boolean inheritsGroup(@NonNull Group group) {
return handle.inheritsGroup(cast(group));
}
@Override
public boolean inheritsGroup(@NonNull Group group, @NonNull ContextSet contextSet) {
return handle.inheritsGroup(cast(group), contextSet);
}
@Override
public OptionalInt getWeight() {
return handle.getWeight();
}
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof ApiGroup)) return false;
ApiGroup other = (ApiGroup) o;
return handle.equals(other.handle);
}
public int hashCode() {
return handle.hashCode();
}
}
@@ -23,7 +23,7 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.api.delegates;
package me.lucko.luckperms.common.api.delegates.model;
import lombok.AllArgsConstructor;
import lombok.NonNull;
@@ -37,26 +37,24 @@ import java.util.UUID;
import static me.lucko.luckperms.common.api.ApiUtils.checkName;
/**
* Provides a link between {@link Log} and {@link me.lucko.luckperms.common.actionlog.Log}
*/
@SuppressWarnings("unchecked")
@AllArgsConstructor
public class LogDelegate implements Log {
public class ApiLog implements Log {
private final me.lucko.luckperms.common.actionlog.Log handle;
@Override
public SortedSet<LogEntry> getContent() {
return handle.getContent();
return (SortedSet) handle.getContent();
}
@Override
public SortedSet<LogEntry> getRecent() {
return handle.getRecent();
return (SortedSet) handle.getRecent();
}
@Override
public SortedMap<Integer, LogEntry> getRecent(int pageNo) {
return handle.getRecent(pageNo);
return (SortedMap) handle.getRecent(pageNo);
}
@Override
@@ -66,12 +64,12 @@ public class LogDelegate implements Log {
@Override
public SortedSet<LogEntry> getRecent(@NonNull UUID actor) {
return handle.getRecent(actor);
return (SortedSet) handle.getRecent(actor);
}
@Override
public SortedMap<Integer, LogEntry> getRecent(int pageNo, @NonNull UUID actor) {
return handle.getRecent(pageNo, actor);
return (SortedMap) handle.getRecent(pageNo, actor);
}
@Override
@@ -81,12 +79,12 @@ public class LogDelegate implements Log {
@Override
public SortedSet<LogEntry> getUserHistory(@NonNull UUID uuid) {
return handle.getUserHistory(uuid);
return (SortedSet) handle.getUserHistory(uuid);
}
@Override
public SortedMap<Integer, LogEntry> getUserHistory(int pageNo, @NonNull UUID uuid) {
return handle.getUserHistory(pageNo, uuid);
return (SortedMap) handle.getUserHistory(pageNo, uuid);
}
@Override
@@ -96,12 +94,12 @@ public class LogDelegate implements Log {
@Override
public SortedSet<LogEntry> getGroupHistory(@NonNull String name) {
return handle.getGroupHistory(checkName(name));
return (SortedSet) handle.getGroupHistory(checkName(name));
}
@Override
public SortedMap<Integer, LogEntry> getGroupHistory(int pageNo, @NonNull String name) {
return handle.getGroupHistory(pageNo, checkName(name));
return (SortedMap) handle.getGroupHistory(pageNo, checkName(name));
}
@Override
@@ -111,12 +109,12 @@ public class LogDelegate implements Log {
@Override
public SortedSet<LogEntry> getTrackHistory(@NonNull String name) {
return handle.getTrackHistory(checkName(name));
return (SortedSet) handle.getTrackHistory(checkName(name));
}
@Override
public SortedMap<Integer, LogEntry> getTrackHistory(int pageNo, @NonNull String name) {
return handle.getTrackHistory(pageNo, checkName(name));
return (SortedMap) handle.getTrackHistory(pageNo, checkName(name));
}
@Override
@@ -126,12 +124,12 @@ public class LogDelegate implements Log {
@Override
public SortedSet<LogEntry> getSearch(@NonNull String query) {
return handle.getSearch(query);
return (SortedSet) handle.getSearch(query);
}
@Override
public SortedMap<Integer, LogEntry> getSearch(int pageNo, @NonNull String query) {
return handle.getSearch(pageNo, query);
return (SortedMap) handle.getSearch(pageNo, query);
}
@Override
@@ -0,0 +1,232 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* 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.common.api.delegates.model;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.ImmutableSortedSet;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.DataMutateResult;
import me.lucko.luckperms.api.LocalizedNode;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.PermissionHolder;
import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.User;
import me.lucko.luckperms.common.node.MetaType;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.function.Predicate;
@AllArgsConstructor
public class ApiPermissionHolder implements PermissionHolder {
private final me.lucko.luckperms.common.model.PermissionHolder handle;
@Override
public String getObjectName() {
return handle.getObjectName();
}
@Override
public String getFriendlyName() {
if (handle instanceof Group) {
Group group = (Group) this.handle;
return group.getDisplayName().orElse(group.getName());
}
return handle.getFriendlyName();
}
@Override
public ImmutableSetMultimap<ImmutableContextSet, Node> getNodes() {
return handle.getEnduringNodes();
}
@Override
public ImmutableSetMultimap<ImmutableContextSet, Node> getTransientNodes() {
return handle.getTransientNodes();
}
@Override
public List<Node> getOwnNodes() {
return handle.getOwnNodes();
}
@Override
public SortedSet<? extends Node> getPermissions() {
return ImmutableSortedSet.copyOfSorted(handle.getOwnNodesSorted());
}
@Override
public Set<Node> getEnduringPermissions() {
return ImmutableSet.copyOf(handle.getEnduringNodes().values());
}
@Override
public Set<Node> getTransientPermissions() {
return ImmutableSet.copyOf(handle.getTransientNodes().values());
}
@Override
public SortedSet<LocalizedNode> getAllNodes(@NonNull Contexts contexts) {
return new TreeSet<>(handle.resolveInheritancesAlmostEqual(contexts));
}
@Override
public SortedSet<LocalizedNode> getAllNodes() {
return new TreeSet<>(handle.resolveInheritancesAlmostEqual());
}
@Override
public Set<LocalizedNode> getAllNodesFiltered(@NonNull Contexts contexts) {
return new HashSet<>(handle.getAllNodes(contexts));
}
@Override
public Map<String, Boolean> exportNodes(Contexts contexts, boolean lowerCase) {
return new HashMap<>(handle.exportNodesAndShorthand(contexts, lowerCase));
}
@Override
public Tristate hasPermission(@NonNull Node node) {
return handle.hasPermission(node, false);
}
@Override
public Tristate hasTransientPermission(@NonNull Node node) {
return handle.hasPermission(node, true);
}
@Override
public Tristate inheritsPermission(@NonNull Node node) {
return handle.inheritsPermission(node);
}
@Override
public DataMutateResult setPermission(@NonNull Node node) {
return handle.setPermission(node);
}
@Override
public DataMutateResult setTransientPermission(@NonNull Node node) {
return handle.setTransientPermission(node);
}
@Override
public DataMutateResult unsetPermission(@NonNull Node node) {
return handle.unsetPermission(node);
}
@Override
public DataMutateResult unsetTransientPermission(@NonNull Node node) {
return handle.unsetTransientPermission(node);
}
@Override
public void clearMatching(Predicate<Node> test) {
handle.removeIf(test);
if (handle instanceof User) {
handle.getPlugin().getUserManager().giveDefaultIfNeeded((User) handle, false);
}
}
@Override
public void clearMatchingTransient(Predicate<Node> test) {
handle.removeIfTransient(test);
}
@Override
public void clearNodes() {
handle.clearNodes();
}
@Override
public void clearNodes(@NonNull ContextSet contextSet) {
handle.clearNodes(contextSet);
}
@Override
public void clearParents() {
handle.clearParents(true);
}
@Override
public void clearParents(@NonNull ContextSet contextSet) {
handle.clearParents(contextSet, true);
}
@Override
public void clearMeta() {
handle.clearMeta(MetaType.ANY);
}
@Override
public void clearMeta(@NonNull ContextSet contextSet) {
handle.clearMeta(MetaType.ANY, contextSet);
}
@Override
public void clearTransientNodes() {
handle.clearTransientNodes();
}
@Override
public Set<Node> getTemporaryPermissionNodes() {
return handle.getTemporaryNodes();
}
@Override
public List<LocalizedNode> resolveInheritances(Contexts contexts) {
return handle.resolveInheritances(contexts);
}
@Override
public List<LocalizedNode> resolveInheritances() {
return handle.resolveInheritances();
}
@Override
public Set<Node> getPermanentPermissionNodes() {
return handle.getPermanentNodes();
}
@Override
public void auditTemporaryPermissions() {
handle.auditTemporaryPermissions();
}
}
@@ -23,7 +23,7 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.api.delegates;
package me.lucko.luckperms.common.api.delegates.model;
import lombok.AllArgsConstructor;
import lombok.NonNull;
@@ -49,11 +49,8 @@ import java.util.concurrent.Executor;
import static me.lucko.luckperms.common.api.ApiUtils.checkName;
import static me.lucko.luckperms.common.api.ApiUtils.checkUsername;
/**
* Provides a link between {@link Storage} and {@link me.lucko.luckperms.common.storage.Storage}
*/
@AllArgsConstructor
public class StorageDelegate implements Storage {
public class ApiStorage implements Storage {
private final LuckPermsPlugin plugin;
private final me.lucko.luckperms.common.storage.Storage handle;
@@ -84,7 +81,7 @@ public class StorageDelegate implements Storage {
@Override
public CompletableFuture<Log> getLog() {
return handle.noBuffer().getLog().thenApply(log -> log == null ? null : new LogDelegate(log));
return handle.noBuffer().getLog().thenApply(log -> log == null ? null : new ApiLog(log));
}
@Override
@@ -94,7 +91,7 @@ public class StorageDelegate implements Storage {
@Override
public CompletableFuture<Boolean> saveUser(@NonNull User user) {
return handle.noBuffer().saveUser(UserDelegate.cast(user));
return handle.noBuffer().saveUser(ApiUser.cast(user));
}
@Override
@@ -124,7 +121,7 @@ public class StorageDelegate implements Storage {
@Override
public CompletableFuture<Boolean> saveGroup(@NonNull Group group) {
return handle.noBuffer().saveGroup(GroupDelegate.cast(group));
return handle.noBuffer().saveGroup(ApiGroup.cast(group));
}
@Override
@@ -132,7 +129,7 @@ public class StorageDelegate implements Storage {
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().get(ConfigKeys.DEFAULT_GROUP_NAME))) {
throw new IllegalArgumentException("Cannot delete the default group.");
}
return handle.noBuffer().deleteGroup(GroupDelegate.cast(group), DeletionCause.API);
return handle.noBuffer().deleteGroup(ApiGroup.cast(group), DeletionCause.API);
}
@Override
@@ -157,12 +154,12 @@ public class StorageDelegate implements Storage {
@Override
public CompletableFuture<Boolean> saveTrack(@NonNull Track track) {
return handle.noBuffer().saveTrack(TrackDelegate.cast(track));
return handle.noBuffer().saveTrack(ApiTrack.cast(track));
}
@Override
public CompletableFuture<Boolean> deleteTrack(@NonNull Track track) {
return handle.noBuffer().deleteTrack(TrackDelegate.cast(track), DeletionCause.API);
return handle.noBuffer().deleteTrack(ApiTrack.cast(track), DeletionCause.API);
}
@Override
@@ -23,7 +23,7 @@
* SOFTWARE.
*/
package me.lucko.luckperms.common.api.delegates;
package me.lucko.luckperms.common.api.delegates.model;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
@@ -32,21 +32,17 @@ import lombok.NonNull;
import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.DataMutateResult;
import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.api.Track;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
/**
* Provides a link between {@link Track} and {@link me.lucko.luckperms.common.model.Track}
*/
@AllArgsConstructor
public final class TrackDelegate implements Track {
public final class ApiTrack implements Track {
public static me.lucko.luckperms.common.model.Track cast(Track g) {
Preconditions.checkState(g instanceof TrackDelegate, "Illegal instance " + g.getClass() + " cannot be handled by this implementation.");
return ((TrackDelegate) g).getHandle();
Preconditions.checkState(g instanceof ApiTrack, "Illegal instance " + g.getClass() + " cannot be handled by this implementation.");
return ((ApiTrack) g).getHandle();
}
@Getter(AccessLevel.PACKAGE)
@@ -68,46 +64,46 @@ public final class TrackDelegate implements Track {
}
@Override
public String getNext(@NonNull Group current) throws ObjectLacksException {
public String getNext(@NonNull Group current) {
try {
return handle.getNext(GroupDelegate.cast(current));
return handle.getNext(ApiGroup.cast(current));
} catch (IllegalArgumentException e) {
throw new ObjectLacksException();
return null;
}
}
@Override
public String getPrevious(@NonNull Group current) throws ObjectLacksException {
public String getPrevious(@NonNull Group current) {
try {
return handle.getPrevious(GroupDelegate.cast(current));
return handle.getPrevious(ApiGroup.cast(current));
} catch (IllegalArgumentException e) {
throw new ObjectLacksException();
return null;
}
}
@Override
public void appendGroup(@NonNull Group group) throws ObjectAlreadyHasException {
handle.appendGroup(GroupDelegate.cast(group)).throwException();
public DataMutateResult appendGroup(@NonNull Group group) {
return handle.appendGroup(ApiGroup.cast(group));
}
@Override
public void insertGroup(@NonNull Group group, @NonNull int position) throws ObjectAlreadyHasException, IndexOutOfBoundsException {
handle.insertGroup(GroupDelegate.cast(group), position).throwException();
public DataMutateResult insertGroup(@NonNull Group group, @NonNull int position) throws IndexOutOfBoundsException {
return handle.insertGroup(ApiGroup.cast(group), position);
}
@Override
public void removeGroup(@NonNull Group group) throws ObjectLacksException {
handle.removeGroup(GroupDelegate.cast(group)).throwException();
public DataMutateResult removeGroup(@NonNull Group group) {
return handle.removeGroup(ApiGroup.cast(group));
}
@Override
public void removeGroup(@NonNull String group) throws ObjectLacksException {
handle.removeGroup(group).throwException();
public DataMutateResult removeGroup(@NonNull String group) {
return handle.removeGroup(group);
}
@Override
public boolean containsGroup(@NonNull Group group) {
return handle.containsGroup(GroupDelegate.cast(group));
return handle.containsGroup(ApiGroup.cast(group));
}
@Override
@@ -122,9 +118,9 @@ public final class TrackDelegate implements Track {
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof TrackDelegate)) return false;
if (!(o instanceof ApiTrack)) return false;
TrackDelegate other = (TrackDelegate) o;
ApiTrack other = (ApiTrack) o;
return handle.equals(other.handle);
}
@@ -0,0 +1,128 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* 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.common.api.delegates.model;
import lombok.Getter;
import lombok.NonNull;
import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.DataMutateResult;
import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.api.User;
import me.lucko.luckperms.api.caching.UserData;
import me.lucko.luckperms.api.context.ContextSet;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
public final class ApiUser extends ApiPermissionHolder implements User {
public static me.lucko.luckperms.common.model.User cast(User u) {
Preconditions.checkState(u instanceof ApiUser, "Illegal instance " + u.getClass() + " cannot be handled by this implementation.");
return ((ApiUser) u).getHandle();
}
@Getter
private final me.lucko.luckperms.common.model.User handle;
public ApiUser(@NonNull me.lucko.luckperms.common.model.User handle) {
super(handle);
this.handle = handle;
}
@Override
public UUID getUuid() {
return handle.getUuid();
}
@Override
public String getName() {
return handle.getName().orElse(null);
}
@Override
public String getPrimaryGroup() {
return handle.getPrimaryGroup().getValue();
}
@Override
public DataMutateResult setPrimaryGroup(@NonNull String s) {
if (getPrimaryGroup().equalsIgnoreCase(s)) {
return DataMutateResult.ALREADY_HAS;
}
if (!handle.hasPermission("group." + s.toLowerCase(), true)) {
return DataMutateResult.FAIL;
}
handle.getPrimaryGroup().setStoredValue(s.toLowerCase());
return DataMutateResult.SUCCESS;
}
@Override
public UserData getCachedData() {
return handle.getUserData();
}
@Override
public CompletableFuture<Void> refreshCachedData() {
return handle.getRefreshBuffer().request();
}
@Override
public boolean isInGroup(@NonNull Group group) {
return handle.inheritsGroup(ApiGroup.cast(group));
}
@Override
public boolean isInGroup(@NonNull Group group, @NonNull ContextSet contextSet) {
return handle.inheritsGroup(ApiGroup.cast(group), contextSet);
}
@Override
@Deprecated
public void refreshPermissions() {
handle.getRefreshBuffer().requestDirectly();
}
@Override
@Deprecated
public void setupDataCache() {
handle.preCalculateData();
}
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof ApiUser)) return false;
ApiUser other = (ApiUser) o;
return handle.equals(other.handle);
}
public int hashCode() {
return handle.hashCode();
}
}
@@ -71,7 +71,7 @@ public class CreateGroup extends SingleCommand {
Message.CREATE_SUCCESS.send(sender, groupName);
ExtendedLogEntry.build().actor(sender).actedName(groupName).entryType(LogEntry.Type.GROUP)
ExtendedLogEntry.build().actor(sender).actedName(groupName).type(LogEntry.Type.GROUP)
.action("create")
.build().submit(plugin, sender);
@@ -80,7 +80,7 @@ public class DeleteGroup extends SingleCommand {
Message.DELETE_SUCCESS.send(sender, group.getFriendlyName());
ExtendedLogEntry.build().actor(sender).actedName(groupName).entryType(LogEntry.Type.GROUP)
ExtendedLogEntry.build().actor(sender).actedName(groupName).type(LogEntry.Type.GROUP)
.action("delete")
.build().submit(plugin, sender);
@@ -25,7 +25,7 @@
package me.lucko.luckperms.common.commands.impl.log;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.actionlog.Log;
import me.lucko.luckperms.common.commands.CommandException;
import me.lucko.luckperms.common.commands.CommandResult;
@@ -84,11 +84,11 @@ public class LogGroupHistory extends SubCommand<Log> {
return CommandResult.INVALID_ARGS;
}
SortedMap<Integer, LogEntry> entries = log.getGroupHistory(page, group);
SortedMap<Integer, ExtendedLogEntry> entries = log.getGroupHistory(page, group);
String name = entries.values().stream().findAny().get().getActedName();
Message.LOG_HISTORY_GROUP_HEADER.send(sender, name, page, maxPage);
for (Map.Entry<Integer, LogEntry> e : entries.entrySet()) {
for (Map.Entry<Integer, ExtendedLogEntry> e : entries.entrySet()) {
long time = e.getValue().getTimestamp();
long now = DateUtil.unixSecondsNow();
Message.LOG_ENTRY.send(sender, e.getKey(), DateUtil.formatTimeShort(now - time), e.getValue().getFormatted());
@@ -25,7 +25,7 @@
package me.lucko.luckperms.common.commands.impl.log;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.actionlog.Log;
import me.lucko.luckperms.common.commands.CommandException;
import me.lucko.luckperms.common.commands.CommandResult;
@@ -127,7 +127,7 @@ public class LogRecent extends SubCommand<Log> {
return CommandResult.INVALID_ARGS;
}
SortedMap<Integer, LogEntry> entries = (filter != null) ? log.getRecent(page, filter) : log.getRecent(page);
SortedMap<Integer, ExtendedLogEntry> entries = (filter != null) ? log.getRecent(page, filter) : log.getRecent(page);
if (filter != null) {
String name = entries.values().stream().findAny().get().getActorName();
Message.LOG_RECENT_BY_HEADER.send(sender, name, page, maxPage);
@@ -135,7 +135,7 @@ public class LogRecent extends SubCommand<Log> {
Message.LOG_RECENT_HEADER.send(sender, page, maxPage);
}
for (Map.Entry<Integer, LogEntry> e : entries.entrySet()) {
for (Map.Entry<Integer, ExtendedLogEntry> e : entries.entrySet()) {
long time = e.getValue().getTimestamp();
long now = DateUtil.unixSecondsNow();
Message.LOG_ENTRY.send(sender, e.getKey(), DateUtil.formatTimeShort(now - time), e.getValue().getFormatted());
@@ -25,7 +25,7 @@
package me.lucko.luckperms.common.commands.impl.log;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.actionlog.Log;
import me.lucko.luckperms.common.commands.CommandException;
import me.lucko.luckperms.common.commands.CommandResult;
@@ -77,10 +77,10 @@ public class LogSearch extends SubCommand<Log> {
return CommandResult.INVALID_ARGS;
}
SortedMap<Integer, LogEntry> entries = log.getSearch(page, query);
SortedMap<Integer, ExtendedLogEntry> entries = log.getSearch(page, query);
Message.LOG_SEARCH_HEADER.send(sender, query, page, maxPage);
for (Map.Entry<Integer, LogEntry> e : entries.entrySet()) {
for (Map.Entry<Integer, ExtendedLogEntry> e : entries.entrySet()) {
long time = e.getValue().getTimestamp();
long now = DateUtil.unixSecondsNow();
Message.LOG_ENTRY.send(sender, e.getKey(), DateUtil.formatTimeShort(now - time), e.getValue().getFormatted());
@@ -25,7 +25,7 @@
package me.lucko.luckperms.common.commands.impl.log;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.actionlog.Log;
import me.lucko.luckperms.common.commands.CommandException;
import me.lucko.luckperms.common.commands.CommandResult;
@@ -84,11 +84,11 @@ public class LogTrackHistory extends SubCommand<Log> {
return CommandResult.INVALID_ARGS;
}
SortedMap<Integer, LogEntry> entries = log.getTrackHistory(page, track);
SortedMap<Integer, ExtendedLogEntry> entries = log.getTrackHistory(page, track);
String name = entries.values().stream().findAny().get().getActedName();
Message.LOG_HISTORY_TRACK_HEADER.send(sender, name, page, maxPage);
for (Map.Entry<Integer, LogEntry> e : entries.entrySet()) {
for (Map.Entry<Integer, ExtendedLogEntry> e : entries.entrySet()) {
long time = e.getValue().getTimestamp();
long now = DateUtil.unixSecondsNow();
Message.LOG_ENTRY.send(sender, e.getKey(), DateUtil.formatTimeShort(now - time), e.getValue().getFormatted());
@@ -25,7 +25,7 @@
package me.lucko.luckperms.common.commands.impl.log;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.actionlog.Log;
import me.lucko.luckperms.common.commands.CommandException;
import me.lucko.luckperms.common.commands.CommandResult;
@@ -114,11 +114,11 @@ public class LogUserHistory extends SubCommand<Log> {
return CommandResult.INVALID_ARGS;
}
SortedMap<Integer, LogEntry> entries = log.getUserHistory(page, user);
SortedMap<Integer, ExtendedLogEntry> entries = log.getUserHistory(page, user);
String name = entries.values().stream().findAny().get().getActedName();
Message.LOG_HISTORY_USER_HEADER.send(sender, name, page, maxPage);
for (Map.Entry<Integer, LogEntry> e : entries.entrySet()) {
for (Map.Entry<Integer, ExtendedLogEntry> e : entries.entrySet()) {
long time = e.getValue().getTimestamp();
long now = DateUtil.unixSecondsNow();
Message.LOG_ENTRY.send(sender, e.getKey(), DateUtil.formatTimeShort(now - time), e.getValue().getFormatted());
@@ -71,7 +71,7 @@ public class CreateTrack extends SingleCommand {
Message.CREATE_SUCCESS.send(sender, trackName);
ExtendedLogEntry.build().actor(sender).actedName(trackName).entryType(LogEntry.Type.TRACK)
ExtendedLogEntry.build().actor(sender).actedName(trackName).type(LogEntry.Type.TRACK)
.action("create").build()
.submit(plugin, sender);
@@ -73,7 +73,7 @@ public class DeleteTrack extends SingleCommand {
Message.DELETE_SUCCESS.send(sender, trackName);
ExtendedLogEntry.build().actor(sender).actedName(trackName).entryType(LogEntry.Type.TRACK)
ExtendedLogEntry.build().actor(sender).actedName(trackName).type(LogEntry.Type.TRACK)
.action("delete")
.build().submit(plugin, sender);
@@ -33,7 +33,7 @@ import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache;
import me.lucko.luckperms.common.api.delegates.LPConfigurationDelegate;
import me.lucko.luckperms.common.api.delegates.misc.ApiConfiguration;
import me.lucko.luckperms.common.config.keys.EnduringKey;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
@@ -58,7 +58,7 @@ public class AbstractConfiguration implements LuckPermsConfiguration, CacheLoade
// the adapter used to read values
private final ConfigurationAdapter adapter;
// the api delegate
private final LPConfigurationDelegate delegate = new LPConfigurationDelegate(this);
private final ApiConfiguration delegate = new ApiConfiguration(this);
// the contextsfile handler
private final ContextsFile contextsFile = new ContextsFile(this);
@@ -25,7 +25,7 @@
package me.lucko.luckperms.common.config;
import me.lucko.luckperms.common.api.delegates.LPConfigurationDelegate;
import me.lucko.luckperms.common.api.delegates.misc.ApiConfiguration;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
/**
@@ -38,7 +38,7 @@ public interface LuckPermsConfiguration {
*
* @return the api delegate
*/
LPConfigurationDelegate getDelegate();
ApiConfiguration getDelegate();
/**
* Gets the main plugin instance.
@@ -35,6 +35,7 @@ import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.api.context.StaticContextCalculator;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
@@ -54,8 +55,10 @@ import java.util.stream.Collectors;
public abstract class AbstractContextManager<T> implements ContextManager<T> {
protected final LuckPermsPlugin plugin;
private final Class<T> subjectClass;
private final List<ContextCalculator<T>> calculators = new CopyOnWriteArrayList<>();
private final List<ContextCalculator<?>> staticCalculators = new CopyOnWriteArrayList<>();
private final List<StaticContextCalculator> staticCalculators = new CopyOnWriteArrayList<>();
// caches context lookups
private final LoadingCache<T, Contexts> lookupCache = Caffeine.newBuilder()
@@ -63,8 +66,14 @@ public abstract class AbstractContextManager<T> implements ContextManager<T> {
.expireAfterWrite(50L, TimeUnit.MILLISECONDS) // expire roughly every tick
.build(new Loader());
protected AbstractContextManager(LuckPermsPlugin plugin) {
protected AbstractContextManager(LuckPermsPlugin plugin, Class<T> subjectClass) {
this.plugin = plugin;
this.subjectClass = subjectClass;
}
@Override
public Class<T> getSubjectClass() {
return subjectClass;
}
@Override
@@ -124,13 +133,17 @@ public abstract class AbstractContextManager<T> implements ContextManager<T> {
}
@Override
public void registerCalculator(ContextCalculator<T> calculator, boolean isStatic) {
public void registerCalculator(ContextCalculator<T> calculator) {
// calculators registered first should have priority (and be checked last.)
calculators.add(0, calculator);
}
if (isStatic) {
staticCalculators.add(0, calculator);
}
@Override
public void registerStaticCalculator(StaticContextCalculator calculator) {
//noinspection unchecked
registerCalculator((ContextCalculator<T>) calculator);
staticCalculators.add(0, calculator);
}
@Override
@@ -25,11 +25,10 @@
package me.lucko.luckperms.common.contexts;
import lombok.NonNull;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.StaticContextCalculator;
import java.util.Optional;
@@ -42,12 +41,11 @@ import java.util.Optional;
public interface ContextManager<T> {
/**
* Queries the ContextManager for current context values for the subject.
* Gets the class of the subject handled by this instance
*
* @param subject the subject
* @return the applicable context for the subject
* @return the subject class
*/
ImmutableContextSet getApplicableContext(@NonNull T subject);
Class<T> getSubjectClass();
/**
* Queries the ContextManager for current context values for the subject.
@@ -55,7 +53,15 @@ public interface ContextManager<T> {
* @param subject the subject
* @return the applicable context for the subject
*/
Contexts getApplicableContexts(@NonNull T subject);
ImmutableContextSet getApplicableContext(T subject);
/**
* Queries the ContextManager for current context values for the subject.
*
* @param subject the subject
* @return the applicable context for the subject
*/
Contexts getApplicableContexts(T subject);
/**
* Gets the contexts from the static calculators in this manager.
@@ -102,24 +108,21 @@ public interface ContextManager<T> {
*
* @param calculator the calculator
*/
default void registerCalculator(ContextCalculator<T> calculator) {
registerCalculator(calculator, false);
}
void registerCalculator(ContextCalculator<T> calculator);
/**
* Registers a context calculator with the manager.
* Registers a static context calculator with the manager.
*
* @param calculator the calculator
* @param isStatic if the calculator is static. (if it allows a null subject parameter)
*/
void registerCalculator(ContextCalculator<T> calculator, boolean isStatic);
void registerStaticCalculator(StaticContextCalculator calculator);
/**
* Invalidates the lookup cache for a given subject
*
* @param subject the subject
*/
void invalidateCache(@NonNull T subject);
void invalidateCache(T subject);
/**
* Gets the number of calculators registered with the manager.
@@ -27,17 +27,17 @@ package me.lucko.luckperms.common.contexts;
import lombok.AllArgsConstructor;
import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.api.context.StaticContextCalculator;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.config.LuckPermsConfiguration;
@AllArgsConstructor
public class LuckPermsCalculator<T> implements ContextCalculator<T> {
public class LuckPermsCalculator implements StaticContextCalculator {
private final LuckPermsConfiguration config;
@Override
public MutableContextSet giveApplicableContext(T subject, MutableContextSet accumulator) {
public MutableContextSet giveApplicableContext(MutableContextSet accumulator) {
String server = config.get(ConfigKeys.SERVER);
if (!server.equals("global")) {
accumulator.add("server", server);
@@ -30,7 +30,7 @@ import lombok.experimental.UtilityClass;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import me.lucko.luckperms.api.PlatformType;
import me.lucko.luckperms.api.platform.PlatformType;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.storage.StorageType;
@@ -0,0 +1,42 @@
/*
* This file is part of LuckPerms, licensed under the MIT License.
*
* Copyright (c) lucko (Luck) <luck@lucko.me>
* Copyright (c) contributors
*
* 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.common.logging;
/**
* Represents the logger instance being used by LuckPerms on the platform.
*
* <p>Messages sent using the logger are sent prefixed with the LuckPerms tag, and on some implementations will be colored
* depending on the message type.</p>
*/
public interface Logger {
void info(String s);
void warn(String s);
void severe(String s);
}
@@ -30,8 +30,6 @@ import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.HashSet;
import java.util.Set;
@@ -85,16 +83,4 @@ public class ProgressLogger {
logAllProgress(msg, amount);
}
}
public void handleException(Exception ex) {
handleAndPrintException(ex);
}
public static void handleAndPrintException(Exception ex) {
if (ex instanceof ObjectAlreadyHasException || ex instanceof ObjectLacksException) {
return;
}
ex.printStackTrace();
}
}
@@ -28,7 +28,6 @@ package me.lucko.luckperms.common.logging;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.commands.utils.Util;
import me.lucko.luckperms.common.config.ConfigKeys;
@@ -96,7 +96,7 @@ public abstract class AbstractMessagingService implements ExtendedMessagingServi
} else if (msg.startsWith("log:") && msg.length() > "log:".length()) {
String logData = msg.substring("log:".length());
Map.Entry<UUID, LogEntry> entry = null;
Map.Entry<UUID, ExtendedLogEntry> entry = null;
try {
entry = ExtendedLogEntry.deserialize(gson.fromJson(logData, JsonObject.class));
} catch (Exception e) {
@@ -31,7 +31,7 @@ import lombok.ToString;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.common.api.delegates.GroupDelegate;
import me.lucko.luckperms.common.api.delegates.model.ApiGroup;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.references.GroupReference;
@@ -50,7 +50,7 @@ public class Group extends PermissionHolder implements Identifiable<String> {
private final String name;
@Getter
private final GroupDelegate delegate = new GroupDelegate(this);
private final ApiGroup delegate = new ApiGroup(this);
public Group(String name, LuckPermsPlugin plugin) {
super(name, plugin);
@@ -45,7 +45,7 @@ import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.common.api.delegates.PermissionHolderDelegate;
import me.lucko.luckperms.common.api.delegates.model.ApiPermissionHolder;
import me.lucko.luckperms.common.buffers.Cache;
import me.lucko.luckperms.common.caching.MetaAccumulator;
import me.lucko.luckperms.common.caching.handlers.StateListener;
@@ -262,7 +262,7 @@ public abstract class PermissionHolder {
*
* @return the api delegate
*/
public abstract PermissionHolderDelegate getDelegate();
public abstract ApiPermissionHolder getDelegate();
/**
* Returns an immutable copy of this objects nodes
@@ -33,7 +33,7 @@ import lombok.ToString;
import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.api.DataMutateResult;
import me.lucko.luckperms.common.api.delegates.TrackDelegate;
import me.lucko.luckperms.common.api.delegates.model.ApiTrack;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.references.Identifiable;
@@ -65,7 +65,7 @@ public class Track implements Identifiable<String> {
private List<String> groups = Collections.synchronizedList(new ArrayList<>());
@Getter
private final TrackDelegate delegate = new TrackDelegate(this);
private final ApiTrack delegate = new ApiTrack(this);
@Override
public String getId() {
@@ -30,7 +30,7 @@ import lombok.Getter;
import lombok.ToString;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.common.api.delegates.UserDelegate;
import me.lucko.luckperms.common.api.delegates.model.ApiUser;
import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.caching.UserCache;
import me.lucko.luckperms.common.config.ConfigKeys;
@@ -74,7 +74,7 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
private BufferedRequest<Void> refreshBuffer;
@Getter
private final UserDelegate delegate = new UserDelegate(this);
private final ApiUser delegate = new ApiUser(this);
public User(UUID uuid, LuckPermsPlugin plugin) {
super(uuid.toString(), plugin);
@@ -35,16 +35,11 @@ import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.common.utils.DateUtil;
import me.lucko.luckperms.common.utils.PatternCache;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkState;
@@ -130,8 +125,6 @@ public final class ImmutableNode implements Node {
private final List<String> resolvedShorthand;
private String serializedNode = null;
/**
* Make an immutable node instance
*
@@ -307,119 +300,16 @@ public final class ImmutableNode implements Node {
return suffix;
}
@Override
@Deprecated
public boolean shouldApply(boolean includeGlobal, boolean includeGlobalWorld, String server, String world, ContextSet context, boolean applyRegex) {
return shouldApplyOnServer(server, includeGlobal, applyRegex) && shouldApplyOnWorld(world, includeGlobalWorld, applyRegex) && shouldApplyWithContext(context, false);
}
@Override
@Deprecated
public boolean shouldApplyOnServer(String server, boolean includeGlobal, boolean applyRegex) {
if (server == null || server.equals("") || server.equalsIgnoreCase("global")) {
return !isServerSpecific();
}
return isServerSpecific() ? shouldApply(server, applyRegex, this.server) : includeGlobal;
}
@Override
@Deprecated
public boolean shouldApplyOnWorld(String world, boolean includeGlobal, boolean applyRegex) {
if (world == null || world.equals("") || world.equalsIgnoreCase("null")) {
return !isWorldSpecific();
}
return isWorldSpecific() ? shouldApply(world, applyRegex, this.world) : includeGlobal;
}
@Override
@Deprecated
public boolean shouldApplyWithContext(ContextSet context, boolean worldAndServer) {
if (worldAndServer) {
return getFullContexts().isSatisfiedBy(context, false);
} else {
return getContexts().isSatisfiedBy(context, false);
}
}
@Override
public boolean shouldApplyWithContext(ContextSet context) {
return getFullContexts().isSatisfiedBy(context, false);
}
@Override
@Deprecated
public boolean shouldApplyOnAnyServers(List<String> servers, boolean includeGlobal) {
for (String s : servers) {
if (shouldApplyOnServer(s, includeGlobal, false)) {
return true;
}
}
return false;
}
@Override
@Deprecated
public boolean shouldApplyOnAnyWorlds(List<String> worlds, boolean includeGlobal) {
for (String s : worlds) {
if (shouldApplyOnWorld(s, includeGlobal, false)) {
return true;
}
}
return false;
}
@Override
public List<String> resolveWildcard(List<String> possibleNodes) {
if (!isWildcard() || possibleNodes == null) {
return Collections.emptyList();
}
String match = getPermission().substring(0, getPermission().length() - 2);
return possibleNodes.stream().filter(pn -> pn.startsWith(match)).collect(Collectors.toList());
}
@Override
public List<String> resolveShorthand() {
return resolvedShorthand;
}
@Override
public synchronized String toSerializedNode() {
if (serializedNode == null) {
serializedNode = calculateSerializedNode();
}
return serializedNode;
}
private String calculateSerializedNode() {
StringBuilder builder = new StringBuilder();
if (server != null) {
builder.append(NodeFactory.escapeDelimiters(server, SERVER_WORLD_DELIMITERS));
if (world != null) builder.append("-").append(NodeFactory.escapeDelimiters(world, SERVER_WORLD_DELIMITERS));
builder.append("/");
} else {
if (world != null) builder.append("global-").append(NodeFactory.escapeDelimiters(world, SERVER_WORLD_DELIMITERS)).append("/");
}
if (!contexts.isEmpty()) {
builder.append("(");
for (Map.Entry<String, String> entry : contexts.toSet()) {
builder.append(NodeFactory.escapeDelimiters(entry.getKey(), "=", "(", ")", ",")).append("=").append(NodeFactory.escapeDelimiters(entry.getValue(), "=", "(", ")", ",")).append(",");
}
builder.deleteCharAt(builder.length() - 1);
builder.append(")");
}
builder.append(NodeFactory.escapeDelimiters(permission, "/", "-", "$", "(", ")", "=", ","));
if (expireAt != 0L) builder.append("$").append(expireAt);
return builder.toString();
}
@SuppressWarnings("StringEquality")
@Override
public boolean equals(Object o) {
@@ -527,46 +417,6 @@ public final class ImmutableNode implements Node {
return getPermission();
}
private static boolean shouldApply(String str, boolean applyRegex, String thisStr) {
if (str.equalsIgnoreCase(thisStr)) {
return true;
}
Set<String> expandedStr = ShorthandParser.parseShorthand(str, false);
Set<String> expandedThisStr = ShorthandParser.parseShorthand(thisStr, false);
if (str.toLowerCase().startsWith("r=") && applyRegex) {
Pattern p = PatternCache.compile(str.substring(2));
if (p == null) {
return false;
}
for (String s : expandedThisStr) {
if (p.matcher(s).matches()) return true;
}
return false;
}
if (thisStr.toLowerCase().startsWith("r=") && applyRegex) {
Pattern p = PatternCache.compile(thisStr.substring(2));
if (p == null) return false;
for (String s : expandedStr) {
if (p.matcher(s).matches()) return true;
}
return false;
}
if (expandedStr.size() <= 1 && expandedThisStr.size() <= 1) return false;
for (String t : expandedThisStr) {
for (String s : expandedStr) {
if (t.equalsIgnoreCase(s)) return true;
}
}
return false;
}
private static String internString(String s) {
return s == null ? null : s.intern();
}
@@ -33,7 +33,6 @@ import com.google.common.base.Splitter;
import com.google.common.collect.Maps;
import me.lucko.luckperms.api.ChatMetaType;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.model.Group;
@@ -62,6 +61,8 @@ public class NodeFactory {
private static final Pattern LEGACY_EXPIRY_DELIM = PatternCache.compileDelimitedMatcher("$", "\\");
private static final Splitter LEGACY_EXPIRY_SPLITTER = Splitter.on(LEGACY_EXPIRY_DELIM).limit(2);
private static final String[] DELIMS = new String[]{".", "/", "-", "$"};
// caches the conversion between legacy node strings --> node instances
private static final LoadingCache<String, Node> LEGACY_SERIALIZATION_CACHE = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES)
@@ -154,7 +155,7 @@ public class NodeFactory {
return makeSuffixNode(100, value);
}
return new NodeBuilder("meta." + MetaUtils.escapeCharacters(key) + "." + MetaUtils.escapeCharacters(value));
return new NodeBuilder("meta." + escapeCharacters(key) + "." + escapeCharacters(value));
}
public static Node.Builder makeChatMetaNode(ChatMetaType type, int priority, String s) {
@@ -162,11 +163,11 @@ public class NodeFactory {
}
public static Node.Builder makePrefixNode(int priority, String prefix) {
return new NodeBuilder("prefix." + priority + "." + MetaUtils.escapeCharacters(prefix));
return new NodeBuilder("prefix." + priority + "." + escapeCharacters(prefix));
}
public static Node.Builder makeSuffixNode(int priority, String suffix) {
return new NodeBuilder("suffix." + priority + "." + MetaUtils.escapeCharacters(suffix));
return new NodeBuilder("suffix." + priority + "." + escapeCharacters(suffix));
}
public static String nodeAsCommand(Node node, String id, boolean group, boolean set) {
@@ -262,6 +263,41 @@ public class NodeFactory {
return sb;
}
/**
* Escapes special characters used within LuckPerms, so the string can be saved without issues
*
* @param s the string to escape
* @return an escaped string
* @throws NullPointerException if the string is null
*/
public static String escapeCharacters(String s) {
if (s == null) {
throw new NullPointerException();
}
return escapeDelimiters(s, DELIMS);
}
/**
* Unescapes special characters used within LuckPerms, the inverse of {@link #escapeCharacters(String)}
*
* @param s the string to unescape
* @return an unescaped string
* @throws NullPointerException if the string is null
*/
public static String unescapeCharacters(String s) {
if (s == null) {
throw new NullPointerException();
}
s = s.replace("{SEP}", ".");
s = s.replace("{FSEP}", "/");
s = s.replace("{DSEP}", "$");
s = unescapeDelimiters(s, DELIMS);
return s;
}
public static String escapeDelimiters(String s, String... delims) {
if (s == null) {
return null;
@@ -305,7 +341,7 @@ public class NodeFactory {
if (!metaParts.hasNext()) return null;
String value = metaParts.next();
return Maps.immutableEntry(MetaUtils.unescapeCharacters(key).intern(), MetaUtils.unescapeCharacters(value).intern());
return Maps.immutableEntry(unescapeCharacters(key).intern(), unescapeCharacters(value).intern());
}
private static Map.Entry<Integer, String> parseChatMetaNode(String type, String s) {
@@ -323,7 +359,7 @@ public class NodeFactory {
try {
int p = Integer.parseInt(priority);
String v = MetaUtils.unescapeCharacters(value).intern();
String v = unescapeCharacters(value).intern();
return Maps.immutableEntry(p, v);
} catch (NumberFormatException e) {
return null;
@@ -29,8 +29,6 @@ import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import com.google.common.collect.Multimap;
import me.lucko.luckperms.api.HeldPermission;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ContextSet;
@@ -74,11 +72,6 @@ public final class NodeHeldPermission<T> implements HeldPermission<T> {
return node.isTemporary() ? OptionalLong.of(node.getExpiryUnixTime()) : OptionalLong.empty();
}
@Override
public Multimap<String, String> getContext() {
return node.getContexts().toMultimap();
}
@Override
public ContextSet getContexts() {
return node.getContexts();
@@ -26,8 +26,7 @@
package me.lucko.luckperms.common.plugin;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.api.PlatformType;
import me.lucko.luckperms.api.platform.PlatformType;
import me.lucko.luckperms.common.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.ApiProvider;
import me.lucko.luckperms.common.buffers.BufferedRequest;
@@ -41,6 +40,7 @@ import me.lucko.luckperms.common.config.LuckPermsConfiguration;
import me.lucko.luckperms.common.contexts.ContextManager;
import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.logging.Logger;
import me.lucko.luckperms.common.managers.GroupManager;
import me.lucko.luckperms.common.managers.TrackManager;
import me.lucko.luckperms.common.managers.UserManager;
@@ -35,7 +35,7 @@ import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.cause.CreationCause;
import me.lucko.luckperms.api.event.cause.DeletionCause;
import me.lucko.luckperms.common.actionlog.Log;
import me.lucko.luckperms.common.api.delegates.StorageDelegate;
import me.lucko.luckperms.common.api.delegates.model.ApiStorage;
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.Track;
@@ -69,12 +69,12 @@ public class AbstractStorage implements Storage {
private final AbstractDao dao;
@Getter
private final StorageDelegate delegate;
private final ApiStorage delegate;
private AbstractStorage(LuckPermsPlugin plugin, AbstractDao dao) {
this.plugin = plugin;
this.dao = dao;
this.delegate = new StorageDelegate(plugin, this);
this.delegate = new ApiStorage(plugin, this);
}
private <T> CompletableFuture<T> makeFuture(Supplier<T> supplier) {
@@ -30,7 +30,7 @@ import lombok.Getter;
@Getter
@AllArgsConstructor
public class DatastoreConfiguration implements me.lucko.luckperms.api.data.DatastoreConfiguration {
public class DatastoreConfiguration {
private final String address;
private final String database;
@@ -30,7 +30,7 @@ import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.cause.CreationCause;
import me.lucko.luckperms.api.event.cause.DeletionCause;
import me.lucko.luckperms.common.actionlog.Log;
import me.lucko.luckperms.common.api.delegates.StorageDelegate;
import me.lucko.luckperms.common.api.delegates.model.ApiStorage;
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.Track;
@@ -47,7 +47,7 @@ import java.util.concurrent.CompletableFuture;
*/
public interface Storage {
StorageDelegate getDelegate();
ApiStorage getDelegate();
String getName();
@@ -290,7 +290,7 @@ public abstract class ConfigurateDao extends AbstractDao {
actionLogger.info(String.format(LOG_FORMAT,
(entry.getActor().equals(Constants.CONSOLE_UUID) ? "" : entry.getActor() + " "),
entry.getActorName(),
Character.toString(entry.getEntryType().getCode()),
Character.toString(entry.getType().getCode()),
(entry.getActed() == null ? "" : entry.getActed().toString() + " "),
entry.getActedName(),
entry.getAction())
@@ -39,6 +39,7 @@ import com.mongodb.client.model.InsertOneOptions;
import me.lucko.luckperms.api.HeldPermission;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.actionlog.Log;
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
import me.lucko.luckperms.common.managers.GenericUserManager;
@@ -165,7 +166,7 @@ public class MongoDao extends AbstractDao {
.append("timestamp", entry.getTimestamp())
.append("actor", entry.getActor())
.append("actorName", entry.getActorName())
.append("type", Character.toString(entry.getEntryType().getCode()))
.append("type", Character.toString(entry.getType().getCode()))
.append("actedName", entry.getActedName())
.append("action", entry.getAction());
@@ -195,15 +196,16 @@ public class MongoDao extends AbstractDao {
actedUuid = d.get("acted", UUID.class);
}
LogEntry e = new LogEntry(
d.getLong("timestamp"),
d.get("actor", UUID.class),
d.getString("actorName"),
d.getString("type").toCharArray()[0],
actedUuid,
d.getString("actedName"),
d.getString("action")
);
ExtendedLogEntry e = ExtendedLogEntry.build()
.timestamp(d.getLong("timestamp"))
.actor(d.get("actor", UUID.class))
.actorName(d.getString("actorName"))
.type(LogEntry.Type.valueOf(d.getString("type").toCharArray()[0]))
.acted(actedUuid)
.actedName(d.getString("actedName"))
.action(d.getString("action"))
.build();
log.add(e);
}
}
@@ -750,8 +752,39 @@ public class MongoDao extends AbstractDao {
Map<String, Boolean> m = new HashMap<>();
for (Node node : nodes) {
//noinspection deprecation
m.put(node.toSerializedNode(), node.getValuePrimitive());
m.put(toSerializedNode(node), node.getValuePrimitive());
}
return m;
}
private static final String[] SERVER_WORLD_DELIMITERS = new String[]{"/", "-"};
private static String toSerializedNode(Node node) {
StringBuilder builder = new StringBuilder();
if (node.getServer().orElse(null) != null) {
builder.append(NodeFactory.escapeDelimiters(node.getServer().orElse(null), SERVER_WORLD_DELIMITERS));
if (node.getWorld().orElse(null) != null) {
builder.append("-").append(NodeFactory.escapeDelimiters(node.getWorld().orElse(null), SERVER_WORLD_DELIMITERS));
}
builder.append("/");
} else {
if (node.getWorld().orElse(null) != null) {
builder.append("global-").append(NodeFactory.escapeDelimiters(node.getWorld().orElse(null), SERVER_WORLD_DELIMITERS)).append("/");
}
}
if (!node.getContexts().isEmpty()) {
builder.append("(");
for (Map.Entry<String, String> entry : node.getContexts().toSet()) {
builder.append(NodeFactory.escapeDelimiters(entry.getKey(), "=", "(", ")", ",")).append("=").append(NodeFactory.escapeDelimiters(entry.getValue(), "=", "(", ")", ",")).append(",");
}
builder.deleteCharAt(builder.length() - 1);
builder.append(")");
}
builder.append(NodeFactory.escapeDelimiters(node.getPermission(), "/", "-", "$", "(", ")", "=", ","));
if (node.isTemporary()) builder.append("$").append(node.getExpiryUnixTime());
return builder.toString();
}
}
@@ -36,6 +36,7 @@ import com.google.gson.reflect.TypeToken;
import me.lucko.luckperms.api.HeldPermission;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.common.actionlog.ExtendedLogEntry;
import me.lucko.luckperms.common.actionlog.Log;
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
import me.lucko.luckperms.common.contexts.ContextSetJsonSerializer;
@@ -232,7 +233,7 @@ public class SqlDao extends AbstractDao {
ps.setLong(1, entry.getTimestamp());
ps.setString(2, entry.getActor().toString());
ps.setString(3, entry.getActorName());
ps.setString(4, Character.toString(entry.getEntryType().getCode()));
ps.setString(4, Character.toString(entry.getType().getCode()));
ps.setString(5, String.valueOf(entry.getActed()));
ps.setString(6, entry.getActedName());
ps.setString(7, entry.getAction());
@@ -253,15 +254,16 @@ public class SqlDao extends AbstractDao {
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
final String actedUuid = rs.getString("acted_uuid");
LogEntry e = new LogEntry(
rs.getLong("time"),
UUID.fromString(rs.getString("actor_uuid")),
rs.getString("actor_name"),
rs.getString("type").toCharArray()[0],
actedUuid.equals("null") ? null : UUID.fromString(actedUuid),
rs.getString("acted_name"),
rs.getString("action")
);
ExtendedLogEntry e = ExtendedLogEntry.build()
.timestamp(rs.getLong("time"))
.actor(UUID.fromString(rs.getString("actor_uuid")))
.actorName(rs.getString("actor_name"))
.type(LogEntry.Type.valueOf(rs.getString("type").toCharArray()[0]))
.acted(actedUuid.equals("null") ? null : UUID.fromString(actedUuid))
.actedName(rs.getString("acted_name"))
.action(rs.getString("action"))
.build();
log.add(e);
}
}
@@ -34,7 +34,7 @@ import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.cause.CreationCause;
import me.lucko.luckperms.api.event.cause.DeletionCause;
import me.lucko.luckperms.common.actionlog.Log;
import me.lucko.luckperms.common.api.delegates.StorageDelegate;
import me.lucko.luckperms.common.api.delegates.model.ApiStorage;
import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.Track;
@@ -292,7 +292,7 @@ public class PhasedStorage implements Storage {
}
private interface Delegated {
StorageDelegate getDelegate();
ApiStorage getDelegate();
String getName();
boolean isAcceptingLogins();
void setAcceptingLogins(boolean b);
@@ -32,7 +32,7 @@ import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.Maps;
import me.lucko.luckperms.common.api.delegates.UuidCacheDelegate;
import me.lucko.luckperms.common.api.delegates.misc.ApiUuidCache;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
@@ -49,7 +49,7 @@ public class UuidCache {
private final BiMap<UUID, UUID> cache = Maps.synchronizedBiMap(HashBiMap.create());
@Getter
private final UuidCacheDelegate delegate = new UuidCacheDelegate(this);
private final ApiUuidCache delegate = new ApiUuidCache(this);
public UUID getUUID(UUID external) {
return inUse() ? external : cache.getOrDefault(external, external);