API 4.0 - this is a breaking change

This commit is contained in:
Luck 2017-11-07 22:05:44 +00:00
parent a2801bff7c
commit 175a21c0e4
No known key found for this signature in database
GPG Key ID: EFA9B3EC5FD90F8B
98 changed files with 2274 additions and 3747 deletions

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>luckperms</artifactId> <artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId> <groupId>me.lucko.luckperms</groupId>
<version>3.4-SNAPSHOT</version> <version>4.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -25,11 +25,6 @@
package me.lucko.luckperms.api; package me.lucko.luckperms.api;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.function.Supplier;
/** /**
* Represents the result of a mutation call. * Represents the result of a mutation call.
*/ */
@ -38,35 +33,27 @@ public enum DataMutateResult {
/** /**
* Indicates the mutation was a success * Indicates the mutation was a success
*/ */
SUCCESS(true, null), SUCCESS(true),
/** /**
* Indicates the mutation failed because the subject already has something * Indicates the mutation failed because the subject already has something
*/ */
ALREADY_HAS(false, ObjectAlreadyHasException::new), ALREADY_HAS(false),
/** /**
* Indicates the mutation failed because the subject lacks something * Indicates the mutation failed because the subject lacks something
*/ */
LACKS(false, ObjectLacksException::new), LACKS(false),
/** /**
* Indicates the mutation failed * Indicates the mutation failed
*/ */
FAIL(false, RuntimeException::new); FAIL(false);
private final boolean value; private final boolean value;
private final Supplier<? extends Exception> exceptionSupplier;
DataMutateResult(boolean value, Supplier<? extends Exception> exceptionSupplier) { DataMutateResult(boolean value) {
this.value = value; this.value = value;
this.exceptionSupplier = exceptionSupplier;
}
public void throwException() {
if (exceptionSupplier != null) {
sneakyThrow(exceptionSupplier.get());
}
} }
/** /**
@ -98,15 +85,4 @@ public enum DataMutateResult {
return !value; return !value;
} }
// allows us to throw checked exceptions without declaring it, as #throwException throws a number of
// exception types.
private static void sneakyThrow(Throwable t) {
sneakyThrow0(t);
}
@SuppressWarnings("unchecked")
private static <T extends Throwable> void sneakyThrow0(Throwable t) throws T {
throw (T) t;
}
} }

View File

@ -26,10 +26,7 @@
package me.lucko.luckperms.api; package me.lucko.luckperms.api;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List;
import java.util.OptionalInt; import java.util.OptionalInt;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -78,242 +75,4 @@ public interface Group extends PermissionHolder {
@Nonnull @Nonnull
OptionalInt getWeight(); OptionalInt getWeight();
/**
* Check to see if the group inherits a group on a specific server
*
* @param group The group to check membership of
* @param server The server to check on
* @return true if the group inherits the group on the server
* @throws NullPointerException if the group or server is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the server is invalid
* @deprecated in favour of {@link #inheritsGroup(Group, ContextSet)}
*/
@Deprecated
boolean inheritsGroup(@Nonnull Group group, @Nonnull String server);
/**
* Check to see if the group inherits a group on a specific server and world
*
* @param group The group to check membership of
* @param server The server to check on
* @param world The world to check on
* @return true if the group inherits the group on the server and world
* @throws NullPointerException if the group, server or world is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the server or world is invalid
* @deprecated in favour of {@link #inheritsGroup(Group, ContextSet)}
*/
@Deprecated
boolean inheritsGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world);
/**
* Make this group inherit another group
*
* @param group the group to be inherited
* @throws ObjectAlreadyHasException if the group already inherits the group
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void setInheritGroup(@Nonnull Group group) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server
*
* @param group the group to be inherited
* @param server The server to inherit the group on
* @throws ObjectAlreadyHasException if the group already inherits the group on that server
* @throws NullPointerException if the group or server is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the server is invalid
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void setInheritGroup(@Nonnull Group group, @Nonnull String server) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server and world
*
* @param group the group to be inherited
* @param server The server to inherit the group on
* @param world The world to inherit the group on
* @throws ObjectAlreadyHasException if the group already inherits the group on that server and world
* @throws NullPointerException if the group, server or world is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the server or world is invalid
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void setInheritGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group temporarily
*
* @param group the group to be inherited
* @param expireAt the unix time when the group should expire
* @throws ObjectAlreadyHasException if the group already inherits the group temporarily
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the expiry time is in the past
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void setInheritGroup(@Nonnull Group group, long expireAt) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server temporarily
*
* @param group the group to be inherited
* @param server The server inherit add the group on
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the group already inherits the group on that server temporarily
* @throws NullPointerException if the group or server is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the expiry time is in the past or the server is invalid
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void setInheritGroup(@Nonnull Group group, @Nonnull String server, long expireAt) throws ObjectAlreadyHasException;
/**
* Make this group inherit another group on a specific server and world temporarily
*
* @param group the group to be inherited
* @param server The server to inherit the group on
* @param world The world to inherit the group on
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the group already inherits the group on that server and world temporarily
* @throws NullPointerException if the group, server or world is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the expiry time is in the past or the server/world is invalid
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void setInheritGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world, long expireAt) throws ObjectAlreadyHasException;
/**
* Remove a previously set inheritance rule
*
* @param group the group to uninherit
* @throws ObjectLacksException if the group does not already inherit the group
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void unsetInheritGroup(@Nonnull Group group) throws ObjectLacksException;
/**
* Remove a previously set inheritance rule
*
* @param group the group to uninherit
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the group does not already inherit the group
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void unsetInheritGroup(@Nonnull Group group, boolean temporary) throws ObjectLacksException;
/**
* Remove a previously set inheritance rule on a specific server
*
* @param group the group to uninherit
* @param server The server to remove the group on
* @throws ObjectLacksException if the group does not already inherit the group on that server
* @throws NullPointerException if the group or server is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the server is invalid
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void unsetInheritGroup(@Nonnull Group group, @Nonnull String server) throws ObjectLacksException;
/**
* Remove a previously set inheritance rule on a specific server and world
*
* @param group the group to uninherit
* @param server The server to remove the group on
* @param world The world to remove the group on
* @throws ObjectLacksException if the group does not already inherit the group
* @throws NullPointerException if the group, server or world is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the server or world is invalid
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void unsetInheritGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world) throws ObjectLacksException;
/**
* Remove a previously set inheritance rule on a specific server
*
* @param group the group to uninherit
* @param server The server to remove the group on
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the group does not already inherit the group
* @throws NullPointerException if the group or server is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the expiry time is in the past or the server is invalid
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void unsetInheritGroup(@Nonnull Group group, @Nonnull String server, boolean temporary) throws ObjectLacksException;
/**
* Remove a previously set inheritance rule on a specific server and world
*
* @param group the group to uninherit
* @param server The server to remove the group on
* @param world The world to remove the group on
* @param temporary if the group being removed was set temporarily
* @throws ObjectLacksException if the group does not already inherit the group
* @throws NullPointerException if the group, server or world is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the expiry time is in the past or the server/world is invalid
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void unsetInheritGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world, boolean temporary) throws ObjectLacksException;
/**
* Get a {@link List} of all of the groups the group inherits, on all servers
*
* @return a {@link List} of group names
* @deprecated in favour of just querying a users permissions
*/
@Deprecated
@Nonnull
List<String> getGroupNames();
/**
* Get a {@link List} of the groups the group inherits on a specific server
*
* @param server the server to check
* @return a {@link List} of group names
* @throws NullPointerException if the server is null
* @throws IllegalArgumentException if the server is invalid
* @deprecated in favour of just querying a users permissions
*/
@Deprecated
@Nonnull
List<String> getLocalGroups(@Nonnull String server);
/**
* Get a {@link List} of the groups the group inherits on a specific server and world
*
* @param server the server to check
* @param world the world to check
* @return a {@link List} of group names
* @throws NullPointerException if the server or world is null
* @throws IllegalArgumentException if the server or world is invalid
* @deprecated in favour of just querying a users permissions
*/
@Deprecated
@Nonnull
List<String> getLocalGroups(@Nonnull String server, @Nonnull String world);
} }

View File

@ -25,8 +25,6 @@
package me.lucko.luckperms.api; package me.lucko.luckperms.api;
import com.google.common.collect.Multimap;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ContextSet;
import java.util.Optional; import java.util.Optional;
@ -88,16 +86,6 @@ public interface HeldPermission<T> {
*/ */
OptionalLong getExpiry(); OptionalLong getExpiry();
/**
* Gets the context for the permission.
*
* @return the context
* @deprecated in favour of {@link #getContexts()}.
*/
@Nonnull
@Deprecated
Multimap<String, String> getContext();
/** /**
* Gets the extra context for the permission. * Gets the extra context for the permission.
* *

View File

@ -25,8 +25,6 @@
package me.lucko.luckperms.api; package me.lucko.luckperms.api;
import me.lucko.luckperms.api.data.DatastoreConfiguration;
import java.util.Map; import java.util.Map;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -44,13 +42,6 @@ public interface LPConfiguration {
@Nonnull @Nonnull
String getServer(); String getServer();
/**
* Gets how often a sync task will run in minutes
*
* @return how often a sync task will run in minutes
*/
int getSyncTime();
/** /**
* Gets if the users on this server will have their global permissions applied * Gets if the users on this server will have their global permissions applied
* *
@ -82,91 +73,6 @@ public interface LPConfiguration {
*/ */
boolean getApplyGlobalWorldGroups(); boolean getApplyGlobalWorldGroups();
/**
* Gets the online mode setting
*
* @return the online mode setting
*/
boolean getOnlineMode();
/**
* Gets if LuckPerms is applying wildcard permissions
*
* @return if LuckPerms is applying wildcard permissions
*/
boolean getApplyWildcards();
/**
* Returns if LuckPerms is resolving and applying regex permissions
*
* @return if LuckPerms is resolving and applying regex permissions
*/
boolean getApplyRegex();
/**
* Gets if LuckPerms is expanding shorthand permissions
*
* @return if LuckPerms is expanding shorthand permissions
*/
boolean getApplyShorthand();
/**
* Gets if LuckPerms will send notifications to users when permissions are modified
*
* @return if LuckPerms will send notifications to users when permissions are modified
* @since 2.7
*/
boolean getLogNotify();
/**
* Gets if the vanilla op system is enabled
*
* @return true if the vanilla op system is enabled
* @since 2.8
*/
boolean getEnableOps();
/**
* Gets if opped players are allowed to use LuckPerms commands
*
* @return true if opped players are allowed to use LuckPerms commands
* @since 2.8
*/
boolean getCommandsAllowOp();
/**
* Gets if auto op is enabled
*
* @return true if auto op is enabled
* @since 2.9
*/
boolean getAutoOp();
/**
* Gets the name of the server used within Vault operations
*
* @return the name of the server used within Vault operations
* @since 2.7
*/
@Nonnull
String getVaultServer();
/**
* Gets if global permissions should be considered when retrieving meta or player groups
*
* @return true if global permissions should be considered when retrieving meta or player groups
* @since 2.7
*/
boolean getVaultIncludeGlobal();
/**
* Gets the values set for data storage in the configuration
*
* @return the values set for data storage in the configuration
*/
@Nonnull
DatastoreConfiguration getDatastoreConfig();
/** /**
* Gets the storage method string from the configuration * Gets the storage method string from the configuration
* *

View File

@ -25,352 +25,79 @@
package me.lucko.luckperms.api; package me.lucko.luckperms.api;
import com.google.common.base.Preconditions; import java.util.Optional;
import java.util.Comparator;
import java.util.UUID; import java.util.UUID;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
/** /**
* A single entry in the log. * Represents a logged action.
*/ */
public class LogEntry implements Comparable<LogEntry> { public interface LogEntry extends Comparable<LogEntry> {
/** /**
* Compares two LogEntries * Gets the time in unix seconds when the action occurred.
*
* @return the timestamp
*/
long getTimestamp();
/**
* Gets the id of the object which performed the action.
*
* <p>This is the players uuid in most cases.</p>
*
* @return the actor id
*/
UUID getActor();
/**
* Gets the name describing the actor.
*
* @return the name of the actor
*/
String getActorName();
/**
* Gets the type of action.
*
* @return the action type
*/
Type getType();
/**
* Gets the uuid of the object which was acted upon.
*
* <p>Will only return a value for {@link Type#USER} entries.</p>
*
* @return the uuid of acted object
*/
Optional<UUID> getActed();
/**
* Gets the name describing the object which was acted upon
*
* @return the name of the acted object
*/
String getActedName();
/**
* Returns a string describing the action which took place.
*
* <p>In most instances, this returns a variation of the command string which caused
* the change.</p>
*
* @return the action
*/
String getAction();
/**
* Represents the type of a {@link LogEntry}.
* *
* @since 3.3 * @since 3.3
*/ */
public static final Comparator<LogEntry> COMPARATOR = Comparator enum Type {
.comparingLong(LogEntry::getTimestamp)
.thenComparing(LogEntry::getActor)
.thenComparing(LogEntry::getActorName, String.CASE_INSENSITIVE_ORDER)
.thenComparing(LogEntry::getEntryType)
.thenComparing(e -> {
UUID u = e.getActed();
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();
private static final String FORMAT = "&8(&e%s&8) [&a%s&8] (&b%s&8) &7--> &f%s";
/**
* Creates a new LogEntry builder
*
* @return a new builder
*/
@Nonnull
public static LogEntryBuilder builder() {
return new LogEntryBuilder();
}
/**
* The time when the log event occurred in unix seconds.
*/
private long timestamp;
/**
* The player who enacted the change
*/
@Nonnull
private UUID actor;
/**
* The name of the player who enacted the change
*/
@Nonnull
private String actorName;
/**
* The entry type.
*/
@Nonnull
private Type type;
/**
* The user who was acted upon
*/
@Nullable
private UUID acted;
/**
* The name of the object who was acted upon
*/
@Nonnull
private String actedName;
/**
* A description of the action
*/
@Nonnull
private String action;
/**
* Creates a new log entry
*
* @param timestamp the timestamp
* @param actor the actor
* @param actorName the actorName
* @param type the type
* @param acted the acted object, or null
* @param actedName the acted object name
* @param action the action
* @since 3.3
*/
public LogEntry(long timestamp, @Nonnull UUID actor, @Nonnull String actorName, @Nonnull Type type, @Nullable UUID acted, @Nonnull String actedName, @Nonnull String action) {
Preconditions.checkNotNull(actor, "actor");
Preconditions.checkNotNull(actorName, "actorName");
Preconditions.checkNotNull(type, "type");
Preconditions.checkNotNull(actedName, "actedName");
Preconditions.checkNotNull(action, "action");
this.timestamp = timestamp;
this.actor = actor;
this.actorName = actorName;
this.type = type;
this.acted = acted;
this.actedName = actedName;
this.action = action;
}
/**
* Creates a new log entry
*
* @param timestamp the timestamp
* @param actor the actor
* @param actorName the actorName
* @param type the type code
* @param acted the acted object, or null
* @param actedName the acted object name
* @param action the action
*/
public LogEntry(long timestamp, @Nonnull UUID actor, @Nonnull String actorName, char type, @Nullable UUID acted, @Nonnull String actedName, @Nonnull String action) {
Preconditions.checkNotNull(actor, "actor");
Preconditions.checkNotNull(actorName, "actorName");
Preconditions.checkNotNull(actedName, "actedName");
Preconditions.checkNotNull(action, "action");
this.timestamp = timestamp;
this.actor = actor;
this.actorName = actorName;
this.type = Type.valueOf(type);
this.acted = acted;
this.actedName = actedName;
this.action = action;
}
/**
* Creates a new LogEntry and copies the values from another
*
* @param other the entry to copy values from
* @since 3.3
*/
protected LogEntry(@Nonnull LogEntry other) {
this.timestamp = other.timestamp;
this.actor = other.actor;
this.actorName = other.actorName;
this.type = other.type;
this.acted = other.acted;
this.actedName = other.actedName;
this.action = other.action;
}
protected LogEntry() {
this.timestamp = 0L;
this.actor = null;
this.actorName = null;
this.type = null;
this.acted = null;
this.actedName = null;
this.action = null;
}
@Override
public int compareTo(@Nonnull LogEntry other) {
Preconditions.checkNotNull(other, "other");
return COMPARATOR.compare(this, other);
}
/**
* Creates a copy of this log entry
*
* @return a copy of this log entry
* @since 3.3
*/
public LogEntry copy() {
return new LogEntry(this);
}
public long getTimestamp() {
return timestamp;
}
void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
@Nonnull
public UUID getActor() {
return Preconditions.checkNotNull(actor, "actor");
}
void setActor(@Nonnull UUID actor) {
this.actor = Preconditions.checkNotNull(actor, "actor");
}
@Nonnull
public String getActorName() {
return Preconditions.checkNotNull(actorName, "actorName");
}
void setActorName(@Nonnull String actorName) {
this.actorName = Preconditions.checkNotNull(actorName, "actorName");
}
/**
* Gets the type of this entry
*
* @return the type of this entry
* @since 3.3
*/
@Nonnull
public Type getEntryType() {
return Preconditions.checkNotNull(type, "type");
}
/**
* Sets the type of this entry
*
* @param type the new type
* @since 3.3
*/
public void setEntryType(@Nonnull Type type) {
this.type = Preconditions.checkNotNull(type, "type");
}
/**
* Gets the code representing this entry type
*
* @return the code representing this entry type
* @deprecated in favour of {@link #getEntryType()}
*/
@Deprecated
public char getType() {
return getEntryType().getCode();
}
/**
* Sets the type of this entry by code
*
* @param code the code type
* @deprecated in favour of {@link #setEntryType(Type)}
*/
@Deprecated
void setType(char code) {
setEntryType(Type.valueOf(code));
}
@Nullable
public UUID getActed() {
return acted;
}
void setActed(@Nullable UUID acted) {
this.acted = acted;
}
@Nonnull
public String getActedName() {
return Preconditions.checkNotNull(actedName, "actedName");
}
void setActedName(@Nonnull String actedName) {
this.actedName = Preconditions.checkNotNull(actedName, "actedName");
}
@Nonnull
public String getAction() {
return Preconditions.checkNotNull(action, "action");
}
void setAction(@Nonnull String action) {
this.action = Preconditions.checkNotNull(action, "action");
}
public boolean matchesSearch(@Nonnull String query) {
query = Preconditions.checkNotNull(query, "query").toLowerCase();
return actorName.toLowerCase().contains(query) ||
actedName.toLowerCase().contains(query) ||
action.toLowerCase().contains(query);
}
@Nonnull
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
);
}
@Override
public String toString() {
return "LogEntry(" +
"timestamp=" + this.getTimestamp() + ", " +
"actor=" + this.getActor() + ", " +
"actorName=" + this.getActorName() + ", " +
"type=" + this.getEntryType() + ", " +
"acted=" + this.getActed() + ", " +
"actedName=" + this.getActedName() + ", " +
"action=" + this.getAction() + ")";
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof LogEntry)) return false;
final LogEntry other = (LogEntry) o;
return this.getTimestamp() == other.getTimestamp() &&
this.getActor().equals(other.getActor()) &&
this.getActorName().equals(other.getActorName()) &&
this.getEntryType() == other.getEntryType() &&
(this.getActed() == null ? other.getActed() == null : this.getActed().equals(other.getActed())) &&
this.getActedName().equals(other.getActedName()) &&
this.getAction().equals(other.getAction());
}
@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.getEntryType().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;
}
/**
* The LogEntry type
* @since 3.3
*/
public enum Type {
USER('U'), USER('U'),
GROUP('G'), GROUP('G'),
TRACK('T'); TRACK('T');
@ -403,152 +130,34 @@ public class LogEntry implements Comparable<LogEntry> {
} }
/** /**
* Builds LogEntry instances * Builds a LogEntry instance
*/ */
public static class LogEntryBuilder extends AbstractLogEntryBuilder<LogEntry, LogEntry.LogEntryBuilder> { interface Builder {
@Override
protected LogEntry createEmptyLog() {
return new LogEntry();
}
@Override
protected LogEntryBuilder getThisBuilder() {
return this;
}
}
/**
* An abstract log entry builder
*
* @param <T> the log type
* @param <B> the log builder type
*/
public static abstract class AbstractLogEntryBuilder<T extends LogEntry, B extends AbstractLogEntryBuilder<T, B>> {
private final T obj;
private final B thisObj;
public AbstractLogEntryBuilder() {
obj = createEmptyLog();
thisObj = getThisBuilder();
}
protected abstract T createEmptyLog();
protected abstract B getThisBuilder();
public long getTimestamp() {
return obj.getTimestamp();
}
@Nonnull @Nonnull
public UUID getActor() { Builder setTimestamp(long timestamp);
return obj.getActor();
}
@Nonnull @Nonnull
public String getActorName() { Builder setActor(@Nonnull UUID actor);
return obj.getActorName();
}
@Nonnull @Nonnull
public Type getEntryType() { Builder setActorName(@Nonnull String actorName);
return obj.getEntryType();
}
@Nonnull @Nonnull
@Deprecated Builder setType(@Nonnull Type type);
public char getType() {
return obj.getType();
}
@Nullable
public UUID getActed() {
return obj.getActed();
}
@Nonnull @Nonnull
public String getActedName() { Builder setActed(@Nullable UUID acted);
return obj.getActedName();
}
@Nonnull @Nonnull
public String getAction() { Builder setActedName(@Nonnull String actedName);
return obj.getAction();
}
@Nonnull @Nonnull
public B timestamp(long timestamp) { Builder setAction(@Nonnull String action);
obj.setTimestamp(timestamp);
return thisObj;
}
@Nonnull @Nonnull
public B actor(@Nonnull UUID actor) { LogEntry build();
obj.setActor(actor);
return thisObj;
}
@Nonnull
public B actorName(@Nonnull String actorName) {
obj.setActorName(actorName);
return thisObj;
}
@Nonnull
public B entryType(@Nonnull Type type) {
obj.setEntryType(type);
return thisObj;
}
@Nonnull
@Deprecated
public B type(char type) {
obj.setType(type);
return thisObj;
}
@Nonnull
public B acted(@Nullable UUID acted) {
obj.setActed(acted);
return thisObj;
}
@Nonnull
public B actedName(@Nonnull String actedName) {
obj.setActedName(actedName);
return thisObj;
}
@Nonnull
public B action(@Nonnull String action) {
obj.setAction(action);
return thisObj;
}
@Nonnull
public T build() {
Preconditions.checkNotNull(getActor(), "actor");
Preconditions.checkNotNull(getActorName(), "actorName");
Preconditions.checkNotNull(getEntryType(), "type");
Preconditions.checkNotNull(getActedName(), "actedName");
Preconditions.checkNotNull(getAction(), "action");
return obj;
}
@Override
public String toString() {
return "LogEntry.LogEntryBuilder(" +
"timestamp=" + this.getTimestamp() + ", " +
"actor=" + this.getActor() + ", " +
"actorName=" + this.getActorName() + ", " +
"type=" + this.getEntryType() + ", " +
"acted=" + this.getActed() + ", " +
"actedName=" + this.getActedName() + ", " +
"action=" + this.getAction() + ")";
}
} }
} }

View File

@ -27,13 +27,19 @@ package me.lucko.luckperms.api;
import me.lucko.luckperms.LuckPerms; import me.lucko.luckperms.LuckPerms;
import me.lucko.luckperms.api.context.ContextCalculator; import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.ContextManager;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.event.EventBus; 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.metastacking.MetaStackFactory;
import me.lucko.luckperms.api.platform.PlatformInfo;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -49,35 +55,49 @@ import javax.annotation.Nullable;
*/ */
public interface LuckPermsApi { public interface LuckPermsApi {
/**
* Gets information about the platform LuckPerms is running on.
*
* @return the platform info
* @since 4.0
*/
@Nonnull
PlatformInfo getPlatformInfo();
/**
* Gets the user manager
*
* @return the user manager
* @since 4.0
*/
@Nonnull
UserManager getUserManager();
/**
* Gets the group manager
*
* @return the group manager
* @since 4.0
*/
@Nonnull
GroupManager getGroupManager();
/**
* Gets the track manager
*
* @return the track manager
* @since 4.0
*/
@Nonnull
TrackManager getTrackManager();
/** /**
* Schedules an update task to run * Schedules an update task to run
*/
void runUpdateTask();
/**
* Gets the API version
* *
* @return the version of the API running on the platform * @since 4.0
* @since 2.6
*/
double getApiVersion();
/**
* Gets the plugin version
*
* @return the version of the plugin running on the platform
*/ */
@Nonnull @Nonnull
String getVersion(); CompletableFuture<Void> runUpdateTask();
/**
* Gets the platform LuckPerms is running on
*
* @return the platform LuckPerms is running on
* @since 2.7
*/
@Nonnull
PlatformType getPlatformType();
/** /**
* Gets the event bus, used for subscribing to events * Gets the event bus, used for subscribing to events
@ -89,7 +109,7 @@ public interface LuckPermsApi {
EventBus getEventBus(); EventBus getEventBus();
/** /**
* Gets a wrapped {@link LPConfiguration} instance, with read only access * Gets the configuration
* *
* @return a configuration instance * @return a configuration instance
*/ */
@ -97,7 +117,7 @@ public interface LuckPermsApi {
LPConfiguration getConfiguration(); LPConfiguration getConfiguration();
/** /**
* Gets a wrapped {@link Storage} instance. * Gets the backend storage dao
* *
* @return a storage instance * @return a storage instance
* @since 2.14 * @since 2.14
@ -106,7 +126,7 @@ public interface LuckPermsApi {
Storage getStorage(); Storage getStorage();
/** /**
* Gets the messaging service in use on the platform, if present. * Gets the messaging service
* *
* @return an optional that may contain a messaging service instance. * @return an optional that may contain a messaging service instance.
*/ */
@ -114,21 +134,41 @@ public interface LuckPermsApi {
Optional<MessagingService> getMessagingService(); Optional<MessagingService> getMessagingService();
/** /**
* Gets the {@link Logger} wrapping used by the platform * Gets a {@link UuidCache} instance, providing read access to the LuckPerms
* * internal uuid caching system
* @return the logger instance
*/
@Nonnull
Logger getLogger();
/**
* Gets a wrapped {@link UuidCache} instance, providing read access to the LuckPerms internal uuid caching system
* *
* @return a uuid cache instance * @return a uuid cache instance
*/ */
@Nonnull @Nonnull
UuidCache getUuidCache(); UuidCache getUuidCache();
/**
* Gets the context manager
*
* @return the context manager
* @since 4.0
*/
ContextManager getContextManager();
/**
* Gets the node factory
*
* @return the node factory
*/
@Nonnull
NodeFactory getNodeFactory();
/**
* Gets the MetaStackFactory
*
* @return the meta stack factory
* @since 3.2
*/
@Nonnull
MetaStackFactory getMetaStackFactory();
// convenience methods
/** /**
* Gets a wrapped user object from the user storage * Gets a wrapped user object from the user storage
* *
@ -137,19 +177,21 @@ public interface LuckPermsApi {
* @throws NullPointerException if the uuid is null * @throws NullPointerException if the uuid is null
*/ */
@Nullable @Nullable
User getUser(@Nonnull UUID uuid); default User getUser(@Nonnull UUID uuid) {
return getUserManager().getUser(uuid);
}
/** /**
* Gets a wrapped user object from the user storage. * Gets a wrapped user object from the user storage.
* *
* <p>This method does not return null, unlike {@link #getUser(UUID)}</p>
*
* @param uuid the uuid of the user to get * @param uuid the uuid of the user to get
* @return an optional {@link User} object * @return an optional {@link User} object
* @throws NullPointerException if the uuid is null * @throws NullPointerException if the uuid is null
*/ */
@Nonnull @Nonnull
Optional<User> getUserSafe(@Nonnull UUID uuid); default Optional<User> getUserSafe(@Nonnull UUID uuid) {
return getUserManager().getUserOpt(uuid);
}
/** /**
* Gets a wrapped user object from the user storage * Gets a wrapped user object from the user storage
@ -159,19 +201,21 @@ public interface LuckPermsApi {
* @throws NullPointerException if the name is null * @throws NullPointerException if the name is null
*/ */
@Nullable @Nullable
User getUser(@Nonnull String name); default User getUser(@Nonnull String name) {
return getUserManager().getUser(name);
}
/** /**
* Gets a wrapped user object from the user storage. * Gets a wrapped user object from the user storage.
* *
* <p>This method does not return null, unlike {@link #getUser(String)}</p>
*
* @param name the username of the user to get * @param name the username of the user to get
* @return an optional {@link User} object * @return an optional {@link User} object
* @throws NullPointerException if the name is null * @throws NullPointerException if the name is null
*/ */
@Nonnull @Nonnull
Optional<User> getUserSafe(@Nonnull String name); default Optional<User> getUserSafe(@Nonnull String name) {
return getUserManager().getUserOpt(name);
}
/** /**
* Gets a set of all loaded users. * Gets a set of all loaded users.
@ -179,7 +223,9 @@ public interface LuckPermsApi {
* @return a {@link Set} of {@link User} objects * @return a {@link Set} of {@link User} objects
*/ */
@Nonnull @Nonnull
Set<User> getUsers(); default Set<User> getUsers() {
return getUserManager().getLoadedUsers();
}
/** /**
* Check if a user is loaded in memory * Check if a user is loaded in memory
@ -188,16 +234,19 @@ public interface LuckPermsApi {
* @return true if the user is loaded * @return true if the user is loaded
* @throws NullPointerException if the uuid is null * @throws NullPointerException if the uuid is null
*/ */
boolean isUserLoaded(@Nonnull UUID uuid); default boolean isUserLoaded(@Nonnull UUID uuid) {
return getUserManager().isLoaded(uuid);
}
/** /**
* Unload a user from the internal storage, if they're not currently online. * Unload a user from the internal storage, if they're not currently online.
* *
* @param user the user to unload * @param user the user to unload
* @throws NullPointerException if the user is null * @throws NullPointerException if the user is null
* @since 2.6
*/ */
void cleanupUser(@Nonnull User user); default void cleanupUser(@Nonnull User user) {
getUserManager().cleanupUser(user);
}
/** /**
* Gets a wrapped group object from the group storage * Gets a wrapped group object from the group storage
@ -207,7 +256,9 @@ public interface LuckPermsApi {
* @throws NullPointerException if the name is null * @throws NullPointerException if the name is null
*/ */
@Nullable @Nullable
Group getGroup(@Nonnull String name); default Group getGroup(@Nonnull String name) {
return getGroupManager().getGroup(name);
}
/** /**
* Gets a wrapped group object from the group storage. * Gets a wrapped group object from the group storage.
@ -219,7 +270,9 @@ public interface LuckPermsApi {
* @throws NullPointerException if the name is null * @throws NullPointerException if the name is null
*/ */
@Nonnull @Nonnull
Optional<Group> getGroupSafe(@Nonnull String name); default Optional<Group> getGroupSafe(@Nonnull String name) {
return getGroupManager().getGroupOpt(name);
}
/** /**
* Gets a set of all loaded groups. * Gets a set of all loaded groups.
@ -227,7 +280,9 @@ public interface LuckPermsApi {
* @return a {@link Set} of {@link Group} objects * @return a {@link Set} of {@link Group} objects
*/ */
@Nonnull @Nonnull
Set<Group> getGroups(); default Set<Group> getGroups() {
return getGroupManager().getLoadedGroups();
}
/** /**
* Check if a group is loaded in memory * Check if a group is loaded in memory
@ -236,17 +291,22 @@ public interface LuckPermsApi {
* @return true if the group is loaded * @return true if the group is loaded
* @throws NullPointerException if the name is null * @throws NullPointerException if the name is null
*/ */
boolean isGroupLoaded(@Nonnull String name); default boolean isGroupLoaded(@Nonnull String name) {
return getGroupManager().isLoaded(name);
}
/** /**
* Gets a wrapped track object from the track storage * Gets a wrapped track object from the track storage
* *
* @param name the name of the track to get * @param name the name of the track to get
* @return a {@link Track} object, if one matching the name exists, or null if not * @return a {@link Track} object, if one matching the name exists, or null
* if not
* @throws NullPointerException if the name is null * @throws NullPointerException if the name is null
*/ */
@Nullable @Nullable
Track getTrack(@Nonnull String name); default Track getTrack(@Nonnull String name) {
return getTrackManager().getTrack(name);
}
/** /**
* Gets a wrapped track object from the track storage. * Gets a wrapped track object from the track storage.
@ -258,7 +318,9 @@ public interface LuckPermsApi {
* @throws NullPointerException if the name is null * @throws NullPointerException if the name is null
*/ */
@Nonnull @Nonnull
Optional<Track> getTrackSafe(@Nonnull String name); default Optional<Track> getTrackSafe(@Nonnull String name) {
return getTrackManager().getTrackOpt(name);
}
/** /**
* Gets a set of all loaded tracks. * Gets a set of all loaded tracks.
@ -266,7 +328,9 @@ public interface LuckPermsApi {
* @return a {@link Set} of {@link Track} objects * @return a {@link Set} of {@link Track} objects
*/ */
@Nonnull @Nonnull
Set<Track> getTracks(); default Set<Track> getTracks() {
return getTrackManager().getLoadedTracks();
}
/** /**
* Check if a track is loaded in memory * Check if a track is loaded in memory
@ -275,24 +339,17 @@ public interface LuckPermsApi {
* @return true if the track is loaded * @return true if the track is loaded
* @throws NullPointerException if the name is null * @throws NullPointerException if the name is null
*/ */
boolean isTrackLoaded(@Nonnull String name); default boolean isTrackLoaded(@Nonnull String name) {
return getTrackManager().isLoaded(name);
}
/** /**
* Gets the node factory instance for the platform * Returns a new LogEntry Builder instance
* *
* @return the node factory * @return a new builder
* @since 4.0
*/ */
@Nonnull LogEntry.Builder newLogEntryBuilder();
NodeFactory getNodeFactory();
/**
* Gets the MetaStackFactory, used for creating MetaStacks.
*
* @return the meta stack factory
* @since 3.2
*/
@Nonnull
MetaStackFactory getMetaStackFactory();
/** /**
* Returns a permission builder instance * Returns a permission builder instance
@ -304,15 +361,19 @@ public interface LuckPermsApi {
* @since 2.6 * @since 2.6
*/ */
@Nonnull @Nonnull
Node.Builder buildNode(@Nonnull String permission) throws IllegalArgumentException; default Node.Builder buildNode(@Nonnull String permission) throws IllegalArgumentException {
return getNodeFactory().newBuilder(permission);
}
/** /**
* Register a custom context calculator to the server * Register a custom context calculator to the server
* *
* @param contextCalculator the context calculator to register. The type MUST be the player class of the platform. * @param calculator the context calculator to register. The type MUST be the player class of the platform.
* @throws ClassCastException if the type is not the player class of the platform. * @throws ClassCastException if the type is not the player class of the platform.
*/ */
void registerContextCalculator(@Nonnull ContextCalculator<?> contextCalculator); default void registerContextCalculator(@Nonnull ContextCalculator<?> calculator) {
getContextManager().registerCalculator(calculator);
}
/** /**
* Gets a calculated context instance for the user using the rules of the platform. * Gets a calculated context instance for the user using the rules of the platform.
@ -323,7 +384,9 @@ public interface LuckPermsApi {
* @return an optional containing contexts. Will return empty if the user is not online. * @return an optional containing contexts. Will return empty if the user is not online.
*/ */
@Nonnull @Nonnull
Optional<Contexts> getContextForUser(@Nonnull User user); default Optional<Contexts> getContextForUser(@Nonnull User user) {
return getContextManager().lookupApplicableContexts(user);
}
/** /**
* Gets set of contexts applicable to a player using the platforms {@link ContextCalculator}s. * Gets set of contexts applicable to a player using the platforms {@link ContextCalculator}s.
@ -333,7 +396,9 @@ public interface LuckPermsApi {
* @since 2.17 * @since 2.17
*/ */
@Nonnull @Nonnull
ContextSet getContextForPlayer(@Nonnull Object player); default ContextSet getContextForPlayer(@Nonnull Object player) {
return getContextManager().getApplicableContext(player);
}
/** /**
* Gets a Contexts instance for the player using the platforms {@link ContextCalculator}s. * Gets a Contexts instance for the player using the platforms {@link ContextCalculator}s.
@ -343,23 +408,8 @@ public interface LuckPermsApi {
* @since 3.3 * @since 3.3
*/ */
@Nonnull @Nonnull
Contexts getContextsForPlayer(@Nonnull Object player); default Contexts getContextsForPlayer(@Nonnull Object player) {
return getContextManager().getApplicableContexts(player);
/** }
* Gets the unique players which have connected to the server since it started.
*
* @return the unique connections
* @since 3.3
*/
@Nonnull
Set<UUID> getUniqueConnections();
/**
* Gets the time when the plugin first started in milliseconds.
*
* @return the enable time
* @since 3.3
*/
long getStartTime();
} }

View File

@ -1,287 +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.api;
import me.lucko.luckperms.LuckPerms;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* A collection of utilities to help retrieve meta values for {@link PermissionHolder}s
*
* @since 2.7
* @deprecated in favour of using {@link NodeFactory#makeMetaNode(String, String)} or {@link me.lucko.luckperms.api.caching.MetaData}.
*/
@Deprecated
public class MetaUtils {
private static final String[] DELIMS = new String[]{".", "/", "-", "$"};
private static String escapeDelimiters(String s, String... delims) {
for (String delim : delims) {
s = s.replace(delim, "\\" + delim);
}
return s;
}
private static String unescapeDelimiters(String s, String... delims) {
for (String delim : delims) {
s = s.replace("\\" + delim, delim);
}
return s;
}
/**
* 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;
}
/**
* Sets a meta value on a holder
*
* @param holder the holder to apply the meta node to
* @param server the server to apply the meta on, can be null
* @param world the world to apply the meta on, can be null
* @param key the meta key
* @param value the meta value
* @throws NullPointerException if the holder, node or value is null
* @throws IllegalArgumentException if the node or value is empty
*/
public static void setMeta(PermissionHolder holder, String server, String world, String key, String value) {
if (holder == null) throw new NullPointerException("holder");
if (key == null) throw new NullPointerException("node");
if (value == null) throw new NullPointerException("value");
if (key.equals("")) throw new IllegalArgumentException("node is empty");
if (value.equals("")) throw new IllegalArgumentException("value is empty");
key = escapeCharacters(key);
value = escapeCharacters(value);
Set<Node> toRemove = new HashSet<>();
for (Node n : holder.getEnduringPermissions()) {
if (n.isMeta() && n.getMeta().getKey().equals(key)) {
toRemove.add(n);
}
}
for (Node n : toRemove) {
try {
holder.unsetPermission(n);
} catch (ObjectLacksException ignored) {}
}
Node.Builder metaNode = LuckPerms.getApi().buildNode("meta." + key + "." + value).setValue(true);
if (server != null) {
metaNode.setServer(server);
}
if (world != null) {
metaNode.setWorld(world);
}
try {
holder.setPermission(metaNode.build());
} catch (ObjectAlreadyHasException ignored) {}
}
/**
* Gets a meta value for the holder
*
* @param holder the holder to get the meta from
* @param server the server to retrieve the meta on, can be null
* @param world the world to retrieve the meta on, can be null
* @param node the node to get
* @param defaultValue the default value to return if the node is not set
* @param includeGlobal if global nodes should be considered when retrieving the meta
* @return a meta string, or the default value if the user does not have the meta node
* @throws NullPointerException if the holder or node is null
* @throws IllegalArgumentException if the node is empty
*/
public static String getMeta(PermissionHolder holder, String server, String world, String node, String defaultValue, boolean includeGlobal) {
if (holder == null) throw new NullPointerException("holder");
if (node == null) throw new NullPointerException("node");
if (node.equals("")) {
throw new IllegalArgumentException("node is empty");
}
node = escapeCharacters(node);
for (Node n : holder.getPermissions()) {
if (!n.getValuePrimitive() || !n.isMeta()) continue;
if (!n.shouldApplyOnServer(server, includeGlobal, false)) continue;
if (!n.shouldApplyOnWorld(world, includeGlobal, false)) continue;
Map.Entry<String, String> meta = n.getMeta();
if (meta.getKey().equalsIgnoreCase(node)) {
return unescapeCharacters(meta.getValue());
}
}
return defaultValue;
}
private static void setChatMeta(boolean prefix, PermissionHolder holder, String value, int priority, String server, String world) {
if (holder == null) throw new NullPointerException("holder");
if (value == null || value.equals("")) {
throw new IllegalArgumentException("value is null/empty");
}
Node.Builder node = LuckPerms.getApi().buildNode(prefix ? "prefix" : "suffix" + "." + priority + "." + escapeCharacters(value));
node.setValue(true);
if (server != null) {
node.setServer(server);
}
if (world != null) {
node.setWorld(world);
}
try {
holder.setPermission(node.build());
} catch (ObjectAlreadyHasException ignored) {}
}
/**
* Adds a prefix to a holder on a specific server and world
*
* @param holder the holder to set the prefix for
* @param prefix the prefix value
* @param priority the priority to set the prefix at
* @param server the server to set the prefix on, can be null
* @param world the world to set the prefix on, can be null
* @throws NullPointerException if the holder is null
* @throws IllegalArgumentException if the prefix is null or empty
*/
public static void setPrefix(PermissionHolder holder, String prefix, int priority, String server, String world) {
setChatMeta(true, holder, prefix, priority, server, world);
}
/**
* Adds a suffix to a holder on a specific server and world
*
* @param holder the holder to set the suffix for
* @param suffix the suffix value
* @param priority the priority to set the suffix at
* @param server the server to set the suffix on, can be null
* @param world the world to set the suffix on, can be null
* @throws NullPointerException if the holder is null
* @throws IllegalArgumentException if the suffix is null or empty
*/
public static void setSuffix(PermissionHolder holder, String suffix, int priority, String server, String world) {
setChatMeta(false, holder, suffix, priority, server, world);
}
private static String getChatMeta(boolean prefix, PermissionHolder holder, String server, String world, boolean includeGlobal) {
if (holder == null) {
throw new NullPointerException("holder");
}
int priority = Integer.MIN_VALUE;
String meta = null;
for (Node n : holder.getAllNodes(Contexts.allowAll())) {
if (!n.getValuePrimitive()) continue;
if (!n.shouldApplyOnServer(server, includeGlobal, false)) continue;
if (!n.shouldApplyOnWorld(world, includeGlobal, false)) continue;
if (prefix ? !n.isPrefix() : !n.isSuffix()) {
continue;
}
Map.Entry<Integer, String> value = prefix ? n.getPrefix() : n.getSuffix();
if (value.getKey() > priority) {
meta = value.getValue();
priority = value.getKey();
}
}
return meta == null ? "" : unescapeCharacters(meta);
}
/**
* Returns a holders highest priority prefix, if they have one
*
* @param holder the holder
* @param server the server to retrieve the prefix on
* @param world the world to retrieve the prefix on
* @param includeGlobal if global nodes should be considered when retrieving the prefix
* @return a prefix string, if the holder has one, or an empty string if not.
* @throws NullPointerException if the holder is null
*/
public static String getPrefix(PermissionHolder holder, String server, String world, boolean includeGlobal) {
return getChatMeta(true, holder, server, world, includeGlobal);
}
/**
* Returns a holders highest priority suffix, if they have one
*
* @param holder the holder
* @param server the server to retrieve the suffix on
* @param world the world to retrieve the suffix on
* @param includeGlobal if global nodes should be considered when retrieving the suffix
* @return a suffix string, if the holder has one, or an empty string if not.
* @throws NullPointerException if the holder is null
*/
public static String getSuffix(PermissionHolder holder, String server, String world, boolean includeGlobal) {
return getChatMeta(false, holder, server, world, includeGlobal);
}
private MetaUtils() {
}
}

View File

@ -34,7 +34,6 @@ import java.util.Optional;
import java.util.Set; import java.util.Set;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/** /**
* Represents a permission node. * Represents a permission node.
@ -151,50 +150,6 @@ public interface Node extends Map.Entry<String, Boolean> {
*/ */
boolean hasSpecificContext(); boolean hasSpecificContext();
/**
* Gets if this node is able to apply in the given context
*
* @param includeGlobal if global server values should apply
* @param includeGlobalWorld if global world values should apply
* @param server the server being checked against, or null
* @param world the world being checked against, or null
* @param context the context being checked against, or null
* @param applyRegex if regex should be applied
* @return true if the node should apply, otherwise false
* @since 3.1
*/
boolean shouldApply(boolean includeGlobal, boolean includeGlobalWorld, @Nullable String server, @Nullable String world, @Nullable ContextSet context, boolean applyRegex);
/**
* Gets if this node should apply on a specific server
*
* @param server the name of the server
* @param includeGlobal if global permissions should apply
* @param applyRegex if regex should be applied
* @return true if the node should apply
*/
boolean shouldApplyOnServer(@Nullable String server, boolean includeGlobal, boolean applyRegex);
/**
* Gets if this node should apply on a specific world
*
* @param world the name of the world
* @param includeGlobal if global permissions should apply
* @param applyRegex if regex should be applied
* @return true if the node should apply
*/
boolean shouldApplyOnWorld(@Nullable String world, boolean includeGlobal, boolean applyRegex);
/**
* Gets if this node should apply in the given context
*
* @param context the context key value pairs
* @param worldAndServer if world and server contexts should be checked
* @return true if the node should apply
* @since 2.13
*/
boolean shouldApplyWithContext(@Nonnull ContextSet context, boolean worldAndServer);
/** /**
* Gets if this node should apply in the given context * Gets if this node should apply in the given context
* *
@ -204,35 +159,6 @@ public interface Node extends Map.Entry<String, Boolean> {
*/ */
boolean shouldApplyWithContext(@Nonnull ContextSet context); boolean shouldApplyWithContext(@Nonnull ContextSet context);
/**
* Similar to {@link #shouldApplyOnServer(String, boolean, boolean)}, except this method accepts a List
*
* @param servers the list of servers
* @param includeGlobal if global permissions should apply
* @return true if the node should apply
*/
boolean shouldApplyOnAnyServers(@Nonnull List<String> servers, boolean includeGlobal);
/**
* Similar to {@link #shouldApplyOnWorld(String, boolean, boolean)}, except this method accepts a List
*
* @param worlds the list of world
* @param includeGlobal if global permissions should apply
* @return true if the node should apply
*/
boolean shouldApplyOnAnyWorlds(@Nonnull List<String> worlds, boolean includeGlobal);
/**
* Resolves a list of wildcards that match this node
*
* @param possibleNodes a list of possible permission nodes
* @return a list of permissions that match this wildcard
* @deprecated as this is no longer used internally to resolve wildcards
*/
@Nonnull
@Deprecated
List<String> resolveWildcard(@Nonnull List<String> possibleNodes);
/** /**
* Resolves any shorthand parts of this node and returns the full list * Resolves any shorthand parts of this node and returns the full list
* *
@ -309,16 +235,6 @@ public interface Node extends Map.Entry<String, Boolean> {
@Nonnull @Nonnull
ContextSet getFullContexts(); ContextSet getFullContexts();
/**
* Converts this node into a serialized form
*
* @return a serialized node string
* @deprecated because this serialized form is no longer used by the implementation.
*/
@Deprecated
@Nonnull
String toSerializedNode();
/** /**
* Gets if this is a group node * Gets if this is a group node
* *

View File

@ -67,6 +67,17 @@ public interface NodeFactory {
@Nonnull @Nonnull
Node.Builder makeGroupNode(@Nonnull Group group); Node.Builder makeGroupNode(@Nonnull Group group);
/**
* Creates a node builder from a group
*
* @param groupName the name of the group
* @return a node builder instance
* @throws NullPointerException if the groupName is null
* @since 4.0
*/
@Nonnull
Node.Builder makeGroupNode(@Nonnull String groupName);
/** /**
* Creates a node builder from a key value pair * Creates a node builder from a key value pair
* *
@ -112,35 +123,4 @@ public interface NodeFactory {
@Nonnull @Nonnull
Node.Builder makeSuffixNode(int priority, @Nonnull String suffix); Node.Builder makeSuffixNode(int priority, @Nonnull String suffix);
/**
* Creates a node from a serialised node string
*
* <p>This format is what was previously used in YAML/JSON storage files.</p>
*
* @param serialisedPermission the serialised permission string
* @param value the value of the node
* @return a node instance
* @throws NullPointerException if the permission is null
* @deprecated since this format isn't used internally for permissions anymore
* @see Node#toSerializedNode()
*/
@Deprecated
@Nonnull
Node fromSerialisedNode(@Nonnull String serialisedPermission, boolean value);
/**
* Creates a node builder from a serialised node string
*
* @param serialisedPermission the serialised permission string
* @param value the value of the node
* @return a node builder instance
* @throws NullPointerException if the permission is null
* @deprecated since this format isn't used internally for permissions anymore
* @see Node#toSerializedNode()
*/
@Deprecated
@Nonnull
Node.Builder newBuilderFromSerialisedNode(@Nonnull String serialisedPermission, boolean value);
} }

View File

@ -30,8 +30,6 @@ import com.google.common.collect.Multimap;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet; import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -40,7 +38,6 @@ import java.util.SortedSet;
import java.util.function.Predicate; import java.util.function.Predicate;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/** /**
* An object which holds permissions. * An object which holds permissions.
@ -48,7 +45,6 @@ import javax.annotation.Nullable;
* <p>Any changes made to permission holding objects will be lost unless the * <p>Any changes made to permission holding objects will be lost unless the
* instance is saved back to the {@link Storage}.</p> * instance is saved back to the {@link Storage}.</p>
*/ */
@SuppressWarnings("RedundantThrows")
public interface PermissionHolder { public interface PermissionHolder {
/** /**
@ -292,22 +288,12 @@ public interface PermissionHolder {
* Sets a permission for the object * Sets a permission for the object
* *
* @param node The node to be set * @param node The node to be set
* @throws ObjectAlreadyHasException if the object already has the permission
* @throws NullPointerException if the node is null
* @since 2.6
*/
void setPermission(@Nonnull Node node) throws ObjectAlreadyHasException;
/**
* Sets a permission for the object
*
* @param node The node to be set
* @throws NullPointerException if the node is null
* @return the result of the operation * @return the result of the operation
* @since 3.1 * @throws NullPointerException if the node is null
* @since 4.0
*/ */
@Nonnull @Nonnull
DataMutateResult setPermissionUnchecked(@Nonnull Node node); DataMutateResult setPermission(@Nonnull Node node);
/** /**
* Sets a transient permission for the object * Sets a transient permission for the object
@ -322,73 +308,34 @@ public interface PermissionHolder {
* <p>For unsetting a transient permission, see {@link #unsetTransientPermission(Node)}</p> * <p>For unsetting a transient permission, see {@link #unsetTransientPermission(Node)}</p>
* *
* @param node The node to be set * @param node The node to be set
* @throws ObjectAlreadyHasException if the object already has the permission
* @throws NullPointerException if the node is null
* @since 2.6
*/
void setTransientPermission(@Nonnull Node node) throws ObjectAlreadyHasException;
/**
* Sets a transient permission for the object
*
* <p>A transient node is a permission that does not persist.
* Whenever a user logs out of the server, or the server restarts, this permission will disappear.
* It is never saved to the datastore, and therefore will not apply on other servers.</p>
*
* <p>This is useful if you want to temporarily set a permission for a user while they're online, but don't
* want it to persist, and have to worry about removing it when they log out.</p>
*
* <p>For unsetting a transient permission, see {@link #unsetTransientPermission(Node)}</p>
*
* @param node The node to be set
* @throws NullPointerException if the node is null
* @return the result of the operation * @return the result of the operation
* @since 3.1 * @throws NullPointerException if the node is null
* @since 4.0
*/ */
@Nonnull @Nonnull
DataMutateResult setTransientPermissionUnchecked(@Nonnull Node node); DataMutateResult setTransientPermission(@Nonnull Node node);
/** /**
* Unsets a permission for the object * Unsets a permission for the object
* *
* @param node The node to be unset * @param node The node to be unset
* @throws ObjectLacksException if the node wasn't already set
* @throws NullPointerException if the node is null
* @since 2.6
*/
void unsetPermission(@Nonnull Node node) throws ObjectLacksException;
/**
* Unsets a permission for the object
*
* @param node The node to be unset
* @throws NullPointerException if the node is null
* @return the result of the operation * @return the result of the operation
* @since 3.1 * @throws NullPointerException if the node is null
* @since 4.0
*/ */
@Nonnull @Nonnull
DataMutateResult unsetPermissionUnchecked(@Nonnull Node node); DataMutateResult unsetPermission(@Nonnull Node node);
/** /**
* Unsets a transient permission for the object * Unsets a transient permission for the object
* *
* @param node The node to be unset * @param node The node to be unset
* @throws ObjectLacksException if the node wasn't already set
* @throws NullPointerException if the node is null
* @since 2.6
*/
void unsetTransientPermission(@Nonnull Node node) throws ObjectLacksException;
/**
* Unsets a transient permission for the object
*
* @param node The node to be unset
* @throws NullPointerException if the node is null
* @return the result of the operation * @return the result of the operation
* @since 3.1 * @throws NullPointerException if the node is null
* @since 4.0
*/ */
@Nonnull @Nonnull
DataMutateResult unsetTransientPermissionUnchecked(@Nonnull Node node); DataMutateResult unsetTransientPermission(@Nonnull Node node);
/** /**
* Clears any nodes from the holder which pass the predicate * Clears any nodes from the holder which pass the predicate
@ -456,421 +403,64 @@ public interface PermissionHolder {
*/ */
void clearTransientNodes(); void clearTransientNodes();
/**
* Checks to see if the object has a certain permission
*
* @param node The permission node
* @param b If the node is true/false(negated)
* @return true if the object has the permission
* @throws NullPointerException if the node is null
* @throws IllegalArgumentException if the node is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
@Deprecated
boolean hasPermission(@Nonnull String node, boolean b);
/**
* Checks to see the the object has a permission on a certain server
*
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server
* @return true if the object has the permission
* @throws NullPointerException if the node or server is null
* @throws IllegalArgumentException if the node or server is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
@Deprecated
boolean hasPermission(@Nonnull String node, boolean b, @Nonnull String server);
/**
* Checks to see the the object has a permission on a certain server and world
*
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server
* @param world The world
* @return true if the object has the permission
* @throws NullPointerException if the node, server or world is null
* @throws IllegalArgumentException if the node, server or world is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
@Deprecated
boolean hasPermission(@Nonnull String node, boolean b, @Nonnull String server, @Nonnull String world);
/**
* Checks to see the the object has a permission
*
* @param node The permission node
* @param b If the node is true/false(negated)
* @param temporary if the permission is temporary
* @return true if the object has the permission
* @throws NullPointerException if the node is null
* @throws IllegalArgumentException if the node is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
@Deprecated
boolean hasPermission(@Nonnull String node, boolean b, boolean temporary);
/**
* Checks to see the the object has a permission on a certain server
*
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server to check on
* @param temporary if the permission is temporary
* @return true if the object has the permission
* @throws NullPointerException if the node or server is null
* @throws IllegalArgumentException if the node or server is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
@Deprecated
boolean hasPermission(@Nonnull String node, boolean b, @Nonnull String server, boolean temporary);
/**
* Checks to see the the object has a permission on a certain server and world
*
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server to check on
* @param world The world to check on
* @param temporary if the permission is temporary
* @return true if the object has the permission
* @throws NullPointerException if the node, server or world is null
* @throws IllegalArgumentException if the node, server or world is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
@Deprecated
boolean hasPermission(@Nonnull String node, boolean b, @Nonnull String server, @Nonnull String world, boolean temporary);
/**
* Checks to see if the object inherits a certain permission
*
* @param node The permission node
* @param b If the node is true/false(negated)
* @return true if the object inherits the permission
* @throws NullPointerException if the node is null
* @throws IllegalArgumentException if the node is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
@Deprecated
boolean inheritsPermission(@Nonnull String node, boolean b);
/**
* Checks to see the the object inherits a permission on a certain server
*
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server
* @return true if the object inherits the permission
* @throws NullPointerException if the node or server is null
* @throws IllegalArgumentException if the node or server is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
@Deprecated
boolean inheritsPermission(@Nonnull String node, boolean b, @Nonnull String server);
/**
* Checks to see the the object inherits a permission on a certain server and world
*
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server
* @param world The world
* @return true if the object inherits the permission
* @throws NullPointerException if the node, server or world is null
* @throws IllegalArgumentException if the node server or world is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
@Deprecated
boolean inheritsPermission(@Nonnull String node, boolean b, @Nonnull String server, @Nonnull String world);
/**
* Checks to see if the object inherits a permission
*
* @param node The permission node
* @param b If the node is true/false(negated)
* @param temporary if the permission is temporary
* @return true if the object inherits the permission
* @throws NullPointerException if the node is null
* @throws IllegalArgumentException if the node is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
@Deprecated
boolean inheritsPermission(@Nonnull String node, boolean b, boolean temporary);
/**
* Checks to see if the object inherits a permission on a certain server
*
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server
* @param temporary if the permission is temporary
* @return true if the object inherits the permission
* @throws NullPointerException if the node or server is null
* @throws IllegalArgumentException if the node or server is invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
@Deprecated
boolean inheritsPermission(@Nonnull String node, boolean b, @Nonnull String server, boolean temporary);
/**
* Checks to see if the object inherits a permission on a certain server and world
*
* @param node The permission node
* @param b If the node is true/false(negated)
* @param server The server
* @param world The world
* @param temporary if the permission is temporary
* @return true if the object inherits the permission
* @throws NullPointerException if the node, server or world is null
* @throws IllegalArgumentException if the node, server or world if invalid
* @deprecated in favour of {@link #hasPermission(Node)}
*/
@Deprecated
boolean inheritsPermission(@Nonnull String node, boolean b, @Nonnull String server, @Nonnull String world, boolean temporary);
/** /**
* Sets a permission for the object * Sets a permission for the object
* *
* @param node The node to be set * @param node The node to be set
* @param value What to set the node to - true/false(negated) * @return the result of the operation
* @throws ObjectAlreadyHasException if the object already has the permission
* @throws NullPointerException if the node is null * @throws NullPointerException if the node is null
* @throws IllegalArgumentException if the node is invalid * @since 3.1
* @deprecated in favour of {@link #setPermission(Node)} * @deprecated now forwards to {@link #setPermission(Node)}.
*/ */
@Nonnull
@Deprecated @Deprecated
void setPermission(@Nonnull String node, boolean value) throws ObjectAlreadyHasException; default DataMutateResult setPermissionUnchecked(@Nonnull Node node) {
return setPermission(node);
}
/** /**
* Sets a permission for the object on a specific server * Sets a transient permission for the object
* *
* @param node The node to set * @param node The node to be set
* @param value What to set the node to - true/false(negated) * @return the result of the operation
* @param server The server to set the permission on
* @throws ObjectAlreadyHasException if the object already has the permission
* @throws NullPointerException if the node or server is null
* @throws IllegalArgumentException if the node or server is invalid
* @deprecated in favour of {@link #setPermission(Node)}
*/
@Deprecated
void setPermission(@Nonnull String node, boolean value, @Nonnull String server) throws ObjectAlreadyHasException;
/**
* Sets a permission for the object on a specific server and world
*
* @param node The node to set
* @param value What to set the node to - true/false(negated)
* @param server The server to set the permission on
* @param world The world to set the permission on
* @throws ObjectAlreadyHasException if the object already has the permission
* @throws NullPointerException if the node, server or world is null
* @throws IllegalArgumentException if the node, server or world is invalid
* @deprecated in favour of {@link #setPermission(Node)}
*/
@Deprecated
void setPermission(@Nonnull String node, boolean value, @Nonnull String server, @Nonnull String world) throws ObjectAlreadyHasException;
/**
* Sets a temporary permission for the object
*
* @param node The node to set
* @param value What to set the node to - true/false(negated)
* @param expireAt The time in unixtime when the permission will expire
* @throws ObjectAlreadyHasException if the object already has the permission
* @throws NullPointerException if the node is null * @throws NullPointerException if the node is null
* @throws IllegalArgumentException if the node is invalid or if the expiry time is in the past * @since 3.1
* @deprecated in favour of {@link #setPermission(Node)} * @deprecated now forwards to {@link #setTransientPermission(Node)}
*/ */
@Nonnull
@Deprecated @Deprecated
void setPermission(@Nonnull String node, boolean value, long expireAt) throws ObjectAlreadyHasException; default DataMutateResult setTransientPermissionUnchecked(@Nonnull Node node) {
return setTransientPermission(node);
/** }
* Sets a temporary permission for the object on a specific server
*
* @param node The node to set
* @param value What to set the node to - true/false(negated)
* @param server The server to set the permission on
* @param expireAt The time in unixtime when the permission will expire
* @throws ObjectAlreadyHasException if the object already has the permission
* @throws NullPointerException if the node or server is null
* @throws IllegalArgumentException if the node/server is invalid or if the expiry time is in the past
* @deprecated in favour of {@link #setPermission(Node)}
*/
@Deprecated
void setPermission(@Nonnull String node, boolean value, @Nonnull String server, long expireAt) throws ObjectAlreadyHasException;
/**
* Sets a temporary permission for the object on a specific server and world
*
* @param node The node to set
* @param value What to set the node to - true/false(negated)
* @param server The server to set the permission on
* @param world The world to set the permission on
* @param expireAt The time in unixtime when the permission will expire
* @throws ObjectAlreadyHasException if the object already has the permission
* @throws NullPointerException if the node, server or world is null
* @throws IllegalArgumentException if the node/server/world is invalid, or if the expiry time is in the past
* @deprecated in favour of {@link #setPermission(Node)}
*/
@Deprecated
void setPermission(String node, boolean value, @Nonnull String server, @Nonnull String world, long expireAt) throws ObjectAlreadyHasException;
/** /**
* Unsets a permission for the object * Unsets a permission for the object
* *
* @param node The node to be unset * @param node The node to be unset
* @param temporary if the permission being removed is temporary
* @throws ObjectLacksException if the node wasn't already set
* @throws NullPointerException if the node is null * @throws NullPointerException if the node is null
* @throws IllegalArgumentException if the node is invalid * @return the result of the operation
* @deprecated in favour of {@link #unsetPermission(Node)} * @since 3.1
* @deprecated now forwards to {@link #unsetPermission(Node)}
*/ */
@Nonnull
@Deprecated @Deprecated
void unsetPermission(@Nonnull String node, boolean temporary) throws ObjectLacksException; default DataMutateResult unsetPermissionUnchecked(@Nonnull Node node) {
return unsetPermission(node);
}
/** /**
* Unsets a permission for the object * Unsets a transient permission for the object
* *
* @param node The node to be unset * @param node The node to be unset
* @throws ObjectLacksException if the node wasn't already set
* @throws NullPointerException if the node is null * @throws NullPointerException if the node is null
* @throws IllegalArgumentException if the node is invalid * @return the result of the operation
* @deprecated in favour of {@link #unsetPermission(Node)} * @since 3.1
* @deprecated now forwards to {@link #unsetTransientPermission(Node)}
*/ */
@Nonnull
@Deprecated @Deprecated
void unsetPermission(@Nonnull String node) throws ObjectLacksException; default DataMutateResult unsetTransientPermissionUnchecked(@Nonnull Node node) {
return unsetTransientPermission(node);
/** }
* Unsets a permission for the object on a specific server
*
* @param node The node to be unset
* @param server The server to unset the node on
* @throws ObjectLacksException if the node wasn't already set
* @throws NullPointerException if the node or server is null
* @throws IllegalArgumentException if the node or server is invalid
* @deprecated in favour of {@link #unsetPermission(Node)}
*/
@Deprecated
void unsetPermission(@Nonnull String node, @Nonnull String server) throws ObjectLacksException;
/**
* Unsets a permission for the object on a specific server and world
*
* @param node The node to be unset
* @param server The server to unset the node on
* @param world The world to unset the node on
* @throws ObjectLacksException if the node wasn't already set
* @throws NullPointerException if the node, server or world is null
* @throws IllegalArgumentException if the node, server or world is invalid
* @deprecated in favour of {@link #unsetPermission(Node)}
*/
@Deprecated
void unsetPermission(@Nonnull String node, @Nonnull String server, @Nonnull String world) throws ObjectLacksException;
/**
* Unsets a permission for the object on a specific server
*
* @param node The node to be unset
* @param server The server to unset the node on
* @param temporary if the permission being unset is temporary
* @throws ObjectLacksException if the node wasn't already set
* @throws NullPointerException if the node or server is null
* @throws IllegalArgumentException if the node or server is invalid
* @deprecated in favour of {@link #unsetPermission(Node)}
*/
@Deprecated
void unsetPermission(@Nonnull String node, @Nonnull String server, boolean temporary) throws ObjectLacksException;
/**
* Unsets a permission for the object on a specific server and world
*
* @param node The node to be unset
* @param server The server to unset the node on
* @param world The world to unset the node on
* @param temporary if the permission being unset is temporary
* @throws ObjectLacksException if the node wasn't already set
* @throws NullPointerException if the node, server or world is null
* @throws IllegalArgumentException if the node, server or world is invalid
* @deprecated in favour of {@link #unsetPermission(Node)}
*/
@Deprecated
void unsetPermission(@Nonnull String node, @Nonnull String server, @Nonnull String world, boolean temporary) throws ObjectLacksException;
/**
* Clears all nodes held by the object on a specific server
*
* @param server the server to filter by, can be null
* @since 2.17
* @deprecated in favour of {@link #clearNodes(ContextSet)}
*/
@Deprecated
void clearNodes(@Nullable String server);
/**
* Clears all nodes held by the object on a specific server and world
*
* @param server the server to filter by, can be null
* @param world the world to filter by, can be null
* @since 2.17
* @deprecated in favour of {@link #clearNodes(ContextSet)}
*/
@Deprecated
void clearNodes(@Nullable String server, @Nullable String world);
/**
* Clears all parents on a specific server
*
* @param server the server to filter by, can be null
* @since 2.17
* @deprecated in favour of {@link #clearParents(ContextSet)}
*/
@Deprecated
void clearParents(@Nullable String server);
/**
* Clears all parents on a specific server and world
*
* @param server the server to filter by, can be null
* @param world the world to filter by, can be null
* @since 2.17
* @deprecated in favour of {@link #clearParents(ContextSet)}
*/
@Deprecated
void clearParents(@Nullable String server, @Nullable String world);
/**
* Clears all meta held by the object on a specific server
*
* @param server the server to filter by, can be null
* @since 2.17
* @deprecated in favour of {@link #clearMeta(ContextSet)}
*/
@Deprecated
void clearMeta(@Nullable String server);
/**
* Clears all meta held by the object on a specific server and world
*
* @param server the server to filter by, can be null
* @param world the world to filter by, can be null
* @since 2.17
* @deprecated in favour of {@link #clearMeta(ContextSet)}
*/
@Deprecated
void clearMeta(@Nullable String server, @Nullable String world);
/**
* Clears all meta for a given key.
*
* @param key the meta key
* @param server the server to filter by, can be null
* @param world the world to filter by, can be null
* @param temporary whether the query is for temporary nodes or not.
* @deprecated in favour of {@link #clearMatching(Predicate)}
*/
@Deprecated
void clearMetaKeys(@Nonnull String key, @Nullable String server, @Nullable String world, boolean temporary);
} }

View File

@ -134,18 +134,6 @@ public interface Storage {
@Nonnull @Nonnull
CompletableFuture<Boolean> saveUser(@Nonnull User user); CompletableFuture<Boolean> saveUser(@Nonnull User user);
/**
* Removes users from the main storage who are "default". This is called every time the plugin loads.
*
* @return true if the operation completed successfully
* @deprecated this method no longer does anything - the cleanup feature was removed. :)
*/
@Nonnull
@Deprecated
default CompletableFuture<Boolean> cleanupUsers() {
return CompletableFuture.completedFuture(false);
}
/** /**
* Gets a set all "unique" user UUIDs. * Gets a set all "unique" user UUIDs.
* *

View File

@ -25,9 +25,6 @@
package me.lucko.luckperms.api; package me.lucko.luckperms.api;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List; import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
@ -36,7 +33,6 @@ import javax.annotation.Nullable;
/** /**
* An ordered chain of {@link Group}s. * An ordered chain of {@link Group}s.
*/ */
@SuppressWarnings("RedundantThrows")
public interface Track { public interface Track {
/** /**
@ -69,67 +65,69 @@ public interface Track {
/** /**
* Gets the next group on the track, after the one provided * Gets the next group on the track, after the one provided
* *
* <p>{@code null} is returned if the group is not on the track.</p>
*
* @param current the group before the group being requested * @param current the group before the group being requested
* @return the group name, or null if the end of the track has been reached * @return the group name, or null if the end of the track has been reached
* @throws ObjectLacksException if the track does not contain the group given
* @throws NullPointerException if the group is null * @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms. * @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/ */
@Nullable @Nullable
String getNext(@Nonnull Group current) throws ObjectLacksException; String getNext(@Nonnull Group current);
/** /**
* Gets the previous group on the track, before the one provided * Gets the previous group on the track, before the one provided
* *
* <p>{@code null} is returned if the group is not on the track.</p>
*
* @param current the group after the group being requested * @param current the group after the group being requested
* @return the group name, or null if the start of the track has been reached * @return the group name, or null if the start of the track has been reached
* @throws ObjectLacksException if the track does not contain the group given
* @throws NullPointerException if the group is null * @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms. * @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/ */
@Nullable @Nullable
String getPrevious(@Nonnull Group current) throws ObjectLacksException; String getPrevious(@Nonnull Group current);
/** /**
* Appends a group to the end of this track * Appends a group to the end of this track
* *
* @param group the group to append * @param group the group to append
* @throws ObjectAlreadyHasException if the group is already on this track somewhere * @return the result of the operation
* @throws NullPointerException if the group is null * @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms. * @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/ */
void appendGroup(@Nonnull Group group) throws ObjectAlreadyHasException; DataMutateResult appendGroup(@Nonnull Group group);
/** /**
* Inserts a group at a certain position on this track * Inserts a group at a certain position on this track
* *
* @param group the group to be inserted * @param group the group to be inserted
* @param position the index position (a value of 0 inserts at the start) * @param position the index position (a value of 0 inserts at the start)
* @throws ObjectAlreadyHasException if the group is already on this track somewhere * @return the result of the operation
* @throws IndexOutOfBoundsException if the position is less than 0 or greater than the size of the track * @throws IndexOutOfBoundsException if the position is less than 0 or greater than the size of the track
* @throws NullPointerException if the group is null * @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms. * @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/ */
void insertGroup(@Nonnull Group group, int position) throws ObjectAlreadyHasException, IndexOutOfBoundsException; DataMutateResult insertGroup(@Nonnull Group group, int position) throws IndexOutOfBoundsException;
/** /**
* Removes a group from this track * Removes a group from this track
* *
* @param group the group to remove * @param group the group to remove
* @throws ObjectLacksException if the group is not on this track * @return the result of the operation
* @throws NullPointerException if the group is null * @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms. * @throws IllegalStateException if the group instance was not obtained from LuckPerms.
*/ */
void removeGroup(@Nonnull Group group) throws ObjectLacksException; DataMutateResult removeGroup(@Nonnull Group group);
/** /**
* Removes a group from this track * Removes a group from this track
* *
* @param group the group to remove * @param group the group to remove
* @throws ObjectLacksException if the group is not on this track * @return the result of the operation
* @throws NullPointerException if the group is null * @throws NullPointerException if the group is null
*/ */
void removeGroup(@Nonnull String group) throws ObjectLacksException; DataMutateResult removeGroup(@Nonnull String group);
/** /**
* Checks if a group features on this track * Checks if a group features on this track

View File

@ -27,12 +27,9 @@ package me.lucko.luckperms.api;
import me.lucko.luckperms.api.caching.UserData; import me.lucko.luckperms.api.caching.UserData;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ContextSet;
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.UUID;
import java.util.concurrent.CompletableFuture;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -75,19 +72,11 @@ public interface User extends PermissionHolder {
* Sets a users primary group. This will only take effect if platform is using stored primary groups. * Sets a users primary group. This will only take effect if platform is using stored primary groups.
* *
* @param group the new primary group * @param group the new primary group
* @throws ObjectAlreadyHasException if the user already has this set as their primary group * @return if the change was applied successfully
* @throws IllegalStateException if the user is not a member of that group * @throws IllegalStateException if the user is not a member of that group
* @throws NullPointerException if the group is null * @throws NullPointerException if the group is null
*/ */
void setPrimaryGroup(@Nonnull String group) throws ObjectAlreadyHasException; DataMutateResult setPrimaryGroup(@Nonnull String group);
/**
* Refresh and re-assign the users permissions.
*
* <p>This request is not buffered, and the refresh call will be ran directly. This should be called on an
* asynchronous thread.</p>
*/
void refreshPermissions();
/** /**
* Gets the user's {@link UserData} cache. * Gets the user's {@link UserData} cache.
@ -99,14 +88,13 @@ public interface User extends PermissionHolder {
UserData getCachedData(); UserData getCachedData();
/** /**
* Pre-calculates some values in the user's data cache. * Refreshes and applies any changes to the cached user data.
* *
* <p>Is it <b>not</b> necessary to call this method before * @return the task future
* using {@link #getCachedData()}.</p> * @since 4.0
*
* @since 2.17
*/ */
void setupDataCache(); @Nonnull
CompletableFuture<Void> refreshCachedData();
/** /**
* Check to see if the user is a direct member of a group * Check to see if the user is a direct member of a group
@ -130,249 +118,26 @@ public interface User extends PermissionHolder {
boolean isInGroup(@Nonnull Group group, @Nonnull ContextSet contextSet); boolean isInGroup(@Nonnull Group group, @Nonnull ContextSet contextSet);
/** /**
* Gets the user's {@link UserData} cache, if they have one setup. * Refresh and re-assign the users permissions.
* *
* @return an optional, possibly containing the user's cached lookup data. * <p>This request is not buffered, and the refresh call will be ran directly. This should be called on an
* @since 2.13 * asynchronous thread.</p>
* @deprecated in version 3.2, as this cache is now always loaded *
* @deprecated in favour of {@link #refreshCachedData()}.
*/ */
@Deprecated @Deprecated
@Nonnull void refreshPermissions();
Optional<UserData> getUserDataCache();
/** /**
* Check to see if a user is a member of a group on a specific server * Pre-calculates some values in the user's data cache.
* *
* @param group The group to check membership of * <p>Is it <b>not</b> necessary to call this method before
* @param server The server to check on * using {@link #getCachedData()}.</p>
* @return true if the user is a member of the group *
* @throws NullPointerException if the group or server is null * @since 2.17
* @throws IllegalArgumentException if the server is invalid * @deprecated because use of this method is no longer necessary.
* @deprecated in favour of {@link #isInGroup(Group, ContextSet)}
*/ */
@Deprecated @Deprecated
boolean isInGroup(@Nonnull Group group, @Nonnull String server); void setupDataCache();
/**
* Check to see if a user is a member of a group on a specific server and world
*
* @param group The group to check membership of
* @param server The server to check on
* @param world The world to check on
* @return true if the user is a member of the group
* @throws NullPointerException if the group, server or world is null
* @throws IllegalArgumentException if the server or world is invalid
* @deprecated in favour of {@link #isInGroup(Group, ContextSet)}
*/
@Deprecated
boolean isInGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world);
/**
* Add a user to a group
*
* @param group The group to add the user to
* @throws ObjectAlreadyHasException if the user is already a member of the group
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void addGroup(@Nonnull Group group) throws ObjectAlreadyHasException;
/**
* Add a user to a group on a specific server
*
* @param group The group to add the user to
* @param server The server to add the group on
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
* @throws NullPointerException if the group or server is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the server is invalid
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void addGroup(@Nonnull Group group, @Nonnull String server) throws ObjectAlreadyHasException;
/**
* Add a user to a group on a specific server and world
*
* @param group The group to add the user to
* @param server The server to add the group on
* @param world The world to add the group on
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
* @throws NullPointerException if the group, server or world is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the server or world is invalid
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void addGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world) throws ObjectAlreadyHasException;
/**
* Add a user to a group temporarily on a specific server
*
* @param group The group to add the user to
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the expiry time is in the past
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void addGroup(@Nonnull Group group, long expireAt) throws ObjectAlreadyHasException;
/**
* Add a user to a group temporarily on a specific server
*
* @param group The group to add the user to
* @param server The server to add the group on
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
* @throws NullPointerException if the group or server is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the expiry time is in the past or the server is invalid
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void addGroup(@Nonnull Group group, @Nonnull String server, long expireAt) throws ObjectAlreadyHasException;
/**
* Add a user to a group temporarily on a specific server and world
*
* @param group The group to add the user to
* @param server The server to add the group on
* @param world The world to add the group on
* @param expireAt when the group should expire
* @throws ObjectAlreadyHasException if the user is already a member of the group on that server
* @throws NullPointerException if the group, server or world is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the expiry time is in the past or the server/world is invalid
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void addGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world, long expireAt) throws ObjectAlreadyHasException;
/**
* Remove the user from a group
*
* @param group the group to remove the user from
* @throws ObjectLacksException if the user isn't a member of the group
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void removeGroup(@Nonnull Group group) throws ObjectLacksException;
/**
* Remove the user from a group
*
* @param group the group to remove the user from
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the user isn't a member of the group
* @throws NullPointerException if the group is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void removeGroup(@Nonnull Group group, boolean temporary) throws ObjectLacksException;
/**
* Remove the user from a group on a specific server
*
* @param group The group to remove the user from
* @param server The server to remove the group on
* @throws ObjectLacksException if the user isn't a member of the group
* @throws NullPointerException if the group or server is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the server is invalid
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void removeGroup(@Nonnull Group group, @Nonnull String server) throws ObjectLacksException;
/**
* Remove the user from a group on a specific server and world
*
* @param group The group to remove the user from
* @param server The server to remove the group on
* @param world The world to remove the group on
* @throws ObjectLacksException if the user isn't a member of the group
* @throws NullPointerException if the group, server or world is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the server or world is invalid
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void removeGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world) throws ObjectLacksException;
/**
* Remove the user from a group on a specific server
*
* @param group The group to remove the user from
* @param server The server to remove the group on
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the user isn't a member of the group
* @throws NullPointerException if the group or server is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the expiry time is in the past or the server is invalid
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void removeGroup(@Nonnull Group group, @Nonnull String server, boolean temporary) throws ObjectLacksException;
/**
* Remove the user from a group on a specific server and world
*
* @param group The group to remove the user from
* @param server The server to remove the group on
* @param world The world to remove the group on
* @param temporary if the group being removed is temporary
* @throws ObjectLacksException if the user isn't a member of the group
* @throws NullPointerException if the group, server or world is null
* @throws IllegalStateException if the group instance was not obtained from LuckPerms.
* @throws IllegalArgumentException if the expiry time is in the past or the server/world is invalid
* @deprecated in favour of {@link NodeFactory#makeGroupNode(Group)}
*/
@Deprecated
void removeGroup(@Nonnull Group group, @Nonnull String server, @Nonnull String world, boolean temporary) throws ObjectLacksException;
/**
* Get a {@link List} of all of the groups the user is a member of, on all servers
*
* @return a {@link List} of group names
* @deprecated in favour of just querying a users permissions
*/
@Deprecated
@Nonnull
List<String> getGroupNames();
/**
* Get a {@link List} of the groups the user is a member of on a specific server
*
* @param server the server to check
* @param world the world to check
* @return a {@link List} of group names
* @throws NullPointerException if the server or world is null
* @throws IllegalArgumentException if the server or world is invalid
* @deprecated in favour of just querying a users permissions
*/
@Deprecated
@Nonnull
List<String> getLocalGroups(@Nonnull String server, @Nonnull String world);
/**
* Get a {@link List} of the groups the user is a member of on a specific server
*
* @param server the server to check
* @return a {@link List} of group names
* @throws NullPointerException if the server is null
* @throws IllegalArgumentException if the server is invalid
* @deprecated in favour of just querying a users permissions
*/
@Deprecated
@Nonnull
List<String> getLocalGroups(@Nonnull String server);
} }

View File

@ -33,6 +33,7 @@ import javax.annotation.Nonnull;
* @param <T> the subject type. Is ALWAYS the player class of the platform. * @param <T> the subject type. Is ALWAYS the player class of the platform.
* @since 2.13 * @since 2.13
*/ */
@FunctionalInterface
public interface ContextCalculator<T> { public interface ContextCalculator<T> {
/** /**

View File

@ -0,0 +1,172 @@
/*
* 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.api.context;
import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.User;
import java.util.Optional;
import javax.annotation.Nonnull;
/**
* Manages {@link ContextCalculator}s, and calculates applicable contexts for a
* given type.
*
* This interface accepts {@link Object} types as a parameter to avoid having to depend
* on specific server implementations. In all cases, the "player" or "subject" type for
* the platform must be used.
*
* Specifically, {@code org.bukkit.entity.Player},
* {@code net.md_5.bungee.api.connection.ProxiedPlayer} and
* {@code org.spongepowered.api.service.permission.Subject}.
*
* @since 4.0
*/
public interface ContextManager {
/**
* Queries the ContextManager for current context values for the subject.
*
* @param subject the subject
* @return the applicable context for the subject
*/
@Nonnull
ImmutableContextSet getApplicableContext(@Nonnull Object subject);
/**
* Queries the ContextManager for current context values for the subject.
*
* @param subject the subject
* @return the applicable context for the subject
*/
@Nonnull
Contexts getApplicableContexts(@Nonnull Object subject);
/**
* Queries the ContextManager for current context values for the given User.
*
* <p>This will only return a value if the player corresponding to the
* {@link User} is online.</p>
*
* <p>If you need to be a {@link Contexts} instance regardless, you should
* initially try this method, and then fallback on {@link #getStaticContext()}.</p>
*
* @param user the user
* @return the applicable context for the subject
*/
@Nonnull
Optional<ImmutableContextSet> lookupApplicableContext(@Nonnull User user);
/**
* Queries the ContextManager for current context values for the given User.
*
* <p>This will only return a value if the player corresponding to the
* {@link User} is online.</p>
*
* <p>If you need to be a {@link Contexts} instance regardless, you should
* initially try this method, and then fallback on {@link #getStaticContexts()}.</p>
*
* @param user the user
* @return the applicable context for the subject
*/
@Nonnull
Optional<Contexts> lookupApplicableContexts(@Nonnull User user);
/**
* Gets the contexts from the static calculators in this manager.
*
* <p>Static calculators provide the same context for all subjects, and are
* marked as such when registered.</p>
*
* @return the current active static contexts
*/
@Nonnull
ImmutableContextSet getStaticContext();
/**
* Gets the contexts from the static calculators in this manager.
*
* <p>Static calculators provide the same context for all subjects, and are
* marked as such when registered.</p>
*
* @return the current active static contexts
*/
@Nonnull
Contexts getStaticContexts();
/**
* Forms a {@link Contexts} instance from an {@link ImmutableContextSet}.
*
* <p>This method relies on the plugins configuration to form the
* {@link Contexts} instance.</p>
*
* @param subject the reference subject
* @param contextSet the context set
* @return a contexts instance
*/
@Nonnull
Contexts formContexts(@Nonnull Object subject, @Nonnull ImmutableContextSet contextSet);
/**
* Forms a {@link Contexts} instance from an {@link ImmutableContextSet}.
*
* <p>This method relies on the plugins configuration to form the
* {@link Contexts} instance.</p>
*
* @param contextSet the context set
* @return a contexts instance
*/
@Nonnull
Contexts formContexts(@Nonnull ImmutableContextSet contextSet);
/**
* Registers a context calculator with the manager.
*
* @param calculator the calculator
*/
@Nonnull
void registerCalculator(@Nonnull ContextCalculator<?> calculator);
/**
* Registers a static context calculator with the manager.
*
* <p>Static calculators provide the same context for all subjects.</p>
*
* @param calculator the calculator
*/
@Nonnull
void registerStaticCalculator(@Nonnull StaticContextCalculator calculator);
/**
* Invalidates the lookup cache for a given subject
*
* @param subject the subject
*/
@Nonnull
void invalidateCache(@Nonnull Object subject);
}

View File

@ -0,0 +1,63 @@
/*
* 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.api.context;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Extension of {@link ContextCalculator} which provides the same context
* regardless of the subject.
*
* @since 4.0
*/
@FunctionalInterface
public interface StaticContextCalculator extends ContextCalculator<Object> {
/**
* Adds this calculators context to the given accumulator.
*
* @param accumulator a map of contexts to add to
* @return the map
*/
@Nonnull
MutableContextSet giveApplicableContext(@Nonnull MutableContextSet accumulator);
/**
* Gives the subject all of the applicable contexts they meet
*
* @param subject the subject to add contexts to
* @param accumulator a map of contexts to add to
* @return the map
*/
@Nonnull
@Override
@Deprecated
default MutableContextSet giveApplicableContext(@Nullable Object subject, @Nonnull MutableContextSet accumulator) {
return giveApplicableContext(accumulator);
}
}

View File

@ -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.api.manager;
import me.lucko.luckperms.api.Group;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Represents the object responsible for managing {@link Group} instances.
*
* @since 4.0
*/
public interface GroupManager {
/**
* Gets a wrapped group object from the group storage
*
* @param name the name of the group to get
* @return a {@link Group} object, if one matching the name exists, or null if not
* @throws NullPointerException if the name is null
*/
@Nullable
Group getGroup(@Nonnull String name);
/**
* Gets a wrapped group object from the group storage.
*
* <p>This method does not return null, unlike {@link #getGroup}</p>
*
* @param name the name of the group to get
* @return an optional {@link Group} object
* @throws NullPointerException if the name is null
*/
@Nonnull
default Optional<Group> getGroupOpt(@Nonnull String name) {
return Optional.ofNullable(getGroup(name));
}
/**
* Gets a set of all loaded groups.
*
* @return a {@link Set} of {@link Group} objects
*/
@Nonnull
Set<Group> getLoadedGroups();
/**
* Check if a group is loaded in memory
*
* @param name the name to check for
* @return true if the group is loaded
* @throws NullPointerException if the name is null
*/
boolean isLoaded(@Nonnull String name);
}

View File

@ -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.api.manager;
import me.lucko.luckperms.api.Track;
import java.util.Optional;
import java.util.Set;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Represents the object responsible for managing {@link Track} instances.
*
* @since 4.0
*/
public interface TrackManager {
/**
* Gets a wrapped track object from the track storage
*
* @param name the name of the track to get
* @return a {@link Track} object, if one matching the name exists, or null if not
* @throws NullPointerException if the name is null
*/
@Nullable
Track getTrack(@Nonnull String name);
/**
* Gets a wrapped track object from the track storage.
*
* <p>This method does not return null, unlike {@link #getTrack}</p>
*
* @param name the name of the track to get
* @return an optional {@link Track} object
* @throws NullPointerException if the name is null
*/
@Nonnull
default Optional<Track> getTrackOpt(@Nonnull String name) {
return Optional.ofNullable(getTrack(name));
}
/**
* Gets a set of all loaded tracks.
*
* @return a {@link Set} of {@link Track} objects
*/
@Nonnull
Set<Track> getLoadedTracks();
/**
* Check if a track is loaded in memory
*
* @param name the name to check for
* @return true if the track is loaded
* @throws NullPointerException if the name is null
*/
boolean isLoaded(@Nonnull String name);
}

View File

@ -0,0 +1,113 @@
/*
* 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.api.manager;
import me.lucko.luckperms.api.User;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Represents the object responsible for managing {@link User} instances.
*
* @since 4.0
*/
public interface UserManager {
/**
* Gets a wrapped user object from the user storage
*
* @param uuid the uuid of the user to get
* @return a {@link User} object, if one matching the uuid is loaded, or null if not
* @throws NullPointerException if the uuid is null
*/
@Nullable
User getUser(@Nonnull UUID uuid);
/**
* Gets a wrapped user object from the user storage.
*
* @param uuid the uuid of the user to get
* @return an optional {@link User} object
* @throws NullPointerException if the uuid is null
*/
@Nonnull
default Optional<User> getUserOpt(@Nonnull UUID uuid) {
return Optional.ofNullable(getUser(uuid));
}
/**
* Gets a wrapped user object from the user storage
*
* @param name the username of the user to get
* @return a {@link User} object, if one matching the uuid is loaded, or null if not
* @throws NullPointerException if the name is null
*/
@Nullable
User getUser(@Nonnull String name);
/**
* Gets a wrapped user object from the user storage.
*
* @param name the username of the user to get
* @return an optional {@link User} object
* @throws NullPointerException if the name is null
*/
@Nonnull
default Optional<User> getUserOpt(@Nonnull String name) {
return Optional.ofNullable(getUser(name));
}
/**
* Gets a set of all loaded users.
*
* @return a {@link Set} of {@link User} objects
*/
@Nonnull
Set<User> getLoadedUsers();
/**
* Check if a user is loaded in memory
*
* @param uuid the uuid to check for
* @return true if the user is loaded
* @throws NullPointerException if the uuid is null
*/
boolean isLoaded(@Nonnull UUID uuid);
/**
* Unload a user from the internal storage, if they're not currently online.
*
* @param user the user to unload
* @throws NullPointerException if the user is null
*/
void cleanupUser(@Nonnull User user);
}

View File

@ -0,0 +1,78 @@
/*
* 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.api.platform;
import java.util.Set;
import java.util.UUID;
import javax.annotation.Nonnull;
/**
* Provides information about the platform LuckPerms is running on.
*
* @since 4.0
*/
public interface PlatformInfo {
/**
* Gets the plugin version
*
* @return the version of the plugin running on the platform
*/
@Nonnull
String getVersion();
/**
* Gets the API version
*
* @return the version of the API running on the platform
*/
double getApiVersion();
/**
* Gets the type of platform LuckPerms is running on
*
* @return the type of platform LuckPerms is running on
*/
@Nonnull
PlatformType getType();
/**
* Gets the unique players which have connected to the server since it started.
*
* @return the unique connections
*/
@Nonnull
Set<UUID> getUniqueConnections();
/**
* Gets the time when the plugin first started in milliseconds.
*
* @return the enable time
*/
long getStartTime();
}

View File

@ -23,7 +23,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
package me.lucko.luckperms.api; package me.lucko.luckperms.api.platform;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;

View File

@ -1,40 +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.exceptions;
/**
* Thrown when an object lacks something.
*
* <p>For example, when:</p>
* <p></p>
* <ul>
* <li>a permission holding object doesn't have a permission</li>
* <li>a permission holding object isn't already a member of a group</li>
* <li>a track doesn't contain a group</li>
* </ul>
*/
public class ObjectLacksException extends MembershipException {
}

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>luckperms</artifactId> <artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId> <groupId>me.lucko.luckperms</groupId>
<version>3.4-SNAPSHOT</version> <version>4.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>luckperms</artifactId> <artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId> <groupId>me.lucko.luckperms</groupId>
<version>3.4-SNAPSHOT</version> <version>4.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -28,9 +28,8 @@ package me.lucko.luckperms.bukkit;
import lombok.Getter; import lombok.Getter;
import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.api.LuckPermsApi; import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.api.PlatformType; import me.lucko.luckperms.api.platform.PlatformType;
import me.lucko.luckperms.bukkit.calculators.BukkitCalculatorFactory; import me.lucko.luckperms.bukkit.calculators.BukkitCalculatorFactory;
import me.lucko.luckperms.bukkit.contexts.BukkitContextManager; import me.lucko.luckperms.bukkit.contexts.BukkitContextManager;
import me.lucko.luckperms.bukkit.contexts.WorldCalculator; import me.lucko.luckperms.bukkit.contexts.WorldCalculator;
@ -45,8 +44,8 @@ import me.lucko.luckperms.bukkit.processors.ChildPermissionProvider;
import me.lucko.luckperms.bukkit.processors.DefaultsProvider; import me.lucko.luckperms.bukkit.processors.DefaultsProvider;
import me.lucko.luckperms.bukkit.vault.VaultHookManager; import me.lucko.luckperms.bukkit.vault.VaultHookManager;
import me.lucko.luckperms.common.actionlog.LogDispatcher; import me.lucko.luckperms.common.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.ApiHandler;
import me.lucko.luckperms.common.api.ApiProvider; import me.lucko.luckperms.common.api.ApiProvider;
import me.lucko.luckperms.common.api.ApiSingletonUtils;
import me.lucko.luckperms.common.buffers.BufferedRequest; import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.buffers.UpdateTaskBuffer; import me.lucko.luckperms.common.buffers.UpdateTaskBuffer;
import me.lucko.luckperms.common.caching.handlers.CachedStateManager; import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
@ -63,6 +62,7 @@ import me.lucko.luckperms.common.dependencies.DependencyManager;
import me.lucko.luckperms.common.locale.LocaleManager; import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.NoopLocaleManager; import me.lucko.luckperms.common.locale.NoopLocaleManager;
import me.lucko.luckperms.common.locale.SimpleLocaleManager; import me.lucko.luckperms.common.locale.SimpleLocaleManager;
import me.lucko.luckperms.common.logging.Logger;
import me.lucko.luckperms.common.logging.SenderLogger; import me.lucko.luckperms.common.logging.SenderLogger;
import me.lucko.luckperms.common.managers.GenericGroupManager; import me.lucko.luckperms.common.managers.GenericGroupManager;
import me.lucko.luckperms.common.managers.GenericTrackManager; import me.lucko.luckperms.common.managers.GenericTrackManager;
@ -243,7 +243,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
// setup context manager // setup context manager
contextManager = new BukkitContextManager(this); contextManager = new BukkitContextManager(this);
contextManager.registerCalculator(new WorldCalculator(this)); contextManager.registerCalculator(new WorldCalculator(this));
contextManager.registerCalculator(new LuckPermsCalculator<>(getConfiguration()), true); contextManager.registerStaticCalculator(new LuckPermsCalculator(getConfiguration()));
// inject our own subscription map // inject our own subscription map
new SubscriptionMapInjector(this).run(); new SubscriptionMapInjector(this).run();
@ -257,7 +257,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
// register with the LP API // register with the LP API
apiProvider = new ApiProvider(this); apiProvider = new ApiProvider(this);
ApiHandler.registerProvider(apiProvider); ApiSingletonUtils.registerProvider(apiProvider);
getServer().getServicesManager().register(LuckPermsApi.class, apiProvider, this, ServicePriority.Normal); getServer().getServicesManager().register(LuckPermsApi.class, apiProvider, this, ServicePriority.Normal);
@ -366,7 +366,7 @@ public class LPBukkitPlugin extends JavaPlugin implements LuckPermsPlugin {
messagingService.close(); messagingService.close();
} }
ApiHandler.unregisterProvider(); ApiSingletonUtils.unregisterProvider();
getServer().getServicesManager().unregisterAll(this); getServer().getServicesManager().unregisterAll(this);
if (vaultHookManager != null) { if (vaultHookManager != null) {

View File

@ -35,7 +35,7 @@ import org.bukkit.entity.Player;
public class BukkitContextManager extends AbstractContextManager<Player> { public class BukkitContextManager extends AbstractContextManager<Player> {
public BukkitContextManager(LPBukkitPlugin plugin) { public BukkitContextManager(LPBukkitPlugin plugin) {
super(plugin); super(plugin, Player.class);
} }
@Override @Override

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>luckperms</artifactId> <artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId> <groupId>me.lucko.luckperms</groupId>
<version>3.4-SNAPSHOT</version> <version>4.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -28,8 +28,7 @@ package me.lucko.luckperms.bungee;
import lombok.Getter; import lombok.Getter;
import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Logger; import me.lucko.luckperms.api.platform.PlatformType;
import me.lucko.luckperms.api.PlatformType;
import me.lucko.luckperms.bungee.calculators.BungeeCalculatorFactory; import me.lucko.luckperms.bungee.calculators.BungeeCalculatorFactory;
import me.lucko.luckperms.bungee.contexts.BackendServerCalculator; import me.lucko.luckperms.bungee.contexts.BackendServerCalculator;
import me.lucko.luckperms.bungee.contexts.BungeeContextManager; import me.lucko.luckperms.bungee.contexts.BungeeContextManager;
@ -39,8 +38,8 @@ import me.lucko.luckperms.bungee.listeners.BungeePermissionCheckListener;
import me.lucko.luckperms.bungee.messaging.BungeeMessagingFactory; import me.lucko.luckperms.bungee.messaging.BungeeMessagingFactory;
import me.lucko.luckperms.bungee.util.RedisBungeeUtil; import me.lucko.luckperms.bungee.util.RedisBungeeUtil;
import me.lucko.luckperms.common.actionlog.LogDispatcher; import me.lucko.luckperms.common.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.ApiHandler;
import me.lucko.luckperms.common.api.ApiProvider; import me.lucko.luckperms.common.api.ApiProvider;
import me.lucko.luckperms.common.api.ApiSingletonUtils;
import me.lucko.luckperms.common.buffers.BufferedRequest; import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.buffers.UpdateTaskBuffer; import me.lucko.luckperms.common.buffers.UpdateTaskBuffer;
import me.lucko.luckperms.common.caching.handlers.CachedStateManager; import me.lucko.luckperms.common.caching.handlers.CachedStateManager;
@ -57,6 +56,7 @@ import me.lucko.luckperms.common.dependencies.DependencyManager;
import me.lucko.luckperms.common.locale.LocaleManager; import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.NoopLocaleManager; import me.lucko.luckperms.common.locale.NoopLocaleManager;
import me.lucko.luckperms.common.locale.SimpleLocaleManager; import me.lucko.luckperms.common.locale.SimpleLocaleManager;
import me.lucko.luckperms.common.logging.Logger;
import me.lucko.luckperms.common.logging.SenderLogger; import me.lucko.luckperms.common.logging.SenderLogger;
import me.lucko.luckperms.common.managers.GenericGroupManager; import me.lucko.luckperms.common.managers.GenericGroupManager;
import me.lucko.luckperms.common.managers.GenericTrackManager; import me.lucko.luckperms.common.managers.GenericTrackManager;
@ -188,15 +188,15 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
// setup context manager // setup context manager
contextManager = new BungeeContextManager(this); contextManager = new BungeeContextManager(this);
contextManager.registerCalculator(new BackendServerCalculator(this)); contextManager.registerCalculator(new BackendServerCalculator(this));
contextManager.registerCalculator(new LuckPermsCalculator<>(getConfiguration()), true); contextManager.registerStaticCalculator(new LuckPermsCalculator(getConfiguration()));
if (getProxy().getPluginManager().getPlugin("RedisBungee") != null) { if (getProxy().getPluginManager().getPlugin("RedisBungee") != null) {
contextManager.registerCalculator(new RedisBungeeCalculator(), true); contextManager.registerStaticCalculator(new RedisBungeeCalculator());
} }
// register with the LP API // register with the LP API
apiProvider = new ApiProvider(this); apiProvider = new ApiProvider(this);
ApiHandler.registerProvider(apiProvider); ApiSingletonUtils.registerProvider(apiProvider);
// schedule update tasks // schedule update tasks
int mins = getConfiguration().get(ConfigKeys.SYNC_TIME); int mins = getConfiguration().get(ConfigKeys.SYNC_TIME);
@ -234,7 +234,7 @@ public class LPBungeePlugin extends Plugin implements LuckPermsPlugin {
messagingService.close(); messagingService.close();
} }
ApiHandler.unregisterProvider(); ApiSingletonUtils.unregisterProvider();
getLog().info("Shutting down internal scheduler..."); getLog().info("Shutting down internal scheduler...");
scheduler.shutdown(); scheduler.shutdown();

View File

@ -35,7 +35,7 @@ import net.md_5.bungee.api.connection.ProxiedPlayer;
public class BungeeContextManager extends AbstractContextManager<ProxiedPlayer> { public class BungeeContextManager extends AbstractContextManager<ProxiedPlayer> {
public BungeeContextManager(LPBungeePlugin plugin) { public BungeeContextManager(LPBungeePlugin plugin) {
super(plugin); super(plugin, ProxiedPlayer.class);
} }
@Override @Override

View File

@ -28,16 +28,14 @@ package me.lucko.luckperms.bungee.contexts;
import com.imaginarycode.minecraft.redisbungee.RedisBungee; import com.imaginarycode.minecraft.redisbungee.RedisBungee;
import com.imaginarycode.minecraft.redisbungee.RedisBungeeAPI; import com.imaginarycode.minecraft.redisbungee.RedisBungeeAPI;
import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.MutableContextSet; import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.api.context.StaticContextCalculator;
import net.md_5.bungee.api.connection.ProxiedPlayer; public class RedisBungeeCalculator implements StaticContextCalculator {
public class RedisBungeeCalculator implements ContextCalculator<ProxiedPlayer> {
private static final String PROXY_KEY = "proxy"; private static final String PROXY_KEY = "proxy";
@Override @Override
public MutableContextSet giveApplicableContext(ProxiedPlayer subject, MutableContextSet accumulator) { public MutableContextSet giveApplicableContext(MutableContextSet accumulator) {
RedisBungeeAPI redisBungee = RedisBungee.getApi(); RedisBungeeAPI redisBungee = RedisBungee.getApi();
if (redisBungee != null) { if (redisBungee != null) {
accumulator.add(PROXY_KEY, redisBungee.getServerId()); accumulator.add(PROXY_KEY, redisBungee.getServerId());

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>luckperms</artifactId> <artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId> <groupId>me.lucko.luckperms</groupId>
<version>3.4-SNAPSHOT</version> <version>4.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -25,6 +25,11 @@
package me.lucko.luckperms.common.actionlog; 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.common.collect.Maps;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
@ -40,94 +45,269 @@ import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.utils.DateUtil; import me.lucko.luckperms.common.utils.DateUtil;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
* An extended version of {@link LogEntry}, with helper methods for * An implementation of {@link LogEntry} and {@link LogEntry.Builder},
* populating and using the entry using internal LuckPerms classes. * with helper methods for populating and using the entry using internal
* LuckPerms classes.
*/
@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 class ExtendedLogEntry extends LogEntry {
public static ExtendedLogEntryBuilder build() { public static ExtendedLogEntryBuilder build() {
return new ExtendedLogEntryBuilder(); return new ExtendedLogEntryBuilder();
} }
public ExtendedLogEntry copy() { private final long timestamp;
return (ExtendedLogEntry) super.copy(); 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) { public void submit(LuckPermsPlugin plugin, Sender sender) {
plugin.getLogDispatcher().dispatch(this, 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;
}
public static Map.Entry<UUID, LogEntry> deserialize(JsonObject object) {
LogEntry.LogEntryBuilder builder = LogEntry.builder();
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());
}
public static class ExtendedLogEntryBuilder extends AbstractLogEntryBuilder<ExtendedLogEntry, ExtendedLogEntryBuilder> {
@Override @Override
protected ExtendedLogEntry createEmptyLog() { public String toString() {
return new ExtendedLogEntry(); return "LogEntry(" +
"timestamp=" + this.getTimestamp() + ", " +
"actor=" + this.getActor() + ", " +
"actorName=" + this.getActorName() + ", " +
"type=" + this.getType() + ", " +
"acted=" + this.getActed() + ", " +
"actedName=" + this.getActedName() + ", " +
"action=" + this.getAction() + ")";
} }
@Override @Override
protected ExtendedLogEntryBuilder getThisBuilder() { public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof LogEntry)) return false;
final LogEntry other = (LogEntry) o;
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());
}
@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
public ExtendedLogEntryBuilder setTimestamp(long timestamp) {
this.timestamp = timestamp;
return this; 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) { public ExtendedLogEntryBuilder actor(Sender actor) {
super.actorName(actor.getNameWithLocation()); actorName(actor.getNameWithLocation());
super.actor(actor.getUuid()); actor(actor.getUuid());
return this; return this;
} }
public ExtendedLogEntryBuilder acted(PermissionHolder acted) { public ExtendedLogEntryBuilder acted(PermissionHolder acted) {
if (acted instanceof User) { if (acted instanceof User) {
super.actedName(((User) acted).getName().orElse("null")); actedName(((User) acted).getName().orElse("null"));
super.acted(((User) acted).getUuid()); acted(((User) acted).getUuid());
super.entryType(Type.USER); type(Type.USER);
} else if (acted instanceof Group) { } else if (acted instanceof Group) {
super.actedName(((Group) acted).getName()); actedName(((Group) acted).getName());
super.entryType(Type.GROUP); type(Type.GROUP);
} }
return this; return this;
} }
public ExtendedLogEntryBuilder acted(Track track) { public ExtendedLogEntryBuilder acted(Track track) {
super.actedName(track.getName()); actedName(track.getName());
super.entryType(Type.TRACK); type(Type.TRACK);
return this; 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; return this;
} }
@Override @Override
public ExtendedLogEntry build() { public ExtendedLogEntry build() {
if (getTimestamp() == 0L) { if (timestamp == 0L) {
super.timestamp(DateUtil.unixSecondsNow()); 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());
}
} }

View File

@ -46,7 +46,7 @@ public class Log {
return new Builder(); 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) { if (pageNo < 1) {
throw new IllegalArgumentException("pageNo cannot be less than 1: " + pageNo); throw new IllegalArgumentException("pageNo cannot be less than 1: " + pageNo);
} }
@ -57,11 +57,11 @@ public class Log {
"Requested: " + minimumEntries + ", Log Count: " + set.size()); "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; final int max = minimumEntries + entries - 1;
int index = 0; int index = 0;
for (LogEntry e : set) { for (ExtendedLogEntry e : set) {
index++; index++;
if (index >= minimumEntries) { if (index >= minimumEntries) {
out.put(index, e); out.put(index, e);
@ -83,17 +83,17 @@ public class Log {
} }
@Getter @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); this.content = ImmutableSortedSet.copyOfSorted(content);
} }
public SortedSet<LogEntry> getRecent() { public SortedSet<ExtendedLogEntry> getRecent() {
return content; return content;
} }
public SortedMap<Integer, LogEntry> getRecent(int pageNo) { public SortedMap<Integer, ExtendedLogEntry> getRecent(int pageNo) {
return getPage(content, pageNo, PAGE_ENTRIES); return getPage(content, pageNo, PAGE_ENTRIES);
} }
@ -101,13 +101,13 @@ public class Log {
return getMaxPages(content.size(), PAGE_ENTRIES); return getMaxPages(content.size(), PAGE_ENTRIES);
} }
public SortedSet<LogEntry> getRecent(UUID actor) { public SortedSet<ExtendedLogEntry> getRecent(UUID actor) {
return content.stream() return content.stream()
.filter(e -> e.getActor().equals(actor)) .filter(e -> e.getActor().equals(actor))
.collect(Collectors.toCollection(TreeSet::new)); .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); return getPage(getRecent(actor), pageNo, PAGE_ENTRIES);
} }
@ -117,69 +117,69 @@ public class Log {
.count(), PAGE_ENTRIES); .count(), PAGE_ENTRIES);
} }
public SortedSet<LogEntry> getUserHistory(UUID uuid) { public SortedSet<ExtendedLogEntry> getUserHistory(UUID uuid) {
return content.stream() 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() != null)
.filter(e -> e.getActed().equals(uuid)) .filter(e -> e.getActed().equals(uuid))
.collect(Collectors.toCollection(TreeSet::new)); .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); return getPage(getUserHistory(uuid), pageNo, PAGE_ENTRIES);
} }
public int getUserHistoryMaxPages(UUID uuid) { public int getUserHistoryMaxPages(UUID uuid) {
return getMaxPages(content.stream() 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() != null)
.filter(e -> e.getActed().equals(uuid)) .filter(e -> e.getActed().equals(uuid))
.count(), PAGE_ENTRIES); .count(), PAGE_ENTRIES);
} }
public SortedSet<LogEntry> getGroupHistory(String name) { public SortedSet<ExtendedLogEntry> getGroupHistory(String name) {
return content.stream() return content.stream()
.filter(e -> e.getEntryType() == LogEntry.Type.GROUP) .filter(e -> e.getType() == LogEntry.Type.GROUP)
.filter(e -> e.getActedName().equals(name)) .filter(e -> e.getActedName().equals(name))
.collect(Collectors.toCollection(TreeSet::new)); .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); return getPage(getGroupHistory(name), pageNo, PAGE_ENTRIES);
} }
public int getGroupHistoryMaxPages(String name) { public int getGroupHistoryMaxPages(String name) {
return getMaxPages(content.stream() return getMaxPages(content.stream()
.filter(e -> e.getEntryType() == LogEntry.Type.GROUP) .filter(e -> e.getType() == LogEntry.Type.GROUP)
.filter(e -> e.getActedName().equals(name)) .filter(e -> e.getActedName().equals(name))
.count(), PAGE_ENTRIES); .count(), PAGE_ENTRIES);
} }
public SortedSet<LogEntry> getTrackHistory(String name) { public SortedSet<ExtendedLogEntry> getTrackHistory(String name) {
return content.stream() return content.stream()
.filter(e -> e.getEntryType() == LogEntry.Type.TRACK) .filter(e -> e.getType() == LogEntry.Type.TRACK)
.filter(e -> e.getActedName().equals(name)) .filter(e -> e.getActedName().equals(name))
.collect(Collectors.toCollection(TreeSet::new)); .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); return getPage(getTrackHistory(name), pageNo, PAGE_ENTRIES);
} }
public int getTrackHistoryMaxPages(String name) { public int getTrackHistoryMaxPages(String name) {
return getMaxPages(content.stream() return getMaxPages(content.stream()
.filter(e -> e.getEntryType() == LogEntry.Type.TRACK) .filter(e -> e.getType() == LogEntry.Type.TRACK)
.filter(e -> e.getActedName().equals(name)) .filter(e -> e.getActedName().equals(name))
.count(), PAGE_ENTRIES); .count(), PAGE_ENTRIES);
} }
public SortedSet<LogEntry> getSearch(String query) { public SortedSet<ExtendedLogEntry> getSearch(String query) {
return content.stream() return content.stream()
.filter(e -> e.matchesSearch(query)) .filter(e -> e.matchesSearch(query))
.collect(Collectors.toCollection(TreeSet::new)); .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); return getPage(getSearch(query), pageNo, PAGE_ENTRIES);
} }
@ -191,9 +191,9 @@ public class Log {
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public static class Builder { 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); content.add(e);
return this; return this;
} }

View File

@ -27,7 +27,6 @@ package me.lucko.luckperms.common.actionlog;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.event.log.LogBroadcastEvent; import me.lucko.luckperms.api.event.log.LogBroadcastEvent;
import me.lucko.luckperms.common.commands.impl.log.LogNotify; import me.lucko.luckperms.common.commands.impl.log.LogNotify;
import me.lucko.luckperms.common.commands.sender.Sender; import me.lucko.luckperms.common.commands.sender.Sender;
@ -43,7 +42,7 @@ import java.util.Optional;
public class LogDispatcher { public class LogDispatcher {
private final LuckPermsPlugin plugin; 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 // set the event to cancelled if the sender is import
if (!plugin.getApiProvider().getEventFactory().handleLogPublish(sender.isImport(), entry)) { if (!plugin.getApiProvider().getEventFactory().handleLogPublish(sender.isImport(), entry)) {
plugin.getStorage().logAction(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)) { if (!plugin.getConfiguration().get(ConfigKeys.BROADCAST_RECEIVED_LOG_ENTRIES)) {
return; return;
} }

View File

@ -25,80 +25,101 @@
package me.lucko.luckperms.common.api; package me.lucko.luckperms.common.api;
import lombok.AccessLevel;
import lombok.Getter; 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.LPConfiguration;
import me.lucko.luckperms.api.Logger; import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.LuckPermsApi; import me.lucko.luckperms.api.LuckPermsApi;
import me.lucko.luckperms.api.MessagingService; import me.lucko.luckperms.api.MessagingService;
import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.NodeFactory; import me.lucko.luckperms.api.NodeFactory;
import me.lucko.luckperms.api.PlatformType;
import me.lucko.luckperms.api.Storage; 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.UuidCache;
import me.lucko.luckperms.api.context.ContextCalculator; import me.lucko.luckperms.api.context.ContextManager;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.event.EventBus;
import me.lucko.luckperms.common.api.delegates.MetaStackFactoryDelegate; import me.lucko.luckperms.api.manager.GroupManager;
import me.lucko.luckperms.common.api.delegates.NodeFactoryDelegate; import me.lucko.luckperms.api.manager.TrackManager;
import me.lucko.luckperms.common.api.delegates.UserDelegate; import me.lucko.luckperms.api.manager.UserManager;
import me.lucko.luckperms.common.contexts.ContextManager; 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.EventFactory;
import me.lucko.luckperms.common.event.LuckPermsEventBus; import me.lucko.luckperms.common.event.LuckPermsEventBus;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; 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.Optional;
import java.util.Set; import java.util.concurrent.CompletableFuture;
import java.util.UUID;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors;
/** /**
* Implements the LuckPerms API using the plugin instance * Implements the LuckPerms API using the plugin instance
*/ */
public class ApiProvider implements LuckPermsApi { public class ApiProvider implements LuckPermsApi {
@Getter(AccessLevel.NONE)
private final LuckPermsPlugin plugin; 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; private final LuckPermsEventBus eventBus;
private final ContextManager contextManager;
@Getter private final MetaStackFactory metaStackFactory;
private final EventFactory eventFactory; private final EventFactory eventFactory;
@Getter
private final MetaStackFactoryDelegate metaStackFactory;
public ApiProvider(LuckPermsPlugin plugin) { public ApiProvider(LuckPermsPlugin plugin) {
this.plugin = 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.eventBus = new LuckPermsEventBus(plugin);
this.contextManager = new ApiContextManager(plugin, plugin.getContextManager());
this.metaStackFactory = new ApiMetaStackFactory(plugin);
this.eventFactory = new EventFactory(eventBus); this.eventFactory = new EventFactory(eventBus);
this.metaStackFactory = new MetaStackFactoryDelegate(plugin); }
public EventFactory getEventFactory() {
return eventFactory;
} }
@Override @Override
public void runUpdateTask() { public PlatformInfo getPlatformInfo() {
plugin.getUpdateTaskBuffer().request(); return platformInfo;
} }
@Override @Override
public double getApiVersion() { public UserManager getUserManager() {
return 3.4; return userManager;
} }
@Override @Override
public String getVersion() { public GroupManager getGroupManager() {
return plugin.getVersion(); return groupManager;
} }
@Override @Override
public PlatformType getPlatformType() { public TrackManager getTrackManager() {
return plugin.getServerType(); return trackManager;
}
@Override
public CompletableFuture<Void> runUpdateTask() {
return plugin.getUpdateTaskBuffer().request();
}
@Override
public EventBus getEventBus() {
return eventBus;
} }
@Override @Override
@ -122,132 +143,22 @@ public class ApiProvider implements LuckPermsApi {
} }
@Override @Override
public Logger getLogger() { public ContextManager getContextManager() {
return plugin.getLog(); return contextManager;
}
@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);
} }
@Override @Override
public NodeFactory getNodeFactory() { public NodeFactory getNodeFactory() {
return NodeFactoryDelegate.INSTANCE; return ApiNodeFactory.INSTANCE;
} }
@Override @Override
public Node.Builder buildNode(@NonNull String permission) throws IllegalArgumentException { public MetaStackFactory getMetaStackFactory() {
return me.lucko.luckperms.common.node.NodeFactory.newBuilder(permission); return metaStackFactory;
}
@SuppressWarnings("unchecked")
@Override
public void registerContextCalculator(@NonNull ContextCalculator<?> contextCalculator) {
ContextManager contextManager = plugin.getContextManager();
contextManager.registerCalculator(contextCalculator);
} }
@Override @Override
public Optional<Contexts> getContextForUser(@NonNull User user) { public LogEntry.Builder newLogEntryBuilder() {
return Optional.ofNullable(plugin.getContextForUser(UserDelegate.cast(user))); return ExtendedLogEntry.build();
}
@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();
} }
} }

View File

@ -30,7 +30,7 @@ import me.lucko.luckperms.api.LuckPermsApi;
import java.lang.reflect.Method; import java.lang.reflect.Method;
public class ApiHandler { public class ApiSingletonUtils {
private static final Method REGISTER; private static final Method REGISTER;
private static final Method UNREGISTER; private static final Method UNREGISTER;
static { static {

View File

@ -50,9 +50,4 @@ public class ApiUtils {
return s.toLowerCase(); 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;
}
} }

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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));
}
}

View File

@ -23,26 +23,34 @@
* SOFTWARE. * SOFTWARE.
*/ */
package me.lucko.luckperms.api.data; package me.lucko.luckperms.common.api.delegates.manager;
import javax.annotation.Nullable; import lombok.AllArgsConstructor;
import lombok.NonNull;
/** import me.lucko.luckperms.api.Group;
* Represents the data section of the main LuckPerms configuration. import me.lucko.luckperms.api.manager.GroupManager;
* All methods could return null.
*/
public interface DatastoreConfiguration {
@Nullable import java.util.Set;
String getAddress(); import java.util.stream.Collectors;
@Nullable @AllArgsConstructor
String getDatabase(); public class ApiGroupManager implements GroupManager {
private final me.lucko.luckperms.common.managers.GroupManager handle;
@Nullable @Override
String getUsername(); public Group getGroup(@NonNull String name) {
me.lucko.luckperms.common.model.Group group = handle.getIfLoaded(name);
return group == null ? null : group.getDelegate();
}
@Nullable @Override
String getPassword(); 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);
}
} }

View File

@ -23,21 +23,34 @@
* SOFTWARE. * SOFTWARE.
*/ */
package me.lucko.luckperms.exceptions; package me.lucko.luckperms.common.api.delegates.manager;
/** import lombok.AllArgsConstructor;
* Thrown when a certain membership state is / isn't met. import lombok.NonNull;
*
* For example, when: import me.lucko.luckperms.api.Track;
* <p></p> import me.lucko.luckperms.api.manager.TrackManager;
* <ul>
* <li>a permission holding object doesn't have a permission</li> import java.util.Set;
* <li>a permission holding object already has a permission</li> import java.util.stream.Collectors;
* <li>a permission holding object is already a member of a group</li>
* <li>a permission holding object isn't already a member of a group</li> @AllArgsConstructor
* </ul> public class ApiTrackManager implements TrackManager {
* private final me.lucko.luckperms.common.managers.TrackManager handle;
* @since 2.7
*/ @Override
public abstract class MembershipException extends Exception { 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);
}
} }

View File

@ -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()));
}
}

View File

@ -23,24 +23,20 @@
* SOFTWARE. * 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.LPConfiguration;
import me.lucko.luckperms.api.data.DatastoreConfiguration;
import me.lucko.luckperms.common.config.ConfigKey; import me.lucko.luckperms.common.config.ConfigKey;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.config.LuckPermsConfiguration; import me.lucko.luckperms.common.config.LuckPermsConfiguration;
import java.util.Map; import java.util.Map;
/** public class ApiConfiguration implements LPConfiguration {
* Provides a link between {@link LPConfiguration} and {@link LuckPermsConfiguration}
*/
public class LPConfigurationDelegate implements LPConfiguration {
private final LuckPermsConfiguration handle; private final LuckPermsConfiguration handle;
private final Unsafe unsafe; private final Unsafe unsafe;
public LPConfigurationDelegate(LuckPermsConfiguration handle) { public ApiConfiguration(LuckPermsConfiguration handle) {
this.handle = handle; this.handle = handle;
this.unsafe = new UnsafeImpl(); this.unsafe = new UnsafeImpl();
} }
@ -50,11 +46,6 @@ public class LPConfigurationDelegate implements LPConfiguration {
return handle.get(ConfigKeys.SERVER); return handle.get(ConfigKeys.SERVER);
} }
@Override
public int getSyncTime() {
return handle.get(ConfigKeys.SYNC_TIME);
}
@Override @Override
public boolean getIncludeGlobalPerms() { public boolean getIncludeGlobalPerms() {
return handle.get(ConfigKeys.INCLUDING_GLOBAL_PERMS); return handle.get(ConfigKeys.INCLUDING_GLOBAL_PERMS);
@ -75,61 +66,6 @@ public class LPConfigurationDelegate implements LPConfiguration {
return handle.get(ConfigKeys.APPLYING_GLOBAL_WORLD_GROUPS); 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 @Override
public String getStorageMethod() { public String getStorageMethod() {
return handle.get(ConfigKeys.STORAGE_METHOD); return handle.get(ConfigKeys.STORAGE_METHOD);

View File

@ -23,7 +23,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
package me.lucko.luckperms.common.api.delegates; package me.lucko.luckperms.common.api.delegates.misc;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.NonNull; import lombok.NonNull;
@ -41,7 +41,7 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
@AllArgsConstructor @AllArgsConstructor
public class MetaStackFactoryDelegate implements MetaStackFactory { public class ApiMetaStackFactory implements MetaStackFactory {
public final LuckPermsPlugin plugin; public final LuckPermsPlugin plugin;
@Override @Override

View File

@ -23,21 +23,21 @@
* SOFTWARE. * SOFTWARE.
*/ */
package me.lucko.luckperms.common.api.delegates; package me.lucko.luckperms.common.api.delegates.misc;
import lombok.NonNull; import lombok.NonNull;
import me.lucko.luckperms.api.ChatMetaType; import me.lucko.luckperms.api.ChatMetaType;
import me.lucko.luckperms.api.Group; import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.api.Node; import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.common.api.delegates.model.ApiGroup;
import me.lucko.luckperms.common.node.NodeFactory; import me.lucko.luckperms.common.node.NodeFactory;
public class NodeFactoryDelegate implements me.lucko.luckperms.api.NodeFactory { public final class ApiNodeFactory implements me.lucko.luckperms.api.NodeFactory {
public static final NodeFactoryDelegate INSTANCE = new NodeFactoryDelegate(); public static final ApiNodeFactory INSTANCE = new ApiNodeFactory();
private ApiNodeFactory() {
@Override
public Node fromSerialisedNode(@NonNull String serialisedPermission, boolean value) {
return NodeFactory.fromSerializedNode(serialisedPermission, value);
} }
@Override @Override
@ -51,13 +51,13 @@ public class NodeFactoryDelegate implements me.lucko.luckperms.api.NodeFactory {
} }
@Override @Override
public Node.Builder newBuilderFromSerialisedNode(@NonNull String serialisedPermission, boolean value) { public Node.Builder makeGroupNode(Group group) {
return NodeFactory.builderFromLegacyString(serialisedPermission, value); return NodeFactory.newBuilder("group." + ApiGroup.cast(group).getName());
} }
@Override @Override
public Node.Builder makeGroupNode(Group group) { public Node.Builder makeGroupNode(String groupName) {
return NodeFactory.newBuilder("group." + GroupDelegate.cast(group).getName()); return NodeFactory.newBuilder("group." + groupName);
} }
@Override @Override

View File

@ -23,18 +23,44 @@
* SOFTWARE. * SOFTWARE.
*/ */
package me.lucko.luckperms.exceptions; package me.lucko.luckperms.common.api.delegates.misc;
/** import lombok.RequiredArgsConstructor;
* Thrown when an object already has something.
* import me.lucko.luckperms.api.platform.PlatformInfo;
* <p>For example, when:</p> import me.lucko.luckperms.api.platform.PlatformType;
* <p></p> import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
* <ul>
* <li>a permission holding object already has a permission</li> import java.util.Collections;
* <li>a permission holding object is already a member of a group</li> import java.util.Set;
* <li>a track already contains a group</li> import java.util.UUID;
* </ul>
*/ @RequiredArgsConstructor
public class ObjectAlreadyHasException extends MembershipException { 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();
}
} }

View File

@ -23,7 +23,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
package me.lucko.luckperms.common.api.delegates; package me.lucko.luckperms.common.api.delegates.misc;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.NonNull; import lombok.NonNull;
@ -32,11 +32,8 @@ import me.lucko.luckperms.api.UuidCache;
import java.util.UUID; import java.util.UUID;
/**
* Provides a link between {@link UuidCache} and {@link me.lucko.luckperms.common.utils.UuidCache}
*/
@AllArgsConstructor @AllArgsConstructor
public class UuidCacheDelegate implements UuidCache { public class ApiUuidCache implements UuidCache {
private final me.lucko.luckperms.common.utils.UuidCache handle; private final me.lucko.luckperms.common.utils.UuidCache handle;
@Override @Override

View File

@ -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();
}
}

View File

@ -23,7 +23,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
package me.lucko.luckperms.common.api.delegates; package me.lucko.luckperms.common.api.delegates.model;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.NonNull; import lombok.NonNull;
@ -37,26 +37,24 @@ import java.util.UUID;
import static me.lucko.luckperms.common.api.ApiUtils.checkName; import static me.lucko.luckperms.common.api.ApiUtils.checkName;
/** @SuppressWarnings("unchecked")
* Provides a link between {@link Log} and {@link me.lucko.luckperms.common.actionlog.Log}
*/
@AllArgsConstructor @AllArgsConstructor
public class LogDelegate implements Log { public class ApiLog implements Log {
private final me.lucko.luckperms.common.actionlog.Log handle; private final me.lucko.luckperms.common.actionlog.Log handle;
@Override @Override
public SortedSet<LogEntry> getContent() { public SortedSet<LogEntry> getContent() {
return handle.getContent(); return (SortedSet) handle.getContent();
} }
@Override @Override
public SortedSet<LogEntry> getRecent() { public SortedSet<LogEntry> getRecent() {
return handle.getRecent(); return (SortedSet) handle.getRecent();
} }
@Override @Override
public SortedMap<Integer, LogEntry> getRecent(int pageNo) { public SortedMap<Integer, LogEntry> getRecent(int pageNo) {
return handle.getRecent(pageNo); return (SortedMap) handle.getRecent(pageNo);
} }
@Override @Override
@ -66,12 +64,12 @@ public class LogDelegate implements Log {
@Override @Override
public SortedSet<LogEntry> getRecent(@NonNull UUID actor) { public SortedSet<LogEntry> getRecent(@NonNull UUID actor) {
return handle.getRecent(actor); return (SortedSet) handle.getRecent(actor);
} }
@Override @Override
public SortedMap<Integer, LogEntry> getRecent(int pageNo, @NonNull UUID actor) { public SortedMap<Integer, LogEntry> getRecent(int pageNo, @NonNull UUID actor) {
return handle.getRecent(pageNo, actor); return (SortedMap) handle.getRecent(pageNo, actor);
} }
@Override @Override
@ -81,12 +79,12 @@ public class LogDelegate implements Log {
@Override @Override
public SortedSet<LogEntry> getUserHistory(@NonNull UUID uuid) { public SortedSet<LogEntry> getUserHistory(@NonNull UUID uuid) {
return handle.getUserHistory(uuid); return (SortedSet) handle.getUserHistory(uuid);
} }
@Override @Override
public SortedMap<Integer, LogEntry> getUserHistory(int pageNo, @NonNull UUID uuid) { public SortedMap<Integer, LogEntry> getUserHistory(int pageNo, @NonNull UUID uuid) {
return handle.getUserHistory(pageNo, uuid); return (SortedMap) handle.getUserHistory(pageNo, uuid);
} }
@Override @Override
@ -96,12 +94,12 @@ public class LogDelegate implements Log {
@Override @Override
public SortedSet<LogEntry> getGroupHistory(@NonNull String name) { public SortedSet<LogEntry> getGroupHistory(@NonNull String name) {
return handle.getGroupHistory(checkName(name)); return (SortedSet) handle.getGroupHistory(checkName(name));
} }
@Override @Override
public SortedMap<Integer, LogEntry> getGroupHistory(int pageNo, @NonNull String name) { public SortedMap<Integer, LogEntry> getGroupHistory(int pageNo, @NonNull String name) {
return handle.getGroupHistory(pageNo, checkName(name)); return (SortedMap) handle.getGroupHistory(pageNo, checkName(name));
} }
@Override @Override
@ -111,12 +109,12 @@ public class LogDelegate implements Log {
@Override @Override
public SortedSet<LogEntry> getTrackHistory(@NonNull String name) { public SortedSet<LogEntry> getTrackHistory(@NonNull String name) {
return handle.getTrackHistory(checkName(name)); return (SortedSet) handle.getTrackHistory(checkName(name));
} }
@Override @Override
public SortedMap<Integer, LogEntry> getTrackHistory(int pageNo, @NonNull String name) { public SortedMap<Integer, LogEntry> getTrackHistory(int pageNo, @NonNull String name) {
return handle.getTrackHistory(pageNo, checkName(name)); return (SortedMap) handle.getTrackHistory(pageNo, checkName(name));
} }
@Override @Override
@ -126,12 +124,12 @@ public class LogDelegate implements Log {
@Override @Override
public SortedSet<LogEntry> getSearch(@NonNull String query) { public SortedSet<LogEntry> getSearch(@NonNull String query) {
return handle.getSearch(query); return (SortedSet) handle.getSearch(query);
} }
@Override @Override
public SortedMap<Integer, LogEntry> getSearch(int pageNo, @NonNull String query) { public SortedMap<Integer, LogEntry> getSearch(int pageNo, @NonNull String query) {
return handle.getSearch(pageNo, query); return (SortedMap) handle.getSearch(pageNo, query);
} }
@Override @Override

View File

@ -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();
}
}

View File

@ -23,7 +23,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
package me.lucko.luckperms.common.api.delegates; package me.lucko.luckperms.common.api.delegates.model;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.NonNull; 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.checkName;
import static me.lucko.luckperms.common.api.ApiUtils.checkUsername; import static me.lucko.luckperms.common.api.ApiUtils.checkUsername;
/**
* Provides a link between {@link Storage} and {@link me.lucko.luckperms.common.storage.Storage}
*/
@AllArgsConstructor @AllArgsConstructor
public class StorageDelegate implements Storage { public class ApiStorage implements Storage {
private final LuckPermsPlugin plugin; private final LuckPermsPlugin plugin;
private final me.lucko.luckperms.common.storage.Storage handle; private final me.lucko.luckperms.common.storage.Storage handle;
@ -84,7 +81,7 @@ public class StorageDelegate implements Storage {
@Override @Override
public CompletableFuture<Log> getLog() { 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 @Override
@ -94,7 +91,7 @@ public class StorageDelegate implements Storage {
@Override @Override
public CompletableFuture<Boolean> saveUser(@NonNull User user) { public CompletableFuture<Boolean> saveUser(@NonNull User user) {
return handle.noBuffer().saveUser(UserDelegate.cast(user)); return handle.noBuffer().saveUser(ApiUser.cast(user));
} }
@Override @Override
@ -124,7 +121,7 @@ public class StorageDelegate implements Storage {
@Override @Override
public CompletableFuture<Boolean> saveGroup(@NonNull Group group) { public CompletableFuture<Boolean> saveGroup(@NonNull Group group) {
return handle.noBuffer().saveGroup(GroupDelegate.cast(group)); return handle.noBuffer().saveGroup(ApiGroup.cast(group));
} }
@Override @Override
@ -132,7 +129,7 @@ public class StorageDelegate implements Storage {
if (group.getName().equalsIgnoreCase(plugin.getConfiguration().get(ConfigKeys.DEFAULT_GROUP_NAME))) { if (group.getName().equalsIgnoreCase(plugin.getConfiguration().get(ConfigKeys.DEFAULT_GROUP_NAME))) {
throw new IllegalArgumentException("Cannot delete the default group."); 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 @Override
@ -157,12 +154,12 @@ public class StorageDelegate implements Storage {
@Override @Override
public CompletableFuture<Boolean> saveTrack(@NonNull Track track) { public CompletableFuture<Boolean> saveTrack(@NonNull Track track) {
return handle.noBuffer().saveTrack(TrackDelegate.cast(track)); return handle.noBuffer().saveTrack(ApiTrack.cast(track));
} }
@Override @Override
public CompletableFuture<Boolean> deleteTrack(@NonNull Track track) { 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 @Override

View File

@ -23,7 +23,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
package me.lucko.luckperms.common.api.delegates; package me.lucko.luckperms.common.api.delegates.model;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
@ -32,21 +32,17 @@ import lombok.NonNull;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import me.lucko.luckperms.api.DataMutateResult;
import me.lucko.luckperms.api.Group; import me.lucko.luckperms.api.Group;
import me.lucko.luckperms.api.Track; import me.lucko.luckperms.api.Track;
import me.lucko.luckperms.exceptions.ObjectAlreadyHasException;
import me.lucko.luckperms.exceptions.ObjectLacksException;
import java.util.List; import java.util.List;
/**
* Provides a link between {@link Track} and {@link me.lucko.luckperms.common.model.Track}
*/
@AllArgsConstructor @AllArgsConstructor
public final class TrackDelegate implements Track { public final class ApiTrack implements Track {
public static me.lucko.luckperms.common.model.Track cast(Track g) { 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."); Preconditions.checkState(g instanceof ApiTrack, "Illegal instance " + g.getClass() + " cannot be handled by this implementation.");
return ((TrackDelegate) g).getHandle(); return ((ApiTrack) g).getHandle();
} }
@Getter(AccessLevel.PACKAGE) @Getter(AccessLevel.PACKAGE)
@ -68,46 +64,46 @@ public final class TrackDelegate implements Track {
} }
@Override @Override
public String getNext(@NonNull Group current) throws ObjectLacksException { public String getNext(@NonNull Group current) {
try { try {
return handle.getNext(GroupDelegate.cast(current)); return handle.getNext(ApiGroup.cast(current));
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new ObjectLacksException(); return null;
} }
} }
@Override @Override
public String getPrevious(@NonNull Group current) throws ObjectLacksException { public String getPrevious(@NonNull Group current) {
try { try {
return handle.getPrevious(GroupDelegate.cast(current)); return handle.getPrevious(ApiGroup.cast(current));
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new ObjectLacksException(); return null;
} }
} }
@Override @Override
public void appendGroup(@NonNull Group group) throws ObjectAlreadyHasException { public DataMutateResult appendGroup(@NonNull Group group) {
handle.appendGroup(GroupDelegate.cast(group)).throwException(); return handle.appendGroup(ApiGroup.cast(group));
} }
@Override @Override
public void insertGroup(@NonNull Group group, @NonNull int position) throws ObjectAlreadyHasException, IndexOutOfBoundsException { public DataMutateResult insertGroup(@NonNull Group group, @NonNull int position) throws IndexOutOfBoundsException {
handle.insertGroup(GroupDelegate.cast(group), position).throwException(); return handle.insertGroup(ApiGroup.cast(group), position);
} }
@Override @Override
public void removeGroup(@NonNull Group group) throws ObjectLacksException { public DataMutateResult removeGroup(@NonNull Group group) {
handle.removeGroup(GroupDelegate.cast(group)).throwException(); return handle.removeGroup(ApiGroup.cast(group));
} }
@Override @Override
public void removeGroup(@NonNull String group) throws ObjectLacksException { public DataMutateResult removeGroup(@NonNull String group) {
handle.removeGroup(group).throwException(); return handle.removeGroup(group);
} }
@Override @Override
public boolean containsGroup(@NonNull Group group) { public boolean containsGroup(@NonNull Group group) {
return handle.containsGroup(GroupDelegate.cast(group)); return handle.containsGroup(ApiGroup.cast(group));
} }
@Override @Override
@ -122,9 +118,9 @@ public final class TrackDelegate implements Track {
public boolean equals(Object o) { public boolean equals(Object o) {
if (o == this) return true; 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); return handle.equals(other.handle);
} }

View File

@ -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();
}
}

View File

@ -71,7 +71,7 @@ public class CreateGroup extends SingleCommand {
Message.CREATE_SUCCESS.send(sender, groupName); 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") .action("create")
.build().submit(plugin, sender); .build().submit(plugin, sender);

View File

@ -80,7 +80,7 @@ public class DeleteGroup extends SingleCommand {
Message.DELETE_SUCCESS.send(sender, group.getFriendlyName()); 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") .action("delete")
.build().submit(plugin, sender); .build().submit(plugin, sender);

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.common.commands.impl.log; 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.actionlog.Log;
import me.lucko.luckperms.common.commands.CommandException; import me.lucko.luckperms.common.commands.CommandException;
import me.lucko.luckperms.common.commands.CommandResult; import me.lucko.luckperms.common.commands.CommandResult;
@ -84,11 +84,11 @@ public class LogGroupHistory extends SubCommand<Log> {
return CommandResult.INVALID_ARGS; 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(); String name = entries.values().stream().findAny().get().getActedName();
Message.LOG_HISTORY_GROUP_HEADER.send(sender, name, page, maxPage); 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 time = e.getValue().getTimestamp();
long now = DateUtil.unixSecondsNow(); long now = DateUtil.unixSecondsNow();
Message.LOG_ENTRY.send(sender, e.getKey(), DateUtil.formatTimeShort(now - time), e.getValue().getFormatted()); Message.LOG_ENTRY.send(sender, e.getKey(), DateUtil.formatTimeShort(now - time), e.getValue().getFormatted());

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.common.commands.impl.log; 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.actionlog.Log;
import me.lucko.luckperms.common.commands.CommandException; import me.lucko.luckperms.common.commands.CommandException;
import me.lucko.luckperms.common.commands.CommandResult; import me.lucko.luckperms.common.commands.CommandResult;
@ -127,7 +127,7 @@ public class LogRecent extends SubCommand<Log> {
return CommandResult.INVALID_ARGS; 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) { if (filter != null) {
String name = entries.values().stream().findAny().get().getActorName(); String name = entries.values().stream().findAny().get().getActorName();
Message.LOG_RECENT_BY_HEADER.send(sender, name, page, maxPage); 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); 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 time = e.getValue().getTimestamp();
long now = DateUtil.unixSecondsNow(); long now = DateUtil.unixSecondsNow();
Message.LOG_ENTRY.send(sender, e.getKey(), DateUtil.formatTimeShort(now - time), e.getValue().getFormatted()); Message.LOG_ENTRY.send(sender, e.getKey(), DateUtil.formatTimeShort(now - time), e.getValue().getFormatted());

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.common.commands.impl.log; 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.actionlog.Log;
import me.lucko.luckperms.common.commands.CommandException; import me.lucko.luckperms.common.commands.CommandException;
import me.lucko.luckperms.common.commands.CommandResult; import me.lucko.luckperms.common.commands.CommandResult;
@ -77,10 +77,10 @@ public class LogSearch extends SubCommand<Log> {
return CommandResult.INVALID_ARGS; 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); 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 time = e.getValue().getTimestamp();
long now = DateUtil.unixSecondsNow(); long now = DateUtil.unixSecondsNow();
Message.LOG_ENTRY.send(sender, e.getKey(), DateUtil.formatTimeShort(now - time), e.getValue().getFormatted()); Message.LOG_ENTRY.send(sender, e.getKey(), DateUtil.formatTimeShort(now - time), e.getValue().getFormatted());

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.common.commands.impl.log; 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.actionlog.Log;
import me.lucko.luckperms.common.commands.CommandException; import me.lucko.luckperms.common.commands.CommandException;
import me.lucko.luckperms.common.commands.CommandResult; import me.lucko.luckperms.common.commands.CommandResult;
@ -84,11 +84,11 @@ public class LogTrackHistory extends SubCommand<Log> {
return CommandResult.INVALID_ARGS; 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(); String name = entries.values().stream().findAny().get().getActedName();
Message.LOG_HISTORY_TRACK_HEADER.send(sender, name, page, maxPage); 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 time = e.getValue().getTimestamp();
long now = DateUtil.unixSecondsNow(); long now = DateUtil.unixSecondsNow();
Message.LOG_ENTRY.send(sender, e.getKey(), DateUtil.formatTimeShort(now - time), e.getValue().getFormatted()); Message.LOG_ENTRY.send(sender, e.getKey(), DateUtil.formatTimeShort(now - time), e.getValue().getFormatted());

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.common.commands.impl.log; 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.actionlog.Log;
import me.lucko.luckperms.common.commands.CommandException; import me.lucko.luckperms.common.commands.CommandException;
import me.lucko.luckperms.common.commands.CommandResult; import me.lucko.luckperms.common.commands.CommandResult;
@ -114,11 +114,11 @@ public class LogUserHistory extends SubCommand<Log> {
return CommandResult.INVALID_ARGS; 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(); String name = entries.values().stream().findAny().get().getActedName();
Message.LOG_HISTORY_USER_HEADER.send(sender, name, page, maxPage); 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 time = e.getValue().getTimestamp();
long now = DateUtil.unixSecondsNow(); long now = DateUtil.unixSecondsNow();
Message.LOG_ENTRY.send(sender, e.getKey(), DateUtil.formatTimeShort(now - time), e.getValue().getFormatted()); Message.LOG_ENTRY.send(sender, e.getKey(), DateUtil.formatTimeShort(now - time), e.getValue().getFormatted());

View File

@ -71,7 +71,7 @@ public class CreateTrack extends SingleCommand {
Message.CREATE_SUCCESS.send(sender, trackName); 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() .action("create").build()
.submit(plugin, sender); .submit(plugin, sender);

View File

@ -73,7 +73,7 @@ public class DeleteTrack extends SingleCommand {
Message.DELETE_SUCCESS.send(sender, trackName); 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") .action("delete")
.build().submit(plugin, sender); .build().submit(plugin, sender);

View File

@ -33,7 +33,7 @@ import com.github.benmanes.caffeine.cache.CacheLoader;
import com.github.benmanes.caffeine.cache.Caffeine; import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.LoadingCache; 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.config.keys.EnduringKey;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
@ -58,7 +58,7 @@ public class AbstractConfiguration implements LuckPermsConfiguration, CacheLoade
// the adapter used to read values // the adapter used to read values
private final ConfigurationAdapter adapter; private final ConfigurationAdapter adapter;
// the api delegate // the api delegate
private final LPConfigurationDelegate delegate = new LPConfigurationDelegate(this); private final ApiConfiguration delegate = new ApiConfiguration(this);
// the contextsfile handler // the contextsfile handler
private final ContextsFile contextsFile = new ContextsFile(this); private final ContextsFile contextsFile = new ContextsFile(this);

View File

@ -25,7 +25,7 @@
package me.lucko.luckperms.common.config; 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; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
/** /**
@ -38,7 +38,7 @@ public interface LuckPermsConfiguration {
* *
* @return the api delegate * @return the api delegate
*/ */
LPConfigurationDelegate getDelegate(); ApiConfiguration getDelegate();
/** /**
* Gets the main plugin instance. * Gets the main plugin instance.

View File

@ -35,6 +35,7 @@ import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.context.ContextCalculator; import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.ImmutableContextSet; import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.MutableContextSet; 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.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
@ -54,8 +55,10 @@ import java.util.stream.Collectors;
public abstract class AbstractContextManager<T> implements ContextManager<T> { public abstract class AbstractContextManager<T> implements ContextManager<T> {
protected final LuckPermsPlugin plugin; protected final LuckPermsPlugin plugin;
private final Class<T> subjectClass;
private final List<ContextCalculator<T>> calculators = new CopyOnWriteArrayList<>(); 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 // caches context lookups
private final LoadingCache<T, Contexts> lookupCache = Caffeine.newBuilder() 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 .expireAfterWrite(50L, TimeUnit.MILLISECONDS) // expire roughly every tick
.build(new Loader()); .build(new Loader());
protected AbstractContextManager(LuckPermsPlugin plugin) { protected AbstractContextManager(LuckPermsPlugin plugin, Class<T> subjectClass) {
this.plugin = plugin; this.plugin = plugin;
this.subjectClass = subjectClass;
}
@Override
public Class<T> getSubjectClass() {
return subjectClass;
} }
@Override @Override
@ -124,13 +133,17 @@ public abstract class AbstractContextManager<T> implements ContextManager<T> {
} }
@Override @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 registered first should have priority (and be checked last.)
calculators.add(0, calculator); 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 @Override

View File

@ -25,11 +25,10 @@
package me.lucko.luckperms.common.contexts; package me.lucko.luckperms.common.contexts;
import lombok.NonNull;
import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.context.ContextCalculator; import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.ImmutableContextSet; import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.StaticContextCalculator;
import java.util.Optional; import java.util.Optional;
@ -42,12 +41,11 @@ import java.util.Optional;
public interface ContextManager<T> { 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 subject class
* @return the applicable context for the subject
*/ */
ImmutableContextSet getApplicableContext(@NonNull T subject); Class<T> getSubjectClass();
/** /**
* Queries the ContextManager for current context values for the subject. * Queries the ContextManager for current context values for the subject.
@ -55,7 +53,15 @@ public interface ContextManager<T> {
* @param subject the subject * @param subject the subject
* @return the applicable context for 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. * Gets the contexts from the static calculators in this manager.
@ -102,24 +108,21 @@ public interface ContextManager<T> {
* *
* @param calculator the calculator * @param calculator the calculator
*/ */
default void registerCalculator(ContextCalculator<T> calculator) { void registerCalculator(ContextCalculator<T> calculator);
registerCalculator(calculator, false);
}
/** /**
* Registers a context calculator with the manager. * Registers a static context calculator with the manager.
* *
* @param calculator the calculator * @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 * Invalidates the lookup cache for a given subject
* *
* @param subject the subject * @param subject the subject
*/ */
void invalidateCache(@NonNull T subject); void invalidateCache(T subject);
/** /**
* Gets the number of calculators registered with the manager. * Gets the number of calculators registered with the manager.

View File

@ -27,17 +27,17 @@ package me.lucko.luckperms.common.contexts;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import me.lucko.luckperms.api.context.ContextCalculator;
import me.lucko.luckperms.api.context.MutableContextSet; 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.ConfigKeys;
import me.lucko.luckperms.common.config.LuckPermsConfiguration; import me.lucko.luckperms.common.config.LuckPermsConfiguration;
@AllArgsConstructor @AllArgsConstructor
public class LuckPermsCalculator<T> implements ContextCalculator<T> { public class LuckPermsCalculator implements StaticContextCalculator {
private final LuckPermsConfiguration config; private final LuckPermsConfiguration config;
@Override @Override
public MutableContextSet giveApplicableContext(T subject, MutableContextSet accumulator) { public MutableContextSet giveApplicableContext(MutableContextSet accumulator) {
String server = config.get(ConfigKeys.SERVER); String server = config.get(ConfigKeys.SERVER);
if (!server.equals("global")) { if (!server.equals("global")) {
accumulator.add("server", server); accumulator.add("server", server);

View File

@ -30,7 +30,7 @@ import lombok.experimental.UtilityClass;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap; 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.config.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.storage.StorageType; import me.lucko.luckperms.common.storage.StorageType;

View File

@ -23,9 +23,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
package me.lucko.luckperms.api; package me.lucko.luckperms.common.logging;
import javax.annotation.Nonnull;
/** /**
* Represents the logger instance being used by LuckPerms on the platform. * Represents the logger instance being used by LuckPerms on the platform.
@ -35,10 +33,10 @@ import javax.annotation.Nonnull;
*/ */
public interface Logger { public interface Logger {
void info(@Nonnull String s); void info(String s);
void warn(@Nonnull String s); void warn(String s);
void severe(@Nonnull String s); void severe(String s);
} }

View File

@ -30,8 +30,6 @@ import lombok.RequiredArgsConstructor;
import me.lucko.luckperms.common.commands.sender.Sender; import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.locale.Message; 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.HashSet;
import java.util.Set; import java.util.Set;
@ -85,16 +83,4 @@ public class ProgressLogger {
logAllProgress(msg, amount); 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();
}
} }

View File

@ -28,7 +28,6 @@ package me.lucko.luckperms.common.logging;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.NonNull; import lombok.NonNull;
import me.lucko.luckperms.api.Logger;
import me.lucko.luckperms.common.commands.sender.Sender; import me.lucko.luckperms.common.commands.sender.Sender;
import me.lucko.luckperms.common.commands.utils.Util; import me.lucko.luckperms.common.commands.utils.Util;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;

View File

@ -96,7 +96,7 @@ public abstract class AbstractMessagingService implements ExtendedMessagingServi
} else if (msg.startsWith("log:") && msg.length() > "log:".length()) { } else if (msg.startsWith("log:") && msg.length() > "log:".length()) {
String logData = msg.substring("log:".length()); String logData = msg.substring("log:".length());
Map.Entry<UUID, LogEntry> entry = null; Map.Entry<UUID, ExtendedLogEntry> entry = null;
try { try {
entry = ExtendedLogEntry.deserialize(gson.fromJson(logData, JsonObject.class)); entry = ExtendedLogEntry.deserialize(gson.fromJson(logData, JsonObject.class));
} catch (Exception e) { } catch (Exception e) {

View File

@ -31,7 +31,7 @@ import lombok.ToString;
import me.lucko.luckperms.api.Node; import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ImmutableContextSet; 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.config.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.references.GroupReference; import me.lucko.luckperms.common.references.GroupReference;
@ -50,7 +50,7 @@ public class Group extends PermissionHolder implements Identifiable<String> {
private final String name; private final String name;
@Getter @Getter
private final GroupDelegate delegate = new GroupDelegate(this); private final ApiGroup delegate = new ApiGroup(this);
public Group(String name, LuckPermsPlugin plugin) { public Group(String name, LuckPermsPlugin plugin) {
super(name, plugin); super(name, plugin);

View File

@ -45,7 +45,7 @@ import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.Tristate; import me.lucko.luckperms.api.Tristate;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet; 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.buffers.Cache;
import me.lucko.luckperms.common.caching.MetaAccumulator; import me.lucko.luckperms.common.caching.MetaAccumulator;
import me.lucko.luckperms.common.caching.handlers.StateListener; import me.lucko.luckperms.common.caching.handlers.StateListener;
@ -262,7 +262,7 @@ public abstract class PermissionHolder {
* *
* @return the api delegate * @return the api delegate
*/ */
public abstract PermissionHolderDelegate getDelegate(); public abstract ApiPermissionHolder getDelegate();
/** /**
* Returns an immutable copy of this objects nodes * Returns an immutable copy of this objects nodes

View File

@ -33,7 +33,7 @@ import lombok.ToString;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import me.lucko.luckperms.api.DataMutateResult; 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.plugin.LuckPermsPlugin;
import me.lucko.luckperms.common.references.Identifiable; 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<>()); private List<String> groups = Collections.synchronizedList(new ArrayList<>());
@Getter @Getter
private final TrackDelegate delegate = new TrackDelegate(this); private final ApiTrack delegate = new ApiTrack(this);
@Override @Override
public String getId() { public String getId() {

View File

@ -30,7 +30,7 @@ import lombok.Getter;
import lombok.ToString; import lombok.ToString;
import me.lucko.luckperms.api.Contexts; 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.buffers.BufferedRequest;
import me.lucko.luckperms.common.caching.UserCache; import me.lucko.luckperms.common.caching.UserCache;
import me.lucko.luckperms.common.config.ConfigKeys; import me.lucko.luckperms.common.config.ConfigKeys;
@ -74,7 +74,7 @@ public class User extends PermissionHolder implements Identifiable<UserIdentifie
private BufferedRequest<Void> refreshBuffer; private BufferedRequest<Void> refreshBuffer;
@Getter @Getter
private final UserDelegate delegate = new UserDelegate(this); private final ApiUser delegate = new ApiUser(this);
public User(UUID uuid, LuckPermsPlugin plugin) { public User(UUID uuid, LuckPermsPlugin plugin) {
super(uuid.toString(), plugin); super(uuid.toString(), plugin);

View File

@ -35,16 +35,11 @@ import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.api.context.ImmutableContextSet; import me.lucko.luckperms.api.context.ImmutableContextSet;
import me.lucko.luckperms.api.context.MutableContextSet; import me.lucko.luckperms.api.context.MutableContextSet;
import me.lucko.luckperms.common.utils.DateUtil; 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.Date;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional; 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; import static com.google.common.base.Preconditions.checkState;
@ -130,8 +125,6 @@ public final class ImmutableNode implements Node {
private final List<String> resolvedShorthand; private final List<String> resolvedShorthand;
private String serializedNode = null;
/** /**
* Make an immutable node instance * Make an immutable node instance
* *
@ -307,119 +300,16 @@ public final class ImmutableNode implements Node {
return suffix; 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 @Override
public boolean shouldApplyWithContext(ContextSet context) { public boolean shouldApplyWithContext(ContextSet context) {
return getFullContexts().isSatisfiedBy(context, false); 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 @Override
public List<String> resolveShorthand() { public List<String> resolveShorthand() {
return resolvedShorthand; 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") @SuppressWarnings("StringEquality")
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
@ -527,46 +417,6 @@ public final class ImmutableNode implements Node {
return getPermission(); 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) { private static String internString(String s) {
return s == null ? null : s.intern(); return s == null ? null : s.intern();
} }

View File

@ -33,7 +33,6 @@ import com.google.common.base.Splitter;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import me.lucko.luckperms.api.ChatMetaType; import me.lucko.luckperms.api.ChatMetaType;
import me.lucko.luckperms.api.MetaUtils;
import me.lucko.luckperms.api.Node; import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ContextSet; import me.lucko.luckperms.api.context.ContextSet;
import me.lucko.luckperms.common.model.Group; 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 Pattern LEGACY_EXPIRY_DELIM = PatternCache.compileDelimitedMatcher("$", "\\");
private static final Splitter LEGACY_EXPIRY_SPLITTER = Splitter.on(LEGACY_EXPIRY_DELIM).limit(2); 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 // caches the conversion between legacy node strings --> node instances
private static final LoadingCache<String, Node> LEGACY_SERIALIZATION_CACHE = Caffeine.newBuilder() private static final LoadingCache<String, Node> LEGACY_SERIALIZATION_CACHE = Caffeine.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES) .expireAfterAccess(10, TimeUnit.MINUTES)
@ -154,7 +155,7 @@ public class NodeFactory {
return makeSuffixNode(100, value); 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) { 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) { 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) { 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) { public static String nodeAsCommand(Node node, String id, boolean group, boolean set) {
@ -262,6 +263,41 @@ public class NodeFactory {
return sb; 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) { public static String escapeDelimiters(String s, String... delims) {
if (s == null) { if (s == null) {
return null; return null;
@ -305,7 +341,7 @@ public class NodeFactory {
if (!metaParts.hasNext()) return null; if (!metaParts.hasNext()) return null;
String value = metaParts.next(); 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) { private static Map.Entry<Integer, String> parseChatMetaNode(String type, String s) {
@ -323,7 +359,7 @@ public class NodeFactory {
try { try {
int p = Integer.parseInt(priority); int p = Integer.parseInt(priority);
String v = MetaUtils.unescapeCharacters(value).intern(); String v = unescapeCharacters(value).intern();
return Maps.immutableEntry(p, v); return Maps.immutableEntry(p, v);
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
return null; return null;

View File

@ -29,8 +29,6 @@ import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
import lombok.Getter; import lombok.Getter;
import com.google.common.collect.Multimap;
import me.lucko.luckperms.api.HeldPermission; import me.lucko.luckperms.api.HeldPermission;
import me.lucko.luckperms.api.Node; import me.lucko.luckperms.api.Node;
import me.lucko.luckperms.api.context.ContextSet; 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(); return node.isTemporary() ? OptionalLong.of(node.getExpiryUnixTime()) : OptionalLong.empty();
} }
@Override
public Multimap<String, String> getContext() {
return node.getContexts().toMultimap();
}
@Override @Override
public ContextSet getContexts() { public ContextSet getContexts() {
return node.getContexts(); return node.getContexts();

View File

@ -26,8 +26,7 @@
package me.lucko.luckperms.common.plugin; package me.lucko.luckperms.common.plugin;
import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.Logger; import me.lucko.luckperms.api.platform.PlatformType;
import me.lucko.luckperms.api.PlatformType;
import me.lucko.luckperms.common.actionlog.LogDispatcher; import me.lucko.luckperms.common.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.ApiProvider; import me.lucko.luckperms.common.api.ApiProvider;
import me.lucko.luckperms.common.buffers.BufferedRequest; 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.contexts.ContextManager;
import me.lucko.luckperms.common.locale.LocaleManager; import me.lucko.luckperms.common.locale.LocaleManager;
import me.lucko.luckperms.common.locale.Message; 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.GroupManager;
import me.lucko.luckperms.common.managers.TrackManager; import me.lucko.luckperms.common.managers.TrackManager;
import me.lucko.luckperms.common.managers.UserManager; import me.lucko.luckperms.common.managers.UserManager;

View File

@ -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.CreationCause;
import me.lucko.luckperms.api.event.cause.DeletionCause; import me.lucko.luckperms.api.event.cause.DeletionCause;
import me.lucko.luckperms.common.actionlog.Log; 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.bulkupdate.BulkUpdate;
import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.Track; import me.lucko.luckperms.common.model.Track;
@ -69,12 +69,12 @@ public class AbstractStorage implements Storage {
private final AbstractDao dao; private final AbstractDao dao;
@Getter @Getter
private final StorageDelegate delegate; private final ApiStorage delegate;
private AbstractStorage(LuckPermsPlugin plugin, AbstractDao dao) { private AbstractStorage(LuckPermsPlugin plugin, AbstractDao dao) {
this.plugin = plugin; this.plugin = plugin;
this.dao = dao; this.dao = dao;
this.delegate = new StorageDelegate(plugin, this); this.delegate = new ApiStorage(plugin, this);
} }
private <T> CompletableFuture<T> makeFuture(Supplier<T> supplier) { private <T> CompletableFuture<T> makeFuture(Supplier<T> supplier) {

View File

@ -30,7 +30,7 @@ import lombok.Getter;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public class DatastoreConfiguration implements me.lucko.luckperms.api.data.DatastoreConfiguration { public class DatastoreConfiguration {
private final String address; private final String address;
private final String database; private final String database;

View File

@ -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.CreationCause;
import me.lucko.luckperms.api.event.cause.DeletionCause; import me.lucko.luckperms.api.event.cause.DeletionCause;
import me.lucko.luckperms.common.actionlog.Log; 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.bulkupdate.BulkUpdate;
import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.Track; import me.lucko.luckperms.common.model.Track;
@ -47,7 +47,7 @@ import java.util.concurrent.CompletableFuture;
*/ */
public interface Storage { public interface Storage {
StorageDelegate getDelegate(); ApiStorage getDelegate();
String getName(); String getName();

View File

@ -290,7 +290,7 @@ public abstract class ConfigurateDao extends AbstractDao {
actionLogger.info(String.format(LOG_FORMAT, actionLogger.info(String.format(LOG_FORMAT,
(entry.getActor().equals(Constants.CONSOLE_UUID) ? "" : entry.getActor() + " "), (entry.getActor().equals(Constants.CONSOLE_UUID) ? "" : entry.getActor() + " "),
entry.getActorName(), entry.getActorName(),
Character.toString(entry.getEntryType().getCode()), Character.toString(entry.getType().getCode()),
(entry.getActed() == null ? "" : entry.getActed().toString() + " "), (entry.getActed() == null ? "" : entry.getActed().toString() + " "),
entry.getActedName(), entry.getActedName(),
entry.getAction()) entry.getAction())

View File

@ -39,6 +39,7 @@ import com.mongodb.client.model.InsertOneOptions;
import me.lucko.luckperms.api.HeldPermission; import me.lucko.luckperms.api.HeldPermission;
import me.lucko.luckperms.api.LogEntry; import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.Node; 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.actionlog.Log;
import me.lucko.luckperms.common.bulkupdate.BulkUpdate; import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
import me.lucko.luckperms.common.managers.GenericUserManager; import me.lucko.luckperms.common.managers.GenericUserManager;
@ -165,7 +166,7 @@ public class MongoDao extends AbstractDao {
.append("timestamp", entry.getTimestamp()) .append("timestamp", entry.getTimestamp())
.append("actor", entry.getActor()) .append("actor", entry.getActor())
.append("actorName", entry.getActorName()) .append("actorName", entry.getActorName())
.append("type", Character.toString(entry.getEntryType().getCode())) .append("type", Character.toString(entry.getType().getCode()))
.append("actedName", entry.getActedName()) .append("actedName", entry.getActedName())
.append("action", entry.getAction()); .append("action", entry.getAction());
@ -195,15 +196,16 @@ public class MongoDao extends AbstractDao {
actedUuid = d.get("acted", UUID.class); actedUuid = d.get("acted", UUID.class);
} }
LogEntry e = new LogEntry( ExtendedLogEntry e = ExtendedLogEntry.build()
d.getLong("timestamp"), .timestamp(d.getLong("timestamp"))
d.get("actor", UUID.class), .actor(d.get("actor", UUID.class))
d.getString("actorName"), .actorName(d.getString("actorName"))
d.getString("type").toCharArray()[0], .type(LogEntry.Type.valueOf(d.getString("type").toCharArray()[0]))
actedUuid, .acted(actedUuid)
d.getString("actedName"), .actedName(d.getString("actedName"))
d.getString("action") .action(d.getString("action"))
); .build();
log.add(e); log.add(e);
} }
} }
@ -750,8 +752,39 @@ public class MongoDao extends AbstractDao {
Map<String, Boolean> m = new HashMap<>(); Map<String, Boolean> m = new HashMap<>();
for (Node node : nodes) { for (Node node : nodes) {
//noinspection deprecation //noinspection deprecation
m.put(node.toSerializedNode(), node.getValuePrimitive()); m.put(toSerializedNode(node), node.getValuePrimitive());
} }
return m; 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();
}
} }

View File

@ -36,6 +36,7 @@ import com.google.gson.reflect.TypeToken;
import me.lucko.luckperms.api.HeldPermission; import me.lucko.luckperms.api.HeldPermission;
import me.lucko.luckperms.api.LogEntry; import me.lucko.luckperms.api.LogEntry;
import me.lucko.luckperms.api.Node; 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.actionlog.Log;
import me.lucko.luckperms.common.bulkupdate.BulkUpdate; import me.lucko.luckperms.common.bulkupdate.BulkUpdate;
import me.lucko.luckperms.common.contexts.ContextSetJsonSerializer; import me.lucko.luckperms.common.contexts.ContextSetJsonSerializer;
@ -232,7 +233,7 @@ public class SqlDao extends AbstractDao {
ps.setLong(1, entry.getTimestamp()); ps.setLong(1, entry.getTimestamp());
ps.setString(2, entry.getActor().toString()); ps.setString(2, entry.getActor().toString());
ps.setString(3, entry.getActorName()); 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(5, String.valueOf(entry.getActed()));
ps.setString(6, entry.getActedName()); ps.setString(6, entry.getActedName());
ps.setString(7, entry.getAction()); ps.setString(7, entry.getAction());
@ -253,15 +254,16 @@ public class SqlDao extends AbstractDao {
try (ResultSet rs = ps.executeQuery()) { try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) { while (rs.next()) {
final String actedUuid = rs.getString("acted_uuid"); final String actedUuid = rs.getString("acted_uuid");
LogEntry e = new LogEntry( ExtendedLogEntry e = ExtendedLogEntry.build()
rs.getLong("time"), .timestamp(rs.getLong("time"))
UUID.fromString(rs.getString("actor_uuid")), .actor(UUID.fromString(rs.getString("actor_uuid")))
rs.getString("actor_name"), .actorName(rs.getString("actor_name"))
rs.getString("type").toCharArray()[0], .type(LogEntry.Type.valueOf(rs.getString("type").toCharArray()[0]))
actedUuid.equals("null") ? null : UUID.fromString(actedUuid), .acted(actedUuid.equals("null") ? null : UUID.fromString(actedUuid))
rs.getString("acted_name"), .actedName(rs.getString("acted_name"))
rs.getString("action") .action(rs.getString("action"))
); .build();
log.add(e); log.add(e);
} }
} }

View File

@ -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.CreationCause;
import me.lucko.luckperms.api.event.cause.DeletionCause; import me.lucko.luckperms.api.event.cause.DeletionCause;
import me.lucko.luckperms.common.actionlog.Log; 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.bulkupdate.BulkUpdate;
import me.lucko.luckperms.common.model.Group; import me.lucko.luckperms.common.model.Group;
import me.lucko.luckperms.common.model.Track; import me.lucko.luckperms.common.model.Track;
@ -292,7 +292,7 @@ public class PhasedStorage implements Storage {
} }
private interface Delegated { private interface Delegated {
StorageDelegate getDelegate(); ApiStorage getDelegate();
String getName(); String getName();
boolean isAcceptingLogins(); boolean isAcceptingLogins();
void setAcceptingLogins(boolean b); void setAcceptingLogins(boolean b);

View File

@ -32,7 +32,7 @@ import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap; import com.google.common.collect.HashBiMap;
import com.google.common.collect.Maps; 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.config.ConfigKeys;
import me.lucko.luckperms.common.plugin.LuckPermsPlugin; import me.lucko.luckperms.common.plugin.LuckPermsPlugin;
@ -49,7 +49,7 @@ public class UuidCache {
private final BiMap<UUID, UUID> cache = Maps.synchronizedBiMap(HashBiMap.create()); private final BiMap<UUID, UUID> cache = Maps.synchronizedBiMap(HashBiMap.create());
@Getter @Getter
private final UuidCacheDelegate delegate = new UuidCacheDelegate(this); private final ApiUuidCache delegate = new ApiUuidCache(this);
public UUID getUUID(UUID external) { public UUID getUUID(UUID external) {
return inUse() ? external : cache.getOrDefault(external, external); return inUse() ? external : cache.getOrDefault(external, external);

View File

@ -6,7 +6,7 @@
<groupId>me.lucko.luckperms</groupId> <groupId>me.lucko.luckperms</groupId>
<artifactId>luckperms</artifactId> <artifactId>luckperms</artifactId>
<version>3.4-SNAPSHOT</version> <version>4.0-SNAPSHOT</version>
<modules> <modules>
<module>api</module> <module>api</module>
@ -47,7 +47,7 @@
<maven.test.skip>true</maven.test.skip> <maven.test.skip>true</maven.test.skip>
<!-- Manually entered release version --> <!-- Manually entered release version -->
<release.version>3.4</release.version> <release.version>4.0</release.version>
<!-- Get how many commits have been made since the last tag (the previous release) --> <!-- Get how many commits have been made since the last tag (the previous release) -->
<patch.version>${git.closest.tag.commit.count}</patch.version> <patch.version>${git.closest.tag.commit.count}</patch.version>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>luckperms</artifactId> <artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId> <groupId>me.lucko.luckperms</groupId>
<version>3.4-SNAPSHOT</version> <version>4.0-SNAPSHOT</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>luckperms</artifactId> <artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId> <groupId>me.lucko.luckperms</groupId>
<version>3.4-SNAPSHOT</version> <version>4.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>luckperms</artifactId> <artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId> <groupId>me.lucko.luckperms</groupId>
<version>3.4-SNAPSHOT</version> <version>4.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>luckperms</artifactId> <artifactId>luckperms</artifactId>
<groupId>me.lucko.luckperms</groupId> <groupId>me.lucko.luckperms</groupId>
<version>3.4-SNAPSHOT</version> <version>4.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath> <relativePath>../../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -31,10 +31,10 @@ import com.google.inject.Inject;
import me.lucko.luckperms.api.Contexts; import me.lucko.luckperms.api.Contexts;
import me.lucko.luckperms.api.LuckPermsApi; import me.lucko.luckperms.api.LuckPermsApi;
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.actionlog.LogDispatcher;
import me.lucko.luckperms.common.api.ApiHandler;
import me.lucko.luckperms.common.api.ApiProvider; import me.lucko.luckperms.common.api.ApiProvider;
import me.lucko.luckperms.common.api.ApiSingletonUtils;
import me.lucko.luckperms.common.backup.ImporterSender; import me.lucko.luckperms.common.backup.ImporterSender;
import me.lucko.luckperms.common.buffers.BufferedRequest; import me.lucko.luckperms.common.buffers.BufferedRequest;
import me.lucko.luckperms.common.buffers.UpdateTaskBuffer; import me.lucko.luckperms.common.buffers.UpdateTaskBuffer;
@ -175,7 +175,7 @@ public class LPSpongePlugin implements LuckPermsPlugin {
private ExtendedMessagingService messagingService = null; private ExtendedMessagingService messagingService = null;
private UuidCache uuidCache; private UuidCache uuidCache;
private ApiProvider apiProvider; private ApiProvider apiProvider;
private me.lucko.luckperms.api.Logger log; private me.lucko.luckperms.common.logging.Logger log;
private LuckPermsService service; private LuckPermsService service;
private LocaleManager localeManager; private LocaleManager localeManager;
private CachedStateManager cachedStateManager; private CachedStateManager cachedStateManager;
@ -247,7 +247,7 @@ public class LPSpongePlugin implements LuckPermsPlugin {
// setup context manager // setup context manager
contextManager = new SpongeContextManager(this); contextManager = new SpongeContextManager(this);
contextManager.registerCalculator(new WorldCalculator(this)); contextManager.registerCalculator(new WorldCalculator(this));
contextManager.registerCalculator(new LuckPermsCalculator<>(getConfiguration()), true); contextManager.registerStaticCalculator(new LuckPermsCalculator(getConfiguration()));
// register the PermissionService with Sponge // register the PermissionService with Sponge
getLog().info("Registering PermissionService..."); getLog().info("Registering PermissionService...");
@ -265,7 +265,7 @@ public class LPSpongePlugin implements LuckPermsPlugin {
// register with the LP API // register with the LP API
apiProvider = new ApiProvider(this); apiProvider = new ApiProvider(this);
ApiHandler.registerProvider(apiProvider); ApiSingletonUtils.registerProvider(apiProvider);
game.getServiceManager().setProvider(this, LuckPermsApi.class, apiProvider); game.getServiceManager().setProvider(this, LuckPermsApi.class, apiProvider);
// schedule update tasks // schedule update tasks
@ -320,7 +320,7 @@ public class LPSpongePlugin implements LuckPermsPlugin {
messagingService.close(); messagingService.close();
} }
ApiHandler.unregisterProvider(); ApiSingletonUtils.unregisterProvider();
getLog().info("Shutting down internal scheduler..."); getLog().info("Shutting down internal scheduler...");
scheduler.shutdown(); scheduler.shutdown();

View File

@ -35,7 +35,7 @@ import org.spongepowered.api.service.permission.Subject;
public class SpongeContextManager extends AbstractContextManager<Subject> { public class SpongeContextManager extends AbstractContextManager<Subject> {
public SpongeContextManager(LPSpongePlugin plugin) { public SpongeContextManager(LPSpongePlugin plugin) {
super(plugin); super(plugin, Subject.class);
} }
@Override @Override