#luckperms-api

1 messages · Page 14 of 1

nocturne elbow
#

why not setting permission

jaunty pecan
#

are you saving afterwards?

nocturne elbow
#

hmm?

#

saving?

#

i need to save?

#

how to do that?

jaunty pecan
nocturne elbow
#

btw whats going on with method invocation setpermission may produce nullpointer

#

i should cast user to player?

#

JasCore.lpapi.getUserManager().saveUser((User) p);

jaunty pecan
#

you need to check if getUser is returning null

#

it will do that when the player isn't online

nocturne elbow
#

but i doing that in inventoryClickEvent

#

so

#

player must be online

#
            Node kill1 = JasCore.lpapi.getNodeFactory().newBuilder("JasCore.player.killparticles1").build();


            if(e.getCurrentItem().getType().equals(Material.ANVIL)){
                if(ec.getBalance(p) >= cfg.getInt("SkyWarsShop.Price.KillParticles1")){
                    if(ExpSystem.getLevelPlayer(p) >= cfg.getInt("SkyWarsShop.Lvl.KillParticles1")){
                        if(!JasCore.lpapi.getUser(p.getName()).hasPermission(kill1).asBoolean()){
                            ec.withdrawPlayer(p, cfg.getInt("SkyWarsShop.Price.KillParticles1"));
                            JasCore.lpapi.getUser(p.getName()).setPermission(kill1);
                            JasCore.lpapi.getUserManager().saveUser((User) p);
                            fYml.set("kp1", 1);
                        } else {
                            alreadyOwned.send(p);
                            p.closeInventory();
                        }
                    } else {
                        noLevel.send(p);
                        p.closeInventory();

                    }
                } else {
                    noMoney.send(p);
                    p.closeInventory();

                }
jaunty pecan
#

ok don't worry about checking then

#

also suggest using p.getUniqueId() instead of p.getName()

#

the method accepts both, but uuid is faster

vestal edge
#

How does one add a group?

#

This is a very messy API. o.o

static pendant
#

maybe in this

vestal edge
#

I think I've found out how to do it, I really Wish User#addGroup was a thing, so much simpler! Do we need to save after every modification to a user/group?

sinful moat
#

@trail oar are you at home?

sinful moat
#

To send me your code

trail oar
#

@sinful moat

    User user = plugin.luckPermsApi.getUser(staff.getUniqueId());
    try{
        UserManager userManager = luckPermsApi.getUserManager();
        MetaData metaData = user.getCachedData().getMetaData(Contexts.global());
        String prefix = metaData.getPrefix();
        String suffix = metaData.getSuffix();
        //use the prefix, this is considering that the player is online and data is loaded
    }catch (NullPointerException e){
        plugin.console.sendMessage(ChatColor.RED+"[StaffBot] Error");
        return;
    }

if player is not online, then data is not loaded, you have to load it sth like this
User user = null;
try {
user = userManager.loadUser(UUID.fromString(uuid)).get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
And use user as you want, like above.
Thats working for me, otherwise i get null cause user is not loaded

sinful moat
#

Thank you I will try this

grim pier
#

but it still puts my in group.default while i dont have a rank

crystal sonnet
sonic flare
#
new BukkitRunnable() {
    public void run() {
        CompletableFuture<User> logFuture = api.loadUser(playerUUID);
        logFuture.thenAcceptAsync(log ->
        {
            //
        });
    }
}.runTaskAsynchronously(plugin);```
#

is that

#

how to use that

#

do I need the async runnable?

sonic flare
#

@frank drift do you know? 🙂

crystal sonnet
#

@sonic flare completable futures are already async

#

No need to start an async Action async

sonic flare
#

@crystal sonnet are they always async or just in the case of LuckPerms

frank driftBOT
#

Hey Aerocet! Please don't tag staff members.

sonic flare
#

how do I delete the bot's comment

thorny echo
#

You don't

crystal sonnet
#

You can’t. That’s the point

thorny echo
#

Also, it depends what runs the runnable

#

But you're using runTaskAsynchronously

#

So it's async

sonic flare
#

sooo if I make a method that returns a future is it async or not

crystal sonnet
#

Anyways. CompleteableFutures are designed to be async. The idea is that you can start an async task (or a task async (slight difference)) without a blocking call. It allows you to check if that task has been completed and the value is available

#

@Aerocet#0001

sonic flare
#

I'm still confused though... if my method returns a completablefuture from a database query, do I have to make it async manually

#

or not

#

does it automatically do it async

sonic flare
#

...

long moon
#

No, the future is because LP runs it async for you

marble salmon
#

Hi

#

I want to check if the weight of the player's group is superior to 40

#

How can I do it ?

#

I succeeded, for those who want:

#
LuckPermsApi api = LuckPerms.getApi(); 
if (api.getGroup(api.getUser(event.getName()).getPrimaryGroup()).getWeight().getAsInt() < 40) {
}
crystal sonnet
#

Heifer weight for higher groups, so you’d want the operator to be the other way around

crystal sonnet
#

@nocturne elbow don’t forget to save the changes. The wiki has tons of examples

frank driftBOT
#

Hey Luwie! Please don't tag staff members.

near swallow
#

Hi, I want to check permissions of an offline proxiedplayer using the UUID.
is User#hasPermission(getNodeFactory().newBuilder(...).build()) enough? (Of course I get the user with #loadUser).

crystal sonnet
#

@near swallow should be enough

nocturne elbow
#

Is it possible to set a users group with User.setPrimaryGroup or is there some better way to add and remove user groups? Its not really mentioned on the wiki at all

#

Also using VaultAPI permission.playerAddGroup( player, ADMIN_GROUP ); seems to have no effect at all with LuckPerms, I cant find any into saying how compatible this is with vaults perm system.

umbral bison
#

Hey. How do i set group with api?
Current code:

jaunty pecan
#

looks ok to me

#

if you're wanting to remove default, you may have to add a call to remove that specifically after the user.setprimarygroup call

crystal sonnet
#

@nocturne elbow the wiki has examples on how to properly use the API. Including setting groups

nocturne elbow
#

Went with the lazy solution instead of just running a console command from code. Does the job 👌

crude laurel
#

Hi

#

Quick question

#

If a group inherits other group

#

i.e. group #1 and #2

#

Would player.hasPermission("group.1") return true for a player on group #2?

#

Considering that group #2 interits #1

crude laurel
#

also whats the event to listen to a parent change

crystal sonnet
#

Yes

#

@crude laurel there’s just a generic event. See the wiki on how to listen to it, as it is fired not using the platform’s event system

crude laurel
#

ic

crystal sonnet
#

The “yes” was answering the first question

wheat barn
#

hey people! super dumb question but i was just wondering if it's possible to access the luckperms api in python?

crystal sonnet
#

@wheat barn no

#

It's an API for plugins running on the server

#

So the only way would be to write an interfacing plugin that would communicate with your python scripts

wheat barn
#

Ah ok, ty anyway @crystal sonnet :)

frank driftBOT
#

Hey HewloThere! Please don't tag staff members.

wheat barn
#

Rip me

#

Soz fam

chrome tinsel
#

Can i use the api with bungeecord too?

proud crypt
#

I'd assume so

thorny echo
#

@chrome tinsel You can

#

Although you have to obtain it statically, as described in the wiki

chrome tinsel
#

Ok, thanks!

soft wasp
#

"worldsPowerLossEnabled": {
"standard": true,
"exceptions": []
},

#

In "exceptions": [], I would like to add the following worlds: "MinaPobre" "MinaRica" and "MinaHeroica"

#

Should it be like this? ->

#

"worldsPowerLossEnabled": {
"standard": true,
"exceptions":
},

#

"worldsPowerLossEnabled": {
"standard": true,
"exceptions": [MinaPobre,MinaRica,MinaHeroica]
},

#

?

crystal sonnet
#

@soft wasp this is the LuckPerms Discord.

long moon
#

(x) doubt

soft wasp
#

oops sorry

fleet knoll
#

Hello! How can I set a player into a group ( code ) ?
api.getUser("user name").setPermission("group.name", What is here ? );

#

Can anyone help me ?

#

Or set permission to a player using code

crystal sonnet
#

@fleet knoll check the wiki for examples

fleet knoll
#

Please send me a link, because I'm not found it.

crystal sonnet
#

Navigation is on the right and the API is the last menu element @fleet knoll

earnest zodiac
#

Hey,
With the API how to get a info of a offline user ?

crystal sonnet
#

Load their data first

#

Then use it normally

#

@earnest zodiac

#

Wiki contains examples on just that

fleet knoll
#

In the wiki not tell or example about how to set permission to a player.

ebon ether
fleet knoll
#

@ebon ether .setPermission(node, temporaryMergeBehaviour); What is temporaryMergeBehaviour?

#

I can't only .setPermission(node)

#

It's require temporaryMergeBehaviour

ebon ether
#

I actually cant tell you. I just corrected a error I made and changed the link

earnest zodiac
#

Hey,
I want to get the user prefix or if not set the user primary group prefix. I'am on LuckPermsBungee

#

I have look on the api documentation

teal tartan
fervent oracle
#

Hello. How can i add a group to a player?

rancid moss
#

/lp user (user) parent set (group)

crystal sonnet
#

@rancid moss this is the API channel ;P

#

@fervent oracle the wiki has examples on exactly that.

rancid moss
#

shit I didnt notice that

#

sorry

fervent oracle
#

@crystal sonnet I've already saw that, ty.

frank driftBOT
#

Hey KickPost! Please don't tag staff members.

crystal sonnet
#

Awesome 👍

earnest zodiac
#

@teal tartan I have see this on the API documentation but not working.

#

My code this is for testing / debuging :

#
    @EventHandler
    public void onChat(ChatEvent event)
    {
        if (!event.isCommand()) {
            ProxiedPlayer player = (ProxiedPlayer) event.getSender();

            ContextManager cm = api.getLuckPermsApi().getContextManager();

            User user = api.getUser(player.getUniqueId());
            Group group = api.getGroup(user.getPrimaryGroup());

            Contexts contexts = cm.lookupApplicableContexts(user).orElse(cm.getStaticContexts());

            MetaData metaUser = user.getCachedData().getMetaData(contexts);
            MetaData metaGroup = group.getCachedData().getMetaData(contexts);

            System.out.print("USER: " + metaUser.getPrefix());
            System.out.print("GROUP: " + metaGroup.getPrefix());
            System.out.print("MESSAGE: " + (metaUser.getPrefix() != null ?metaUser.getPrefix():metaGroup.getPrefix()) + " " + player.getDisplayName() + " " + event.getMessage());
        }
    }
rain lodge
#

Hey! How do I set up the API for Bungee? The bukkit 'RegisteredServiceProvider' does not appear to exist in BungeeAPI

thorny echo
#

Grab the API statically, I believe it is LuckPerms.getApi() or LuckPermsApi.getApi() 😃

rain lodge
#

Alright. Thank you 🙂

#

Hey! Another thing..

#

Is it possible to load my plugin after LP?

#

Otherwise I won't be able to set up the API

#

plugin.yml - depend: [LuckPerms]

#

That doesn't seem to work either

thorny echo
#

That's it, I think?

#

does it still start after LP?

rain lodge
#

Before

thorny echo
#

hmm

#

Bungee right?

rain lodge
#

Yep

#

Perhaps it isn't called LuckPerms

#

Okay. I had a typo (actually depends: and not depend:)

rain lodge
#

I found it. I used compile before which it didn't like, using compileOnly fixed the problem

thorny echo
#

Ahhh yeah

rain lodge
#

Hey! So I'm trying to grab the prefix and suffix of some offline players

#

When in the userFuture.thenAcceptAsync(user -> {} lambda, It doesn't seem to add it to the list?

#

This works fine, but then when I want to send the message from an offline user (e.g. from a Discord bridge), It just throws a jolly load of nulls

#

That's using the original code ^

#

@jaunty pecan ?

frank driftBOT
#

Hey TheFlash787! Please don't tag staff members.

jaunty pecan
#

yeah, the getUser method returns null when the player isn't online

#

@rain lodge

rain lodge
#

I gave that a go

#

But no success

#

Would you be able to draft a quick example for grabbing the meta data using that method?

#

The code above shows me trying to use what you send me already ^^

tacit moon
#

Hello Guys i work with the luckperm plugin for 1 Week and now i would like to know how to give a permission to a player with the API. Maybe you have an code example or something like this. Thank you

thorny echo
tacit moon
tacit moon
#

please can you give an example how to give an player ther permissions test.*

thorny echo
#

It's on the wiki

tacit moon
#

but why doesnt work my code ?

jaunty pecan
#

you need to save your changes

tacit moon
#

And how?

jaunty pecan
jade vine
#

Is there a method to get a loaded users group's displayname?

crystal sonnet
#

@jade vine Get a Users primary group and get the group name. There are a few methods to check for the name. The javadocs should tell you which is the right one

finite tiger
#

Is there perhaps a plugin that bridges the PEx api to the LuckPerms api?

polar hinge
#

I'd be doubtful if that exists, at least I've never seen or heard of one

somber prairie
#

nobody would happen to have a pre-done user group i could just copy paste would they

#

:')

rancid moss
#

No.

somber prairie
#

Lol could've guessed

rancid moss
#

Do the work yourself, lazy.

somber prairie
#

wow cant eeven use my ExcuseMe emote

#

but that's what i would've used

prime basin
#

What's the best way to check if a player got a new permission?

rancid moss
#

Lp user user permission info

#

I think

proud crypt
prime basin
#

I meant the API. 😂

thorny echo
#

@prime basin What do you mean by got a new permission?

#

You want your function to run every time a permission is added?

#

Or you want to get all permissions?

prime basin
#

I want a function that runs every time a new permission is added.

crystal sonnet
#

You gotta listen to the LP events

prime basin
#

I know, I am currently using the UserDataRecalculationEvent but there is no way to check what has changed.

crystal sonnet
#

There are other events

#

And make sure that you use the LP event system

prime basin
#

I'm using the LP event system. The problem is that I don't know what the right event is for that what I wanna do.

normal hedge
#

Hey, I have an error again. API is not loaded

#

Not sure why

#

nvm

crystal sonnet
#

@prime basin if you’re using an IDE you should be able to browse the LP API jar and look which events exist

prime basin
#

But there is no event for that...

crystal sonnet
#

There's an event that has Node in it's name iirc @prime basin

prime basin
#

Thanks! I'm going to test it tomorrow.

normal hedge
#

ERROR; API is not loaded

How can I fix that?

ebon ether
#

load the API

normal hedge
#

How

ebon ether
#

Is that a server Error or a coding software error?

normal hedge
#

Server error

ebon ether
#

Put LP on the server

normal hedge
#

I have

#

😂

ebon ether
#

Are you sure it is a LP error and not caused from another dependency?

normal hedge
#

Lp error

ebon ether
#

Whats the full error message, or even better a console log?

jade vine
#

remember you have to load it in your onEnable method

normal hedge
#

It worked before

jaunty pecan
#

your plugin needs to declare a dependency or soft dependency on luckperms

#

but yeah, i can't really comment without the actual error message / seeing your code

normal hedge
#

Hmm ill try things out. Tyy

wicked coral
#

Do luckperms have a limit for maximal permission string length?

jaunty pecan
#

200 characters for sql storage types, others have no such limit

wicked coral
#

Is the limit on the column just a database constraint which i could simply remove, or are there any other validations in code.

jaunty pecan
#

Ahh uhh

#

I'm not too sure

#

can't remember off the top of my head

wicked coral
#

ok, thanks

#

Also is it posisble to attach to one permission node some more context?

Let's say i want to have a permission node which last part will be an incrementing integer.
some.permission.max.amount.of.something:1
some.permission.max.amount.of.something:2
some.permission.max.amountof.something:.n

And then with luckapi i would check if the player has a permission "some.permission.max.amountof.something" and if the permission is present in the player context then get the integer value

#

Im on sponge btw

jaunty pecan
#

You should be using options / "meta" nodes for that

wicked coral
#

I need fast lookups, so iterating over all nodes and checking whenever they start with "some...:"is not an option for me

#

Is this somewhere more documented?

jaunty pecan
#

yes, meta values are cached

#

uhh, here

#

see: "build a metadata node"

#

& then use this for the lookup

#

see: "Retrieving meta data"

#

if you're using sponge, you also have the option of using the native sponge APIs for this

#

What LuckPerms calls "metadata" or "meta nodes" - Sponge calls them options

wicked coral
#

What is relation between a permission node and an option/metadata value (in player context

#

is it 1:1 or 1:n

#

Can a single player have one permission value with more metadata/options?

jaunty pecan
#

yeah technically players can have more than one metadata "value" for each key

#

however, the lookup methods will only return one result - usually the one that was inherited first

#

so if you don't want that, it's down to you to ensure any existing values are cleared before setting a new value - unless you use the Sponge API, in which case that is done for you

mild flax
#

How do I get all players from a specific group?

crystal sonnet
#

Load all players and check if they are in said group

#

@mild flax

prime basin
#

If I call event.isUser in NodeAddEvent I get this error: [LuckPerms] Unable to pass event $Proxy47 to handler eu.unusa.core.listener.LuckPermsListener$$Lambda$1941/753419349 java.lang.reflect.UndeclaredThrowableException at com.sun.proxy.$Proxy47.isUser(Unknown Source) at eu.unusa.core.listener.LuckPermsListener.onNodeAdd(LuckPermsListener.java:25) at me.lucko.luckperms.common.event.LuckPermsEventHandler.invoke(LuckPermsEventHandler.java:108) at me.lucko.luckperms.common.event.LuckPermsEventHandler.invoke(LuckPermsEventHandler.java:45) at me.lucko.luckperms.lib.eventbus.SimpleEventBus.post(SimpleEventBus.java:107) at me.lucko.luckperms.common.event.AbstractEventBus.post(AbstractEventBus.java:84) at me.lucko.luckperms.common.event.EventFactory.lambda$post$0(EventFactory.java:124) at me.lucko.luckperms.common.plugin.scheduler.AbstractJavaScheduler$WrappedRunnable.run(AbstractJavaScheduler.java:79) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266) at java.util.concurrent.FutureTask.run(FutureTask.java) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748) does anyone know how to fix it?

crystal sonnet
#

@jaunty pecan ready for your daily wtf? xD

long moon
#

java.lang.reflect.UndeclaredThrowableException

#

update your API target

#

that exception basically means that the method declares an exception that it didn't used too from what I recall

jaunty pecan
#

has slightly different behaviour in proxy classes

#

although it should have a Cause too, which is usually printed afterwards

#

Is that the full error message, or was there anything else before/after?

#

@prime basin

nocturne elbow
#

Where can I get info on how to use this api

crystal sonnet
#

The wiki

nocturne elbow
#

OK thanks

prime basin
#

This comes afterwards: Caused by: java.lang.IllegalAccessException: no private access for invokespecial: interface me.lucko.luckperms.api.event.node.NodeMutateEvent, from me.lucko.luckperms.api.event.node.NodeMutateEvent/public at java.lang.invoke.MemberName.makeAccessException(MemberName.java:850) at java.lang.invoke.MethodHandles$Lookup.checkSpecialCaller(MethodHandles.java:1572) at java.lang.invoke.MethodHandles$Lookup.unreflectSpecial(MethodHandles.java:1231) at me.lucko.luckperms.common.event.gen.GeneratedEventSpec$EventInvocationHandler.invoke(GeneratedEventSpec.java:149) ... 16 more

crystal sonnet
#

@prime basin for the future:
Exceptions can have multiple Caused by: blocks. They are ironically more important than the messages above. So when copying an error message be sure to always copy the whole thing

prime basin
#

Okay, I couldn't send it because of the discord character-limit.

proud crypt
#

Hastebin

prime basin
#

😶

wraith wedge
#

i installed luckperms on my server and while in the server i can only perform luckperms commands (i am OP and gave myself all luckperms commands through console) i cant even do /help. I made a group called admin and then gave it perms and then added myself to it but i still have no access to any permissions

#

it was fine before i installed luckperms

wraith wedge
#

a girl is LOST

proud crypt
wraith wedge
#

oop

tacit moon
#

Hello Guys i have an problem in my plugin when a player gets there a permission it is going to remove it when the player leave why? i use setPermission

crystal sonnet
#

@tacit moon

#

As the docs on the wiki clearly state you need to save the changes

tacit moon
#

I saved the changes

crystal sonnet
#

Then they should stay

tacit moon
#

But they dont

wicked shadow
#

Is the API for external messaging services incomplete?

#

While I can implement it I don't see how to force LuckPerms to use it?

wicked shadow
#

You can create a message provider, register it and everything but there is no way to make LP use it as configured values for the messaging service are hard coded.

Besides the plugin that registers the messaging service would also need to register it BEFORE LP loads for it to be used.

#

Ahhh I see, LP has an undocumented "custom" messaging service configuration value.

crystal sonnet
#

@wicked shadow mind if I ask what you need a custom messaging service for?

wicked shadow
#

Redis Sentinel.

#

Well, Redisson Java library on top of Redis Sentinel.

crystal sonnet
#

I see

thorny echo
#

@wicked shadow I know a friend of merijilin has made a custom LP messaging service. I think they're KaiNoName on github, the project might be there

tacit moon
#

hello guys how can i fix this problem above

crystal sonnet
#

Showing us your code might be a start @tacit moon

tacit moon
#

luckPermsApi.getUser(p.getUniqueId()).setPermission(luckPermsApi.getNodeFactory().newBuilder(kitManager.getKitPermission(clickedSlot)).build());
luckPermsApi.getUserManager().saveUser(luckPermsApi.getUser(p.getUniqueId()));

#

this works but when the player leave it remove the perms

crystal sonnet
#

Try saving the user instance returned by luckPermsApi.getUser(p.getUniqueId()) in a variable

tacit moon
#

Ok i will try it later

thorny echo
#

Yeah @tacit moon there you're getting the user from the database, modifying your local copy of it, then doing nothing with it. Then you get it again, then save it

tacit moon
#

Ok thx i will try it

crystal sonnet
#

Also just for efficiency, cache objects in variables when you use them again

faint geyser
thorny echo
#

@faint geyser cloudflare is blocking your request

#

Probably because you've made too many

faint geyser
#

how can i solve it @thorny echo

thorny echo
#

No idea @faint geyser

faint geyser
#

ok Thanks @thorny echo

frank driftBOT
#

Hey JOz4! Please don't tag staff members.

faint geyser
#

ok

normal hedge
#

How can I solve: API is not loaded?

#

Im using Maven dep for LuckPermsAPI

crystal sonnet
#

@normal hedge make sure LP is installed on the server

normal hedge
#

Its in all my plugins folders

thorny echo
#

And make sure you're shading it, therefore of type provided

crystal sonnet
#

No

normal hedge
#

ehm

thorny echo
#

?

crystal sonnet
#

The API must not be shaded!

thorny echo
#

Oh sorry

#

I meant you have to set it to type provided and not shade it

#

🤦

crystal sonnet
#

LP implements the API. Shading it cannot work

thorny echo
#

I haven't used Maven but you have to compileOnly instead of compile in gradle. I just used the wrong word

crystal sonnet
#

Also make that your plugin declares a dependency on LP so LP loads first

#

While that is recommended, it’s not necessary @thorny echo

#

@normal hedge also don’t try to access it before onEnable

thorny echo
#

@crystal sonnet what do you mean? compile shades it right

crystal sonnet
#

No

#

shade shades it

#

Oh wait. That’s gradle. But it won’t get shaded in if you don’t have the shade plugin

thorny echo
#

🤔 what about if I've got the shadow plugin installed

#

Exactly

#

If you've got any other dependencies that need shading then you have to install the shadow plugin which means that things marked as compile will be shaded

crystal sonnet
#

Yeah. Shouldn’t be an issue though

#

Shading doesn’t relocate by default

#

So it’ll still work. At least the basics

thorny echo
#

Well I've used compile before on plugins that use the lp api and it hasn't worked

#

Worked as soon as I changed it to compileOnly

thorny echo
#

If I load the user, rather than getting them, is it guaranteed that that is up to date?

#

Uh.... turns out you can't access MetaData inside of a ContextCalculator

#

kind of makes sense but uh

#

kinda screws what I was about to make :9

#

Hey @jaunty pecan, I have a question, sorry for pinging you

#

Is there a way I can grab metadata inside of a contexts calculator? I'm working on a plugin that uses LP meta to store whether a staff member is in staff mode, and displays that as a context

#

But it causes a recursion stack overflow if I calculate contexts inside of a ContextCalculator

rancid moss
#

I can't believe you've pinged our God, our worthy one. God bless his soul

thorny echo
#

Oh wait nevermind me I can use Context.global()

#

I know 😮

#

Hey Void! Please don't tag staff members.

jaunty pecan
#

here's the "rules" for implementing context calculators

#

they're unwritten rules at the moment, but eventually will be added to the LP & Sponge javadocs

thorny echo
#

Right now, this is what I'm doing

#

Is that kosher?

jaunty pecan
#

yeah that's ok

thorny echo
#

👌 thanks

#

Also I got errors longer than hastebin upload allows when I did recursive contexts accidentally 😰

civic oxide
#

I'm new here. Can i when the player change his rang update him(I mean the tablist...). Sorry for my bad English i'm from Germany

crystal sonnet
#

I’ve read it like 3 times

#

Even tried translating it back to German

#

But I still have no idea what you want to say

civic oxide
#

I would like if the edge of the player is changed to update his tabliste, is there an event for that? (Google translater)

crystal sonnet
#

@civic oxide nochmal auf deutsch bitte

#

Und versuche https://deepl.com

civic oxide
#

Kannst du deutsch?

crystal sonnet
#

Nein. Ich tu nur so

dull orchid
#

Can someone help me how to check does player have temporary group with LP API?

dull orchid
#

Anyone?

civic oxide
#

Ich möchte wenn der Spieler einen Rang bekommt die Tablist und das Scoreboard updaten

jaunty pecan
#

@dull orchid you want to check for temporary groups only, or just groups in general?

crystal sonnet
#

@civic oxide es gibt ein Event, wenn sich Permissions eines Spielers ändern. Im Wiki steht mehr

civic oxide
#

kk

dull orchid
#

@jaunty pecan i know how to check for permanent group, but i need for temporary

frank driftBOT
#

Hey Lobenski! Please don't tag staff members.

dull orchid
#

Ops sry

thorny echo
#

@dull orchid Get the group Node object, there should be a method like .isTemporary()...

dull orchid
#

Can you give me example

#

I dont understand this API really well

thorny echo
#

Yeah one sec

#
List<Node> nodes = user.getAllNodes();
Node found;
for (Node node : nodes) {
     if (node.isTemporary() && node.isGroupNode() && node.getPermission() == "group.moderator") {
         found = node;
    }
}
// use found
#

@dull orchid

dull orchid
#

Ty 😃

wispy harness
#

Can you also use the api for bungeecord

jaunty pecan
#

yep

wispy harness
#

Hmm

#

Last time i tried it wasn't working

#

😮

#

Same usage aight?

#

@jaunty pecan ?

frank driftBOT
#

Hey iFlyinq! Please don't tag staff members.

wispy harness
#

Oepms

#

Sorry ❤

jaunty pecan
#

yep same usage

#

just make sure your plugin depends on LP

wispy harness
#

How can i check if an group has an specific permission?

dull orchid
#

Myb

for (Node node : nodes) {
     if (node.isGroupNode() && node.getPermission() == "perm.ission") {
         //Return true?
    }
}
#

@wispy harness

thorny echo
#

@dull orchid That won't work

#

They want to check if a Group has a permission. Your code will loop through a Users permissions, and that if statement is broken, a node can't be a group node and have a permission other than group.something

dull orchid
#

Kk 😆

wispy harness
#

Ye its fixed

#

Just forget to remove it xx

dull orchid
#

How to get player's parent group name?

thorny echo
#

player.getPrimaryGroup iirc

#
  • @dull orchid
dull orchid
#

kk, ty

thorny echo
#

Your IDE's autocomplete is a powerful tool...

arctic moon
#

Is it possible to use the API through a Bungeecord plugin? As soon as I try to get an instance of the API I get an error that the API is not loaded.

crystal sonnet
#

@arctic moon yes it is. Make sure that’ your plugin depends on LP (soft or hard dependency is up to you) and make sure to not try to access it before your onEnable

nocturne elbow
#

How can I do register this LuckPermsAPI in my main as an instance? As soon as I tried it, I got an error called Caused by: java.lang.IllegalStateException: API is not loaded..

thorny echo
#

@nocturne elbow Make sure you're not shading it in and that you depend upon it in your plugin.yml

nocturne elbow
#

In my plugin.yml it says depends: [LuckPerms]. It's for BungeeCord

thorny echo
#

Okay

#

And the other part

nocturne elbow
#

`ProxiedPlayer proxiedPlayer = (ProxiedPlayer) commandSender;
LuckPermsApi luckPermsApi = LuckPerms.getApi();

    User user = luckPermsApi.getUserManager().getUser(proxiedPlayer.getUniqueId());`
thorny echo
#

Are you shading it?

nocturne elbow
#

I'm working with maven an I shade it, yes.

thorny echo
#

Don't

#

Put it as <type> provided </type>

nocturne elbow
#

It works, i changed it to
<type>jar</type> <scope>provided</scope>

#

Thank you c:

thorny echo
#

You're welcome!

rancid eagle
#

Hullo

thorny echo
#

Hi

#

LP has a java api

nocturne elbow
#

How can I change a rank/parent of an user via the API? I tried it by using this: `
User user = luckPermsApi.getUser(args[0]);

        UserManager userManager = luckPermsApi.getUserManager();

        user.setPrimaryGroup(args[1].toLowerCase());
        userManager.saveUser(user);`
crystal sonnet
#

@nocturne elbow the wiki should have examples on how to change player groups. Setting the primary group is not the way to do it. I’d also recommend you read the java docs your IDE displays when hovering over methods.

nocturne elbow
#

Okay, thank you.

jade vine
#

Is there a way to check if an user inherits a group from a string?

#

so if I had a rank called "admin", check if it matches a luckperm group called admin

crystal sonnet
#

Sure. Get all the players permission nodes and check if it contains group.admin

#

Or even easier just check if the player has the permission group.admin through the platforms permission system

#

That’ll only work with LP though @jade vine

jade vine
#

That will give me a Tristate, won't it?

#

Because if I use hasPermission it needs a Node

crystal sonnet
#

The platforms permission check will return a Boolean

#

LPs method a tristate

jade vine
#

Can I check if the permission is true or false with the tristate though? Looks like you can, just inspected the enum

crystal sonnet
#

I’d recommend you use the platform’s checks unless you need to check for offline staff

#

Yes you can. It has the respective conversion methods

jade vine
#

Oh there's a asBoolean method

crystal sonnet
#

Yup. Will only return true when the tristate is true

jade vine
#

Alright. Thank you for the help, appreciate it!

crystal sonnet
#

You’re welcome

lone spoke
#

How can i got rank time?

#

for how long it its

#

for specific player

#

I Want to check player group and time

upbeat karma
#

f

#

f

crystal sonnet
#

@lone spoke check the examples on the wiki

latent briar
#

Hello

#

What event should I use, when I want to check that player's temporary permission expired?

crystal sonnet
#

Not sure if there’s an event

#

@jaunty pecan

modern yew
#

is there any event like onParentSetEvent ?

crystal sonnet
#

No. But a more generic event when permissions get changed

wispy harness
#

Hi, i've got an question,

thorny echo
#

wassup?

wispy harness
#

How is the messaging between multiple servers with Luckperms? 😮

#

Bcz in Console i see SQL Messaging

thorny echo
#

You want the code explanation or the overview?

wispy harness
#

Uhm

#

Code is aight xd

#

I was wondering the whole messaging of Luckperms.

thorny echo
#

Well basically there's a bunch of drivers that define how pings can be sent across servers

#

Each driver can put it's own config in the config.yml, for example the redis driver adds a redis host config option

wispy harness
#

yeah, but when i use MySQL;

thorny echo
#

Then each driver has to do it's job and send messages to any servers that need them

wispy harness
#

How did he ever made that 😮

thorny echo
#

The sql driver uses a message table I believe

wispy harness
#

Owh 😮

#

But if you check it like each 1ms

thorny echo
#

Basically just a table each instance spams ARE DERE NEW MESSAGES?

wispy harness
#

Its lagging af isnt it?

thorny echo
#

Not each ms, it's done every couple seconds I believe

#

It doesn't have to be instant

wispy harness
#

Its pritty instant 😮

thorny echo
#

Yeah, up to a few seconds

#

😉

wispy harness
#

HMM

#

xD

#

Bcz i want to create a new Plugin to link discord accounts etc

#

And i want to use a Messaging channel to do that.

thorny echo
#

Why would you do that?

#

Just store shit in luckperms meta via the api

wispy harness
#

But..

thorny echo
#

Let LP deal with carrying messages

wispy harness
#

The linking part itsself.

thorny echo
#

Ah

wispy harness
#

Like that when you type in your MC name in DC its instant opening a book on the server.

#

Like that xd

#

And Bungee

thorny echo
#

Use HTTP requests

wispy harness
#

So you cant use JDA in that xd

#

Never worked w/ https requests 😮

thorny echo
#

option a) Run a Spark http server from the bungee plugin and call it using your fav http library from a discord bot
option b) Run a redis server and ferry messages through it

#

And it's not great practice but you can run JDA from a bungee plugin

#

I've done it before 😛

wispy harness
#

I also do that xD

thorny echo
crystal sonnet
#

@wispy harness even at a rate of 0.1 ms you wouldn’t feel anything. As it’s async anyways

#

MySQL is pretty decent at handling a ton of connections

wispy harness
#

So you say when you do each 1ms a SQL Statement

#

You wont feel it?

crystal sonnet
#

If the ping is low enough, absoltely not

wispy harness
#

Hmm

#

When i try to do each 60 seconds a check its allready in the Timings for lagg.

crystal sonnet
#

You need to do it async

#

And not on the main server thread

wispy harness
#

And how can i do that Async

#

Just by using synchronized?

crystal sonnet
#

There should be plenty of tutorials for your platform

#

And you can do it with plain java too

thorny echo
#

^

crystal sonnet
#

Async is not magic

wispy harness
#

xd

nocturne elbow
#
command hey:
    trigger:
        execute unsafe "SELECT {@oyuncuadi} FROM {@database} ORDER BY {@tablo-satir} DESC LIMIT 0,1" in {murder} and store the result in {1::*}
        set {_grup} to value of placeholder "luckperms_primary_group_name" from {1::playername::1}
        broadcast "%{_prefix}% %{_grup}%"
#

He can't get any data at all. {1::playername::1} There is a problem with this section.
Can you help me?

frigid leaf
#

Hello people, with which event can I query whether a user has changed the group? Please Tagg me with @frigid leaf

delicate iris
#

Aight so, I code SavageFactions, Im trying to use an async task in a method but I cannot actually return a value as the values have to be final if used in the actual code it self. So how about I be able to return a value?

public String getPrimaryGroup(OfflinePlayer player) {
        Bukkit.getScheduler().runTaskAsynchronously(this, () -> {
            return perms == null || !perms.hasGroupSupport() ? " " : perms.getPrimaryGroup(Bukkit.getWorlds().get(0).toString(), player);
        });
    }

Obviously you cannot do this because the lambda will take the return value not the actual method we wanna return for. Could anyone of the people give any ideas

#

Luck perms wont let my plugin perform lookups as theyre on the main thread

#

and I cannot do a async task

#

cuz

#

i cannot return

#

@jaunty pecan

frank driftBOT
#

Hey ProSavage! Please don't tag staff members.

jaunty pecan
#

ProSavage, you can use callbacks. Pass a Consumer<String> to the method

#

And then call that once the value in the async task is found

delicate iris
#

Awesome, Ill keep that in mind Luck!

narrow blade
#

Hei 😃 i know this is a really dump question but im new to it. who can i add a permission to a user which is only applyed to one world and only a specific time... hope anyone can help me 😃 thanks alot

thorny echo
#

Check the docs for NodeFactory

#

I believe there's something like .setContext("server", "lobby");

narrow blade
#

i ve looked there but i´ve not found something like this....

thorny echo
narrow blade
#

i think im too stupid to use luckperm...

narrow blade
#

can anyone just send me an example of this.... :/

narrow blade
#

no one? ok...

nocturne elbow
#

Wiki

narrow blade
#

i just looked there... the wiki is confusing

nocturne elbow
#

Well, what information do u want
?

#

@narrow blade

narrow blade
#

i want to set a permisson to an user for a specific time and only in one world...

crystal sonnet
#

Use the NodeBuilder. Set the time and the context

#

And for the context use the ContextBuilder

narrow blade
#

.. ok but my Problem is that my English is Not the best and i dont understand much of the explanation in the Wiki...

crystal sonnet
#

Then there’s really not much we can do

nocturne elbow
#

What's API? If anyone calls me a noob, I'm pulling out my .44 magnum and blowing your brain to bits.

#

Ofc I'm joking.

crystal sonnet
#

Google is a thing. And I’m mentioning this because you’ll find better answers there than I could here

nocturne elbow
#

pulls out glock

nocturne elbow
#

Jeez

wispy harness
#

hmm

#

How can i listen to LuckPerms's events?

#

@crystal sonnet ?

frank driftBOT
#

Hey iFlyinq! Please don't tag staff members.

wispy harness
#

Owh

#

x

crystal sonnet
#

wiki is a thing @wispy harness

wispy harness
#

Cant find anything on the wiki.

jaunty pecan
wispy harness
#

I'm down

#

xd

#

OWHH

#

On the usage tab 😦

#

What is the event called when a player's parents are getting editted?

#

?

#

Hello?

#

@crystal sonnet sorry for mention

frank driftBOT
#

Hey iFlyinq! Please don't tag staff members.

crystal sonnet
#

@wispy harness there's only an event for when nodes change

#

You'll need to implement checks yourself if that meant a parent changed

wispy harness
#

That includes also group.?

#

Aight?

crystal sonnet
#

Yes

#

Everything in LP is a permission node

wispy harness
#

& is that also getting fired when a players temp rank is gone?

crystal sonnet
#

I'm not sure but I don't think so

#

If an event is fired it's that

wispy harness
#

Ill test.

crystal sonnet
#

You'll need to check

wispy harness
#

Thanks for responding & sorry for mention.

#

It isn't even working.

#
    public ParentsUpdateListener(LuckPermsApi api) {
        EventBus eventBus = api.getEventBus();
        eventBus.subscribe(NodeAddEvent.class, this::onNodeAdd);
        eventBus.subscribe(UserLoginProcessEvent.class, this::onShit);
    }

    private void onNodeAdd(NodeAddEvent e) {
        System.out.print(e.getNode().getPermission());
        System.out.print(e.getTarget().getFriendlyName() + " -> " + e.getNode().getPermission());
    }```
jaunty pecan
#

are you sure the ParentsUpdateListener constructor is being called?

#

I know these events work because I use them myself in other projects :p

wispy harness
#

Strange

#

Bcz if i use eg UserLoginEvent

#

In that class

#

Its working.

#

& Its Bungee.

nocturne elbow
#

hello, can i check player's permission in AsyncPlayerPreLoginEvent?

nocturne elbow
#

there is way to get hasPermission() in ApiUser?

#
LuckPerms.getApi().getUserManager().loadUser(player.getUniqueId()).join().hasPermission("test")
crystal sonnet
#

Don’t use the join() also the wiki has examples @nocturne elbow

nocturne elbow
#

tried without join()

#

doesn't work too

crystal sonnet
#

Check the wiki for examples

nocturne elbow
#

there is no example for permission 😦

#

only for groups

#

and for groups it works

#

but not for permission

crystal sonnet
#

There’s is an example for loading players

#

And certainly one to check permissions

#

You do it the same way for groups and players

#

Also your IDE should help you with the methods

#

And you should add the Javadocs of the API or the source so you can see the docs in your IDE

#

That’s incredibly useful

nocturne elbow
#
LuckPerms.getApi().getUserManager().loadUser(event.getUniqueId()).join().getPrimaryGroup()
#

it works

crystal sonnet
#

Why are you calling join()?

nocturne elbow
#

because player is offline

crystal sonnet
#

Doesn’t matter

nocturne elbow
#

and it doesn't work without join()

crystal sonnet
#

It certainly works for me without

#

But gimme a minute

#

And thanks for ignoring my comment above ^^

#

Oh my apologies

#

It returns a CompletableFuture

nocturne elbow
#

yes

crystal sonnet
#

So join() is needed.

nocturne elbow
#

i know

crystal sonnet
#

I mean all it does is wait for the user to load. Not making them join the server

#

And I’m certain there’s an example on the wiki showing how to do that

#

Does that example here help @nocturne elbow ?

signal seal
#

@jaunty pecan Can you help me?

frank driftBOT
#

Hey PerryPlaysMC! Please don't tag staff members.

signal seal
#

shush

jaunty pecan
#

No I can't, you haven't provided any information about what you want help with 😉

#

General rule is: don't ask to ask (even though you may see it as being polite, it just slows things down) - just ask your full question, give all the info you have, and wait patiently for a reply

#

;p

signal seal
#

Your API Commodore won't work for me

#

I copied your Example

#

and it still didn't work

#

Can you join my server and I can show you?

#

@jaunty pecan

frank driftBOT
#

Hey PerryPlaysMC! Please don't tag staff members.

signal seal
#

shhh clippy

#

shhh

jaunty pecan
#

well, the library definitely works, I use it myself :p

#

so you're probably doing something wrong

#

I need to see your code / any errors you're getting to be able to help

signal seal
#
        PluginCommand command = getCommand("testa");
        if (CommodoreProvider.isSupported()) {

            // get a commodore instance
            Commodore commodore = CommodoreProvider.getCommodore(this);

            // register your completions.
            registerCompletions(commodore, command);
        }
    }
    private static void registerCompletions(Commodore commodore, PluginCommand command) {
        commodore.register(command, LiteralArgumentBuilder.literal("testa")
                .then(RequiredArgumentBuilder.argument("some-argument", StringArgumentType.string()))
                .then(RequiredArgumentBuilder.argument("some-other-argument", BoolArgumentType.bool())
                .argument("Hey", StringArgumentType.string()))
        );
        for(LiteralCommandNode<?> a : commodore.getRegisteredNodes()) {
            System.out.println(a.getLiteral());
        }
    }```
#
     PluginCommand command = getCommand("testa");
        if (CommodoreProvider.isSupported()) {

            // get a commodore instance
            Commodore commodore = CommodoreProvider.getCommodore(this);

            // register your completions.
            registerCompletions(commodore, command);
        }
    }``` is in onEnable
jaunty pecan
#

I mean, it looks ok

#

but idk what you're trying to achieve

signal seal
#

Can you join my server and I can show you?

#

@jaunty pecan

frank driftBOT
#

Hey PerryPlaysMC! Please don't tag staff members.

jaunty pecan
#

no

#

and please stop tagging me

#

the bot is there for a reason

signal seal
#

It loads it as /minecraft:testa but it doesn't have the argument thing

#

saying "some-argument" or "some-other-argument"

jaunty pecan
#

that's because some-argument is nested under "testa"

#

however, that's an issue with your usage of brigadier, nothing wrong with commodore

signal seal
#

What is "literal"?

#

is it just the command name?

#

I'm so lost ;-;

dense steeple
#

literal means one of the options NEEDS to be present in order for the command to go through

#

If the first argument of a command is a literal and you supply the options ONE TWO and THREE then you must supply one of those when running the command

#

/testa ONE would be valid, /testa five would not.

signal seal
#

How do I fix the CommandSyntaxException?

#

I don't understand it

#
CommandDispatcher<CommandSource> dispatcher = new CommandDispatcher<>();
        LiteralArgumentBuilder<CommandSource> s = LiteralArgumentBuilder.literal("testa");
        s.literal("testa").then(argument("aye", StringArgumentType.greedyString()))
                .then(
                        argument("bar", integer())
                                .executes(c -> {
                                    System.out.println("Bar is " + getInteger(c, "bar"));
                                    return 1;
                                })
                ).executes(c -> {
            System.out.println("Called foo with no arguments");
            return 1;
        });
        dispatcher.register(s);
        final ParseResults<CommandSource> parse = dispatcher.parse("", getConsole());
        final int result = dispatcher.execute(parse);```
#

I have this

#

copied the stuff from the git

rancid moss
#

@jaunty pecan i secretly have feelings for you

frank driftBOT
#

Hey Vaughn! Please don't tag staff members.

rancid moss
#

Oh shit, sorry

iron tendon
#

@rancid moss gay

nocturne elbow
#

@rancid moss i have feelings for you

fossil girder
#

🏳️‍🌈

nocturne elbow
#

@fossil girder lmao

rancid moss
#

lol

nocturne elbow
#

@jaunty pecan @jaunty pecan we talked yesterday about working with permissions to our core... But the thing is...
We want to get the data before player joins.. Example you gave me an example about the whitelist.
But the player have first to join the server to get the whitelist data and then get kicked or how do you manage that?

frank driftBOT
#

Hey /home/UserRoot! Please don't tag staff members.

nocturne elbow
#

Sorry...

jolly hazel
#

Lol apologising to a bot

jaunty pecan
#

use the PlayerLoginEvent

nocturne elbow
#

Really?

#

hmm

rancid moss
#

@jolly hazel Hey, Clippy is a human too!

#

This some disrespect and gender guessing

jolly hazel
#

Dang... Sry

rancid moss
#

What if there's a human being typing all this shit?

thorny echo
#

It's me

rancid moss
#

My clippy gang gang

#

See

jolly hazel
#

Then tell it to stop saying the same thing every time it speaks

thorny echo
#

The staff joked long before I was a mod that I would be a good replacement for clippy

jolly hazel
#

I'm real clip gang

rancid moss
#

He doesn't know other words, stop

jolly hazel
#

Why you assume it's gender

#

Lol

rancid moss
#

He told me he was a male

#

No gender assuming here, all clear

#

I'm calling 911

keen rain
#

how can i check a users group in luckperms using the api?

crystal sonnet
#

@keen rain the wiki has a lot of examples

nocturne elbow
#

How can I get the primarygroup of a user? Because if I go trough all the nodes I don't see a object like isPrimaryGroup.

#

@jaunty pecan do you know that? or is that not implemented in the API?

frank driftBOT
#

Hey NoPermission | Joël! Please don't tag staff members.

jaunty pecan
#

It's a method on User

nocturne elbow
#

@ancient gazelle

#

^^

ancient gazelle
#

Oh yea I forgot you can grab the name of the primarygroup and then get the group object through the getGroup method

#

Thanks

languid yarrow
#

I use "user.setPrimaryGroup("default")" but it doesn't do anything.. can anyone explain me why and what to use?

crystal sonnet
#

As said before, check the wiki

languid yarrow
#

how to get the parent from a user?

crystal sonnet
#

Did you check the examples on the wiki?

echo harness
#

hey, how can i get duration on group ? (expiry time)

#

is it like in metadata or where ?

crystal sonnet
#

Did you check the example on the wiki @echo harness

echo harness
#

im looking in developer api usage for like 15 minutes now

#

i think i can get it in user.getAllNodes()

#

because when i looked in javadocs i saw there getExpiry()

crystal sonnet
#

You can get the primary group of a user

echo harness
#

user.getPrimaryGroup() like that ?

crystal sonnet
#

turn it into a group node and get it from the player, then check the time

echo harness
#

ohhhh

crystal sonnet
#

Group nodes are literally just group.<group>

echo harness
#

i love u

#

ok i got group instance

crystal sonnet
#

And if you can't get the node directly, get all nodes, stream them, filter by their name and bam

#

*permission

echo harness
#

i have group instance now

#

is it in cacheddata ?

crystal sonnet
#

Probably

#

I don't know the API by heart

echo harness
#

i dont think expiry time is in group instance

crystal sonnet
#

You need a node instance

echo harness
#

Set<String> groups = user.getAllNodes().stream() like this ?

#

then filter it and get expire time ?

#

it must be there

#

because in javadocs theres getExpiry under node

crystal sonnet
#

If it's a xxx<String> then you have the wrong method

#

The user method needs to return xxx<Node>

#

And then use normal stream semantics on it

echo harness
#

well getExpiry is date

#

so do i do like Date expiry = user.getAllNodes()......

#

?

#

i think i got it

#

Date expiry = user.getAllNodes().first().getExpiry();

#

oh this wont work am i right...

jaunty pecan
#

not quite

echo harness
#

because it will get first permisison

#

not even group

jaunty pecan
#
public Date getExpiryTime(User user, String group) {
    return user.getOwnNodes().stream()
            .filter(Node::isGroupNode)
            .filter(Node::isTemporary)
            .filter(n -> n.getGroupName().equals(group))
            .map(Node::getExpiry)
            .findFirst()
            .orElse(null);
}
echo harness
#

well i would not get that either :DDD

#

thank you

#

i wasted my time figuring it out 😄

jaunty pecan
#

ya it's just stream magic

echo harness
#

but i was going the right direction 😄

jaunty pecan
#

the equivalent code just using java loop / selection constructs looks like

#
public Date getExpiryTime(User user, String group) {
    for (Node n : user.getOwnNodes()) {
        if (n.isGroupNode()) {
            if (n.isTemporary()) {
                if (n.getGroupName().equals(group)) {
                    Date expiry = n.getExpiry();
                    return expiry;
                }
            }
        }
    }
    return null;
}
echo harness
#

oh

#

im so dumb ...

#

i did this getExpiryTime(user, this.plugin.api.getGroupManager().getGroup(user.getPrimaryGroup()));

#

then saw it requires String....

jaunty pecan
#

mhm

#

so just: getExpiryTime(user, user.getPrimaryGroup());

echo harness
#

ye

#

i did that already 😄

jaunty pecan
#

👍

echo harness
#

ye im making my own placeholder

jaunty pecan
#

nice!

echo harness
#

for expire time

#

so it will show expire time for current group

jaunty pecan
#

uhh

#

bear in mind

#

the users primary group miiight not be temporary

#

😉

echo harness
#

ye i know

#

like u mean

#

primary will be default

#

and second one would be temporary ?

#

for example vip ?

jaunty pecan
#

possibly

#

it depends how you have things setup

echo harness
#

i have addtemp

#

and that always sets the new one to primary one doesnt it ?

#

it does work

#

but i have question

#

if theres two temporary groups

#

and first one expires

#

will it set the second one to primary ?

#

i will make the code check if expiry is null and if it is it will make the tab just empty

jaunty pecan
#

yep

#

by default the "primary" group is just the one with the highest weight

echo harness
#

ok i love u luck

#

everything works

echo harness
#

your API is brilliant

jaunty pecan
#

sweet

#

glad you managed to work it out 😉

echo harness
#

yeah im not that terrible with java

#

Luck, when i want to check for permission expiry time

#

do it need to filter if its permission ?

#

like if u have isGroupNode

#

do i need to do something like that too ?

#
                .filter(Node::isTemporary)
                .filter(n -> n.getPermission().equals("cmi.command.fly"))
                .map(Node::getExpiryUnixTime)
                .findFirst()
                .map(e -> formatTime((int) (e - currentTime)))
                .orElse(null);
``` i have this atm, is there something wrong about it ?
crystal sonnet
#

Looks good

echo harness
#

im little bit scared

#

what if GROUP get thru first filter

#

and then hits n.getPermission

#

that will do error wouldn't it ?

crystal sonnet
#

Though a small tip, have the filter like this n -> "cmi.command.fly".equals(n.getPermission())

echo harness
#

whats the difference ?

crystal sonnet
#

It's NullPointer safe

echo harness
#

oh

#

thats actually 200iq

crystal sonnet
#

a string constant can never be null

echo harness
#

i have never though of that

crystal sonnet
#

But a method can return null, even if it promises it doesn't

echo harness
#

this tip will solve the issue

#

if it hits non permission node

#

it will not throw nullpointer

crystal sonnet
#

Everything is a permission node

#

even group nodes

echo harness
#

oooohh

#

so if it hits gorup

#

group

#

it will return group.<group> ??,

crystal sonnet
#

Yes

echo harness
#

oooohhh

crystal sonnet
#

Also .findAny() is faster

#

In theory at least

echo harness
#

well it will find random in array am i right ?

#

and it doesnt matter

#

because there will be only one thing

crystal sonnet
#

If you can only have one match at most (which is the case if you're looking for a specific node), findAny is the better option

echo harness
#

well what does findAny do ?

crystal sonnet
#

Because it allows the stream to be processed parallel, if it wants to do that

#

While findFirst requires the stream to be sequential

echo harness
#

"well what does findAny do ?"

crystal sonnet
#

It finds any one element in the stream

echo harness
#

like random element ?

crystal sonnet
#

if there are multiple, it can be any

#

it's relevant when you have a parallel stream

echo harness
#

findany is only in stream right ?

crystal sonnet
#

It's a method of stream

#

use it exactly as findFirst

#

As long as you don't need explicitly the first element in a stream, use findAny

echo harness
#

ok

#

so

crystal sonnet
#

It's either faster or equally fast

echo harness
#

findAny gets random element from stream ?

crystal sonnet
#

No. The first it finds

echo harness
#

oooh

crystal sonnet
#

but it doesn't necessarily have to be the first element in the stream

#

like if the stream is processed parallel, the order may become mixed up

echo harness
#

but that doesnt matter

#

if theres only one element

#

am i right ?

crystal sonnet
#

Technically yes

#

But it could be faster

echo harness
#

ok ty

crystal sonnet
#

And can never be slower

echo harness
#
        return user.getOwnNodes().stream()
                .filter(Node::isTemporary)
                .filter(n -> "cmi.command.fly".equals(n.getPermission()))
                .map(Node::getExpiryUnixTime)
                .findAny()
                .map(e -> formatTime((int) (e - currentTime)))
                .orElse(null);
crystal sonnet
#

So if you don't need the first element that matches, but just one element that matches, it's the better use

echo harness
#

cant be better now right ?

crystal sonnet
#

Not really

echo harness
#

well its good enough

crystal sonnet
#

that#s as good as you get with streams

echo harness
#

@crystal sonnet can u get all players in group ? even offline ones with API ?

frank driftBOT
#

Hey Poggik! Please don't tag staff members.

echo harness
#

i have this list

#

but i made it with config

#

and u just set staff member

#

is there a way to make it with api ?

crystal sonnet
#

The wiki has examples on how to load offline players

echo harness
#

well

#

but u know his name

crystal sonnet
#

Not by heart

echo harness
#

i need to get all names from group

crystal sonnet
#

You can load all players (that's slow so only do it async. And cache the result) and check if they have the respective group.<group> node

echo harness
#

load all players with luckperms ?

crystal sonnet
#

Yes

echo harness
#

how do u make it in async ? u do async method or ?

crystal sonnet
#

The wiki has examples on how you can get all players known to LP and how to load the data of a single player

#

Don't run it on the main thread

echo harness
#

well i can do for loop cant i ?

crystal sonnet
#

Bukkit should have methods for that

echo harness
#

oohh

crystal sonnet
#

Streaming is better

echo harness
#

with scheduler ?

crystal sonnet
#

Probably

echo harness
#

theres async thing

crystal sonnet
#

What's so hard to understand that I don't know much about the Bukkit API?

echo harness
#

its ok i understand

crystal sonnet
#

There's a thing called google

echo harness
#

im googling already

crystal sonnet
#

good

echo harness
#
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@Override
public void run() {
// code goes here
}
));
#

that was easy

#

i knew it was in scheduler

crystal sonnet
#

With Java 8, you can even use lambdas

echo harness
#

oh whats that

#

never heard of that

crystal sonnet
#

Google 🌈

echo harness
#

googling already lol

#

i think i will stick to the scheduler

crystal sonnet
#

No no

#

You can pass a lambda expression in the method

echo harness
#

i cant understand lambdas lol

crystal sonnet
#

For example in .filter(Node::isTemporary) the Node::isTemporary is a special type of lambda expression

#

I forget what that is called

#

But where the method exprects a runnable, you can pass a method

echo harness
#

i cant really find getting all users in developer api guide

#

could you please redirect me ?

crystal sonnet
#

Then check the Javadocs

echo harness
#

oh its only in javadocs ?

crystal sonnet
#

I have done it before, but I don't have the source handy

echo harness
#

its ok

#

i dont really want to be spoon feeden

#

i need to learn something

crystal sonnet
#

WIthout trying to be rude, it doesn't sound like it

echo harness
#

yeah

#

i cant really understand the api

crystal sonnet
#

Minecraft isn't known to be beginner friendly

echo harness
#

well

#

i think i got it without even looking into javadocs

#

api.getUsers()

#

now i add .stream() right ,

#

?

crystal sonnet
#

Yes

echo harness
#

ok nice

crystal sonnet
#

load their data

echo harness
#

should i do some filtering ?

#

no right ?

crystal sonnet
#

and then your can work with them

echo harness
#

i want all users

crystal sonnet
#

like checking if they have the group permission you're looking for

echo harness
#

oh right

#

well

#

this is not effective way

#

because look

#

i have like 7 groups

#

and i cant do 7 streams

#

that would be slow af

crystal sonnet
#

Or checking all their group permission nodes

echo harness
#

how about storing all player names with group names ?

crystal sonnet
#

Then you need to turn into a map

echo harness
#

then just handling that hashmap

crystal sonnet
#

Something like Map<User, List<String>>

echo harness
#

yea

crystal sonnet
#

Or Group instead of String

echo harness
#

yes

#

how about storing their name instead ?

#

because i dont need anything else

#

just name

crystal sonnet
#

If you just need their name, then sure

echo harness
#

ok

#

theres no need to handle more luckperms users

crystal sonnet
#

And how to turn a stream into a map can be found online

echo harness
#

going to google it now

#

ehm

#

i think i got it

#
Map<String, String> fest = this.plugin.api.getUsers().stream().collect(Collectors.toMap(User::getName, User::getPrimaryGroup));
crystal sonnet
#

Almost

#

You still haven't loaded the players yet

echo harness
#

oh

crystal sonnet
#

And you don't need to worry about online players

#

If you try to load their data, nothing will happen

#

So if you can treat online players the same as offline players

echo harness
#

im thinking

#

should i load them like with userManager ?

crystal sonnet
#

The wiki tells you exactly how to do it

#

Can all be done with a stream

echo harness
#

lemme have a look

#

give me second

#

well i see UserManager#loadUser

#

which works on offline and online users

crystal sonnet
#

yup

echo harness
#

should i use that one ?

crystal sonnet
#

yes

echo harness
#

i think i got it

crystal sonnet
#

You still haven't checked the wiki,

echo harness
#

is there a way to do it on stream

#

on wiki ?

#

like the exact way ?