#help-development
1 messages Β· Page 1296 of 1
prob in 2020 u couldnt do much with skript
you could, i've use skReflect or smth like that
where you can create custom skript expressions with bukkit api and java classes
potion?
well they use that i think but its not only this
it does look like it
hmm
.
maybe it's a few degress movement
That mod did not log every packet
why its so hard
go to config and disable ignore player move I think
How do people make queue systems
like what if i wanna make a minigame
set spwans
and it makes a queue
u join and then it tp's u to a new world
That depends on how you want a queue system to work. If you want to queue in lobby, you can communicate with a Redis server and store a list of players in queue. Once you reach a certain size, spin up a server and throw them into a game. Or if you're doing a single-server setup, you can do the same thing but you can just do everything in-memory instead of in Redis (cause it's all on one server anyways) then throw them into a world.
Alternatively, if you want to queue in game, put them into the world immediately and wait until the world has x amount of players
a waiting lobby phase/state is all you need
heyyy, the getKeys is a thing that is cached or it load all the keys at the moment?
i use nbt-api
given that itemstacks no longer are stored as raw nbt anymore, it will get serialized to nbt each time
also why are you casting to HashSet lol
just use the returned Set?
?paste
how do you call this design pattern where you control the instantiation of certain types of objects in centralized way (just like value objects), but you implement interfaces for them only to be used from outside project's scope (lets say public api)?
and in implementation you use the concrete classes for safety against leaky third party implementations and to centralize certain logic with smart constructors
How can I have a Java project where one module is Java 21 and the other is Java 8? Is it possible?
multi version plugin
you can use gradle's subprojects and java plugin which allows you to setup source and output target version for each subproject
yeah gradle would be to go for anything like that
this way ill have 1 .jar ?
you can have it technically by shading both subprojects into one
but im not sure how to do this
since JRE is backwards compatible with previous bytecode instructions compiled in older JRE's
if i compile my plugin on java 21 ill cant run on java 8 server
iirc
?1.8
Too old! (Click the link to get the exact time)
aint java 8 for 1.8 π
1.12 uses java 8 iirc
1.16 uses 17
i can use java8 plugin on 1.16 server
possibly
this way ill have 1 .jar and plugni will supports java 8-21?
yes
this is maven π¦
maven is the chosen build system for Spigot
what EXACTLY are you trying to do? A simple java 8 plugin will run fine under java 21
?img
Can't send images? That's because you're not verified! Use !verify to complete verification.
Alternatively, you can upload screenshots to any image hosting site and share the link.
Here's some screenshot utilities that you can use to upload images.
Lightshot: https://prnt.sc
Imgur: https://imgur.com/upload
Flameshot: https://flameshot.org
you can not build against bukkit 1.17 using java 8
but u said was possible have 1 .jar to work with all java versions
i need have my plugin running on java 8
no he is saying
u cant use the 1.17 bukkit api
with java 8
u need to use 1.16 or any other supported api
then how multi version plugins works
yes, but you can not build in a single jar against all Spigot API versions without using modules
this dont use nms
if you are building under java 8 and want to to run on a spigot 1.8 server you can only build against the spigot 1.8 API
ik
and im already doing this
the problem is java version on compilling my project bro
not this
java version and spigot versions are different
BRO IK
you can NOT reference 1.17 Spigot in a 1.8 plugin
i know lol
and im not doing this
my plugin is 1.8-1.21
and im already using submodules
your build error says you are
i just use for example 1.15 spigot api on 1.15 server version
my build error is saying i cant compile 1.17 api bc it is modern java
referencing 1.17 bukkit using java 8
I just said you can't do that
u can
LPX are 1.8-1.21
and supports java 8
for example
TAB is 1.8-1.21
and supports java 8
thats not what I'm saying
then what are u sayin
they use modules or reflection to support other version of the spigot API
just include nms with it??
but im using modules
and isnt working
YOU are using java 8 for bukkit 1.17, which you can not do
but im using modules
incorrectly
why incorrect?
your error tells you that you are doing it incorrectly
I use mavan so can;t tell you what is wrong with yoru gradle, but it is wrong
im using modules
but I don't understand how a . jar will have classes compiled in Java 8 and other classes in Java 21
this is possible?
I don't gradle sorry
Can't speak for gradle on that one, but it doesn't matter with maven if you set your compilation source and targets in your poms.
ure talking chinese tom e xd
I did a quick search for gradle and it seems like you'd want to use compatibility flags in your build.gradle file.
java {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
This is similar to how maven does it.
https://docs.gradle.org/current/userguide/toolchains.html#sec:source-target-toolchain
This page describes things pretty well.
idk if i need
they didnt put anything
and they are 1.8-1.21 plugin
and running on java 8
Could not determine the dependencies of task ':bukkit:shadowJar'.
Could not resolve all dependencies for configuration ':bukkit:runtimeClasspath'.
Could not resolve project :bukkit:v1_17_R1.
Required by:
project :bukkit
Dependency resolution is looking for a library compatible with JVM runtime version 8, but 'project :bukkit:v1_17_R1' is only compatible with JVM runtime version 22 or newer.
I put what you said in the main build.gradle.kts in the bukkit module and then in the bukkit submodule which would be versions 1.8, 1.9 etc. I put java 22 in the build.gradle.kts of the minecraft version 1.17 and this happens
Is the a way to know if the PlayerInteractEvent results in opening a block / interacting with the block or just interaction with the item in hand while looking at a block?
you know that it will cause jittery if i move my screen?
change it in craft player
It's the same thing
just try to use the resourcepack that the server ur on uses
with the same packets
its probs shaders to get it that smooth
i dont think u can make it without jittering fully server sided
If its shaders then the player shouldnt move at all
player head
^
IF it were shaders, I'd expect them to "pass" a variable to the shader to enable/disable this in some way
Should be really easy to check if they are using shaders tho, extract the RP
?
they are not using shaders
that has to be 100% packets then?
ye, just some form of teleportation
but which one?
instead of some api method, just do /tp :D
again, the mod does not log every packet, only some of them
its jittery i already tried
relative and set is the same ?
what server is it
gimme a bit
ok, I created logs that should tell you what they're doing
logs that start with "SC: " are I think sent from client
Idunno, I just used what that packet logger used but instead of custom formatting per packet, I just used reflection
All packets here were logged only when I held RMB - I was shooting
Anyways, these ones may be the info you want
how do you send this packet via api/skript ? I have no clue
@bold nebula
Oh and if you do, do tag me
I am curious lul
alr
hi im neww
Hello neww I'm NuclearKat
uh huh
uh huh indeed
wassup gooner how r u
I have so many issues with my server
yeah
i need someone to run it
nobody can help w tummy aches
u need someone to run ur server?
ye
what type of server?
survival
ok are you looking for a basic survival server on java ?
so like a mod pack?
just dm me
give me money
ok fase just gimme a minute
im not interested thank youi
bruh
+1
i'm interested in free money
same
anyways i got a plane ride so bye
So in CraftItemEvent, when you .setCancelled(true) or .setResult(Result.DENY), the outcome is the same correct? The cancellation of the event that is
how would i go about creating custom advancements?
declaration: package: org.bukkit, interface: UnsafeValues
thanks
I'm bored and want to create a new plugin, but I have no ideas.
Does anyone have an idea I can implement?
Make the create mod into a plugin
make a plugin that makes eating a cookie cause spontaneous combustion
Nah you're just setting people up for failure
Send a request by email lol
with configurable terrain damage or purely cosmetic explosion effect
Why would I send a request by email
to Waiting for the answer hahaha
I didn't really get the idea. π
if u eat a cookie, u explode and die instantly
just?
and u can configure whether or not this explosion is only cosmetic (just particle effects), or an explosion that also damages terrain
Instructions unclear
i was getting there
Ate explosion, turned into a cookie
based on an old recommendation someone had told me when i asked a similar question bc i was out of ideas lol
it had something to do with cookies and dying
wich version?
like which mc version?
ye
events for item consume are like as old as time in spigot so it shouldnt really matter
same for explosions i think
ideally latest stable π
test the plugin
i tested the plugin in 1.12.2 its work fine i think it shouklld be work to laster version
well give me 5min i found a proplem
@EventHandler
public void onBlockPlace(BlockPlaceEvent event) {```
how can i get the itemstack of what was placed
oh i thought that was for after they placed
well sorry i made evrey thing idk why the plugin isnt work evrey thing looks good idk but ill go to sllep rn sry
ayy this reminds me of SlimeFun
idek if SlimeFun but that with custom models sounds like bliss
man oh man I wish I was just working on my own game
I am getting mighty tired of this whole juggling 5 different projects and dealing with multiversion nms bs
can anyone help with an issue i have for a plugin/project i am making?
Someone here has a method to center a gui title?
can anyone help me with particle making for my mc server
trigger:
set {_gold} to amount of gold ingot in player's inventory
if {_gold} <= 0:
send "&cYou have no gold ingots to convert."
stop
remove {_gold} of gold ingot from player's inventory
add {_gold} to {goldcoins::%uuid of player%}
send "&aConverted %{_gold}% gold ingots into coins!"
or can anyone add a /ah and /ah sell (amount) to this
Why is this not Java?
i tried learning java and failed
rip bro
I cant lie, I dont really know Skript. but i think they have a dedicated server?
Have you tried this specific plugin in java?
i tried finding one but none have a /ah built with it
TheGoldEconomy
yea
i dont understand what ur saying
im asking, if you've attempted to make this plugin in java directly
if you can learn skript you can learn java
what ends up stopping many prospective programmers to ever come out of the skript bubble is that they have "a java at home" in the form of skript, so they're far less motivated to actually try and learn anything new
it is for this reason that i sort of frown upon skript
even if it is in principle a good gateway drug of sorts to programming
skript is honestly harder to learn than java with the amount of random bullshit
Hello, I wonder why there is no BlockState#isLiquid method?
I need to check if a block was liquid on BlockPlaceEvent.
liquid is derived from a bucket empty event
i think he wants to know whether the block state replaced by the placed block was liquid
like placing a block in the water
you should be able to get the type of the blockstate and then call isLiquid on it or something
there is no blockplaceevent for liquid though
the placed block isn't a liquid
the replaced block is a liquid
e.g. you place a dirt block in a lake
or that's what i assume what he wants, dunno
ah he's wantign to test the original block state
This is what I want to check. I fixed the problem by checking BlockState#getType for WATER and LAVA.
a million hardcoded block collision shapes and all nms access is done through obfuscated reflection
you'll also want to check for bubble column
that is distinct from water
true
I guess you could just check if it was AIR. if not it was a liquid.
I don;t know of any other blocks that could exist there in a place event. Possibly crops?
anything that instabreaks, like tallgrass, maybe
nom solid blocks
https://www.spigotmc.org/resources/legendary.127177/ How can i add icon ?
set resource icon on the bottom right
u can
its on that same section
update resource or something
not post upsare
edit resource
than ?
theres no cahnge name
change
ahhhhh
ok ok
thanks
did you set a discord invite as the source code link
no lol
you did ...
Yeah I asked him about it and apparently he doesnβt know GitHub and you gotta join his discord and ask for the source code
Hello, what's the best way to compare mc versions ?
What do you want to compare
I want to reimplement EntityRemoveEvent for before 1.20.4, and I think the best way is extending the base EntityRemoveEvent for calling it in 1.20.4+ or in the other case, making a custom EntityRemoveEvent.
if you want the code to run on servers running a version that don't have the entity remove event, you can't extend the entity remove event
because that class won't exist at runtime and class linking will fail for any class trying to extend/implement a class that doesn't exist
I mean, extending it for when it exists, so 1.20.4 and after
I'll try to see the best way of doing it, for now the thing I would need to is comparing versions
And I've got some problems with my old system, maybe something also supporting snapshots could be useful, for weird server implementations
no clue what you are saying but checking if a class exists is simple. no need for a version check
if all you need to do is check whether the event class exists, yes, that is the ideal approach
oh yeah forgot about Class#forName π
my bad
Thanks for remembering me how to code in java x)
no i didnt
ohhh i did π
@thorn isle i was want do the link in support link but by mistake i pot it there
lol
i will never add more src π I will learn on GitHub. Then I will publish src
no bro i just I didn't think about posting there but it's easy i think
@EventHandler(priority = EventPriority.HIGHEST)
i dont wanna do anything if the event is cancelled. do i have to check if event.isCancelled() and return.. or do cancelled events not get passed?
see the other parameter for the annotation, ignoreCancelled
the default value means that your listener will receive cancelled events
the non-default value will cause the cancelled events to be ignored by your listener
okay thanks. so i have 1 listener which checks for EntityDamageEntityEvent, and if they're 2 players, it gives them antilogout for 30seconds. and in another plugin i sometimes cancell the event if 2 players are from the same clan
so what values do i set in these plugins?
should i do: antilogout - highest
clans - lowers ?
or like maybe antilogout - highest
clans - normal
like how do i pick
well
the higher the priority
the later it fires
so to fire after another listener, your priority needs to be higher than that other listener's priority
lowest -> low -> normal -> high -> highest -> monitor
If you want a plugin to cancel the event and prevent the second plugin seeing it, you need to cancel at a low priority
ok i just cared about other plugins too
impossible to know without knowing what those other plugins listen at
i guess ill do highest and lowest
the priority system is kind of half baked
yeah..
why
generally speaking i guess regular listeners fire at normal, protection plugins usually at low
probably a good idea to avoind lowest and highest as those are mostly used by service plugins like permissions
myeah
monitor is for when you don't change anything about the event
so high and low, or hight and normal
so if your listener is read-only, use monitor
what does antilogout do in this context
if it fucks with the player's inventory or something, that kind of counts as changing the event
@EventHandler
public void onEntityDamageEntity(EntityDamageByEntityEvent event) {
if (!(event.getEntity() instanceof Player victim)) return;
if (!(event.getDamager() instanceof Player damager)) return;
antiLogout.addAntiLogout(victim);
antiLogout.addAntiLogout(damager);
}
no
its just
saving the player to a map
and displaying text
to them
yeah monitor is fine
what does that do
just cancel the event if players are in the same clan
that's sort of a protection plugin, i'd say low is about right for that
doesn't really matter whether it's worldguard or clans or whatever other no-pvp plugin that ends up cancelling it
okayy thannks
i'd expect stuff like custom damage listeners to run at normal or maybe high, so you want to fire before those to make sure they see you cancelled the event
low priority gets the event last right?
yeah this is messed up, in APIs like NeoForge I think LOW is the last, however in spigot LOW means the higher priorty
cause it can override so its higher priority
LOWEST, then LOW, then NORMAL, then HIGH, then HIGHEST, then MONITOR
it does make sense yeah, think about it as who gets the "last word" on what happens
Lowest first first because higher priority events can alter the state of the event
the later you fire the more decisions you can override
highest being last makes some sense, and lowest being last makes some sense, but other sense
ah oof I reverse psycho'd myself
now what actually makes no sense and is objectively shit is the naming of ignoreCancelled
If I set the join message to "blah" in lowest, then I, as a higher priority listener, can overwrite "blah" to then be "hello!"
You can blame md_5 for that one 
I thought highest prio meant first but lowest actual control over the outcome
but also, the lowest, can cancell events so highest doesnt do anything. but its also the highest priority handler's own decision to not handle cancelled events. so i''d say the name is good
not my problem; neoforge is not owned by me
I can cancel event on lowest priority, but uncancel it on highest priority ;P
should've been a double π€‘
For that granular control
it's kind of clownish but it would mean that you can squeeze in between whichever pair of listeners you have to
just listen to the event on all priorities and check if it changes after each one
which is sometimes an issue
Or you can be a menace and schedule your events at priorioty 1.00000000000001
well, user error
ideally i suppose we would use named eventhandler registrations, sort of like the netty pipeline, and make in-code declarations about what we want to run before/after; with detection for circular dependencies
but that's borderline impossible with annotations
yeah as i said its higher pirority decicion to ignore cancell, they dont hav eto
That would have been my suggestion if I were to rewrite it :p I think Fabric does this with event phases or something
i'm sure we could jerryrig that double priority into it while maintaining legacy priority compat
wdym?
doesn't fabric provide callbacks
yeah
ohh maybe you meant they have multiple stages for the same event
but those callbacks can be called in phases or whatever
the fact that its callbacks doesnt change anything about the priority system
so wasn't it a number instead of enum before?
oki
Does v1_19_R3 depend on the version? If it is 1.19.1 1.19.2 etc? Or is v1_19_R3 for any version of 1.19?
it is for a specific release of 1.19
Server revisions are incremented when there are significant internal server changes
It's a reminder to developers to update their references to server internals between versions. Their bumping criteria is largely arbitrary though
new to using this thing... should i just upload it through the website or somehow else, and how to not add the target dir, cause someone 8 months ago told me not to
How do I make my code a .jar?
is there an event for when an entity collides into a block?
on the right side, expand the build tasks and click on the jar task
what is collides
say a chicken runs straight into a block
for example a log
iirc there is only playerMoveEvent for players
hmm ok
where do I find it then?
?xy
under here
No, the jar fileπ
very helpful π
oh
but ill try sumthin real quick
it will be in build/libs or something by default
ok, thanks
<folder with the build.gradle file>/build/libs
U can use the IntelliJ plugin
Add a .gitignore to ignore the target folder
You can use a template for it
I recommend Github Desktop
thanks
thanks !
what is paperweight.paperDevBundle(version) on gradle
That's the paper dev bundle version
(AHHHH SOMEONE SAID PAPER π£οΈ )
what version of Paper to depend on
I'm here with my pitchfork
1,20.6
Read the userdev guide or ask on their discord
im muted there
W
bc i was doign 1.17 plugin
doubt that was the reason
ah you kept asking even after being told it's not supported
ye
make a discord alt and dodge the ban, that's what the rest of us (probably like 20% of paper userbase) do
or like you could try appealing the ban but glhf
sorry
give me 1 day just pls
i alr tried
xd
im muted for 7 days
someone want ask for me there? xd
yeah you'll have to either get a dynamic ip from your isp, or use a vpn; and sooner or later you'll have to start using burner SMS services, i recommend onlinesim
You've been banned.
Reason
During a timeout for repeated outdated support requests, user continued to hassle staff in DM for support with outdated versions
Punishment: 687e97cd8aa5eb733c9ba76c
now im banned
magiciana
[DNZN]
β 16:50
sorry
give me 1 day just pls
magiciana
[DNZN]
β 20:33
i nheed helppp
Imagem
i alr added paperweight
i send this to a staff xd
well that's your problem now deal with it yourself
Please do not bother other Discords with complaints about our bans. We have an appeal system. Also, please stop DMing me for support we already said wouldn't be provided. π
i really dont understand
where can i do appeal'
this is the only reason why paper doesn't have a 100% market share yet
it's only 80% because 20% of the bukkit ecosystem is banned from their discord
how do I open a working anvil inventory?
Hello, how can I simulate correct lightning (like blocks) for ItemDisplay when there is a light source other than the sky ?
The ItemDisplay is the darkest bone block, and the real bone block is the other one
The second picture is my light reproduction without the light source, and it's pretty accurate
Here's how I calculate the light :```java
// Precise lightning: check the light level of the block in all cartesian directions
byte maxLight = 0;
for (BlockFace blockFace : BlockFace.values()) {
if(!blockFace.isCartesian()) {
continue;
}
byte actualLight = block.getRelative(blockFace).getLightFromSky();
if(actualLight > maxLight) {
maxLight = actualLight;
}
}
this.spawnedDisplay.setBrightness(new Display.Brightness(block.getLightFromBlocks(), maxLight));```
Also, I think I don't really spot the difference between blockLight and skyLight for the ItemDisplay Brightness, if someone could explain it, I would be very grateful. Thanks in advance.
set sky light to the actual light from the sky and block light to the actual light from blocks
they both are used for the color blending operation
beyond that, the difference you see is just ambient occlusion being absent for the display entity
or smooth lighting
do you know how I can simulate actual vanilla client lightning ?
it's a bit difficult and somewhat impossible because as said there's no smooth lighting or ambient occlusion for display entities, and vanilla lighting is per block face while for display entities it controls the light for the entire model
is there a solid block in the space the display entity is in?
that means the light from blocks at that location is zero
shove the block light get into that cartesian direction loop
and similarly take the maximum
what do you mean ? (I don't understand this in english lol)
Like, putting the block itself in the relative block faces in the loop ?
if you want more accurate per-face lighting, spawn 6 block displays, one for each face, and use the scale transform to flatten them so they're 2d planes; and then do the light get's per-face and apply them to that face only
block.getLightFromBlocks() is always zero
because block is a solid block
look at the adjacent blocks
just as you do with skylight
I see, thanks
that would be very accurate I guess lol
can someone explain how my updateusableweaponname is hitting its null error when an item should def have it's key?
thanks for your help !
damn it works as I wanted now, thanks !
it's more accurate
how do I open a working anvil inventory?
MenuType.ANVIL.idkidk(player)
Hi! I'm working on a Minecraft plugin where I want to display a custom model on an armor stand's head using CustomModelData.
This is my gold_ingot.json file in my resource pack:
{
"parent": "item/generated",
"textures": {
"layer0": "item/gold_ingot"
},
"overrides": [
{ "predicate": { "custom_model_data": 1 }, "model": "item/gold_bar" },
{ "predicate": { "custom_model_data": 2 }, "model": "item/vault1" },
{ "predicate": { "custom_model_data": 3 }, "model": "item/vault2" },
{ "predicate": { "custom_model_data": 4 }, "model": "item/vault3" },
{ "predicate": { "custom_model_data": 5 }, "model": "item/vault4" }
]
}```
In my plugin, I'm creating an ItemStack like this:
```java
ItemStack item = new ItemStack(Material.GOLD_INGOT);
ItemMeta meta = item.getItemMeta();
meta.setCustomModelData(2);
item.setItemMeta(meta);
armorStand.setHelmet(item);```
But when I run the plugin, the armor stand just shows the regular gold ingot β not the custom model from vault1.json.
What am I doing wrong?
How do I properly display a custom item model (from my resource pack) as the helmet on an armor stand?
what version?
1.21+
specific version pls
1.21.4
this changed considerably in 1.21.4
why u suing armor stands?
Yea
this isnt 2018
- custom model datas arent numbers anymore
u provide the model id
like mymodel:fire_sword
- use display entities
Oh okay, I'm still pretty new to all this so I was just experimenting with armor stands.
Right now, I have a custom model on an item, and I'm rotating the armor stand's head by 90 degrees when you click it kind of like a simple animation.
But now I understand that in 1.21.4, you don't use numeric custom_model_data anymore, and instead use model names like mymodel:fire_sword. So Iβll need to switch to that format.
Do display entities also support this kind of setup? Like, can you rotate them the same way you would rotate an armor standβs head? Just wondering if they work the same for animation-like effects.
they use a slightly different notation for the rotation
armor stands use euler angles
display entities use transformation matrices, which are more powerful (they can scale and shear in addition to just rotate) but a bit more complicated to deal with
you can provide the rotations as quaternions, for which fairly well-defined utilities exist to translate between euler angle, axis angle, and quaternion
.builder().build(player) or .create(player, title) ?
Okay tysm, but is it even possible to get custom model data onto an armor stand using the new method? And if so, how would you do that, or is it only possible with display entities?
yes
there are text displays, item displays, and block displays
for custom models you want the item display
which is functionally identical to an armor stand wearing an item on its head, but without the hitbox and other undesired things that an armorstand comes with
as in using the api you just shove an itemstack on it, same stack as you would equip on the armor stand
as for what metadata you put in the itemstack and how you do it and how you make that work with your resourcepack depends a bit on whether you're using paper or spigot
spigot
for the resourcepack side, the format is quite different in .4 than it was before, i'd recommend reading the minecraftwiki to get a grasp of what the data looks like now, and then maybe ask in some vanilla/datapack discord about how to write a resourcepack for that version, and then ask here or at paper how you'd get the data you need to get on the item
Okay, it seems complicated but I will do my best, thank you very much. β€οΈ
Anyone know how to create entity metadata packets in 1.21.5? Getting an error with this
this.entityMetadata = ProtocolLibrary.getProtocolManager().createPacket(PacketType.Play.Server.ENTITY_METADATA);
this.entityMetadata.getIntegers().write(0, target.getEntityId());
WrappedDataWatcher watcher = new WrappedDataWatcher();
WrappedDataWatcher.WrappedDataWatcherObject wObj = new WrappedDataWatcher.WrappedDataWatcherObject(17, WrappedDataWatcher.Registry.get((Type) Byte.class));
watcher.setObject(wObj, (byte)127);
this.entityMetadata.getWatchableCollectionModifier().write(0, watcher.getWatchableObjects()); ```
What are you trying to do?
I'm using packets to modify player skins - when i refresh the player using playerInfoRemove/Add, I see them without the second (hat) layer on the skin
I read you have to use the metadata packet to get the skin layer visibile
This changed in 1.19.4 to a list of Watchable Objects
.
watcher.getWatchableObjects() returns a list of WatchableObjects
ok so this would be valid for 1.21?
Yup
ok so i went to the "git" tab in intellij, i clicked some 'create local repository' thing, and now its all red and i dont really want to know how that works, just how to cancel that for now lol π
delete .git folder
where is that?
oh i found that
now do i ignore this
before, there was 'version control' now its written 'git'... why??
intellij is anti-mercurial /j
I just have all the version control plugins disabled
I manage git via cmd when I need it
I am getting these errors from my plugin whenever the server closes and i want to know if anybody knows of a way to fix them
I am running a websocket connection with socket.io and disconnecting from it in onDisable
whats that mean
make sure you block onDisable when disconnecting, otherwise plugin disable logic is going to run before your socket closes
also, obligatory
?whereami
==so what does it mean its anti mercucrial
that it isn't really made to be used with mercurial, thought I wouldn't particularly say that
their git integration is definitely better than the mercurial one, but the mercurial integration is fine on its own
How can I set the scale of an nms text display -- I am taking a bukkit text display entity and creating an nms copy of it with different text so I can refresh entity data with that nms display and make it show different text :)
like per player text practically using packets but I just need to be able to set the scale of the nms display
Itβs part of the transformation matrix
how can I use that?
with the set transformation method
if you're going to do that, why not just spawn a different text display per player
display entities are dirt cheap so having many of them doesn't really affect anything, and it is easier to manage
eh too expensive
I don't like hiding a ton of entities
you might think that but it really isn't
it gets annoying
TextDisplay display = someWorld.spawn(player.getLocation(), TextDisplay.class, display -> {
display.setVisibleByDefault(false);
// configure display
}
player.showEntity(MyPlugin.instance(), display);
just like that, you have per-player displays
but if you insist on doing it the way you're doing right now, make sure to listen to the entity metadata packet and apply your changes there, otherwise they're going to get reverted when if they leave the chunk (aka untrack the entity)
but then I gotta run like a billion bukkit runnables for each one which seems hard to manage tbh
I apply the changes when they track it
should be good enough then
I don't see why that would be the case
you mean like, in order to know which display to set when setting the text/transformation?
you can do it in a single runnable, you'd just have to have a Map<UUID, UUID>
well id have to have a map of <uuid, set<text display>> probably
cus there's like a hundred displays per player
sure, that works too, or you could use Guava's Multimap as well
I would go one step further and just make a HologramInfo record which holds the text display's uuid (or a WeakReference<TextDisplay>, either way works probably) and other information like update time
well let's see how hard it is to reload after this, rn it takes about 2 ms to reload displays
what?
I imagine not every text display updates at the same rate
no they all update once per second then they update for certain events
I plan on using map<uuid, map<string, text display>>
where uuid is the players uuid, and string is the name of the display for updating specific ones
now very hard to spot the fake one ahaha
is there a reason you would have a string id instead of just, a Multimap<UUID, UUID> and track them by uuid?
sooo I can update specific ones?
like say I wanted to update the player's text display that is for their money named "money" I could call updatedisplay(map.get(playeruuid).get("money"))
updatedisplay will, well, update the display
I don't know which is the better option tbh, it may not matter either way
I was going to say that you could just iterate through the values but either way works
ah, but don't put the entity on the map, if you're going to do that then use a WeakHashMap or just use the UUID instead
why?
ok well ig I'll just call getentity then on the uuid
it shouldn't happen if you make sure to remove the entity whenever it is dead and/or invalidated, but most people don't bother with that
I mean yeah I'll just .remove() it when the player leaves or server shuts down
I guess since these are text displays, it should be fine like that
I am now curious which collection would have better performance, a nested map or a guava Table in this scenario
the Table has better semantics for this kind of thing but I don't know if it'd beat the nested map performance wise. Not that it would matter that much for this scenario where there is just about a hundred elements per column
Works! Ty.
does PluginDisableEvent run for your own plugin in your plugin?
the event is called before JavaPlugin::setEnabled which is the method that calls onDisable so I would like to say yes. Better to try it and make sure though
https://hub.spigotmc.org/stash/projects/SPIGOT/repos/bukkit/browse/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java#346-381 here's the chunk of code that handles plugin disable logic for reference
Yes, it does btw
@EventHandler
public void onStop(PluginDisableEvent event) {
Bukkit.broadcast(mm("<red>PLUGIN SHUTDOWN EVENT EXECUTED"));
}
In onEnable()
Bukkit.getScheduler().runTaskLater(getPlugin(), () -> {
getServer().getPluginManager().disablePlugin(this);
}, 20 * 10);
honestly I forgot that event exists lol
I use it in my classes cus its so annoying to cram it all into main class onDisable
makes a giant main class
its exactly the same speed
almost to the microsecond
what do you mean exactly
like to reload all of the players text displays it takes 2200 microseconds again
the Table thing or using multiple entities that are hidden by default instead of an entity that you modify their entity metadata
yes
welp, I told you they're dirt cheap lol
true but now I'm also realizing this is overall pretty expensive, like if I had 100 players online just the displays alone would be taking up 20% of the miliseconds we have per second, and thats if there is only 20 displays
I will prob get to 50+ displays in future
but maybe thats just my hardware
cus rn I'm localhosting
so we'll see
server is on 7th gen intel soooo
The more it scales, the more the jvm will try to optimize hot paths too so it might not be all that bad
Then again, at 100 players everything starts becoming an issue
yeah we'll see, if I need to I can just increase the time
Servers nowadays are barely able to hold 50 with good performance
yeah thats why I made my server with the ability to do lobbies in mind
in case I need to I can do that
Itβs mostly why projects like Folia and MultiPaper are becoming popular, the vanilla server just doesnβt scale
also my server is very customized but requires like 0 chunk gen and 0 entity spawning
so should be able to handle a decent amount on good hardware
Am I reading correctly that to use chat components in the bossbar, the most common solution at the moment is adventure?
@worldly ingot when full bungee chat component integration πππππ»
I'd assume the PR needs rebasing and reviewing π
Usually Iβll just delegate it to single method calls for cleanup related stuff, for sure still end up with a modest sized onDisable but at least itβs neat
the good old <system>.unload() or <system>.save() chain in onDisable ππ»ππ»ππ»
Like I said, at least itβs neat
is it possible to create a map item with a set destination? wanting to remake villager trades but i cant really remake the cartographer without their special maps
i mean with spigot
Yeah yeah 1 sec
I think you'd just create a new filled map item stack, you can cast item meta to MapMeta, then there should a getter and setter for "view" or something. Or you can create a new with Bukkit.createMap. Either way you'll want a MapView object... and I think you're smart enough to figure it out from there (just read the javadoc).
Theres also #addRenderer which should allow you to set those banner icons? iunno the implementation of that but I think you can write text on the map too with MapCanvas
declaration: package: org.bukkit.map, interface: MapView
@hushed spindle
i dont see a way to add a structure destination to this, or would i need to figure out where certain structures are another way?
wait
i know you can make a map for a certain location, thats not the issue, i want one of those exploration maps that people can buy from cartographers that leads them to a generated structure
i have no clue how those maps work internally or even ingame since i've never used them
You'll need to use NMS, i had a look.
but you could maybe find a structure using the whatever method lets you do that on World iirc, and then set a marker on the map for that position
StructureSearchResult will provide you the structure. As I mentioned you can use MapView to add a custom render for a banner marker and give it text, but you cant use the icons like the "red x" for treasure or woodland mansion icon.
im ok with using nms, where should i look?
using nms generally involves looking around for yourself
yea but since they just said they looked before..
map related classes are a good place to start but you probably knew that already
You can add these markers (and text) to an image, with the location of a structure. WITHOUT NMS. But you wont be able to add those custom icons.
StructureSearchResult result = player.getWorld().locateNearestStructure(...) will give you a structure, then you can just make a banner for it.
so a good approach would be to grab the location with a structure search result and use spigot again to make the actual map for it
^ as i mentioned here, you can use addRenderer to render banners
Yeah
skibidi toilet.
very sigma rizz of you my lord
sigma sigma boy sigma boy
that's kind of odd, i'd assume the cross treasure icon would be treated the same internally as these other map markers
are treasure maps handled somehow specially internally?
mate, I'd have no clue
I just read the MapMeta and MapRenderer. I cant see anywhere that you could cast a StructureSearchResult
it looks like the MapCursor Type enum does include a red cross icon
so at least the marker should be doable
That should, I think you can change its color too.
But... others... idk
@hushed spindle okay nvm @thorn isle was right
I didnt open the MapCursor.Type enum because i thought that would just be the banners.
You can do literally everything
so: #locateNearestStructure from World > grab location > new marker > marker enum to the type of structure > render it > return MapView > get MapMeta > apply to itemstack
im... not even gonna bother correcting it. thanks sigma
public MerchantOffer getOffer(Entity trader, RandomSource random) {
if (trader.level() instanceof ServerLevel serverLevel) {
if (!serverLevel.paperConfig().environment.treasureMaps.enabled) return null; // Paper - Configurable cartographer treasure maps
BlockPos blockPos = serverLevel.findNearestMapStructure(this.destination, trader.blockPosition(), 100, !serverLevel.paperConfig().environment.treasureMaps.findAlreadyDiscoveredVillager); // Paper - Configurable cartographer treasure maps
if (blockPos != null) {
ItemStack itemStack = MapItem.create(serverLevel, blockPos.getX(), blockPos.getZ(), (byte)2, true, true);
MapItem.renderBiomePreviewMap(serverLevel, itemStack);
MapItemSavedData.addTargetDecoration(itemStack, blockPos, "+", this.destinationType);
itemStack.set(DataComponents.ITEM_NAME, Component.translatable(this.displayName));
return new MerchantOffer(
new ItemCost(Items.EMERALD, this.emeraldCost), Optional.of(new ItemCost(Items.COMPASS)), itemStack, this.maxUses, this.villagerXp, 0.2F
);
} else {
return null;
}
} else {
return null;
}
}
all of this should be doable over the api, except maybe for that renderBiomePreviewMap call
without it, the map will appear either blank or filled
vcs, your profile picture looks like the narrator from spongebob cosplaying as an extremist
it's one of the guys in my unit from back when i was in the military
How many iraqis you smoke?
he had catastrophic eye problems in one eye so he had to use an eyepatch over his better eye for a while
we didn't have any of course so we cobbled one together from bootlaces and a cloth from a rifle cleaning kit
public ItemStack createExplorerMap(World world, Location location, StructureType structureType, int radius, boolean findUnexplored) {
there's this on CraftServer for creating an explorer map, but it'll try actually searching for a structure; you can't the mark to an arbitrary position
i'm not sure if you could maybe manually place a structure there and then use this to generate a map for it
alternatively you could copy paste the actual preview render method from nms and put it in your own map renderer
it's around 100 lines of nested x y z biome check loops
should be fairly straight forward with a bit of elbow grease
Ah that makes sense how do i do that?
i thought it made sense?
Hello, I'm trying to serialize inventories and their information (holder, size and title), but when trying to save and load an inventory full of full shulker boxes, it crashes. Here's my code so far: https://paste.md-5.net/wilicapowa.java
I'm based on this code: https://gist.github.com/graywolf336/8153678
Why are you trying to serialise the whole thing?
can you not just serialise the contents
also does it give an error on crash?
I want to save inventories in a item display pdc so I can restore it across restart
no because I need to identify the inventory from its holder
Thats the wrong way of implementing inventory discrimination
I'll reproduce it
you definitely don't want to store an inventory full of shulker boxes in a pdc of any kind
how can I do it then please ?
what are you even trying to do
also trying to serialise an inventory holder won't really work
I'm trying to create fake blocks by putting an ItemDisplay on top. and I want to create one which open an inventory associated to the custom block on PlayerInteractEvent
actually, it works
store the inventory in a file or something
how is it normally stored in the world then
not in a pdc
i dont really see anything wrong with using pdc
not in nbt either
then how?
tile entities are stored in the same fashion
only on disk
yes, on disk
my pdc are stored on disk too
thats what the persistent in pdc is for
the difference is that the pdc is stored in nbt which is in memory also
for tile entities, the nbt stays on disk and it gets parsed into a proper object model to be stored in memory
i.e. a list of ItemStacks
whats the difference here
nbt is far less space efficient
i meant what is the difference between what you explained and how paulem wants to do it
from what i understood, he wants to keep the data in the pdc of the entity
I can change if needed
this is ass because an inventory full of shulkers is going to be HUGE when represented as nbt
but I don't want it to be stored in a file in plugin data folder
it being HUGE is not as much of a problem for tile entities like chests because again, the nbt is only for disk storage, it doesn't stay resident in memory
but for pdc, the raw pdc data is in memory as nbt, so it's HUGE and it's in memory and that's a bad combination
but its the same data
how can I store nbt only on disk then ?
attach an id to the entity and use that id to locate a file on disk
by caching it in a list the rest of the time
the pdc is still going to be in memory unless you delete the entity/pdc entry, but then it's no longer persistent
and how does using an entity id fix that
because then the data is on disk in a file and not in a pdc in memory
only the id/pointer used to locate the file is in a pdc in memory
but how do you load it into the class then
what
how do you get the items into your entity when you load it
without the pdc staying in memory
the pdc stays in memory, but it is no longer an issue because it is not HUGE, because an id is not HUGE
but then the file is in plugin data folder ?
what do you mean
you look at the id in the pdc when the entity loads, and you use the id to locate a file on disk, and you load the data from disk
the HUGE stays on disk
yes
π
but you loading the data from a file puts that files data into memory?
yes
so
but what you have to understand here, like i've said many times, is that not all storage formats for data are equal
nbt in base64 is HUGE
ItemStack is less huge
sure
so you load it in memory as itemstacks
how do you do that
. (pls)
any way you want; the way he's doing is fine, except i would probably use a file input stream rather than a byte array input stream
How can i block the main thread in my onDisable to ensure that everything shuts down correctly?
the problem with his approach is that the huge 2 megabyte string is in a pdc and not in a file
"uhh whats memory" codingjesus interview question.
xD
yes
hum
but what if you wanted it to be in the level dat
now i vaguely recall that last you brought this up, you had a solid block occupying the same space as the display?
I'd better write everything in the file and load it at start if I use plugin datafolder
yes
the display is 0.0005f taller π€
what you could do is place a shulker in that space instead and use that to hold the inventory; when clicking the entity, get the inventory of the shulker and open it for the player
this does limit you to the 3 row inventory however, and it won't be per-player if you want that
no, because there is a shulker opening animation
and I want my inventory to do the size I want
i don't think the opening animation will play if you open the inventory manually
oh yeah, opening it with spigot
but yeah, if the size is an issue you'll just have to take the file route
hum then the problem is for the inventory size so yeah
storing it in a pdc could be fine if you're sure nothing massive gets put into it
like shulkers or written books
yeah, it's working witha acacia planks ahaha
what do you think of this ?
https://gist.github.com/graywolf336/8153678?permalink_comment_id=5011936#gistcomment-5011936
you think ?
just guessing
that won't work
but that depends on how the custom pdc types work
it's stored as raw nbt under the hood
how so
and every time you do get() or set(), your custom datatype is used to convert it from the complex type to the primitive type
what if I split itemstack datas in chunks of pdc ? x)
for example if you put his code in a pdc data type, every time he'd get an item it'd cause a base64 string to be deserialized into a new itemstack; and that base64 string would still remain in memory
what is actually crashing, the pdc size being high or the global pdc size supported by the ItemDisplay ?
thats dumb
it's convenient but quite expensive and not particularly efficient
I guess thats just an issue with how its implemented then ig
have you sent the error/crash report yet
oh forgot yeah
it could i think be implemented in a way where the datatype is used to deserialize the data only once and then that result is cached, but it'd be quite a bit of work to make work safely
fair enough
wtf it don't print errors anymore
but it still doesn't work
I'll do something horrible but I don't have choice
[12:37:07 ERROR]: Failed to write NBT String
java.io.UTFDataFormatException: encoded string (rO0ABXNy...EAfgAq
) too long: 130528 bytes
at java.base/java.io.DataOutputStream.writeUTF(DataOutputStream.java:363) ~[?:?]
at java.base/java.io.DataOutputStream.writeUTF(DataOutputStream.java:327) ~[?:?]
at net.minecraft.util.DelegateDataOutput.writeUTF(DelegateDataOutput.java:80) ~[server-1.21.8.jar:1.21.8-11-a5f2f61]
at net.minecraft.nbt.NbtIo$StringFallbackDataOutput.writeUTF(NbtIo.java:215) ~[server-1.21.8.jar:1.21.8-11-a5f2f61]
at net.minecraft.nbt.StringTag.write(StringTag.java:66) ~[server-1.21.8.jar:1.21.8-11-a5f2f61]
at net.minecraft.nbt.CompoundTag.writeNamedTag(CompoundTag.java:436) ~[server-1.21.8.jar:1.21.8-11-a5f2f61]
at net.minecraft.nbt.CompoundTag.write(CompoundTag.java:181) ~[server-1.21.8.jar:1.21.8-11-a5f2f61]
at net.minecraft.nbt.CompoundTag.writeNamedTag(CompoundTag.java:436) ~[server-1.21.8.jar:1.21.8-11-a5f2f61]```
when saving
and so when loading
yeah, I saw it and though at first it was the title the problem because it's saying it's for a string lol
how did you get it to save that though
it doesn't want to
oh nvm this is saving where it goes wrong
well, what is this data
like what do the contents look like
a big, big, big, base64 string
or well more accurately i guess this is a limitation in the java dataoutputstream
no i mean the contents of the container in game
it limits utf8 strings to 65535 bytes
I wouldnt store it as a single string probably then
2^16-1, since the length of the string is encoded as an unsigned short
I think what I can do is writing the amount of chunks in a integer pdc, and then loading each chunks from their base key_chunkIndex
oh okay
that can do a lot of pdc ?
and there's still space in each pdc
I would try using a list of serialized bytes (itemstacks) and see if that works
pdc is limited by your server memory I guess
i guess if i really had to store a huge list of items in a pdc without nms, i probably would use the paper serializeAsJson methods and then map the json object to a pdc; in that way there's no intermediate string or base64 encoding and the data gets saved as optimally as is possible to encode it in a pdc
with access to nms, i'd serialize to nbt via nms and store it directly in the custom_data component next to the pdc
id say serializeAsBytes is pretty optimal for most stacks
that serializes it to nbt and then writes the nbt as a binary stream into bytes
if you have nms I would just put it in the level dat just like actual chests, if thats possible
but its more complicated
a custom tile entity would be ideal yes
i don't have much experience with those but they're sort of doable afaik
Humm interesting
There's no limit to this NBT ?
the limit is your memory
From which version is this supported in plugin.yml ?
there are some limits to it still, like if you go over the maximum size of data in a chunk you'll get problems, but at that point it's not much different from regular chests and containers
yeah seem logical
and the raw data is still always in memory as long as the chunk is loaded, so memory-wise it's far less efficient than a regular container
so keep an eye on resource usage as you place them; i definitely wouldn't let players create these things without restrictions, for example
I think I've found
the way to do it, in one string
it works
god damn
private static byte[] compress(byte[] data) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try (java.util.zip.DeflaterOutputStream dos = new java.util.zip.DeflaterOutputStream(bos)) {
dos.write(data);
}
return bos.toByteArray();
}
private static byte[] decompress(byte[] data) throws IOException {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try (java.util.zip.InflaterInputStream iis = new java.util.zip.InflaterInputStream(new ByteArrayInputStream(data))) {
byte[] buffer = new byte[1024];
int len;
while ((len = iis.read(buffer)) > 0) {
bos.write(buffer, 0, len);
}
}
return bos.toByteArray();
}```
What do you think of compressing with something like ZLib ?
but if you have nms isnt it possible to make it work like the vanilla chests and have no memory lingering that you dont need?
with a custom tile entity, yeah
but it isn't really worth the effort
having a pointer to a file in the pdc is much easier and about as reliable
1.18.2 iirc
should I then load it in memory when the server starts or... ?
depends
you could load it when the chunk or entity loads
you could load it when it's first interacted with and needed
then do I unload it ?
depends
i'd probably unload it on chunk unload, but save it whenever the inventory is closed, to make sure i don't miss any changes
and if it's a pdc, does it unload with chunks ?
like, when using ZLib for compresson, I'm now at 1977 bytes
yes, the pdc is attached to an entity/chunk/world and whenever what it's attached is unloaded the pdc itself is also unloaded
personally i would still use a pointer to a file but this should probably be fine
It's actually very small when stored, and it unloads automatically, and I prefer it that storing in datafolder
but it's just preferences at this state ?
there are still some difficulties with this approach, especially around parsing/saving it asynchronously which can become an issue if there are a lot of these and they have large contents, but for a basic approach this will be fine
π
Does the client send the server information on their FOV? Im just thinking because there is a noticeable difference in how the creaking mob attacks you at 30FOV and 100FOV.
what do you have on your onDisable right now
I believe it does
the player abilities packet seems to send something related to that
creaking does not respect the players FOV
iirc this was reported as a bug and resolved as WAI
Clientbound
I don't think the server has any way of knowing that setting
public Future<Boolean> disconnect() {
return EXECUTOR.submit(() -> {
SOCKET.disconnect();
while(SOCKET.connected()) {}
return true;
});
}```
```java
// onDisable:
try {
Future<Boolean> future = adapterManager.stop(); // -> calls disconnect()
if(future != null) future.get(5, TimeUnit.SECONDS);
}
catch(InterruptedException | ExecutionException | TimeoutException e) {
e.printStackTrace();
}```
Im doing this now which seems to work
it just waits until the socket.connected() variable is set to false
not sure if thats best practice to do it like that but the library doesnt seem to offer a bettter solution
which library is it?
socket.io-client java
as im comunicating with a js service which also uses socket.io
his ass is NOT Thread.onSpinWait()ing and Thread.yield()ing :Sadge:
In the JDK's ExecutorService javadocs, it explains how to drain the executor service in order to await termination
so, if you follow that, it should all work out
