Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
package com.denizenscript.depenizen.bukkit.bridges;

import com.denizenscript.denizencore.DenizenCore;
import com.denizenscript.denizencore.objects.ObjectFetcher;
import com.denizenscript.denizencore.objects.core.ListTag;
import com.denizenscript.denizencore.tags.PseudoObjectTagBase;
import com.denizenscript.denizencore.tags.TagManager;
import com.denizenscript.depenizen.bukkit.Bridge;
import com.denizenscript.depenizen.bukkit.commands.luckperms.LuckPermsCommand;
import com.denizenscript.depenizen.bukkit.objects.luckperms.LuckPermsGroupTag;
import com.denizenscript.depenizen.bukkit.objects.luckperms.LuckPermsTrackTag;
import com.denizenscript.depenizen.bukkit.properties.luckperms.LuckPermsPlayerExtensions;
Expand Down Expand Up @@ -65,6 +67,7 @@ public void register() {
@Override
public void init() {
luckPermsInstance = LuckPermsProvider.get();
DenizenCore.commandRegistry.registerCommand(LuckPermsCommand.class);
LuckPermsPlayerExtensions.register();
ObjectFetcher.registerWithObjectFetcher(LuckPermsGroupTag.class, LuckPermsGroupTag.tagProcessor);
ObjectFetcher.registerWithObjectFetcher(LuckPermsTrackTag.class, LuckPermsTrackTag.tagProcessor);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package com.denizenscript.depenizen.bukkit.commands.luckperms;

import com.denizenscript.denizen.objects.PlayerTag;
import com.denizenscript.denizencore.exceptions.InvalidArgumentsRuntimeException;
import com.denizenscript.denizencore.objects.ObjectTag;
import com.denizenscript.denizencore.objects.core.*;
import com.denizenscript.denizencore.scripts.ScriptEntry;
import com.denizenscript.denizencore.scripts.commands.AbstractCommand;
import com.denizenscript.denizencore.scripts.commands.generator.*;
import com.denizenscript.denizencore.utilities.text.StringHolder;
import com.denizenscript.depenizen.bukkit.bridges.LuckPermsBridge;
import com.denizenscript.depenizen.bukkit.objects.luckperms.LuckPermsGroupTag;
import net.luckperms.api.model.user.User;
import net.luckperms.api.node.Node;
import net.luckperms.api.node.NodeBuilder;

import java.util.Map;
import java.util.concurrent.TimeUnit;

public class LuckPermsCommand extends AbstractCommand {

public LuckPermsCommand() {
setName("luckperms");
setSyntax("luckperms [{set}/unset] [user:<player>/group:<group>] [permission] (state:{true}/false) (duration:<duration>) (contexts:<map>)");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could probably make this take users and groups as ListTag rather than only one value.
Which would allow to do easier things like this rather than foreach:

- luckperms set users:<server.online_players> bonus duration:2h

setRequiredArguments(2, 6);
autoCompile();
}

// <--[command]
// @Name mcMMO
// @Syntax luckperms [{set}/unset] [user:<player>/group:<group>] [permission] (state:{true}/false) (duration:<duration>) (contexts:<map>)
// @Group Depenizen
// @Plugin Depenizen, mcMMO
// @Required 2
// @Maximum 6
// @Short Edits LuckPerms permissions.
//
// @Description
// This command allows you to add or unset permission nodes from players and LuckPerms groups.
//
// The 'duration' argument specifies how long a player or group will have the specified permission
// before it is removed. Not using this argument will result in the permission staying until manually removed.
//
// The 'contexts' argument sets the contexts in which the permission and state specified is active.
// Format is in MapTag format: 'type=value'.
// The 'value' accepts a ListTag for multiple entries of the same key.
//
// @Tags
// <PlayerTag.has_permission[<permission.node>]>
// <PlayerTag.luckperms_permission_expiry[<permission.node>]>
// <LuckPermsGroupTag.has_permission[<permission.node>]>
// <LuckPermsGroupTag.permission_expiry[<permission.node>]>
//
// @Usage
// Use to give a player the 'dscript.help' permission.
// - luckperms set user:<player> dscript.help state:true
//
// @Usage
// Use to give a player the 'dscript.warp' permission for 5 minutes in the main world.
// - luckperms user:<player> dscript.warp duration:5m contexts:[world=world]
//
// @Usage
// Use to disallow a group access to the 'dscript.spawn' permission in the nether and end.
// - luckperms group:<group> dscript.spawn state:false contexts:[dimension_type=the_nether|the_end]
//
// @Usage
// Use to unset the 'dscript.ban' permission back to the default for a player when in survival mode on the hub server.
// - luckperms unset user:<player> dscript.ban contexts:[gamemode=survival;server=hub]
//
// -->

public enum Action {SET, UNSET}

public static void autoExecute(ScriptEntry scriptEntry,
@ArgName("action") @ArgDefaultText("set") Action action,
@ArgName("user") @ArgPrefixed @ArgDefaultNull PlayerTag player,
@ArgName("group") @ArgPrefixed @ArgDefaultNull LuckPermsGroupTag group,
@ArgName("permission") @ArgLinear String permission,
@ArgName("state") @ArgPrefixed @ArgDefaultText("true") boolean state,
@ArgName("duration") @ArgPrefixed @ArgDefaultNull DurationTag duration,
@ArgName("contexts") @ArgPrefixed @ArgDefaultNull MapTag contexts) {
if (player == null && group == null) {
throw new InvalidArgumentsRuntimeException("Must specify either a player or a group!");
}
if (player != null && group != null) {
throw new InvalidArgumentsRuntimeException("Cannot specify both a player and a group!");
}
NodeBuilder<?, ?> nodeBuilder = Node.builder(permission).value(state);
if (duration != null) {
nodeBuilder = nodeBuilder.expiry((long) duration.getSeconds(), TimeUnit.SECONDS);
}
if (contexts != null) {
for (Map.Entry<StringHolder, ObjectTag> entry : contexts.entrySet()) {
for (String value : entry.getValue().asType(ListTag.class, scriptEntry.context)) {
nodeBuilder = nodeBuilder.withContext(entry.getKey().low, value);
}
}
}
Node node = nodeBuilder.build();
switch (action) {
case SET: {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could use that new switch without needing to break it

if (player != null) {
User user = LuckPermsBridge.luckPermsInstance.getUserManager().getUser(player.getUUID());
if (user == null) {
throw new InvalidArgumentsRuntimeException("This user does not exist, have they joined the server before?");
}
user.data().add(node);
LuckPermsBridge.luckPermsInstance.getUserManager().saveUser(user);
}
else {
group.getGroup().data().add(node);
LuckPermsBridge.luckPermsInstance.getGroupManager().saveGroup(group.getGroup());
}
break;
}
case UNSET: {
if (player != null) {
User user = LuckPermsBridge.luckPermsInstance.getUserManager().getUser(player.getUUID());
if (user == null) {
throw new InvalidArgumentsRuntimeException("This user does not exist, have they joined the server before?");
}
user.data().remove(node);
LuckPermsBridge.luckPermsInstance.getUserManager().saveUser(user);
}
else {
group.getGroup().data().remove(node);
LuckPermsBridge.luckPermsInstance.getGroupManager().saveGroup(group.getGroup());
}
break;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@

import com.denizenscript.denizencore.objects.Fetchable;
import com.denizenscript.denizencore.objects.ObjectTag;
import com.denizenscript.denizencore.objects.core.DurationTag;
import com.denizenscript.denizencore.objects.core.ElementTag;
import com.denizenscript.denizencore.tags.Attribute;
import com.denizenscript.denizencore.tags.ObjectTagProcessor;
import com.denizenscript.denizencore.tags.TagContext;
import com.denizenscript.depenizen.bukkit.bridges.LuckPermsBridge;
import net.luckperms.api.model.group.Group;
import net.luckperms.api.node.NodeType;
import net.luckperms.api.node.types.PermissionNode;

import java.util.OptionalInt;

Expand Down Expand Up @@ -153,6 +156,37 @@ public static void register() {
tagProcessor.registerTag(ElementTag.class, ElementTag.class, "has_permission", (attribute, object, p) -> {
return new ElementTag(object.getGroup().getCachedData().getPermissionData().checkPermission(p.asString()).asBoolean());
});

// <--[tag]
// @attribute <LuckPermsGroupTag.permission_expiry[<permission.node>]>
// @returns DurationTag
// @plugin Depenizen, LuckPerms
// @description
// Returns how long a group has a permission for.
// If the group does not have the specific permission set, this will return the time for the closest wildcard permission, if any.
// -->
tagProcessor.registerTag(DurationTag.class, ElementTag.class, "permission_expiry", (attribute, object, p) -> {
String permission = p.asString();
PermissionNode bestNode = null;
int wildcardLevel = 0;
for (PermissionNode node : object.getGroup().getNodes(NodeType.PERMISSION)) {
if (node.getKey().equalsIgnoreCase(permission)) {
bestNode = node;
break;
}
else if (node.isWildcard() && node.getWildcardLevel().isPresent()) {
int size = node.getKey().substring(0, node.getKey().length() - 1).length();
if (permission.length() < size || !permission.substring(0, size).equalsIgnoreCase(node.getKey().substring(0, size))) {
continue;
}
if (node.getWildcardLevel().getAsInt() > wildcardLevel) {
bestNode = node;
wildcardLevel = node.getWildcardLevel().getAsInt();
}
}
}
return bestNode != null ? new DurationTag(bestNode.getExpiryDuration() != null ? (int) bestNode.getExpiryDuration().getSeconds() : 0) : null;
Comment on lines +172 to +188

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could probably extract this to a method since its the same for both tags

});
}

public static ObjectTagProcessor<LuckPermsGroupTag> tagProcessor = new ObjectTagProcessor<>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package com.denizenscript.depenizen.bukkit.properties.luckperms;

import com.denizenscript.denizen.objects.PlayerTag;
import com.denizenscript.denizencore.objects.core.DurationTag;
import com.denizenscript.denizencore.objects.core.ElementTag;
import com.denizenscript.denizencore.objects.core.ListTag;
import com.denizenscript.depenizen.bukkit.bridges.LuckPermsBridge;
import com.denizenscript.depenizen.bukkit.objects.luckperms.LuckPermsGroupTag;
import com.denizenscript.depenizen.bukkit.objects.luckperms.LuckPermsTrackTag;
import net.luckperms.api.model.group.Group;
import net.luckperms.api.model.user.User;
import net.luckperms.api.node.NodeType;
import net.luckperms.api.node.types.PermissionNode;
import net.luckperms.api.query.QueryOptions;
import net.luckperms.api.track.Track;

Expand Down Expand Up @@ -67,5 +70,39 @@ public static void register() {
return new LuckPermsGroupTag(group);
});

// <--[tag]
// @attribute <PlayerTag.luckperms_permission_expiry[<permission.node>]>
// @returns DurationTag
// @plugin Depenizen, LuckPerms
// @description
// Returns how long a player has a permission for.
// If the player does not have the specific permission set, this will return the time for the closest wildcard permission, if any.
// -->
PlayerTag.tagProcessor.registerTag(DurationTag.class, ElementTag.class, "luckperms_permission_expiry", (attribute, player, param) -> {
User user = LuckPermsBridge.luckPermsInstance.getUserManager().getUser(player.getUUID());
if (user == null) {
return null;
}
String permission = param.asString();
PermissionNode bestNode = null;
int wildcardLevel = 0;
for (PermissionNode node : user.getNodes(NodeType.PERMISSION)) {
if (node.getKey().equalsIgnoreCase(permission)) {
bestNode = node;
break;
}
else if (node.isWildcard() && node.getWildcardLevel().isPresent()) {
int size = node.getKey().substring(0, node.getKey().length() - 1).length();
if (permission.length() < size || !permission.substring(0, size).equalsIgnoreCase(node.getKey().substring(0, size))) {
continue;
}
if (node.getWildcardLevel().getAsInt() > wildcardLevel) {
bestNode = node;
wildcardLevel = node.getWildcardLevel().getAsInt();
}
}
}
return bestNode != null ? new DurationTag(bestNode.getExpiryDuration() != null ? (int) bestNode.getExpiryDuration().getSeconds() : 0) : null;
});
}
}