#luckperms-api

1 messages · Page 39 of 1

turbid solar
#

Did you save the user?

#

And actually add the node to the user

uneven radish
#

MineconomyWorld.luckPerms.getUserManager().modifyUser(p.getUniqueId(), (User user) -> { user.data().clear(NodeType.INHERITANCE::matches); Node node = InheritanceNode.builder(MineconomyWorld.luckPerms.getGroupManager().getGroup("spieler")).build(); user.data().add(node); }); MineconomyWorld.luckPerms.runUpdateTask();

#

the player is added to the group, but to the default group too

nocturne elbow
#

You'll want to runUpdateTask when the CompletableFuture finishes

#

Can't do much on mobile but would look something like this

  // modifyUser
}).thenRun(MineconomyWorld.luckPerms::runUpdateTask);
#

Because all that is ran async so you want to ensure the update task runs when the modifyUser finishes running the one inside

uneven radish
#

okay, ill try that

nocturne elbow
#

I'll try testing later anyway

uneven radish
#

okay, still the same problem

#

i am in group test and after my code i am in default and spieler

nocturne elbow
#

Hm

uneven radish
#

and how can i check the parent group of an player

#

im totally lost

#

sorry

turbid solar
uneven radish
#

thx

dapper flame
#

Hey, I'm sure you guys have been asked this a thousand times, but is there any reason why this is returning null?

CachedDataManager = LuckPermsProvider.get().getUserManager().getUser(player.getName()).getCachedData();

String prefix = data.getMetaData().getPrefix();
String suffix = data.getMetaData().getSuffix();
#

I'm on bungee

#

like the prefix/suffix are null

#

no error was thrown or anything

turbid solar
#

Screenshot lpb user <user> info

dapper flame
#

ok

crystal sonnet
#

@dapper flame use the player’s UUID. Not the player’s name

dapper flame
#

ok

crystal sonnet
#

Also what exactly is null?

dapper flame
#

the prefix and suffix strings

#

data.getMetaData().getPrefix();

#

to be more specific

turbid solar
#

Well suffix isnt set

dapper flame
#

and is there anyway to get an instance of the api through the bungee plugin manager? when I do it returns an object with the type "LPBungeeBootstrap" which cannot be cast to LuckPerms, and I assume its got a private modifier because I cannot import it

#

using uuid fixed the null issue :) thanks

nocturne elbow
#

No, Bungee doesn't have a service provider like Bukkit or Sponge do

#

So you have to use the static singleton from LuckPermsProvider

dapper flame
#

ok thanks

night warren
#

How do I give a player a permission (hardcore.reset)

#

I have looked in the docs and have no idea

obtuse jolt
#

Assuming its about the API, what have you tried?

night warren
#

with the error

nocturne elbow
#

Do you.. have an object/variable named user somewhere accessible from there..?

night warren
#

no

#

I tried Player user = (Player) sender

#

but that did not work

nocturne elbow
#

I don't know what docs you've been looking but the 2 main API usage pages cover obtaining Users well

#

!api should be in the second link iirc

frank driftBOT
nocturne elbow
#

something along the lines "Obtaining a User instance"

night warren
#

Thats what i was looking at I could not understand it

nocturne elbow
#

What part of it you don't understand? Let's see if we can break this down

night warren
#

All I am trying to do it give the user the perm hardcore.reset and when they use it take away that perm

nocturne elbow
#

That doesn't really answer the question tho..

#

To do that you need a User object

#

The one corresponding to the player

night warren
#

How do I create that

#

This is my first time using luck perms I have no idea

nocturne elbow
#

What platform is this for?

night warren
#

Spigot

#

in java 1.8

nocturne elbow
#

Then you store that LuckPerms object somewhere for you to access and use

#

And with that object this is how you get user data (for online players!!)

night warren
#

like this?

nocturne elbow
#

Yeah you are mixing bits.. you'll want to initialize the api (I suggest you rename it as luckPerms or something) to null instead and then use the service provider to get it

night warren
#

is that under on Enable?

nocturne elbow
#

yes

night warren
#

This cant be right

nocturne elbow
#

Well the name of the class isn't right, Java is a case sensitive language, so Luckperms and LuckPerms are different classes

#

And then inside onEnable use the service provider to give it a value

#

In that case, the value would be a LuckPerms object

night warren
#

this is what i am at

nocturne elbow
#

Yes, that looks good, that is how you get the API

#

Although again, I suggest you rename it to luckPerms instead, api alone is very vague an unidentifiable

night warren
#

ok so this should give them the perm

nocturne elbow
#

Yes

#

Remember to save the user data

night warren
#

and this should remove

cinder zealot
#

this is what I was doing now :thimk:

nocturne elbow
#

Hello A.L.I.C.E

cinder zealot
#

hey fefo xd

night warren
#

ok and that saves it right?

nocturne elbow
#

yes.. why are you removing and then adding the node back again...?

night warren
#

I am removing the perm once they use it

#

so for my example they die get the perm to reset everything and once used remove it again

nocturne elbow
#

yeah but.... you're adding it back immediately after..?

night warren
#

they are in separate bits

#

at bottom is when they die

#

does that event

#

adds command then there is top when they do command and remove perm

nocturne elbow
#

I'mma go now snooze

night warren
#

same 😛

#

thanks for the help

nocturne elbow
#

c;

cinder zealot
#

btw, I had installed the LuckPerms API with maven, said in github

#

but there're some sources with no documentation

nocturne elbow
#

Uuh not sure what you mean exactly? But afaik maven should pull the sources version of the API jar too

#

Although for that matter you can also use the online javadoc, p much literally the same contents since the API jar has no actual implementation code, all interfaces

#

!javadoc

frank driftBOT
cinder zealot
#

I mean, there're some with no .java [ source/documented ] but .class [ (de)compiled ]

nocturne elbow
#

That IntelliJ?

cinder zealot
#

yea

nocturne elbow
#

Uuuuh double shift and type "Download sources and documentation" and click the thingy

cinder zealot
#

yeah I did it

#

but it didn't work

#

XD

nocturne elbow
#

Eh..

nocturne elbow
nocturne elbow
#

although I also prefer looking through the source jars rather than the javadoc lol

cinder zealot
#

btw, thanks for help XD [ también soy español por si quieres saber xd ]

nocturne elbow
cinder zealot
#

okay I did restart IntelliJ IDEA and now it works

nocturne elbow
#

yay

cinder zealot
#

thank you XD

cinder zealot
#

mmm, I was looking in docs to get a list of players that are in a group, but I couldn't find anything :(

nocturne elbow
#

UserManager#searchAll

cinder zealot
#

oh, got it

earnest python
#

How do i make it so when someone types in chat their group is in front of their name

turbid solar
#

!chat

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
wanton frost
#

How can I prefix of a group with LP API?

#

In string

nocturne elbow
#

!cookbook check this example plugin, it has an example command to get someone's prefix

frank driftBOT
wanton frost
#

thank you UwU

cinder zealot
#

is NodeType#INHERITANCE used for groups too?
I mean, I'm seeing that groups are kinda treated like permissions or something like that :sadcat:

nocturne elbow
#

Everything is a node, not necessarily a permission node. Inheritance nodes denote parent groups, prefix and suffix nodes are.. self-explanatory, meta nodes are used to "store" arbitrary data in a key->value pair manner, permission nodes are meant to be used as permissions with a true/false value

cinder zealot
tribal wave
#

about the specifics of transient nodes, do they last until a user leaves the spigot server, or until they disconnect from bungee (assuming you're using the same database for every spigot/bungee instance, as well as that you assigned the node from the aforementioned spigot server)

rustic laurel
#

I believe until they leave the bungee

#

Can't be too hard to test :D

nocturne elbow
rustic laurel
#

Oh yikes

#

You're totally right

#

Intelligence is soup; I am fork

nocturne elbow
#

Even if you set the server setting, even if you use any kind of database with messaging service: LP doesn't know if you're on a network and doesn't know of other existing instances, they are isolated units basically

tribal wave
#

alright, i like that

#

thank you for the info 🤤❤

stiff jacinth
#

How can I check if a player's currently most weighted group is permanent? Like what would luckperm return if it is when I call for: Node#getExpiryDuration()

nocturne elbow
stiff jacinth
#

Uff, thanks. That was what I was looking for. Can you give me the link instead?

nocturne elbow
#

!javadoc

frank driftBOT
nocturne elbow
#

last link

#

they neat mmlul

stiff jacinth
#

Thanks my man!

pastel brook
#

How do I add/remove a prefix from a player using the API?

#

Should I just use vault's API?

nocturne elbow
#

and clear by node type (PREFIX) and its weight

#

or maybe just node type, depends on your use case

#

because if you want to do something like user.data().remove(node), the node has to match exactly all the qualities (expiry, value, the whole node key, contexts)

night warren
#

Hi there, I am trying to set a permission to a player but for some reason it is not working, this is my code the node i want to set is hardcore.reset

#
        
        user.data().add(Node.builder("hardcore.reset").build());
        
        user.data().add(Node.builder("hardcore.reset").build());

        LuckPerms.getUserManager().saveUser(user);```
nocturne elbow
#

That should work alright, except for the bit you are adding the same node twice but that doesn't play a role in that..

night warren
nocturne elbow
#

I'll test it soon

night warren
#

wait dont worry its not that part which is broken its the listener which then broke that bit#

#

my bad

nocturne elbow
#

oh ok

nocturne elbow
pastel brook
#

I ended up just using the vault API

nocturne elbow
#

And they left lol

wild whale
#

that's barty for ya

low rune
#

Hey. So, I want the user to be able to have x, let's say, friends. I give him the permission friends.max.20 and he can have 20 friends. Okay, nice. Now I want to retrieve this number from the user. In plain Bukkit I would to it with permission attachment infos, but I'm quite unsure how to do it with the luckperms API. Should I use meta nodes?

nocturne elbow
#

Yeah you should use meta nodes

#

I mean you can just use regular permission nodes and do some fancy-schmancy regex and filtering but you'll be way better off using meta nodes

low rune
#

Aight. Is there a solution to include meta nodes from groups in the result, as user.getCachedData().getMetaData() only returns the meta set directly to the user?

nocturne elbow
#

Hi, how to add player permissions via DevAPI

turbid solar
#

!api

frank driftBOT
nocturne elbow
#

afaik they are included..?

#

internet yes 🌝 it's dead

low rune
#

apparently they're not. I set meta data to a group I am in and it didn't show up in this list. But I'll try again with another meta key, because I used . which gets replaced with \.

nocturne elbow
#

because I used . which gets replaced with \.
that is intended, yes

#

they are escaped

low rune
#

I know

#

But I don't know how it behaves if I use getMetaValue("something.something")

nocturne elbow
#

that works fine tho, everything is escaped properly

#

if it weren't, plugins like griefdefender wouldn't use them :d

low rune
#

No, I don't use any of these 😄

#

ah, understood your message wrong, nvm

nocturne elbow
#

does the meta show when you run /lp user <user> info//lp user <user> meta info?

low rune
#

nope

nocturne elbow
#

how are you adding the meta nodes?

low rune
#

but I set it using /lp group default meta set something.something 50

nocturne elbow
#

do you.. inherit default?

#

or maybe you messed with config?

#

many factors are taken into account

low rune
#

Ah, I somehow thought I'd inherit default by default lol

#

so I think it's fixed haha

uneven radish
#

fefo thanks for the report 🙂

nocturne elbow
#

e.getUser() How can I turn that to a spigot player

turbid solar
#

getUsername or getUUID

#

Then Bukkit#getPlayer

nocturne elbow
#

alright ty

hushed oxide
#

How do i make a context?

#

I want context if player hit level 10 for example

night warren
#

is there away to give ranks based on playtime?

hushed oxide
#

There is a plugin that does that

night warren
#

I cant find a up to date one

hushed oxide
#

There is a popular one

night warren
#

can you link me?

hushed oxide
#

K wait

#

I dont remember its name

#

But its popular

nocturne elbow
#

@hushed oxide I suggest you take a look at the ExtraContexts plugin see how it does it

#

!extracontexts

frank driftBOT
magic palm
#

Hello I have problem with api because I want to do: api.getUserManager().getUser(target.getUniqueId().toString()).setPrimaryGroup("svip"); and its dont work

sweet mirage
#

UserManager#getUser takes a UUID

#

You’re turning the UUID into a string

#

Is that what’s not working

#

the string param for #getUser searches a user by username

#

and i assume their username isn’t their uuid

nocturne elbow
#

Well:

  1. "dont work" doesn't really tell me anything, I don't know what your objective is, what it's actually doing or how you are doing things. Detail is key when troubleshooting! 🙏

  2. UserManager#getUser(String) takes the player name! Not the UUID as a string

  3. You already have the UUID, you can just call UserManager#getUser(UUID), unsure why you're converting it to a string

  4. User#setPrimaryGroup(String) doesn't do what you think it does. The primary group is, by default, the user's parent group that weights the most. What you want to do is get the user nodes data, clear all nodes of type NodeType.INHERITANCE, build an InheritanceNode and add it to the same nodes data (don't forget to save the user!!) (maybe you don't want to remove the other parent groups, but add this other alongside the existing ones instead)

magic palm
#

so how to repair it anyone can write this line ready to paste into eclipse

nocturne elbow
#

What you want to do is get the user nodes data, clear all nodes of type NodeType.INHERITANCE, build an InheritanceNode and add it to the same nodes data (don't forget to save the user!!) (maybe you don't want to remove the other parent groups, but add this other alongside the existing ones instead)

#

You can check a working example plugin that uses the LP API in the API cookbook repo, you can use that as guide, see how it does things

#

!cookbook

frank driftBOT
magic palm
#

I read this and I dont know how to do it

nocturne elbow
#

In that example plugin there is an example command exactly for setting a parent group (clearing the others and adding one)

#

"simulates" LP's parent set command with the API

magic palm
#

this: this.luckPerms.getUserManager().modifyUser(player.getUniqueId(), (User user) ->{ user.data().clear(NodeType.INHERITANCE::matches); Node node = InheritanceNode.builder(group).build(); user.data().add(node); sender.sendMessage(ChatColor.RED + user.getUsername() + " is now in group " + group.getDisplayName()); } give me an error

#

Consumer<User> cannot be resolved to a type

nocturne elbow
#

What version of the API are you working with?

magic palm
#

where to see it?

nocturne elbow
#

I don't know, depends on how you are adding the API as a dependency, only you can know that

magic palm
#

I have LuckPerms 5.2.61

nocturne elbow
#

Uuuh you aren't supposed to add the whole LP jar as a dependency

#

Only the API jar, provided in the main Dev API wiki page iirc

#

!api

frank driftBOT
magic palm
#
  - LuckPerms``` this is in plugin.yml and this ```RegisteredServiceProvider<LuckPerms> provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class);
        if (provider != null) {
            LuckPerms api = provider.getProvider(); 
        }``` in main class
nocturne elbow
#

Although realistically you should prolly use a build system like maven or gradle for easy dependency management

nocturne elbow
magic palm
#

i do it and when i send command i have error on line: Group group = luckPerms.getGroupManager().getGroup("vip");

nocturne elbow
#

And..... what does the error say

magic palm
nocturne elbow
#

Are you giving this luckPerms object a value?

magic palm
#

what does it mean?

#

send this class?

nocturne elbow
#

Sure I guess... I mean if you are doing something like luckPerms = ..., giving that luckPerms object a value

magic palm
#

i dont have line luckPerms = ...

#

this line is the problem Group group = luckPerms.getGroupManager().getGroup("vip");

turbid solar
#

Paste your whole code in hastebin

magic palm
#

hastebin have lag

#

i cant save file

obtuse jolt
#

!paste

frank driftBOT
#
Please use pastebin!

Seeing a paste of the problem makes everything so much easier! Use https://bytebin.lucko.me/ 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!

magic palm
turbid solar
#

Use api

magic palm
obtuse jolt
#

yea you kinda need to know your variables

#

and you probably want to figure out why the luckPerms you pass into the contructor is null

nocturne elbow
#

I mean no offense but you should probably re-review your Java basics before jumping into the LP API, or even Spigot API. "Giving the object a value" is a trivial concept.

I suggest jumping back and forth between theory and practice; don't follow YouTube tutorials, they usually are not even decent. I heard that the "JetBrains academy" is good actually, has a 2 months free trial https://www.jetbrains.com/academy/

Start with this -
https://docs.oracle.com/javase/tutorial/java/concepts/index.html
Breeze through this skipping stuff that doesn't seem relevant like bitwise operators-
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/index.html
and then hit this
https://docs.oracle.com/javase/tutorial/java/javaOO/index.html

They're the first three from this larger thing - https://docs.oracle.com/javase/tutorial/java/index.html
Which you should definitely go through overall. But those three should be enough for slightly better understanding of wtf is happening here without feeling like a huge time sink
That one is a small part of this larger site - https://docs.oracle.com/javase/tutorial/index.html
wherein "Essential Java Classes" and "Collections" also have good useful stuff

magic palm
#

and I want to unset player rank but i cant see it on github

obtuse jolt
#

yea I agree with Fefo

turbid solar
#

Remove the inhertitance node

obtuse jolt
#

!api

frank driftBOT
magic palm
#

i change .add to .remove

obtuse jolt
#

well yea

#

but

#

there can much more that can go wrong than that

pastel brook
#

what is the equivalent of "permission checkinherits" for the API?

#

checkPermission() seems to just do the equivalent of "permission check"

pastel brook
#

nvm

inland yacht
#

hi

#

i use this for get a luckperms user

#

but some times if the user is not online returns null

#

how i can get if the player are offline?

nocturne elbow
#

!api see in the second link "Obtaining a user instance"

frank driftBOT
inland yacht
#

readed

#

but could you give me something more specific xd?

nocturne elbow
#

Not really? Check the one that says "If the player isn't (or might not be) online"

#

It shows you how to load user data from storage (since the player is offline)

inland yacht
#

oh ok

turbid solar
#

Once you loaded it ye

#

Or whatever the userFuture is

inland yacht
#

oh ok

prisma trout
#

ok so idk how the internals of permissions really work, and if this is even the right way to accomplish this goal

#

but basically i want to have a permission, quantum.cooldown.x, where x is a number

#

for example, the default group could have quantum.cooldown.20 while another group could have quantum.cooldown.10 (or any different number - higher or lower)

#

now, is there a way to get the highest "priority" quantum.cooldown node?

#

initialliy i considered just iterating over every permission with quantum.cooldown. as the prefix, and basically making the cooldown the lowest value, but that's kinda limiting and i was wondering if this idea would be possible instead

#

dunno if that makes any sense

#

alternatively i could probably use the meta api

rustic laurel
#

please please please use meta

#

key: quantum-cooldown value: n number

prisma trout
#

yeah that's what im thinking

#

i'll just provide a guide on how to use luckperms meta with quantum then i guess

rustic laurel
#

with permissions it's just such a pain, like check every int pain

prisma trout
#

yeah

rustic laurel
#

essx did something like that with multiple homes

#

and you can see how that went for both dev and ux

prisma trout
#

god yeah i didn't even consider that

#

that system blows

#

alright, thanks for bringing me to the light side larebear

rustic laurel
prisma trout
#

just to make sure:

group default {
  quantum-cooldown: 10
}

group larry inherits default {
  quantum-cooldown: 999999
}

any user with larry group will return 999999 for cooldown instead of 10 yeah

rustic laurel
#

what is this syntax

prisma trout
#

idk just an example

rustic laurel
#

uh yeah

prisma trout
#

ok pog

rustic laurel
#

group weight determines meta

prisma trout
#

yeah group weight

rustic laurel
#

and so does direct inheritance

prisma trout
#

thats the word

rustic laurel
#

!advanced

frank driftBOT
rustic laurel
#

!weight

frank driftBOT
#

LuckPerms allows you to set weights in order to determine the priority of certain nodes, like permissions and even prefixes. A higher weight number is a higher priority.

prisma trout
#

pog

rustic laurel
#

I wrote the book on weight sunglas

prisma trout
#

and if the user's meta themselves is changed, that'll override everything

#

haha larry fat joek!

#

owned

rustic laurel
#

lol i didn't even consider the self deprecation implied in that

#

i meant to imply i was 'cool' for writing a simple tiny wiki page but mock myself in that manner smh

prisma trout
#

oh

#

well, 2 for 1 combo

crystal sonnet
#

Btw there’s a config option in LP to make it so that it picks the highest (or lowest) value for a meta node @prisma trout

prisma trout
#

alright thanks

#

not too worried about the lp configuration itself - gonna leave that up to the users

inland yacht
#

hi

#

exists some method for load offline user data?

#

this only works in a future

crystal sonnet
#

That loads offline users

#

You should really learn to work with Futures

#

They are super useful!

#

I mean that is literally linked in your screenshot @inland yacht

inland yacht
#

Example

#

I want show a System.out.print(user.getnick)

#

Want i need do?

turbid solar
#

What should it print

inland yacht
#

Is a example

crystal sonnet
#

@inland yacht look at the link I sent

#

It explains for to work with Futures

inland yacht
#

but give me a specific example please

turbid solar
#

Thats on the page

crystal sonnet
#

There's 3 examples on the page

#

One even doing exactly what you want

nocturne elbow
#

what does that even mean

wicked briar
#

do you use a host?

crystal sonnet
#

Showing where?

nocturne elbow
#

Is this related to the developer api?

crystal sonnet
#

And did you restart the server?

#

And that

wicked briar
#

correct version?

nocturne elbow
#

Sounds like you are, yes

crystal sonnet
#

Are you programming a plugin that interfaces with the LP API?

#

If you don't know what an API is, the answer is no btw

pastel brook
#

is there some sort of limit on how fast you can add permissions to a user?

crystal sonnet
#

no

pastel brook
#

using this code:

    private fun addPerkPerms(userUUID: UUID, perkPerms: List<String>) {
        perkPerms.forEach {
            luckPerms.userManager.modifyUser(userUUID) { user: User ->
                println(it)
                user.data().add(Node.builder(it).build())
            }
        }
    }

where perkPerms is a list of permissions to add to the user.

the console output is

[22:20:40 INFO]: crazyauctions.sell.2
[22:20:40 INFO]: crazyauctions.bid.2
[22:20:45 INFO]: BartyRealms issued server command: /lp user BartyRealms editor
[22:20:52 INFO]: BartyRealms issued server command: /perks
[22:20:54 INFO]: crazyauctions.sell.3
[22:20:54 INFO]: crazyauctions.bid.3
[22:20:55 INFO]: crazyauctions.bid.4
[22:20:55 INFO]: crazyauctions.sell.4
[22:20:56 INFO]: crazyauctions.sell.5
[22:20:56 INFO]: crazyauctions.bid.5
[22:20:57 INFO]: crazyauctions.sell.6
[22:20:57 INFO]: crazyauctions.bid.6
[22:20:58 INFO]: crazyauctions.sell.7
[22:20:58 INFO]: crazyauctions.bid.7
[22:20:59 INFO]: crazyauctions.sell.8
[22:20:59 INFO]: crazyauctions.bid.8
[22:20:59 INFO]: crazyauctions.sell.9
[22:20:59 INFO]: crazyauctions.bid.9
[22:21:01 INFO]: crazyauctions.sell.10
[22:21:01 INFO]: crazyauctions.bid.10

(I ran it 9 times)

crystal sonnet
#

Well keep in mind that modifyUsersaves the data

#

So run the loop inside of modifyUser

nocturne elbow
#

Sounds a whole lot like a use for meta keys

crystal sonnet
#

And that too

#

But yeah don't loop modifyUser

#

Loop inside

pastel brook
#

okay

#

so instead run modifyUser and then do perks.forEach ... inside of that?

crystal sonnet
#

Bad (modifyUser is a slow call):

        perkPerms.forEach {
            luckPerms.userManager.modifyUser(userUUID) { user: User ->
                println(it)
                user.data().add(Node.builder(it).build())
            }
        }

Good (calling modifyUser only once)

        luckPerms.userManager.modifyUser(userUUID) { user: User ->
             perkPerms.forEach {
                println(it)
                user.data().add(Node.builder(it).build())
            }
        }
pastel brook
#

gotcha, trying that now

crystal sonnet
#

That's kotlin btw, right?

pastel brook
#

yeah

#

kotlin is ❤️

nocturne elbow
#

Also use meta nodes for that 😬

crystal sonnet
#

I see. That syntax looked off

pastel brook
#

I was using the method that was used in the developer API usage 🤷

#

why would I use meta nodes vs. permission nodes?

nocturne elbow
#

That is what meta nodes are for

#

It's basically just stores a key->value pair so you can get a value directly from the key

pastel brook
#

i'm setting permissions from the CrazyAuctions plugin

nocturne elbow
#

Assuming that isn't yours and uses permissions itself and is out of the scope of modification?

pastel brook
#

correct

nocturne elbow
#

Yeah then you'll have to stick with the spec of that plugin lol

pastel brook
#

however, I do use permissions to store data in one of my plugins, what makes meta nodes superior to just using a permission node?

crystal sonnet
#

They are designed to store data

pastel brook
#

yeah I can just get the permission just as easily?

nocturne elbow
#

To get the data from a regular permission, you have to iterate through all the available permissions, filter and parse

#

That... is expensive

pastel brook
#

fair enough, i'll switch to that then

#

thanks for letting me know about them

nocturne elbow
pastel brook
#

also, looping inside of modifyuser fixed my issue, thanks for your quick response + helpfulness 😄

crystal sonnet
#

You're welcome

inland yacht
crystal sonnet
#

I know

#

Now all you need to do is put the pieces together

#

You have everything you need right in front of you

#

Now put it together

inland yacht
#

here?

crystal sonnet
#

For example. Or check the very first code box

#

First as in first counting from the highlighted header

cinder zealot
cinder zealot
#

nvm, I just read something from wiki that helped me

normal hedge
#

Hey hello,

public CachedPermissionData getCachedPermissionData() {
  ImmutableContextSet contextSet = this.getContextManager().getContext(this.getUser()).orElseGet(this.getContextManager()::getStaticContext);
  return this.getUser().getCachedData().getPermissionData(QueryOptions.contextual(contextSet));
}

public String getPrimaryPrefix() {
  try {
    return this.getCachedMetaData().getPrefix();
  } catch (NullPointerException e) {
    return null;
  }
}

So I wrote this using the LuckPerms API wiki on github. This is working perfectly is the User is online, but if it's offline, it gives null.
Any help?

sudden pelican
normal hedge
#

aahh thats what I was looking for, thanks

#

So if I'm reading this correctly (My English isn't great), this Future can be used for Offline AND Online players right?

#

Question #3: If I use UserManager#loadUser(UUID), what do I use if I want to get it as a variable? get or join or something else?

nocturne elbow
normal hedge
#

I want to return the User object itself, not do anything with it yet

#

public User getUser() {

nocturne elbow
#

Well that's the point of CompletableFutures

#

The data takes time to load from disk

#

Maybe it's on a database on the other side of the world

normal hedge
#

ahh okay

nocturne elbow
#

So it's loaded asynchronously instead "inside" the CompletableFuture

normal hedge
#

So I shouldn't return the User itself at all

nocturne elbow
#

Nop, if you call join or get on the future it will basically wait until it completes

normal hedge
#

Well, thats fine I guess

#

If I use the thenAcceptAsync it will wait for it to complete as well right?

#

like, in 'inside' the Future, User is 100% loaded right?

nocturne elbow
#

Yeah, but it runs your method async waiting in that other thread, not lagging the server

#

Or if it lags it won't be the cause of it mmlul

normal hedge
#

Ahh okay well then I need to change up my player object xD

#

This is all assumed the User is online, but it needs to be both xd

normal hedge
#

Why does User#getUsername() return the user's name in lowercase?

nocturne elbow
#

Because LP stores it that way

#

It makes everything easier and way safer when it comes to searching, calculating and stuff

normal hedge
#

Is there any way to get it with the right cases?

nocturne elbow
#

The idea being that you won't have issues due to case sensitivity

nocturne elbow
#

And get the player name from there

normal hedge
#

hmm alright

#

Well the thing is, the player might not even joined the specific gamemode yet

nocturne elbow
#

Might be of interest

normal hedge
#

Aight, thanks

#

Just made the getUsername method as fallback if the OfflinePlayer doesn't exist

nocturne elbow
#

Not sure what you mean by "doesn't exist" thonk afaik getOfflinePlayer will never return null because for Bukkit "the player will always exist" but uuh you do you lol

normal hedge
#

Lets say you have a bungeecord with 2 servers, Skyblock and Factions

#

If a player joined Skyblock, that doesnt mean they joined factions

#

if they didn't join factions a single time

#

there isn't an offlineplayer right?

nocturne elbow
#

That is correct but getOfflinePlayer will always return a valid object

normal hedge
#

but then getName would be null?

nocturne elbow
#

Null or empty

#

No clue lol

normal hedge
#

hmm okay

#

Well, I assumed it returns null xD

#

if it's null, use the luckperms Username cuz thats synced

#

with mysql

nocturne elbow
normal hedge
#

yes

#

Thats why I assumed it returns null

nocturne elbow
#

Then yeah

normal hedge
inland yacht
crystal sonnet
#

Just give it a try

inland yacht
#

i try but the actions execute after players join

visual field
#

is it possible to return the player's rank colour from the api.

turbid solar
#

Yes depends on how you want

visual field
#

well i have a mention plugin public, looking to support luckperms to have chat color same as the player's rank colour after the mention

nocturne elbow
#

Well you can't really get "the color of the prefix", what if the prefix for my operator group is &#c42e00O&#ca3a00p&#d04700e&#d65400r&#dc6100a&#e26e00t&#e87b00o&#ee8800r&f (a nice smooth gradient)? It has many colors, one for each letter, which one should I pick?

#

If you want to do this with the API the proper way, I suggest you use MetaNodes (a key->value pair node used to store arbitrary data as a string), have a meta node for the key rank-color (or whatever, idk) and for each group set a different value for it, the value would be the color code desired

inland yacht
crystal sonnet
#

You need to be able to figure that out by reading up on how to use Futures

#

If that is too much for you, this is way too advanced for your current programming skill

inland yacht
#

oh ok

#

But just tell me one thing, futures run instantly or not

royal condor
#

They start instantly

#

They just don't finish instantly

#

They are used to capture the output of long running asynchronous taks

#

Like loading players from a database

tribal wave
#

gonna repost from general into here because it's more fitting:
is there a way to maintain any transient nodes on a player while saving a regular node?

from what I understand, transient nodes are just normal nodes which are never saved - meaning as soon as the user is saved when regular nodes are applied to them, the transient nodes are also saved and stop being lost on logout.

is there a way to keep those nodes transient, or only save the nodes that I want to be saved for a user instead of any and all changes made to them?

nocturne elbow
#

Transient nodes are never saved

#

Period

#

If you want transient nodes to be saved..... put the nodes in the normal data map instead of the transient data map?

#

Like, they are still nodes, there is no difference there, the difference relies in which NodeMap they are "saved" (in memory)

tribal wave
#

oooooooooh i was under the impression that there was no difference at all between transient and normal nodes except for them not being saved with the saveUser() function

nocturne elbow
#

There is no difference between the nodes themselves, they are Node instances

tribal wave
#

sorry let me rephrase, i mean i thought that if you saved a node that was applied as a transient node with saveUser() it would be considered a normal node from then on

nocturne elbow
#

But the PermissionHolder has two NodeMaps: one for the DataType.NORMAL, those nodes are saved to storage; and another for DataType.TRANSIENT, those nodes are not saved to storage

tribal wave
#

yeah xd

#

okay this makes much more sense

nocturne elbow
tribal wave
#

yeah... 🥲 i don't know what I was thinking

#

but now that I know it works like this, do I make transient nodes with Node.builder() just like normal nodes

#

or do I have to do something fancier

#

or wait

#

ohh do i apply them to the PermissionHolder differently then

nocturne elbow
#

what

nocturne elbow
#

both NodeMaps store regular everyday Nodes

#

there is no difference between the nodes themselves

#

They are all Nodes

tribal wave
#

gotcha

#

so what I want to do is get the transient NodeMap from the permissionHolder instead of the normal one

#

and add the node to that

tribal wave
#

ooooo that's exactly what I want 😮

#

thank you Fefo, you're a lifesaver ;3

nocturne elbow
dusky wagon
jaunty pecan
#

which event are you referring to?

dusky wagon
#

NodeMutateEvent

nocturne elbow
#

^

dusky wagon
#

but it call on bukkit, when i run /lp user Meerpaluten parent set admin

nocturne elbow
#

Ight then I'mma shut up :<

jaunty pecan
#

it is most definitely called on bungeecord too

#

can you share the code you use on bungee to register your event listener?

#

bear in mind, if the change is applied on bukkit, the event will not be called on bungee, and vice versa

#

in other words, if you use /lpb to make the change, the event will be called on bungeecord, not bukkit

dusky wagon
#

and how can I make it be called on both. Or which event is suitable for this?

nocturne elbow
#

Wait NodeMutateEvent is called??

dusky wagon
#

Yep, that's what the Javadocs say too

nocturne elbow
#

I've been living a lie this whole time, I remember testing one time with that specific event and it never got called, unlike other subclasses

#

Wtf

clever zodiac
#

am I allowed to ask a question about something other than luckperms here xd

jaunty pecan
#

@dusky wagon One of the log events - they are the only ones that get called across the network

clever zodiac
#

its about one of your things tho luck

jaunty pecan
#

which thing

clever zodiac
#

bytebin

jaunty pecan
clever zodiac
#

all right, ty 😄

dusky wagon
#

and how i get the Player from the LogID?

jaunty pecan
#

event.getEntry().getTarget()

#

you will need to check whether the target is the USER type too

dusky wagon
#

ok ty

haughty solar
#

Is there a Luckperms-log event in the Api?

nocturne elbow
#

Hello

#

Is there any way to collect statistics on users using luckpermsapi? For example retrieving the amount of users that inherit a specific group?

crystal sonnet
#

Yes there are methods to look up players with certain permissions. And since group assignments are just that, it's pretty easy actually

nocturne elbow
#

Awesome! So I’d just have to index all players cache with luckpermsapi somehow, then check for permission “group.””” And account for that?

#

Non, the method BrainStone was talking about is UserManager#searchAll(NodeMatcher) :)

#

!javadoc you can check that out in the JavaDoc in the third link

frank driftBOT
nocturne elbow
#

got it thanks, hate to ask for spoonfeeding but im a bit confused on how exactly to implement this? it seems to want a CompletableFuture<Map<UUID, Collection<T>>> which i dont understand, documentation didnt really help much too, id appreciate any help?

crystal sonnet
#

@nocturne elbow are you sure that’s not the return type?

nocturne elbow
#

Return type?

#

Yeah, that’s the value it’s looking for I think

#

I’m not sure on how exactly to match it

crystal sonnet
#

It’s not looking for that. That’s what you are getting back @nocturne elbow

#

Do you know basic programming?

nocturne elbow
#

Yeah very basic

crystal sonnet
#

Then this isn’t for you yet. Making plugins is not suitable for beginners to programming

#

And this API expects you to know a fair bit more about programming that you need for plugins

nocturne elbow
#

Well I can make basic stuff still, that’s what learning is for right?

#

I just need to know what exactly this method is trying to do and how to convert that to the values I want

crystal sonnet
#

Sure. But you’re currently learning to walk. And this is a double marathon

crystal sonnet
nocturne elbow
#

Haha guess you’re right

crystal sonnet
#

I’m not saying you can’t learn these things. I’m just saying you’re jumping into the very deep end

nocturne elbow
#

Alright, if possible could u explain where the flaw in my thinking is though? I’m just confused because that’s the value it’s giving me, presumably I have to set some variable to that returned variable right?

crystal sonnet
#

Absolutely not

nocturne elbow
#

Then query it for the value I want?

#

I see

crystal sonnet
#

It’s a return value

nocturne elbow
#

Return value, like for a public variable?

crystal sonnet
#

Process it the way you need

#

I mean that’s the thing. If you don’t understand what a return value of a function is I have no meaningful way to even begin to convey to you what you’d need to do

#

You’re lacking the very very basics

nocturne elbow
#

I understand what a return value is, just not in this context

crystal sonnet
#

The only thing I can do is to spoonfeed you the solution

nocturne elbow
#

For example like if we have a method that returns a Boolean after specified parameters are inserted, like for example if I want to check for whether or not there is a dirt block in range, I’d do something like public boolean... return true/false

warm crane
#

help?

#

anyone can help me

nocturne elbow
#

So my understanding is that this is somewhat similar to this return value you’re showing me?

crystal sonnet
#

!ask @nocturne elbow

frank driftBOT
#
Please ask your question!

Please ask the question you have. Don't ask to ask, or ask to DM someone. There are people here to help you, but we need to know what to help you with, so please just ask the question you want to in as much detail as possible!

Or, try here first:
Why shouldn't I ask to ask?
crystal sonnet
#

Also check the channel (description) to verify you’re in the right channel @warm crane

warm crane
#

k

#

brainstone can you help me?

crystal sonnet
#

@warm crane not if you’re straight up ignoring what I write

nocturne elbow
#

Ooo I see, like void means no return value right? Or like Boolean, int etc

crystal sonnet
#

Yes

nocturne elbow
#

Is that the “return type” you mean?

crystal sonnet
#

Yes

nocturne elbow
#

Oh awesome, so I’d set up some function like completeablefuture<...> to return queries based on params specified elsewhere?

crystal sonnet
#

No

nocturne elbow
#

Oh okay

crystal sonnet
#

The function already exists

nocturne elbow
#

I see? How do I use it then?

#

If you don’t mind me asking

#

Thanks for helping me by the way, really appreciate it

crystal sonnet
#

You call the function and process the return value

nocturne elbow
#

Could you show me some pseduocode for how would that look? Can’t really wrap my head around it haha

#

Cuz if the function already exists it still needs params right? And I’m assuming it wants map UUID and such

crystal sonnet
#

No

#

That’s the return value

nocturne elbow
#

Would that UUID map be compiled beforehand? Like for all offline players? But I thought luckperms already cached all players offline

#

Ohhh

#

Oh ok ok ok

crystal sonnet
#

The parameter types are in the parentheses

nocturne elbow
#

Sorry lmao this is probably so annoying for ya

#

I see

crystal sonnet
#

As I said

nocturne elbow
#

So you specify what you want, in my case the amount of users that inherit a group, set that to an int, and it’ll just return it?

crystal sonnet
#

This is waay too advanced for you if you don’t even know the very very very basics

nocturne elbow
#

Can’t stick with the basics man plunging right in is how to learn

crystal sonnet
#

Then good luck. I’m out

nocturne elbow
#

Oh alright :/

crystal sonnet
#

Because again. There is no meaningful way I can even try to begin to explain what you have to do except spoonfeeding

#

And that is something I categorically refuse to do

nocturne elbow
#

Yeah I feel u, I don’t want to be spoon fed anyways

#

But even sometimes spoonfeeding can help, not that I want it but it’s definitely a form of learning

crystal sonnet
#

Good. Then you’re at least 2 months of experience shy from being able to do this

nocturne elbow
#

Damn 👀

crystal sonnet
#

And that is cutting it close

crystal sonnet
nocturne elbow
#

Yeah true, most people are just trying to get the info they want then dipping

crystal sonnet
#

And I think you can understand why don’t want to do that considering I help thousands of people a year

nocturne elbow
#

I’m in it for the long run tho haha

#

Absolutely

halcyon mica
nocturne elbow
#

Uuh you don't give it the UUID as a string

#

You either give it the UUID as a UUID or the player name as a String

halcyon mica
#

i try to set User user = luckPerms.getUserManager().getUser(e.getConnection().getUniqueId()); and User user = luckPerms.getUserManager().getUser(pName); but it doesn't work

nocturne elbow
#

Might want to do event priority HIGH or NORMAL, not sure at what stage LP loads user data exactly

#

Or depending on what you want to do exactly, HIGHEST or MONITOR

#

Either that or loadUser instead ¯\_(ツ)_/¯

halcyon mica
#

I've tried everything but it still doesn't work ç_ç

nocturne elbow
#

What is "everything"? Because I have no clue what you tried other than that screenshot you shared above

#

Because loadUser for sure will work

halcyon mica
#

Oh thank you, now it works :D!!!!

glass spear
tepid spruce
#

what

#

it says just that

#

this is the wrong channel also

turbid solar
indigo nest
#

I'm trying to set the player's rank in the track (instead of promote). /lp user TheExus parent settrack dungeon dungeon4 for example.
I figured out setting a perm in the API, but can anyone guide me on doing this?

crystal sonnet
#

@indigo nest you need to remove all inheritance nodes from groups that or on the track

#

Then add the new inheritance node

wheat breach
#

Found a small issue - if listening to NodeMutateEvent and doing something blocking (like a discord api call, which is how I found this), the command will execute and display success but not write changes to the database. I'm not sure if this is local to my environment and setup, and I don't feel familiar enough with the api design to know if this is intended behavior or a bug.

nocturne elbow
#

"something blocking" could be a simple Thread.sleep? Are you able to reliably reproduce this?

wheat breach
#

I can reliably reproduce it with a custom plugin. Would you like me to replace my method with a Thread.sleep to see if it still happens?

nocturne elbow
#

If it's "something blocking" that should work as well, shouldn't it?

#

Eeh open an issue on GitHub anyway I guess

#

!issue

frank driftBOT
nocturne elbow
#

Please follow the issue template

#

Discord formatting breh

wheat breach
# nocturne elbow "something blocking" could be a simple Thread.sleep? Are you able to reliably re...

I replaced the code that was blocking with a 10s Thread.sleep and the bug vanished. Unfortunately, I didn't realize it that replacing the method was the thing that broke the bug for a few hours, but that's probably since it's a bit late. I've also tried a few other hacks (such as doing pointless operations a billion times or something like time = now + 10s; while (current time < time) do nothing) in case thread.sleep was allowing other things to happen in the background - that didn't reproduce the bug either. Want me to upload the method causing the bug to occur?

wheat breach
#
    public void recalculateRoles(UUID uuid) {
        if (uuid == null) return;
        Member member;

        try {
            member = this.guild.retrieveMemberById(sync.getUser(uuid), false).complete();
        } catch (Exception exception) {
            return;
        } // Bad practice but idc

        if (member == null) return;

        for (String group : configManager.getAllGroups()) {
            Role role = configManager.getRole(group);
            if (bridge.hasPermission(uuid, "group." + group) && !member.getRoles().contains(role)) this.guild.addRoleToMember(member, role).queue();
            else if (!bridge.hasPermission(uuid, "group." + group) && member.getRoles().contains(role)) this.guild.removeRoleFromMember(member, role).queue();
        }    
    }
#

This method causes all the issues when called in the NodeMutateEvent

#

It uses the JDA library for Discord.

#

And the sync.getUser function fires off a mysql query to a database with discord user ids and ingame uuids

#

Oh, and bridge.getPermission is a fun method that queries permissions for offline users. The current implementation is

    public boolean hasPermission(UUID user, String permission) {
        return LuckPermsProvider.get().getUserManager().loadUser(user).join().getCachedData().getPermissionData().checkPermission(permission).asBoolean();
    }
magic palm
#

Hello I have problem with api because I have on server saving data on mysql and when I do Group group = api.getGroupManager().getGroup("vip"); // Group doesn't exist? if (group == null) { sender.sendMessage(ChatColor.RED + "group vip" + " does not exist!"); return true; } api.getUserManager().modifyUser(player.getUniqueId(), (User user) ->{ user.data().clear(NodeType.INHERITANCE::matches); Node node = InheritanceNode.builder(group).build(); user.data().add(node); player.sendMessage(ChatColor.GREEN + "[SzczecinProjekt] " + "Nadałeś range na nick: " + args[0]); Bukkit.broadcastMessage("Zakupil vipa"); }); its dont work

turbid solar
#

!nw

frank driftBOT
#
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:
magic palm
#

nothing error normaly its dont work when i send command its give nothing

turbid solar
#

Tried debugging ?

magic palm
#

like how (i'm new in java)

turbid solar
#

log stuff to console

#

also can you send a log of when you done the command?

crystal sonnet
wheat breach
#

In case anyone has the same problem I did with database write issues in the future... after an extremely embarrassing amount of time cloning the offending plugin and removing as much functionality as I could without the bug vanishing, I was left with this.

LuckPermsProvider.get().getEventBus().subscribe(NodeMutateEvent.class, nodeMutateEvent -> {
  if (!nodeMutateEvent.isUser()) return;
  LuckPermsProvider.get().getUserManager().loadUser(((User) nodeMutateEvent.getTarget()).getUniqueId()).join().getCachedData().getPermissionData().checkPermission("group.default").asBoolean();
});```
There are some days I question my past self. 🤦
nocturne elbow
#

why are you loading the user if it's already in the event lol

wheat breach
#

The event was calling another method that called another method that called another method that used a permission handler system where the plugin side was abstracted away and was supposed to work with offline users.

nocturne elbow
#

you can also do LuckPermsEvent#getLuckPerms() btw to get the specific LP instance for that event (not like it'll differ from the one the provider gives but it'd be a better idea)

wheat breach
#

Needless to say, I feel incredibly stupid now lol

#

Welp, now at least if I make that mistake in the future it won't take approx. 12 hours to fix lol

nocturne elbow
#

I still want to know why you're calling loadUser if the user object is already the event target lmao

#

just curious btw

wheat breach
#

The plugin's essentially a homemade version of DiscordSRV but one that runs on bungee so I don't have to have like 5 things connected to discord and triggering the connection ratelimit

#

The method that was originally being called listened for changes ingame to change a user's discord roles depending on their ingame roles

nocturne elbow
#

right

wheat breach
#

Since Bungee's offline player support is garbage, I wrote an interface for permission handling with a hasPermission(UUID, String) function

#

Since this is just a network for friends, I don't want to have like 20+ spigot or forge servers running at once (they want me to install a modpack and play it for like a day >.<).

#

Once they pinged me 38 times in 30 minutes to start one of them I decided to make a ?start <name>, but I wanted it to check ingame permissions (since there's test servers and such they have no business on)

#

(I already had a mysql database mapping discord user ids to uuids btw)

#

So now I have an offline player checking a single permission. And then I wanted to mirror groups to discord, and figured "What's the harm in reusing the PermissionsHandler.hasPermission(UUID, String) function?" since all the actual handling was in LuckPermsPermissionHandler.

#

The mirroring itself was also done in a function called recalculateRoles(UUID) in a different class, so I forgot that the user's data was already loaded when writing the function.

#

tl;dr i abstracted enough that i forgot what i actually had loaded at the time

glass spear
frank driftBOT
obtuse jolt
#

your server have chunk errors, nothing lp related.

glass spear
#

but how to fix it, I clamp the pkm with a compass and sulfur ofaetsya

frank driftBOT
nocturne elbow
#

Please use the appropriate channel

turbid solar
#

?

#

might wanna change your passwords now

wheat breach
#

Eep, can someone delete those? They have live creds

#

And an ip addess that's not localhost - i'd wager to say that there's no ip restriction

turbid solar
nocturne elbow
#

@half tartan might want to be more careful next time you share files with sensitive data over the internet

#

Thankfully I just came in and deleted the links but I really encourage you to change your DB passwords ASAP

turbid solar
#

pretty sure you can't connect to the db anyway

indigo nest
#

Are there any example of removing an Inheritance node from a user? I seem to be having trouble because

#

the group has a server specific context. I get a FAIL_LACKS

nocturne elbow
#

how are you trying to remove it?

indigo nest
#

InheritanceNode.builder node = InheritanceNode.builder("dungeon4").build()
user.data().remove(node)

nocturne elbow
#

mhm well the node you give to NodeMap#remove has to match every aspect of it: node key, node value, contexts and expiry date

#

and well you just said it yourself:
> the group has a server specific context
so you'd need to add it to the builder

#

I think it's withServer or just server

#

or... no I'm imagining things lol

#

withContext(key, value)

indigo nest
#

ahh. Yeah I figured haha, thought I had it until I hit this problem.

#

ok I'll try this

nocturne elbow
#

ye

indigo nest
#

Thanks

nocturne elbow
#

np

indigo nest
#

I'm using skript, so I'm having a bit of fun lol

nocturne elbow
indigo nest
#

quicker for something small I guess

wheat breach
#

I'm wondering if the lp api would work in JavaScript, like in the js placeholderapi expansion...

clever zodiac
#

how does the verbose thing work

#

(I know how to use it, I meant in like the backend)

tired jackal
#

hi everyone, I have a question about luckperms im trying to add a rank beside everyones name but for some reason its not showing

#

I installed everything that is needed for this but still doesnt work

nocturne elbow
#

with the api...?

tired jackal
#

api?

nocturne elbow
tired jackal
#

oh sorry

clever zodiac
#

so complex

#

thank you @nocturne elbow

frank driftBOT
#

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

opal creek
#

and keeps comming

wheat breach
opal creek
#

oh

#

okay thanks

nocturne elbow
#

.. is this to do with the developer api?

mossy surge
#

Hello. Is there an event I can listen to for when a users meta data changes including meta data in groups users inherits or is added to?

nocturne elbow
#

NodeAddEvent?

mossy surge
#

Is there some documentation of this event somewhere?

#

nvm, thanks Fefo 🙂 🙂

nocturne elbow
#

!javadoc in the third link

frank driftBOT
nocturne elbow
#

Very useful

paper burrow
#

hi , how can i delete group using api ?

turbid solar
#

GroupManager#deleteGroup

#

read java docs ;d

crystal sonnet
#

!api

frank driftBOT
hushed bane
#

How i can make (Owner) BackPlayYT ?

#

a prefix

#

@unreal mantle

frank driftBOT
#

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

unreal mantle
#

!meta

frank driftBOT
hushed bane
#

it doesnt

#

why it doesnt work

sour pier
#

Is there a way to store multiple values under the same meta key? I'm trying to store multiple nicknames for users in the meta system (so for example both 'meta.nickname.Aiko' and 'meta.nickname.Aiko123'), but I can't figure out how. user.getCachedData().getMetaData().getMetaValue("nickname") always seems to return only one of them.

paper burrow
crystal sonnet
#

@paper burrow ask in #support-1 or #support-2. It sounds like you’re just using the plugin as is and aren’t making your own plugin interfacing with LP. Please read channel descriptions in the future before asking in random channels

crystal sonnet
sour pier
#

Hrmm, there's absolutely no way to have them in seperate nodes?

crystal sonnet
#

No. One value per key. It’s not a multi map @sour pier

obtuse jolt
#

It sound like you want to store data and not permission related things tbh

sour pier
#

Yeah, I kind of am. I'm trying to find some way to do it through LuckPerms since that makes it easy to share the same data across servers in a bungee network, and it already stores prefixes and suffixes as well.

obtuse jolt
#

then you can do brainstones suggestion

#

you put them all in a string and separate them out later

crystal sonnet
#

Like store them as Nick1,Nick2,Nick3

#

You can easily split them up using String#split

sour pier
#

I'll try that. I was hoping there was a less hacky way to do it, but that should work. Thanks for the help guys! 😄

honest crest
#

idk if this is the place to get support but everytime i try accessing the link to manage the groups the link does not appear

turbid solar
candid quest
#

Any ideas?

#

everything works but the error is annoying

turbid solar
#

try replacing L33 with this::update instead of e -> update()?

candid quest
#

that's what I got first

#

no difference

nocturne elbow
#
    private static Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
    private static LuckPerms luckPerms;

Those have no reason to be static btw

candid quest
#

of course they do

turbid solar
#

wat

candid quest
#

how else am I supposed to save the scoreboard in an easy lightweight way

nocturne elbow
#

????????

#

what??????

candid quest
#

but it's not the problem.

nocturne elbow
#

how do you know?

#

the issue is not related to luckperms but to scoreboard

candid quest
#

it's related to the api..

#

I'm doing something wrong with the api.. that's why I'm in the #luckperms-api ..

nocturne elbow
#

The stacktrace points at this line: player.setScoreboard(scoreboard);

#

In fact, it gets there from the very first line in update()

#

wait a minute

#

shit is being called async

wheat breach
#

getServer().getScheduler() will be helpful

nocturne elbow
#

You need to use the bukkit scheduler to schedule update() in the main thread

nocturne elbow
#

Those really have no reason to be static

candid quest
#

any delay?

nocturne elbow
#

non

wheat breach
#

I can't stress enough how no fun it is to have static things that should in no way be static

#

In my experience it can lead to a lot of weird and questionable behavior and be a pain to fix.

nocturne elbow
#

mhm

candid quest
#

Why wouldn't that be static? The scoreboard should be saved and not recreated over and over again.
It should go to each player and not for each player its own.
So where is the problem?

wheat breach
#

*Me being a hyprocryte by having like 8 static things in my main class that should not be static b/c convenience and "It's just a small plugin"

nocturne elbow
wheat breach
#

If you're constructing a class that extends Plugin or JavaPlugin... I'd feel sorry for you.

candid quest
wheat breach
#

.........

#

...............................

#

............................................................................................

candid quest
#

big oof

wheat breach
#

I've written a few plugins...

nocturne elbow
#

From what I can see in that class there is literally no reason whatsoever why those 2 should be static

wheat breach
#

Nobody should ever create a new instance of a class extending Plugin or JavaPlugin. Leave that to Bungee/Bukkit.

nocturne elbow
#

bet :^)

wheat breach
#

Somewhere out there, there's probably someone creating an instance of CraftServer or something...

candid quest
#

A little tip on the side...
If you want to frighten people away, then continue in the same way...
By distracting from the problem and criticizing the style of programming will not get you anywhere...
Responding sarcastically to questions also do not.
I'm surprised that at the end still came a purposeful hint.

#

it's pretty much meant to @wheat breach

wheat breach
#

A lot of nasty surprises can come from improper access...

#

But thanks for the tip. I'll be sure to apply it to everything I do. /s

nocturne elbow
#

Bad use of static is the reason why commands like /reload (or plugman reloads) are unsafe tbh, in my experience (especially when I didn't know any better), static can lead to some really weird silent issues, particularly in android development.
I really do not see a reason why those 2 should be static in that class, especially because you are instantiating them... from a non static context (registerTeams)?

#

Not trying to "frighten" people or anything, it's a suggestion I thought the second I saw them because
> you are instantiating them... from a non static context
and there are no other static methods or anything in the entire class

wheat breach
nocturne elbow
#

Aaaand they left

wheat breach
#

Pfft. Either way, if they keep programming, they'll learn about the issue some way or another,

#

It'll probably be in the form of a heisenbug, but either way.

nocturne elbow
#

It totally makes sense for those to do that

wheat breach
#

Some of them make a new CraftServer every time a getServer() is called.

crystal sonnet
#

What on earth happened here?

#

Half the messages are deleted I feel

nocturne elbow
#

They are not lol

crystal sonnet
#

I mean like from that guy

wheat breach
crystal sonnet
#

You keep referring to stacktraces and code that’s very clearly no longer there

wheat breach
#

It seems the message was deleted

crystal sonnet
#

See. I said so

#

That’s why I was asking what happened

wheat breach
#

Command + Shift + T / Browsing history are always interesting to use when links are deleted

nocturne elbow
#

@mossy surge how are you trying to get the meta nodes you say returns 0? Could you share your code?

mossy surge
nocturne elbow
#

lol yeah, PermissionHolder#getNodes returns the holder's own nodes, not inherited ones

#

Not sure what is it exactly you need to do, but usually the best is to getCachedData, get meta cache and get the value for the key you want

#

Can't remember the exact methods but you can start in PermissionHolder#getCachedData

#

!javadoc

frank driftBOT
nocturne elbow
#

Third link

crystal sonnet
#

Yeah. Cached Data contains the meta values after resolved inheritance

mossy surge
crystal sonnet
#

I mean if you need the data before it was resolved

mossy surge
crystal sonnet
#

What are you doing where you would need that?

#

Like if you need that you clearly don't use meta for key-value pairs but as an extended data storage and that's not what it was made for

mossy surge
#

each group has a meta data field called "discord_role" and I need to collect all roles and add them to the user using a discord api

crystal sonnet
#

That sounds like you should use your own data storage

#

But the best way would be to build a map with that mapping and rebuild it once permission data changes

#

So in short you iterate over all groups and get their discord role through the group's cached data and store that in a map

#

Then get the user's groups and use the map to figure out the discord roles

#

And also listen to changes in permissions to rebuild that map

#

I think changes in groups are enough

#

@nocturne elbow you're the event expert

frank driftBOT
#

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

nocturne elbow
#

what?

#

am I? thonk

turbid solar
#

yes

nocturne elbow
warm lagoon
#

Hey i am running a SMP server and i am planning to have 2 different SMP servers in the hub. The thing is, when i try to make new ranks on the new smp i edit the ranks from the other smp. i think this is because its connected with bungeecord. does anyone know how to make a seperate luckperms editor for the other smp?

nocturne elbow
#

Is.. this to do with the developer api?

mossy surge
nocturne elbow
#

getInheritedGroups? thonk

mossy surge
nocturne elbow
#

No, hence the name, getInheritedGroups lol

#

I don't remember exactly but maybe it takes some QueryOptions?

crystal sonnet
#

Pretty sure you can get all groups with a single call

mossy surge
#

@crystal sonnet Got it working perfectly now! 🙂

#

One more question: When I add a group to a user(either with a command ingame or with the API), is all the cached data/values refreshed on the fly in the luckperms api or do I have to call refresh on something?

crystal sonnet
#

That should be all refreshed

#

Regarding your mapping: you do update it when there's an update in the LP data, right?

mossy surge
zealous rose
#

Hello

nocturne elbow
#

Hi

zealous rose
#

I'm trying to get the expiry time of a permission node of a user

#

but it doesn't work for some reason

#

here's a picture of my code

#

am I doing it the right way ?

crystal sonnet
#

!cookbook

frank driftBOT
crystal sonnet
#

@zealous rose check out the cook book repo. I'm sure there's an example on how to do that the right way

turbid solar
#

Dont think there is ||yet?||

zealous rose
crystal sonnet
zealous rose
#

Does anyone know how to do it ?

turbid solar
#

!nw btw

frank driftBOT
#
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:
zealous rose
#

huh?

turbid solar
#

What doesnt work

zealous rose
#

I'm doing a command where it show the time left for the rank to be expired, i've tried a method as showen in the screenshot. The thing is that i can't find a way to filter his Nodes to get the last permission node and then get it's expiry time

sorry for the bad english

outer dock
#

How do you initialise an instance of LuckPerms in BungeeCord?

obtuse jolt
#

!downloads get bungeecord version

frank driftBOT
obtuse jolt
#

!bungee

frank driftBOT
outer dock
#

Unsure what it's looking for.

jaunty pecan
#

Make sure you’re depending on api 5.2

remote flower
#

How to I get the players rank prefix?

turbid solar
#

!cookbook

frank driftBOT
turbid solar
#

!api

frank driftBOT
compact spruce
#

I'm not sure if this is the right place for this question. I'm not using the luckperms API, I'm just developing a bungee plugin. My question is: why is it that I am able to use ProxiedPlayer.hasPermission("some.permission") and it returns true when I have that permission, but when I loop through the Collection<String>ProxiedPlayer.getPermissions(), all I get is "bungeecord.command.list" and "bungeecord.command.server"

#

I think it's a fairly reasonable expectation that if hasPermission("some.permission") returns true, then the list of permissions returned by getPermissions() should contain that same permission. What am I missing here? Obviously I am able to check the permission directly, but I need to be able to loops through the permissions and match certain permissions.

#

My setup is using SQL for storage method and plugin messaging on both bungee and spigot

#

My assumption is that behind the scenes, the hasPermission function just checks against the collection returned by getPermission

crystal sonnet
#

There’s significantly more logic going on. Every permissions plugin does a lot more than just maintain such a list.

compact spruce
#

but my point is, hasPermission is a bungeecord api function that correctly returns that the player has the permission

#

the luckperms bungee plugin has to somehow have made that data available for my plugin to be able to correctly check hasPermission

#

and I'm looking at the bungee source code right now and it does in fact check the same Collection that getPermissions returns

#

so I don't get how this is possible

#

oh i think I see.

    @Override
    public Collection<String> getPermissions()
    {
        return Collections.unmodifiableCollection( permissions );
    }
#

it seems that it doesn't allow you to modify the list returned by getPermissions. Yet somehow luckperms is able to insert data that is read by hasPermission

crystal sonnet
#

It’s possible because permission plugins override both functions

compact spruce
#

but UserConnection is a final class

#

so how can that be

crystal sonnet
#

Or at the very least the hasPermission function

#

Are you checking the bungee source code or the bungee api source code?

compact spruce
#

both

#

the api source code is just a bunch of unimplemented interfaces

crystal sonnet
#

More or less

compact spruce
#

doesn't tell me much about what's happening

#

like you can implement proxied player I guess but you'd have to reimplement the entire server to be able to insert your implementation into the ProxiedPlayer list

#

because that also returns an unmodifiable collection

#

I'm confused

crystal sonnet
#

Frankly I can’t tell you where exactly bungee performs the insertion. But permission plugins essentially override the hasPermission function

compact spruce
#

I mostly just wanted to know if there's a way I can loop through the permissions and check for wildcards

#

and I can't find away other than sending the permissions from spigot via plugin messaging

#

or via another server

crystal sonnet
#

While it’s possible that the permission list function remains unchanged, meaning it just reads from the BungeeCord config.yml

compact spruce
#

What i got from luckperms website was that the permissions were synced across servers

#

and that is correct, i am able to check if the user has a permission inside bungee

#

i'm just not able to loop through them i guess

#

that's unfortunate

crystal sonnet
compact spruce
#

I thought I might have to. I don't know anything about the API, presumably it's linked on the luckperms site? hopefully a maven dependency I can add

crystal sonnet
#

!api

frank driftBOT
compact spruce
#

nice

#

thanks

crystal sonnet
#

!cookbook for some examples

frank driftBOT
crystal sonnet
#

You’re welcome

compact spruce
#

nice i was just on that site but I wasn't sure if i needed that. guess i do

crystal sonnet
#

The cookbook is just examples

compact spruce
#

is the API for bungee or spigot or both?

crystal sonnet
compact spruce
#

thanks