Search in sources :

Example 21 with User

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

the class VaultPermissionHook method userGetPrimaryGroup.

@Override
public String userGetPrimaryGroup(String world, UUID uuid) {
    if (uuid == null) {
        return null;
    }
    User user = getUser(uuid);
    if (user == null) {
        return null;
    }
    String value = user.getPrimaryGroup().getValue();
    Group group = getGroup(value);
    if (group != null) {
        value = group.getDisplayName().orElse(group.getName());
    }
    if (log()) {
        logMsg("#userGetPrimaryGroup: %s - %s - %s", user.getFriendlyName(), world, value);
    }
    return value;
}
Also used : Group(me.lucko.luckperms.common.model.Group) User(me.lucko.luckperms.common.model.User)

Example 22 with User

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

the class VaultPermissionHook method userGetGroups.

@Override
public String[] userGetGroups(String world, UUID uuid) {
    if (uuid == null) {
        return new String[0];
    }
    User user = getUser(uuid);
    if (user == null) {
        return new String[0];
    }
    ContextSet contexts = contextForLookup(user, world).getContexts();
    String[] ret = user.getEnduringNodes().values().stream().filter(Node::isGroupNode).filter(n -> n.shouldApplyWithContext(contexts)).map(n -> {
        Group group = this.plugin.getGroupManager().getIfLoaded(n.getGroupName());
        if (group != null) {
            return group.getDisplayName().orElse(group.getName());
        }
        return n.getGroupName();
    }).toArray(String[]::new);
    if (log()) {
        logMsg("#userGetGroups: %s - %s - %s", user.getFriendlyName(), contexts, Arrays.toString(ret));
    }
    return ret;
}
Also used : ContextSet(me.lucko.luckperms.api.context.ContextSet) MutableContextSet(me.lucko.luckperms.api.context.MutableContextSet) Arrays(java.util.Arrays) CommandManager(me.lucko.luckperms.common.command.CommandManager) CheckOrigin(me.lucko.luckperms.common.verbose.CheckOrigin) Contexts(me.lucko.luckperms.api.Contexts) PermissionHolder(me.lucko.luckperms.common.model.PermissionHolder) Tristate(me.lucko.luckperms.api.Tristate) PermissionCache(me.lucko.luckperms.common.caching.type.PermissionCache) NodeFactory(me.lucko.luckperms.common.node.NodeFactory) Player(org.bukkit.entity.Player) UUID(java.util.UUID) ContextSet(me.lucko.luckperms.api.context.ContextSet) MutableContextSet(me.lucko.luckperms.api.context.MutableContextSet) ConfigKeys(me.lucko.luckperms.common.config.ConfigKeys) Executors(java.util.concurrent.Executors) Objects(java.util.Objects) LPBukkitPlugin(me.lucko.luckperms.bukkit.LPBukkitPlugin) Group(me.lucko.luckperms.common.model.Group) Preconditions(com.google.common.base.Preconditions) Node(me.lucko.luckperms.api.Node) User(me.lucko.luckperms.common.model.User) ExecutorService(java.util.concurrent.ExecutorService) Permission(net.milkbowl.vault.permission.Permission) Group(me.lucko.luckperms.common.model.Group) User(me.lucko.luckperms.common.model.User)

Example 23 with User

use of me.lucko.luckperms.common.model.User 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 24 with User

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

the class BungeeConnectionListener method onPlayerLogin.

@EventHandler(priority = EventPriority.LOW)
public void onPlayerLogin(LoginEvent e) {
    /* Called when the player first attempts a connection with the server.
           Listening on LOW priority to allow plugins to modify username / UUID data here. (auth plugins)

           Delay the login here, as we want to cache UUID data before the player is connected to a backend bukkit server.
           This means that a player will have the same UUID across the network, even if parts of the network are running in
           Offline mode. */
    /* registers the plugins intent to modify this events state going forward.
           this will prevent the event from completing until we're finished handling. */
    e.registerIntent(this.plugin.getBootstrap());
    final PendingConnection c = e.getConnection();
    if (this.plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) {
        this.plugin.getLogger().info("Processing pre-login for " + c.getUniqueId() + " - " + c.getName());
    }
    this.plugin.getBootstrap().getScheduler().doAsync(() -> {
        recordConnection(c.getUniqueId());
        /* Actually process the login for the connection.
               We do this here to delay the login until the data is ready.
               If the login gets cancelled later on, then this will be cleaned up.

               This includes:
               - loading uuid data
               - loading permissions
               - creating a user instance in the UserManager for this connection.
               - setting up cached data. */
        try {
            User user = loadUser(c.getUniqueId(), c.getName());
            this.plugin.getEventFactory().handleUserLoginProcess(c.getUniqueId(), c.getName(), user);
        } catch (Exception ex) {
            this.plugin.getLogger().severe("Exception occurred whilst loading data for " + c.getUniqueId() + " - " + c.getName());
            ex.printStackTrace();
            // there was some error loading
            if (this.plugin.getConfiguration().get(ConfigKeys.CANCEL_FAILED_LOGINS)) {
                // cancel the login attempt
                e.setCancelReason(TextComponent.fromLegacyText(Message.LOADING_ERROR.asString(this.plugin.getLocaleManager())));
                e.setCancelled(true);
            }
        }
        // finally, complete our intent to modify state, so the proxy can continue handling the connection.
        e.completeIntent(this.plugin.getBootstrap());
    });
}
Also used : User(me.lucko.luckperms.common.model.User) PendingConnection(net.md_5.bungee.api.connection.PendingConnection) EventHandler(net.md_5.bungee.event.EventHandler)

Example 25 with User

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

the class BukkitConnectionListener method onPlayerQuit.

// Wait until the last priority to unload, so plugins can still perform permission checks on this event
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerQuit(PlayerQuitEvent e) {
    final Player player = e.getPlayer();
    // Remove the custom permissible
    try {
        PermissibleInjector.unInject(player, true);
    } catch (Exception ex) {
        ex.printStackTrace();
    }
    // Handle auto op
    if (this.plugin.getConfiguration().get(ConfigKeys.AUTO_OP)) {
        player.setOp(false);
    }
    // Register with the housekeeper, so the User's instance will stick
    // around for a bit after they disconnect
    this.plugin.getUserManager().getHouseKeeper().registerUsage(player.getUniqueId());
    // force a clear of transient nodes
    this.plugin.getBootstrap().getScheduler().doAsync(() -> {
        User user = this.plugin.getUserManager().getIfLoaded(player.getUniqueId());
        if (user != null) {
            user.clearTransientNodes();
        }
    });
}
Also used : Player(org.bukkit.entity.Player) User(me.lucko.luckperms.common.model.User) EventHandler(org.bukkit.event.EventHandler)

Aggregations

User (me.lucko.luckperms.common.model.User)67 Group (me.lucko.luckperms.common.model.Group)20 UUID (java.util.UUID)16 Node (me.lucko.luckperms.api.Node)14 Contexts (me.lucko.luckperms.api.Contexts)10 List (java.util.List)9 NodeFactory (me.lucko.luckperms.common.node.NodeFactory)9 Tristate (me.lucko.luckperms.api.Tristate)8 Track (me.lucko.luckperms.common.model.Track)8 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)7 CommandPermission (me.lucko.luckperms.common.command.access.CommandPermission)7 ProgressLogger (me.lucko.luckperms.common.logging.ProgressLogger)7 Sender (me.lucko.luckperms.common.sender.Sender)7 Map (java.util.Map)6 Set (java.util.Set)6 Collectors (java.util.stream.Collectors)6 LuckPermsPlugin (me.lucko.luckperms.common.plugin.LuckPermsPlugin)6 MutableContextSet (me.lucko.luckperms.api.context.MutableContextSet)5 CommandResult (me.lucko.luckperms.common.command.CommandResult)5 SubCommand (me.lucko.luckperms.common.command.abstraction.SubCommand)5