#help-development
1 messages · Page 1342 of 1
surely no issues could come from doing that
My preferred approach which I recommended in the linked thread is to kill the player so their inventory isn't loaded
Or well it is loaded but presumably not going to be interacted with
was about to say, it should still be loaded due to Spigot and derivatives preserving the instance even on death
Wonky soulbound plugins aside that fuck with a dead player's inv, it'd probably be fine
I don't remember if inventory data is written as soon as you modify it
if it is then that kind of plugin can become a bigger issue, if not then just pray and hope someone isn't doing some hacky shit I guess
To disk? I think it's a staggered autosave task defaulting to a few minute interval
then it should be fine
So, simply do this:
AsyncPlayerPreLoginEvent called on any server:
If the player, in this event, is in connected_players (Redis Map), then set the event result to not_allowed and the player will be kicked. The Redis query is done in the same thread as the async_player_pre_login_event to allow setting the result as not_allowed.
Otherwise, add the player to connected_players along with the server ID and fetch the inventory data, etc. (all done in the async_player_pre_login_event thread).
If the playerquitevent is processed and the server ID from which this event is called is the same as the one in Redis, then remove it from the Redis Map in another thread (in a single-thread executor specifically for Redis operations, for example).
This way, I don't block the main thread in playerquitevent, and I have a guarantee that the inventory won't change between server transitions.
Isn't that all that's necessary? I believe having a connected_players Map with the server_id value isn't even necessary; a Redis Set is sufficient
you wouldn't kick on async player pre login, you would kick/kill on player quit event of the previous server if I understood what vcs2 said
otherwise the player would never be able to access the server they're being transferred to
though this assumes you're going with this approach, which well, you'll have to play around to see how safe it is for your server (assuming you don't have anything that relies on this weird behavior by accident)
other than that, the approach sounds fine
I don't understand why I can't kick the player in an async login event. There's a method like async_pre_login_event#setResult(not_allowed) or something similar that prevents the player from logging in
kicking the player from the server they're being transferred to would imply you don't want them to be transferred
So I can have another Set structure called connected_servers that will be atomically updated with connected_players.
Thus, every minute, for example in Velocity, I iterate through all the connected_servers and check if the server in question is offline. If so, then atomically update connected_servers to remove the offline server. To avoid having to iterate through all the connected_players and check if the value matches the offline server, instead I can have a Map<Server_ID, Set<Connected_players> structure in Redis. Obviously, this structure would also be atomically updated with connected_players and connected_servers
The problem with this approach is that checking if the server is offline wouldn't be possible atomically by updating connected_servers and connected_players. I don't know if this is really a problem, probably yes. I have to think about it a bit more to see if it's actually a problem
that shouldn't be necessary given that you would always remove them from connected_players as soon as PlayerQuitEvent is called, which would happen when you transfer them out of the offline server or for other reason
The problem is that if server A crashes, the playerquitevent will not be called, and the connected_players will always contain the player in question
if the server crashes then you have bigger issues
you can probably handle that at the proxy level in that scenario
What I can do is: when the plugin starts, iterate through all connected_players and if the server_id of the connecting server is in the values of the map structure, then remove them from connected_players.
For this, I need to assume that the server starts automatically if the server crashes
This way I avoid having multiple cache structures that need to be updated atomically and performing fetches every minute on the proxy side
I still don't understand the problem xd
Ah, I understand the problem. When a player transfers from server A to server B, the removal of connected_players on server A may not have been processed yet because is done async on player quit event
So yeah, I think that approach isn't valid then
i recommend just going with the existing solution
The current solution has 1001 problems, and I bet that's why
more like, there is no need to work out an already solved problem
HuskSync does it fine
Perhaps a valid approach is to use the Velocity EventTask API for this. When ServerPreConnectEvent is called, check if the player is contained in a Velocity network server (done with the Velocity API). If not, then simply check in Redis if connected_players is contained (a Redis search). If so, then schedule a check in 1 second that verifies if the player is contained in connected_players (Redis operation) and if so, fail the event. The check to see if the player is already on the network or not is to avoid queries in Redis if the player joins the network for the first time, and also to make the player's entry into the server faster.
The 1-second timeout is to give the playerquitevent on the player's old server time to process the removal of connected_players. If it takes more than 1 second, then the player will not be able to switch servers and will remain on the same server (I don't know if additional logic needs to be added to remain on the same server).
I'm only experiencing rollbacks and duplication issues with this plugin
you'd rather find the cause of those and report them rather than developing a new solution that would probably end up having other duplication and rollback issues
This plugin is not actively supported anymore
last commit was just two months ago
Yes, but check out their announcement
that's been merged, hasn't it?
they also have a post on the english fandub of harumi susumiya which sounds random lol
if you're on latest, you can use the default config
where?
im using the latest version but im experiencing rollback/dupe issues yet
are you shutting down servers without /save-all sometimes?
I just do /stop and for me to stop servers, I have to kick all the players
that might be the issue
But that's the least of the problems. The biggest problem is players suffering rollback when players switch between servers
I suggest to open another issue on HuskSync's github
do you have a good way to reproduce it
we have not experienced any dupe bugs since the following thing was merged (gimme a sec to find it):
reproduce what? server shutdown thing or server transfer?
the dupe and/or rollback issues
Unfortunately not, that only happens sometimes
I would start finding out why it happens then
I've already tried, but it's a pattern I still haven't been able to figure out
Add some debug messages and stuff to HuskSync
Is it possible to force a server's TPS to 5?
https://github.com/WiIIiam278/HuskSync/commit/5c4111b6a767f0f04a7ac6e6fc7ac684899f4cf2
This was the PR that fixed dupes for us
latest version already includes that
then I don't know, you'll have to contact the author then
Do you have a plugin to perform a /save-all and then /stop immediately afterwards?
the cleanest way is to have players go through a hub instead of directly jumping from one server to another
no, we're doing restarts via simple bash scripts
Because if I enter /save-all and /stop, some player will edit their inventory between two commands
the good ol' way
yeah we enable maintenance mode beforehand
that way only one backend server has the inventory and data loaded at a time
we usually enable maintenance mode, which means players have 60 seconds to leave the server or get kicked to fallback server. Only after that we do /save-all and then /restart
i see
And why is the save-all necessary? Aren't the players' inventories updated in Redis?
We have disabled auto world saves, so we do that do save block inventories etc
But the server automatically saves by default when it shuts down
otherwise you might get dupes etc if a player takes out an item out of a chest, then husksync saves player inventories, but world might not have been saved yet -> dupe
better be safe then sorry
This is about trusting science now
If the server shuts down, then the save-all will occur
yea maybe it's pointless, but as said - better save than sorry
If the save-all command fails during shutdown, then the save-all command would also fail
that's why we do it beforehand
And the server freezes until it saves successfully?
I'm doing it manually. /whitelist on, kick @a and then I type /stop
This our restart script
#!/bin/bash
set -u
SERVERS=(
# name host save
"proxy-1 delta 0"
"proxy-2 zeta 0"
"proxy-3 sigma 0"
"lobby-1 sigma 0"
"lobby-2 sigma 0"
"lobby-3 sigma 0"
"lobby-4 sigma 0"
"lobby-5 sigma 0"
"cb-1 delta 1"
"cb-1_fw-1 delta 1"
"cb-1_fw-2 delta 1"
"cb-1_fw-3 delta 1"
"cb-1_fw-4 delta 1"
"cb-1_fw-5 delta 1"
"cb-1_fw-6 delta 1"
"cb-2 zeta 1"
"cb-2_fw-1 zeta 1"
"cb-2_fw-2 zeta 1"
"cb-2_fw-3 zeta 1"
"cb-2_fw-4 zeta 1"
"cb-2_fw-5 zeta 1"
"cb-2_fw-6 zeta 1"
"cb-3 kappa 1"
"cb-3_fw-1 kappa 1"
"cb-3_fw-2 kappa 1"
"cb-3_fw-3 kappa 1"
"cb-3_fw-4 kappa 1"
"cb-3_fw-5 kappa 1"
"cb-3_fw-6 kappa 1"
"event-1a gamma 1"
"event-1b gamma 0"
"event-1c gamma 0"
"event-2a gamma 0"
"event-2b gamma 0"
"event-2c gamma 0"
"event-3a kappa 0"
"event-3b kappa 0"
"event-3c kappa 0"
"creative kappa 1"
"vistas_server sigma 0"
)
errcho() {
>&2 echo $@;
}
esleep() {
echo "Waiting $1 s"
sleep $1
}
exec_ssh() {
ssh $1@$2 "source .profile && $3"
}
start_one_server() {
echo "start: $2"
sleep 0.05
exec_ssh mc $1 "cd $2 && ./start.sh || >&2 echo COULDNT START $2"
}
stop_one_server() {
echo "stop: $2"
sleep 0.05
exec_ssh mc $1 "screen -XS $2 quit"
}
save_one_server() {
echo "save-all: $2"
sleep 0.05
exec_ssh mc $1 "screen -XS $2 stuff '\nsave-all\n'"
}
start_all_server() {
for entry in "${SERVERS[@]}"; do
read -r server host save <<< "$entry"
start_one_server $host $server
done
}
clean_all_hosts() {
/home/mc/bin/clean_all_hosts.sh
}
flush_all_redis() {
/home/mc/bin/reset-redis.sh sigma <redacted>
/home/mc/bin/reset-redis.sh delta <redacted>
/home/mc/bin/reset-redis.sh zeta i<redacted>
/home/mc/bin/reset-redis.sh kappa <redacted>
}
stop_all_server() {
# Iteration 1: Save
for (( idx=${#SERVERS[@]}-1 ; idx>=0 ; idx-- )); do
entry=${SERVERS[$idx]}
read -r server host save <<< "$entry"
if [[ $save -eq 1 ]]; then
save_one_server $host $server
fi
done
esleep 3
# Iteration 2: Actual stop
for (( idx=${#SERVERS[@]}-1 ; idx>=0 ; idx-- )); do
entry=${SERVERS[$idx]}
read -r server host save <<< "$entry"
stop_one_server $host $server
done
esleep 3
# Flush Redis
flush_all_redis
clean_all_hosts
}
restart_all_server() {
stop_all_server
esleep 5
start_all_server
}
main() {
case "$action" in
start)
start_all_server
;;
stop)
stop_all_server
;;
restart)
restart_all_server
;;
*)
errcho "Unknown action: $action"
exit 1
esac
}
##############################
action="${1:-}"
if [[ -z "$action" ]]; then
errcho "Missing arguments. Usage: $0 <action>"
exit 2
fi
main $action
And I haven't had any more problems with restarts. The problem now is with rollbacks when players switch between servers
you will have to flush redis
shutdown all servers, then reset redis (FLUSHALL)
then start again
when?
once all servers are shutdown
why
because husksync keeps inventory data in redis
the plugin that should handle this
There's nothing to say about that in their documentation
there is
wait a sec
This page contains a number of common issues when using HuskSync and how you can troubleshoot and resolve them.
But when I restart all the servers, the date that will be in Redis is supposedly the most up-to-date. They probably say this so that memory usage doesn't grow indefinitely
yeah idk, I didnt write husksync. imho it's a pretty shitty plugin
we're only using it because it's "always been there"
I'm just trying to help, not to justify husksync's stupid behaviour
yes i see
Access your MySQL Database using MySQL Workbench or similar. DROP your husksync database, or at the very least DROP ALL husksync tables.
Double check you have done this
This documentation is for resetting the server, not for restarting all servers
you can simply FLUSHALL your redis, unless you're using it for anything else than husksync
But the HuskSync documentation says it's not necessary. However, it's good practice to do this so the memory doesn't grow indefinitely, I'd say
yeah their docs are shit
the whole plugin is shit imho
why do you think I made so many PRs in that repo
You have more scripts than that, right?
of course
like clean_allhosts.sh etc
clean_allhosts only removes plugins that we didnt install through our auto plugin updater
nothing interesting
but flush_all_redis does not solve the rollback issue when players are changing the server
I can't help you with that, if the linked github doesn't help, then you have a different issue than what we had
What I've noticed is that when a player switches servers, their inventory gets rolled back. This happens rarely. It might be related to low server tps
husksync is dead, the author doesnt do shit. he sometimes accepts PRs from strangers, but he hasnt worked on that plugin in ages himself
That's why I was looking into making a sync plugin
If the save-all fails, the script will still shut down the server
I'm going to force the server TPS to 5 and see if the inventory rollback is related to the low server TPS
yes, the rollback/dupe issue has to do with tps
lol
i'll send u a video
https://imgur.com/y1pmJIY @tender shard see this lol
You were right in saying it was the TPS server causing this
that is so sketch
The update to the player's database is likely done asynchronously, and what should happen is that the asynchronous save should occur after the database is fetched from the new server
so as always, a race condition. is the database call synced?
https://pastes.dev/wW9qwfxzIt This is called in the playerquitevent. This should be called after the player has already changed the server
Since the lock is not global (but local), this happens
so the ideal way of doing this is:
- velocity starts transferring player from A -> B
- B fires async prelogin; data can be optimistically prefetched here
- B fires login; velocity starts disconnecting the player from A
- concurrently, B goes through config/play protocol phases, and A fires quitevent and disconnects the player
- A unlocks database row
- B waits on the lock
- B fires player join event; the player loads into the world
the problem is that there is no sane way of doing "B waits on the lock" at that stage that don't block the main thread, without doing weird protocol hacks, like delaying some config phase packets; one subpar but practical solution is to just block for the lock in the join event at LOWEST priority, as in practice, the quit event almost always fires before the join event; but if the origin server crashes mid-quit or there is a networking issue, this can hang the destination server
one thing that is probably tolerable is to put a sane cap of say 50ms on the blocking in the event, and kicking the player if the lock isn't released in time
isnt this where transactions come into play
in a perfect world
yea
unfortunately just about every paradigm under the sky ends up in little pieces all over the floor when it runs into real world constraints in a system not designed for it, like the minecraft server and protocol
I am not sure what I'm supposed to see in that video
I think they're showing the dupe
they keep the item they just threw when changing back and forth between the servers
so they could abuse of lag spikes to cause that, but sounds complicated to reproduce even for players lol
ezpz just never have lag
if you think about it, it's like an automatic SLA
whenever your server starts shitting bricks, players get free stuff as recompensation
@young knoll
?ban @kindred crater Spam bot
Done. That felt good.
those have been increasing lately
you'd think the guys at discord could put together a regex matcher or something after all these years
or if that's not technologically feasible, perhaps hire an AI (Actually Indian) to do string matching instead
I used to do h+e+c+k as a kid and it actually worked if i remember correctly
I didn't know what regex was back then
rollback/dupe happens when server tps is low
What's happening is that the save is done asynchronously when the player quits; if the player leaves server A with the tps on 5, then the scheduling will be 4 times slower and they will go to server B with the tps at 20. The login event on server B is processed 4 times faster than on server A, and therefore the database fetch is performed before the save on server A
My server was experiencing some low TPS spikes due to a memory leak, which I believe I've already resolved
Don't advertise your stuff here
where'd that even come from
and in the dev channel rather than the server admin channel too 🤡
Was the check-in petition used to resolve this error? @tropic knoll
@tender shard SORRY
wrong person
AI ahh plugin
Couldn't even be bothered to fix the unhandled color codes in the preview images
fucking lol
the preview image of the config having butchered ass text 😭
how does that even happen
mfw &c[ViperAuth]
⚡ Optimized TPS
send me the source code and give me $25 and i'll perform an Independent Assessment & Certification of your codebase (normally priced at $75 but as a promising first time customer i'll give you a discount)
you can put the certificate next to the mangled chat screenshots
You're the goat
check-in-petition=true solve this yea
You can block B at the prelogin
no?
or after prelogin fires but before join fires on the netty thread or something
I don't recall the exact protocol but the client should signal it's done receiving chunks or something
no; blocking on prelogin or anything before login, causes the player to never disconnect from the origin server
velocity maintains both connections until the login protocol phase completes
so you must block in either play or config; blocking play will block the main thread, since that's where those packets are processed, and there are no events by which you can block in config
this is so that velocity can print login phase disconnect messages, e.g. "you're not whitelisted on this server", in chat while the player is still on the origin server, without disconnecting them from the whole network
in other words until velocity is sure that the player can actually join the destination server, it won't disconnect from the origin server
isn't there that one velocity plugin that keeps connections alive and "reconnects" people
what if you disconnect in the backend, use velocity to keep the connection alive
block the other connection
Or you can make your transfer command / event listener trigger a manual save instead of tying it all to the quit event
use a distributed lock and yeet the player
velocity kinda sorta does this or something similar to this built in; if you get kicked from a backend, it will keep the connection alive and try connecting you to a fallback server
but it's kind of ass because to use this, you always have to kick the player when they want to change servers
doing it with a velocity plugin like you mentioned might work better, definitely worth a try
though what i ended up with was using protocollib to delay config phase packets to "block" on waiting for the database row to be unlocked
anyway husksync is working - just need enable the check-in-petition option
this is husksync solution:
// Another server is saving the player's data after they've logged out - we'll try fetching the data in a little while
if (server.isPresent() && !server.get().equals(plugin.getServerName())) {
if (plugin.getSettings().getSynchronization().isCheckinPetitions()) {
getRedis().petitionServerCheckin(server.get(), user);
}
return false;
}
If the method returns false, the lambda code will occur in next tick (with the default configuration) with a maximum of 18 attempts. If Redis is offline during server transitions, then rollbacks/dupes will occur
and checkinpetitions need be true
the problem with this is that while you might save all the data before the quit event manually, other plugins are very liable to modify the data on quit event, and the data goes out of sync
suppose e.g. a transient item that gets deleted from your inventory when you quit; the plugin will remove it on quit, but you've already saved the inventory before quit
when the player returns, the deleted item reappears
the converse is sort of true with what husksync does, except that window occurs on the destination server; premature access to the inventory or other data might cause those modifications to be lost or for you to read stale data, if you access it before the server receives the data saved/sent by the origin server
husksync tries to get around this by listening to and blocking typical player interactions that'd access the data, e.g. inventory interactions
but other plugins must explicitly check for and respect whether the data is ready to be accessed, so you end up with your entire tech stack depending on husksync
yeah, that PR about the checking petitions did fix all our dupe issues
we only got 2 problems left with husksync:
- map sync is random (doesn't really work)
- admin commands such as /inventory may cause inventory desyncs if that person is online on another server
we had like 3 other issues but I've fixed them myself through PRs to HuskSync's repo
the authors seems to be doing nothing, we're glad he's still accepting PRs so we at least don't have to maintain a fork
but u enabled the option right?
They're telling me to disable the option, I don't know why
https://imgur.com/a/cCNElmA see: check-in-petition= true solve the problem
yea then make sense now
For some reason they tell you to leave the option disabled
who says that?
but it was fixed
the main issue was when switching servers with different TPS, e.g. going from a 5 tps server to a 20 tps server
which happens to us once a month when we got 500 players
but since that "checkin petition" thing got merged, this has never happened again
so I suggest that you use the default config, having checkin petitions enabled
default config have this option disabled idk why
and they are talking to disable the option that's why i dont understand
enable it
With check-in petitions, this happens:
Player leaves server A -> disassociates the player from server A in Redis -> as soon as the disassociation is done, it is saved in the database -> Player enters server B -> checks if there is any associated server (if server A has TPS=5, then it will probably say yes) --> if there is an associated server, then it checks if the associated server is different from server B (in this case, yes, because the associated server is A), then it sends a petition message to the associated server (in this case, A), and server A, as soon as it receives this message, disassociates the player if the player is offline and unlocked (I don't understand why there's this additional message logic) -> as soon as server A disassociates the player, server B, since it is constantly checking if the player is disassociated, as soon as they are disassociated, associates the player with server B and fetches the database as soon as the association is made. (Server B constantly checks for up to 18 attempts and by default keeps trying every tick)
The disassociation is done as soon as the save to the database is performed in the player quit. I don't understand the reason for this message additional logic
well you do you. All I know is that, since we merged that PR in our own fork, no dupe/item loss has ever been reported again
Yes, there are indeed no dupes/rollbacks in the flow, but there is redundancy
https://imgur.com/a/9sM8G7S The code inside the red square is redundant and can be removed
checks for up to 18 attempts and by default keeps trying every tick
this is exactly what i was talking about earlier
that's an 18 tick time window where all reads and writes to the local data will be wrong/overwritten
For this to happen, Redis needs to be offline during the transition or very slow
But Redis being slow is much less likely than the server TPS be low
Bruh its called self lose by self mistake
In other words, the check-in-petition option is useless. The duplicate was happening because the server-id was the same on both servers 🤡
doesn't matter, what matters is that it can still happen
Yes, of course, but for now I'm fine with it
If I have a class with a variable that has a Block, will the world associated with that block be deleted in the gc?
public class CraftBlock implements Block {
private final net.minecraft.world.level.LevelAccessor world;
private final BlockPos position;
private CraftBlock(LevelAccessor world, BlockPos position) {
this.world = world;
this.position = position.immutable();
}
it's a strong reference
are you trying to diagnose another memory leak? the heap dump allows you to find the ref path from an object to gc roots; you don't need to guesstimate or xy ask here
Shi bro, after the Intro to OOP 3 credit course in college
the way i look at java code is completely different
life changing,
college courses are actually useful
does anyone know any plugins that can regenerate big arenas automatically and remove player placed blocks for free that works on 1.21.11?
i need help so bad about this
I think I see what you mean about file permissions.
I used my other computer to run buildtools, copied the the output file over to my main, ran diffoscope on it and got this output.
I'm not 100% certain which line represents which file, but my best guess is that the red text is the first jar and the green text is the second jar.
In which case, this would be the jar I build on my main pc (red), and the jar I build on my second one (green)
From what I can tell, this is actually really good/close to working as intended. Because there is nothing else from the output suggesting that anything else within these files are different.
Granted, this is on two linux systems. (Linux Mint 22.2 & Zorin OS 17)
Not sure how windows would be differ (if at all)
yea
I saw that the heapdump and offline craftplayers were in GC Roots because of Block - I just confirmed it here
Looks like <dependencySet> in assembly.xml also supports fileMode which should fix that
https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/src/assembly/bootstrap.xml
I think we just gotta add fileMode to everything
we really need ssh equivalent of minecraft's rcon
what
what can you recommend to contain data? I need to log info about ores that players breaking. I think JSON and XML are too bad for this. SQLite with local .db files, I think, the best variant
Just tested that theory and I have matching hashes.
Now, this is fantastic, but I still wonder if there is any variance in Windows enviornments.
Then we might have another issue with Java variants. (OpenJDK, Temurin, Oracle, etc)
But, I'm still pretty happy with the progress right now.
XML?
sure, SQLite would fit the usecase. in the end it's up to you, what you want to use. Best you can do is modularize your architecture, so you have the input layer, a cache layer and an persistence layer. With that you can later swap the persistence impl if you found something better without breaking your whole architecture
oh, thats my first plugin so i dont know about all these layers
thanks
Is it possible to view the Spark Heap summary to see if there are more Craftplayer instances than online ones?
idk but you shouldnt be storing players as an object anyways
by taking a heapdump and analysing it, sure
just throw it at the promptitute and ask it to read it for you
the summary should probably show it, but you'll have to scroll down quite far since there will be so few of those objects
i don't remember off the top of my head if there's a search bar
knowing spark there probably isn't or it doesn't work
The problem is that there's no Ctrl+F
i'll need use heap dump yea
It's not my plugin with the memo leak
it is huskhomes
@tender shard you are using huskhomes?
oof
lol
no its donald trump white homes
Is there a way to stop the totem pop sound?
Yes, probably by intercepting the sound packet
Yeah did it by stopping the sound at the PLAYERS sound category
I think you can check for specific sound so it doesn't mess up other sounds
getAge() of an adult ageable shouldn't be zero, right?
dont babies have negative age, and then zero means its an adult
I forgot this was a minecraft discord and was very confused at first
yeah i was o
confused at first too xD
is it "intended" that the InventoryClickEvent#action seems to completely malfunction for any events in the creative inventory (no matter the view)?
It seems to somehow categorize anything (really) as PLACE_ALL
*getAction, kotlin destroyed my brain
Creative does what Creative wants
There’s a specific event for Creative Inventory stuff though
Creative does what Creative wants 🤷🏽♂️ and yeah.
meh
anyone know how World.getBlockAt() can load server if use it on unloaded chunks?
or there are no difference between loaded and unloaded chunks?
Are you asking why it loads the chunk?
getBlockAt() on an unloaded chunk will load it synchronously i think?? blocking main thread
idk what u mean "how", how it works?
just guard with isChunkLoaded
that will take a chunk tho, u can do location.getBlockX() >> 4 to get the chunk from an X
no, will it load the chunk
I want to use this method but I don't know how much load it will put on the server if it loads chunks when trying to get a block from an unloaded one
if (world.isChunkLoaded(blockX >> 4, blockZ >> 4)) {
Block block = world.getBlockAt(x, y, z);
}
i dont think us spigoters get async loaders like paper
also @winter viper do you plan to modify it, or do you just want to know what it IS? You can use ChunkSnapshots which are thread-safe (if you ARENT planning on modifying it) https://hub.spigotmc.org/javadocs/spigot/org/bukkit/ChunkSnapshot.html
declaration: package: org.bukkit, interface: ChunkSnapshot
oh thank you
ok ill check it
Iirc it might also not until he calls any functions on the block, cause it’s a glorified wrapper. Can’t recall though
ur right, i think CraftBlock is just a BlockPosition right????
but again, i cant imagine calling the getBlockAt, and then doing nothing with it.
The minute u call getType or anything its gonna access the chunk, its just a matter of when, so the guard is still needed, and the chunk will need to be loaded synchronously, again, just a matter of when rather if.
i need just get block type at coordinates and put it in db
so there are will be better to use chunksnapshot?
Hey guys, I'm trying to create a "care package" dropping from the sky (invisible armor stand with a chest as helmet), and it has a parachute of chickens, connected to the armorstand with leads, but I can't seem to get the connection right. The leads should be connected to the chest, instead of currently being connected to like the side of the armor stand.. I cant send an image to clarify, but if anyone has any ideas how I can make it look clean lmk
yessir
guard it still
thanks
Send an image, with either imgur or verify your account
code?
my velocity have this memory usage:
Memory(process)
1.2 GB
/
4 GB
29.19%
why is the velocity using 2.7 gbs swap? I'm on linux
creating a chunk snapshot to access a single block is extreme overkill and still has to be done sync; not only does it not help in any way, it is much slower
chunk snapshots are useful when you have to look at hundreds or thousands of blocks in bulk or have complex, expensive logic happening in between your block checks, which you want to do off the main thread
e.g. matching large structures to the world, or checking if a spot is a valid spot for a structure to be generated at
to clarify, the snapshot itself is thread safe to access, but creating it still requires syncing to main; so it is not at all an async substitute for World::getBlockAt
OK, I have a data pack that includes a scoreboard on the side bar. But whenever I have a certain plug-in on that I need for my server the sidebar disappears. I need help figuring out how to keep the plug-in, but actually be able to see the scoreboard for the data pack.
this should work no?
arraycopy doesn't like it when i give the second component as Jpanel
even if i know for a fact what elements there's in the panel
actually wait
might not be safe
there's a getparent
that'd only work if components contains only jpanels
Throws:
ArrayStoreException - if an element in the src array could not be stored into the dest array because of a type mismatch.
yo guys, any way to not show a wither's shield particle when its health is >= 50% (spigot 1.8.8)? its for a countdown bossbar
i just put the wither really far
location.getDirection().multiply(60)
or wait
can you just set a very small size to the wither?
what's the behaviour to the shield if the size approaches 0?
its still noticable even from a distance tho, also when a player looks down the bossbar dissapears
hmm that might be a good idea no idea if its possible tho
yeah I already got it, was just wondering how to remove the shield etc
since on hypixel it doesnt show so I guess there's a way to completly hide it but idk
yes
i think it's this
r(500); if small wither
either 1000 or 10 is small
make sure to send the datawatcher
i'm making a custom gui and going into a slot a highlight appears, is there any way to disable it? i'm on 1.21.10
i assume it can be done via resource pack
a highlight? like a tooltip of the filler item, or clientside hover effect?
Yea i got it, but i meant the hover effect on a slot
If I have an Entity instance where the chunk it's in has been unloaded and loaded, does Entity#isValid still return true?
I doubt it
which client version do you guys think i should use for these options?
i was thinking http/1.1
it should support more servers this way no?
should I use bukkit#getEntity right
and check if is not null
@sullen marlin I'm still looking into the reproducibility stuff and I've found that there is consistency between java vendors within the operating systems, but not across them. (Both Linux & Windows with the <fileMode> changes)
This is good since it's one less variable, but I actually think that maven is what's controlling most of the factors here.
The diffoscope output between linux and windows had much more this time, but the differences between the two are, from what I can tell, small inconsistencies.
First being a small 53 byte difference between the jar files themselves. There's also bunch of stuff at the end of the comparisons that just shouldn't be there.
I don't know how far you got initially, or if you even came to this conclusion already, but this seems to point towards OS specific line endings being another contributing factor. (LF vs CRLF)
This makes some sense because the compilation is done on the end user's machine which might pull in/auto format to the OS specific line ending. (At least on windows that is)
I'm trying to look into how we can make maven enforce one specific type, at least to test, but I'm coming up short at the moment.
I never tried different OSs
but looks like line endings is an issue
https://hakanozbay.github.io/2017/02/15/maven-assembly-line-ending.html
looks like a line ending option for the .list files?
Another Software Engineering blog. Sharing my experiences to help others.
@sullen marlin I have matching hashes across operating systems now.
There is some stuff to consider with these specific changes.
- The
<project.build.outputTimestamp>flag needs to be set for this to work correctly.- Currently, this variable is used to set the Vendor name so that CraftBukkit can read it for the outdated check it does. (Still don't fully understand why it is the way it is btw)
- A different flag should be found and used if at all possible.
- Setting this to the maven wiki example (
2023-01-01T00:00:00Z) will cause spigot to not load. (Unless you have the IReallyKnow flag set)- This is due to CraftBukkit reading this and expecting it to be an integer. Setting the value to 1 let's spigot load as expected.
- This flag should be set dynamically somehow. I would assume this needs to be done through the jenkins pipeline.
- Currently, this variable is used to set the Vendor name so that CraftBukkit can read it for the outdated check it does. (Still don't fully understand why it is the way it is btw)
- Automated testing for each build would need to be figured out.
- Also assuming that this would be done in jenkins, as I don't think we would want to include diffoscope as a dependency for BuildTools.
- I have no idea if maven profiles are affected by this.
My testing still shows that OpenJDK, Azul/Zulu, & Oracle JDKs will produce the same hashes. (This likely extends to other vendors)
I also have no idea how to push these would be changes to stash. I am extremely confused on how that works for spigot itself.
<assembly
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">
<id>x</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<fileSets>
<fileSet>
<directory>../../deploy/script/linux_x86</directory>
<outputDirectory>${project.version}/bin</outputDirectory>
<fileMode>0755</fileMode>
<!-- Options are "keep" - Preserve all line endings
"unix" - Use Unix-style line endings (i.e. "\n")
"lf" - Use a single line-feed line endings (i.e. "\n")
"dos" - Use DOS-/Windows-style line endings (i.e. "\r\n")
"windows" - Use DOS-/Windows-style line endings (i.e. "\r\n")
"crlf" - Use carriage-return, line-feed line endings (i.e. "\r\n") -->
<lineEnding>unix</lineEnding>
</fileSet>
</fileSets>
to fix line endings of files
dm for custom plugins
?services
If you wish to request or offer development/art/building/administration services, please do so at https://www.spigotmc.org/forums/services-recruitment-v2.54/
Not sure your point about timestamps is right, scriptus already sets timestamps based on git hash and they're definitely static in all the diffs both you and I have done
Just removed the flag and the compilation shows no differences. My bad, I guess I put too much emphasis on that part. I had just gotten matching hashes working when I sent that message and had those timestamps set.
I wasn't aware that scriptus was actually setting the timestamp. :p
no, of course I don't
When LivingEntity#getEquipment can return null?
i think it returns null for entities that don't support equipment, like cows and such
oh i see
cow armor when?
All LivingEntities support equipment
Most just don’t render it
if (entity instanceof Mob || entity instanceof ArmorStand || entity instanceof Mannequin) {
equipment = new CraftEntityEquipment(this);
}```
I don’t think any vanilla entities will fail that if statement
Okay players fail it but they have a different override for getEquipment anyway
no
having an ups is so cool
made a http json api thats kind of a wrapper of snmp data.. a plugin that checks the api and can read the whole ups data.. one of the coolest things is it can read the ups state and can say like "Lost electricity. Running on battery" in the game.. can send a warning and stuff XD if theres no electricity
Wait is an correct there
i dont know
then?
i imagine its made by the same person who made husksync and both are open source so you can just check the github or any of its plugin pages
An is indeed wrong
if we say UPS it must be "a UPS"
but if we say Uninterrupted Power Supply then we must use "an Uninterrupted Power Supply"
cuz UPS starts with yoo sound like university
we say a university not an university
So the yoo sound isn’t a vowel sound
Yea
It has to be a uhh sound
English moment
smn like that
i studied ts when i was in 5th std
they made us remember how words sound
based on phoenetics
looks? like near the end of the tick
eh doesnt actually matter for what im using this info for
Uh i dont think its something you can reliable determine
what do u mean, like across versions?
my question ended up being pretty irrelevant for my use, since one way or another, ill get the data i need
(im just crudely calculating mspt using a repeating 0 delay synchronous task)
(API for exposing TPS data when??)
Interesting
IP leaked!!!!1
:(
im gonna ddos that ip so hard you wont even see it coming
you can't really calculate mspt from the tps since the tps is clamped to 20, while mspt isn't
and the reason why we prefer mspt over tps is specifically that it's not clamped
on paper, you could compute it from the tick start vs tick end event, but on paper you also just have a getter for it
on spigot you might be able to hack something together by finding out some event that runs at tick start, and then use the scheduler for the tick end
although now that i think about it, i don't remember if scheduler tasks run at the start or the end of the tick
i want to say end because that'd make more sense for "0 delay" tasks that get scheduled and executed in the same tick, but god only knows
yeah im doing it backwards, calculating TPS from MSPT, where TPS = MIN(1000.0 / MSPT, ServerTickManager#getTickRate())
me calling it MSPT is misleading though, as it is the time between ticks (+ the time a tick spends), rather than just the time of a tick itself
MIN only to avoid the visual "error" where TPS may exceed the target tick rate due to a time delta of <1000.0 / ServerTickManager#getTickRate()ms (or else i may see something like 20.04 or some other odd value)
good enough for me
sadge
its just visual flair anyway so the accuracy of it doesnt have to be super high, im not using this calculation for anything critical
it just has to look "correct enough"
EntityRemoveFromWorldEvent is not called when a world unloads? (for the loaded entities)
sure should
And with the Entities Load Event, can I be sure that they will all be in the same chunk?
Or the list of entities in that event may be in different chunks
i mean, not if i go and modify the region files manually before loading the world again
like, generally yeah but there are no guarantees about that stuff
One more thing: For some reason, when I teleport to a chunk in the world, entitiesloadevent and entityremovefromworld are called multiple times
once per chunk, once per entity, respectively
i feel like we're having this conversation every week now
and have had for months
just let natural selection do its thing
Doesn’t work for spigot devs
oh yeah because he's developing for spigot
I mean they are developing for Paper
They're just already banned in the paper discord
also this 💀
What if there was tho?
what are u waiting for? get scribing 📜
atp spigot should just Steal events from paper lowkirkenuinely
@mortal vortex write these PRs for me
no need to write them or steal them
choco already has pr's for all of them and all of them are in ice and limbo forever
test
weird
i can message some people and some people i cant.. 50 50.. russian roulette
yeah putler is currently in the discord datacenters pulling random ethernet cables so that the ookranians don't organize to nuke his victory parade tomorrow
yea
Yes mommy :c
they're in 🧊 custody?!
Now my local matches Jenkins
probably just need to fix line endings now for cross platform support
that's fun
file permissions will never not bite me in the ass when it comes to reproducible builds
Now for the hard part.
does anyone know a koth plugin that has inbuilt option to add boss fights in the koth snd stuff like that i mean i want warzone events that i can add to different different warzones that im adding in my server, but im unable to find a suitable plugin for it, anyone knows any plugin pls tell
guys, i cooked up, i made an amazing login backend
waow
So, is the entities loadevent called for the same entity multiple times?
no
This is what's happening
I'm using player#teleportAsync for a chunk containing entity X, and EntitiesLoadEvent and EntityRemoveFromWorldEvent are called multiple times for entity X
teleportAsync is paper API, you'll have to ask on paper's discord
im banned there xd
maybe show your code
Okay, but if you use paper and if u know why this happens maybe someone here could help
everyone uses paper so yea
i use spigot :-(
The code won't help at all ig
I literally only do that
print out the stacktrace in the respective events
then you'll know why that event is called / where it's called from
e.g. just do new Exception().printStackTrace()
alr
I think the EntitiesLoadEvent is called multiple times because the chunk state constantly changes during chunk loading
idk, never happened to me
oh thats a cursed way of doing that, i love it
how would you do it lol
well i probably wouldnt bc im stupid
I use that very often when I don't know why the heck something is happening
yewa this is smart lol
i once tried to use Reflection.getCallerClass or whatever the method is for something
This doesn't cause me any problems either, but I'm doing unnecessary database fetches this way
but java didnt like that i was trying to use a sun class
i just wanted to be cool and do the same stuff jre internals do :-(
internals are cursed
yeah
oh god I just found my "basics" project again https://github.com/SpigotBasics/basics/tree/main
some day I'll finish that
already 2 years ago, felt like yesterday
oh hey i contributed to that
everyone contributed except @rotund ravine
Does anyone wanna contribute to bot creator? Noone? Alright 🥹
Oh, this is sort of like essentials
yeah but modular and with only 4% of Essentials's features
it was my project to start learning kotlin and gradle
thx
What's that?
You can use bots to test your server
Ahhh i was wondering when i’d get pinged for that again
Is it possible to spawn an entity with a predefined UUID?
that sounds like flawed design
I have a database with minions where the entities have UUIDs. Now the entities are persistent (before they weren't) and I need to add all the entities to my worlds that are in my database. To do this, I need to generate an entity with the UUID that is in my database
If that's not possible, then I'll have to update the UUID entity that's in my database
If the entities are persistent why are you trying to spawn them again
That will just cause there to be multiple of them
besides even if they weren't persistent it's still a bad design
(before they weren't)
still bad design
why?
The possible options are: persistent or non-persistent. If persistent is bad design and non-persistent is bad design, what do you do?
That's not what we were saying
Your way of storing data and trying to force a uuid on an entity is a flawed design
Persistent or non-persistent both options are fine as long as they're handled well
This will only be done once in the onenable to create the world entities from the data in the database
That would require loading all the chunks that your entities are stored in
I know that. Is that bad design?
Ideally you'd migrate things as needed
because too many chunks being loaded and such will take too long
I'm just trying to update the world state with the information in my database - I just wanted to know if it was possible to create an entity with a UUID to avoid writing additional code - that's all
It is possible just a bad idea
i don't have many minions
The problem here will be loading multiple worlds because I use one world per player, not the number of chunks themselves
But I iterate through all the worlds, and when I finish iterating through one world, I unload it before iterate on to the next
So I don't think it will run out of memory
If you really want to do it that way just update the uuid in the database
I can have rows in the database and not have the entity in the world
Ah, yes, I update the database with the new entity uuid
I'm listening to EntitiesLoadEvent, and for each entity that is a minion, I query the database to load the minion cache. Since EntitiesLoadEvent is called for the same entity multiple times during chunk loading, I need to create logic that, for example, schedules a task to be executed in 1 second for each entity in EntitiesLoadEvent, and then uses map#put(entityId, taskId) (to track the last taskid associated with the entityid). If the associated taskid is in the map, then performs the scheduler task, and then loads the database to update the Bukkit minion cache if the entity is still valid?
This is simply to avoid creating multiple database fetches multiple times, since this event is called multiple times for the same entity during chunk loading
should I do this?
sure, that is generally known as debouncing
in this case i'll do that:
check if there's a completablefuture in my future cache, return the result of that if it is
if none of thos exist, create a future and add it to the future map
im making an antenna and i wanna check if im in reach of it
how do you check how far away you are from the block? and if theres anything in between?
Ray trace
man
cant wait to get my antenna plugin fully running. im making repeaters now. so that in tunnels there will be signal repeaters
😮
and system will keep track of minecarts in the tunnels where they are and display them on a map
have to make an image api on my web server so i can use image to map plugin api
that will be sick
I love having tech stuff in minecraft
How can I access the task ID within the lambda of a scheduled task?
?scheduling
The problem with this is that if I replace the () with task, the method then doesn't return the taskid (I need to access the task id both inside and outside the task)
I would like to do that
but line 81 have an error
this way I need create a class for that
you can put it in an existing class
you could make the first scheduler an annymous class that holds the task of the second
In the current class I can't because it's a Listener and I can't share the same instance for different entity IDs
if you want that either
the listener does accept a custom constructor
you could inject a class that takes a task id
and use that
can u give me an example?
it's too much to write
but imagine this
in your listener
you make a constructor
and pass an object
in that object you then do something like object.setTask(Task);
and you can also reuse that elsewhere
to cancel it on server stop for example
In this way, the object instance will be shared by all entities
yes
That's not what I want
I think this is the only way
final int[] taskIdHolder = new int[1];
taskIdHolder[0] = Bukkit.getScheduler().runTaskLater(plugin, () -> {
int taskId = taskIdHolder[0]; // acessível aqui
plugin.getLogger().info("taskId = " + taskId);
}, 20L).getTaskId();
if you want a local variable this works too
use bukkitrunnable
any time you see weird array wrappers for mutable inline variables like this in a bukkit task, you probably want to use bukkitrunnable
chatgpt peak
is there a way to set a textComponent as a header / footer of a tablist? Im trying to use custom fonts but the #setPlayerListHeader method for example doesn't let me parsing them.
i've see that here and called it out more than once
how can i do the code above with this?
i have no idea what you're doing or trying to do
int taskId = new BukkitRunnable() {
@Override
public void run() {
}
}.runTaskLater(plugin, 20).getTaskId();
how can I get the taskId inside @run
i need an array yet
Just read the wiki page I linked...
You gotta use the consumer way of scheduling the task
personally i'd make the taskid a field on the class and assign it from this.runTaskLater in the constructor
that said i'm not sure what you need the task id for since you already have the runnable itself
how
ugh I havent used java in ages, but sh like that I guess? Bukkit.getScheduler().runTask(plugin, (myTask) -> { ...
and then you can do myTask.cancel() or whatever
this method is Void type
correct
and I need access the task Id outside too
why?
because i need lol
why?
https://pastes.dev/kT7bg1prtT here is the code
I'm listening to EntitiesLoadEvent, and for each entity that is a minion, I query the database to load the minion cache. Since EntitiesLoadEvent is called for the same entity multiple times during chunk loading, I need to create logic that, for example, schedules a task to be executed in 1 second for each entity in EntitiesLoadEvent, and then uses map#put(entityId, taskId) (to track the last taskid associated with the entityid). If the associated taskid is in the map, then performs the scheduler task, and then loads the database to update the Bukkit minion cache if the entity is still valid
you can keep a reference to the callback inside the callback itself, if you really need to
can you give me a example code?
ScheduledTask myRememberedTask = null;
Bukkit.getScheduler().runTask(plugin, (myTask) -> { ...
myRembembered Task = myTask;
...
sth like this
i'd use a uuid -> completablefuture map
makes little sense though normally
this will not works
myRememberedTask will be null until the task is executed
for what
correct but it will never be executed immedietaly
otherwise it wouldn't be a task
yk
I need to access myRememberedTask immediately after the task is scheduled, and in 100% of cases this happens before the task is actually executed
why do you need that?
read this code: https://pastes.dev/kT7bg1prtT
No, tell me
see the line 106
^^
use a completable future instead of messing with this task nonsense
your whole logic is flawed if you rely upon both the actually scheduled task, and the ID assigned by the scheduler
I don't understand how ur solution works
trying to jerryrig the bukkit scheduler to do some sort of async data dependency stuff and callbacks from a database is an exercise in futility'
wdy,m
erm hard to explain, lemme think
If it's what I'm thinking, then it doesn't work
you are trying to code some kind of hypixel-like minion thing? right?
yes
entityloadevent -> fetch db and load the minion cache
entityremoveevent -> remove from minion cache
the problem is:
entityloadevent is called multiple times on the chunk loading
and i want avoid many useless database fetches
okay so you should either have
- one runnable per minion, OR
- one global runnable that iterates over all existing minions
Which option are you currently doing?
then you only have to schedule ONE runnable ONCE
and you never have to worry about its task id
wdym
just make some task that does sth like this:
for (Minion minion : allMyMinions) {
// do stuff
}
and run that e.g. idk once per second
i have this
ok so what's the issue?
I don't understand where you're going with this
^^
^^
I have no clue how those two problems would even remotely have sth in common
read this
Keep a Map<Location,MyMinionStuff> in memory
the only way i can make sense of it is that he wants to collect all the entities in the loaded chunk and then do a bulk db query for them all, rather than one query per
not sure though
no no
especially since the entities load event fires on a per chunk basis and already has all the entities in the chunk
Have you read this????
EntitiesLoadEvent definitely does not fire 1000 times on latest paper, nor does it do on latest Spigot
they do
no
u alr debugged?
It should be once per chunk load
i don't see what that has to do with task id's
exactly
EntityAddedToWorldEvent or whatever it is might fire a lot more
but is not
and yes, it should be once per chunk load, not multiple times
are you sure you're instrumenting it properly
show your code
@EventHandler
public void onEntitiesLoad(EntitiesLoadEvent event) {
List<Entity> entities = event.getEntities();
minionController.onMinionLoad(entities);
}
Add my suggested way of debugging at the top of the event
E.g. simply printout "listener called" or better, create an exception and print out the stacktrace
you'll see that it will NOT be called multiple times
“Oops I accidentally have a task running that loads and unloads 50 chunks every tick”
bc i alr removed
yeah probably sth like that
@EventHandler
public void onEntitiesLoad(EntitiesLoadEvent event) {
List<Entity> entities = event.getEntities();
minionController.onMinionLoad(entities);
try {
throw new RuntimeException("test");
} catch (Exception e) {
BukkitMinionPlugin.INSTANCE.getLogger().log(Level.INFO, "exception occurred on EntitiesLoadEvent", e);
}
}
if I have this, can I see what's causing the event call?
yes
But won't it always be paper?
but you can also just do new Exception().printStackTrace()
it is true that having tasks like this, accessing chunks and triggered by chunk loads or unloads, can result in infinite loops where the chunk loads, schedules the task, unloads, and then gets loaded again by the task, rinse and repeat
well yes ofc
myes
then how this will be help me?
we don't believe what you're saying, basically
My Minion Tick Loop won't load chunks if the chunk is unloaded
.....
this will help you by proving what you're saying is happening is happening
by checking out the other lines that are not paper related
or alternatively by finding out the issue that is causing it to appear as if it's called multiple times
I still claim that the event is not called multiple times by the server software; they are causing this themselves. probably by loading a chunk themselves in the chunk load event
well my minions plugin does not use chunkloadevent. my other plugins i dont think so too
yes im starting the server
@Override
public void onMinionLoad(List<Entity> entities) {
for (Entity entity : entities) {
String customName = entity.getCustomName();
if (customName == null || !customName.contains(KeyConstants.MINION_ENTITY)) {
continue;
}
if (entity.getType() != EntityType.ARMOR_STAND) {
continue;
}
UUID entityUuid = entity.getUniqueId();
new Exception("Entity Uuid: " + entityUuid).printStackTrace();
i added the exception here
Oh boy using entity name for identification
no....
please print the stack trace at the top of the event handler
not somewhere convuluted inside your existing flawed logic
what should I use?
PDC
this plugin is 1.8-1.21
this way we ll dont know if the event is being called multiple times to the same entity
1.8?
I'm running 1.21
like this?
@EventHandler
public void onEntitiesLoad(EntitiesLoadEvent event) {
new Exception().printStackTrace();
List<Entity> entities = event.getEntities();
minionController.onMinionLoad(entities);
}
Yep
Oh wait without the PDC patches the game doesn’t even save custom nbt data on entities so that wouldn’t work
wdym? It still doesn't do that for everything
e.g. tile entities
(unless I'm wrong)
IIRC you can write to a chest's PDC but it'll be gone upon chunk unload / reload
yeah but the holder isn't
Well no, but why would you be using the holder
you're calling the event yourself by accessing the chunk in the EntitiesLoedEvent, it seems
you must not access the chunk in EntitiesLoadEvent because the chunk might not be loaded at that point
if however you decide to access it at that point, you force load it, causing the EntitiesLoadEvent to be called again
(I think - might be wrong)
Please show your EntityChunkModernListener class
I don't see where in those stack traces it is the plugin causing a sync chunk load?
idk but some stacktraces are longer than others
Even if a plugin causes chunk loading, won't only paper appear in the stack trace?
so we can conclude that the server software is causing the EntitiesLoadEvent to be called multiple times for the same entity during chunk loading
they don't change this
we can test this on paper too if u want
I'm banned on paper
But we can test this on spigot too
🤡
sure but coming to the spigot discord saying "this happens in paper too" isn't exactly what here is for
In my mind, entitiesLoadEvent wasn't even from Spigot, but then I saw that it is
How many chunks are actually being loaded
And how many times is the event being called
anyway, nothing in that paste shows it's happening for one singular chunk, but that is a known "issue", however, and as you mentioned before, the unload event is called as well
https://github.com/PaperMC/Paper/issues/9581
you really just need some minimal debouncing logic, nothing crazy
yes unload event is called too
yes! i did
I just wanted to do this debug because I was almost killed here for being accused of messing things up
I'm gonna go out on a limb and say that's a slight exaggeration lol
That issue doesn’t mention the EntitiesLoadEvent
Well i tested myself
the idea is the same
see: the event is being called 3 times for the same entity on the chunk loading
definitely not
That implies the game is loading, unloading, loading, unloading, and loading the chunk
Either that or the event is being called from places it shouldn’t be
should I use EntitiesLoadEvent or EntityAddToWorldEvent?
they do different things
what is the difference?
look up the previous 30 conversations about that exact question
that you yourself had
I think i just asked the difference between EntitiesLoadEvent and ChunkLoadEvent + event#getChunk#getEntities
one for all entities in a chunk load, one for any individual entity being added for any reason, chunk load or natural mob spawning or dropping an item etc etc
you should write that down on a notebook
I will lol
entitiesloadevent does not include natural mob spawning etc? entitiesloadevent just include chunk load?
but well. I think my logic is well done then https://pastes.dev/kT7bg1prtT
correct
Hello guys
I'm facing a issue with geyser mc can anyone help me ?
I'm getting end of the stream issue
With the API?
show your code
I’m using a setup with Geyser, Floodgate, JPremium, and a Velocity proxy for cracked + premium support and Bedrock crossplay.
The issue is that Java players can join normally, but Bedrock players joining through Geyser/Floodgate receive an “End of Stream” error during login. Online mode is currently set to false on both the Velocity proxy and all backend servers. Geyser is only installed on the proxy side, not on backend servers.
I want help identifying what configuration conflict or authentication issue could be causing Bedrock players to disconnect with the “End of Stream” error.
Okay so you aren't developing a plugin?
Maybe ask the developer(s) of the plugin.
Ahh ok
how heavy can it be for the server to make per player world system? but limited to eg 4000x4000
and for eg. 50 players?
same system like skyblock but the actual world, with worldborder set at 4000x4000, fully loaded on request via a command?
Like a virtual world?
Or like an actual world per player
chat how does this perf metric look so far
TPS is updated once per second, MSPT is updated every tick (to explain visual discrepancies)
me 2
what do you mean by virtual world?
an actual world
What happened to org.bukkit.Server.getMinecraftVersion()? I see several people have discussed its absence years back as well, but it always been present in the Javadocs as far as I can tell
But now it's fully gone in 26.1
I know getVersion() does the same thing, but I want to know if it was intentionally removed or not
i mean each world is negligble overhead so willl just be similar to having that many chunks loaded normally
something like SWM would definitely help though
From md_5's post about 26.1:
There are currently no significant API changes since 1.21.11 and no breakages expected for plugins using the API in this release.
So I guess it was not removed intentionally
?jd-s unrelated
?stash
#bot-commands
fake news
POV: you're asking about a Paper method on Spigot
2b2t spawn
Except it's in Spigot's Javadoc for 1.21.11 and older
No wait, that's not what I checked, because Spigot doesn't keep hosting old docs
Hrm
Yup, I believe it. I had docs for several versions of Paper open in addition to Spigot's when trying to figure out where the method came from and where it went
Must have confused myself
Too much blood in my caffeine stream today
?ask
If you have a question, please just ask it. Don't look for staff or topic experts. Don't ask to ask or ask if people are awake or available. Just ask the question to the channel straight out, and wait patiently for a reply. Make sure you use the right channel regarding the topic of your question. Create a thread in case the channel is already in use!
Does anyone know how to make a mob when it spawn and get kill ,it will send a messenger in chat so everyone could see
mythic is kill
How to make auto stasis trigger work in paper servers?
?whereami
MrBozo
Pls
broski
Sire, this is Spigot
paper is a separate project with a separate discord
Where is paper dc server
Try googling for once
@young knoll
?ban @wheat lance spam bot
Done. That felt good.
thx!
Whats recommended way of making custom currency? Vault, persistent data storage, something else?
Vault is just an API between plugins, and if you want persistent data storage there are multiple ways of going about it depending on your needs
Anything you would recommend? Kinda new, trying to convert my skripts to java plugins so the currency needs to work across multiple plugins
does vault even support multi-currency?
It doesn't
i remember it supports per-world currency, but not so sure about multi-currency
to be clear, are you intending to have a "custom" currency in the sense that the server will have "dollars" as a regular currency, and like "gems" or whatever the shit as a different "custom" currency?
or are you just trying to hook your plugin into a currency in general, be that dollars or whatever else the server admin calls it by?
Yes, multiple custom currencies like gems, tokens etc, not like name matters but yes
i think reserve supports multi-currencies, but from what i know its adoption is mostly limited to whoever the towny guys can get their hands on
you can have multiple economy providers however the consumers of the economy services always choose the last registered one
because who would go out of their way to for loop each economy service on each transaction
currency needs to work across multiple plugins
if these plugins are all yours, then you can just implement the currency stuff yourself
vault is for when all plugins, including those you didn't write, have to play one tune and work with the same currency
you can still expose your own api for other plugins to hook into to do transactions and checks on your custom currencies
as far as economy goes, I think Vault is pretty much useless anyway
or was it permissions
permissions probably
bukkit has its own permissions system anyway, i think permissions is only ever used for like getting "metadata" like the primary group and nick and other things popularized by role plugins
there's also been multiple spinoffs of Vault like VaultUnlocked centered on improving the Economy service, also Vault 2.0 which is like, just an economy provider
long archived, luckily enough
they stopped maintaining it, yeah
but it was maintained for fairly longer than reserve
nature is healing
this is me as hell
im out here usin Fairy Dust as my currency
fully custom eco solution with integration in my own plugin suite 🤞
block#breakNaturally calls blockbreakevent on some circunstance?
Anyone using XSeries? https://github.com/CryptoMorin/XSeries
(i might have to "dont ask to ask" myself)
I mean, does it truly bridge the gap between Spigot and Paper, or is it not as useful as it seems?
i misunderstood the point of the lib, nvm.
icl forgot that existed, wasnt it more for version mapping materials and other registry types
:,)
was hoping something like PaperLib still existed
i used it just for version compatibilities from 1.8 to 1.19 but then disabled it honestly
Does it not?
does what not what
PaperLib still exist
it dont lad
Skill issue
how can i add item flags with datacomponenttypes?
yes but i can't find itemflags thing
to hide the enchants
i can add enchants but i can't hide them
You can just use the addItemFlags method
that too
This might be as simple as adding a .gitattributes file and doing a little bit of resource filtering for some metadata. (Has to be committted for it to apply)
I added this to the repo and it does a lot of heavy lifting. This file overrides any autocrlf settings as long as the file type is specified. My diffoscope outputs were much smaller because of it.
The issue I had with metadata was it not having the correct line endings. Specifically on these files.
META-INF/libraries/spigot-api-26.1.2-R0.1-SNAPSHOT.jar/META-INF/maven/org.spigotmc/spigot-api/pom.properties
META-INF/versions/spigot-26.1.2-R0.1-SNAPSHOT.jar/META-INF/maven/org.spigotmc/spigot/pom.properties
Apparently, the maven-jar-plugin dynamically generates the pom.properties during execution using system specific line endings.
This is unfortunate since there is no tag that can be used to change this behavior other than <addMavenDescriptor>, but that would end up removing both the pom.properties and the pom.xml.
However, I got around this by adding the file to the project and filtered it in with the resources plugin.
Spigot-API/
└── src/main/resources/META-INF/maven/org.spigotmc/spigot-api/pom.properties
Spigot-Server/
└── src/main/resources/META-INF/maven/org.spigotmc/spigot/pom.properties
I added this to both poms. (spigot & spigot-api)
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
That just left me with the .list files in the outermost jar which could thankfully be fixed in the assembly file by adding the <lineEnding>unix</lineEnding> tag to the files and filesets.
Those four changes are what I did to get a reproducible build across operating systems.
There is another approach which involved unpacking the entire jar, forcing the correct line endings, and then repacking it all. However, it comes at the cost of more computation and a longer compile time.
I opted for the resource filtering because of that.
.setData(DataComponentTypes.HIDDEN_COMPONENTS, ...) ? or what do you mean?
this use metadata
Isn't that paper api?