You can take a look at the cookbook example for adding groups (without the clear(NodeType.INHERITANCE) of course) https://github.com/LuckPerms/api-cookbook/blob/master/src/main/java/me/lucko/lpcookbook/commands/SetGroupCommand.java
Might also want to check out the general API usage page on the wiki https://luckperms.net/wiki/Developer-API-Usage it contains lots of info you'll find yourself using
#luckperms-api
1 messages · Page 52 of 1
How do I remove the player from the group? please
user.removeGroup(g)
user.setPrimaryGroup(g) ?
Build and InheritanceNode for that group, and call remove(node) on user.data()
I suggest you check out these ones as well for general guidance ^^
On line 52 I'm getting a Unhandled exception executing command error, have no idea why. Yes, I read the wiki but I also have 30 IQ so
Pastebin
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
err, and what's the error?
Dont mean to be rude but I said it in my ask for help, there is a unhandled exception executing command on line 52
Yeah but like, is there no stack trace?
That can't possibly be the single thing about the error
Hold on imma reread the wiki and then ill ask my question again if i still cant get it working
I mightve just found something on the wiki
🤨
🤨
🤨
🤨
🤨
🤨
hello, i'm new at APIs and i was trying the lp one.
here i was in the docs, and i was wondering how to get the luckperms instance
do i need to use api.getPlayerAdapter ecc...?
cause luckperms.getPlayerAdapter ecc... is not working
(i'm new at spigot dev lol)
All I did is make a private variable for luckperms, then create a getter for it, and initialize that variable with the = provider.getProvider()
Then just call the getter
Remove the LuckPerms from the LuckPerms api =...
since you already have LuckPerms api at the top
then its done like this?
Then you can just create a getter for the variable and then you can call the getter whenever you need to use the api
oh yeah its working now. tysm ^^
You should look at using Dependency injection though, instead of static 😉
hello again! i was wondering how to add a user to a group.. i tried by doing java user.setPrimaryGroup(group) but it isnt working
can anyone help me about this?
!cookbook
The cookbook is a working example plugin which shows how to get/change data for users and groups, listen to LuckPerms events, and more.
thankyou!
Hello
Hi
guys, i want to make a listener that runs when a rank ("diamond") expires from a player
what's the eventclass called?
NodeRemoveEvent
nvm, i fixed
Good morning! Is it possible to find out the remaining time from a temporary group of a user?
My function #refresh should be triggered when a user gets a new group or loses one, right? Because exactly this does not happen.
package de.playunlimited.limitdiscord.bungeecord.listener;
import de.playunlimited.limitdiscord.bungeecord.BungeeCordPlugin;
import de.playunlimited.limitdiscord.bungeecord.mysql.MySQLApi;
import de.playunlimited.limitdiscord.discord.action.SyncRoles;
import net.luckperms.api.LuckPerms;
import net.luckperms.api.LuckPermsProvider;
import net.luckperms.api.event.EventBus;
import net.luckperms.api.event.node.NodeAddEvent;
import net.luckperms.api.event.node.NodeRemoveEvent;
import net.luckperms.api.model.user.User;
import net.md_5.bungee.api.plugin.Plugin;
public class LuckPermsListener {
public LuckPermsListener() {
LuckPerms api = LuckPermsProvider.get();
EventBus eventBus = api.getEventBus();
Plugin plugin = BungeeCordPlugin.getPlugin();
eventBus.subscribe(plugin, NodeAddEvent.class, event -> refresh((User) event.getTarget()));
eventBus.subscribe(plugin, NodeRemoveEvent.class, event -> refresh((User) event.getTarget()));
}
private void refresh(User user) {
System.out.println("refresh process");
if (user != null) {
System.out.println("user is not null");
String uuid = user.getUniqueId().toString();
if (MySQLApi.getMySQLApi().isVerified(uuid))
SyncRoles.syncRoles(uuid);
}
}
}
Are questions about a Java plug-in code also answered here? I have the problem that when I query the permissions like this:
if (player.hasPermission ("command.use")) { }
Tabbing works, but when I want to do it through another class, tabbing doesn't work.
For example:
if (player.hasPermission (PermissionClass.command1)) { }
Authorization class would be:
public static String command1 = "command.use".
By tabbing I mean, for example:
/lp user Bapty permission set comma -> tab (for command.use)
Can anyone help?
Start reading from here #luckperms-api message
Does anything at all happen? Any errors, any of the print statements…?
I'll do, thank you
rate my cringy variant (and unsafe likely) 😄
public static Instant getExpire(String playername, String node) {
User user = LuckPermsProvider.get().getUserManager().getUser(playername);
return user.getNodes().stream()
.filter(n -> n.getKey().equals(node) && n.hasExpiry())
.findFirst().get().getExpiry();
}
why unsafe?
It' not tested and I'm sure there are several nullpointer exceptions may be here.
user can be null, and the node might not exists
And LuckPermsProvider could technically be null
?
register them in your plugin.yml
But I don't want that.
?
that's the only way to tell the server / other plugins about the permissions in your plugin
It works if I put them right in the quotation marks.
if(player.hasPermission("")){}
they are functionally the same so something else must be broken or different
Did you add the permission via command before?
it is worth noting that after you've performed a hasPermission check at least once, LP will "know" about the permission
But why does it work if I enter the permission directly and not when I query it through another class?
No.
they are functionally the same so something else must be broken or different
What difference does it make whether I do "if(player.hasPermission("command.use")) " or "if(player.hasPermission(CommandUtil.command1))" -> "public static String command1 = "command.use""?
But what?
None unless you change the field value during runtime
Simply changing it from passing a string literal to passing a String field doesn't make a difference
But I would like to have all permissions queried via a central class.
Then do that
It literally makes no difference
they are functionally the same so something else must be broken or different
Yes, but what is that supposed to be?
I don't know, it's your codebase, not ours
But if it's the same it doesn't make any sense.
From what you've shared, that works fine and LP will suggest it fine
They're literally the same thing
It's time for you to debug, add print statements at every step, ideally attach a debugger and see the state of the whole thing from your ide as it's running, keeping to repeat the same thing to us doesn't change how Java works and that it's your code with your changes, we don't know them
I just tried again and now it suddenly works. Please excuse me. Thank you very much for your effort.
probably this then ^
You mean as soon as the command has been carried out?
I didn't pay attention to that ... I tried right at the beginning and it just didn't work ... I'm sorry.
Thanks very much!
How do i get all the groups in a server into an array?
GetgroupsManager getloadedgroups or something can't remember the exact method call but I know you need to use getgroupmanager
are all groups loaded by default?
Yeah
i did it but i need to get the name of each group
nvm
found it
is there a way I can get the user's current group in a specific track
also, how can I determine which track a group belongs to
If you're looking for the highest group a user has on a track, I currently use
public Optional<Group> getTopGroup(User user, Track track) {
SortedSet<Node> allNodes = user.getDistinctNodes();
if (!allNodes.isEmpty()) {
GroupManager groupManager = luckPerms.getGroupManager();
return allNodes.stream()
.filter(NodeType.INHERITANCE::matches)
.map(NodeType.INHERITANCE::cast)
.map(InheritanceNode::getGroupName)
.map(groupManager::getGroup)
.filter(Objects::nonNull)
.filter(track::containsGroup)
.max(Comparator.comparingInt(g -> g.getWeight().orElse(0)));
}
return Optional.empty();
}
``` which works fine, though I'm not positive it's the optimal way of doing it
thanks, I hope there's something simpler but lp sure can be verbose
If there is, Cunningham's law will take over 😅
I see no better way that could go
You that looks like the best way from what I can tell
if it works why change it xD
hey everybody, already sorry for my bad english. Also I'm a beginner with java coding... ^^
just wanted to ask if someone has a simple answer on my following problem.
Currently I'm trying to add the users current group into a scoreboard. So far, I can already seperate between someone with op
and casual players. See my code here: https://www.toptal.com/developers/hastebin/enimolohaf.less
I've already added the luckyperms api into mavens dependencies. But besides that, im stuck :D
Already read trough the wiki, but as I said, im a beginner and.. that didnt really helped me
You’ll want to use the api to get their prefix
There is an example in the api wiki cookbook
which example do you mean? the one which named 'Finding a players group'?
thank you for sending... already brought me a step further i guess
but how exactly to i implement that? for example which things need to be put into the main class and also the scoreboard class? This is my current scoreboard code: https://www.toptal.com/developers/hastebin/icekowawul.swift
Im trying to add those prefixes into the scoreboard since hours now, but i dont get it... if someone has time and might check my code, would be pretty nice :^)
Main - LatteMC.java: https://www.toptal.com/developers/hastebin/otibarequm.java
TestScoreboard: https://www.toptal.com/developers/hastebin/jucuyofize.java
ScoreboardBuilder.java: https://www.toptal.com/developers/hastebin/ovuyuxaxiy.java
yes, i did add the dependencies into the pom
thats what my IntelliJ says
not a question about the API, but just question on the coding style. is there a reason why NonNull/Nullable is used in some places and not others?
For things like Collections/CompletableFutures/Optionals (or any kind of "value container"), it's sort of implied that they shouldn't be null… and it is kind of bad API design for those, you'd return instead an empty collection, a failed future or an empty optional
When returning values themselves such as Strings, you'd let the API user know whether they can get null or not
It does get called for prefixes, show us the event code
that command would call the NodeClearEvent since it would remove every prefix node with that weight
NodeRemove is for single node removals, NodeClear for multiple
hi
can i integrate this api with nameless?
to create a nameless module
i explain what i want to do
I have a non-premium server, and I want to link the ranks of my users with the forum, so it had occurred to me to use the integration of auth me to register, and give the ranks with the luckperms
@hybrid pantheroh, you are here hahaha
Hey anchelthe! Please don't tag helpful/staff members directly.
sorry
i mean, you could. it would be a bit of a headache to write, but nameless provides the right api endpoints for that to be possible + obviously luckperms api makes it possible as well
So, it is possible, but very difficult, right?
How much do you estimate a developer could charge me?
Considering you're using non premium. Uuids would change every now and then and break it.
but for that there is a login system
The truth is that probably yes, but it is more difficult to grow, apart from the fact that I started as non-premium, now I cannot change ...
Never too late to change.
and what do I do with my users? and the people who have paid?
daily ethics debate in luckperms
is there always this debate?
Idk your server. You pick. I'm only giving you advice which you asked for. Non premium servers always have a chance of breaking everything. An provide countless issues. So its your choice what you're wanting to do.
None have arisen so far, can they appear out of nowhere in the future?
If I'm honest, if the server started it today, it would leave the online option to true, but now I can't do that anymore ...
Yep. That's the unpredictability of cracked servers. A single uuid change or name change can break so much
You mean when a premium user changes their account name? or what?
Non premium.
but the non-premium ones, they don't have an id registered by mojang, right?
Premium users have a dedicated uuid that doesn't change so things go off that. Non premium can change name and uuid
ah ok, thanks
well...
but how can you change the name of the non-premium ones? changing of acount, right?
The client they use let's them change it.
yea, i know
but that is like create a diferent acount, right?
they do not keep the same uuid
I haven't used cracked clients so can't remember.
hey guys im running a plugin and wanted to change the people who can use a specfic command from default to op, how do i do this 😄
Probably. But if nonpremium user name changes, it will break it for that user.
mmmm
it simply loose their rank
i have to put a package of acount transfere on my webstore or something
or an area of the staff that is dedicated to that, free
I mean, free for the customer
well, no customer
because it is free xd
uuids don’t change
ohh
i see
ur right
ahh
cracked servers!!!
yea cracked servers generate a random uuid for cracked players
Based on name
i don’t think so
I think so
ok
ah fax
i only saw OfflienPlayer
and was oh ok then
you think correctly
i didn’t think so
i knew so
If I wanted to create a command like /giveytrank <player> how would I do this (using luckperms ofc)?
Get an instance of the api first, then get the user then add the group
I want to luckperms autocomplete my plugin permissions on website
How I can do that?
The LP web-editor will suggest permissions that are registered correctly and permission checks have been made for them since last restart
regarding to my message here, I've made this post on spigotmc https://www.spigotmc.org/threads/luckperms-api-get-group-prefix-into-scoreboard.540952/#post-4336453
might anyone have a answer on that? especially my last two comments i have made are important for me ^^
Why use the api? Why not just use a placeholder?
what exactly do you mean?
!placeholder
Display data such as user prefixes and groups from LuckPerms in other plugins.
Read more
Otherwise, all you need to do is get the group, then get the cacheddata then get metadata then get prefix
...getCachedData().getMetaData().getPrefix()
@hollow niche
thank you.. ill check that
so i've installed PlaceholderAPI, the latest version of the expansion and reloaded
what do i have to do to use it in my code? do i have to import smth?
ah ive found its github
ill try that first :)
...
and reloaded
Did you use /reload?
If you do never use /reload
ive used /papi reload
It kinda works, but still give me a error: https://www.toptal.com/developers/hastebin/leyiyoqilo.properties
code: https://www.toptal.com/developers/hastebin/xazelaludo.java
also gets me the prefix, but not the rest of the join message:
jesus... i finally got it
thank you
You never defined the luckPerms variable
private LuckPerms luckPerms; this?
I have used that variable to use the methods that you see in the picture
I want to add the permission that I add as second argument to the method to the user, I have put as it comes in the documentation but the error that I get is what you see in the hastebin that I have passed
It tells me that the value is null...
Yeah you didn’t initialize the luckPerms variable to anything
And what do I have to start it? The variable is simply to call the API.
You’re softdepending LuckPermsAPI. it’s just LuckPerms
Well that's what I mean, it indicates that it is not a softdepend of my plugin, isn't it?
It’s not, because you’re not soft depending the right name.
What is the name I should put then?
oh ok sorry, my english is not good xD
Is there a way that instead of adding, it sets it in case there is an existing one to replace it?
!cookbook
The cookbook is a working example plugin which shows how to get/change data for users and groups, listen to LuckPerms events, and more.
Hi How to get the time of the range in days or in seconds because in case the code comes out like this when there is a range with temp 2022-01-13T
Code
if (user != null) {
for (Node node : user.getNodes()) {
score = score.replace("%rank_expire%", String.valueOf(node.getExpiry()));
}
}
What I want to do is make it appear in scoreboard expires: 1d (days) or Seconds
LuckPerms doesn't do anything related to chat formatting, but how is this API related? 
Hey MrKebabas! Please don't tag helpful/staff members directly.
Oh sorry @frank drift
OPS...
¿?
There’s an example
...
...
...
That's not something LP provides, LP gives you the Instant the node expires at or the Duration until it expires
You may format it however you want, but it's up to you to do
is that so? If (user != null) {
for (Node node : user.getNodes()) {
score = score.replace("%rank_expire%", String.valueOf(node.getDuration()));
}
}
If i update nodes for a user (like the example in the cookbook plugin's "AddPermissionCommand"), how would I go about notifying other servers of the change?
like, in the same way as the notification goes out if I were to manually do /lp user SomeUser parent add SomeGroup as a player.
The issue is that if the player connects to a server that still has data cached from a point in time before a node got added via the api (in this instance, an inheritance node), the server isn't notified and continues to use the old data.
This isn't so much an issue for servers that don't have cached data because they'll just load it from the SQL database
I can see in the developer-api-usage page that I can subscribe to LP's events, but not any way to send out my own
I checked the pins of all the other channels but this one, thanks
When using the NodeRemoveEvent in my plugin, it gets called everytime a node is added and removed rather than just removed
my code is: https://pastebin.com/dwKXHPN4
Pastebin
Pastebin.com is the number one paste tool since 2002. Pastebin is a website where you can store text online for a set period of time.
setting a node with a value involves removing the node with opposite value
ok, so in this case, check if the node is false?
Thanks
it depends on your needs 🤷♀️
if that does the job for you, absolutely
just needing to check if its false/unset, which is exactly what i wanted
sounds appropriate
I edited the luckperms plugin for my own server, but now I'm having a problem, the placeholderapi plugin gives an error
help pls
Seems like you broke it!
My suggestion would be to not make changes to the plugin if you don’t know what you’re doing
I just wanted to edit the English texts and commands and permissions in the console.
./lp -> /rp
example
hello, I have a question, if I check for Player#hasPermission in the bungeecord api, will it check for luckperms perms?
someone?
I need this asap please
If you have LP on the proxy
so it overrides it?
Yeah that's what LuckPerms is for
alr thanks
Hi everyone I have implemented the luckperms bees and I would like to put in the events of the "onQuit" which verifies if a player has the permission if it is not there it removes it through luckperms only that reading the bees and putting only the part of the permission check doesn't work it asks me more and more cos and to import
// run a permission check!
Tristate checkResult = permissionData.checkPermission("some.permission.node");
// the same as what Player#hasPermission would return
boolean checkResultAsBoolean = checkResult.asBoolean();
public boolean hasPermission(User user, String permission) {
return user.getCachedData().getPermissionData().checkPermission(permission).asBoolean();
}
what?
And what is recommended on the site in the Developer API part
what
Sorry but I don't understand what you're trying to say or do..
To check if a player has a certain permission if you have to remove it
Once again, if you change things without knowing what you're doing, things will break.
It has nothing to do with the change I made.

my editor subdomain is not working either
why are you attempting to rebrand luckperms ??
fantastic question
Does anyone know if there is a way through the API to create a new group? I couldn't find it on the wiki. I feel like there is probably a better method than to run /lp creategroup with Bukkit.dispatchCommand() and wait a tick before trying to use the new group, but I am not sure what it is
The cookbook is a working example plugin which shows how to get/change data for users and groups, listen to LuckPerms events, and more.
Doesn’t seem like it, nevermind.
Yeah, I already checked. I was surprised because I assumed it's be a pretty basic thing
getGroupManager().createAndLoadGroup(String name)
I swear that didn't pop up on my autocomplete when I typed in create lol. Thanks
That will create a new group in the plugins storage provider and then load it.
If it already is created, it will just load it
Won't the rank already be loaded if it exists or no?
Not 100% sure, but might depend if a player online is in that group, or inherits from that group
Alright, gotcha
or if you are obviously editing said group, then it loads it
You can always check if a group is loaded with getGroupManager().isLoaded(String name)
I learned the hard way that LP doesn't like it if you try to use vault to add a group to a player if the group doesn't exist
Yeah, it generally won't like that
That's why if you were going to use vault to add the player to a group you'd check if the group exists first
But if you're using LP api, just add the group to the player with that
Yeah but I didn't see a way with vault to create a group, hence why I am using the LP api
Fair enough, it's pretty easy to create a group through the api
Well I managed to do something interesting. /lp user me info doesn't show that I am in the group I added myself to, but when my plugin checks if I have the perm for the group group.group I do
How did you add yourself to the group
I made an InheritanceNode using the builder and gave it the group, then did user.data().add(node)
Didn't realize I had to do that
Yeah, after you modify a user you need to save it back to the storage provider
I guess that makes sense
If you want, you can actually use
luckPerms.getUserManager().modifyUser(userUuid, user -> {
// Add the permission
user.data().add(Node.builder(permission).build());
});
To auto save
I assume I have to do the same thing if I modify a group
Yeah, you'll need to save the group as well
an excuse to use a lambda, say no more
The modifyUser method, will do the thing, then it will save at the end
🤨
Perfect, thank you
On any platform, how can I listen to updates to users, groups, tracks, etc
Like what? What are you wanting to do?
Need to listen to every update to keep something in sync
can i get the priority of the user's prefix?
%luckperms_in_group% hi when I put this API it puts "no" or "yes" how to replace by ✘
(ping me )
thats not very cash money of you
so i've just realized that bukkit doesn't natively deal with or support wildcards in permissions
does luckperms inject anything such that calling bukkitPlayer#hasPermission(String permission) handles wildcards?
That should be possible with PAPI scripts (the no to X)
LP does handle wildcards, yes
how do I look up the meta value without using the CachedData?
I tried the following:
user.resolveInheritedNodes(queryOptions).stream()
.filter(NodeType.META::matches)
.map(NodeType.META::cast)
.filter(node -> node.getKey().equals(metaKey))
.map(MetaNode::getMetaValue)
.map(Integer::parseInt).reduce(Integer::sum)
but it doesn't return anything
nvm, got it. I needed to use getMetaKey instead of getKey
Hey 👋, I was looking for a way to get a list of members sorted by their group weight and since I haven't worked with Streams before I wasn't really sure how to do it
When using the accumulate tag to add time to a already existing temporary permission, it removes and adds the permission with the new time. This also calls the NodeRemoveEvent. Is there a way to check if time is being added and/or if the time has actually ran out?
Node#hasExpired I think it's called?
I’ll have to give it a try
Late response, but this worked. Thank you
what method i have to use for get all the nodes that a player has and copy them in a new user?
this is what i done
LuckPerms lp = LuckPermsProvider.get();
UUID oldUUID = UUID.fromString(args[1]); // the UUID of the player from which we will take the data
UserManager userManager = lp.getUserManager();
User newUser = lp.getPlayerAdapter(Player.class).getUser(target); //gets the "target" user what will receive the data from "oldUser"
CompletableFuture<User> oldUserFuture = userManager.loadUser(oldUUID);
oldUserFuture.thenAcceptAsync(oldUser -> {
//What to do now?
Collection<Node> oldNodes = oldUser.getNodes();
});
jaja discrods.gift
i wont be surpised if nobody is able to help with this but im using grakkit and when i try to use the luckperms api in a certain command i have it works perfectly fine, but in a different one calling the api with basically the same code causes .getUserManager().modifyUser(uuid, function) to never call my function. in my /nick command i the setLPMeta function (the code of which is attached in a screenshot) with setLPMeta(sender, "nickname", nick) where sender is the player who sent the message and nick is just a string with the nick they want, and this works fine, but in my /infolocation command i call it with setLPMeta(sender, 'tdmsinfo', 'sb') (again with sender being the player) and this seems to only work sometimes, doing nothing most of the time. the attached log you can see that the all the logs statements get run when i do the /nick command, but when i do /infolocation it never runs the one inside the modifyUser call that logs the user object. im stumped as to why it works in once place but not another
Yes
How can I change the prefix of a player / group (whichever is easier)
thats not very cash money of you
either way works ¯_(ツ)_/¯
Hello, with the LuckPerms API if i have a User Object, can i retrieve all their groups?
I am aware there is a getPrimaryGroup(); But i want to retrieve all of them
disregard i figured it out thank you
You're welcome!!
streams can be beautiful if written well
Is there any relationships of a group to track? So lets say i have group A can I determine the tracks its on?
The group doesn't know in what tracks it's in
A Track is basically a List<Group>
With some funny methods to make things a tad easier
That reminds me: reminder to self: improve track API too
mod abuse pinning
Based
Could look at /lp listgroups code? Iirc that shows the tracks a group is in
Im new to the API however, it would be useful it seems with the stream API to be able to use make use of the track. So like there are InheritanceNodes is it possible for a like a TrackNode?
obviously i don't know how it is designed so i may be wrong on this lol
what does the stream api have to do with Tracks 🤨
Nah, tracks are essentially a "simple" way for end users to have a promotion system, all it does is "remove the previous InheritanceNode and add the next one"
ah okay
For anyone wondering seems like this is how they get the TRACKS FOR A GROUP lol
List<String> tracks = allTracks.stream().filter(t -> t.containsGroup(group)).map(Track::getName).collect(Collectors.toList());
You mean the tracks for a group? 😄
sorry im all over the place LOL
Lmao it's fine
Guys i cant understand how to get a LuckPerm instance inside my Spigot plugin
PluginManager pm = Bukkit.getServer().getPluginManager();
if (pm.isPluginEnabled("LuckPerms")) {
ConsoleUtils.logInfo("Hooked LuckPerms.");
RegisteredServiceProvider<LuckPerms> provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class);
if (provider != null) {
this.luckPermsApi = provider.getProvider();
}
} else {
ConsoleUtils.logInfo("Can't hook LuckPerms.");
}
``` this is what i did so far
// in onEnable()
LuckPerms luckperms = getServer().getServicesManager().load(LuckPerms.class);
Is how I load it in my plugin, which i believe is how the wiki used to show it but now it's not... I've looked back through the commit history for the wiki, and nothing mentions changing of the way to get the luckperms api so I have no idea how i got my code to work...
it is entirely possible that i'm doing something the wrong way so my solution might not be correct
getLuckPermsApi() returns your luckperms variable
I am following the code written in the documentation but it is not working
other than the difference in how we get the LuckPerms variable, you're doing the same as what my code does and that isn't flagging up any warnings... Try restarting your IDE? I've had Idea tell me something isn't defined or whatever and a restart usually forced it to re-index stuff properly
let me try
nop
the only thing you included in your pom.xml is:
<!-- https://mvnrepository.com/artifact/me.lucko.luckperms/luckperms-api -->
<dependency>
<groupId>me.lucko.luckperms</groupId>
<artifactId>luckperms-api</artifactId>
<version>4.0</version>
</dependency>
ah
right?
API is at version 5 now
which might explain the issues you're getting if it's pulling an old API down
is how i've got it set up
No problem 
do you have an idea on how to get the "highest" rank for a player?
ex. if a player has Groups "User" and "Vip", i want to get "Vip" (which is higher)
get the primary group name from the user, get the group from the groupmanager, get its weight
thank you
Unrelated, I worked out where I got this way of loading the LP class from. The api-cookbook does it that way.
I'll raise a ticket on its repo in a bit
which i believe is how the wiki used to show it but now it's not.
mean this? https://luckperms.net/wiki/Developer-API#obtaining-an-instance-of-the-api its still there tho
The way my plugin gets the class is different than what the wiki shows
Which confused me as to how I managed to get a working instance the way I did but the API cookbook also does it the way I do it
(hopefully that made sense)
if (plugin.getLuckPermsApi() != null) {
net.luckperms.api.model.user.User luckUser = plugin.getLuckPermsApi().getUserManager().getUser(p.getName());
if (luckUser != null) {
embedMsg.addField("Rank", luckUser.getPrimaryGroup(), false);
}
}
java.lang.NullPointerException: Cannot invoke "net.luckperms.api.model.user.User.getPrimaryGroup()" because "luckUser" is null
How is this possible?
Is the user online?
no
how can i check for offline users?
how?
Learn how to use the LuckPerms API in your project.
Read more
Example usages
Read the Javadoc
thank you
Is there a way of getting the default context set? I'm basically trying to recreate the behavior of the various set commands when you don't pass in contexts, which use the contexts.json default-contexts
@ Luck 
The QueryOptionsRegistry::defaultContextualOptions' context set is empty, uh
yeah.. no D:
I kinda regret that feature
Or rather, regret how it was implemented
contexts.json shouldn’t be a thing really
And all that stuff should just be in the main configuration file
I think the reason I did it that way was because bukkits config library didn’t support what I needed in a nice way
as for this - yeah the API generally does not expose configuration info
the server name + static contexts are I think the only exceptions to that rule
hmmm
im using the luckperms api right now to get uuids from usernames for my whitelist plugin, but is there one like UserManager#loadUser or something that can look it up for users that haven't joined before?
i'm using velocity
Then query the Mojang api
ok
!api
Learn how to use the LuckPerms API in your project.
Read more
Example usages
Read the Javadoc
Hi question, i can't seem to find it. But what determines if it is a players primary group?
Cause i may think the way im determining getPlayerPrimary(group) is the wrong group 😮
By default, the highest weighted group a user inherits is their primary, although this is modifiable in the config. You can easily check which group LP thinks is someone's primary w/ /lp user <who> info
Okay thank you, that makes sense. I think im just going to get the players groups then the track im looking for then to ensure i don't get the weight of a group not on that track
hi
?
any one know why luckPerms.getGroupManager() is null?
full code:
public static boolean addPlayerToGroup(OfflinePlayer player, String group) {
**Group newGroup = luckPerms.getGroupManager().getGroup(group);**
if (newGroup == null) {
return false;
}
String playerName = player.getName();
if (playerName == null) {
return false;
}
User user = luckPerms.getUserManager().getUser(playerName);
if (user == null) {
return false;
}
InheritanceNode node = InheritanceNode.builder(group).build();
DataMutateResult result = user.data().add(node);
if (result == DataMutateResult.FAIL) {
return false;
}
luckPerms.getUserManager().saveUser(user);
return true;
}
public static User getUser(UUID uniqueId) {
UserManager userManager = luckPerms.getUserManager();
CompletableFuture<User> userFuture = userManager.loadUser(uniqueId);
return userFuture.join();
}
(i have the LuckPerms luckPerms = new LuckPerms() and all the other stuff)
you have the what?
🥲
you create a new luckperms instance?
who hit you on the head because that is definitely not how you use an API
!cookbook
The cookbook is a working example plugin which shows how to get/change data for users and groups, listen to LuckPerms events, and more.
@cerulean apex
thats not how you get a luckperms instance at all
have a look at https://github.com/LuckPerms/api-cookbook/blob/master/src/main/java/me/lucko/lpcookbook/CookbookPlugin.java as suggested above
im like dying right now
who told you to ever do that
and of course it returns null if your anonymous class returns null
just what i was typing out lmao
okokok
now that its working I need help with removing some one from a group
nvm
Does UserManager::searchAll work on offline users, and if so is there a method that only works on online ones? Just trying to grab all users who inherit a group and update some cached values based on meta
Hello!
I am trying at the moment to get the groups of a player, that are direct linked. No inherits.
I saw something about the Flag.RESOLVE_INHERITANCE but I am not sure where to set that.
Is there some link to look that up or does anyone have some small codeline?
EDIT: NVM. I think I just found it....
!api
Learn how to use the LuckPerms API in your project.
Read more
Example usages
Read the Javadoc
not exactly a question about the api, but where are luck perm users/players cached?
AbstractManager (which is extended by.. managers, among them there's the AbstractUserManager, extended by StandardUserManager)
then there's the UserHousekeeper which handles the scheduled user unloading
!api
Learn how to use the LuckPerms API in your project.
Read more
Example usages
Read the Javadoc
is this call expensive to do? Might want to use ContextSet but now sure how I would perform the permission lookup
Player p = event.getPlayer();
LuckPerms api = LuckPermsProvider.get();
User user = api.getPlayerAdapter(Player.class).getUser(p);
String permissionMultipler = user.resolveDistinctInheritedNodes(QueryOptions.nonContextual()).stream().map(Node::getKey).filter(permission -> permission.startsWith("bigdrop.multiplier.")).findFirst().get();
my users have different permission values with numbers after the permission bigdrop.multiplier. so I don't see how I would be able to use metadata (ex bigdrop.multiplier.10000, bigdrop.multiplier.95
that's exactly what meta nodes are for
And they're cached, update as needed, get contexts applied etc etc
Read these specific sections
https://luckperms.net/wiki/Prefixes,-Suffixes-&-Meta#meta
https://luckperms.net/wiki/Developer-API-Usage#store-and-query-custom-metadata
oh I see, I just need to convert all the permissions to meta
is it possible to sync the perms from the database with the api?
like do /lp sync without executing the command?
LuckPerms#runUpdateTask
Note that that's just (the equivalent of) /lp sync and not /lp networksync which propagates the task throughout the network, for that you'd have to runUpdateTask + get the MessagingService and call #pushUpdate (
)
thanks, because on every server "pluginmsg" is set but its still not syncing autmatically
that will sync by default
but there are like a bajillion settings controlling how syncing works
trying to work around that with a custom made plugin may or may not yield the same result
hmm
i tried setting auto-sync or what its called to 3, maybe it works then
¯_(ツ)_/¯
pluginmsg requires players to be online for the message to be propagated, both in the server that runs the task and in the server that will receive the update message
auto-push-updates should be set to true, and it is by default
sync-minutes set as -1 is fine for most people as it will just push/pull updates as necessary (when changes are made)
in general if you're using sql-based storage (postgresql, mariadb, mysql), setting it to sql is more than enough
for other cases (mongodb) personally I suggest redis or rabbitmq, I myself am not super keen about pluginmsg, it's not my jam
oh thats the problem, when im on one server no one is on the other server
and then it doesnt get synced
whats redis?
thx
yo im tryna loop through offline players using uuid and checking if their group/them have permissions but its not working as expected can anyone help me
if(resultSet.next()) {
String uuid = resultSet.getString("uuid");
System.out.println(uuid);
plugin.getLuckPermsApi().getUserManager().loadUser(UUID.fromString(uuid)).thenAcceptAsync(user -> {
user.getNodes(NodeType.PERMISSION).forEach(p -> {
System.out.println("passed 1");
if(p.getValue()) {
System.out.println("passed 2");
if(p.getPermission().equals("mcevents.staff")) {
System.out.println("passed 3");
try {
System.out.println("adding " + UUID.fromString(uuid));
staffTime.put(UUID.fromString(uuid), resultSet.getInt("playtime"));
} catch (SQLException e) {
e.printStackTrace();
}
}
}
});
});
}
weird
while(resultSet.next()) {
String uuid = resultSet.getString("uuid");
System.out.println(uuid);
plugin.getLuckPermsApi().getUserManager().loadUser(UUID.fromString(uuid)).thenAcceptAsync(user -> {
user.getNodes(NodeType.PERMISSION).forEach(p -> {
System.out.println("passed 1");
if(p.getValue()) {
System.out.println("passed 2");
if(p.getPermission().equals("mcevents.staff")) {
System.out.println("passed 3");
try {
System.out.println("adding " + UUID.fromString(uuid));
staffTime.put(UUID.fromString(uuid), resultSet.getInt("playtime"));
} catch (SQLException e) {
e.printStackTrace();
}
}
}
});
});
}
}
gonna try this
only loads one or two players
uh...
[20:24:11] [ForkJoinPool.commonPool-worker-15/INFO]: passed 1
[20:24:11] [ForkJoinPool.commonPool-worker-15/INFO]: passed 2
loading the user is done async and your processing happens both in another thread and at a later time
that is to say you're basically fucking up all your resultset usage
are you trying to get all users that have a certain permission?
yep, UserManager#searchAll, then process all of them against your db
any examples
!cookbook
The cookbook is a working example plugin which shows how to get/change data for users and groups, listen to LuckPerms events, and more.
there's a "group members command" example in there that uses the searchAll function
what
like get all players that have that permission nomatter if its from group or just user
yeah no there's no such thing, searchAll looks up those that have the permission in their own data, not inherited
any idea wat i could do
mm not without loading every single user to check
i wanted to just loop on start to find all staff and add them to an arraylist
how would i do that
ideally you'd check if they have the permission as they log in tho
do you really need ALL of the UUIDs at ALL times? before during and after they're playing?
How i can get all player uuid in a group?
Through the api, say I have the messaging-channel set to bungee. how do I see if player has permission {x} on server1 so i can grant them access to {y} on server2
Why do that through API, sounds like something just using a remote database can do
I was going to check for Rank names and duplicate them, and flush the permissions. I'm using Lilypad and needed a way to make ranks in hubs.
!sync
To sync data between servers, you need to connect each LuckPerms plugin to the same database (for example MySQL) and set up a messaging service.
!context
You can set a permission or group on a per-world/per-server basis, through what we call "contexts".
Read more
Well I didn't see this part, but I did see the part above. Thanks
When I type the command with server in it, how do I actually sync that with the hub or is it like that by default ?
You need to make sure they are connected to the same remote database, and you have luckperms on all servers.
Oh database alright, I just had it still set to lily pad
whats up with the display_name node type? cant find any obvious way to use it, atleast in the same manner of prefix and suffixes
the displayname is used instead of the actual group name wherever a group name would be returned
Oh, so not for players? makes sense
Would be cool if it could be used on a player like the prefix and suffix so you could grab that easily if you are making a chat plugin.
Was playing around with a forge based chat formatter and saw that , couldn't find any documentation on it figured it could be used like prefix and suffix types
Ended up just making my own meta key for it
since lp works with vault, the vault placeholder %vault_rank% should return the group name. ofc you can only use this in chat if your chat plugin has support for it. most, like for instance essentials, introduce their very own which also hook directly into vault, for essx, that would be {group}.
Where you put it depends on how you want to lay out your plugin
If you mean like "where in the class do I put it", LP API is not for java newbies,
its just my first plugin so i just use main class
in onEnable
i just want to be able to check if the user has a role
cycle through all roles they have and do something
Learn how to use the LuckPerms API in your project.
Read more
Example usages
Read the Javadoc
How can I check if a group has been modified, in terms of the prefix? I have already used an event, for the overview here already once the code to it:
final LuckPerms api = LuckPermsProvider.get();
api.getEventBus().subscribe(LimitProxy.getPlugin(), NodeAddEvent.class, event -> {
if (!event.isUser()) return;
final Node node = event.getNode();
if (node instanceof InheritanceNode) {
final ProxiedPlayer player = ProxyServer.getInstance().getPlayer(((User) event.getTarget()).getUniqueId());
if (player != null) {
updatePlayerPermissionGroup(player);
ProxyServer.getInstance().getConsole().sendMessage("NodeAddEvent, update team info");
}
}
});
public interface PrefixNode
extends Builder>```
PrefixNode has 2 methods, 1 extensions, and 5 super interfaces.
Description:
A sub-type of Node used to store prefix assignments.
Requested by: powercas_gamer • lp
thanks 🙂
one more question,. how can i get the node from NodeMutateEvent
Ehm, he doesn't trigger on prefix change?
public ScoreboardStyle() {
final LuckPerms api = LuckPermsProvider.get();
api.getEventBus().subscribe(LimitProxy.getPlugin(), NodeAddEvent.class, event -> {
final Node node = event.getNode();
if (node instanceof InheritanceNode) {
if (!event.isUser()) return;
final ProxiedPlayer player = ProxyServer.getInstance().getPlayer(((User) event.getTarget()).getUniqueId());
if (player != null) {
updatePlayerPermissionGroup(player);
ProxyServer.getInstance().getConsole().sendMessage("NodeAddEvent, update team info");
}
} else if (node instanceof PrefixNode) {
if (!event.isGroup()) return;
final Group group = (Group) event.getTarget();
updatePermissionGroupMeta(group);
ProxyServer.getInstance().getConsole().sendMessage("NodeAddEvent:PrefixNode, update team META");
}
});
api.getEventBus().subscribe(LimitProxy.getPlugin(), NodeRemoveEvent.class, event -> {
final Node node = event.getNode();
if (!event.isGroup()) return;
if (node instanceof PrefixNode) {
final Group group = (Group) event.getTarget();
updatePermissionGroupMeta(group);
ProxyServer.getInstance().getConsole().sendMessage("NodeRemoveEvent:PrefixNode, update team META");
}
});
}
if (provider == null) {
this.plugin.getLogger().severe("LuckPerms not found!");
Bukkit.shutdown();
return;
}
this.luckPerms = (LuckPerms)provider.getProvider()```
provider is null somehow
I tried to sout all the registered classes and it outputs LuckPerms but still provider is null
any ideas?
I'm having this problem too on 1.18
Are you (soft)depending on Luckperms?
yes
Make sure you aren't shading LuckPerms into your plugin, add the dependency as shown here https://luckperms.net/wiki/Developer-API#adding-luckperms-to-your-project (with scope provided / compileOnly)
CC @foggy flower @tough geyser
It was an error in our spigot fork. Thank you anyways!
How can I get all the groups that are in my server and put them in the Collection<String> required to get the highest group a player is in?
Nevermind I think I found a different way to do what I need
hello
How can I add a group to an entity?
The cookbook is a working example plugin which shows how to get/change data for users and groups, listen to LuckPerms events, and more.
why would you even attempt that...
Because I want to add Entities to the tab list
to do what though? display a pet wolf's name in tablist with a rank prefix?
Yes
I just want them under other players
So that entities won't come above normal players
So I want to add a group
That is configured in TAB
i see. as far as i know, pets get the same 'label' as their owners if you will. im unsure if that can be changed, but i know it can be disabled (pet name fix, TAB wiki lists it). entities themselves do not have a uuid like players do, so i dont think it would remotely be possible to even do that. if you really want pets displayed in tablist for example, it would be easier to just get a pet plugin which has placeholder which you can then use in your tablist format, perhaps even after the name of the players so its obvious whose pet it is.
Entities have UUID's.
id's, not uuids
they are not player entities, those are different
^ Just to show you
@nocturne elbow Could I do something with this then?
nmsHelper.sendPacket(player, new PacketPlayOutPlayerInfo(PacketPlayOutPlayerInfo.EnumPlayerInfoAction.a, this.entity));
nmsHelper.sendPacket(player, new PacketPlayOutNamedEntitySpawn(this.entity));
But if I do that
It shows above every other player
and thats not what i want
i think this is the same issue then as if you let tab add the prefix of its owner to the pet
im not sure exactly but somehow the owner and their pet are connected
i dont think you can break that connection
if you could, im sure someone else would have done this by now
No it is just a entity
I want to add
Not a pet that is connected to a player
just a entity that i spawn with nms
that is why i asked you if that is what you wanted to do
still, lp checks if an entity is a player
so working with lp and groups i dont see this happening at all
why not set a static hologram for above the entity and add a static text containing that name to tablist
so much easier, its just a config setting
!download
You can download LuckPerms for Bukkit/Spigot/Paper, BungeeCord, Sponge, Fabric, Nukkit and Velocity.
Additional downloads
Hello, how do you think I could get the remaining time of permission ? Of course with the API
what is a "leave"?
ho sorry shit traductor, the remaining time of permission
@left estuary theres a getExpiry method or something similar in Node iirc
Hi, I am facing some cases (a few only) where some new players are joining but not getting permission that I try to give them. How every, the code is really basic
@EventHandler
public void onPlayerFirstJoin(PlayerJoinEvent event) {
if(!event.getPlayer().hasPlayedBefore()) {
Player player = event.getPlayer();
List<String> permissions = new ArrayList<>();
permissions.add("historya.jobs.nojob");
LuckPermsUtils.addPlayerPermissions(player, permissions);
}
public static void addPlayerPermissions(Player player, List<String> permissions) {
luckPermsAPI.getUserManager().modifyUser(player.getUniqueId(), (User user) -> {
permissions.forEach(permission -> {
DataMutateResult result = user.data().add(Node.builder(permission).build());
if (!result.wasSuccessful()) {
Bukkit.getLogger().log(Level.WARNING, user.getUsername() + " à déjà la permission: " + permission);
}
});
});
}
Those issue are happening rarely. Any idea where does it could come from ?
Yes I did read the wiki
mostly
🙄
- are you sure the event is firing? Tried adding debug prints to the listener to ensure it's firing & the hasPlayedBefore check is as expected?
- Why are you not just adding the permission to the
defaultgroup? Adding a permission to each user seems like you're doing something odd.
- are you sure the event is firing? Tried adding debug prints to the listener to ensure it's firing & the hasPlayedBefore check is as expected?
Wanna try to add some debug prints just to be sure. However, I feel like it's unlikely that this event is sometimes not fired or thathasPlayedBeforedoesn't work has excepted. I guess those things have been tested, tested, and tested again by thousand of servers.
Why are you not just adding the permission to the default group? Adding a permission to each user seems like you're doing something odd.
You are right, it could have been done in different way. Instead of adding then negating the permission on the player, we could just negate the permission on the player. But I am still curious about how those issue could happen. I will go for this way and it might solve the issue (I hope so)
Thanks
What's the use case? This feels like XY problem, like you're using permissions to store data that would best be stored either in meta or in a dedicated storage system
How do I get the groups in the correct weight order?
One screenshot is the plugin, one is what it should be.
@clever zodiac Hello, thanks but i don't understand to get the permission node with this method getExpiry with just the UUID of the player
Edit: I kind of fixed it by just using a hashmap and sorting it by value/weight but the problem is now:
How do I get what the group is from an offlineplayer? Right now I'm using this but it has 2 problems
- It's using Vault not LuckPerms and even a message came up in console that you shouldn't do that which I had to disable using the config
- If I have * it always assumes I have the top rank
public static String getPlayerGroup(OfflinePlayer player) {
List<String> possibleGroups = getGroups();
for (String group : possibleGroups) {
if(vaultpermsapi.playerHas(Bukkit.getWorlds().get(0).getName(), player, "group." + group)) {
return group;
}
}
return "default";
}
Pseudo-code of what I want:
public static String getPlayerGroup(OfflinePlayer player) {
Group group = lpapi.getPlayer(player).getPrimaryGroup();
return group.getName();
}
It's about storing if players has started their jobs. Yes we could use an external storage, but using lp make it a bit easier since some other plugins also need to query this information
How do I get the player prefix using the Api
I currently have this but I don't know what a context is
!cookbook
The cookbook is a working example plugin which shows how to get/change data for users and groups, listen to LuckPerms events, and more.
make sure oyu're using API 5.3
Yeah I fixed it thank you!
im trying to convert some stuff i made a while ago using luckperms from bukkit to sponge. do i just replace the org.bukkit.Player in getPlayerAdapter(Player.class) with org.spongepowered.api.entity.living.player.Player, or is it something else?
does luckperms work with 1.18.1
Yes
original link
If I'm using API 4.3, how do I make it work with the latest version of Luckperms?
Don't use that version of the API. Best to use 5.3
The Legacy API won't work without the addon for it, but you won't get support for it.
Addon?
Legacy API Extension
But it is 100% recommended you use the latest api version
If you want to use the latest version of LP
There shouldn't really be any reason not to use the latest api version
Just the last update of the plugin (not mine) was 2019. I decided to fix it...
boolean result = luckyPermsUser.setPermission(api.getNodeFactory()
.newBuilder("group." + group).build()).wasSuccess();
setPermission and getNodeFactory don`t work...
!notworking
Please tell us what's going on!
We really would absolutely love to help you out! However, telling us that it isn't working wastes everyone's time. Please, just describe the issue you're having clearly and with as much detail as possible, and send any relevant screenshots of whatever problems you're having.
For Console Errors:
public class LuckPermsProvider implements PermissionProvider {
private static RegisteredServiceProvider<LuckPerms> LuckPermsProvider = Bukkit.getServicesManager().getRegistration(LuckPerms.class);
@Override
public boolean addToGroup(ru.mrbrikster.shoppingcartreborn.cart.User user, String group, long time) {
if (!(user instanceof BukkitUser)) {
return false;
}
if (LuckPermsProvider != null) {
LuckPerms api = LuckPermsProvider.getProvider();
User luckyPermsUser = api.getUserManager().getUser(((BukkitUser) user).getAsPlayer().getName());
boolean result = luckyPermsUser.setPermission(api.getNodeFactory()
.newBuilder("group." + group)
.setExpiry(time, TimeUnit.SECONDS).build()).wasSuccess();
api.getUserManager().saveUser(luckyPermsUser);
return result;
}
return false;
}
Updated Luck Perms API to 5.3
When i add the dependency to Maven, the IDE I use(IntelliJ IDEA), complains that it doesnt exist
What did you add to your pom
Press this
still there
Did it actually finish reloading the dependencies?
!api
Learn how to use the LuckPerms API in your project.
Read more
Example usages
Read the Javadoc
First link
Hello everyone, I have a question, what event is responsible for removing the player's permission after his time expires?
NodeRemoveEvent, you'll want to check for both Node#hasExpiry and Node#hasExpired
Hello, I am struggling removing a user (playerID) from a single group (groupName) using the following:
Group verified = luckPerms.getGroupManager().getGroup(groupName);
User u = Util.getLuckPermUser(luckPerms, playerID);
InheritanceNode r = InheritanceNode.builder(groupName).build();
u.data().remove(r);
luckPerms.getUserManager().saveUser(u);
luckPerms.getGroupManager().saveGroup(verified);
Nothing happens, no error thrown but also the group is still parent. Any ideas?
how do i check if a user's primary group is a temp group?
Node#hasExpiry
Get the permission from the player, then use this to check whether it has an expiry.
Anyone have ideas for how I (a) get a user's groups given a particular context, and (b) check a user's permissions in a given context? Or does simple LP checks check for their active context already? Porting a plugin of mine to Velocity, so yeah (UPDATE: Nevermind I think I might have figured it out)
How do I get and set a users role using API? I can't understand the collection framework of luckperms because I'm quite new to data structures :)
(I tried reading the docs I'm just new)
!cookbook
The cookbook is a working example plugin which shows how to get/change data for users and groups, listen to LuckPerms events, and more.
is the user offline?
How to handle permissions checking in LuckPermsAPI?
I want to handle permissions before return result
Hi, is PlayerDataSaveEvent called when player's permission groups change?
Ok found the answer <#luckperms-api message> 👌
Hey :D I have a little problem with the API. I have subscribed my proxy plugin to the GroupCreateEvent. My problem is that the event is only toggled when groups are created through the proxy (/luckpermsbungee). It does not work with the default /lp setting, although Redis messaging works properly. Any ideas how to fix this?
._.
is there an easy platform agnostic way to get a world object (minecraft) and get the context key for it ?
hey, how can I perform
/lp user <user> permission unset <permission> via the API?
User#getNodes().remove(Node.builder("chatcontrol.chat.globalrange").build());
Is this correct?
It looks correct, why not try it lol
@Unmodifiable @NonNull
default Collection<Node> getNodes()```
Description:
Gets a flattened view of the holders own Nodes.
This list is constructed using the values of both the normal and transient backing node maps.
It may contain duplicate entries if the same node is added to both the normal and transient node maps. You can use getDistinctNodes() for a view without duplicates.
This method does not resolve inheritance rules.
Returns:
a collection of the holders own nodes.
Requested by: powercas_gamer • lp
d;lp User#data
@NonNull
NodeMap data()```
Description:
Gets the holders DataType.NORMAL data.
Returns:
the normal data
Requested by: powercas_gamer • lp
Yep
oh kekw
Hi, I'm getting an issue. I'm using Jedis with LuckPerms to make it works on a bungeecord serveur. Everything works fine when I'm making the command for example /lp user <name> group set myGroup.
I want to know when the group is updated. So, -such as suggested in doc- in my plugin I made this:
public void load(MyPlugin pl) {
EventBus bus = LuckPermsProvider.get().getEventBus();
bus.subscribe(UserTrackEvent.class, this::onTrackEvent);
}
public void onTrackEvent(UserTrackEvent e) {
log("Receiving event for " + e.getUser().getUsername());
}
But:
- The serveur well receive informations like showed in the screen
- I tried by using my plugin's instance in the first object, before setting class
- I tried by using
UserPromoteEvent&UserDemoteEventsuch as said in doc - No logs, no error and this event seems well registered (this method is well called)
Events are not propagated through a network, if an event is dispatched on the proxy, listeners on the servers won't be called
There are other various network/post/sync/refresh events that will be dispatched but because of the syncing behavior, you might want to look into those instead.
^
oh ok, because it's just running sub command with Jedis's publish subscriber ?
what
the "LOG" is just with jedis event ? Also, I just tried PreNetworkSyncEvent & PostSyncEvent, and each time the server send log that it receive something, but no event are called
the log message is only shown when anything is changed, and that same message is sent throughout the network as well
you can disable the log message altogether but syncing and events will still happen, they're somewhat unrelated
yes but if there is a log message, there is something that is runned on the server, and I want to intercept that to do something with it
What exactly are you doing? Where are you running the command? Where are you listening to events and which events?
Got this from the API docs but it just doesn't make sense to me, the instance will only be set if the provider isn't null? So if the provider is not null the instance will be null?
RegisteredServiceProvider<LuckPerms> provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class);
if (provider != null) {
luckPerms = provider.getProvider();
}
if the provider isn't null.. the instance won't be null either
I just want to save my own rank when the player rank change, and just detect when data change for user, to get the rank and change my own system
why would it? what?
yes, now please answer my questions because I can't help with what I can't see
How? I havn't set the instance any other places, does that just mean the provider will always be null?
yes you want to detect changes, that's what events are for, but not all events are useful and it depends on where you run stuff and how you're listening to what events and where
you don't set it, luckperms sets it and you get it
Oh I just created a field for it like this private LuckPerms luckPerms; but I guess that's wrong then
no, that's correct
because you need to get it from the services manager and assign it into the field
Ok.
I'm running command /lp user Someone group set somerank. I tried on the server where the event is setup, and on another serveur. Both time it's not working.
Each time, the code of the method's event is just a logger
Hmm okay makes kinda sense
Right, UserPromote/DemoteEvent are not for lp user <user> parent set <group>
they are for the promote/demote commands; for parent set you'll want to use NodeAddEvent, check that the target is a User and that the event node is an InheritanceNode
Hello, still wondering how to remove a group from a player with the api (#luckperms-api message).
Discord
Discord is the easiest way to communicate over voice, video, and text. Chat, hang out, and stay close with your friends and communities.
Run the command in console ?
Modify the user's data and remove the inheritance node for that group.
Make sure to save the changes as well.
I don’t think you know what he’s talking about. He said “with the API”
Group verified = luckPerms.getGroupManager().getGroup(groupName);
luckPerms.getGroupManager().saveGroup(verified);
User u = Util.getLuckPermUser(luckPerms, playerID);
InheritanceNode r = InheritanceNode.builder(groupName).build();
u.data().remove(r);
luckPerms.getUserManager().saveUser(u);
I think i did - but no effect
How would i get a users group with the most weight and get all the info for it and also check if its temporary
How would i get a users group with the most weight
by default that's whatUser#getPrimaryGroupreturns
Now I'm not sure what you mean by "get all the info for it", but if you want to get the node for it (which would give you info such as expiry date if any) in API 5.4 there's this method you can use in the CachedPermissionData https://javadoc.io/static/net.luckperms/api/5.4/net/luckperms/api/cacheddata/CachedPermissionData.html#queryPermission(java.lang.String)
though the "permission" would be group.<group> rather than just the group name itself, cuz that's what the inheritance node actually is
so getPrimarygroup would return the group name which i can then use to check for the permission to check for expiry?
yeah
and how would i check for expiry if it has one?
Node#hasExpiry, #getExpiry
so if user has the permission for the group it would return true?
or how would i get the instance to get the expiry
with this new method I linked above ^^
Whats a tristate?
and its this one right?
yes it's that one.
k thanks Emily
one last thing @nocturne elbow (sorry for ping), i have to do user#getCachedData and then what?
Hey agus_marmor! Please don't tag helpful/staff members directly.
Then getPermissionData()
and then what?
because the query thing is not there
nmv i think i know why
im using 5.3
and i need 5.4
Player player = chat.getPlayer();
User user = luckPerms.getPlayerAdapter(Player.class).getUser(player);
String message = "§7§l(§3§lL§7§l)" + user.getCachedData().getMetaData().getPrefix() + chat.getPlayer().getName() + "§f"+msg + user.getCachedData().getMetaData().getSuffix();
How can I include the group's prefix and suffix colors into the message?
nvm; just added an alternateChatCode tag
i am struggeling to use the api i am trying to add a player to a group but cant find the code on the website
whetre do i get user from
well, you haven't defined groupName anywhere, so that's not gonna do anything.
also if you hover over this.luckPerms it will tell you whats wrong
Is it possible to get a Prefix from the Spigot server onto the BungeeCord plugin?
Or just generally Spigot permissions to my BungeeCord plugin
Or any way to switch from BungeeCord to Spigot with the API
If you have Luckperms connected to the same remote database on all servers, just get the prefix normally.
Hi, i'm trying to import the luckperms api on itellij idea, i tried to follow some tutorials but when i try to access the api, i get only errors
Learn how to use the LuckPerms API in your project.
Read more
Example usages
Read the Javadoc
cannot resolve symbol LuckPerms
!paste your build file
Please use pastebin!
Seeing a paste of the problem makes everything so much easier! Use https://pastes.dev/ for easy pasting!
For console errors:
Pastebin any relevant segments of the console log. If it's a startup error, this includes the entire startup log!
Other errors:
Pastebin the entire LuckPerms config file (passwords removed) as well as any other relevant files!
intellij suggests me to import the luckperms api class, but when i click on it nothing happens
your build file.
settings.gradle or pom.xml
how are you trying to add the api to your project
i tried to use the library section on "project structure" in the intellij file menu
the package isn't me.lucko.luckperms anymore
it's net.luckperms.api
that's what i found on the official wiki
nowhere in there it says me.lucko.luckperms? 
i know
i found it out now
because i clicked on a intellij suggestion to import luckperms api
yeah you shouldn't have these as dependency, v4 is err.. very old and unsupported lol
btw, the exact line below that there is compileOnly("net.luckperms:api:5.4")
yes?
another question
once i removed that two lines in the build file, should i hit build on gradle toolbar?
there should be a refresh button floating around somewhere
on the gradle toolbar
just floating around
but if there's a refresh button on the toolbar that could work too i guess ¯_(ツ)_/¯
no worries
How do I setup luckperms api into my plugin?
!api
Learn how to use the LuckPerms API in your project.
Read more
Example usages
Read the Javadoc
it ok i did it
does User#getNodes include nodes from their parent groups or does it only return their specific nodes
it returns the holder's own nodes
alright thanks
Is the event PlayerLoginProcessEvent called anywhere? I'm using Fabric and doesn't look like I am getting the event
So, I have a plugin where there's this "actions" feature such as [command] say Hey there! [player] warp spawn etc.. and I want to add a [luckperms] action to help people avoid the usage of [console] lp user %player_name% ....
Basically, I want to turn [console] lp user %player_name% permission set permission.node true into [luckperms] permission set permission.node true.
I was wondering if I could pass permission set permission.node true and the player object to the LuckPerms api and it would process the arguments like it does when someone run /lp user {player} permission set permission.node true
err short answer is no, that's command syntax/"spec", which is not API
yeah I was expecting that answer xD guess I will implement the command login on my end
It should be called https://github.com/LuckPerms/LuckPerms/blob/4bdcca6566bf522a09e5d123e89ed745a518ebc9/fabric/src/main/java/me/lucko/luckperms/fabric/listeners/FabricConnectionListener.java#L101
Is your handler not called when subscribed?
A bit unsure, if I recall correctly it didn't. May have been my fault thoug
or is that not actually exposed
that's not api, no
I know its not part of the APi aha
its exposed
CommandManager#executeCommand is public, then LPBukkitPlugin exposes getCommandManager(), which would allow him to use executeCommand
I know its not intended for use of course, but he is able to 🤷♂️
that's really not any different (at all) that just using Server#dispatchCommand or whatever
though dispatchCommand will log it to console that it was ran
I mean, LP would log the action too
if he creates a custom Sender would he be able to override sendMessage to make it not actually go to console
@daring sandal I can't recommend you do this and because it's not API, there is no guarantee that this will not be broken in any future version. However, if this is functionality you really want, you can find a way to get the CommandManager instance and call executeCommand with a custom Sender modelling console and just not accepting messages
he could use reflection to do so anyways, there are a number of hacky ways 🤷♂️
it just depends on how much he really wants this
¯_(ツ)_/¯
he asked if it was possible with the api
it's not
internals are internals
I thought about using the command manager, will see, don't really want to use this hacky system though
might as well just not implement it at all
using bukkit.dispatchcommand is the only correct way to achieve what you're doing
doing reflection in LP internals is not a good idea
well it’s exposed so it wouldn’t be reflection, but just as hacky imo
actually it's not "exposed", since (at least for bukkit (and a few other platforms)) the common module and the "plugin" class is in the nested jar
good luck getting around that 🥴
Nope, and afaik it's on it's own classloader
lmfao it seems I dont know anything about how LP is loaded into the server
again, you ""can"" get it
just like you ""can"" get the internal command dispatcher
but like you have to go out of your way by a thousand miles
and there's no way without reflection
Say no to reflection
Alright Luck
package net.plexpvp.core;
import net.luckperms.api.LuckPerms;
import net.luckperms.api.LuckPermsProvider;
import net.milkbowl.vault.economy.Economy;
import net.plexpvp.core.data.GuildControl;
import net.plexpvp.core.data.MiscControl;
import net.plexpvp.core.data.PlayerControl;
import net.plexpvp.core.data.instanceTargets.FilteredWords;
import net.plexpvp.core.guilds.Command;
import net.plexpvp.core.misc.ChatFormat;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;
import redempt.redlib.commandmanager.ArgType;
import redempt.redlib.commandmanager.CommandParser;
import redempt.redlib.misc.UserCache;
import java.util.UUID;
public final class Main extends JavaPlugin {
// Instance Methods
private static Main instance;
public static Main get() { return instance; }
private static Economy econ = null;
public static Economy getEconomy() { return econ; }
private static final LuckPerms luckperms = LuckPermsProvider.get();
public static LuckPerms getLuckPerms() { return luckperms; }
private static PlayerControl playerControl;
public static PlayerControl getPlayerControl() { return playerControl; }
private static GuildControl guildControl;
public static GuildControl getGuildControl() { return guildControl; }
private static MiscControl miscControl;
public static MiscControl getMiscControl() { return miscControl; }
@Override
public void onEnable() {
instance = this;
playerControl = new PlayerControl();
guildControl = new GuildControl();
miscControl = new MiscControl();
// Config Registration
playerControl.reloadPlayers();
guildControl.registerExisting();
miscControl.register("miscData/FilteredWords", new FilteredWords());
// Listener Registration
Bukkit.getPluginManager().registerEvents(playerControl, this);
Bukkit.getPluginManager().registerEvents(new ChatFormat(), this);
// Library Registration
if (!setupEconomy()) getServer().getPluginManager().disablePlugin(this);
new Placeholders().register();
// Command Registration
ArgType<OfflinePlayer> offlinePlayerArgType = new ArgType<>("offlineplayer", UserCache::getOfflinePlayer).tabStream(c -> Bukkit.getOnlinePlayers().stream().map(Player::getName));
ArgType<UUID> uuidArgType = new ArgType<>("uuid", UUID::fromString);
new CommandParser(getResource("command.rdcml"))
.setArgTypes(offlinePlayerArgType, uuidArgType)
.parse().register("plex", new Command());
}
@Override
public void onDisable() {
// Config Saving
playerControl.save();
guildControl.save();
miscControl.save();
}
private boolean setupEconomy() {
if (getServer().getPluginManager().getPlugin("Vault") == null)
return false;
RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);
if (rsp == null)
return false;
econ = rsp.getProvider();
return econ != null;
}
}```
this is my main file
move LuckPermsProvider.get(); to onEnable
how does that even work
LuckPerms luckPerms;
onEnable:
luckPerms = LuckPermsProvider.get()
Capital P, and did you do the first part cas said
Hi, can anyone help me with getting player's group. Ik that there is a method for it and i'm using it but how do i convert Collection<Group> to Collection<String>?
// Get a Bukkit player adapter.
PlayerAdapter<Player> playerAdapter = main.luckPerms.getPlayerAdapter(Player.class);
// Get a LuckPerms user for the player.
User user = playerAdapter.getUser(player);
// Get all of the groups they inherit from on the current server.
Collection<Group> groups = user.getInheritedGroups(playerAdapter.getQueryOptions(player));
// Convert to a comma separated string (e.g. "admin, mod, default")
String groupsString = groups.stream().map(Group::getName).collect(Collectors.joining(", "));
String format = "<group-prefix><player>: <message>";
format.replace("<group-prefix>", ChatColor.translateAlternateColorCodes('&', main.getPlayerGroup(player, groupsString)));
//MAIN
public static String getPlayerGroup(Player player, Collection<String> possibleGroups) {
for (String group : possibleGroups) {
if (player.hasPermission("group." + group)) {
return group;
}
}
return null;
}
how can i get all online players with a certain permission
There's User#getPrimaryGroup? That's probably what you want?
As for "how to convert Coll<Group> to Coll<String>" the stream method is fine
Bukkit.getOnlinePlayers and you can just filter normally with Player#hasPermission
i figure it out somehow but now i have other problem
Code
Player player = e.getPlayer();
// Get a Bukkit player adapter.
PlayerAdapter<Player> playerAdapter = main.luckPerms.getPlayerAdapter(Player.class);
// Get a LuckPerms user for the player.
User user = playerAdapter.getUser(player);
// Get all of the groups they inherit from on the current server.
Collection<Group> groups = user.getInheritedGroups(playerAdapter.getQueryOptions(player));
Collection<String> groupsToString = Collections.singleton(groups.toString());
Group group = main.luckPerms.getGroupManager().getGroup(main.getPlayerGroup(player, groupsToString));
player.sendMessage(group.getCachedData().getMetaData().getPrefix()); // LINE 95
ERROR
Caused by: java.lang.NullPointerException: Cannot invoke "net.luckperms.api.model.group.Group.getCachedData()" because "group" is null
at com.mires.rpg.core.events.OnChat.onChat(OnChat.java:95) ~[?:?]
You shouldn't call toString on random things, the stream.map method was fine, this isn't
yeah but then the problem is that the method accepts Collection<String> not String
Yes, because you're not supposed to call toString on random things, that doesn't work like that
groups.stream().map(Group::getName).collect(toList) should work fine
Like player -> player.hasPermission("blah")?
ok it works tysm
What
What exactly are you trying to do
nvmd i got it working
How can I check if an offline player has a permission?
Right now, after following the wiki I have:
UserManager userManager = luckPerms.getUserManager();
CompletableFuture<User> userFuture = userManager.loadUser(p.getUniqueId());
userFuture.thenAcceptAsync(user -> {
});
not sure how to check the users perms with the user variable though...
Maybe something like this:
user.getNodes(NodeType.PERMISSION).stream()
.map(PermissionNode::getPermission)
.anyMatch(perm -> perm.equals(permission));
I dont understand it, in other Plugins from me, is working everything.
You seem to be shading/bundling the LP API into your own plugin :P
Don't do that 😆
in other Plugins, i used this too, with no errors
Because you're not shading the LP API in those
huh?
Make sure the dependency is set like shown here https://luckperms.net/wiki/Developer-API#adding-luckperms-to-your-project (scope provided / compileOnly)
its the same
Huh, can you share the entire pom file?
It's definitely being pulled in somehow, otherwise it wouldn't show that it's from your jar file
err
!pasteit please