#development

1 messages · Page 76 of 1

merry knoll
#

so you just go

#

artifacts.getItem(key)

#

and not care

dense galleon
#

Are you talking about the ArtifactItem.build() method?

merry knoll
#

yes

#

i would also hand that away to the artifacts manager or w.e. class you name it

dense galleon
#

w.e.?

merry knoll
#

whatever*

dense galleon
#

Ah sorry haha

dense galleon
merry knoll
#

facade all that away to a nice api and you good i think

#

ArtifactsAPI.register(artifactobj)
ArtifactsAPI.getClone(key)

dense galleon
#

Okay so the objective is to do so that all my plugins interact with each other ONLY through classes found in my api package?

merry knoll
#

ye it also makes it easier on you as well

#

in case you need to change implementation in the future

dense galleon
#

How does that differ though if I have ArtifactsAPI.getItem() instead of Artifacts.getItem()?

merry knoll
#

anything that depends on artifacts then only need to know about

#

a) Artifact objects themselves

#

b) API to get and register

#

anything else is abstracted away

dense galleon
#

I get that it's all for "good practice"

#

But what are the actual advantages about that

#

Like yeah it's defo cleaner

merry knoll
#

for example, in the future minecraft or spigot changes

#

the way model data works

#

you do not need to change everything then in a case where its abstracted like this

#

or lets say

#

you need this code to work concurrently in the future

#

you just change how it works in the background

#

and your plugin1 plugin2

#

does not need to change

dense galleon
merry knoll
#

another big advantage thats not really prevelant in spigot is that you can unit test

#

way easier when you use interfaces

#

but unit testing in mc is effectively non existant

#

except mockbukkit

dense galleon
#

The api package I guess should have pretty much no data of its own then

#

Hence it is usually all interfaces

merry knoll
#

yes, its just a contract

#

that says hey i will give you x if you call y

dense galleon
#

Okay this has been very helpful can't lie

#

Though the hardest part of all this now is naming the API classes haha

#

ArtifactItemAPI doesn't seem like a good name

merry knoll
#

it isnt

#

artifact factory is though since thats lowkey what you are doing

dense galleon
#

what about the static isArtifact() method found in ArtifactItem, I don't feel like that fits in the factory class much

#

even just based on the name

#

I'd normally delegate a static method like that in a ArtifactUtil class or something

merry knoll
#

yeaah, its probably a util type deal

dense galleon
#

Then whenever I want some plugin to create a new artifact, I should:

  1. Create a new NamespacedKey static instance for that artifact
  2. Register it in my ArtifactRegistry class
hoary scarab
#

I listen to incoming packets via ChannelPipeline.addBefore("packet_handler", player.getUniqueId().toString(), getHandler())
Do I have to remove it when the player leaves?
And why does it error when I just use a string, "injector" for example?
yapperyapps lost connection: Internal Exception: java.lang.IllegalArgumentException: Invalid UUID string: injector

minor summit
#

the pipeline is basically discarded when the player is disconnected so you don't need to remove it

#

as for the other thing, it just sounds like someone is trying to parse the string as a uuid? can't really say anything else without the stack trace

hoary scarab
#

the pipeline is basically discarded when the player is disconnected so you don't need to remove it
Thought so just wanted to make sure.

As for the stacktrace. There is none listed on that actual error but the errors above it are from via version. I'm checking now to see if It occurs when the client and server version match. Also removing via version.

#

Yeap occurs without viaversion and when server/client version match.

No stack trace just lost connection with that error.

#

Even if I delay the method it will let me in the server but then kick me with that error when the method is ran.

hoary scarab
#

Hmmm looks like I can't even put a null handler.
Yet if I loop through the names in the pipeline DefaultChannelPipeline$TailContext#0 returns null...

shell moon
#

using canvas (html element), how to draw an image (changed with a solid color) something like a shadow (same shape)

worn jasper
#

I think I know the answer to this but would it be wise to do http requests on the main thread if the response times are less than 100ms? It blocking it would be intended in a way. Since it could get hacky.

XY Problem: I am wondering the best way to cancel a message the player sent depending on what the http request says.

river solstice
#

no it's not wise

dusty frost
#

Doesn't Paper have an AsyncPlayerChatEvent for exactly this reason?

worn jasper
river solstice
#

im pretty sure the event itself is async (or not) (event.isAsynchronous) , your listener is not automatically async

#

though for figuring it out I think you can use Bukkit.isPrimaryThread() in your listener

merry knoll
sterile hinge
#

yeah chat thread is separate

merry knoll
worn jasper
dusky harness
river solstice
#

say if you get 5 consecutive messages in a span of 10ms, then what

worn jasper
#

What I could in theory do is canceling and triggering afterwards again

river solstice
#

well that's probably your only hope

worn jasper
#

Hell, the worse pain of it all is having to support 1.8 😭

#

I now understand @rugged bane...

river solstice
#

cancel all the messages from the event,
store the message in a stack,
create a scheduler that pops the message and processes it,
pass -> send
fail -> continue

#

¯_(ツ)_/¯

worn jasper
#

that could work, but sending would have to be with Player#chat method since I want to support chat plugins too

dusky harness
#

I wouldn't use a scheduler
Use like an executorservice with a 4 thread pool or smth

worn jasper
#

I have never used that...

dusky harness
#

So that you can avoid the delay of having to run it on ticks

worn jasper
#

what even would be the benefits of not using a scheduler

rugged bane
worn jasper
dusky harness
#

🥲

worn jasper
#

since Analyse does a bunch of http requests

#

although in theory, my project gonna do WAY more lmao

dusky harness
#

If the http server is across the world or smth it'll take over 100ms though

rugged bane
dusky harness
#

In Charlie's case there's no canceling chat tho right?

worn jasper
worn jasper
merry knoll
worn jasper
# dusky harness Oh

The standard option is where it only requests every so often and sends a bulk of messages instead of a single one which is what real-time does.
In this case, chat is not canceled.

worn jasper
merry knoll
#

i didnt read the rest of the convo so if it got solved already just ignore me

dusky harness
#

And make sure to not make it ca your own event

#

And have that on loop

#

Infinitely

worn jasper
#

I would listen to the event, and only let through events that are async

#

since Player#chat is not async, it's fine

worn jasper
#

it wouldn't trigger a loop

dusky harness
#

I thought async event was always async but ig not... Noted for future coding lol

worn jasper
# dusky harness I thought async event was always async but ig not... Noted for future coding lol
The constructor provides a boolean to indicate if the event was fired synchronously or asynchronously. When asynchronous, this event can be called from any thread, sans the main thread, and has limited access to the API.

If a player is the direct cause of this event by an incoming packet, this event will be asynchronous. If a plugin triggers this event by compelling a player to chat, this event will be synchronous.```
worn jasper
merry knoll
#

you can probably call it from another thread to make it fire async

#

would need to see its implementation though

worn jasper
#

Yeah but I don't want it to be async, cause that would cause a looping xD

#

it still triggers AsyncPlayerChatEvent, async or not.

dusky harness
#

Tbf u can have like a boolean to prevent it

#

True on the line before player#hat, then false after

#

Thanks autocorrect

worn jasper
#

difference is that chat plugins just listen to it and don't care about async or sync, and I will filter it to only listen to async using isAsynchronous()

#

so chat plugins would continue to work.

#

We will see how it goes, I am planning things out, making a prototype too first.
Then once my schedule clears out, I will start developing the api, testing it, website, etc.

#

Gonna have to check how I will do it, gonna take some inspiration off analyse 👀

rugged bane
#

Helps a lot when you can dig through and see how its done

#

Our http stuff is both lightweight and very performant

worn jasper
#

I have some ideas of making it register a server which them you can apply a group/platform, and the group is what the plan is for.

#

You will be able to buy different plans for each group/platform

worn jasper
rugged bane
rugged bane
worn jasper
rugged bane
worn jasper
rugged bane
hoary scarab
#

I don't want to use the UUID incase other plugins do the same. Just can't figure out why this error is occurring.

worn jasper
#

Never worked with pipelines or whatever so... no idea

grand island
hoary scarab
#

Its weird cause often I see player name being used. And all of the names in the pipeline currently aren't UUIDs

hoary scarab
minor summit
#

what does your channel handler do? i guess it would be good to see it

#

because that is certainly not a behaviour that i can reproduce in a clean environment

hoary scarab
#

Issue isn't the handler though... I can do pipeline.addBefore("packet_handler", "injector", new ChannelDuplexHandler()) and it would still kick the player with that error.

lusty smelt
#

Cannot execute command 'gm' in plugin Essentials v2.21.0-dev+67-622c814 - plugin is disabled. how is this possible=

#

Can somebody help me with it?

shell moon
#

its not enabled

lusty smelt
#

How to enabled it sir?

shell moon
#

install it correctly

#

wait

lusty smelt
#

I didnt know where to ask im sorry.

shell moon
lusty smelt
#

Thanks 🙂

hoary scarab
minor summit
#

UUID.fromString(context.name())

uhhhh

#

yeah that isn't going to work unless the handler name is a uuid string xD

hoary scarab
#

sigh

#

So how are other names added then?

minor summit
#

just adding a name?

#

pipeline.addLast("foo", new MyHandler())?

#

they just don't take that string and try to get it as a uuid

hoary scarab
#

Could but to listen to packets it has to be before packet_handler.

minor summit
#

sure?

#

the issue is that you are using that handler name as a uuid

#

not how or where you add the handler

hoary scarab
#

I might be misreading. What do you mean?

minor summit
#

that very first line is what is throwing the exception, context.name() will give you the name of the current handler basically, so if you do pipeline.addWhatever("my_handler", new MyChannelHandler()), then context.name() will give you "my_handler" back

#

but you are trying to read it as a UUID, which "injector" is not

hoary scarab
#

Son of a BITCH! 🤦

minor summit
#

lol

hoary scarab
#

Spent over 2 days on that.

#

Works. Thanks.
Now I gotta figure out why the meta data is apprently invalid. (According to via version)

atomic trail
#

Does anyone have an idea how an implemented dependency is missing methods at runtime?

atomic trail
#

I have the shadow plugin in the build.gradle.kts and I use implementation that should work right?

worn jasper
#

you have to use shadowJar to build it AND you have to relocate the dependency(ies)

atomic trail
#

How does the relocating actually work? I've used it a few times but only when the original devs wrote a note that it should be relocated lol

#

So I relocate org.spongepowered.configurate-yaml if the method is in that module?

river solstice
#

well instead of your dependency being in your jar in
the.dependency.package
you can tell it to relocate to
your.package.the.dependency.package

dense drift
#

You relocate the package, which can be different from the name of the dependency

atomic trail
#

I publish it as a local maven repository

worn jasper
atomic trail
#

It's a fork

#

That added it

worn jasper
#

ah

#

actually send me that

atomic trail
#

Lmao

#

It's failing a few tests that doesn't really matter, but the assemble task should be used and then it compiles

#

This works :)) relocate("org.spongepowered.configurate.yaml", "com.valdemarf.weaponabilities.yaml")

river solstice
#

Relocating is often required when one of the dependencies is susceptible to breaking changes in versions or to classpath pollution in a downstream project.

Basically, you dont want to have conflicts from different versions of the library in the same classpath.

atomic trail
#

So the dependency module got overriden? Which it doesn't now that I relocated it?

#

Ahhh it might be because paper jar already has a version of configurate at runtime, which it uses instead

dusky harness
#

btw just wanna mention that spigot, starting from 1.17, allows for downloading of maven central dependencies during server runtime

#

haven't really read the convo so I don't know if it applies here but

#

:)

worn jasper
#

and allow for non-maven repos too

minor summit
#

non central

#

all maven repos are maven repos lol

worn jasper
spring crescent
#

Does anyone have any advice on serializing player inventories player end chests and container contents? I need, specifically, whatever is in them at any given time. I need to be able to reliably serialize this data, save it to a database, and then later deserialize it.

#

It also needs to be 100% NBT friendly and retain all item data, wether custom or vanilla.

merry knoll
fiery creek
#

How can i make a kits menu in a kits menu? Because i have a gui if you do /kits. But i want to make gui for ranked, and members and tools. But it must be make a category

spring crescent
#

Does the plugin.yml automatically handle permission nodes if I have the permissions defined there, or should I handle it in code with the Command executors, or both?

dusky harness
spring crescent
#

Well that will simplify the crap out of some logic i have going on then xD

lusty smelt
#

Can somebody help me with CombatLogX
I have a problem when players are in Combat they still can use commands like /spawn etc.

dusky harness
#

but asking in their discord server is probably best

terse osprey
#

Nobody respond to him for a few days and see if we can get $300+ out of him pepelaugh

real cedar
#

Hello, I am currently trying to create a placeholder for my money variable, so the users can use the eco system on other plugins like RealScoreboard or PlayerShops. How exactly can I do this now?

The main problem right now is to import the required package.
(import me.clip.placeholderapi.expansion.PlaceholderExpansion;)

warm steppe
#

how can i see if the component contains some string?
for exampl, in paper's AsyncChatEvent event
i guess that this is the only way? PlainTextComponentSerializer.plainText().serialize(textComponent);
basically i want to check if the chat message contains some word and replace it if it does

sterile hinge
#

it kinda depends on how you want to deal with text that is split up into multiple parts by formatting

#

but plain text should work

warm steppe
#

all i want is to keep the origlinal formatting

#

or maybe some hover events etc that it could have

sterile hinge
#

so you want to replace something? Or only check if it contains something?

warm steppe
#

both? ig

dense drift
#

Custom minimessage instance without color tags maybe? But if you want to replace, it is a bit harder ig

sterile hinge
#

adventure has some methods to replace text afaik

warm steppe
#

TextReplacementConfig

#

will post updates on how it goes

pulsar ferry
#

Please do not spam every channel, and wait for people to reply to your thread
If you want to put a bounty on it then put it in #1202497504655188028

dense galleon
#

If I try doing event.message(component), and this component has no contents but only children (as the contents were added with .append()), will the message show up as empty?

#

Cause that's what seems to happen

dusky harness
dense galleon
#

Nvm it was another problem sorry

dusky harness
#

alr

dense galleon
#

Another question though: how does TextColor.lerp() work?

dusky harness
#

uhh should prob ask kyori discord

dense galleon
#

As

textComponent.append(Component.text(line).color(TextColor.lerp(lerpFactor, startColor, endColor)))``` Does not do anything it seems
warm steppe
#

is it possible to get the item displayname without [ and ]

dense drift
#

I think it is name()

warm steppe
#

i tried to replace them but they wont go away xd

dense drift
#

ah nvm, name() is from triumph-gui xD

worn jasper
warm steppe
#

yes, but i can't seem to be able to remove those brackets

worn jasper
#

| is not [] though?

#

or wait

#

that's regex

#

wait

dense drift
#

I think you can simply append the ItemStack and it will display the right name

worn jasper
#

idk what I am saying lmao

dense drift
#

The [ ] come from translation iirc

worn jasper
#

worse case scenario you can serialize it, do what you want and deserialize it again

#

that's what I do in Runway xD

dense drift
warm steppe
#

needs a component

dense drift
#

duh, you get a component with Component.translatable(itemStack) or smth

warm steppe
#

heyyy

#

that worked

#

ah, but it seems to ignore the display name, it only shows item name

warm steppe
#

hmm

worn jasper
#

Totally different question, but if a premium user joins an offline minecraft server, is their uuid the same or will it also change?

dense drift
#

Last time I've checked, the UUID was created from the bytes of the string "OfflinePlayer:" + name

sterile hinge
#

yeah the UUID is always generated like that if the server is in offline mode

worn jasper
#

oof then rip the way I was thinking on doing it xD

#

suppose the only way to know if an user is a premium user is with packets then

#

dies

sterile hinge
#

use online-mode=true and you always know

dense drift
#

check what plugins like jpremium do shrug if the src is public xD

worn jasper
#

it's not xd

sterile hinge
#

fastlogin is open source

warm steppe
#

solved by using String#substring

#

aaand LegacyComponentSerializer.legacyAmpersand().serialize(itemStack.displayName());

spring crescent
#

So I just realized I'm compiling an absolutely MASSIVE plugin. Talking 80+ Mb when it should be less than 2. I recently added a dependency which caused it to skyrocket. Can someone explain to me what I'm doing wrong? I think I'm using the shade version because I have my dev environment setup to push that jar file to my local server instance for testing. I definitely need that, as it makes debugging much much simpler as I can hot-swap classes as I'm working. What is the correct way to handle this? Here is my pom.xml https://paste.helpch.at/kujotufona.xml

sterile hinge
dense drift
worn jasper
#

wait kangarko?

spring crescent
#

yeh it's a library to help create better GUI's

#

pagination, etc..

worn jasper
dense drift
#

it does more than that

worn jasper
#

hell their wiki is legit "go buy my course to get documentation" lmao

spring crescent
dense drift
#

open your plugin's jar and see what's inside as Ywell said

spring crescent
#

There's a crap ton inside of it xD

worn jasper
#

at these times is when you realize, minimize() isn't as bad as you think xD

#

am I stupid or... in maven when you don't include the provided scope, it's the same as implementing it right? (gradle)

spring crescent
#

There appear to be 3 main folders, io moss and a few others being 2-5mb each. As part of adding this dependency, I had to add a repository, jitpack could that also be part of the problem?

worn jasper
spring crescent
worn jasper
#

I swear if this is true, it's gonna be the most typical kangarko moment ever

#

lmao

#

Idk how people buy his course

spring crescent
#

I must not be part of the inside joke lol. What is this "Kangarko" moment? Does he frequently do things that are just "Wrong" should I abandon this dependency and use something else for GUI's? xD

worn jasper
#

and on top of that, bruv can't code

spring crescent
#

Okay, so I'm going to listen to said advice, and go idk, Triumph somewhere else? lmao

worn jasper
#

xD

#

no but fr, triumph-gui is just good.

#

Also, answering your last question too, just the fact that the guy creates a whole library (badly done), that claims to be the best and open sourced, and then legit puts the documentation behind his course that no one should buy lol

#

says a lot about that guy

#

there's a reason why he was banned from spigotmc too

#

xd

spring crescent
#

Oh my god. I almost stepped on a mine.. you guys have saved me

worn jasper
#

yeah...

#

it's also funny, he did a video on his youtube channel on why he was banned and basically incriminated himself

#

that video is now deleted.

spring crescent
#

Lol added a new dependency Triumphantly, 1mb shaded jar xD

worn jasper
spring crescent
#

Play on words -.-

#

I added the GUI library you recommended. 10/10 quality stuff

worn jasper
spring crescent
#

Apparently not as slow as a kangaroo (🤞 Maybe he catches this one first try. I have faith in him.)

worn jasper
#

xd 😂

river solstice
#

well

#

at least we stepped away from using chatcontrol red

#

just had too many issues with it

river solstice
#

and, well, couldn't fix them myself, since its.. a paid resource and closed-source

#

chatchat for the win (ish)

#

missing some things we need but I added them myself

grand island
dusky harness
#

bc minimessage was only on like 1.18+ or smth

worn jasper
atomic trail
spring crescent
atomic trail
#

When creating the keys

#

I had it as enum before but got told it’s bad because it’s not really extendable, and with a key I can more easily setup an api

#

I guess I could keep the enum there for default races? Or would that be bad?

dense drift
#

what's so bad about creating the keys?

worn jasper
atomic trail
#

Well just to add one it would be all this

        weaponAbilities.getRaceRegistry().register(
                new NamespacedKey(WeaponAbilities.getRaceKey().getNamespace(), WeaponAbilities.getRaceKey().getKey() + "-demon"),
                (DemonRace) getConfig("demon-race").get()
        );
#

And there's a lot of them

dense drift
#

can't each race provide its key dynamicly?

atomic trail
#

Wdym? As is store the key as a field inside the race class?

dense drift
#

For example if DemonRace has any method that returns demon, like getName() you can simply make a getKey() method that returns
new NamespacedKey(WeaponAbilities.getRaceKey().getNamespace(), WeaponAbilities.getRaceKey().getKey() + '-' + getName())

atomic trail
#

Ahhhh yeah true

#

This is the best I could come up with

        DemonRace demonRace = (DemonRace) addConfig(DemonRace.class, "demon-race", "races/demon.yml");
        weaponAbilities.getRaceRegistry().register(demonRace.getKey(), demonRace);
dense drift
#

you can remove the key parameter from the register method or overload it (the method)

atomic trail
dense drift
#

and I don't think the cast to DemonRace is needed shrug alternatively you can make addConfig return a generic

atomic trail
#

It's because I use Configurate ObjectMapper, and I mark all the classes to map with LocaleReference

    private LocaleReference addConfig(Class<? extends LocaleReference> reference, String name, String resourcePath) {
        ConfigurationWrapper wrapper = new ConfigurationWrapper(reference, classLoader, dataFolder, resourcePath);
        configs.put(name, wrapper);
        return wrapper.get();
    }
#

Couldn't figure out how to make it more generic

dense drift
#

try T addConfig(Class<T extends LocalReference>, ...) and return (T) wrapper.get();

atomic trail
dense drift
#

oh sorry, you need to put the extends before
public <T extends LocalReference> T addConfig(Class<T> reference...)

atomic trail
#

Ah yeah that works! Should I just supress the unchecked cast?

dense drift
#

yeah

#

I usually just ignore it kek

atomic trail
#

I prefer having no warnings so I just use @SuppressWarnings("unchecked")

dense drift
#

but you can do ... reference.isInstance(result of get()) and return null on an else branch

atomic trail
#

Ahhh yeah smart, what's the difference between that and just instanceof?

#

This looks pretty good to me

    @SuppressWarnings("unchecked")
    private <T extends LocaleReference> T addConfig(Class<T> reference, String name, String resourcePath) {
        ConfigurationWrapper wrapper = new ConfigurationWrapper(reference, classLoader, dataFolder, resourcePath);
        configs.put(name, wrapper);
        if(!reference.isInstance(wrapper.get())) {
            throw new RuntimeException("Invalid configuration class reference (must implement LocaleReference)");
        }
        return (T) wrapper.get();
    }
dense drift
#

I guess they are the same thing, but you can't use it here because you have a Class<> not the actual Class, idk how to say it

atomic trail
#

Ah yeah makes sense

#

Thank you! This really saved the code imo lol

dense drift
#

and you can not do wrapper.get() instanceof T

#

I think if you put the result of get() in a variable, which you probably should, the ide won't complain about unchecked cast

atomic trail
#

Same thing

#

But the warning doesn't really matter imo

dense drift
#

no, not like that

#

Object result = wrapper.get();
and then do the isInstance check and return (T) result

#

The ide can't know that the second time you call get() the same object will be returned, so if you put it in a variable and check if is an instance of T then is safe to cast it

atomic trail
#

Ohhhh yeah I understand what you mean now

warm steppe
#

just suppress that warning

#

#ezfix

atomic trail
#

Nvm is this what you meant?

graceful hedge
#

if u wna get rid of it

#

reference.cast()

#

:}

atomic trail
#

Or checked ig?

river solstice
#

check the sauce

dense galleon
#

Does anyone here know what TextColor.lerp() does/how it works?

river solstice
#

well, lerp is known as linear interpolation, so.. linearly interpolates between colors?

#

returns a color blended between color a, at t=0.0, and color b, at t=1.0, where t is the interpolation value

sterile hinge
#

in the case of RGB, it's linear interpolation on each component

lilac portal
sterile hinge
#

you have a random import there

spring crescent
#

Does anyone have experience using Inventory-Framework aka IF? I am trying to get the darned thing to work as a paginated inventory, but it seems that it auto-adds NBT data, thus making items added, incompatible with stacking. Also it lacks any form of peristence.

worn jasper
spring crescent
#

Same problem

#

There was no triumph to be had

worn jasper
#

you can avoid that problem lmao

#

if you do it properly

#

did you even care to ask in the discord server if it was possible?

#

instead of just running away maybe try and ask?

#

lol

spring crescent
#

I did ask, "Ghost town"

worn jasper
#

people, including matt, have a life

#

you asked yesterday lmao

#

well actually, today, at 1am for me

#

so less than 24h

#

if you had patience and waited a bit then yeah.

broken elbow
spring crescent
#

The issue isn't peristing it in the DB. I already have a method to store and retrieve it, but upon retrival, and adding to either TriumphGUI or IF, results in additional NBT data being added to the items, making them unstackable with any vanilla items. Or, paging to a new page, after removing items from the first page, and then returning dupes the items because it isn't persisted there.

worn jasper
#

Besides, you provided a code of a method that returns an itembuilder for the currentpage item

#

how in the world are we supposed to use that to solve 2 completely unrelated issues lmao

#

we are not akinators, we don't read minds, nor are we hackers that hack their way to see your screen and somehow figure out what code you are using.

#

If you want fast support, ask for it properly. Otherwise, you will wait, and wait, and wait.

broken elbow
worn jasper
spring crescent
#

I did look around. I'm not an idiot. The code takes an item stack and turns it into a GuiItem

worn jasper
#

.....

#

Suppose I will have to open Intellij then

spring crescent
#

I took the time to find a solution before requesting support.

worn jasper
#

what's also this

broken elbow
#

I think you guys are just misunderstanding each other

#

lol

worn jasper
#

nha I understood him

dusky harness
#

those items have additional nbt that triumph gui puts on for identification

#

which I think is the issue

worn jasper
#

hmhm

#

any gui library/frameworks does that

#

or well, most do

#

it's the best and most secure way of doing it

#

but you still could make a copy of the item clicked, without that nbt and give it to the player

#

just a simple example:

ItemStack itemToGive = ItemBuilder.from(Material.PAPER).build();
gui.addItem(ItemBuilder.from(itemToGive).asGuiItem(e -> {
    p.getInventory().addItem(itemToGive);
    // remove item from the paginated gui
    // refresh gui
}));
broken elbow
#

Or

worn jasper
#

you can even remove specific guiItems with #removeItem()

broken elbow
#

I'm pretty sure you can change the item stack on the player cursor

worn jasper
#

it's just an example of a way of doing it

#

several other ways of doing it.

broken elbow
#

use that to make it work more like usual inventories

worn jasper
#

several ways of going about this lol

#

but moving it around with paginated guis like a normal inventory won't work

spring crescent
#

Here's the problem I need to solve.

As a user, who won hardcore season 1, I want to collect my rewards from the season.
As a season, I want to track all containers contents, to give rewards to winners of the season.

Problem:

  • I need a reliable way to give up to, 100 chests of items for example, to one player who has a limited inventory size.
  • I am open to suggestion on this. Maybe my current solution is not the right way to go about this.

**Potential Solution: **(The one I'm trying to debug right now

  • Create a paginated GUI that will have all the combined ItemStack[] from all containers, pulled from the DB.
  • The items MUST be stackable with vanilla items
  • The page must act as a normal inventory, with exception of navigation buttons.
  • I need a reliable way to persist data (Locally) between pages.
    • I considered updating the DB with every Click event but that seems uneccessarily bad.
worn jasper
#

since the way paginated guis work in triumph-gui, they populate the gui one by one

worn jasper
#

stated above

#

at least with triumph-gui

#

pretty sure IF works in the same way

broken elbow
#

with triumph-gui and IF, this is impossible or very hard to do

#

yeah

#

they were not really made with this in mind

worn jasper
#

not at all

#

I don't even see WHY that's needed, why would they want to move them around, they are there to be collected, nothing else

#

I would assume

spring crescent
#

Yes collected only, but that part is easy if I can just reliably get the stacks in a familiar way.

dusky harness
#

so the gui items specifically don't have to be stackable

#

you just click it, and then the code gives the real item, not the gui item

#

if that makes sense

worn jasper
dusky harness
#

oh

worn jasper
#

can be done in several ways ofc, just speedran that one

#

xD

#

in theory, this will even work with stacked items

#

since when you add an item, if they are the same itemstacks, they will automatically stack

#

so yeah

spring crescent
#

Oh wait, I can create a set of Material and just have an icon for what is redeemable, and upon redemption, just change it to some barrier or something to show that it was redeemed.

#

I am following what you are suggesting rn.

worn jasper
#

or just totally remove it from the list

#

but yes

#

that could also work

spring crescent
#

Okay, so what do I do in the event that say "Dirt" is 10000 and it would overflow their inventory upon click. How is that edge case resolved?

dusky harness
#

when doing addItem, it returns the items that couldn't be added, so you can keep those in the gui or drop on the ground

spring crescent
#

oooh didn't know that.

#

Okay, I have a solution to go forward. Thanks guys ❤️

river solstice
#

How would one go about implement a "module" system?
I have a main plugin, which would load "modules" (commands, listeners) from the "module", which would be placed inside "/plugins/mymainplugindir/modules"

#

I don't want the "module" to be treated as a plugin itself, it would just have an interface that would return commands and listeners that the main plugin would register

dusty frost
#

and probably do a class java moment and have a standard resource file like a plugin.yml that defines the main class, then get that class

#

have it implement an interface with like 2 functions to return command and listener classes, then bam

river solstice
#

does this make any sense?

#

how would I go about making the main plugin registering the listener, and not the the module?

#

or do I just call the plugin manager of the main plugin from the module to register it

merry knoll
#

have a onLoad type method on the module

#

and make all your modules implement an interface

river solstice
#

yeah I have that, just onEnable.

#

for some reason I get java.lang.ClassNotFoundException: me.m0dii.testmodule.TestModule

#

though it does see the jar file

#

and, well, the path is correct

merry knoll
#

are you loading the class

river solstice
merry knoll
river solstice
#

I'm not sure if that's a directory issue or what

sterile hinge
river solstice
#

nah Id rather do it in the worst way possible and suffer

river solstice
#

is there a way to register commands without them being in plugin.yml?

dense drift
#

Ye ofc, I think you have to get the CommandMap from the Server or w/e

river solstice
#

very cool

hoary scarab
#
try {
    Field f = Bukkit.getServer().getClass().getDeclaredField("commandMap");
    f.setAccessible(true);

    CommandMap commandMap = (CommandMap) f.get(Bukkit.getServer());
    commandMap.register("<command>", <CommandExecutor>);
} catch (Exception e) {
    e.printStackTrace();
}
river solstice
#

reflection bleh

dusty frost
#

If you're using Paper, they expose a getter

#

Server#getCommandmap()

river solstice
#

paper all the way

#
    public static void registerCommand(String commandName,
                                       CommandExecutor executor,
                                       TabCompleter tabCompleter) {
        PluginCommand cmd = Pagrindai.getInstance().getCommand(commandName);

        if (cmd != null) {
            cmd.setExecutor(executor);
            cmd.setTabCompleter(tabCompleter);
            return;
        }

        PluginCommand command = getCommand(commandName, Pagrindai.getInstance());

        try {
            Bukkit.getServer().getCommandMap().register(Pagrindai.getInstance().getDescription().getName(), command);
        } catch (Exception e) {
            Messenger.warn("Failed to register command: " + commandName);
            return;
        }

        if (command == null) {
            Messenger.warn("Failed to register command: " + commandName);
            return;
        }

        command.setExecutor(executor);
        command.setTabCompleter(tabCompleter);
    }

    private static PluginCommand getCommand(String name, Plugin plugin) {
        PluginCommand command = null;
        try {
            Constructor<PluginCommand> c = PluginCommand.class.getDeclaredConstructor(String.class, Plugin.class);
            c.setAccessible(true);
            command = c.newInstance(name, plugin);
        } catch (SecurityException | IllegalArgumentException | IllegalAccessException | InstantiationException |
                 InvocationTargetException | NoSuchMethodException e) {
            e.printStackTrace();
        }
        return command;
    }
#

the mega catch 😔 🫰

dusty frost
#

what's with the constructring a PluginCommand?

#

you can just register a normal Command class

river solstice
#

I can say that Im not sure, that's the method of creating one I found lol

#

and.. it works

#

good enough

hoary scarab
#

reflection bleh
😕

dusty frost
#

yeah wtf lol

river solstice
#

lmao

#

I dont know

#

lemme just figure this sh out first

hoary scarab
dusty frost
#

actually you know what, while i'm here

#

you guys have like a nice library or anything to construct blocks with nice NBT stuff?

river solstice
#

havent embarked on NBT journey yet, still in my future plans

dusty frost
#

I was working on this minigame that randomly shuffles a dozen books between bookshelves, and I literally could not figure out how to make a bookshelf and put books in it and put it in the world

#

like it was so annoying, i don't know why they don't just like have a nice builder or something for it

hoary scarab
#

Don't know of any. Generally people stay away from NBT data.

dusty frost
#

yeah well I need to make blocks and I don't know how else to do it 😔

hoary scarab
#

🤷 Suggestions?

sterile hinge
#

Not wrapping inefficient code with more inefficient code

hoary scarab
#

Example?

sterile hinge
#

example for what?

hoary scarab
#

Of how I can make it better/efficient.

river solstice
sterile hinge
#

I don't see any benefit added by that library, why does it need to exist in first place?

hoary scarab
#

Convenience and usage example

dense drift
dusty frost
#

like the way I tried to do it involved a ton of like getting BlockData, casting it, setting it, assigning it to a block, etc. and it all just didn't work

#

surely somebody must have made a thing where you can just like make a new block object and set it

river solstice
#

also, once the command is registered in the commandmap, it autocompletes just fine (the command exists), how do I unregister it?

#

I don't want it to be visible anymore

#

command.unregister(Bukkit.getServer().getCommandMap()) doesn't seem to do the trick

sterile hinge
hoary scarab
dusty frost
river solstice
#

stringy

dusty frost
#

yeah like if I could do the string that would be cool

hoary scarab
#

CraftBlockData.fromData(<BlockState>).getAsString()

dusty frost
#

how do I make a BlockState?

hoary scarab
#

Yeah I'm at a loss there lol. Just example from my schematic code.

dusty frost
#

yeah like that's what I'm saying lol

#

why is there not just a nice way to create a block with the right data then just set it in the world

hoary scarab
#

But what you could do is make the bookshelf and just use that to get the string and modify the string.

dusty frost
#

😫

hoary scarab
#

One sec

dusty frost
#

i just wanna go like new ChiseledBookshelf(ItemStack[] books).setInWorld(x, y, z)

river solstice
#

hol up lemme just add that to the api

hoary scarab
#

^^^ lol

dusty frost
#

like for reals man

#

why is this shit so ass

#

who thought that programatically editing worlds in a game literally all about building could be this hard

dense drift
hoary scarab
#
World minecraftWorld = (World) ((CraftWorld) block.getWorld()).getHandle();
IBlockData data = minecraftWorld.a_(new BlockPosition(block.getX(), block.getY(), block.getZ()));
player.sendMessage(CraftBlockData.fromData(data).getAsString());
#

new CraftChiseledBookShelf().createBlockState()?

#

Best I could find is java CraftChiseledBookShelf craftShelf = (CraftChiseledBookShelf) CraftChiseledBookShelf.newData(Material.CHISELED_BOOKSHELF, null); craftShelf.setSlotOccupied(0, true); and then just set the block state normally but use craftShelf.

dusty frost
#

I mean I don't wnat to just set it to occupied

#

I want to actually put books in it lol

hoary scarab
#

I figured. Yeah no one liners or short code for that as far as I can tell. Could make your own lib lol

dense drift
minor summit
#

no

#

that's just the block state (what bukkit calls BlockData), e.g. minecraft:redstone_wire[north=true,power=13] etc

#

there is no one-liner you can use, you need to:

  1. set the block material to chiseled_bookshelf
  2. get the blockstate and cast to chiseledbookshelf
  3. get the inventory and set the contents
  4. update the blockstate
dense drift
#

Sad

river solstice
#

so I'm using boosted-yaml and am facing an issue regarding the configuration.
since my modules are loaded by my main plugin, getClass().getResourceAsStream() gives me the resources of the main plugin, not of the module.

any ideas?

#
        File dataDirectory = new File(Pagrindai.getInstance().getDataFolder(), "modules/config");
        try {
            config = YamlDocument.create(new File(dataDirectory, "config.yml"),
                    Objects.requireNonNull(getClass().getResourceAsStream("/config.yml")),
                    GeneralSettings.DEFAULT,
                    LoaderSettings.builder().setAutoUpdate(true).build(),
                    DumperSettings.DEFAULT,
                    UpdaterSettings.builder().setVersioning(new BasicVersioning("file-version"))
                            .setOptionSorting(UpdaterSettings.OptionSorting.SORT_BY_DEFAULTS).build());

            config.update();
            config.save();
        } catch (IOException e) {
            e.printStackTrace();
        }
dense drift
#

accessing resources is always a trial and error process for me kek try to put the file in a folder that has the name of the module and access it by the full path

river solstice
#

huh

dense drift
#

example-module.jar/example-module/config.yml > getResourceAsStream("example-module/config.yml")

river solstice
#

um

#

it's uh, a bit different

#

I have a main plugin, which loads "modules" via classloader.
The main plugin has dir /plugins/mycoolplugin/ and has it's own config file /plugins/mycoolplugin/config.yml, that is in the jar resources dir.
The modules reside in /plugins/mycoolplugin/modules and have a ``/plugins/mycoolplugin/modules/directory`, where the config files will be stored.

river solstice
#

not sure if that explained it

dense drift
#

My guess is it cant distinguish plugin.jar/config.yml from module.jar/config.yml so you need to put the module's config on a different path

minor summit
#

a classloader will look up in the parent classloader first

#

personally I just suggest putting the resource alongside your classes (basically, under the package/namespace)

#

e.g. deez.nuts.AreBig class getClass().getResource("config.yml")
deez/nuts/config.yml

river solstice
#

alright, thanks, I'll try it out

#

also

#

I ran into another issue. While loading the "module" seems fine, some of the classes are not loaded and I get java.lang.NoClassDefFoundError.
Does the class loader only load classes that are directly used in the class that is considered the "main" module class?

minor summit
#

huh

river solstice
#

i dont know

#

my brain melted from lack of sleep

#

tldr some of the classes work, ex. the command I pass it to the main plugin to register it, it outputs a response, but theres an argument in that command, say /cmd blah, which calls an utility class

#

and then I get no class def whatever

#

tldrtldr im kinda not sure what im doing and just trying to figure it out while messing around

dense galleon
#

I'm making a UML diagram for the plugins needed on my servers (Which I have written) and is it normal for it to almost become a web of dependencies haha

#

I mean it is relatively well organized

#

This is it for now, 6 minor plugins which all depend on my core plugin, two of which depend on ProtocolLib.
The core plugin depends on that extra library, same as the velocity plugin

#

(The solid line I am using to indicate that the dependency is being shaded in)

errant cosmos
river solstice
worn jasper
#

not at all xD

#

that's more of a diagram/schema

#

but def. not UML

dense galleon
worn jasper
#

still not the actual uml

river solstice
#

I suppose it's a very, uh, idk, undefined? UML diagram, personally I wouldn't call it UML, just a diagram.

#

I had several classes that required UML diagrams, and it was pain

sterile hinge
#

I'd never say something isn't UML because there's a wide range of different things in UML, and no sane person knows all of them

river solstice
#

it's either we call every diagram UML or some diagrams are just diagrams and not exactly UML

worn jasper
#

well it's def. not the standard uml used in java and the uml you learn at school/uni

worn jasper
#

UMLs usually display fields, methods and class name.

sterile hinge
#

it's much more than just class diagrams

river solstice
#

found a few diagrams from my bachelors degree project lol

#

Use-case, ER, deployment (package?), activity, sequence

dense galleon
#

Yeah I think mine is just a UML diagram in a broad sense

#

But either way, is it normal for a server network to have a web of dependencies like that?

spiral prairie
#

that isnt a web of dependencies

dense galleon
#

Is it not?

spiral prairie
#

Man you haven't seen a web of dependencies

#

I have seen and almost drawn diagrams where you couldn't read the names of the relations and entities because of the lines connecting them

dense galleon
#

Haha yeah fairs

#

Is protocollib available for 1.20.4?

worn jasper
#

but packetevents better

dusty frost
#

if only the plugins I use depended on PacketEvents and not ProtocolLib lmao

dense galleon
#

Okay the issue is that with PacketEvents I can't send events

minor summit
#

lol

robust flower
# worn jasper but packetevents better

I am curious about this, would you mind to elaborate a bit on this topic, I never heard of Packet Events, if you like it, could you please highlight some of the main features you like about it?

worn jasper
spiral prairie
#

Basically you don't need to look at wiki.vg and make the code for the packets for each version from that

#

It also has lots of NMS utils

spring crescent
#

@worn jasper btw your suggestion on the button vs storage solution works 💋

#

I was able to GREATLY improve the quality of my code-base and now it just "Works" which is awesome.

worn jasper
#

pog

spring crescent
#

Okay, so I have my reward system working and functional using the DB. Now do you guys have any suggestions on updating placed chests every X amount of time? Right now I'm simply tracking chest updates and updating contents on the DB by listening to inventory close events. However there will be an obvious situation where players will use hoppers to move things around. By doing this, chest contents will become "Outdated" in the database from the in-game state. How much of a performance hit would it be to iterate over say 1000 chests, get their locations in the world, and update those contents in the database? I think someone mentioned once about doing it by loaded chunks only, but that might prove more difficult than it's worth. Any suggestions?

torpid raft
#

do you have to iterate over all 1000 in the same game tick? or can you spread that out

spring crescent
#

@torpid raft I can spread it out. It's not a critical operation so it really only needs to happen a handful of times per day. Even if it was unable to run because of a restart on the next update it would get it updates.

merry knoll
#

given that you know their coords

merry knoll
mild stirrup
pulsar ferry
#

First of all you're closing the inventory before canceling the event, second, delay the close by 1 tick

proud pebble
#

you should probs just schedule the close of the inventory 1 tick later

#

Bukkit.getScheduler().runTask(YourPluginInstance, ()->player.closeInventory()); i do it alot in my own plugins

#

ofc replace YourPluginInstance with whatever method you use to pass the plugin's main class

#

the original object

dense galleon
#

And that "its got its fair share of issues" which electroniccat couldn't be bothered to get into for some reason

#

What I was told however is that the two are not compatible with one another, and if I ever want to install some anticheat or plugin which depends on ProtocolLib I'm screwed if I use PacketEvents

proud pebble
#

your probably trying to call the class, not the object

pulsar ferry
#

Calling the class directly refers to the instance of the companion object, not the class itself

proud pebble
#

like mine is LunixPrison.getPlugin() but in my main class, ive got

private static LunixPrison plugin;

public void onEnable() {
    plugin = this;
    ...
}

public static LunixPrison getPlugin() {
    return plugin;
}
pulsar ferry
#

please don't do this in kotlin

proud pebble
#

idk how kotlin does it, but they should beable to figure out how to convert it to kotlin

pulsar ferry
#

Just do dependency injection

proud pebble
#

DI works aswell and is probably the way ur supposed to do it, i just do the static abuse method so i dont have to

#

cus lazy

pulsar ferry
# pulsar ferry Just do dependency injection
override fun onEnable() {
  // Pass the instance of the plugin to the listener
  InventoryClickListener(this)
}

// The instance is in the primary constructor
class InventoryClickListener(private val plugin: MyPlugin) : Listener 
dense galleon
minor summit
#

can I see the message

#

because afaik they are just independent from one another and work entirely orthogonally

dense galleon
#

Based on that it sounds like:

  1. PE cannot send packets
  2. They are not compatible with one another
minor summit
#

I'm pretty sure they can coexist

#

they just don't interact with each other

dense galleon
#

Idk when I asked electroniccat to elaborate they said they cba to do it

#

So I am kinda lost now

grand island
#

Tho packet events has its epic gamer moments

dense galleon
#

Wdym?

minor summit
#

afaik you can send packets with PE?

#

some PlayerUtil or smth I think it was

dense galleon
#

Where can I find docs on PE?

minor summit
#

javadocs should be linked on their gh readme, I'm not sure if they have user guide docs however

spiral prairie
#

You can send and listen to packets

dense galleon
#

So I can have both plugins in my server

grand island
#

YES

spring crescent
#

I have a problem I don't know how to efficiently work around. Currently I'm tracking each "Container" eg, furnace, chest, barrel, etc.. that is placed in the world and adding the XYZ coordinates for those to a database. The problem is that I need to track the contents of those containers, but how do I resolve a "Double-Chest" without duping contents into my database? Given a chest has two sides, but their contents are the same. Does anyone have a suggestion for this?

pulsar ferry
#

One day I'll need to implement something similar to that, and I'll just say, it's an absolutely nightmare to do omega_lul

minor summit
#

just save both chests individually

#

they have their own individual inventories

#

double chest inventories are just two chest inventories glued together with spit

spring crescent
#

so if you break one and it moves it all to one side, my chest update method would fix it auto-magically?

minor summit
#

wat

spring crescent
#

When you break one side of a double chest, and there's space, it'll move everything to the remaining single chest

minor summit
#

no

#

if there are items on the right side and you break the right chest it'll just drop everything from that chest

#

they are simply two individual chests

dense galleon
minor summit
#

i mean that's not what i said but sure

#

that depends on whether or not they published the javadoc/sources jar to the maven repo they use

dense galleon
#

Can I somehow attach them manually?

spring crescent
#

Wait... this is a mechanic I never noticed. Going to test that now. If it works out of the box I'll be happy lol

minor summit
#

uh maybe? on intellij you can go to the project structure -> libraries, find PE and you can add sources jar if you have one

#

but, you need to get it lol

dense galleon
#

What's that type of website called? I've seen it before

#

is it just javadocs

minor summit
#

what

dense galleon
#

trying to figure out how to download the sources

minor summit
#

but they host the javadocs online

dense galleon
#

I'm just really bad at using that website

minor summit
#

"that website" being?

dense galleon
minor summit
#

i mean it won't give you anything you ide doesn't already

dense galleon
#

Ah so there is no javadocs for methods etc.?

minor summit
#

it's just gonna help you navigate from class A to B and see what methods they have, return types etc

dense galleon
#

I mean but can't I already do that through my IDE

dense galleon
#

So no Javadocs

#

I really don't get people who write APIs and proceed to not write javadocs for them

minor summit
#

?

dense galleon
#

Javadoc comments

minor summit
#

the javadoc are literally online

dense galleon
#

I mean the comments

minor summit
#

ah yeah ig

dense galleon
#

I've written javadoc comments for private plugins I use in my server ffs

#

Wait so to use PacketEvents it's just... a lot of trial and error and looking at examples?

sharp hemlock
#

Hello, so i have a little problem when using the maven shade plugin i want to create a sources jar that also has the dependencies' sources.
Setting <createSourcesJar>true</createSourcesJar> does indeed do the job. It includes the sources' of my dependencies. It then misses out my main project sources in the source file.

When i have the source plugin and have createSourcesJar false, it does indeed create the sources for my main project but obviously then it misses the dependencies' sources. If i try and have both enabled. It doesn't work.

https://haste.olziedev.com/sahenobaha.xml

This is my POM.XML

dense galleon
#

Is there any examples on how you send packets in PE?

#

Or do I just have to piece it together myself

#

Also, how do I know what each packet type does?

#

If there is no proper documentation

sharp hemlock
dense galleon
dense galleon
#

Sweet thank you I will look at that

worn jasper
#

and again, packetevents can send packets too and it's not as hard as some say

spiral prairie
#

PacketEvents is completely fine with ProtocolLib afaik, just use PLib 5.x.x

#

Imo PE is easier to use and also has a nice Discord and developer everybody can easily reach out to

spring crescent
#

@minor summit so I discovered something "Interesting" about my Double_Chest predicament. It would seem the assumption that double-chests are stuck together with glue is an understatement. If I attempt to update the contents of the chest, using the ChunkLoadEvent that will result in duplicate data, because the data for the inventory is stored in both tile entities. However, using the InventoryCloseEvent will result in a single chest being returned, so updating that way will always result in a single instance in my database being updated.

Curiously, I cast it to a DoubleChest to see what would happen if I return the .leftSide() or the .rightSide() values for it, guess what, they both return the same exact X,Y,Z coordinates despite the tile data carrying unique values for "Individual" chests. WTF is going on.

This is going to result in a proper pain in the butt to update my chests because I can't reliably use ChunkLoad due to the nature of the way that DoubleChests work. So now I'm back to square one with updating chests and redstone will break my setup entirely. Does anyone know if it's possible to get the contents of an unloaded chest at X,Y,Z coordinates? What happens if I get the X,Y,Z of a double-chest and it behaves the same way as the ChunkLoadEvent?!? This is quite a problem xD

lyric gyro
#

@ helo

#

@robust crow can you help me to solve my discord account

neat pierBOT
#
FAQ Answer:

Looking for discord support?
HelpChat is a Minecraft plugin and development support server and is not affiliated with discord in any way.
If you require support from discord, we recommend you to visit their official support website at https://support.discord.com
On this website, you can read their FAQs, or open a support ticket if necessary.

spiral prairie
#

Some people pepela

river solstice
#
  1. Wrong channel
  2. nice @ helo
  3. nice funnycube ping
  4. nice assuming he can "solve" a discord account
  5. how do you "solve" a ddiscord account
  6. this is not a discord server for DISCORD SUPPORT
  7. lol
grim oasis
#

how would I go about retrieving the base64 value of a skull?

spring crescent
grim oasis
#

Can you elaborate?

#

I'm asking because I've never gotten it before

#

so I have no "way I normally would"

spring crescent
#
public static String itemStackToBase64(ItemStack item) throws IllegalStateException {
        try {
            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            BukkitObjectOutputStream dataOutput = new BukkitObjectOutputStream(outputStream);

            // Save every element
            dataOutput.writeObject(item);

            // Serialize that array
            dataOutput.close();
            return new String(Base64Coder.encode(outputStream.toByteArray()));
        } catch (Exception e) {
            throw new IllegalStateException("Unable to save item stacks.", e);
        }
    }
#

Also, looks like there's an instance method .toItemStack() you can use to get the ItemStack

#

So it'd be something like String serializedSkull = itemStackToBase64(skull.toItemStack()) would get you the base64

graceful hedge
spring crescent
#

I need suggestions desperately. I've been stuck on this chest updating problem for a while. I need to track the contents of a chest (Chests placed by a player), and I need it to auto-update even if redstone contraptions change those contents (Eg Hopper -> Chest). I currently have a solution that works for tracking the chest, and updating whenever a player interacts with the chest by using the InventoryCloseEvent which works great. However DoubleChest seems to complicate that matter when using ChunkLoadEvent in particular because I cant' run checks there async due to using Bukkit API. Furthermore getting the contents of a doublechest seems to always "Duplicate" my data in my database, resulting in two separate "Chest" instances, that contain the same thing. This is not expected behavior given an Inventory close event always just updates either the left or right side, depending on which side you interact with initially.

Ultimately the problems that I need to solve are, updating chest contents in my database, regardless of single or double chests & containers, as well as handle redstone adding items to those chests. Any suggestions?

grim oasis
grim oasis
#

skullMeta.getOwnerProfile() returns null

spring crescent
#

Anyone have experience unloading and destroying a world? My world seems to always fail to unload, returns false . Restarting the server results in a newly generated world, but I'm expecting it to not require a restart.

private void generateNewWorld() {
        for (Player p : getServer().getOnlinePlayers()) {
            p.kickPlayer(ChatColor.GOLD + "The world is being reset for the new season. Please rejoin in a moment.");
        }

        List<World> worlds = Bukkit.getWorlds();
        for (int i = 0; i < worlds.size(); i++) {
            World w = worlds.get(i);
            getServer().getScheduler().scheduleSyncDelayedTask(this, () -> {
                boolean result = getServer().unloadWorld(w, false);
                getLogger().info("Unloaded world: " + w.getName() + " Result: " + result);

                // Delete directory
                File worldDir = w.getWorldFolder();
                deleteDirectoryRecursively(worldDir);

                WorldCreator wc = new WorldCreator(w.getName());
                wc.environment(w.getEnvironment());
                wc.hardcore(w.isHardcore());
                wc.generator(w.getGenerator());
                wc.keepSpawnInMemory(false);
                wc.createWorld();
            }, i * 20L * 5L);
        }
    }
#

Also, should be noted, the other worlds, nether and the_end unload just fine.

sterile hinge
#

if it's the default world, that might just be a limitation of how the server works

spring crescent
#

Yes it’s the default world. Hmm is there any way to update that default world?

#

I’d really like to avoid a restart requirement, but I definitely need the worlds reset entirely

sterile hinge
#

make some other placeholder world the default one

merry knoll
#

might wanna take a look to see how they do it

rancid sonnet
#

does anyone know a better way to print TextComponents with player.spigot().sendMessage? sorry i dont know if im in the right place for this. the best method i found for now is making a new textcomponent for every message and using var.addExtra(secondvar); to add the textcomponents together and then print them to the player

hoary scarab
atomic trail
#

Is it possible to have a fixed size for ArrayDequeue? Or should I use something different?

torpid raft
#

just make a tiny wrapper around it to enforce a size restriction

#

but also there seems to be a BlockingDeque which sounds like what you want

sterile hinge
#

It really depends on what you want to happen when trying to add if full

atomic trail
#

I'm trying to store the 5 latest locations for a while, using a scheduler

#

The issue is that it doesn't remove the last element in the queue, when it's filled, which is what I want

#

Important part is this

                    if(!previousLocation.containsKey(uuid)) {
                        ArrayDeque<Location> deque = new ArrayDeque<>(5);
                        deque.addFirst(player.getLocation());
                        previousLocation.put(uuid, deque);
                    } else {
                        previousLocation.get(uuid).addFirst(player.getLocation());
                    }
atomic trail
#

It should just push everything towards the last index when I add something new

dusky surge
#

java.sql.SQLException: No value specified for parameter 1
How is this possible? Happened only on some servers with MySQL.
Here is the code:

this.saveQuery = "INSERT INTO " + this.databaseManager.getUsersTable() + " (uuid, data) VALUES (?, ?) ON DUPLICATE KEY UPDATE data = VALUES(data)";
Connection connection = null;
PreparedStatement preparedStatement = null;
try
{
    connection = this.databaseManager.getConnection();
    preparedStatement = connection.prepareStatement(this.saveQuery);
    preparedStatement.setString(1, this.uuid);
    String data = GsonUtils.getGson().toJson(this.dataSave);
    preparedStatement.setString(2, data);
    preparedStatement.executeUpdate();
}
catch (SQLException sqlException)
{
    sqlException.printStackTrace();
}
finally
{
    this.databaseManager.close(connection, preparedStatement, null);
}```
Anyone SQL expert?
atomic trail
atomic trail
dusky surge
#

Is like is missing this line: preparedStatement.setString(1, this.uuid);

#

If I remove this line I see same error.

atomic trail
#

Try catching all exceptions instead of just SQLException

#

Might be something different

dusky surge
#

Good idea but I don't think.

atomic trail
#

Looks a lot like it's throwing an exception

#

Also use better debugging

#

For example throw new RuntimeException("explain error", exception);

dusky surge
#

I added more debug infos, now waiting for customer. Thanks for the help!

atomic trail
#

don't use exception.printStackTrace

atomic trail
#

Also I'd recommend looking into using TWR instead of using the finally block

dusky surge
atomic trail
#

Yes but actually explain the error lol

#

So your client can see what went wrong

dusky surge
#

I just need to detect and fix that.

#

He is not doing something wrong.

atomic trail
#

For example Exception happened while saving database

atomic trail
dusky surge
#

Yes is something temp until I fix the issue.

atomic trail
#

Aight

sterile hinge
river solstice
#

or just, check the size and remove last if full

#

¯_(ツ)_/¯

#

but yeah, custom data structure is prob something id go with too

sterile hinge
#

having it as a proper data structure makes it easier to ensure the invariants are held

minor summit
#

big words

spring crescent
#

So TIL that resetting a world aka regenerating the Main world is much harder to pull off than I imagined. It would appear that it's entirely impossible to use .unloadWorld(...) on world or whatever is defined in server.properties. Does anyone know of a workaround for this? I am able to regenerate nether and end dimensions just fine, granted I don't know if they're accessible in the way that I'm thinking.

river solstice
#

well thats probably there to ensure a location to put the players in

#

if you are going to unload all worlds where will the players go

#

a workaround would probably be having a different unused main world

spring crescent
#

Yeh it would seem that's the thing I'm going to have to do... even Multiverse doesn't have a workaround, and those guys are pros at world management. It's not the worst, I suppose. Users can just have a "Central" world which will act as a hub to access the seasonal world. Doing so means I'm going to have to manage nether travel and end_travel I believe.

sterile hinge
spring crescent
#

There's always reflection 🤣 but I'm not insane, and I'd rather just work around the problem with something different haha xD

sterile hinge
#

what is the problem with doing what I said

spring crescent
#

I don't think I'm understanding what you mean by "Make placeholder" I think that's already what I'm doing.

sterile hinge
#

you have one world that just is there but isn't in use at all

spring crescent
sterile hinge
#

so the problem is solved then?

spring crescent
#

Ehh up for debate xD I don't know if this is loading the worlds yet. If it is, then yeh I'll just use the PlayerPortalEvent to direct them where they should go.

spring crescent
#

Ooh interesting. That solution "Kinda Works" seems that it only creates 1 world per restart, which is not expected. Is there some limitation of WorldCreator that only allows a single world at a time to be generated?

#

Figured it out. I needed to run it in sync.

spring crescent
# sterile hinge so the problem is solved then?

Do you know if it's possible to force a player onto a world when they join? I presume so, but I want to be certain before I go crazy with this. Seems I now have my rewards and such working from end to end so a release is right around the corner 💃

minor summit
#

PlayerSpawnLocationEvent

#

setSpawnLocation

river solstice
#

i dont like looking at this code

#

uncanny valley

hoary scarab
#

If it's for your server specifically you could edit the server jar you're using.

river solstice
signal grove
#

are there any events related to entity consume? i want to trigger when a witch drinks a potion

wispy iron
#

Please help me!!!! How do I add a glow effect to an item displayed in the menu?

signal grove
#

player

minor summit
#

keep reading

signal grove
#

witch

#

xD

#

thanks

minor summit
#

np

signal grove
#

im using spigot though

#

but i found an EntityRegainHealthEvent

#

so that should work ideally

tight junco
#

i mean what if they use a fire res potion

terse osprey
signal grove
#

the server's paper

#

im making the plugin spigot for compatibility

merry knoll
#

stick to paper or one of its well known ports

#

or folia if it fits your use case

terse osprey
#

Paper, I think we were talking earlier and like 85% of servers are running paper with I think nearly 95% servers running paper if you include forks hold on we were just talking about this

#

I can’t find the messages, discord mobile search is trash. I may be off by ~5% on either or both of those numbers but TLDR just use paper

royal hedge
#

tf

sterile hinge
#

I don't understand what that is supposed to mean

#

if you want to replace an object in place, that's not going to work in Java for a bunch of reasons

hoary scarab
tight junco
#

what link even was it

#

i mean theres not many reasons to post jitpack links when you just joined really

#

send it as a file

#

if you can

#

try to invalidate caches and restart

#

alternatively you could delete the .gradle file

#

just silly intellij things

#

oh yeah

#

im stupid

#

perhaps resetting the .idea file in general ?

dusky harness
#

try File -> Repair IDE
although since you already did invalidate caches, that probably won't fix it, but idk what else to do

dusky harness
tight junco
#

its just intellij being a bit strange sometimes it happens

dusky harness
#

no

tight junco
#

if its compiling fine it should all work its just your ide showing the wrong info

dusky harness
#

maybe we should've given a warning about that 🥲

tight junco
#

yeah i was thinking that but configurations shouldnt be crazy difficult to do again

dense galleon
#

What could result in a ClassNotFoundException, even if the plugin being depended on is present in my server?
I have two plugins: DropNames and Artifacts.
DropNames depends on Artifacts, and has it added as a provided dependency in the pom.xml.
However, when both the plugins are present in my server, the moment DropNames tries calling a method from Artifacts, the ClassNotFoundException error is thrown.
Artifacts does load before DropNames too

dusky harness
dense galleon
#

The Artifacts plugin does work

#

I have no clue what could be wrong, I got another plugin depending on Artifacts and it works without issues

dusky harness
#

like paper-plugin.yml

#

or regular plugin.yml?

dense galleon
#

plugin.yml

dusky harness
#

oh

dense galleon
#

Is it meant to be paper-plugin.yml

dusky harness
#

no i just asked since paper-plugin.yml has a different loading system and stuff

dense galleon
#

Ah okay :/

#

Any idea what could be wrong? The poms for the plugin which depends on artifacts successfully and the current plugin are identical

dense galleon
#

Okay welp, mvn clean fixed it I guess

dusky harness
#

oh yeah
it's recommended to always run mvn clean package

#

instead of just mvn package

#

forgot about that

#

gradle 😌

dense galleon
#

package? why not install?

dusky harness
#

which isn't needed unless you're using that project as a library in another project

#

ex BuildTools does mvn install

dense galleon
#

Question: is there any way to make TextDisplay entities always face the player? Like name tags do

dusky harness
#

hmmm

dense galleon
#

There isn't that many methods in TextDisplay though

#

Ah it's the billboard thingy

spring crescent
#

How do I go about recognizing color codes in my localization file? I'm loading a custom localization.yml config into an object as a string for each keys value. Those String can have a color code, eg & associated with them. However I can't seem to get my colors to appear. Am I missing something? I have tried ChatColor.translate... to no avail.

river solstice
#

Plugman

broken elbow
spring crescent
#

oooh can you give a short example of that? I think thats what I'm actually missing xD

    private static String translateAlternateColorCodes(String text) {
        return ChatColor.translateAlternateColorCodes('&', text);
    }

Raw string is just given right here

#

The string might be something like "&bHello,&6 World!"

#

Are you just trying to support hot-swapping?

#

What IDE are you using?

#

Maven or Gradle?

#

Ezpz, you can run the server from in the IDE, in a separate folder, run it in debugging mode

#

Then have your build artifacts go out to that folder

#

Simply "Build" and viola it'll hot-swap changes so much as you don't change more than one class at a time

broken elbow
#

To see if it returns the string with section symbols instead of ampersands?

spring crescent
#

Prints out the text, with no color codes.

#

Err I see, uno momento

broken elbow
#

And if you send that message to a player, they see it without colors?

spring crescent
#

Console outputs this [15:39:21 INFO]: Translated: have died and must wait until Season no translations. Input was this &6You have died and must wait until Season

#

Correct, players see no colors. Interestingly, why would it be chopping off the entire &6You ? wtf xD

minor summit
#

&blah is special syntax in yaml

#

you'd have to put the whole thing in quotes

#

"&6You have died ....."

spring crescent
#

LOL I just realized that. Ty @minor summit & @broken elbow

dusky harness
#

unload & load

#

note that plugman can break some stuff, so if the plugin doesn't work, try restarting too

#

but other than that, as long as you're not doing it in a production environment, it should be fine

spring crescent
#

Now I should be able to sneak in PAPI support and MiniMessage, all in one place. Ahhh i love it xD

spring crescent
dusky harness
#

I haven't really done research on the actual problems of it though

spring crescent
#

I think it has something to do with the way it loads and unloads classes. So if you update across major changes, it'll break things a lot. It'll also ignore "States", for example FancyNPC's will break entirely if you use it, by causing duplicate entities to spawn.

dusky harness
#

it also seems to keep all of its memory, so FancyNPCs probably has all the entities spawned, and then onEnable results in it spawning again
either that or FancyNPCs doesn't use packet NPCs and it doesn't remove the NPCs in onDisable

spring crescent
#

Just do straight up in-memory. RAM is cheap

dusky harness
#

I haven't used redis myself, so I don't know, but you shouldn't be using redis on the main thread, meaning that you'd probably need to do in-memory caching anyways

spring crescent
#

I'm loading like 1000 chests, locations, contents, etc.. with minimal impact to memory usage

spring crescent
#

Depends on your use-case. I went SQLite so that I can also offer MySQL support which is more readily available to server owners than say, a redis server or a mongo server. Not to mention there's more documetation on that related to Minecraft specifically. You'll be hard pressed to find anything about Minecraft + Redis for example.

minor summit
#

eh

#

using mysql to communicate between servers is not a good use of mysql lol

#

and redis for persistent storage is very harold

merry knoll
#

depends on your data

#

postgresql if you need sql

#

redis if you need cross server cache

sterile hinge
#

Nah that’s fine I guess

dense galleon
#

Is it normal for any entity to not be visible past a TextDisplay entity?

trail burrow
#

it has been a few weeks since I opened my IDE, getting many warnings in my pom about could not transfer metadata, anyone know how I can fix?

dense galleon
#

If I have an int that NEEDS to constantly be synced up between my whole network, does it make sense to access it and store it directly into my database?

spiral prairie
#

redis?

dense galleon
#

What

#

The database is stored locally

#

As in, same machine which the server runs on

spiral prairie
#

use the key value in memory storage of redis

#

its fast

dense galleon
#

I have never heard of Redis

#

Is that built-in

spiral prairie
#

no

dense galleon
#

Right

#

What would be the problem with the approach I mentioned

#

I'd rather avoid using yet another library

spiral prairie
#

depending on the db it could be slower

dense galleon
#

What would the speed depend on?

#

I'm using MySQL

spiral prairie
#

if its storing and reading the value to and from disk

#

also why are you still using MySQL

dense galleon
#

It's my dad's machine, he had that installed

spiral prairie
#

ah

dense galleon
#

It's a complicated story haha

#

What's the problem with MySQL

dense galleon
#

I mean, I guess I could store that data in a Velocity plugin?

spiral prairie
merry knoll
graceful hedge
#

If you use redis + redisson java redis client

#

Its decent, tho afaik it seems like there is no “compareAndSwap” operation which is the only major disappointment of it at first sight

river solstice
#

How heavy would it be to calculate distance between two players in pvp on each hit?

#

considering there could be like ~40 players in pvp at the same time