#luckperms-api

1 messages · Page 51 of 1

nocturne elbow
#

both work

safe lance
#

Aight thanks

#

Imma use isPlayerInGroup because I dont need to bother with thenAcceptAsync

nocturne elbow
#

how can i get all users in the db?

undone plover
nocturne elbow
#

You aren't saving the user; you'd probably want to use UserManager::modifyUser(UUID, Consumer<User>) for that

#

It returns a CF so you can chain the messaging update after it

undone plover
#

So if the CF is completed, the user is saved automatically?

nocturne elbow
#

loadUser just loads it to memory, modifyUser will load it, run the provided action and save it

undone plover
#

Okay, thanks

nocturne elbow
#

yw

gilded sky
#

Hello, does someone know how to get the color of any group? I thought of regex [§]. through the name and getting the first result to use as a color from the group displayname?

nocturne elbow
#

Well there isn't really a concept of "group color"

#

Sounds like you should really use meta nodes for this tbh

gilded sky
#

I dont think this still exists right? You know have to use the meta things?

nocturne elbow
#

isn't that you're describing the same thing I just suggested? huh

gilded sky
nocturne elbow
#

in the LP API no idea, if there ever was it's probably ancient

gilded sky
#

I think then ill use the meta thingi now, thanks ^^

steady glade
#

Uhhh srry you were right it was an issue on my end, im dumb 😅

#

Is there anyway to remove the prefix from a players display name, through code or smthing

last sequoia
#

So, I have a plugin that is saving a value to meta when a user disconnects, it is then reading that value when they connect. However, it seems that if the user reconnects to a different server on the Bungee network, the data is not synced. I'm using pluginmsg as my sync method, with MySQL storage, and have LP running on the proxy server and all game servers. If I manually do /lp user <user> meta info the values appear, and if I do that before the plugin reads the data it works, but until that it seems out of sync, any ideas?

neon ravine
#

How would I display LuckPerms rank on scoreboard in DeluxeHub

olive coyote
#

You must make an suffix

wicked token
#

EN текст

trail oar
#

What is the "mojang" part here?

#

that means that the account is premium?

night pier
#

it means it's properly authenticated.

trail oar
#

Can i access that using luckperms api?

#

to check if its mojang or offline

wild whale
#

it's part of the UUID. If it's a type 4 UUID, it's online, if not, offline.

trail oar
hazy solstice
turbid solar
#

Or 2

safe lance
#
public static boolean isPlayerInGroup(Player player, String group) {
    return player.hasPermission("group." + group);
}```If I use this, and the player has OP but isnt in the group, will this return true?
nocturne elbow
#

likely

safe lance
#

Damn ok

nocturne elbow
#

You can back the check with isPermissionSet as well, that checks if it's explicitly set (to either true or false so it's regardless of explicit value)

hybrid panther
#

dont use op alternatively, thats kind of a goal of a permissions plugin

nocturne elbow
#

@hybrid panther @hybrid panther @hybrid panther @hybrid panther

#

Answer me on Instagram

hybrid panther
#

heyyy xxxx

#

x

#

oh wtf

#

ok

#

i dont have app anymore so lemme login via browser OMEGALUL

nocturne elbow
#

Lmao true

scenic mason
#

How do I get the player's prefix via the API?

hybrid panther
scenic mason
#

Does the User variable type support both offline and online players or no?

turbid solar
#

You need to load the user if they’re offline

scenic mason
hybrid panther
#

please read the wiki

scenic mason
hybrid panther
#

try it and see

scenic mason
# hybrid panther try it and see
OfflinePlayer finalOfflineplayer = offlineplayer;
            CompletableFuture<User> offlineuser = api.getUserManager().loadUser(offlineplayer.getUniqueId(), offlineplayer.getName()).thenApplyAsync(user -> {
                String prefix = user.getCachedData().getMetaData().getPrefix();
                plugin.getLogger().info(prefix);
            Inventory stats = Bukkit.createInventory(player, 27, finalOfflineplayer.getName() + "'s Stats");
            ItemStack money = new ItemStack(Material.SUNFLOWER, 1);
            ItemMeta moneymeta = money.getItemMeta();
            moneymeta.setDisplayName(PlaceholderAPI.setPlaceholders(finalOfflineplayer, "Balance: %vault_eco_balance_commas%"));
            money.setItemMeta(moneymeta);
            ItemStack plots = new ItemStack(Material.GRASS_BLOCK, 1);
            ItemMeta plotsmeta = plots.getItemMeta();
            plotsmeta.setDisplayName(PlaceholderAPI.setPlaceholders(finalOfflineplayer, "Plots: %plotsquared_plot_count%/%plotsquared_allowed_plot_count%"));
            plots.setItemMeta(plotsmeta);
            ItemStack Gens = new ItemStack(Material.COAL_BLOCK, 1);
            ItemMeta GensMeta = Gens.getItemMeta();
            GensMeta.setDisplayName(PlaceholderAPI.setPlaceholders(finalOfflineplayer, "Gens: %skript_gencount%/%skript_gencap%"));
            Gens.setItemMeta(GensMeta);
            ItemStack Silos = new ItemStack(Material.DISPENSER, 1);
            ItemMeta SilosMeta = Silos.getItemMeta();
            SilosMeta.setDisplayName(PlaceholderAPI.setPlaceholders(finalOfflineplayer, "Silos: %skript_silo%/10"));
            Silos.setItemMeta(SilosMeta);
            ItemStack Rank = new ItemStack(Material.NAME_TAG, 1);
            ItemMeta RankMeta = Rank.getItemMeta();
            RankMeta.setDisplayName(PlaceholderAPI.setPlaceholders(finalOfflineplayer, "Rank: " + prefix));
            Rank.setItemMeta(RankMeta);
            ItemStack CGlass = new ItemStack(Material.CYAN_STAINED_GLASS_PANE, 1);
            ItemMeta CGlassMeta = CGlass.getItemMeta();
            CGlassMeta.setDisplayName(PlaceholderAPI.setPlaceholders(finalOfflineplayer, " "));
            CGlass.setItemMeta(CGlassMeta);
            ItemStack GGlass = new ItemStack(Material.GRAY_STAINED_GLASS_PANE, 1);
            ItemMeta GGlassMeta = GGlass.getItemMeta();
            GGlassMeta.setDisplayName(PlaceholderAPI.setPlaceholders(finalOfflineplayer, " "));
            ItemStack Skull = new ItemStack(Material.PLAYER_HEAD, 1);
            SkullMeta Skullmeta = (SkullMeta) Skull.getItemMeta();
            Skullmeta.setOwningPlayer(finalOfflineplayer);
            Skullmeta.setDisplayName(ChatColor.WHITE + "Profile: " + finalOfflineplayer.getName());
            Skull.setItemMeta(Skullmeta);
            GGlass.setItemMeta(GGlassMeta);
            stats.setItem(11, money);
            stats.setItem(12, Gens);
            stats.setItem(13, Silos);
            stats.setItem(14, plots);
            stats.setItem(15, Rank);
            stats.setItem(0, CGlass);
            stats.setItem(8, CGlass);
            stats.setItem(18, CGlass);
            stats.setItem(26, CGlass);
            stats.setItem(1, GGlass);
            stats.setItem(2, GGlass);
            stats.setItem(3, GGlass);
            stats.setItem(4, Skull);
            stats.setItem(5, GGlass);
            stats.setItem(6, GGlass);
            stats.setItem(7, GGlass);
            stats.setItem(9, GGlass);
            stats.setItem(10, GGlass);
            stats.setItem(16, GGlass);
            stats.setItem(17, GGlass);
            stats.setItem(19, GGlass);
            stats.setItem(20, GGlass);
            stats.setItem(21, GGlass);
            stats.setItem(22, GGlass);
            stats.setItem(23, GGlass);
            stats.setItem(24, GGlass);
            stats.setItem(25, GGlass);
            player.openInventory(stats);``` It is printing the prefix to the console, but doesn't open the GUI. .-.
hybrid panther
#

this is unfortunately not the place to get java or bukkit help "/

scenic mason
#

When I leave everything out of the accept the prefix variable, prefix becomes null for some reason. .-.

#

But the first time using it after the server restarts/reloads it is defined properly.

#

What?

scenic mason
#

Fixed it. .-.

hybrid panther
#

thats not very cash money of you

warm hazel
#

is there a chance UserDataRecalculateEvent is not called when it's connected to MySQL and change is made on another server with plugin messaging enabled to forward the new data?

jaunty pecan
#

it is only called for users which are already loaded

warm hazel
#

so apparently the user is modifying prefix of a group on other server while the event does not get executed

#

But if I run an arbitrary Luckperms command on server "b" (for example "/lp user ... info") the event is triggered

jaunty pecan
#

hm maybe, that shouldn't happen, but could be a bug

warm hazel
#

I could provide screenshots of all information I was given (or add you to the ticket so you can see for yourself?)

red pumice
#

the luckperms api is super confusing, how can I add a user to a group? I have the User object, what do I do from there. I tried setPrimaryGroup but that didnt work.

hybrid panther
red pumice
#

thank you!

twilit jasper
#

is there a reason group.getDisplayName() would be returning null even though all of my groups have a display name set

clever zodiac
#

@twilit jasper

nocturne elbow
#

wow there's a typo there

#

TWICE

twilit jasper
#

it's?

nocturne elbow
#

yes

twilit jasper
#

heh

clever zodiac
#

it's and servers I presume

#

it's -> its & servers -> server's because active context is a "property" of the "current server" ?

nocturne elbow
#

groups instead of group's

#

oh my

#

this is a disaster

clever zodiac
#

oh yeah groups too kekw

#

ok that's funny

#

time to git blame whoever committed that javadoc

nocturne elbow
#

Luck

#

lol

clever zodiac
#

oh well we can't yell at luck can we

nocturne elbow
#

for a group that returns null there but shouldn't

pastel brook
#

how do I use the API to do the /lp search command?

nocturne elbow
#

UserManager/GroupManager::searchAll(NodeMatcher), see the static factory methods in NodeMatcher to create those

dull rover
#

Another question could be, is there an efficient way to get all player uuids in a group without caring if they are online or offline?

#

Or all players (online or offline) that have a permission?

nocturne elbow
#

I'm fairly certain the lp group .. listmembers uses the same method it uses for lp search

#

Just with a "predefined" node instead, the node for the own group

dull rover
#

Yup that's it

pastel brook
#

thank you 😄

nocturne elbow
#

what a chad

pastel brook
#

no u

long abyss
#

No u

noble fog
#

There's an Event when temp group is expired?

nocturne elbow
#

NodeRemoveEvent, you'd make sure that the event target is a User, that the node is of NodeType.INHERITANCE and that it had an expiry (so you don't mistakenly catch non-temp parent group removals)

warm hazel
#

Any news on UserDataRecalculateEvent not being called when player's group changes on another server? I don't know if I should be bumping, if I was forgotten or not.

clever zodiac
#

hmm what about NodeMutateEvent @warm hazel, couldn't you listen for that and check if "group.x" was removed/added

warm hazel
#

that sounds quite complicated and I am trying to get updated prefix/suffix

jaunty pecan
#

make sure you have an appropriate messaging service configured in the config, and it should be all good

warm hazel
#

apparently it does update the moment you type any LP command

jaunty pecan
#

how is the group being changed on the other server? if not by command?

warm hazel
#

I mean current server will only receive the event if any command, including lp info is used on current server

#

this is how it's configured

jaunty pecan
#

sounds like their messaging service setup isn't working -- fairly easy to debug, LP logs to the console when those syncs are sent/recvd

pastel brook
#
            val user: User = luckPerms.getPlayerAdapter(Player::class.java).getUser(player)
            user.data().add(Node.builder("meteor_location").build())

why is this not actually setting the permission?

[13:07:53 INFO]: [LP] Permission information for meteor_location:
[13:07:53 INFO]: [LP] - partymc does not have meteor_location set.
#

it looks like it is like kinda setting it but not really. whenever luckperms checks to see if it is set, it removes it

#

do i have toi save the changes or somethign

#

that was it, whoops

clever zodiac
#

yeah in the future use user.modifyUser(user -> {})

#

it loads, modifies, and saves for you

pastel brook
#

oic

rustic laurel
#

I think we'd need to see the error you're getting to give constructive input

#

Likely your own plugin saving something about the player (or not saving something) that is causing it, but there's no great way to know

jaunty pecan
#

as Larry said, we cannot help you without seeing the error

#

that string does not appear anywhere in the LP source

#

so it's coming from somewhere else

waxen bay
#

java.lang.ClassCastException: class me.lucko.luckperms.bukkit.loader.BukkitLoaderPlugin cannot be cast to class net.luckperms.api.LuckPerms (me.lucko.luckperms.bukkit.loader.BukkitLoaderPlugin and net.luckperms.api.LuckPerms are in unnamed module of loader 'LuckPerms-Bukkit-5.3.58.jar' @c4960b8)

What does this mean?

public static LuckPerms getLuckPerms() {
        return (LuckPerms) Bukkit.getPluginManager().getPlugin("LuckPerms");
    }

How am I supposed to get the luckperms user if this isn't letting me cast it?

LuckPerms luckperms = getLuckPerms();
User user = luckperms.getPlayerAdapter(OfflinePlayer.class).getUser(player);
nocturne elbow
#

!api

frank driftBOT
waxen bay
#

oh i see, i can just do LuckPermsProvider.get()

nocturne elbow
#

How do I make my name a certain Color in in game chat and in tab?

night pier
#

is that related to LuckPerms' API, or LuckPerms in general?

nocturne elbow
#

I don’t know

#

I don’t know how to do it in new to hosting a server and using plugins

night pier
#

it's not LuckPerms related.

nocturne elbow
#

Do you know how I could do that?

crisp hemlock
#

Hey!
I have a question about the architecture of the LuckPerms software. I find the idea and concept with the platform providers, adapters and hiding everything behind a facade in the API package really nice and want to reuse some parts in a plugin of mine.
However what I don't understand is the reason for the jarinjar loader. What purpose does it serve and how?

wild whale
#

LP does a bunch of classloader hackery to download dependencies at runtime (reduce jar size since spigot etc has a max size) and have them on an isolated classloader to avoid conflicts with other plugins who shade stuff without relocating
However I'm not an expert, there might be other reasons as well / I might be wrong

gaunt hare
#

ooffffff ;-;

#

guyssssssssssssssssssssssssss

#

ffs i lost the dam error

#

did the api namespace change for the 1.18 version? it was a noclassdeffound error or something like that

karmic shadow
#

NoClassDefFound is a libs error usually (never seen a case where it wasnt that)

gaunt hare
#

nvm lol idk wat that was about 🤣 works fine now

final adder
#

Hi, does someones know how to give a player a list of permissions, without calling x times the method from cookbook "addPlayerPermission" ?

I've done that and sometimes one of the 4 calles i've done has not been send

nocturne elbow
#

You can just iterate your set of Nodes and add each one individually inside the modifyUser function // before saving the user

cursive beacon
#

I'm having trouble comprehending how to use the API in my plugin. I've thoroughly read the wiki, but it's still not clear. Thanks in advance!
I'm trying to make a ranks custom plugin for my server, showing a GUI depending on the permission group a player belongs to. In this GUI, they can click a rank to obtain it and add them to the permission group.

#

Would love some help regarding that!

unreal mantle
#

Did you have a look at the API usage page, it shows how to get a users instance and their group

cursive beacon
#

I did... I'm sort of having a hard time understanding though. I'm not a rookie, but I am not very good at coding.

unreal mantle
#

That bit tells you the most simple way to check if a player is in a specfic group

bleak pelican
#

Hello, how can i get the player's highest group with the expiry? I tried it a few times but it didn't work properly.

fringe skiff
#

I am trying to assign a group to a player if they have permission to do so.
For this I am checking if the user has a permission, for example stafftools.toggle.self.admin.
If the user has this permission they're given the appropriate group.

mod: group.mod
admin: group.admin

I am checking the permission via configuration (admin would then become stafftools.toggle.self.<name>, in this case stafftools.toggle.self.admin.

I am using this code to check for permissions,

public boolean hasPermission(User user, String permission) {
    return user.getCachedData().getPermissionData().checkPermission(permission).asBoolean();
  }

and it seems to return true even if the permission is unset.

I have located this issue by simply using a Player.sendMessage("has perm "+permission)

if(hasPermission(user,permissionAssociation.getTogglePerm())) {
        p.sendMessage("has perm "+permissionAssociation.getTogglePerm());```

And I can see in my chat
`has perm stafftools.toggle.self.mod`
However if I do /lp user _kz_n permission info I see this, "group.mod" is given wrongfully by my plugin, it is supposed to be giving "group.admin" insted, i.e. it says I have the permission `stafftools.toggle.self.mod` when in reality i don't.
nocturne elbow
#

Screenshot lp user <user> permission check stafftools.toggle.... please

fringe skiff
#

I managed to fix this

I only changed hasPermission

public boolean hasPermission(User user, String permission) {
    return user.getCachedData().getPermissionData().checkPermission(permission).asBoolean();
  }

Before

public boolean hasPermission(User user, String permission) {
    Map<String, Boolean> map = user.getCachedData().getPermissionData().getPermissionMap();
    if(map.get(permission) != null){
      return map.get(permission);
    } else {
      return false;
    }
  }

After

cursive beacon
#

Hello folks, would love some help on this, if possible.
I'm developing a plugin with a gui where the content of the GUI depends on the permission group a player belongs to.
I'm having trouble creating an if condition where the player enters a command, and depending on which group a player belongs to, it'll give them one gui or another.
I hope I made myself clear. Screenshot of where I've gotten so far.

fringe skiff
#

@cursive beacon I reccomend you use the luckperms (or vault) api for checking permissions as i've had a lot of issues with player.hasPermission

cursive beacon
fringe skiff
neon sparrow
#

i havent used the luckperms api, so cant really help you either, just thought i'd mention its common practice to have packages names lowercase, e.g Events -> events

fringe skiff
#

How can I remove a group from an User?

neon sparrow
#

!cookbook

frank driftBOT
fringe skiff
neon sparrow
#

it has examples of using the luckperms api

fringe skiff
#

i dont see anythin about removing groups

#

It only shows how to add stuff here

karmic shadow
#

use the search, it won't bite

fringe skiff
#

That still doesn't really help me i think... Am i supposed to use NodeRemoveEvent? That's, an event, how would i?

#

Or am i supposed to use User.data().clear(NodeType.INHERITANCE::matches);?

nocturne elbow
#

create the InheritanceNode for the group and call NodeMap#remove

fringe skiff
#

How do I create an InheritanceNode

nocturne elbow
nocturne elbow
#

!api I strongly suggest you read the second page linked

frank driftBOT
fringe skiff
#

Would NodeMap#remove be the equivalent of Group.getNodes().remove()

nocturne elbow
#

you remove the inheritance node from the user's node map

#

the group holds its own nodes in its own map, the user has the parent group as an inheritance node in their own map

fringe skiff
nocturne elbow
#

please read the wiki

hybrid panther
#

And javadocs

fringe skiff
nocturne elbow
#

yes

#

read the section you just linked

fringe skiff
#

Oh, I think i understand.
I'd need to use user.data().remove() and pass an InheritanceNode to that, correct?

nocturne elbow
#

yep

fringe skiff
#
public void addGroup(User user, String group) {
    user.getNodes().add(InheritanceNode.builder(group).build());
    api.getUserManager().saveUser(user);
  }
  public void removeGroup(User user, String group) {
    user.getNodes().remove(InheritanceNode.builder(group).build());
    api.getUserManager().saveUser(user);
  }

My code is this, For some reason if i addGroup it doesn't show any groups, it doesn't assign "add" it.

nocturne elbow
#

we just went over this

#

it's not getNodes

fringe skiff
#

luckpet i overlooked it

cursive beacon
#

Hello there. I am making a switch case in which, when a player click an item from a GUI, depending on which group they belong to, something specific happens.
I have imported the getPlayerGroup method, but I also need a possibleGroups method. How can I do that?

nocturne elbow
#

"possible groups"? what would that return?

cursive beacon
#

The list of different permission groups that I have on my server, I think

nocturne elbow
#

Well LP has GroupManager#getLoadedGroups(), and Vault has Permission#getGroups()

#

pick your poison

cursive beacon
#

This is what it looks like right now. How would I use the GroupManager getLoadedGroups in this case?

nocturne elbow
#

You get the LuckPerms instance, get the group manager and call getLoadedGroups

#

!api

frank driftBOT
trim matrix
#

I have a quick question regarding the luckperms repository.
How is it that LuckPerms can run on a Spigot server but in none of hte 18 different build.gradle scripts does it include the spigot-api as a dependency. Can somebody explain?

nocturne elbow
#

I don't think it takes advantage of any paper-specific features other than that but I may be wrong

trim matrix
#

So Paper plugins run on Spigot?

nocturne elbow
#

if it does the appropriate checks

trim matrix
#

Gotcha, thanks! I thought it was only the other way around

nocturne elbow
#

all (or at least, most) spigot plugins will run on paper, but whether a paper capable plugin runs or not on spigot depends on whether or not it checks if it's running on paper

#

that does not mean "all paper plugins run on spigot", it's basically going out of its way to check if it supports this or that feature before attempting to use them

hybrid panther
#

thats not very cash money of you

buoyant fog
#

When loading the plugin, im getting the warn Loaded class net.luckperms.api.context.ContextCalculator from LuckPerms v5.3.87 which is not a depend, softdepend or loadbefore of this plugin, and when trying to load onto a different server its erroring with org.bukkit.plugin.InvalidPluginException: java.lang.NoClassDefFoundError: net/luckperms/api/context/ContextCalculator.

I assume these are related, how can I fix it?

turbid solar
#

show plugin.yml and your build script

buoyant fog
#
name: StaffPrefixes
version: '${project.version}'
main: dev.elliotfrost.staffprefixes.Main
api-version: 1.17
prefix: Staff Prefixes
authors: [Jelly_exe]
description: Allow staff to hide their staff prefix
website: <excluded>
commands:
  staffprefix:
    description: Hide or Show your staff prefix
    usage: staffprefix
  prefixstatus:
    description: Get the status of the hidden prefix
    usage: prefixstatus

and the jar is getting built by IntelliJ artifacts

neon sparrow
#

use gradle / maven instead of intellij's artifacts

buoyant fog
#

I just used to maven > lifecycle > package on the right, still producing the same warn

neon sparrow
#

share your pom.xml

buoyant fog
#
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>dev.elliotfrost</groupId>
    <artifactId>StaffPrefixes</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>StaffPrefixes</name>

    <description>Allow staff to hide their staff prefix</description>
    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <url>www.elliotfrost.dev</url>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>3.2.4</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <createDependencyReducedPom>false</createDependencyReducedPom>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

    <repositories>
        <repository>
            <id>spigotmc-repo</id>
            <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
        </repository>
        <repository>
            <id>sonatype</id>
            <url>https://oss.sonatype.org/content/groups/public/</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.spigotmc</groupId>
            <artifactId>spigot-api</artifactId>
            <version>1.18-R0.1-SNAPSHOT</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>net.luckperms</groupId>
            <artifactId>api</artifactId>
            <version>5.3</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
</project>
nocturne elbow
#

you need to add LuckPerms as a depend in your plugin.yml

buoyant fog
#

That fixed it, thanks

#

:)

cursive beacon
#

Hey y'all. Having trouble getting an instance of the API in a class. I have used the code provided in the wiki for API Usage, but I'm still not able to get the luckPerms.whatever methods. Screenshot of what I've got:

hybrid panther
#

are you familiar with how java works

#

because youre storing an instance of luckperms api in a variable called "api", yet youre trying to use it as "luckPerms"

#

furthermore, since variable api is initialized in a condition, there is a chance it might not exist, so you should handle that

#

if you hovered the error on line 40 it would tell you the variable luckPerms doesnt exist

cursive beacon
hybrid panther
#

no problem 😄

cursive beacon
#

So by changing, the variable "api" to "luckPerms" I'd be able to get the method work?

#

Wait, I actually don't need to get the Group names anymore, I figured I wouldn't need it

hybrid panther
#

try it and see

#

ok 😄

cursive beacon
#

My new question is, what is the method for removing a permission group and adding another one?

hybrid panther
#

please check the wiki api cookbook

cursive beacon
#

Will do! Thank you

odd vapor
#

how get weight user?

hybrid panther
#

What

odd vapor
#

how I can read this?

night pier
#

You want to get the weight of a group?

odd vapor
#

no only

night pier
#

only what

odd vapor
#

how group have higher weight I want group weight

#

how user have higher weight I want weight user

#

although I am not sure if weight is taken into account by luckperms

#

and idk why I have priority 150 with owner

night pier
#

Users don't get a weight. the 150 there is the weight of the prefix itself.

odd vapor
#

but this have sense?

karmic shadow
#

There are group weights and prefix/suffix weights. Users themselves dont get or have them

odd vapor
#

how I can read the higher weight with group?

#

would you like to make a hierarchy

#

for example that admin cannot ban the owner

#

and i would like to make this system based on luckperms

timber ravine
#

is it safe to fetch user data during login? exactly when COMMANDS packet is about to be sent

real reef
#

Hello, how can I get the prefix string of an offline player with the LuckPerms API ? I tried the code example that's on the website but it doesn't work. Here's my code :

CompletableFuture<net.luckperms.api.model.user.User> userLoadTask = main.getLuckPerms().getUserManager().loadUser(UUID.fromString(nmPlayer.getPlayerUuid()));

userLoadTask.thenAcceptAsync((net.luckperms.api.model.user.User user) -> {
  String prefix = user.getCachedData().getMetaData().getPrefix();
  main.getExecutionManager().setPrefix(prefix);
});```
#

Basically I'm making a part of my plugin which allows messages sent in a discord channel to be also sent to players in game (using a discord bot), displaying the prefix and minecraft username associated with that Discord user, even if they're not currently on the server

nocturne elbow
#

What about that doesn't work?

#

You're not doing anything with the prefix

real reef
#

i'm just storing it somewhere to reuse it later

#

but it gives a blank string basically when the string is printed in the chat

nocturne elbow
#

For every user?

real reef
#

yep

nocturne elbow
#

Can you run and screenshot lp user <uuid> info?

real reef
#

yep

turbid solar
#

Loaduser takes a uuid iirc

#

You’re giving it a uuid string

real reef
#

i'm giving a UUID which is created from a string

turbid solar
#

Oh

#

I’m stupid

real reef
#

here's the lp user info

#

(the prefix is weird because i'm using hex color codes)

nocturne elbow
#

Well I know for a fact that function works… you'll want to do some debugging, e.g. printing stuff like the UUID, the user's nodes, the user's cached data, etc. or attach a debugger to actually inspect what's going on

real reef
#

okay i'm going to investigate further on my own, thanks for the help 🙂

nocturne elbow
#

Yeah with that right there you don't seem to be doing anything wrong, but there's obviously something somewhere going wrong, whether that's something to do with the LP setup you've got or something in your code — but those 3 lines are correct

turbid solar
#

Don’t join

#

.get is better iirc

#

Also why on the main thread?

#

Or just do it async shouldn’t matter that much?

#

xy much

#

depends on the method

#

What method are you talking about

#

Try and see?

nocturne elbow
#

If you're already using CF why can't you just use loadUser thenApply and do w/e?

pulsar heron
#

Is there a way to have prefixes show up on tab and in chat without any other plugins

nocturne elbow
#

!formatting

frank driftBOT
#
LuckPerms does not perform any chat/tablist formatting of its own!

LuckPerms only acts as the source for prefixes / suffixes, it doesn't actually apply them. You need an appropriately configured chat/tablist formatting plugin for them to be displayed. If the values appear correctly when you run /lp user <user> info, LuckPerms is doing its job!

List of chat/tablist formatting plugins that work with LuckPerms
hallow oar
#

Hello. Is there any way to check permissions in specific server?

#

I mean like in the network. For example im in survival server but i want to check player's permission in hub server.

rocky aurora
#

Hey, quick question.

how can I get highest weight parent?

nocturne elbow
nocturne elbow
hallow oar
#

I dont get it

nocturne elbow
#

which part?

hallow oar
#

(QueryOptions)

nocturne elbow
#

There is a method in the CachedDataManager named getPermissionData, that takes QueryOptions as parameter

rocky aurora
nocturne elbow
nocturne elbow
rocky aurora
#
        Collection<Group> inherited = user.getInheritedGroups(user.getQueryOptions());
        
        Group highest = null;
        
        int highestWeight = 0;
        
        for(Group g : inherited)
        {
            int curr = g.getWeight().orElse(0);
            
            if(curr > highestWeight)
            {
                highestWeight = curr;
                highest = g;
            }
        }
#

is this relatively correct?

hallow oar
#

Can you post a quick example? I need to check artizon.staff permission in server hub for a example. 😄

nocturne elbow
rocky aurora
#

so just Group highest = user.getInheritedGroups(user.getQueryOptions()).toArray(Group[]::new)[0];?

#

or stream findFirst

#

not sure if array conversion changes the order

hallow oar
#

in my mind i got it like so: CachedDataManager::getPermissionData("artizon.staff server:hub")

nocturne elbow
rocky aurora
#

oh, well, I suppose it doesn't solve my issue since I can't check when it expires for that player

#
        Instant expiry = user.getNodes().stream()
                .filter(NodeType.INHERITANCE::matches)
                .filter(Node::hasExpiry)
                .map(Node::getExpiry)
                .findFirst().orElse(null);

would this do the trick?

nocturne elbow
#

mmm i don't think those are necessarily ordered in any particular way

rocky aurora
#

I see

nocturne elbow
#

I remember writing a Comparator for sorting InheritanceNodes based on group weights, but i don't have it rn

#

it's basically just node -> getgroupname -> groupmanager::getGroup -> compare weights

hallow oar
#

idk i dont get it. I dont understand how to use it correctly.

#

wait.. i maybe actually got it

hallow oar
nocturne elbow
#

A QueryOptions is a, well, a set of options for querying data, it contains info such as the desired ContextSet to query for and "flags" which determine certain behavior (e.g. whether inheritances should be considered or not)
Taking a closer look at the javadoc, you can simply create the one you want with QueryOptions.contextual(ImmutableContextSet.of("key", "value"))

hallow oar
#

so

#

its a context?

nocturne elbow
#

No, it's not a context, it contains the context required for when querying data, among other things

hallow oar
#

for example i create queryoption QueryOptions.contextual(ImmutableContextSet.of("server", "survival"))

and then how do i get it in the CachedDataManager? Just like so? CachedDataManager::getPermissionData(QueryOptions)

#

thats it?

nocturne elbow
#

user.getCachedData

hallow oar
#

mm

#

Where do i put it?

nocturne elbow
#

wherever you need it?

hallow oar
#

wdym

nocturne elbow
#

you put it wherever you need the thing

#

only you can know that

hallow oar
#

yea but what it does

#

like

#

why i need it tho

#

user.getCachedData().getPermissionData(QueryOptions);

#

you mean it like so?

#

ooo i get it

nocturne elbow
#

and as parameter you pass the query options you created earlier

hallow oar
#

user.getCachedData("artizon.staff").getPermissionData(QueryOptions);

#

something like so?

nocturne elbow
#

are you using notepad or something? your IDE should be yelling at you right now that that is wrong

hallow oar
#

no lmao

nocturne elbow
#

Look, I don't want to come off as condescending but I strongly recommend learning basic java before jumping into LP API or even Minecraft modding

hallow oar
#

okay

nocturne elbow
#

That aside:

  • getCachedData does not take any parameters
  • you need to actually pass a QueryOptions object to the getPermissionData method, that's just the parameter type
  • as to "where do i put this" well, wherever you need it, in your case in the place you need to check for a permission with another context
chilly forum
#

does anyone know how I can make a rank appear higher in the tablist?

#

is that with weight?

night pier
#

It would depend on your tab plugin, which likely has sorting built in.

chilly forum
#

ah we use tab

#

thank you

limpid grove
#

Hello there, i've develloped a class to update a meta:

 public static void setKarma(Player player, int level) {
        LuckPerms luckperms = LuckPermsProvider.get();
        // obtain a User instance (by any means! see above for other ways)
        User user = luckperms.getPlayerAdapter(Player.class).getUser(player);

        // create a new MetaNode holding the level value
        // of course, this can have context/expiry/etc too!
        MetaNode node = MetaNode.builder("dynshopspalier", Integer.toString(level)).build();

        // clear any existing meta nodes with the same key - we want to override
        user.data().clear(NodeType.META.predicate(mn -> mn.getMetaKey().equals("dynshopspalier")));
        // add the new node
        user.data().add(node);

        // save!
        luckperms.getUserManager().saveUser(user);
    }

it works well most of the time, but sometimes the result is the meta removed and the replacing node lost (no error in console).
How can i make sure that the new node is really added?
Thanks

#

this code is always launched with int level values from 0 to 4 (i made sure of that)

#

(from what i've checked the node cannot be updated but only removed/ recreated right?)

nocturne elbow
#

Mm that should work fine unless you're calling it many times right after the other

#

Concurrencyugh

limpid grove
#

yes i do call them manytime (on player click so spaming is possible) i've to learn how to prevent concurrency from 2 separate instances... i know it's basic java, but any thoughts or keywords to search on google to learn that?

nocturne elbow
#

Hmmmm

#

I wouldn't say concurrency is particularly basic😂 uuh

limpid grove
#

i meant not luckperm specific 😉

noble fog
#

I try to use NodeRemoveEvent to modify player's option when specific temp group is expired

#

But Event is not called when I add debug message. Does NodeRemoveEvent needs more options to called?

nocturne elbow
#

please

#

anyone can help me with my server?

long abyss
nocturne elbow
#

ik mate

#

i cant use luckperms

#

idk why

nocturne elbow
gray verge
turbid solar
#

!cookbook

frank driftBOT
gray verge
#

not bukkit

turbid solar
#

Same concept

#

Api is the same on all platforms

nocturne elbow
#

what factors are involved? are you running this on a network? is the player online?

hallow oar
#

Hello again. I know, last time it didnt end well but still, i really need some help!!
Also i changed my mind, i want to check all player's (Like all players on the network) permission in specific server.

I'll explain myself better.

Im really new to coding so yes, im very stupid but i really need to get this to working.
I dont understand, what queryoptions actually does. I dont know how i exactly check the permissions in specific server and how i check all players.
I did learn some java but im still very noob at this and i really appreciate the help.
I propably need some code examples etc.

If you ask, why i need it, then im making a helpop plugin. If player executes /helpop <message> it sends the message to all servers in network but only for players who has the required permission.

clever lichen
#

how can i get the groups that a user has and also its information, like the duration and that

#

like i want to get the groups that the user is on, and also for how much time

limpid grove
wraith estuary
#

Does anyone know why my placeholders dont work

karmic shadow
#

What emily sent was only an example.

wraith estuary
#

why does my placeholder not work?

#

(bungee luckperms)

karmic shadow
#

/papi ecloud download vault
/papi reload

#

Also, this is the api channel for api stuff from luckperms.

#

Next time use the support channel please :3

wraith estuary
#

Alright

#

tab is luckperms 🙂

karmic shadow
#

/papi ecloud download luckperms
/papi reload

wraith estuary
#

did that

#

had it installed already

supple sable
#

I'm trying to make it so that people with a certain group are exempt from an event but i'm confused how I'm meant to do this?

night pier
#

could you not just check if the player has the permission group.<groupname> ?

supple sable
#

Using player.hasPermission or?

night pier
#

i dont see why not

supple sable
#

I'll double check it again but it didn't work for me

#

Found my issue, thanks anyway :D

nocturne elbow
# hallow oar Hello again. I know, last time it didnt end well but still, i really need some h...
ImmutableContextSet context = ImmutableContextSet.of("server", "whichever");
QueryOptions queryOptions = QueryOptions.contextual(context);
CachedPermissionData permissionData = user.getCachedData().getPermissionData(queryOptions);
// can be one of three states: undefined, true or false
Tristate result = permissionData.checkPermission("some.permission");

now where you put this and how you use it only you know that

limpid grove
#

Thanks @nocturne elbow thanks to your help my plugin is working. your idea of single thread was nice and it works

frank driftBOT
#

Hey uharn! Please don't tag helpful/staff members directly.

nocturne elbow
#

sweet

fringe skiff
#

How would one go about get the user's current prefix?

long abyss
#

/lp info [user]

fringe skiff
#

..with the api

nocturne elbow
#

!cookbook

frank driftBOT
fringe skiff
#

thanks

half glen
#

!api

frank driftBOT
half glen
#

!placeholder

frank driftBOT
#

Sorry! I do not understand the command placeholder Did you mean placeholders?
Type !help for a list of commands

nocturne elbow
#

!help

frank driftBOT
#
Available commands

!advanced
!api
!argumentbased
!ask
!bulkupdate
!bungee
!bungeecheck
!cauldron
!colours
!commandequivalents
!commands
!config
!context
!cookbook
!default
!downloads
!editor
!editorsafety
!errors
!essentials
!extensions
!extracontexts
!faq
!formatting
!hack
!helpchat
!inheritance
!install
!libsdir

!locale
!meta
!migration
!notworking
!nowildcard
!offline
!pasteit
!permissions
!placeholders
!selfhosting
!stacking
!storage
!suggestions
!switchstorage
!sync
!testingperms
!tracks
!translationprogress
!translations
!tutorial
!upgrade
!usage
!userinfo
!verbose
!version
!weight
!whyluckperms
!wiki

nocturne elbow
#

!placeholders

frank driftBOT
nocturne elbow
#

@clever lichen ^

clever lichen
nocturne elbow
#

uh ig you can omit the max part and do findFirst or whatever criteria you'd do to get just one node

clever lichen
#

and what about what im doing

nocturne elbow
#

yeah that's not gonna work, you are building the node, you're not fetching the existing ones from the user's parents

#

and the expiry will be null in your case because you're building it without an expiry which is what you're trying to get from the existing one(s)

clever lichen
#

so i would have to use your code inside my for each?

nocturne elbow
#

uh why inside the forEach?

clever lichen
#

because im creating an item in a gui for each group that the user is inside of

nocturne elbow
#

yeah no

clever lichen
#

im adding the info to the lore of the item in the gui

#

like the expiry

nocturne elbow
#

yes, but the expiring information is not present in the group

clever lichen
#

its in the user

nocturne elbow
#

it's present in the InheritanceNode held by the user

clever lichen
#

and how do i get it then

nocturne elbow
#

might want to just keep something like this then

List<InheritanceNode> tempParentGroups = user.getNodes(NodeType.INHERITANCE).stream().filter(Node::hasExpiry).collect(Collectors.toList())

from those you'd be able to fetch both the group name and the expiry

clever lichen
#

and what if i also want to get it if is permanent

nocturne elbow
#

Collection<InheritanceNode> tempParentGroups = user.getNodes(NodeType.INHERITANCE);

#

then as you process each check if it has an expiry etc...

clever lichen
#

and then i would check it like this

clever lichen
#
 Collection<InheritanceNode> tempParentGroups = user.getNodes(NodeType.INHERITANCE);
#

so i do this right

#

and then how would i find the expiry of the value

#

the value is the group name

clever lichen
#

.forEach(group -> {
if(group == value) // do something
}

#

would it be like something like that?

nocturne elbow
#

get the group name from the node and compare it

clever lichen
#
if(group.getGroupName() == value.getName())
#

like this?

nocturne elbow
#

.equals

clever lichen
#

-1 would be permanent right?

nocturne elbow
#

-1 what?

#

what method are we even talking about?

clever lichen
#

like the expiry time

#

when i do group.getExpiry().toString();

nocturne elbow
#

please read the javadoc

clever lichen
#

k

#

thanks for your help and patience

nocturne elbow
#

!hack

frank driftBOT
#
Has LuckPerms been exploited/hacked?

Most certainly: no. In most cases a 'LuckPerms exploit' is a simple case of human error, which can be avoided easily. Look below for some tips to be on the safe side.

Don't give random people full ( * ) permissions / admin permissions

While this should be obvious, a lot of times a exploit can be traced back to faulty permission settings. You should always take your time with permissions and read the plugin documentations. In 99% of all cases the plugins have documentations explaining each permission, in the rare case that the plugin you are using does not have a documentation, you could still:
A: Ask the plugin developer for help
B: Use LuckPerms verbose functionality ( !verbose )
C: Select a different plugin with proper documentation.

Do not run your server/network in offline mode

If you are running your server or network in offline mode, hackers have it really easy to steal your, or any other admins identity. While the server is in offline mode, certain checks ( which exist to prevent exactly this ), are being skipped, and the server does not verify if the person joining actually is the person they claim to be. While there may be plugins which increase the security of offline mode servers by adding things such as admin codes, you should just switch it to online to prevent the issue in the first place.

Do not download plugins from shady websites / sent by friends

You should never put anything on your server which has not been downloaded by yourself from official sources. Plugins can be infected with malware which injects itself into all other plugins, and thus is hard to remove. While it may look like a plugin has been hacked, you most certainly downloaded a modified version of it and it is not the plugin authors fault. In case your server has been infected by such malware:

  1. Stop the server
  2. Delete all plugins in your plugins folder, and just to be safe also the server jar file
  3. Re-Download all plugins and server jar files from official websites such as SpigotMC or official plugin websites ( luckperms.net for example ).
  4. Check if there have been any modifications to the permission system and remove unknown users and wrong permissions.
    if you follow these steps you should have a clean server by the end, without exploits.
bright osprey
#

hey guys, is there a way to get user with predefined QueryOptions? i would like to pass User object around without having to use user.cachedData.getPermissionData(queryOpts)

nocturne elbow
#

?:(*)R_TY

nocturne elbow
bright osprey
#

I need to set my own query options, code is checking permissions in different static context (other server)

#
    private suspend fun fetchPermissionData(playerId: UUID, upstreamType: UpstreamType?, upstreamId: UpstreamId?) =
        withContext(Dispatchers.IO) {
            val permsQueryOptions = QueryOptions.contextual(
                ImmutableContextSet.builder().apply {
                    if (upstreamId != null) {
                        add("upstream_id", upstreamId)
                    }
                    if (upstreamType != null) {
                        add("upstream_type", upstreamType)
                    }
                }.build()
            )
            val user = luckPerms.userManager.loadUser(playerId).await()!!
            val perms = user.cachedData.getPermissionData(permsQueryOptions)
            val meta = user.cachedData.getMetaData(permsQueryOptions)
            Pair(perms, meta)
        }


/// other method

        val (callerPerms, callerMeta) = fetchPermissionData(caller, currentUpstream.type, currentUpstream.id)
        val hasPerm = callerPerms.let {
            { perm: String -> it.checkPermission(perm).asBoolean() }
        }```
#

it would be a lot more handy to have user with preset context

nocturne elbow
#

I don't think what you want is possible, that would be changing the user's active contexts which for something like "world" or "server" you cannot change

#

You can make a small User wrapper class if it's that much of a hassle I guess, not sure up until what point that's actually useful

bright osprey
#

ok, thx

meager gazelle
#

how can i get a temp permission's end time?

#

or can i?

#

nvm found it

slim bloom
#

im making a little web dashboard thing, does the luckperms API have a way to get a web dashboard link i can put in an iframe?

#

or at least link to?

orchid mortar
#

Hey :)
i need a sync function which returns the primarygroup of an offline player and i am not into async so... is that possible?

I read the api usage docs, but in the example the code only does something with the result inside the .thenAcceptAsync, but i need to return it from the outer function...

#

a sync function...

turbid solar
#

Why sync

orchid mortar
#

because i need to cancel a inventory open event based on the primary group

#

but based on the primary group of an other, maybe offline player

nocturne elbow
#

You can call CompletableFuture#join and it will block until the result is ready (or an exception is thrown), but that's non-ideal, ideally you'd have a cache of sorts if the player is offline

timber ravine
#

Is it safe to use hasPermission on offline players?

pastel cliff
#

Now I’m making an invisible armor stand with a custom name that follows people, so that I can display invisible player names when they are invisible.

#

Because vanilla doesn’t display names of invisible players.

#

My question is when generating this name, I want to use the prefixes, suffixes and colors of luckperms

#

i read your docs and your api

#

i accessed the player adapter and the user instance then the cached meta data

#

and tried getting the prefix and suffix

#

but on my friends server they were both null

#

even though they show up on top their heads by default

#

and in chat

#

Player#getDisplayName alone doesn’t do the trick

nocturne elbow
#

do you have a question or..?

pastel cliff
#

Yes

#

How do i get the name thats by default above their heads

#

including colors

#

and prefixes and all that

#

cause when i tried your api, prefix was null but i could clearly see it

nocturne elbow
#

well through the cached metadata, that is the way you do it; if it's returning null then something in either your code or their LP setup is wrong

pastel cliff
#

i’ll talk to them about their luckperms, im not sure but i think they said its in their server core

#

server software that do that, including viaversion or luckperms for example make it difficult to handle bugs

#

cause they usually dont update them

nocturne elbow
#

😵‍💫

#

LP is not the kind of plugin you want to leave outdated lol

pastel cliff
#

ill ask them if its possible to update or for more information

nocturne elbow
#

myes please

#

qq

#

have you tested your code on a test env or smth to ensure it works as intended?

pastel cliff
#

im not entirely the best when it comes to setting up colors or prefixes

#

when im on my pc

#

ill ask for help here

nocturne elbow
#

oki

pastel cliff
#

sometimes its really unfortunate, im staff on other projects, and people really spent a lot of money into custom server forks and they end up like this

#

and they have issues

#

i don’t know what one can do

nocturne elbow
#

paid forks are snake oil

#

all and every single one of them

pastel cliff
#

anyway, i admire the way your api is designed

#

i might take notes haha

nocturne elbow
#

oh yeah it's amazing

#

i personally took a lot of inspiration from it

pastel cliff
#

i also started making my library cross platform and i see the way you do a few things quite well

#

and impressively

#

anyway, im gonna sleep

#

gn

obtuse shale
#

Hello, I have such a problem I do not know how to get time from the expiration of the group that the player is wearing (Is there a possibility to get neg. in milli seconds?)

nocturne elbow
obtuse shale
#

Now I have such a problem its a while behind 😄

night pier
#

What is a while behind..?

hybrid panther
#

hm

obtuse shale
obtuse shale
#

I give to me VIP rank for 10 days
And i see when i check 10s....

fringe skiff
#

Is luckpermsbungee a different thing in the api

nocturne elbow
#

nope, the api is completely platform agnostic

fringe skiff
#

how do i mess with user data in luckpermsbungee with the api?

nocturne elbow
#

!api

frank driftBOT
nocturne elbow
#

how do I get groups prefix

unreal mantle
nocturne elbow
#

so?

#

i need to get groups prefix in a loop

unreal mantle
unreal mantle
#

Then just get a group instead of a user??

nocturne elbow
unreal mantle
#

Isn't what?

nocturne elbow
karmic shadow
#

Do groups even have cached data....

#

My logical thinking tells me 'no'

nocturne elbow
#

oh

#

my

#

god

#

wrong import

unreal mantle
nocturne elbow
#

when I want to sort tablist by groups weight, how do I do it

unreal mantle
nocturne elbow
# unreal mantle Not sure if there is a more direct way, but you could possibly get a list of the...
Scoreboard scoreboard = Bukkit.getServer().getScoreboardManager().getMainScoreboard();
        for(Player player : Bukkit.getOnlinePlayers()) {
            Team team = scoreboard.getTeam(player.getName());
            if(team == null) {
                team = scoreboard.registerNewTeam(player.getName());
            }

            User user = plugin.getLuckPerms().getPlayerAdapter(Player.class).getUser(player);

            String prefix = user.getCachedData().getMetaData().getPrefix();

            if(prefix != null)
                team.setPrefix(Utils.tc(prefix));

            team.addPlayer(player);
        }
#

I have this, any idea how to transform it ot that?

fringe skiff
nocturne elbow
#

because it's the exact same API everywhere

#

[19:34] kz-n: Is luckpermsbungee a different thing in the api
[19:37] Lord_Samosa: nope, the api is completely platform agnostic

fringe skiff
#

I dont understand... user info is different on lp and lpb, i assumed it was in the api too

#

do i just use the same code to edit user data

nocturne elbow
fringe skiff
#

Oh, so to perform edits on lpb I'd just have to run my plugin on the proxy?

nocturne elbow
#

yeah - and push the changes through the messaging service (see ReadPins)

fringe skiff
#

How does that work? (What does it do)

nocturne elbow
#

propagates the changes throughout the network, notifying the other LP instances to pull those changes from storage

fringe skiff
#

Oh

#

So do I still need to run my plugin in the proxy too?

#

Or does it propagate automatically..?

nocturne elbow
#

wherever your plugin runs, whenever you make some changes (add/remove permissions, create groups etc) you tell the LP your plugin is hooked up to to propagate those changes throughout the entire network

odd belfry
#

how can I get time left on a specific permission?

fringe skiff
#
public void addGroupBungee(User user, String group) {
        user.data().add(InheritanceNode.builder(group).build());
        api.getUserManager().saveUser(user).thenRunAsync(() -> {
            Optional<MessagingService> messagingService = api.getMessagingService();
            System.out.println(messagingService.isPresent());
            if (messagingService.isPresent()) {
                messagingService.get().pushUserUpdate(api.getUserManager().getUser(user.getUniqueId()));
            }
        });
    }

This isn't pushing the update properly, i think.

messagingService.isPresent() prints true, and I see a [Messaging] telling me it's sending a user ping for '_kz_n'

torn fog
#

hello, are luckperms events called on the main thread?

nocturne elbow
#

most aren't

nocturne elbow
fringe skiff
#

am i doing this correctly? i dont see the information changing

nocturne elbow
#

and I see a [Messaging] telling me it's sending a user ping for '_kz_n'
well that does means the user was saved successfully and the change was pushed through the msging service

#

how are you checking back if it "worked" exactly?

fringe skiff
#

lpb user _kz_n group info

fringe skiff
nocturne elbow
#

can you screenshot lpb listgroups?

fringe skiff
fringe skiff
nocturne elbow
#

i mean i know for a fact that it works

#

what about lpb group litebans-admin listmembers (or showmembers? can't remember)

fringe skiff
#

aka not me

nocturne elbow
#

when calling that function, where are you taking that User from?

#

like, are you storing it in a collection/map and taking it from there, are you taking it directly from the usermanager...?

fringe skiff
#

i have a utility class for this stuff (where addGroupBungee is in too) which has a method called getUser and that is what I use to perform all actions in the function, the same variable (User user = luckPermsUtils.getUser(player)) is passed every time i perform these operations, i have 3 other calls to the LuckPerms api before this point, and they all work.

...
User user = luckPermsUtils.getUser(p);
            if (luckPermsUtils.hasPermission(user, permissionAssociation.getTogglePerm())) {
                for (Player p1 : staffedPlayers) {
                    if (p == p1) {

                        luckPermsUtils.removeGroup(user, staffedPermissions.get(p));
                        luckPermsUtils.removePrefix(user,permissionAssociation.getToggledPrefix());
                        luckPermsUtils.addPrefix(user,permissionAssociation.getUntoggledPrefix());
                        luckPermsUtils.removeGroupBungee(user, permissionAssociation.getAssignPermBungee().replace("group.", ""));
...
#

forgot to mention

#
public User getUser(Player player) {
        return api.getPlayerAdapter(Player.class).getUser(player);
}
nocturne elbow
#

mmmmmmmmmmm

fringe skiff
#

intense thonking

nocturne elbow
#

ugh i don't have the energy to go through this now, i'll try something tomorrow but that looks like it should work... if the stdout said the right user w/ the right group and it showed the msging service msg then it for sure saved it to storage, otherwise it wouldn't have run

fringe skiff
#
[02:34:55] [Server thread/INFO]: [STDOUT] User _kz_n group litebans-admin
[02:34:55] [ForkJoinPool-1-worker-41/INFO]: [Messaging] Sending user ping for '_kz_n' with id: 5fa588db-3a77-4966-955b-fb4cec73e358
nocturne elbow
#

okay wait actually

#

do all of these call saveUser(blah).then... ?

fringe skiff
#

Only the last part calls thenAsync

#

removeGroupBungee i mean

#

But yes

nocturne elbow
#

all of them call saveUser?

fringe skiff
#

yes

nocturne elbow
#

mm concurrency chefskiss

fringe skiff
#

huh

nocturne elbow
#

basically, since saveUser spawns a new thread to save to storage asynchronously, running it several times one right after the other won't guarantee any particular order in which that is done

fringe skiff
nocturne elbow
#

perhaps the thread from the 3rd call is spawned first, and the one from the 1st call is spawned last

#

yeah lol

fringe skiff
#

so basically until now it worked out of luck LUL

#

so basically id have to save the user separately

nocturne elbow
#

i'd say mm use UserManager#modifyUser

#

d;lp usermanager#modifyuser

slate deltaBOT
#
@NonNull
default CompletableFuture<Void> modifyUser(@NonNull UUID uniqueId, @NonNull Consumer action)```
Description:

Loads a user from the plugin's storage provider, applies the given action, then saves the user's data back to storage.

This method effectively calls loadUser(UUID), followed by the action, then saveUser(User), and returns an encapsulation of the whole process as a CompletableFuture.

Since:

5.1

Parameters:

uniqueId - the uuid of the user
action - the action to apply to the user

Returns:

a future to encapsulate the operation

nocturne elbow
#

and basically add/remove all the nodes inside the Consumer<User> action, then it'll be saved for you, and then from the returned CF you can do thenRun/thenWhatver... and call the msging service

fringe skiff
#

i dont understand, why would this be better than calling saveUser?

nocturne elbow
#

how you have it right now, you're saving (or.. trying to) each individual change right after it's done, but what i said earlier happens so it sucks

#

with modifyUser you will apply all those changes together, in tandem

#

then it calls saveUser for you which is neat ig

fringe skiff
#

would this be any different than basically removing the saveUser line and adding then calling manually saveUser after the operations are done?

nocturne elbow
#

no

#

it's more of a convenience thing

#

/shrug

#

discord pls

night pier
#

¯_(ツ)_/¯

fringe skiff
#

or would that cause the same problem of maybe saveUser can be called before/after/amidst the operations

nocturne elbow
#

the idea is that you add/remove all the nodes you want in tandem/batch, after that, when you're done modifying it you save the user

hybrid panther
#

Oh ok

fringe skiff
#

how would I be certain of exactly when i'm done modifying

#

I honestly thought this was synchronous for some reason

nocturne elbow
#

uh

#

after you call that last method that adds/removes nodes

nocturne elbow
#

(assuming you remove the saveUser calls from them all)

fringe skiff
#

method that adds/removes nodes
what method?

nocturne elbow
#

your.. method

fringe skiff
#

oh

#
                         luckPermsUtils.removeGroup(user, staffedPermissions.get(p));
                        luckPermsUtils.removePrefix(user,permissionAssociation.getToggledPrefix());
                        luckPermsUtils.addPrefix(user,permissionAssociation.getUntoggledPrefix());
                        luckPermsUtils.removeGroupBungee(user, permissionAssociation.getAssignPermBungee().replace("group.", ""));

                        luckPermsUtils.saveUser(user);
                        luckPermsUtils.messagingSaveUser(user);

this is my code, it still doesn't seem to be working

    public void saveUser(User user) {
        api.getUserManager().saveUser(user);
    }

    public void messagingSaveUser(User user) {
        api.getUserManager().saveUser(user).thenRunAsync(() -> {
            Optional<MessagingService> messagingService = api.getMessagingService();
            System.out.println(messagingService.isPresent());
            if (messagingService.isPresent()) {
                messagingService.get().pushUserUpdate(api.getUserManager().getUser(user.getUniqueId()));
            }
        });
    }

(i removed saving from all methods)

fringe skiff
wintry pier
#

Hello, what does this error mean?

[15:01:25 ERROR]: [LPT] LPT v1.0 attempted to register an invalid EventHandler method signature "public void de.greenman999.lpt.util.Util.onUserCacheChange(net.luckperms.api.event.user.UserDataRecalculateEvent)" in class de.greenman999.lpt.util.Util
[15:01:25 ERROR]: [LPT] LPT v1.0 attempted to register an invalid EventHandler method signature "public void de.greenman999.lpt.util.Util.onNodeMutate(net.luckperms.api.event.node.NodeMutateEvent)" in class de.greenman999.lpt.util.Util
#
package de.greenman999.lpt.util;

import de.greenman999.lpt.LPT;
import dev.jorel.commandapi.CommandAPICommand;
import dev.jorel.commandapi.arguments.StringArgument;
import net.luckperms.api.LuckPerms;
import net.luckperms.api.event.node.NodeAddEvent;
import net.luckperms.api.event.node.NodeClearEvent;
import net.luckperms.api.event.node.NodeMutateEvent;
import net.luckperms.api.event.node.NodeRemoveEvent;
import net.luckperms.api.event.user.UserDataRecalculateEvent;
import net.luckperms.api.model.user.User;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

import java.util.HashMap;
import java.util.UUID;

public class Util implements Listener {

    private static HashMap<UUID, String> prefixes = new HashMap<>();
    private static HashMap<UUID, String> suffixes = new HashMap<>();
    private static HashMap<UUID, String> messageColors = new HashMap<>();
    private static HashMap<UUID, String> usernameColors = new HashMap<>();
    private static LuckPerms api = LPT.getAPI();

    @EventHandler
    public void onUserCacheChange(UserDataRecalculateEvent event) {
        User user = event.getUser();
        UUID uuid = user.getUniqueId();
        reloadCaches();
        //LPT.log("Event");
    }

    @EventHandler
    public void onNodeMutate(NodeMutateEvent event) {

        reloadCaches();
    }

    public static void reloadCaches() {
        for(Player player : Bukkit.getOnlinePlayers()) {
            api.getUserManager().loadUser(player.getUniqueId());
        }
        for(User user : api.getUserManager().getLoadedUsers()) {
            Player player = Bukkit.getPlayer(user.getUniqueId());

            String prefix = user.getCachedData().getMetaData().getPrefix();
            String suffix = user.getCachedData().getMetaData().getSuffix();
            String messageColor = user.getCachedData().getMetaData().getMetaValue("messageColor");
            String usernameColor = user.getCachedData().getMetaData().getMetaValue("usernameColor");

            player.sendMessage("Prefix: " + prefix);
            player.sendMessage("Suffix: " + suffix);
            player.sendMessage("MessageColor: " + messageColor);
            player.sendMessage("UsernameColor: " + usernameColor);

            if(prefixes.containsKey(user.getUniqueId())) {
              prefixes.remove(user.getUniqueId());
              prefixes.put(user.getUniqueId(), prefix);
            }else {
                prefixes.put(user.getUniqueId(), prefix);
            }

            if(suffixes.containsKey(user.getUniqueId())) {
                suffixes.remove(user.getUniqueId());
                suffixes.put(user.getUniqueId(), suffix);
            }else {
                suffixes.put(user.getUniqueId(), suffix);
            }

            if(messageColors.containsKey(user.getUniqueId())) {
                messageColors.remove(user.getUniqueId());
                messageColors.put(user.getUniqueId(), messageColor);
            }else {
                messageColors.put(user.getUniqueId(), messageColor);
            }

            if(usernameColors.containsKey(user.getUniqueId())) {
                usernameColors.remove(user.getUniqueId());
                usernameColors.put(user.getUniqueId(), usernameColor);
            }else {
                usernameColors.put(user.getUniqueId(), usernameColor);
            }






        }
    }

    public static void registerReloadCommand() {
        new CommandAPICommand("lpt")
                .withSubcommand(new CommandAPICommand("reload")
                        .withPermission("lpt.reload")
                        .executes((sender,args) -> {
                            LPT.getPlugin().reloadConfig();
                            reloadCaches();
                            sender.sendMessage("§aReloaded LPT!");
                        })

                ).register();
    }
}

this is my class

jaunty pecan
nocturne elbow
#

how do i add a group for player for limited time, like a month or three

wintry pier
#

It still says invalid event handler

jaunty pecan
#

Don't annotate your method with @EventHandler

#

and register it as the wiki shows instead

jaunty pecan
#

read the wiki, it has an example for adding nodes with an expiry

nocturne elbow
#

and how do I add the node?

jaunty pecan
#

it tells you how to do that too

nocturne elbow
#

that node is something like a permission?

nocturne elbow
jaunty pecan
#

Yes, I’ve done so already, on the wiki

#

It explains everything you need to know

#

Check the API Usage page

fringe skiff
#

is messaging service on the reference?

nocturne elbow
jaunty pecan
fringe skiff
#

link?

jaunty pecan
nocturne elbow
jaunty pecan
#

the wiki page explains everything in sufficient detail, there is also a sample plugin (cookbook) which is a fully working example you can copy.

#

we don't have any other resources to offer, so if that's not enough then maybe you need to use something else or find someone to help guide you step by step.

#
nocturne elbow
jaunty pecan
#

Yes

nocturne elbow
#

because there's not much how to do it

#

it's a full blown plugin showcasing how to use many aspects of the API

nocturne elbow
#

well no, an example is not documentation

#

and the wiki does go over it

#

i read the wiki

#

it's the same

#

I want to add group to player for limited time using code

#

"it's the same"?

#

but I don't know how

#

it explains what a node is, the different attributes it has, how you create it, how to add it to a user/group

#

well, other than that, what do I do with it now

#

please, please make an effort and actually read the wiki

#

it's all there

#

the very second example of "Creating new node instances" shows how you can make a temporary node

#

reading later on, it shows how you can add it to a user/group

#

what even is the node

nocturne elbow
#

Please

#

read

#

i dont need or want java class explanation, I want to know what it really represents

#

like when you open a luckperms editor

nocturne elbow
#

You're not even pretending to read oh my god

neat jackal
#

a Node represents a (permission) node

nocturne elbow
#

and that is added to the role that user have?

#

and then when it expires then it removes it?

#

when the expiry date is past "now" it's removed, yes

#
User user = plugin.getLuckPerms().getPlayerAdapter(Player.class).getUser(p);

            Node node = Node.builder("rcore."+itemButton.getGroup())
                    .value(false)
                    .expiry(Duration.ofDays(itemButton.getDays()))
                    .build();
            Group group = plugin.getLuckPerms().getGroupManager().getGroup(itemButton.getGroup());

            group.data().add(node);

            user.setPrimaryGroup(group.getName());
#

so this will add the node to group and then asign the group to player for limited time

#

so?

#

adding the node to the group, yes, changing the player's parent group, no, check the SetGroupCommand example in the cookbook

nocturne elbow
#

it will add the node to the group, everyone who inherits from that group will get that permission as well (through the group, not in their own nodemap)

nocturne elbow
#

modifying the User's own data instead of the group's

#

so when he gets this node, it will asign him that group? or how

#

what?

#

I need to give player a group for 30 days, as a vip that he bought, so, when he buys it, it needs to assign him that group

#

okay then you probably want to use the InheritanceNode.builder, pass in the group, then add it to the user's data

nocturne elbow
#

oh, know I understand this

#

okay, I have a group gold and now I passed it into inheritance node builder and added expiry for 30 days and build() it

#

when I assign it to player, the player will have then group for 30 days and then it will remove?

#
            plugin.getLuckPerms().getUserManager().modifyUser(p.getUniqueId(), (User user) -> {
                user.data().clear(NodeType.INHERITANCE::matches);

                InheritanceNode node = InheritanceNode.builder(itemButton.getGroup()).expiry(Duration.ofDays(itemButton.getDays())).build();

                user.data().add(node);
            });
#

yes

nocturne elbow
#

and if i dont want them to go to default after it expires?

#

then don't run this .clear(NodeType.INHERITANCE::matches)

#
plugin.getLuckPerms().getUserManager().modifyUser(p.getUniqueId(), (User user) -> {
                InheritanceNode node = InheritanceNode.builder(itemButton.getGroup()).expiry(Duration.ofDays(itemButton.getDays())).build();

                user.data().add(node);
            });
#

so like this?

#

myes

wintry pier
#

When I execute the command /lp editor, every tick the userdatarecalculateevent gets called... why?

#

@jaunty pecan

frank driftBOT
#

Hey Greenman999! Please don't tag helpful/staff members directly.

wintry pier
#

whoops sry

jaunty pecan
#

running /lp editor causes a lot of user data to be loaded

#

so that event will be called

wintry pier
#

hmm okay is there a way to get it called only once? when all of the data is loaded?

jaunty pecan
#

UserLoadEvent?

wintry pier
jaunty pecan
#

ah yea that's been broken for a while

#

should be fixed next time we deploy an API version (might be a while..)

wintry pier
#

okie

wintry pier
#

and so also the prefix of the user?

#

or do i have to use GroupDataRecalculateEvent

jaunty pecan
#

the best way is UserDataRecalculateEvent as you were before

#

you can add a buffer if it's being called too frequently

wintry pier
# jaunty pecan the best way is UserDataRecalculateEvent as you were before

Is it possible that subscribing to an event, cancels the event? Because I subscribed to two events, the GroupDataRecalculateEven and the NodeMutateEvent... When my plugin is loaded I cant add me to a group...

public Util() {
        EventBus eventBus = LPT.getAPI().getEventBus();


        eventBus.subscribe(LPT.getPlugin(), GroupDataRecalculateEvent.class, this::onGroupCacheChange);
        eventBus.subscribe(LPT.getPlugin(), NodeMutateEvent.class, this::onNodeMutate);
    }


    private void onGroupCacheChange(GroupDataRecalculateEvent event) {
        reloadCaches();
        LPT.log("groupevent");
    }

    private void onNodeMutate(NodeMutateEvent event) {
        reloadCaches();
        LPT.log("nodeevent");
    }
ruby trench
#

do I need luckperms API if I just want to check if player has a permission node?

hybrid panther
#

no, just use org.bukkit.entity.Player#hasPermission(String node)

paper burrow
#

How can i get Temp Group For User?

iron matrix
#

Hello, I keep getting this error when trying to use the api from luckperms. Luckperms activates perfectly fine and works as it should. I have the maven dependency for it and have an artifact for the jar in there as well. I'm not sure whats causing it.

25.12 14:16:55 [Server] ING Error dispatching event ChatEvent(super=TargetedEvent(sender=OhBuzz, receiver=net.md_5.bungee.ServerConnection@111cc61a), cancelled=false, message=t) to listener me.ohbuzz.listener.ToggleStaffChat@6df7988f
25.12 14:16:55 [Server] INFO net.luckperms.api.LuckPermsProvider$NotLoadedException: The LuckPerms API isn't loaded yet!
25.12 14:16:55 [Server] INFO This could be because:
25.12 14:16:55 [Server] INFO a) the LuckPerms plugin is not installed or it failed to enable
25.12 14:16:55 [Server] INFO b) the plugin in the stacktrace does not declare a dependency on LuckPerms
25.12 14:16:55 [Server] INFO c) the plugin in the stacktrace is retrieving the API before the plugin 'enable' phase
25.12 14:16:55 [Server] INFO (call the #get method in onEnable, not the constructor!)
25.12 14:16:55 [Server] INFO at net.luckperms.api.LuckPermsProvider.get(LuckPermsProvider.java:53)
25.12 14:16:55 [Server] INFO at me.ohbuzz.manager.StaffManager.getPrefix(StaffManager.java:33)
25.12 14:16:55 [Server] INFO at me.ohbuzz.listener.ToggleStaffChat.chatEvent(ToggleStaffChat.java:41)
25.12 14:16:55 [Server] INFO at sun.reflect.GeneratedMethodAccessor14.invoke(Unknown Source)
25.12 14:16:55 [Server] INFO at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
25.12 14:16:55 [Server] INFO at java.lang.reflect.Method.invoke(Method.java:498)

This is the line it says in the error with my code

    public String getPrefix(ProxiedPlayer player) {
        LuckPerms api = LuckPermsProvider.get();
        User user = api.getUserManager().getUser(player.getUniqueId());
        try {
            QueryOptions queryOptions = api.getContextManager().getQueryOptions(player);
            assert user != null;
            return Objects.requireNonNull(user.getCachedData().getMetaData(queryOptions).getPrefix())
                    .replace(" ", "")
                    .replace("]", "")
                    .replace("[", "")
                    .replaceAll("&", "§");
        } catch (NullPointerException e) {
            e.printStackTrace();
            return null;
        }
    }
neat jackal
#

So you shaded the LuckPerms jar into your jar?

iron matrix
#

yes, as well as put it into the pom.xml

#
        <dependency>
            <groupId>me.lucko.luckperms</groupId>
            <artifactId>luckperms-api</artifactId>
            <version>4.4</version>
        </dependency>
#

code throws no errors and no errors on start from either plugin (mine or luck)

#

only internal error when running commands and it gives that stack trace

#

i also have it in the bungee.yml to depend on luckperms

#

depends: [LuckPerms]

neat jackal
iron matrix
#

oh im sorry, ill do that now

turbid solar
#

Also that’s v4

#

!latest

frank driftBOT
#
Latest version

5.3.89

turbid solar
#

Latest api is 5.3

nocturne elbow
#

how can I make tablist sort by group?

turbid solar
#

!tab

frank driftBOT
#
LuckPerms does not perform any chat/tablist formatting of its own!

LuckPerms only acts as the source for prefixes / suffixes, it doesn't actually apply them. You need an appropriately configured chat/tablist formatting plugin for them to be displayed. If the values appear correctly when you run /lp user <user> info, LuckPerms is doing its job!

List of chat/tablist formatting plugins that work with LuckPerms
nocturne elbow
# turbid solar !tab

what? this is luckperms-api page, about coding, I want to make it sort in tablist, I dont want any other plugin to do it

nocturne elbow
turbid solar
#

Check for users weights?

#

And sort by that

iron matrix
#
25.12 15:14:17 [Server] INFO net.luckperms.api.LuckPermsProvider$NotLoadedException: The LuckPerms API isn't loaded yet!
25.12 15:14:17 [Server] INFO This could be because:
25.12 15:14:17 [Server] INFO a) the LuckPerms plugin is not installed or it failed to enable
25.12 15:14:17 [Server] INFO b) the plugin in the stacktrace does not declare a dependency on LuckPerms
25.12 15:14:17 [Server] INFO c) the plugin in the stacktrace is retrieving the API before the plugin 'enable' phase
25.12 15:14:17 [Server] INFO (call the #get method in onEnable, not the constructor!)
25.12 15:14:17 [Server] INFO at net.luckperms.api.LuckPermsProvider.get(LuckPermsProvider.java:53)
25.12 15:14:17 [Server] INFO at me.ohbuzz.manager.StaffManager.getPrefix(StaffManager.java:33)
25.12 15:14:17 [Server] INFO at me.ohbuzz.commands.StaffChat.execute(StaffChat.java:52)

Still get the error.
StaffChat line 52:

.replace("{rank}", this.instance.getStaffManager().getPrefix(player)
.replace("StaffManager", "Staff Manager")
.replace("SupportManager", "Support Manager")
.replace("CommunityManager", "Community Manager"))

StaffManager line 33:

LuckPerms api = LuckPermsProvider.get();
#

ive installed the api-5.3, put the provided scope, and everything else in the wiki

nocturne elbow
#

can you share the whole pom.xml?

iron matrix
#

sure

nocturne elbow
#

is that in a cmd or something?

nocturne elbow
#

well, "or something" more like "or where", lol

iron matrix
#

where it gets the prefix in that one snippet with {rank} obv

#

heres the full code for the staff chat, which is one of the commands giving that error

nocturne elbow
#

Can you check if your jar file contains any of the LP API classes to make sure you're not shading it? Try running the clean task before building the jar again

night pier
#

i believe she's asking you to put your jar in something like luyten and look to see if there are any class files related to LuckPerms.

nocturne elbow
#

just unzipping the jar file will do, lol

iron matrix
#

yeah thats in the zip

turbid solar
#

set the scope to provided

iron matrix
#
    <dependencies>
        <dependency>
            <groupId>net.md-5</groupId>
            <artifactId>bungeecord-api</artifactId>
            <version>1.12-SNAPSHOT</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>net.luckperms</groupId>
            <artifactId>api</artifactId>
            <version>5.3</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>
#

i have

#

im able to access the api perfectly fine in the JDE but as soon as it goes to in game it says the API cant be found

nocturne elbow
#

Try running the clean task before building the jar again

iron matrix
#

i just did

#

still the same error

#

but i tried a different command and it happens any time theres LuckPerms api = LuckPermsProvider.get(); in the code

#

and throws the error exactly to that line

#

thats a full console log of startup to command usage where it throws the error

nocturne elbow
#

are the classes still in the jar file?

iron matrix
#

yeah

turbid solar
#

How are you building the plugin

#

Because thé LuckPerms jarinjar file shouldn’t be there at all

iron matrix
#

i put the jar file in there through intellij as well to see if that would solve the api issue

turbid solar
#

Use maven not your ide to build

iron matrix
#

ive tried both

#

and get the same issue

turbid solar
#

open terminal and type mvn clean package

#

Then open the jar

nocturne elbow
#

the jar* inside the target dir, I believe IJ puts it somewhere different than maven

#

how do I get playes primary group weight

#

so?

nocturne elbow
#

get the primary group name from the user, get the group from the groupmanager, get its weight

paper burrow
ruby trench
#

I get this when checking hasPermission

turbid solar
#

permission cannot be null

midnight locust
#

Can you change the normal prefixes and suffixes via API?

#

I don't mean custom meta values

dire shore
#

Hi, i use

user.data().add(Node.builder("bungeehomes.amount."+(homes+amount)).build());
luckapi.getUserManager().saveUser(user);```
To add homes to players, but they have to disconnect and reconnect to get the permission. How can i reload user to let him using the permission immediately?
clever zodiac
#

Perhaps the plug-in only checks that permission when they join, then saves it into memory on their end

dire shore
#

The plugin call this each time player try to sethome

    private int getMaxHomes(Player player, int defaultValue) {
        String permissionPrefix = "bungeehomes.amount.";
        int maxHomes = defaultValue;

        for (PermissionAttachmentInfo attachmentInfo : player.getEffectivePermissions()) {
            String permission = attachmentInfo.getPermission();
            if (permission.startsWith(permissionPrefix)) {
                int permMaxhomes = Integer.parseInt(permission.substring(permission.lastIndexOf(".") + 1));
                if(permMaxhomes > maxHomes){
                    maxHomes = permMaxhomes;
                }
            }
        }
        return maxHomes;
    }
nocturne elbow
nocturne elbow
dire shore
#

It runs on the server player is in

#

I'll try with MetaNode, thx

lofty yarrow
#

How to add an user to a luckperms group?

#

nvm, found it!

robust stirrup
#

Can anyone help me? I'm trying to add a permission to the player every time an event is launched, which in this case is a plugin that authenticates with discord. I want to give "2FA.Discord" permission to the player when this event is launched but I am not succeeding

frank driftBOT
unreal mantle
#

That shows an example of adding a permission to a user.

#

Make sure you save the changes, and you'll need to get the User first.

robust stirrup
unreal mantle
#

Have you added LP as a dependency first?

robust stirrup
#

yep

unreal mantle
#

User user = luckPerms.getUserManager().getUser(uuid); will get the player . (uuid) is the players uuid

#

@robust stirrup You could also just use something like

public void addPermission(UUID userUuid, String permission) {
    // Load, modify, then save
    luckPerms.getUserManager().modifyUser(userUuid, user -> {
        // Add the permission
        user.data().add(Node.builder(permission).build());
    });
}

To speed up the process. The modifyUser will handle loading and saving the user for you. All you need to do is replace userUuid with the players uuid and replace permission with the permission you're wanting to add.

unreal mantle
#

You can just take the body of the method out, so the

    luckPerms.getUserManager().modifyUser(userUuid, user -> {
        // Add the permission
        user.data().add(Node.builder(permission).build());
    });
#

Or add the full thing under the event

#

Either way works

#

Just make sure you've obtained an instance of the API

#

Otherwise the luckPerms will give you an error

robust stirrup
unreal mantle
#

Did you add luckperms as a dependency into your build file (so pom.xml or build.gradle) depending what you use

turbid solar
#

you need to get an instance of the api first

unreal mantle
#

An ^ I did mention you need to get an instance of the API or it will error 😛

unreal mantle
#

An you don't need the User user = luckPerms... if you're using the modifyUser

#

You also have a broken import line import net.luckperms.api.;

#

@robust stirrup First things first,

Did you add Luckperms into your pom.xml or build.gradle (depending if you use maven or gradle)

unreal mantle
#

Good now. you need to obtain an instance of the Luckperms API

robust stirrup
#

@unreal mantle you can contiue help me in pv?

frank driftBOT
#

Hey Guidi! Please don't tag helpful/staff members directly.

unreal mantle
#

In your plugins main class, in the onEnable method, add

RegisteredServiceProvider<LuckPerms> provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class);
if (provider != null) {
    LuckPerms api = provider.getProvider();
    
}
#

Then in the event class you can add a private Luckperms variable

robust stirrup
unreal mantle
#

You'll need to add the imports for Bukkit and RegisteredServiceProvider so it works 😛

unreal mantle
#

Now in the Event class, add a private variable for Luckperms

robust stirrup
#

private LuckPerms luckPerms; ?

unreal mantle
unreal mantle
#

Yeah
and remove the org.checkerframework.checker.nullness.qual.NonNull

robust stirrup
#

likethis?

unreal mantle
#

Yep, You need to get the user. Does that Event, have a getPlayer() method or something you can call to get the player?

robust stirrup
#

no

hybrid panther
#

Hm

unreal mantle
#

Are you wanting to add it to a single user, or all users online

#

Or atleast, get a players name or uuid from that event?

robust stirrup
#

player name

unreal mantle
#

Okay we can work with that

#

Do UUID userUuid = luckPerms.getUserManager().getUser(<method to get players username>).getUniqueId();

#

replace <method to get players username> with the method that your even uses to get the players name

robust stirrup
#

like this?

unreal mantle
#

Yep, now see if it works

robust stirrup
# unreal mantle Yep, now see if it works
java.lang.NullPointerException: Cannot invoke "net.luckperms.api.LuckPerms.getUserManager()" because "this.luckPerms" is null
        at com.authosiacraft.twofactor.Add.onTwoFactorDiscord(Add.java:21) ~[2FAuthosia.jar:?]
        at com.destroystokyo.paper.event.executor.asm.generated.GeneratedEventExecutor67.execute(Unknown Source) ~[?:?]
        at org.bukkit.plugin.EventExecutor.lambda$create$1(EventExecutor.java:69) ~[patched_1.17.1.jar:git-Paper-402]
        at co.aikar.timings.TimedEventExecutor.execute(TimedEventExecutor.java:76) ~[patched_1.17.1.jar:git-Paper-402]
        at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:70) ~[patched_1.17.1.jar:git-Paper-402]
        at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:628) ~[patched_1.17.1.jar:git-Paper-402]
        at com.nickuc.login.nLogin.a(:323) ~[?:?]
        at com.nickuc.login.security.twofactor.discord.DiscordPrimaryListener.a(:162) ~[?:?]
        at com.nickuc.login.security.twofactor.discord.DiscordPrimaryListener.onMessageReceived(:131) ~[?:?]
        at net.dv8tion.jda.api.hooks.ListenerAdapter.onEvent(ListenerAdapter.java:466) ~[JDASpigot.jar:?]
        at net.dv8tion.jda.api.hooks.InterfacedEventManager.handle(InterfacedEventManager.java:96) ~[JDASpigot.jar:?]
        at net.dv8tion.jda.internal.hooks.EventManagerProxy.handleInternally(EventManagerProxy.java:88) ~[JDASpigot.jar:?]
        at net.dv8tion.jda.internal.hooks.EventManagerProxy.handle(EventManagerProxy.java:70) ~[JDASpigot.jar:?]
        at net.dv8tion.jda.internal.JDAImpl.handleEvent(JDAImpl.java:160) ~[JDASpigot.jar:?]
        at net.dv8tion.jda.internal.handle.MessageCreateHandler.handleInternally(MessageCreateHandler.java:123) ~[JDASpigot.jar:?]
        at net.dv8tion.jda.internal.handle.SocketHandler.handle(SocketHandler.java:36) ~[JDASpigot.jar:?]
        at net.dv8tion.jda.internal.requests.WebSocketClient.onDispatch(WebSocketClient.java:952) ~[JDASpigot.jar:?]
        at net.dv8tion.jda.internal.requests.WebSocketClient.onEvent(WebSocketClient.java:839) ~[JDASpigot.jar:?]
        at net.dv8tion.jda.internal.requests.WebSocketClient.handleEvent(WebSocketClient.java:817) ~[JDASpigot.jar:?]
        at net.dv8tion.jda.internal.requests.WebSocketClient.onBinaryMessage(WebSocketClient.java:990) ~[JDASpigot.jar:?]
        at com.neovisionaries.ws.client.ListenerManager.callOnBinaryMessage(ListenerManager.java:385) ~[JDASpigot.jar:?]
        at com.neovisionaries.ws.client.ReadingThread.callOnBinaryMessage(ReadingThread.java:276) ~[JDASpigot.jar:?]
        at com.neovisionaries.ws.client.ReadingThread.handleBinaryFrame(ReadingThread.java:996) ~[JDASpigot.jar:?]
        at com.neovisionaries.ws.client.ReadingThread.handleFrame(ReadingThread.java:755) ~[JDASpigot.jar:?]
        at com.neovisionaries.ws.client.ReadingThread.main(ReadingThread.java:108) ~[JDASpigot.jar:?]
        at com.neovisionaries.ws.client.ReadingThread.runMain(ReadingThread.java:64) ~[JDASpigot.jar:?]
        at com.neovisionaries.ws.client.WebSocketThread.run(WebSocketThread.java:45) ~[JDASpigot.jar:?] 
turbid solar
#

You need to initialize luckPerms variable

unreal mantle
#

@robust stirrup Main Class:

Add This variable


  private LuckPerms luckPerms;

Add this method below onEnable method

  public static LuckPerms getLuckperms() {
    return luckPerms;
  }

Change Luckperms api To luckPerms

Event Class:

Add constructor

public Add() {
  luckPerms = OnEnable.getLuckperms();
}
robust stirrup
unreal mantle
#

above the event handler

robust stirrup
unreal mantle
#

the getluckperms method needs to go below the onEnable method

#

And you need to add return luckPerms; to it

robust stirrup
#

it was duplicated

#

now it's just below onEnable

#

@unreal mantle if it is insideonEnable the event class does not detect

frank driftBOT
#

Hey Guidi! Please don't tag helpful/staff members directly.

unreal mantle
#

You don't put it inside the onenable method....

#

You put it under that method...

robust stirrup
#

likethis?

unreal mantle
#

Move the getLuckperms() method to UNDER your onDisable method. So it is the LAST method in the class

unreal mantle
#

Good. Now remove the duplicate variable up the top. As you can't have two variables the same.

unreal mantle
#

And change LuckPerms luckperms to luckPerms

#

In the onEnable method

unreal mantle
#

You didn't do what I said.

night pier
#

in the onEnable method

unreal mantle
#

Make it so its

luckPerms = provider.getProvider()

unreal mantle
#

Now try it.

robust stirrup
#

God please work

#

I want to sleep

robust stirrup
wispy stump
#

How my object is an object

wispy stump
#

solved

spring stump
#

Can modifying permissions via the API cause lag?

For some reason LuckPerms is the only thing showing up in a timings report out of that entire class

#

also weird because I don't execute any commands in there

nocturne elbow
#

From what it says there almost all of that time (literally all of the 8+ seconds, lol) is spent inside whichever lambda in "ServerManager", rather than in LP classes itself

#

Though if you want a potentially more useful report I really suggest using Spark plugin instead (I don't really know how to read timings, uh)

spring stump
#

hmm, the only lambda in there is a .5 second delayed task.

#

Switched it to a regular runnable instead of a lambda

#
/**
     * New player specific actions
     * 
     * @param player
     */
    private void setupNewbie(Player player) {
        LuckPermsUtil lpUtil = LuckPermsUtil.getInstance();
        lpUtil.addPermissions(player, "mcpe.newbie", "cmi.keepinventory", "cmi.keepexp");

    }

This is the only place where I interact with LuckPerms in that calss

nocturne elbow
#

whatever you're doing, a lot of the time is consumed by that Json class monkas

spring stump
#

wait, where did you see JSON

nocturne elbow
spring stump
#

🤦‍♂️ I was accessing the files Sync

mild flax
#

I need help. I want all users who are in the Admin group.

unreal mantle
#

/lp group admin listmembers

mild flax
#

With the API

#

I have this

ArrayList<UUID> teamUser = new ArrayList<>();
luckPerms.getUserManager().getUniqueUsers().thenAcceptAsync(uuids -> {
  uuids.forEach(uuid -> {
    luckPerms.getUserManager().loadUser(uuid).thenAcceptAsync(user -> {
      Collection<Group> inheritedGroups = user.getInheritedGroups(user.getQueryOptions());
      if (inheritedGroups.stream().anyMatch(g -> g.getName().equals("admin"))) {
        teamUser.add(uuid);
      }
    });
  });
});```
But the list are all time zero.
unreal mantle
# mild flax With the API
        List<String> admins = new ArrayList<>();
        for(User player : luckPerms.getUserManager().getLoadedUsers()) {
          if(player.getInheritedGroups(QueryOptions.defaultContextualOptions()).contains(luckPerms.getGroupManager().getGroup("admin"))) {
            admins.add(player.getUsername());
          }
        }

Try something like this

#

Obviously use your own list, that's just an example

mild flax
#

I already have it, unfortunately I had a typo in the group name.
Thanks anyway.

timber inlet
#

deos luckperms api work on velocity

#

if so, how do I obtain the instance of the api

#

I got this in my main class but when I boot up the plugin into velocity, it doesnt work

public static LuckPerms luckPerms = LuckPermsProvider.get();
nocturne elbow
#

LP isn't enabled by the time the class is initialized

#

nor constructed for that matter either

#

you need to wait until err... whichever moment velocity considers a plugin to be "enabled", then you can access the LP API

timber inlet
#

so make it wait until luckperms is enabled

#

how do I code that?

#

im fairly new to velocity api

nocturne elbow
#

No idea, I never used the Velocity API

#

Isn't there a ProxyInitializedEvent or something similar?

timber inlet
#

oh ya

#

so what do I put in there

nocturne elbow
#

get the LP API in there

timber inlet
#

like this?

    @Subscribe
    public void onStart(ProxyInitializeEvent event) {
        luckPerms = LuckPermsProvider.get();
    }
nocturne elbow
#

I suppose, looks correct ig

#

make sure to add LP as a plugin dependency

timber inlet
#

I did

#

YAS

#

it works

#

thank a lot

final adder
#

Hi, i got something really strange with luckperm

I got many plugins that use luckperm API, or just execute console commands like "./lp user player permission set perm" (basic things so)
And sometimes (without any founded log), commands are not executed, for exemple in one of my plugins i add to a player 5 permissions when he do something and randomly sometimes one of the 5 is not given (same issue with many plugins that give a permission to a player)

And notice that all theses plugins were used in an other server that i manage and the issue has never been seen

crystal blade
# final adder Hi, i got something really strange with luckperm I got many plugins that use lu...

I'm new to this stuff, but I suspect that if you've got it working on one server but not another then its probably not a gernally known bug and something specific to your setup for that server. You'd probably be able to get a help more quickly if you give as many details as you can. like what plugins your using that are causing this (if its a self made plugin a link to the source code). In what situations have you noticed this happening? You're going to want to give enough information that someone who knows what they are doing could recreate it.

tender hawk
#

how to remove a group from a user?

long abyss
#

And

frank driftBOT
serene saffron
#

I want to code a team plugin and I want it to be such as
/teamjoin (red)

and it adds u to a luckperms group red, is that possible? How can I do that?

and when the game is over it removes you

nocturne furnace
#

Hello how are you ppl?
Anyone know how to get all groups that the user is in?

#

LuckPerms api = LuckPermsProvider.get();
User user = api.getPlayerAdapter(Player.class).getUser(p);

#

user.getGroupsNames()????

nocturne elbow