#development
1 messages · Page 76 of 1
Are you talking about the ArtifactItem.build() method?
w.e.?
whatever*
Ah sorry haha
AKA the class with the register method and registry map
facade all that away to a nice api and you good i think
ArtifactsAPI.register(artifactobj)
ArtifactsAPI.getClone(key)
Okay so the objective is to do so that all my plugins interact with each other ONLY through classes found in my api package?
ye it also makes it easier on you as well
in case you need to change implementation in the future
How does that differ though if I have ArtifactsAPI.getItem() instead of Artifacts.getItem()?
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
I get that it's all for "good practice"
But what are the actual advantages about that
Like yeah it's defo cleaner
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
Okay I get this, since often it happens that I need to rebuild a lot of my plugins cause I changed a small thing in one of my classes
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
The api package I guess should have pretty much no data of its own then
Hence it is usually all interfaces
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
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
yeaah, its probably a util type deal
Then whenever I want some plugin to create a new artifact, I should:
- Create a new NamespacedKey static instance for that artifact
- Register it in my
ArtifactRegistryclass
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
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
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.
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...
using canvas (html element), how to draw an image (changed with a solid color) something like a shadow (same shape)
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.
no it's not wise
Doesn't Paper have an AsyncPlayerChatEvent for exactly this reason?
Hell I forgot that existed, so if I use this event, do I need to still use the scheduler and run my code async or is it already in an async thread?
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
you will block the chat thread AFAIK
yeah chat thread is separate
so ideally if you will do a heavy operation, you want to move to another thread
The thing is, If I execute it async on another thread, can I then cancel the AsyncPlayerChatEvent? Since the message may have already been sent before that...
If it's <100ms it shouldn't be too noticeable
say if you get 5 consecutive messages in a span of 10ms, then what
Exactly, but doing it in a totally different thread can also cause issues :/, what if it somehow takes longer than 100ms, it would block the whole thread. And if I do it in another new thread, I can't really cancel the event.
What I could in theory do is canceling and triggering afterwards again
well that's probably your only hope
Hell, the worse pain of it all is having to support 1.8 😭
I now understand @rugged bane...
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
¯_(ツ)_/¯
that could work, but sending would have to be with Player#chat method since I want to support chat plugins too
I wouldn't use a scheduler
Use like an executorservice with a 4 thread pool or smth
I have never used that...
So that you can avoid the delay of having to run it on ticks
what even would be the benefits of not using a scheduler
Yup, it's a nightmare..
I swear supporting 1.8 is stupid but if you don't do it you lose both clients and people get angry 😭
🥲
Will have to look into this then, wonder if charlie uses something similar
since Analyse does a bunch of http requests
although in theory, my project gonna do WAY more lmao
If the http server is across the world or smth it'll take over 100ms though
I think supporting latest only is great when it's non commercialised
Yeah we do a fuck ton of requests, feel free to source dive https://github.com/track/plugin/blob/main/sdk/src/main/java/io/tebex/analytics/sdk/SDK.java
In Charlie's case there's no canceling chat tho right?
the real-time option is going to be available only on the best plan since it uses a bunch of resources but in theory, I hope to one day be able to do some load balancing + have it connect to the nearest api server. I would assume charlie does not have this since latency isn't that important in analyse.
no, cause he doesn't really mess with chat (I think)
Oh
idk if it got addressed but cancel the event then resend once your operation resolves
or not (aka cancel )
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.
I would just use Player#chat method
i didnt read the rest of the convo so if it got solved already just ignore me
Would that work with chat plugins?
And make sure to not make it ca your own event
And have that on loop
Infinitely
it triggers AsyncPlayerChatEvent, only difference is that it's not async.
I would listen to the event, and only let through events that are async
since Player#chat is not async, it's fine
Oh ic
it wouldn't trigger a loop
I thought async event was always async but ig not... Noted for future coding lol
you get paid?
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.```
I am building a SaaS, so you would assume yes.
you can probably call it from another thread to make it fire async
would need to see its implementation though
Yeah but I don't want it to be async, cause that would cause a looping xD
it still triggers AsyncPlayerChatEvent, async or not.
Tbf u can have like a boolean to prevent it
True on the line before player#hat, then false after
Thanks autocorrect
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 👀
Feel free, one of the beauties of Open Source 😄 I've become a big fan of doing such
Helps a lot when you can dig through and see how its done
Our http stuff is both lightweight and very performant
I mean't backend of analyse xD (networks, servers, etc) I can take some guesses by looking at the dashboard xD
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
Also, yes, was planning on using what you use, looking if I will use gson or not, since there are faster json options.
I’d say use Gson, only change if you face issues. Don’t prematurely optimise
Haha that’s our black magic, our queries are huge 😂
I bet... I am getting assistance from my teachers to structure the database.
What type of project are you doing
The SaaS I spoke with you about a few months ago, I am getting back to work on it soon.
Ahh I might have to hunt our DMs, my minds all over right now 😂
Any other ideas regarding this?
I don't want to use the UUID incase other plugins do the same. Just can't figure out why this error is occurring.
Never worked with pipelines or whatever so... no idea
Are you parsing uuids somewhere?
Its weird cause often I see player name being used. And all of the names in the pipeline currently aren't UUIDs
nope
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
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.
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?
its not enabled
How to enabled it sir?
I didnt know where to ask im sorry.
#general-plugins i guess
Thanks 🙂
Yeah even on a fresh server with only my plugin it still errors on join.
UUID.fromString(context.name())
uhhhh
yeah that isn't going to work unless the handler name is a uuid string xD
just adding a name?
pipeline.addLast("foo", new MyHandler())?
they just don't take that string and try to get it as a uuid
Could but to listen to packets it has to be before packet_handler.
sure?
the issue is that you are using that handler name as a uuid
not how or where you add the handler
I might be misreading. What do you mean?
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
Son of a BITCH! 🤦
lol
Spent over 2 days on that.
Works. Thanks.
Now I gotta figure out why the meta data is apprently invalid. (According to via version)
Does anyone have an idea how an implemented dependency is missing methods at runtime?
not shaded?
I have the shadow plugin in the build.gradle.kts and I use implementation that should work right?
no... it's not just having the plugin that will make things magically work xD
you have to use shadowJar to build it AND you have to relocate the dependency(ies)
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
This is my current build file https://paste.helpch.at/fuyetiyose.kotlin
So I relocate org.spongepowered.configurate-yaml if the method is in that module?
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
You relocate the package, which can be different from the name of the dependency
Is the naming specific? It's this commentsEnabled method here
I publish it as a local maven repository
btw configurate-yaml does not support comments.
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")
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.
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
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
:)
Paper plugin loaders implement this way better....
and allow for non-maven repos too
yes, meant non central
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.
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
#general-plugins .....
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?
iirc it does handle permission nodes
Well that will simplify the crap out of some logic i have going on then xD
Can somebody help me with CombatLogX
I have a problem when players are in Combat they still can use commands like /spawn etc.
note that this is a coding support channel - I'd recommend asking in their discord server
but asking in their discord server is probably best
Nobody respond to him for a few days and see if we can get $300+ out of him 
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;)
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
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
all i want is to keep the origlinal formatting
or maybe some hover events etc that it could have
so you want to replace something? Or only check if it contains something?
both? ig
Custom minimessage instance without color tags maybe? But if you want to replace, it is a bit harder ig
adventure has some methods to replace text afaik
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
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
it won't show up as empty
also what is event?
Nvm it was another problem sorry
alr
Another question though: how does TextColor.lerp() work?
uhh should prob ask kyori discord
As
textComponent.append(Component.text(line).color(TextColor.lerp(lerpFactor, startColor, endColor)))``` Does not do anything it seems
is it possible to get the item displayname without [ and ]
I think it is name()
ah nvm, name() is from triumph-gui xD
that returns a component
I think you can simply append the ItemStack and it will display the right name
idk what I am saying lmao
^^
The [ ] come from translation iirc
worse case scenario you can serialize it, do what you want and deserialize it again
that's what I do in Runway xD
nope
"chat.square_brackets": "[%s]"
https://mcasset.cloud/1.20.4/assets/minecraft/lang
needs a component
will try dat
duh, you get a component with Component.translatable(itemStack) or smth
heyyy
that worked
ah, but it seems to ignore the display name, it only shows item name
This is what I do in Runway, different use case but yeah
hmm
Totally different question, but if a premium user joins an offline minecraft server, is their uuid the same or will it also change?
Last time I've checked, the UUID was created from the bytes of the string "OfflinePlayer:" + name
yeah the UUID is always generated like that if the server is in offline mode
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
use online-mode=true and you always know
check what plugins like jpremium do
if the src is public xD
it's not xd
fastlogin is open source
itemmeta?
oh
solved by using String#substring
aaand LegacyComponentSerializer.legacyAmpersand().serialize(itemStack.displayName());
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
ew maven
I am out
did you look at the jar to see what's so large?
From your build config: https://github.com/kangarko/Foundation/blob/master/pom.xml according to google the default scope for dependencies is "compile" and here are a lot of dependencies..
wait kangarko?
typical kangarko thing 💀
it does more than that
triumph-guis for the win
hell their wiki is legit "go buy my course to get documentation" lmao
In this case, are you saying I should set it to provided and then whenever anyone gets my resource, they should add a dependency? Similar to PAPI
open your plugin's jar and see what's inside as Ywell said
There's a crap ton inside of it xD
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)
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?
if this is correct, Foundations legit implements spigot-api and a bunch of other apis 💀
Yes, based on what @dense drift shared for default.
I swear if this is true, it's gonna be the most typical kangarko moment ever
lmao
Idk how people buy his course
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
if you had that one person that is the most disrespected in the whole community besides md_5, it probably would be kangarko
and on top of that, bruv can't code
yes for the last question
triumph-guis 🔛 🔝
Okay, so I'm going to listen to said advice, and go idk, Triumph somewhere else? lmao
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
Oh my god. I almost stepped on a mine.. you guys have saved me
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.
Lol added a new dependency Triumphantly, 1mb shaded jar xD
never heard of that
I am slow, mb xD
Apparently not as slow as a kangaroo (🤞 Maybe he catches this one first try. I have faith in him.)
xd 😂
well
at least we stepped away from using chatcontrol red
just had too many issues with it
o i did the same
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
btw have u tested this on 1.16?
bc minimessage was only on like 1.18+ or smth
you could add it manually to the plugin at that time
Can someone help fixing this registry? The usage of the NamespacedKey doesn't seem optimal https://paste.helpch.at/abejezutud.java
So I'm giving this TriumphGUI library a shot @worn jasper and I'm seeing with the Page 1/N I always get Page 1/2XXXXXXXXXXX until I tap next page, or previous page then it will show the appropriate Page 1/3 or Page 2/3 etc.. Any clue what could be causing that oddity? https://github.com/mkaulfers/hardcore-seasons/blob/main/src/main/java/us/mkaulfers/hardcoreseasons/commands/SurvivorCommand.java#L90
What needs to be fixed?
When I register for example 20 different races it quickly becomes a mess
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?
what's so bad about creating the keys?
currently not really available, would suggest entering their discord.
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
can't each race provide its key dynamicly?
Wdym? As is store the key as a field inside the race class?
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())
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);
you can remove the key parameter from the register method or overload it (the method)
I should probably overload it yeah, I'm just keeping it there for a potential API
and I don't think the cast to DemonRace is needed
alternatively you can make addConfig return a generic
Tried making it more generic but yeah
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
try T addConfig(Class<T extends LocalReference>, ...) and return (T) wrapper.get();
oh sorry, you need to put the extends before
public <T extends LocalReference> T addConfig(Class<T> reference...)
Ah yeah that works! Should I just supress the unchecked cast?
I prefer having no warnings so I just use @SuppressWarnings("unchecked")
but you can do ... reference.isInstance(result of get()) and return null on an else branch
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();
}
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
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
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
Ohhhh yeah I understand what you mean now
Nvm is this what you meant?
What does that do? Just an unchecked cast?
Or checked ig?
check the sauce
Does anyone here know what TextColor.lerp() does/how it works?
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
in the case of RGB, it's linear interpolation on each component
https://imgur.com/z9ntjvv
Hey! Can someone help me with this? I don't know what is the issue here
you have a random import there
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.
what happened to triumph-gui lmao
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
I did ask, "Ghost town"
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.
For persistance, serialize the inventory and store it in whatever database you want. I believe this gist is pretty commonly referenced: https://gist.github.com/graywolf336/8153678
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.
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.
I was just responding to the second part of your question/statement.
if you looked around, you would see that itembuilders can also build itemstacks, you can easily just make it that when a player clicks the item, it copies that item, and builds it as an itemstack and gives it to the player.
I did look around. I'm not an idiot. The code takes an item stack and turns it into a GuiItem
I took the time to find a solution before requesting support.
what's this then
what's also this
nha I understood him
those items have additional nbt that triumph gui puts on for identification
which I think is the issue
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
}));
Or
you can even remove specific guiItems with #removeItem()
I'm pretty sure you can change the item stack on the player cursor
use that to make it work more like usual inventories
you could also get the clicked itemstack, but it would clone it with the nbt data too, so you would have to remove it manually
several ways of going about this lol
but moving it around with paginated guis like a normal inventory won't work
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
Clickevent but that seems uneccessarily bad.
- I considered updating the DB with every
since the way paginated guis work in triumph-gui, they populate the gui one by one
- option is impossible
stated above
at least with triumph-gui
pretty sure IF works in the same way
with triumph-gui and IF, this is impossible or very hard to do
yeah
they were not really made with this in mind
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
Yes collected only, but that part is easy if I can just reliably get the stacks in a familiar way.
another potential solution:
- have the items in paginated gui, and on click, give that item to the user
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
yup, that's what I suggested above
.
oh
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
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.
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?
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
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
Classloader
specifically URLClassLoader
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
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
have a onLoad type method on the module
and make all your modules implement an interface
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
are you loading the class
with this
if you want to be cool, you could try using java modules, create a ModuleLayer for your stuff, and load services from the implementing modules
nah Id rather do it in the worst way possible and suffer
is there a way to register commands without them being in plugin.yml?
Ye ofc, I think you have to get the CommandMap from the Server or w/e
very cool
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();
}
reflection bleh
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 😔 🫰
what's with the constructring a PluginCommand?
you can just register a normal Command class
declaration: package: org.bukkit.command, interface: CommandMap
I can say that Im not sure, that's the method of creating one I found lol
and.. it works
good enough
reflection bleh
😕
yeah wtf lol
actually you know what, while i'm here
you guys have like a nice library or anything to construct blocks with nice NBT stuff?
havent embarked on NBT journey yet, still in my future plans
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
Don't know of any. Generally people stay away from NBT data.
yeah well I need to make blocks and I don't know how else to do it 😔
terrible
🤷 Suggestions?
Not wrapping inefficient code with more inefficient code
Example?
example for what?
Of how I can make it better/efficient.
worse*/inefficient*
I don't see any benefit added by that library, why does it need to exist in first place?
Convenience and usage example
Do you have to use NBT?
I see there's an api for this
https://hub.spigotmc.org/javadocs/spigot/org/bukkit/inventory/ChiseledBookshelfInventory.html I guess you set the items here and hope the game updates the texture accordingly xD
Otherwise you might have to do it manually through https://hub.spigotmc.org/javadocs/spigot/org/bukkit/block/data/type/ChiseledBookshelf.html
no I mean not necessarily, I just want to make a damn block and set it in the world
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
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
sometimes convenience is a bad thing
Have you tried Bukkit.createBlockData(String)?
uh, idk what the String would look like?
stringy
yeah like if I could do the string that would be cool
CraftBlockData.fromData(<BlockState>).getAsString()
how do I make a BlockState?
Yeah I'm at a loss there lol. Just example from my schematic code.
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
But what you could do is make the bookshelf and just use that to get the string and modify the string.
😫
One sec
i just wanna go like new ChiseledBookshelf(ItemStack[] books).setInWorld(x, y, z)
hol up lemme just add that to the api
^^^ lol
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
Isnt there a method in spigot api that accepts a snbt?
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.
I mean I don't wnat to just set it to occupied
I want to actually put books in it lol
I figured. Yeah no one liners or short code for that as far as I can tell. Could make your own lib lol
Iirc this is the method that accepts a snbt https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Server.html#createBlockData(java.lang.String)
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:
- set the block material to chiseled_bookshelf
- get the blockstate and cast to chiseledbookshelf
- get the inventory and set the contents
- update the blockstate
Sad
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();
}
accessing resources is always a trial and error process for me
try to put the file in a folder that has the name of the module and access it by the full path
huh
example-module.jar/example-module/config.yml > getResourceAsStream("example-module/config.yml")
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.
and by using this, since the class is loaded by my main plugin, getResource looks for resources in mycoolplugin.jar, when it should look in mycoolmodule.jar
not sure if that explained it
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
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
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?
huh
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
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)
im not too sure but that doesnt exactly look like UML to me
I mean when you look up UML diagram, you can find those kind too
still not the actual uml
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
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
it's either we call every diagram UML or some diagrams are just diagrams and not exactly UML
well it's def. not the standard uml used in java and the uml you learn at school/uni
real
UMLs usually display fields, methods and class name.
https://en.wikipedia.org/wiki/Unified_Modeling_Language#Diagrams there's a list of different UML diagram types
it's much more than just class diagrams
found a few diagrams from my bachelors degree project lol
Use-case, ER, deployment (package?), activity, sequence
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?
that isnt a web of dependencies
Is it not?
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
dev builds yes
but packetevents better
if only the plugins I use depended on PacketEvents and not ProtocolLib lmao
What's that?
Okay the issue is that with PacketEvents I can't send events
you can?!?!
lol
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?
can be shaded, built-in wrappers, supports latest versions (without the need to use dev builds) and it's not protocollib (W)
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
@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.
pog
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?
do you have to iterate over all 1000 in the same game tick? or can you spread that out
@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.
doing on loaded chunks is the way to go and is simple
given that you know their coords
for this just use a queue system that spreads it over multiple ticks
Could someone take a look at my code pls read Line 35 and 36 where i explained my Problem Thx <3
https://paste.helpch.at/itovobipul.kotlin
https://www.youtube.com/watch?v=Kg_377t85Wo
First of all you're closing the inventory before canceling the event, second, delay the close by 1 tick
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
I was told in the Paper discord that it's not as easy to send packets
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
https://imgur.com/a/kCl0y7E
Sry to ping you but why is that wrong ?
your probably trying to call the class, not the object
Calling the class directly refers to the instance of the companion object, not the class itself
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;
}
please don't do this in kotlin
idk how kotlin does it, but they should beable to figure out how to convert it to kotlin
Just do dependency injection
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
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
Is this a realistic problem?
Worked
Thank you
wat
where'd you get that from 
From ElectronicCat on the paper discord server
can I see the message
because afaik they are just independent from one another and work entirely orthogonally
Based on that it sounds like:
- PE cannot send packets
- They are not compatible with one another
thats not true
Idk when I asked electroniccat to elaborate they said they cba to do it
So I am kinda lost now
Tho packet events has its epic gamer moments
Wdym?
Where can I find docs on PE?
javadocs should be linked on their gh readme, I'm not sure if they have user guide docs however
You can send and listen to packets
I got bamboozled twice here then
So I can have both plugins in my server
YES
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?
One day I'll need to implement something similar to that, and I'll just say, it's an absolutely nightmare to do 
just save both chests individually
they have their own individual inventories
double chest inventories are just two chest inventories glued together with spit
so if you break one and it moves it all to one side, my chest update method would fix it auto-magically?
wat
When you break one side of a double chest, and there's space, it'll move everything to the remaining single chest
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
when clicking download sources on IntelliJ, it doesn't seem to find the sources :/
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
Can I somehow attach them manually?
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
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
what
trying to figure out how to download the sources
it doesn't seem like they publish them https://repo.codemc.io/service/rest/repository/browse/maven-releases/com/github/retrooper/packetevents/spigot/2.2.1/
but they host the javadocs online
I'm just really bad at using that website
"that website" being?
This
i mean it won't give you anything you ide doesn't already
Ah so there is no javadocs for methods etc.?
it's just gonna help you navigate from class A to B and see what methods they have, return types etc
I mean but can't I already do that through my IDE
So no Javadocs
I really don't get people who write APIs and proceed to not write javadocs for them
?
Javadoc comments
the javadoc are literally online
I mean the comments
ah yeah ig
Those
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?
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
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
only examples i found https://github.com/retrooper/packetevents-example
and using this helps a lot https://wiki.vg/Protocol
Yeah those are all for receiving
Sweet thank you I will look at that
there are some issues with it, yes, including reports of the owner being a kid, will still need protocollib for other plugins that require it but for your own plugins, specially if its a public one, you can just shade it. ProtocolLib has its own issues too so, not really the biggest thing.
and again, packetevents can send packets too and it's not as hard as some say
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
@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
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.
Some people 
- Wrong channel
- nice @ helo
- nice funnycube ping
- nice assuming he can "solve" a discord account
- how do you "solve" a ddiscord account
- this is not a discord server for DISCORD SUPPORT
- lol
how would I go about retrieving the base64 value of a skull?
A skull can be used as a Block so that means you can get the ItemStack variant of it and thus do it the way that you normally would.
Can you elaborate?
I'm asking because I've never gotten it before
so I have no "way I normally would"
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
if u use api u have SkullMeta and PlayerProfile where u can grab the base64 from
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?
oh this is the entire item, i just need the skull owner value
how so?
skullMeta.getOwnerProfile() returns null
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.
if it's the default world, that might just be a limitation of how the server works
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
make some other placeholder world the default one
slime world manager might support it
might wanna take a look to see how they do it
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
InventoryMoveItemEvent for hopper -> chest
InventoryClickEvent for player -> chest
You can use the Inventory async but when updating the chest's block state it has to be sync.
Is it possible to have a fixed size for ArrayDequeue? Or should I use something different?
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
It really depends on what you want to happen when trying to add if full
I'm trying to store the 5 latest locations for a while, using a scheduler
Like this https://paste.helpch.at/najofahive.java
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());
}
BlockingDeque waits until there is space, I don't want that
It should just push everything towards the last index when I add something new
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?
Ignore me, found a simple fix
Does this happen when there's a duplicate key? Because iirc you need to put the data in parentheses as well so it's ON DUPLICATE KEY UPDATE (data) = VALUES(data)"
Happened only on 2 servers, on all other servers work fine.
Is like is missing this line: preparedStatement.setString(1, this.uuid);
If I remove this line I see same error.
Try catching all exceptions instead of just SQLException
Might be something different
Good idea but I don't think.
Looks a lot like it's throwing an exception
Also use better debugging
For example throw new RuntimeException("explain error", exception);
don't use exception.printStackTrace
.
Also I'd recommend looking into using TWR instead of using the finally block
For example Exception happened while saving database
I know
Yes is something temp until I fix the issue.
Aight
just write some custom impl that deals with the limit
or just, check the size and remove last if full
¯_(ツ)_/¯
but yeah, custom data structure is prob something id go with too
having it as a proper data structure makes it easier to ensure the invariants are held
big words
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.
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
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.
I told you #development message, just don't use the main world actively
Discord is the easiest way to communicate over voice, video, and text. Chat, hang out, and stay close with your friends and communities.
There's always reflection 🤣 but I'm not insane, and I'd rather just work around the problem with something different haha xD
what is the problem with doing what I said
I don't think I'm understanding what you mean by "Make placeholder" I think that's already what I'm doing.
you have one world that just is there but isn't in use at all
Ahh yeh I'm pretty sure I'm doing that. Here's a look at my solution, based on what you said.
so the problem is solved then?
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.
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.
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 💃
If it's for your server specifically you could edit the server jar you're using.
wait the blud deleted the message
are there any events related to entity consume? i want to trigger when a witch drinks a potion
Please help me!!!! How do I add a glow effect to an item displayed in the menu?
yep
player
keep reading
np
im using spigot though
but i found an EntityRegainHealthEvent
so that should work ideally
i mean what if they use a fire res potion
There’s your first problem
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
tf
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
I figured. Asked anyways to make sure.
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
if not use paste.helpch.at
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 ?
try File -> Repair IDE
although since you already did invalidate caches, that probably won't fix it, but idk what else to do
oh yeah ig you can try this
its just intellij being a bit strange sometimes it happens
no
if its compiling fine it should all work its just your ide showing the wrong info
maybe we should've given a warning about that 🥲
yeah i was thinking that but configurations shouldnt be crazy difficult to do again
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
then it should work
can you paste the full error here?
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
are you using paper-plugins?
like paper-plugin.yml
or regular plugin.yml?
plugin.yml
oh
Is it meant to be paper-plugin.yml
no i just asked since paper-plugin.yml has a different loading system and stuff
Ah okay :/
Any idea what could be wrong? The poms for the plugin which depends on artifacts successfully and the current plugin are identical
Okay welp, mvn clean fixed it I guess
oh yeah
it's recommended to always run mvn clean package
instead of just mvn package
forgot about that
gradle 😌
package? why not install?
install also runs package, but also installs to your local maven repo
which isn't needed unless you're using that project as a library in another project
ex BuildTools does mvn install
Question: is there any way to make TextDisplay entities always face the player? Like name tags do
Ah cool okay
I think it's possible because there's been discussion of using that to make custom nametags, but I haven't used TextDisplays myself, so idk how to
hmmm
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.
Plugman
Spigot doesn't actually use & for color codes. It uses § (section symbol). You need to translate & to § which you can do using ChatColor#translate. You said you used it but it did not work, however you did not provide any examples of what you have tried so we won't be able to help further. Please provide examples of what you have tried.
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
Have you tried printing out what that function returns?
To see if it returns the string with section symbols instead of ampersands?
And if you send that message to a player, they see it without colors?
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
&blah is special syntax in yaml
you'd have to put the whole thing in quotes
"&6You have died ....."
LOL I just realized that. Ty @minor summit & @broken elbow
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
Now I should be able to sneak in PAPI support and MiniMessage, all in one place. Ahhh i love it xD
I guess I'm a monster then. I use it to update plugins all the time lmao xD
I mean you can do it, but afaik it doesn't actually unload and load the plugins fully, so you want to be careful with it
I haven't really done research on the actual problems of it though
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.
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
Just do straight up in-memory. RAM is cheap
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
I'm loading like 1000 chests, locations, contents, etc.. with minimal impact to memory usage
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.
eh
using mysql to communicate between servers is not a good use of mysql lol
and redis for persistent storage is very 
depends on your data
postgresql if you need sql
redis if you need cross server cache
Nah that’s fine I guess
Is it normal for any entity to not be visible past a TextDisplay entity?
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?
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?
redis?
What
The database is stored locally
As in, same machine which the server runs on
no
Right
What would be the problem with the approach I mentioned
I'd rather avoid using yet another library
depending on the db it could be slower
if its storing and reading the value to and from disk
also why are you still using MySQL
It's my dad's machine, he had that installed
ah
It would be yeah, as I don't really have a way for multiple instances of my plugin to access the same data from different servers
I mean, I guess I could store that data in a Velocity plugin?
redis
That's what I said
didnt read the whole chat mb
There is something called redisson live object service
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