#help-development
1 messages · Page 1006 of 1
could I have some examples in an open source plugin (that's preferably not too large) please?
Uh I’m pretty sure you just do saveConfig
When updates are needed to be made
https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/inventory/meta/SkullMeta.html#setOwnerProfile(org.bukkit.profile.PlayerProfile) Does the Method SkullMeta.setOwnerProfile involve a blocking Web Request to Mojang if only the name is given or will it only look up the players that are online?
declaration: package: org.bukkit.inventory.meta, interface: SkullMeta
if they don't exist in the player data then it will do a lookup
so i should to run it async?
i'm not quite sure you understood me, when you have a config.yml within the resources in your jar, and call JavaPlugin#saveDefaultConfig(), it will copy it to plugins/<plugin name>/config.yml, however if you release a new version of your plugin, where the config.yml has some new properties, they won't get copied over
what a noob \🤓
This doesn’t make any sense to me, it should put every config path/value that you have…
I’ve never had an issue like this before
I don't have any plugins that do this, but the idea is simple.
Iterate over your config while comparing to the new one and write any new sections that don't exist using FileConfiguration#set() and then save the file.
And you have to do this?
Yes
#saveResource() gives you two options
Overwrite the file, or don't.
So you can't get fine grain control
Is there a method that doenst make a web request and just gives a exeption or some stuff so i dont need to run it async?
Odd, I’ve never had an issue like that before, every time I add new config options, I just put ‘em in my config startup method and everything “new” gets added
But how? That's never been the case with the API.
Are you sure you weren't using some other library to handle the files?
https://paste.md-5.net/sigejisufi.cpp
This is pretty much what I do every time, any new config options I just add and it writes it in next reload
Ah, you use the other approach.
Copy default (true) ?
what
Tbh, I don't know much about the config options.
I've always used the direct approach.
FileConfiguration loading from disk
yeah I came across that while browsing online too, however it seemed bizarre to me that I have to have specify a default value in code. But I realised it might just be the best to loop through plugin's own config.yml that comes in the jar, and then add the defaults to the existing config.yml from plugins folder and call copyDefaults
I guess I never realized there was a “direct” approach lol
I’ve also never had to deal with vcs so maybe that’s another issue
But here's the other thing.
That only works with the default config afaik
If you have any other files that need updating, you don't get those benefits.
i have no idea what this is about, too much people yapping
Flat files and stuff and things
started from here lol
here are some related links from the web:
just rename the config in the plugins directory
then call that method
old configs are saved, new configs are used
That’s smort frost
They want existing values that have been changed to exist in the new config.
If you just copy over the new config, you won't have any of the existing changes.
Wouldn’t the new ones be “overriding” the old ones as it were?
Man whatever this “direct approach” is, I don’t like it kek
If they new ones don't exist, then technically yes.
But any ones that already exist shouldn't be touched. (Even if the default has changed)
but, its generally not worth the effort to implement diffing
its just easier to rename the old config, use the updated new config then let the user handle it from there
if the user is too stupid to modify the configs they shouldn't be running a server
not sure why dev's want to put the effort into trying to automate everything as if its somehow better that way lol
Well, if the config options aren't there then the plugin would likely error out if they didn't use the methods that provide fallback values.
what config options?
That’s why I’ve always just done this
The ones they want to add/update.
they should be in the config included with the jar
What’s the difference?
I have to look more into this.
Other than just having easy fallback values
Maybe there's a way to leverage it
probably
but eventually you end up with a big class file of nothing of updating values
when you could just....install a new config file
Why even do that, just use the existing one no? In the way I do it, /myplugin reload will save the new values
Yea, but what if the config file is large and heavily modified?
I think it's a nice thing to have where all of those changes I have made I don't have to redo every single time there's an update.
it depends how much changed. But as I said it is generally not worth coding a diffing mechanism all because you want to save your user from having to update their config stuff themselves
Especially strings/messages.
I don’t even see a point in automated config updates, in the sense of wanting a concurrent state of config values, automation makes no sense to me
I basically said this
all that is happening is you are taking the time and effort the user would put in, quadrupling it and you are putting that time and effort in so they don't have to
and if its a free plugin
even more pointless to go through all that trouble lol
the troll that needs slapping has appeared at the perfect time
@worthy yarrow you can now let your nuclear fustrations out
hey, am struggeling to find the right dependency to hook a later version (dev build) for protocollibs. is that even a thing that I can hook the alter one simply using a dependency? or do I need to build it in if so?
Fortunately I’m on vacation, that’s one of the reasons I’m here!
I had that issue too, idk why it wouldn’t let me use the latest even tho its listed on the git
might try to add the jar file directly in then
Perhaps that will work, I just settled for the most recent (before latest)
am updating my codes to 1.20.6 😐
Eek
You know, I think if #setDefaults() is easy enough to understand and actually works in the way I think it does, then I might be able to update the wiki.
Because if it does provide the ability to set default values without changing existing ones, then I think everyone who made their own systems just didn't realize how it worked in the first place. Me included :kek:
I’m pretty sure it does kek
it sets it in memory if I recall
Like I said that paste is the way I’ve always done it, then to induce the changes I give the user a reload command
Should I look into cleanup of config memory?
Cause here's my initial thoughts right.
A lot of people have files in their plugins. More than just the default config.
#addDefaults() is accessible through FileConfiguration.
So in theory, we could take the existing files in the resources folder, iterate over the sections and use #addDefaults on them to update the existing config.
Which would negate the need for a complex diff comparison.
There’s no theory about it if it’s accessible through fileconfig, why would it be different just for the default config?
Hi guys, where can I get the direct download link for a plugin on spigot?
(Download now)
Are you trying to wget or curl a plugin
Yeah what Olivo said
yes
thats not the directly download link
Use the Spiget api
I didn’t realize there was a more direct link kek
thank you it actually worked. I have no clue how tho, the entity isn't registered anywhere...
thanks
the client knows about the entity
That is all it needs
oh, yeah, that makes sense, so basically even if the server has no clue what I am doing, the client does
I would run under the assumption that it should it doesn’t always work first try :p
I just registered it by a deprecated method OfflinePlayer, then set the nametagvisibility to false and it worked
first try
Well now it’s time to rewrite it
why
Yea, it's what it looks like.
If it’s deprecation to be removed, then rewrite it, but also because no method should be considered “good” until rewritten a couple times - Bruce eckel (thinking in java 4th series)
yeah that is a minor change, I can just change it to its name
Noice glad my simple ways unlocked an easier path for ya haha
now another problem comes with how to detect NPC click; I assume PlayerInteractManager is for that but I don't know.
why not use Path and the Files api?
may I ask how to listen to incoming packets, the problem is that I don't want to write my own netty handler for that, although I know how, but I just want to somehow get a packet PacketPlayInUseEntity
how do u give a command an optional argument? like this:
if u run /mycommand your "storage" will show up
if u run /mycommand <player> the <player> "storage" will show up, but only if u are an admin
my googling skills are so bad 😭
simple
ruturn different stuff based on the arg and if sender has permission
in your CommandExecutor you have String[] args
declaration: package: org.bukkit.command, interface: CommandExecutor
i dont want the player to see that he can enter an argument if he is not admin
all of that will be in the onCommand method, so when the player enters /mycommand in the chat and clicks space, he will see that he can enter a player name as argument, i dont want that, i only want admins to see it
@remote swallow would you happen to know the answer to my question?
modify it on tab complete
you have the exact same arguments
Is tracking the player interaction on a packet entity even possible? (server doesnt know abput it)
idk about packets
kk
so if the client knows it will still send packets about interaction
@remote swallow do you know the answer
@remote swallow your role color is different
you must
come on
slag
alr I will just write my own handler and just check
Thanks
because I will NOT use protocollib, where is the fun in that?
use PacketEvents 💪
maybe if the raw netty channel handler won't work
How do you get the spigot api for 1.20.5/6?
hi, i have my spigot server up and running and it works great for me, i created a port forward for the ip of my server however my friends still cant join, does anyone know what i can do?
OMG IT IS **** WORKING HOW IS IT POSSIBLE?!?!?!?!
adjust windows firewall settings maybe... otherwise look what the error for him says
his error is just a timeout error
go into options and override the java exe
it showed him attempting to join once in the server terminal
ah man i downloaded java 22 this time and clicked the build tools hoping to open the gui but it ran instead -.- wrong folder
thats awkward... do you have both tcp and udp forwarded?
in the cox app i added the port foward set to both tcp and udp for my macs ip address (im using the laptop as the server) and he still couldnt join
something I've never done before, now that I can detect when NPC is clicked with nms, I can add my own spigot event right?
or register it
yes
You need a packet listener
i heard packet
I want packet lessons from retrooper
if compensated, i'd love to provide those.
i'd even give programming lessons
if compensated
that would be more fun
I mean
I feel like you’d be better than illusion cuz he’d just yell at you the whole time
No
you know anywhere to get clients
I’m reading a book, and have been doing spigot dev for maybe a year
That’s my experience
Though I only say a year because I’ve been doing it on / off the past 4
Trooper doesn’t like to converse D:
just fuck around and find out thats how i learn
that was a pretty random fact xd
@worthy yarrow how you got 1
from on and off 4
just say 4, so it sounds better
Sure it sounds better, but for how I write you’d say 1
When someone says they have 10 years of experience, you can't expect that they dedicated hours every single day.
without skipping a single dya
XD
but i get you
stay dedicated though
don't stop
I actually have been doing that since January kek
Only issue is I forgot my computer charger for this trip I’m on, so now I just have to read my book 😦
No
can I use my own commands inside code?
is there a way to format an int like 1200 to 1.2K and 2400000 to 2.4M?
Elaborate please
Why
To save space
Hey, could someone guide me on how to reset a world (trying to make a minigame)
I don't get how to do this
god forbid NumberFormat be used
Is there a formatter for that
https://paste.md-5.net/efakamewad.cpp
You could also do this, I just ripped this up. It should work for versions lower than Java 12. There are likely better ways at this but this is readable
You could use an array with an index as well
sure
NumberFormat.getCompactFormat() + setMin/MaxFractionDigits
He might want to throw it into a variable and do .setMinimumFractionDigits(decimalPlace); if he wants 1234 to be 1.234k
@quaint mantle Put a \ in front of the quote. Regarding your question in general
Yeah I figured it out, thanks.
No problem
Did intellij update their dark theme?
I was used to their old Darcula UI
but, i swear
they changed the theme
to be darker
and have circular stuff
which
is amazing
Yeah it’s really nice now. I still have the old one on my work pc I need to update it there.
I like the old one in its own ways so I keep it lol
The old UI is probably the best in my opinion
New one is sleeker but old one has a place in my heart
It makes me think of VS Code @royal heath
no not dark enough
Lol yeah, I like the font though
soemone should join #695010567907180554
Heya,
At the moment I'm utilizing getItemMeta().getPersistentDataContainer, is there anything similar for Blocks, or an I going to need to spawn in armor stands and use them for persistent data?
?blockpdc
Learn about CustomBlockData here:
https://www.spigotmc.org/threads/custom-block-data-persistentdatacontainer-for-blocks.512422/
Legend thanks
Hello,
I am currently trying to replace the /version and /ver command with my own /version command that will send a custom string to the sender.
But it still uses the normal /version command from bukkit how do i disable the vanilla one?
Any help is much appreciated ^^
do you know how to compile spigot yourself?
you mean the server version itself?
like the .jar file?
Do default bukkit commands exist in the command map?
not entirely sure if the version command can be overridden easily from a plugin, however the version info is pulled from the manifest in the jar which is created from the pom
so the easiest way to change it, is to change it in the pom
I recommend though if you intend on changing it you make it known that it is a spigot variant
but is there no config option/way to do it?
like disable-command or something inside the spigot.yml or bukkit.yml?
no there is not
alright thats unfortunate
not entirely sure been a really long time since I looked at the code for the default and bukkit commands
Because if they do, doesn't it mean overriding is as simple as just getting the command, then overriding the executor and tab completer? Might cause some issues with other plugins that do that, but who cares
possibly, don't have my IDE up to look
but I remember version command being different, don't even think it has tab completion
I think this is the version command
https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/browse/src/main/java/org/bukkit/command/defaults/VersionCommand.java
Hey, that's cheating - only exists since Java 12 (https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/text/NumberFormat.html#getCompactNumberInstance()).
those poor 1.8 users 😭
how does that make sense? every player has their own netty ChannelPipeline. But I want to just intercept the packet from childHandler
sounds familiar
but that's a very odd and specific question @mellow edge
I hope you're aware there's projects that already do this for you.
I know, but I try to do it by myself since I understand netty
I intercept a packet PacketPlayInUseEntity, the only problem is that it triggers Caused by: net.minecraft.server.v1_8_R3.CancelledPacketHandleException every 2nd time I get this packet
does itemdisplay have its own hologram system or something?
do you know any similar project that uses nms (not protocollib) to intercept packets within spigot
Look at TinyProtocol
You might have to tweak it for it to work well today, I don't think it'll be stable out the box. But that's a way to do it.
Generally there's multiple ways to actually inject and hack to get the pipeline and insert your handler. So which project you decide to look at shouldn't matter, you could look at ViaVersion or mine. But since you claim to be a netty expert, from there on you should be capable of assessing where your handler should be inserted and proceed from there on.
If you are fine with only supporting modern paper, the injection process is like a 5 liner.
I mean I injected my handler before packet_handler and used auto-release handler
I will take a look at TinyProtocol
Personally I think ViaVersion's injection is easier to learn from.
But with TinyProtocol, I guess you technically could just yoink the code and get it somewhat working.
Could someone tell me some way to reset a World (trying to make a minigame)
wdym reset
i have a world in my plugins/plugin/maps/mygame which i copy over to the server root and create a world of
elaborate, what do you mean by reset? what some minigames do is they a world of the map. and then they have a seperate minigame world which copies the map upon start of a minigame
then you can juts create a new one
temp worlds ^
yup
well there is multiple ways of doing this, probably the best one would be to use proxy to redirect to the actual minigame server from lobby, but you could also just copy the original world to player world, then when the minigame is over you could delete your playing world and copy it from original source again. BUT do not use an arraylist of "placed blocks" - this is not a good practice
lol
(in a temp world)
but note that when you are deleting the world, you MUST unload it
Oh, that's true
(Bukkit.unloadWorld)
How to get comment above config key (YamlConfiguration)
i mean it's user-specified how many rounds you can play so always loading n worlds can cause a lot of performance impacts as world loading is pretty slow
I mean you can, but what if your server crashes mid-game?
i mean the game would just be over as it's a temp world
there are getComments and getInLineComments in YamlConfiguration
you have a world copy logic (original->temp) world AND a list of blocks to remove?
There are no getComments and getInLineComments methods
well yes, and i also have a reasoning for this.
it's kitpvp duels, i copy over the arena to a tempworld and have a list of actions the players do (blocks broken, placed, etc), and i clear that every round. the reason i don't use multiple tempworlds is because the players can specify how many rounds they want to play, so if somebody wants to play 10 rounds, loading the worlds will lag out the server
old version?, then you have to find a way yourself.
oh yeah that makes sense
I don't know how to do this, so I'm asking here.
make em wait
no
you could have em waiting in some area as they wait for the next round
but i feel you tho
i understand you
whats your server, i want to lag it
especially now that i'm moving stuff over to a temp server architecture, it'll be an even longer wait
no
not public atm
you want to lag it lol
https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/browse/src/main/java/org/bukkit/configuration/file/YamlConfiguration.java
u can look here to see how it stores comments
bruh
yk my api collects non-anonymous stats
ima find you
ok
breaks on my paper fork
PE?
thanks for reporting
packetevents
wait what? you api collects data?
non-anonymous was a joke
kekw
haha imagine
oh no, i sure hope my data is safe
if google wants some user data, they should reach out
hopefully we can find a good deal
i'll manually type in everyone's data
can i get all the data you've collected with a buy-now-pay-later plan
I see you made PE. Then I went to see reviews, they were very positive, except this one:
????
nice pfp
omg, i saw the guy in my discord the other day
his name "govno" is literally "shit" in russian
lmao
he doesn't have plugins....
wait he has
no way... my custom npc click event is working!
poggers
this time protocol wiki saved me
hi , its been a while since i last codded anything , what is the best aproch to deal with local values of kills , deaths , etc? so when game end it reset , a map with String,Integer?
in the User class ?
UUID key ideally
well , can i do it inside the user ? which obv have uuid?
spigot doesn't come with a User class
I mean increasing kills is not bad
better way?
but can't you make a variable for the specific stat?
this is local data, so when a game end , it will calucate it for each player , and then add them to the stats StatsUser have
what does SkyUser class represent?
this is Stats user , so i can do skyuser.getStatsuser().setkills(getKills(),localValues.get(kills)))
if i wana to set the kills in the db
is this a good aproch?
it is ok, if it's working it's working
I mean I would ask myself why I would make it batter.
because I don't know what you mean with batter
so to put it simple , the values in the UserStats class is the user data that will be loaded from database .
and the localValues map , are the ingame (inside arena) data for each user , once a game end , it will get the data from the map for each user and add them to the user Stats data ..
better in design , and performance
why not directly add it to user stats?
and db
also
databases are meant to store huge amounts of data, why would you load all that data back into UserStats class?
why would i store the game data ,and user data? that does not make any sense
I meant why don't you just pull values from database when you need them.
iam doing that , and i think you still don't understand what iam trying to do
so in lobby , i want to pull the data from database [placeholders] , so i can show
well from you've told me I assume you are trying to at the end of the game calculate stats and add them to db
is your system working rn
u can write like private int kills, deaths, killstreaks to make it shorter
already have that
that's for total kills , total deaths .. etc
inside the arena , i want another set of stats for example kills , deaths will show it inside the game , and it is resetable after each game
but the total kills are not
it would be better if userstats was an abstract class containing only players uuid and then you would have SkywarsSoloStats SkywaraDoubleStats etc.. extending your userstats class
oh do you think so that is better?
ig thats open closed principle
and then you could make your saving system work based on given abstract user data class rather than some specific class thou I dont know how your system works right now so I cant give you much help
thanks
When i hit the rate limit of the Mojang API it throws an exeption when i use playerprofile.update and i accept it async. How do i catch that exeption because that method doenst throw one it just prints it in the console so try catch doenst help
How the hell are you hitting the rate limit? Its something like 600 in 10 minutes
nope I just looked its 200 per minute
yes i because i wanted to test if i hit it
But is there a way to catch that exeption?
But i think i will do it on another way. I will just store their profile when the player joins so i dont need to api lookup them
you need to try/catch inside the async call, or use the proper catch Exceptionally
Ok thanks
whats the difference between
pluginname.jar
pluginname-shaded.jar
original-pluginname.jar?
Shortest name is to be used on a server
shaded is teh same as teh shortest name.
original is (I forget)
original took less space in bits
yeah, has no shaded depenedencies
ok
I need a scripting plugin but Im on aternos 1.20.5 and the Skript plugin wont work. I am trying to do that: https://www.youtube.com/watch?v=Mjj-1LDHfBs&ab_channel=FanStaaff can anyone help?
and all of that in only one world
is there a way to teleport to server world spawn? or should i just use a regular teleport event?
this isnt the place to ask for this, but isnt mine reset lite a plugin?
but Its only in blocks no?
i dont think it cna do crops if thats what you are asking
like Its not diagonal
go to skript support
what will they tell me
this is spigot, we dont do that nonsense here
the version of skript is not worknig on 1.20.5 and Im on spigot thats why I came here
Its only with world edit I want to do all of the coal ores in a world
Wrong channel #help-server
go to aternos support or smth if that exists
You are not writing a plugin so wrong channel #help-server
pls help
Try asking a question
#general message
so the font doesnt work here but here it works pls help fix it
Not writing a plugin #help-server
how can i register commands without adding properties? like not having description to a command and such
you cant
can;t have an empty key
you dont need a description
but you need to add it to plugin yml
perhaps a better question would be 'how to add a global command listener'?
and I think the only way is to listen to packets, I could be wrong
what?
no i mean like only having the name of the command in the plugin.yml
you can't
you can
i dont get errors
a key with nothing under it is not a valid section and will be ignored
show me your ways
commands:
test:
idk:
works
what
it does?
ok
lets goo
plot twist, if you wanna get technical you actually dont
what's a good way to hide plugins to non op players? so u can't do /pluginname:command, u can only do /command
i tried using commandmap but that does it globally (even for opped players) and i can't just listen for tab completions cuz that'd leak my plugins if the server stops (unless there's a way to create a non plugin dependant listener)
listen to command pre process event iirc
i can't just listen for tab completions cuz that'd leak my plugins if the server stops
also that event is after u already execute the command
same with that
Hello, I'm making a Spigot plugin, and I'm having some trouble with it. Does someone know how to "set" the Text on a WallHangingSign ? Thank you.
if the plugin stops not the server*
What I linked is what you want
it isn't
yes it is
Its literally all commands that are exposed to a client
(even if the plugin is disabled)
you can;t use a command with no permissions
not all plugins have good devs
you can;t see a command with no permissions
forking moment ig
trash devs use if (!player.hasPermission("wtvr")
for those Like worldedit you can remove the command in that event I just linked
some of them obfuscate their plugins (even if it's free)
is there a way to make a listener that is non plugin dependant
remove the damn command in teh event I linked
if the plugin dies it leaks everything
oh my god, I'm talking to a wall
bro
bro
if the goddamn plugin gets disabled
https://hub.spigotmc.org/javadocs/spigot/org/bukkit/block/Sign.html#getSide(org.bukkit.block.sign.Side)
SignSide has setLine(index, line)
declaration: package: org.bukkit.block, interface: Sign
the plugin stops handling the listener
That event has ALL commands teh client CAN know about
WHICH MEANS IT LEAKS IT
then hide it there
that's global
if it's not sent in that event the client does not know it even exists
the server sends the command update every whatever
that's how when u load a plugin during runtime using plugman the command shows up
it updates on join, permission attachment change and world change
great it updates on join
Thx, I did saw this, but I don't get it. I do a World.GetBlockAt(my location) I get back my WallHangingSign, then, I cast it as a "SignSide" and it throw an error out, so I don't thing I'm on the right track.
what if the plugin gets disabled
missingreports did you even try before saying elgarL's method doesnt work?
how about trying
if of course it works
before saying that
what does "if the server stops" mean?
do you mean that during the server closing, there is a period of time where tab completions work, but your plugin doesn't?
no because the listener is removed and the gc will know it is garbage and will remove it
i meant if the plugin stops
Stop arguing and try it
u owe me 100k if it doesnt work
commands do not leak
they do
its impossible for a client to even know a command exists without it going torough that event
uh
On OLD spigot you used to get a permission error
no? depends on which event, tab completion is not required
how tf do u even set the commands
today the client has no knowlege of teh command at all
It does
oh wait it returns a modifieable list
the client does
okay, are you trying to do this to your plugin, or some other plugin?
in the former, i'm not sure what the problem is about, because when your plugin stops, your plugin's tab completer also stops
Elgar the client gets sent the command tree lmao
Yes, in https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/player/PlayerCommandSendEvent.html which I already linked and told him to remove it from there
ah my bad I misunderstood
show us your code
yes
yes i did
please chill down
are you talking about non-OPs seeing FAWE commands being tab completed, but not being able to execute them?
@dawn flower just to be sure that I/we understand you, are you talking about this behaviour? (hypixel has a /f command for friends)
Show the code in https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/player/PlayerCommandSendEvent.html where you blocked the fawe commands
i just did e.getCommands().clear()
idc abt fawe rn
at first it worked
only fawe popped up
but then i disabled the plugin
rejoined
thats impossible
and all commands r back
what plugin did you disable?
the listener plugin
me about to drop Player#updateCommands
So
Okay?
what
If world guard dies, so is your map
world guard doesnt die
also i have extra protection
bro is schizo
I don;t see its possible to leak commands without firing https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/player/PlayerCommandSendEvent.html
can i just create an always existing listener
this discussion is dumb, if you care to have a minimal surface area, extract that specific logic into its own small plugin that does nothing else
no
no
every command the client knows about goes through that event
with refleciton
No
just, write a two line plugin that does this
it can't break, its just an event listener
Someone already made a plugin which set the text on a WallHangingSign guys?
bruh why, its five lines
sign.getSide(Side.FRONT).setLine(1, "Nice text");```
I'm going to give it a try, thank you
iirc you have to call setSide after that like ItemMeta
cast the blockstate to a Sign
eh, I'm not sure
you don't hacve to call setSide
you have to call .update on the sign block state snapshot
make sure to check first before casting https://discordapp.com/channels/690411863766466590/741875863271899136/1241741686196011070
~~ java if (blockState.getType() == Material.BIRCH_WALL_HANGING_SIGN) // and other types of Material.*_WALL_HANGING_SIGN too~~
just instanceOf it 
just Tag it
what field has the listeners set / map / list?
if (!(block.getState() instanceof final Sign sign)) return`
sign....

why the final lol
what's funny?
listeners are stored in the handler list
I do that
best of luck
final is nice
final is nice 
extra bloat
not really
with no added value in this case
prevents you from changing something you should probably not be changing
^
you have 0 idea what this case is lol
skill issue if you do that
I don't do it much so I should begin doing it more
Yea I mean, people tend to run into skill issues tho
some people reassign variables accidentlly, others fail to come up with a simple 17 endpoint rest service.
It's a nice safety mechanism with no downside beyond verbosity
what happens if i set the plugin as null in RegisteredListener constructor

just patch the damn server man
if you care THIS much about your plugins not leaking
just patch the server
chat remember to always call hasCustomModelData, apparently that fixed my code
or uh
ugh
HandlerList.unregisterAll(this);
I mean a plugin that just filters has 0 attack surface because it reads nothing
Yea
is there a way to identify commands with ":" in their name and pluginname + commandmap?
or do i just use regex
check if they contain a :
commands could contain : for whatever reason
try parse it to a namespaced key
actually commands with : in their name deserve to not exist
Hey, i'm getting the world folder:
But it says it is null
I'm getting the world from player location
hey Bukkit.getPlayer produce an error when the player isn't online or didn't exist, how can i check and delete the error?
bukkitWorld is null
it'll just yield null back
yea, but i'm getting the world from player location
how can that be null?
I mean, show the more extended code for bukkitWorld
you clearly are not
so you are not
you are blindly guessing if a world by that name exists
which, in your case, it does not
no wait

Show where you get teh String world
it doesn't produce an error, it returns null, so just check for that
okay
Player me = Bukkit.getPlayer("musava_ribica");
if (me == null || !me.isOnline())
return;
// do whatever ```
that code would not even compile
it clearly isn't the commented out code 
show us ACTUAL code
use an OfflinePlayer if you can
there you got
Bukkit.unloadWorld(bukkitWorld, false);
GameManager manager = new GameManager(plugin, world);
okay so
yea
that is a great point actually xd
I'll just unload this world and then try to use it later 😉
Well, but I want to copy this world and if it is loaded i cannot do that
i think bukkit.getOnlinePlayer.contain() is better
at this point, it's a matter of preference
it would be a lot worse if there could be thousands of online players, in which case what I sent is faster (assuming the player name is exactly correct), because it uses a Map, while you would still have to iterate through a Collection
https://paste.md-5.net/apubokuhos.cs Something like this would work?
it REALLY isn't
why?
File newSource = new File(source, file);
File newDestination = new File(destination, file);``` is this required? since `source` and `destination` variables are `File` already
beacuse getPlayer does the exact same if you rely on the weird prefix behaviour 
if i check getPlayer.isOnline and the player isn't online i got an error
with bukkit.getOnlinePlayer.contain() i do not
you were literally linked the "pls just null check"
Because it's null then
^ like
the null check is the important part
this didn't work
doubt
did actually work 👍
not that the isOnline check there is actually useful
you don't get an error because the player isn't online
you get an error because you do something assuming he is online, but you forgot to add a check
and generally it's helpful to also mention what type of error you get, in this case it's probably NullPointerException
getPlayer yields null for offline players, non null for online ones
How to check if player is online? getPlayer(playerName) != null
&& player.isOnline()
no
No need to
okay yeah I get it mb
getPlayer will return null if the player is offline
Player target = Bukkit.getPlayer(args[1]); if (target.getName() == null || !target.isOnline()){
fyi use getPlayerExact if you are working with names and not uuids
this is gonna work right?
no
but if you have a Player object instead of their username or UUID, it's probably better to call isOnline method, no?
Whats the difference? never seen getPlayerExact
why bruh
you are null checking the name
which means you call getName() on something that might be null
i believe getplayer can give you the player even if the name doesn't match exactly
yep my bad...
e.g. if you are checking for name123 and the player's name is name1234 you will get the player
but not with getplayerexact
getPlayer simplified is just this java Player found = this.getPlayerExact(name); if (found != null) { return found; } else { return ... /* approximate lookup }
note that getPlayer is deprecated in CraftBukkit
well yeah, but at the time being, it's just a proxy call
how do servers change an inventories apperance based on the inventory (with a texture pack)
I've seen completely different looking guis
but there is only one inventory texture in minecraft, right?
It's pretty trivial
The resourcepack has a font file
Where you can define custom characters and such
And they can map out to a .png file
So you match a utf character (\uE001) to a picture (my-custom-gui.png)
The next thing you need is a negative space font to be able to shift the picture left and right
oh so i just a char?
Once that's done, you just set it on the inventory title (<space.-8>\uE001)
thanks
For animated guis, you just create multiple characters, one for each frame
For fancier guis where buttons can be on/off you can have a hollow main gui and then separate characters for buttons
You change their height by messing with the character ascent
how to get rid of this text though?
I've seen cases where it renders above whatever items are clipping
Lang file -> container.inventory.title iirc
You can then make a font to add it back with a crazy ascent and just toss a character with some spacing in there when needed
If you want lang file support, you can just edit container.inventory.title to container.inventory.customtitle, for example
and then still use the font stuff but with a translatable component
it's wonky
seems cool, I've never looked into using custom fonts
thanks
make sure to make the texture transparentminecraft:gui/sprites/inventory/generic_54.png
since that is the default chest bg
wrong path
minecraft:gui/container/generic_54.png
should just be container.inventory
no fucking clue it's been months
works for me 🤷
how do i spawn an entity at a location and then get the instance of it?
when you spawn it you get the instance back
oh thanks
what do you reckon is the more natural ordering of parameters: x1, x2, y1, y2 or x1, y1, x2, y2?
I think I always did x1, y2, x2, y2 but I feel like I have a little bit of temporary brain damage
depends on their use, the latter for coordinates
well it is for defining a 2D rectangle, so yeah - coordinates
ye the latter
I usually make point classes for this
I've made a custom enchantment system that store the enchantments via PDC. I'm wondering how I should approach displaying the enchantments in lore.
My thought process is: Since Minecraft has its own lore for the default enchantments, I should add the HIDE_ENCHANTS flag and then rewrite the lore myself.
The problem with this is if there is another enchantments plugin that writes their own lore, then that may mess things up.
Any suggestion s on a way to approach this?
then just pass min and max
2 records
the latter imho
Tell people not to use other enchantment plugins
There should only be one
If they use multiple, it's on them to figure shit out
agreed but imo having records is clearer
or that
It feels weird forcing people to use a certain plugin just to be able to use my plugin.
It also makes my plugin pretty heavily dependent on another plugin.
What
I'm saying that they SHOULD NOT use other enchantment plugins
I know. I'm just saying: Lets say my plugin depends on a plugin like AdvancedEnchantments. If the person that wants to use my plugin is already using ANOTHER enchantments plugin, then they would have to switch to AdvancedEnchantments in order to use my plugin (Since, they shouldn't be using more than one enchantments plugin)
Why would your enchantment plugin depend on another enchantment plugin
Free hashCode() equals() and toString() implementation
which iirc also uses invokedynamic or invokespecial
So big W
I explained it poorly before. My plugin isn't an enchantments plugin. It's a crops plugin. I need custom enchantments.
Ah
I mean if advancedenchantments has an api just use that and don't have your own custom enchantment system
Yea
and then I could also support other enchantment plugin in the case that they use another plugin.
In that case I'd use LWJGL's Vector2f class over useless purpose-made records from an API design perspective
would work, assuming you don't need other methods and stuff
Vector2fc :D
wtf does the c stand for
imagine doing a heap allocation for something trivial \🤓
read only type
ahh
Vector2fro kekw
what would be the improvement of that over the normal invokevirtual? I suppose it could do a lazily computed constant but outside of that?
Vector2fim 🤷
invokedynamic means it does code generation at runtime through bootstrap methods
Vector2ManagerFactory
oh god
RecordX::hashcode does not exist in the bytecode when compiled, it gets generated through ObjectMethods::objectMethods or smth
And I'm not sure how you'd need to lazily computed data with indy (unless it is constant per-class, but not per-instance)
ah ::bootstrap its called
ye its per class
classfile size ig? cant think of anything else
Tbh im not sure either, iirc not much was said about it in the JEP ntl
uh wha? I always understood records to be syntatic sugar, but in that case it'd be much more than that.
ye it is
well they’re “transparent immutable data carriers”
with deconstruction right? Or maybe thats still in preview
iirc their getters arent actually written out in the bytecode, but compiled at runtime
basically it's the runtime that chooses the method impl rather than the compiler with room for improvement without having to recompile the class
they just point to a bootstrap method that generates their code
they're present in the classfile
well ye sorta
but they simply do an invokedynamic ObjectMethods::bootstrap or smth
which generates the actual callsite
I don't see how indy is required here
I think we're talking about different things here
i dont either 🤷♂️
invokevirt suffices, no?
not if the bsm wants full access to the class data
ive heard it can be faster but i dont see how
mightve been only for equals/hashcode/toString
indy is good for functional interfaces I'd say. Can also be good for more advanced niche purposes to do things that would otherwise be completely impossible to do with invokeX (i.e. obfuscation)
not sure about the implicit getters anymore
indy is good for reflection
well methodhandles
indy is good for dynamic languages, that's what it was originally introduced for, not java specifically
i believe ruby uses them
jruby was one of the first iirc
* These methods may be used, for example, by
* Java compiler implementations to implement the bodies of {@link Object}
* methods for record classes.
Okay, so it's the compiler-generated implementation of the Record methods that uses them
ye
same for lambdas
but LambdaMetaFactory
theres also one for string concatenations IIRC
yep
StringConcatFactory::concatWithConstants and such
youre not the only one who wrote a classfile reader
and there's one for switch expressions I believe, but the fancier ones like pattern matching over switch
well, not when you're switching over types
Lookupswitch is the old-style switch statements
then there's the jdk.dynalink module which helps dynamic language compilers and runtimes deal with generation of, uh, stuff, it was a cool thing to make a compiler
never used any jdk internals tbh
only ever had the urge to pull in the module that provides @ForceInline
I'm fascinated by how active this chat is, and how long discussions about a certain topic could be, this all started from here and I can't stop reading
ig this isnt about x1, x2 anymore :(
it isn't really internals, it's a jdk module that just isn't part of SE
and by the way I was too scared to mention minX, minY, width, height instead of x1 x2 y1 y2
if it were c i woulve written #define rect(x1, x2) x1, x2 :(
Well for the context it is for querying elements within a QuadTree, doing the "standard" centerX, centerY, width, height makes little sense imo
it's pretty neat but, like, unless you're making your own language runtime it isn't really all that useful
ooh so much new stuff to explore
and ig you did?
idk, the main appeal of invokedynamic I find is for doing obfuscation; which I am not the person to do in the first place
i cannot seem to remember how indy worked for lambdas
i toyed with it for like a weekend, said "that's cool" and deleted the test project
lol
So I kinda ignore invokedynamic (well I still know that javac generates them for me, but there is little reason to actually write ASM transformers that emit them).
I've contributed two or three (depending on how you count it) commits to janino, does that count?
Embedded java compiler, written in java: https://github.com/janino-compiler/janino
in some ways it is equivalent to javac - but doesn't require a JDK to execute!
"execute the code directory in the running jvm"? as in a classfile generator?
feels like hot swapping
it generates *.class files from *.java files
i seem to have read over the fact that its a compiler and not a vm
that is pretty much all it does; it claims to do things ontop of that - but they are mostly scripting related and sit ontop of that compilation thing. It's the main appeal to some, but for me the compiler thing is the main appeal
I mean if you include the jdk.compiler module you can also compile java files at runtime
modules 💜
Well the absolute main appeal is that it has a super intuitive structure for me. But it is sorely out of date feature-wise sadly.
never tried those out, they worth it?
Though I have to warn you: I consider 4k+ LoSC behemoths intuitive (which janino has a few of) - so most will absolutely not like it
it depends on the application ofc
LoSC?
lines of source code
as a library developer there isn't really a downside, as an application developer, well, you have full control over your application
only 4k
ah per file 💀
god bless you, you havent had the time to see 30k lines of generated c code in a file
Yeah, and the Java.java file in janino is 6.5k lines
most editors simply die
I've been meaning to try out modules at runtime + compiletime. So far I exclusively use modules at compiletime where they are quite good at hiding implementation details if necessary
i havent found a reason to use them
Well I've mainly been meaning to use them as it would hide away the fact that a good portion of my projects have a class called "JavaInterop"
its always the legacy code
chat I am setting the InventoryClickEvent's result to DENY but apparently it still lets me pick up items? I added a debug statement before setting it and it's running, it also has the highest priority so idfk anyone know why this may be happening at all?
if (result.shouldCancel()) {
System.out.println("I'm running");
event.setResult(Event.Result.DENY);
}
```This is printing fine but I can still pick up the item
result is my own object, returned from another piece of code
... and now it works what?
Alright thanks guys
wonderful
what does InventoryClickEvent have to do with picking items up?
do you mean take from a chest for example?
also event.setResult(Event.Result.DENY); is very suspicious to me, shouldn't it be something like event.setCancelled(true) ?
setCancelled calls the first one fyi
also yes picking up from a chest
Apparently it works, don't know if I just went full schizo and forgot to build something or what but it works now
Does the <id> in maven repository matter? Cause I have some duplicate repository URL's with different id's and I'm not sure if I need to keep both or can remove one
the ID does matter afaik
ty 👍
My I ask why you opt to use this over setCanceled?
It's the preferred method because you can specify DENY, DEFAULT and ALLOW iirc
where DEFAULT uses vanilla's mechanic, DENY is like setting cancelled to true and ALLOW is like setting cancelled to false
plus if I ever need to have users pick something I can show the name directly
and it's clearer what it is doing
Interesting. Ig I'm just used to using setCanceled. Hopefully it doesn't result in future issues
The less methods I have to mentally register, the better lol
nope, setCancelled just does:
setResult(cancelled ? DENY : ALLOW)
so you're fine with using it
fair I just use tab completion, javadocs and source for methods I don't know
LOL oh I gotchu
how do i get the server's version package like 1_20_R4, i used this previously but the naming conventions seem to have changed
i would prefer not to have to use Bukkit.getVersion() and mapping each to a package version
relocating?
Adding the versioned package
they have on 1.20.5
If a message is cancelled on Spigot, how do I check if that message is cancelled on Bungeecord?
ah ok
?xy
I want to check if a spigot message is cancelled in Bungeecord. I'm sending a message via a spigot server, let's say "hi" is in the list of banned words.
"hi" is cancelled on the spigot server, but on my Bungeecord plugin, even if I check if "event.cancelled()" is true, it still runs, so I assume the event is not cancelled.
Is tehre any communication I can do without plugin messaging channel to check (on the proxy) if an event fired on the spigot server is cancelled
so why do you need to check that
I have a global proxy chat plugin and I want it to be compatible with plugins that cancel messages with links or curse words
🗿
That means I need to make my own "helper" plugin and put it on the spigot server as well right?
theres no real communication between bungee and the server beyond the messaging channel :p
If you really want to avoid it you can check for out going messages
That would cause all sorts of issues though
yes
why not find (or make) a bungee plugin to manage ur chat instead of something per-server?
I was told that cancelling (or editing) proxy messages are not really a good thing to do.
My plugin works with some proxy-based chat filters but not server-based. And again, compatibilty seems to change depending on how that person implemented their filter
why using nms
cuz im making the entities client side
also when working with nms it's very important that you specify the version you're on
i need them to be client sided
oh sorry, 1.20.4 so 1.20_R3 iirc
currently got this:
private void spawnClientSideEntity(@NotNull Player player, @NotNull Location blockLocation) {
final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle();
final ServerLevel level = serverPlayer.level().getWorld().getHandle();
final ServerGamePacketListenerImpl listener = ((CraftPlayer) player).getHandle().connection;
final ItemStack itemStack = ItemStack.fromBukkitCopy(new org.bukkit.inventory.ItemStack(Material.COAL));
final ItemEntity entity = new ItemEntity(level, blockLocation.x() + 0.5, blockLocation.y(), blockLocation.z() + 1.5, itemStack);
listener.send(new ClientboundAddEntityPacket(entity));
listener.send(new ClientboundSetEntityDataPacket(entity.getId(), entity.getEntityData().getNonDefaultValues()));
startTrack(player, listener, entity);
}```
why not use the api? you can show entities to a single player if you wish
