Search in sources :

Example 6 with Track

use of me.lucko.luckperms.common.model.Track in project LuckPerms by lucko.

the class UserPromote method execute.

@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, User user, List<String> args, String label) throws CommandException {
    if (ArgumentPermissions.checkModifyPerms(plugin, sender, getPermission().get(), user)) {
        Message.COMMAND_NO_PERMISSION.send(sender);
        return CommandResult.NO_PERMISSION;
    }
    final String trackName = args.get(0).toLowerCase();
    if (!DataConstraints.TRACK_NAME_TEST.test(trackName)) {
        Message.TRACK_INVALID_ENTRY.send(sender, trackName);
        return CommandResult.INVALID_ARGS;
    }
    Track track = StorageAssistant.loadTrack(trackName, sender, plugin);
    if (track == null) {
        return CommandResult.LOADING_ERROR;
    }
    if (track.getSize() <= 1) {
        Message.TRACK_EMPTY.send(sender, track.getName());
        return CommandResult.STATE_ERROR;
    }
    boolean silent = args.remove("-s");
    MutableContextSet context = ArgumentParser.parseContext(1, args, plugin);
    if (ArgumentPermissions.checkContext(plugin, sender, getPermission().get(), context)) {
        Message.COMMAND_NO_PERMISSION.send(sender);
        return CommandResult.NO_PERMISSION;
    }
    // Load applicable groups
    Set<Node> nodes = user.getEnduringNodes().values().stream().filter(Node::isGroupNode).filter(Node::getValuePrimitive).filter(node -> node.getFullContexts().makeImmutable().equals(context.makeImmutable())).collect(Collectors.toSet());
    nodes.removeIf(g -> !track.containsGroup(g.getGroupName()));
    if (nodes.isEmpty()) {
        String first = track.getGroups().get(0);
        Group nextGroup = plugin.getGroupManager().getIfLoaded(first);
        if (nextGroup == null) {
            Message.USER_PROMOTE_ERROR_MALFORMED.send(sender, first);
            return CommandResult.LOADING_ERROR;
        }
        if (ArgumentPermissions.checkArguments(plugin, sender, getPermission().get(), track.getName(), nextGroup.getName())) {
            Message.COMMAND_NO_PERMISSION.send(sender);
            return CommandResult.NO_PERMISSION;
        }
        user.setPermission(NodeFactory.buildGroupNode(nextGroup.getId()).withExtraContext(context).build());
        Message.USER_TRACK_ADDED_TO_FIRST.send(sender, user.getFriendlyName(), nextGroup.getFriendlyName(), MessageUtils.contextSetToString(context));
        ExtendedLogEntry.build().actor(sender).acted(user).action("promote", track.getName(), context).build().submit(plugin, sender);
        StorageAssistant.save(user, sender, plugin);
        plugin.getEventFactory().handleUserPromote(user, track, null, first, sender);
        return CommandResult.SUCCESS;
    }
    if (nodes.size() != 1) {
        Message.TRACK_AMBIGUOUS_CALL.send(sender, user.getFriendlyName());
        return CommandResult.FAILURE;
    }
    final Node oldNode = nodes.stream().findAny().get();
    final String old = oldNode.getGroupName();
    final String next;
    try {
        next = track.getNext(old);
    } catch (IllegalArgumentException e) {
        Message.TRACK_DOES_NOT_CONTAIN.send(sender, track.getName(), old);
        return CommandResult.STATE_ERROR;
    }
    if (next == null) {
        Message.USER_PROMOTE_ERROR_ENDOFTRACK.send(sender, track.getName(), user.getFriendlyName());
        return CommandResult.STATE_ERROR;
    }
    if (!plugin.getStorage().loadGroup(next).join().isPresent()) {
        Message.USER_PROMOTE_ERROR_MALFORMED.send(sender, next);
        return CommandResult.STATE_ERROR;
    }
    Group nextGroup = plugin.getGroupManager().getIfLoaded(next);
    if (nextGroup == null) {
        Message.USER_PROMOTE_ERROR_MALFORMED.send(sender, next);
        return CommandResult.LOADING_ERROR;
    }
    if (ArgumentPermissions.checkArguments(plugin, sender, getPermission().get(), track.getName(), nextGroup.getName())) {
        Message.COMMAND_NO_PERMISSION.send(sender);
        return CommandResult.NO_PERMISSION;
    }
    user.unsetPermission(oldNode);
    user.setPermission(NodeFactory.buildGroupNode(nextGroup.getName()).withExtraContext(context).build());
    if (context.isEmpty() && user.getPrimaryGroup().getStoredValue().orElse(NodeFactory.DEFAULT_GROUP_NAME).equalsIgnoreCase(old)) {
        user.getPrimaryGroup().setStoredValue(nextGroup.getName());
    }
    Message.USER_PROMOTE_SUCCESS.send(sender, user.getFriendlyName(), track.getName(), old, nextGroup.getFriendlyName(), MessageUtils.contextSetToString(context));
    if (!silent) {
        Message.EMPTY.send(sender, MessageUtils.listToArrowSep(track.getGroups(), old, nextGroup.getName(), false));
    }
    ExtendedLogEntry.build().actor(sender).acted(user).action("promote", track.getName(), context).build().submit(plugin, sender);
    StorageAssistant.save(user, sender, plugin);
    plugin.getEventFactory().handleUserPromote(user, track, old, nextGroup.getName(), sender);
    return CommandResult.SUCCESS;
}
Also used : CommandException(me.lucko.luckperms.common.command.abstraction.CommandException) SubCommand(me.lucko.luckperms.common.command.abstraction.SubCommand) LocaleManager(me.lucko.luckperms.common.locale.LocaleManager) MutableContextSet(me.lucko.luckperms.api.context.MutableContextSet) StorageAssistant(me.lucko.luckperms.common.command.utils.StorageAssistant) ArgumentParser(me.lucko.luckperms.common.command.utils.ArgumentParser) CommandSpec(me.lucko.luckperms.common.locale.command.CommandSpec) Message(me.lucko.luckperms.common.locale.message.Message) LuckPermsPlugin(me.lucko.luckperms.common.plugin.LuckPermsPlugin) ExtendedLogEntry(me.lucko.luckperms.common.actionlog.ExtendedLogEntry) MessageUtils(me.lucko.luckperms.common.command.utils.MessageUtils) Set(java.util.Set) NodeFactory(me.lucko.luckperms.common.node.NodeFactory) Sender(me.lucko.luckperms.common.sender.Sender) Collectors(java.util.stream.Collectors) CommandResult(me.lucko.luckperms.common.command.CommandResult) CommandPermission(me.lucko.luckperms.common.command.access.CommandPermission) Track(me.lucko.luckperms.common.model.Track) List(java.util.List) TabCompletions(me.lucko.luckperms.common.command.utils.TabCompletions) Group(me.lucko.luckperms.common.model.Group) Node(me.lucko.luckperms.api.Node) DataConstraints(me.lucko.luckperms.common.storage.DataConstraints) ArgumentPermissions(me.lucko.luckperms.common.command.access.ArgumentPermissions) User(me.lucko.luckperms.common.model.User) Predicates(me.lucko.luckperms.common.utils.Predicates) Group(me.lucko.luckperms.common.model.Group) MutableContextSet(me.lucko.luckperms.api.context.MutableContextSet) Node(me.lucko.luckperms.api.Node) Track(me.lucko.luckperms.common.model.Track)

Example 7 with Track

use of me.lucko.luckperms.common.model.Track in project LuckPerms by lucko.

the class TrackRename method execute.

@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, Track track, List<String> args, String label) {
    String newTrackName = args.get(0).toLowerCase();
    if (!DataConstraints.TRACK_NAME_TEST.test(newTrackName)) {
        Message.TRACK_INVALID_ENTRY.send(sender, newTrackName);
        return CommandResult.INVALID_ARGS;
    }
    if (plugin.getStorage().loadTrack(newTrackName).join().isPresent()) {
        Message.ALREADY_EXISTS.send(sender, newTrackName);
        return CommandResult.INVALID_ARGS;
    }
    Track newTrack;
    try {
        newTrack = plugin.getStorage().createAndLoadTrack(newTrackName, CreationCause.COMMAND).get();
    } catch (Exception e) {
        e.printStackTrace();
        Message.CREATE_ERROR.send(sender, newTrackName);
        return CommandResult.FAILURE;
    }
    try {
        plugin.getStorage().deleteTrack(track, DeletionCause.COMMAND).get();
    } catch (Exception e) {
        e.printStackTrace();
        Message.DELETE_ERROR.send(sender, track.getName());
        return CommandResult.FAILURE;
    }
    newTrack.setGroups(track.getGroups());
    Message.RENAME_SUCCESS.send(sender, track.getName(), newTrack.getName());
    ExtendedLogEntry.build().actor(sender).acted(track).action("rename", newTrack.getName()).build().submit(plugin, sender);
    StorageAssistant.save(newTrack, sender, plugin);
    return CommandResult.SUCCESS;
}
Also used : Track(me.lucko.luckperms.common.model.Track)

Example 8 with Track

use of me.lucko.luckperms.common.model.Track in project LuckPerms by lucko.

the class Exporter method run.

@Override
public void run() {
    try (BufferedWriter writer = Files.newBufferedWriter(this.filePath, StandardCharsets.UTF_8)) {
        this.log.log("Starting.");
        write(writer, "# LuckPerms Export File");
        write(writer, "# Generated by " + this.executor.getNameWithLocation() + " at " + DATE_FORMAT.format(new Date(System.currentTimeMillis())));
        write(writer, "");
        // Export Groups
        this.log.log("Starting group export.");
        // Create the actual groups first
        write(writer, "# Create groups");
        AtomicInteger groupCount = new AtomicInteger(0);
        List<? extends Group> groups = this.plugin.getGroupManager().getAll().values().stream().sorted((o1, o2) -> {
            int i = Integer.compare(o2.getWeight().orElse(0), o1.getWeight().orElse(0));
            return i != 0 ? i : o1.getName().compareToIgnoreCase(o2.getName());
        }).collect(Collectors.toList());
        for (Group group : groups) {
            if (!group.getName().equals(NodeFactory.DEFAULT_GROUP_NAME)) {
                write(writer, "/lp creategroup " + group.getName());
            }
        }
        for (Group group : groups) {
            if (groupCount.get() == 0) {
                write(writer, "");
            }
            write(writer, "# Export group: " + group.getName());
            for (Node node : group.getEnduringNodes().values()) {
                write(writer, "/lp " + NodeFactory.nodeAsCommand(node, group.getName(), HolderType.GROUP, true));
            }
            write(writer, "");
            this.log.logAllProgress("Exported {} groups so far.", groupCount.incrementAndGet());
        }
        this.log.log("Exported " + groupCount.get() + " groups.");
        write(writer, "");
        write(writer, "");
        // Export tracks
        this.log.log("Starting track export.");
        Collection<? extends Track> tracks = this.plugin.getTrackManager().getAll().values();
        if (!tracks.isEmpty()) {
            // Create the actual tracks first
            write(writer, "# Create tracks");
            for (Track track : tracks) {
                write(writer, "/lp createtrack " + track.getName());
            }
            write(writer, "");
            AtomicInteger trackCount = new AtomicInteger(0);
            for (Track track : this.plugin.getTrackManager().getAll().values()) {
                write(writer, "# Export track: " + track.getName());
                for (String group : track.getGroups()) {
                    write(writer, "/lp track " + track.getName() + " append " + group);
                }
                write(writer, "");
                this.log.logAllProgress("Exported {} tracks so far.", trackCount.incrementAndGet());
            }
            write(writer, "");
            write(writer, "");
        }
        this.log.log("Exported " + tracks.size() + " tracks.");
        // Users are migrated in separate threads.
        // This is because there are likely to be a lot of them, and because we can.
        // It's a big speed improvement, since the database/files are split up and can handle concurrent reads.
        this.log.log("Starting user export. Finding a list of unique users to export.");
        // Find all of the unique users we need to export
        Storage ds = this.plugin.getStorage();
        Set<UUID> users = ds.getUniqueUsers().join();
        this.log.log("Found " + users.size() + " unique users to export.");
        write(writer, "# Export users");
        // divide into 16 pools.
        Cycle<List<UUID>> userPools = new Cycle<>(nInstances(32, ArrayList::new));
        for (UUID uuid : users) {
            userPools.next().add(uuid);
        }
        this.log.log("Split users into " + userPools.getBacking().size() + " threads for export.");
        // Setup a file writing lock. We don't want multiple threads writing at the same time.
        // The write function accepts a list of strings, as we want a user's data to be grouped together.
        // This means it can be processed and added in one go.
        ReentrantLock lock = new ReentrantLock();
        Consumer<List<String>> writeFunction = strings -> {
            lock.lock();
            try {
                for (String s : strings) {
                    write(writer, s);
                }
            } finally {
                lock.unlock();
            }
        };
        // A set of futures, which are really just the threads we need to wait for.
        Set<CompletableFuture<Void>> futures = new HashSet<>();
        AtomicInteger userCount = new AtomicInteger(0);
        // iterate through each user sublist.
        for (List<UUID> subList : userPools.getBacking()) {
            // register and start a new thread to process the sublist
            futures.add(CompletableFuture.runAsync(() -> {
                // iterate through each user in the sublist, and grab their data.
                for (UUID uuid : subList) {
                    try {
                        // actually export the user. this output will be fed to the writing function when we have all of the user's data.
                        List<String> output = new ArrayList<>();
                        User user = this.plugin.getStorage().loadUser(uuid, null).join();
                        output.add("# Export user: " + user.getUuid().toString() + " - " + user.getName().orElse("unknown username"));
                        boolean inDefault = false;
                        for (Node node : user.getEnduringNodes().values()) {
                            if (node.isGroupNode() && node.getGroupName().equalsIgnoreCase(NodeFactory.DEFAULT_GROUP_NAME)) {
                                inDefault = true;
                                continue;
                            }
                            output.add("/lp " + NodeFactory.nodeAsCommand(node, user.getUuid().toString(), HolderType.USER, true));
                        }
                        if (!user.getPrimaryGroup().getStoredValue().orElse(NodeFactory.DEFAULT_GROUP_NAME).equalsIgnoreCase(NodeFactory.DEFAULT_GROUP_NAME)) {
                            output.add("/lp user " + user.getUuid().toString() + " switchprimarygroup " + user.getPrimaryGroup().getStoredValue().get());
                        }
                        if (!inDefault) {
                            output.add("/lp user " + user.getUuid().toString() + " parent remove default");
                        }
                        this.plugin.getUserManager().cleanup(user);
                        writeFunction.accept(output);
                        this.log.logProgress("Exported {} users so far.", userCount.incrementAndGet());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }, this.plugin.getBootstrap().getScheduler().async()));
        }
        // all of the threads have been scheduled now and are running. we just need to wait for them all to complete
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])).join();
        this.log.log("Exported " + userCount.get() + " users.");
        writer.flush();
        this.log.getListeners().forEach(l -> Message.LOG_EXPORT_SUCCESS.send(l, this.filePath.toFile().getAbsolutePath()));
    } catch (Exception e) {
        e.printStackTrace();
    }
}
Also used : Cycle(me.lucko.luckperms.common.utils.Cycle) Date(java.util.Date) SimpleDateFormat(java.text.SimpleDateFormat) CompletableFuture(java.util.concurrent.CompletableFuture) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ProgressLogger(me.lucko.luckperms.common.logging.ProgressLogger) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Message(me.lucko.luckperms.common.locale.message.Message) HolderType(me.lucko.luckperms.common.references.HolderType) Storage(me.lucko.luckperms.common.storage.Storage) LuckPermsPlugin(me.lucko.luckperms.common.plugin.LuckPermsPlugin) Path(java.nio.file.Path) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Files(java.nio.file.Files) BufferedWriter(java.io.BufferedWriter) Collection(java.util.Collection) Set(java.util.Set) IOException(java.io.IOException) NodeFactory(me.lucko.luckperms.common.node.NodeFactory) Sender(me.lucko.luckperms.common.sender.Sender) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) Consumer(java.util.function.Consumer) Track(me.lucko.luckperms.common.model.Track) List(java.util.List) Group(me.lucko.luckperms.common.model.Group) Node(me.lucko.luckperms.api.Node) User(me.lucko.luckperms.common.model.User) Group(me.lucko.luckperms.common.model.Group) User(me.lucko.luckperms.common.model.User) Node(me.lucko.luckperms.api.Node) BufferedWriter(java.io.BufferedWriter) CompletableFuture(java.util.concurrent.CompletableFuture) ArrayList(java.util.ArrayList) List(java.util.List) UUID(java.util.UUID) HashSet(java.util.HashSet) ReentrantLock(java.util.concurrent.locks.ReentrantLock) Date(java.util.Date) Cycle(me.lucko.luckperms.common.utils.Cycle) IOException(java.io.IOException) Storage(me.lucko.luckperms.common.storage.Storage) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Track(me.lucko.luckperms.common.model.Track)

Example 9 with Track

use of me.lucko.luckperms.common.model.Track in project LuckPerms by lucko.

the class ParentClearTrack method execute.

@Override
public CommandResult execute(LuckPermsPlugin plugin, Sender sender, PermissionHolder holder, List<String> args, String label, CommandPermission permission) throws CommandException {
    if (ArgumentPermissions.checkModifyPerms(plugin, sender, permission, holder)) {
        Message.COMMAND_NO_PERMISSION.send(sender);
        return CommandResult.NO_PERMISSION;
    }
    final String trackName = args.get(0).toLowerCase();
    if (!DataConstraints.TRACK_NAME_TEST.test(trackName)) {
        Message.TRACK_INVALID_ENTRY.send(sender, trackName);
        return CommandResult.INVALID_ARGS;
    }
    Track track = StorageAssistant.loadTrack(trackName, sender, plugin);
    if (track == null) {
        return CommandResult.LOADING_ERROR;
    }
    if (track.getSize() <= 1) {
        Message.TRACK_EMPTY.send(sender, track.getName());
        return CommandResult.STATE_ERROR;
    }
    int before = holder.getEnduringNodes().size();
    MutableContextSet context = ArgumentParser.parseContext(1, args, plugin);
    if (ArgumentPermissions.checkContext(plugin, sender, permission, context)) {
        Message.COMMAND_NO_PERMISSION.send(sender);
        return CommandResult.NO_PERMISSION;
    }
    if (ArgumentPermissions.checkArguments(plugin, sender, permission, track.getName())) {
        Message.COMMAND_NO_PERMISSION.send(sender);
        return CommandResult.NO_PERMISSION;
    }
    if (context.isEmpty()) {
        holder.removeIf(node -> node.isGroupNode() && track.containsGroup(node.getGroupName()));
    } else {
        holder.removeIf(node -> node.isGroupNode() && node.getFullContexts().equals(context) && track.containsGroup(node.getGroupName()));
    }
    if (holder.getType().isUser()) {
        plugin.getUserManager().giveDefaultIfNeeded(((User) holder), false);
    }
    int changed = before - holder.getEnduringNodes().size();
    if (changed == 1) {
        Message.PARENT_CLEAR_TRACK_SUCCESS_SINGULAR.send(sender, holder.getFriendlyName(), track.getName(), MessageUtils.contextSetToString(context), changed);
    } else {
        Message.PARENT_CLEAR_TRACK_SUCCESS.send(sender, holder.getFriendlyName(), track.getName(), MessageUtils.contextSetToString(context), changed);
    }
    ExtendedLogEntry.build().actor(sender).acted(holder).action("parent", "cleartrack", track.getName(), context).build().submit(plugin, sender);
    StorageAssistant.save(holder, sender, plugin);
    return CommandResult.SUCCESS;
}
Also used : User(me.lucko.luckperms.common.model.User) MutableContextSet(me.lucko.luckperms.api.context.MutableContextSet) Track(me.lucko.luckperms.common.model.Track)

Example 10 with Track

use of me.lucko.luckperms.common.model.Track in project LuckPerms by lucko.

the class ArgumentPermissions method checkModifyPerms.

/**
 * Checks if the sender has permission to modify the given target
 *
 * @param plugin the plugin instance
 * @param sender the sender to check
 * @param base the base permission for the command
 * @param target the object the sender is truing to modify
 * @return true if the sender should NOT be allowed to modify the target, true if they should
 */
public static boolean checkModifyPerms(LuckPermsPlugin plugin, Sender sender, CommandPermission base, Object target) {
    if (!plugin.getConfiguration().get(ConfigKeys.USE_ARGUMENT_BASED_COMMAND_PERMISSIONS)) {
        return false;
    }
    if (target instanceof User) {
        User targetUser = ((User) target);
        if (targetUser.getUuid().equals(sender.getUuid())) {
            // the sender is trying to edit themselves
            Tristate ret = sender.getPermissionValue(base.getPermission() + ".modify.self");
            if (ret != Tristate.UNDEFINED) {
                return !ret.asBoolean();
            } else {
                // fallback to the global perm if the one for the specific command is undefined
                Tristate globalRet = sender.getPermissionValue(USER_MODIFY_SELF);
                return !globalRet.asBoolean();
            }
        } else {
            // they're trying to edit another user
            Tristate ret = sender.getPermissionValue(base.getPermission() + ".modify.others");
            if (ret != Tristate.UNDEFINED) {
                return !ret.asBoolean();
            } else {
                // fallback to the global perm if the one for the specific command is undefined
                Tristate globalRet = sender.getPermissionValue(USER_MODIFY_OTHERS);
                return !globalRet.asBoolean();
            }
        }
    } else if (target instanceof Group) {
        Group targetGroup = ((Group) target);
        Tristate ret = sender.getPermissionValue(base.getPermission() + ".modify." + targetGroup.getName());
        if (ret != Tristate.UNDEFINED) {
            return !ret.asBoolean();
        } else {
            // fallback to the global perm if the one for the specific command is undefined
            Tristate globalRet = sender.getPermissionValue(GROUP_MODIFY.apply(targetGroup.getName()));
            return !globalRet.asBoolean();
        }
    } else if (target instanceof Track) {
        Track targetTrack = ((Track) target);
        Tristate ret = sender.getPermissionValue(base.getPermission() + ".modify." + targetTrack.getName());
        if (ret != Tristate.UNDEFINED) {
            return !ret.asBoolean();
        } else {
            // fallback to the global perm if the one for the specific command is undefined
            Tristate globalRet = sender.getPermissionValue(TRACK_MODIFY.apply(targetTrack.getName()));
            return !globalRet.asBoolean();
        }
    } else {
        throw new IllegalStateException();
    }
}
Also used : Group(me.lucko.luckperms.common.model.Group) User(me.lucko.luckperms.common.model.User) Tristate(me.lucko.luckperms.api.Tristate) Track(me.lucko.luckperms.common.model.Track)

Aggregations

Track (me.lucko.luckperms.common.model.Track)21 Group (me.lucko.luckperms.common.model.Group)10 User (me.lucko.luckperms.common.model.User)9 List (java.util.List)7 Set (java.util.Set)7 Collectors (java.util.stream.Collectors)7 LuckPermsPlugin (me.lucko.luckperms.common.plugin.LuckPermsPlugin)7 Node (me.lucko.luckperms.api.Node)6 Sender (me.lucko.luckperms.common.sender.Sender)6 CommandResult (me.lucko.luckperms.common.command.CommandResult)5 CommandPermission (me.lucko.luckperms.common.command.access.CommandPermission)5 LocaleManager (me.lucko.luckperms.common.locale.LocaleManager)5 CommandSpec (me.lucko.luckperms.common.locale.command.CommandSpec)5 Message (me.lucko.luckperms.common.locale.message.Message)5 Predicates (me.lucko.luckperms.common.utils.Predicates)5 HashSet (java.util.HashSet)4 UUID (java.util.UUID)4 MutableContextSet (me.lucko.luckperms.api.context.MutableContextSet)4 SubCommand (me.lucko.luckperms.common.command.abstraction.SubCommand)4 MessageUtils (me.lucko.luckperms.common.command.utils.MessageUtils)4