#help-development

1 messages · Page 1334 of 1

tender shard
#

John Jitpack

mortal vortex
#

so fvcking true

tender shard
#

I hate that guy

fading drift
#

is there an event thats called once a player is fully loaded into a world after joining a server for example

#

because spawnlocationlistener is called before the player is even apart of the world.getplayers list

sly topaz
#

what people usually do is just wait a tick in the join event if it comes down to showing a visual effect or something, as sometimes it is triggered before the loading terrain screen changes for the client

wet breach
sly topaz
wet breach
sly topaz
#

It'd be nice if it did make use of that packet but then it'd involve trusting the client to send that packet and idk what side effects changing when the event is triggered would have with current listeners

#

if it were to be implemented, it'd probably be best to have it as a separate event with a method to determine whether it was sent on join (because it is also sent when changing dimensions)

wet breach
#

interesting, would be cool though if it does

#

no more always waiting however many ticks to do something, just can listen for that event lol

sly topaz
#

I do feel like hacked clients could potentially abuse of it

#

like just never sending the packet and still moving around and such, I don't think the server cares whether the client sends it or not

wet breach
#

that is what the wiki says anyways

sly topaz
#

so yeah, if you were to depend on it for anything, it'd only be useable for anything visual because if you actually set player data in there then it might be potentially exploitable

rotund ravine
#

Just do the same as the server

sly topaz
#

that would require consumers of that event know what they're doing, which I don't expect they would

rotund ravine
#

Listen, if it hasn’t come after 60 ticks assume they’re loaded and do your logic anyways.

Keep them in some sort of limbo until your logic is run.

wet breach
#

I would imagine you could just have the server invoke the event after 60 ticks anyways. Only difference is timing on the event if you do it that way

#

and its 60 ticks after the last login or respawn packet was sent

sly topaz
#

I guess 60 ticks isn't long enough of a timespan to do anything potentially dangerous, maybe spam in chat at best

wet breach
#

apparently the wiki provides a better way then just waiting 60 ticks. Apparently the client will send 60 client tick end packets

#

only after 60 of those packets will player ticking start

tender shard
#

isn't there PlayerLoadedWorldEvent or sth?

rotund ravine
#

Like if a player loaded in a world?

tender shard
#

No, like the player has finished loading the world

#

idk

#

Like on velocity there's PlayerFinishedConfigurationEvent

rotund ravine
#

Oh

#

Nuh, we still on the “if they start moving they probably loaded in” i think?

tender shard
#

But I definitely dislike a fixed delay of 60 ticks

#

For example on a modern computer, the delay is like 0 or 2 ticks at most

#

And on @jagged quail's computer, it'd be 500 ticks lmao

#

But yeah, checking for movement is valid

#

Paper e.g. has API for actual buttons used but we're on spigot here

#

so the check might fail if e.g. the player logs in while being in water or similar

#

not sure though

#

paper does have reliable methods for checking when a player actually entered the world, Spigot unfortunately doesn't have it yet

#

What do you need it for anyway?

jagged quail
buoyant viper
#

thats basically all u need

mortal vortex
#

To be fair, Oliver's car might as well be AWS the way it always has issues

tender shard
tender shard
#
  1. I don't remember but sth was broken
  2. I was on the autobahn when suddenly sth with the motor was broken (turned out that only some hose blew up and repair was only 59€)
  3. I got an email from the manufactorer: the airbag is broken and needs to be repaired lmao
#

cars love to have issues

orchid gazelle
#

Broken airbag is insanely expensive

lilac dagger
#

How does an airbag gets broken unless you had to use it at which point isn't the car in pieces already?

quaint basin
#

What is the minimum Java version required to run a server using the latest version?

#

have some wiki about this?

lilac dagger
#

Jdk21 i think

mortal hare
#

is there any text editor which doesnt suck lately

#

visual studio code LSP server keeps getting dementia for some reason

#

sublime text costs money

tall dragon
#

use pen and paper and scan them in

mortal hare
#

zed is incomplete and lacks basic functionality

cloud perch
#

notepad

mortal hare
lilac dagger
#

Notepad should still be good afaik

mortal hare
#

because it forgets that imports exist

lilac dagger
#

Oh you need some sort of ide

mortal hare
#

i want lightweight ide/text editor

cloud perch
#

notepad++

tall dragon
#

idk i always use jetbrains products, they can sometimes have dementia but they work for me

lilac dagger
#

Never had issues with jetbrains' intellij

tall dragon
#

not particularly lightweight tho

lilac dagger
#

There was another text editor i forgot the name

#

Similar to vscode

mortal hare
#

we need open source sublime text 🙁

mortal hare
#

but it has like 500 open PR's

tall dragon
#

start your own ;D

mortal hare
#

editor itself is half baked

lilac dagger
#

Sublime text

#

This was the one i was thinking

mortal hare
#

sublime text is pretty cool but as far as i know its LSP support is not

#

maybe something changed

#

i need to try it

lilac dagger
#

Hmm

thorn isle
#

airbags are for wussies

lilac dagger
#

Until you need them^

#

Not hitting your head is pretty good afaik

onyx fjord
#

well sublime and jetbrains are a different world

thorn isle
#

the issue is more like you cracking your neck/spine because you don't have a seatbelt on your forehead

lilac dagger
#

If i was to do proper coding i'd use jetbrains products

thorn isle
#

myes

#

sublime and whatever else is hipster nonsense

thorn isle
#

just like toml

lilac dagger
#

That then

onyx fjord
#

only thing i think vscode does better is centralized config vs a million xml files

#

also xml for configs 🤮

thorn isle
#

one nice thing about vscode is the web editor and its integration with github

onyx fjord
#

for some reason xml for configs is standard for java

thorn isle
#

i blame apache 🐜

onyx fjord
#

true

thorn isle
#

either way still better than doing it in kotlin

lilac dagger
#

Are those xmls for users?

mortal hare
onyx fjord
#

i can, its called yaml

#

and it supports comments

mortal hare
#

its verbose a bit but not as verbose as xml

mortal hare
thorn isle
#

simpleyaml seems about the best spec for general purpose configs

#

it's essentially yaml without all the weird parsing nuances

mortal hare
#

does it share the same file extension?

#

or is it called something like .syml

thorn isle
#

i don't remember, doesn't really matter as you can put any extension on any file

onyx fjord
thorn isle
#

most of the time regular yaml will parse fine though, so it probably has the same extension

#

nevermind it was strictyaml, not simpleyaml

onyx fjord
#

file extensions generally dont exist

#

.json doesnt make a json file

thorn isle
#

the most important change it makes in my mind is that it gets rid of implicit typing, much like most of the proper json parsers do with json

#

the config itself doesn't capture any type information; it's determined at runtime by whoever is deserializing it

#

so you no longer get errors out the ass when e.g. version: 1.0 in plugin.yml gets treated as a double rather than a string

#

secondary to that is all the multiline string shit

#

my only regret is that it also does away with anchors and references, which i do end up using in e.g. mythicmobs configurations

onyx fjord
thorn isle
#

nope, typical pythonoid behavior

#

hurr durr everyone just does everything in python anyway

onyx fjord
#

snakeyaml repo btw

quaint basin
#

If the location I tried is invalid, what location should I try? Perhaps at an offset of 32 blocks?

Something like this where NEARBY_OFFSET_RANGE is 32? https://pastes.dev/CJPSBkxxRF

#

I have no idea what proportion of blocks I should set for the attempt and how many attempts I should make before looking for another completely random location; I set it as 32 and 3 attempts, I don't know if those are good values

#

I'm also thinking that if the first attempt increased x and z, then the second attempt should increase x and z, not go back

thorn isle
#

depends on why it fails

#

not all checks are equal

#

if you hit water, you're probably very likely to hit water again in any blocks within say a 8 block range

#

if you hit a tree trunk, well, those are either 1x1 or 2x2, so any adjacent block is still very likely to work

#

if you hit leaves, positions within a 3 block range are probably also going to be leaves, but farther out is likely to work

#

the main point is that you want to stay within the same chunk as long as possible, as going out will generate more chunks again

quaint basin
# thorn isle not all checks are equal

Yes, in my case I only apply this if the highest block at the location is not found; if it stops because of the ocean biome or the chunk has already been generated, I try a completely random location

thorn isle
#

even within other biomes, you can hit fairly large bodies of water, like lakes

#

well, "large" as in like 10 blocks across

#

but much larger than a tree

quaint basin
#

i quoted the wrong msg btw

thorn isle
#

something to keep in mind is that reading blocks in the world is many orders of magnitude cheaper than generating a chunk; to get a gist of the scale, remember that many mobs like drowned, villagers, and bees constantly scan thousands of blocks to find blocks to navigate to, and every mob scans hundreds or thousands of blocks whenever it pathfinds, and most of this is unnoticeable in the tick loop

#

so even if you end up checking every block column in the chunk, it will take less time than generating the adjacent chunk

#

so i would not recommend jumps of 32 blocks or anything more than 2-5 blocks, unless you hit a condition that indicates the whole chunk is very likely to be invalid - such as water

quaint basin
#

I see

#

So in this case you recommend checking the highest block of an entire chunk (even if it's water) and if everything is invalid (for example, a huge hole because I only consider it valid for y>40) then in that case try an adjacent chunk

#

entire chunk = I mean the chunk corresponding to the first location attempt

thorn isle
#

correct, except i'd bail out and move to neighboring chunks immediately if i hit water

#

since if there is one block of water, there is probably an entire lake of water: and the entire chunk is probably invalid

#

for cactus, leaves, whatever else that's more "spurious" i'd continue scanning the whole initial chunk

tender shard
#

just google "Opel Rückrufaktion"

quaint basin
orchid gazelle
#

Oh nice

quaint basin
#

public static final HeightMap MOTION_BLOCKING_NO_LEAVES
The highest block that blocks motion or contains a fluid or is in the Tag.LEAVES.

When it says "contains liquid," could that be water or lava? Or does it refer to blocks like stairs with water inside?

young knoll
#

Water and lava

quaint basin
#

If the location has a leaf, I teleport underneath the leaf; if it has water or stairs with water, I stay on top of the water/stairs with water

quaint basin
#

If I do:


world#getChunkAtAsync#thenCompose(... -> {

if (...) return CF#completedFuture(...);

(...)

}).thenAccept(... -> {

// chunk loaded here guaranteed?

});
thorn isle
#

supposing the future does get completed by the main thread, yes

quaint basin
#

So the instructions cannot be executed in the middle between the thenCompose block and the thenAccept block?

thorn isle
#

i'm not 100% sure if that guarantee is quite exact, i think there might be a race condition in it if you do the getChunkAtAsync call off of the main thread, but it's probably reliable enough

quaint basin
#

getChunkAtAsync is called on main thread here

thorn isle
#

if the other future you're passing to thenCompose isn't complete, the chunk is very likely going to unload

quaint basin
thorn isle
#

also, if the future you're passing to thenCompose is completed off the main thread, then thenAccept will also run off of the main thread

quaint basin
#

i see

#

But if getChunkAtAsync is called in the main thread, then do I have the guarantee?

thorn isle
#

no, i think i misread your original question: the guarantee only exists for a pure chain of ``thenX`s from getChunkAtAsync; introducing any other future into the mix invalidates the guarantee

#

unless you are 100% certain that other future is already completed

#

this is because doing any sort of composition of futures, like allOf or compose, will cause the resulting future to execute only all of its dependencies (the futures being composed) are complete

#

while getChunkAtAsync only guarantees for the chunk to be loaded for 1 tick

quaint basin
thorn isle
#

you know this is kind of what i was talking about with the virtual threads

quaint basin
#

My question here is about the behavior of thenCompose; if when I do CF#thenCompose and within that block it returns a completionfuture that is already completed; if when using CF#thenAccept after the compose, something is executed in that thread between those two calls

thorn isle
#

the thread chat completes the future (getChunkAtAsync) you call thenCompose on (the main thread) will continue to immediately execute its dependents (the lambda in thenCompose), and then, if and only if the future returned by thenCompose is already completed, immediately continues to execute the composite's dependents (the thenAccept)

#

in this case, yes, the main thread will immediately execute the thenAccept without any instructions in between it and your lambda in thenCompose, but only if the if in the thenCompose is true, or the future it returns in the else case is already completed

#

which means that the chunk is guaranteed to be loaded in thenAccept under the same conditions

thorn isle
#

that*

quaint basin
#

oh

thorn isle
#

don't know how that turned into a c

quaint basin
#

Is the thread that completes the CF returned by getChunkAsyncAt determined by the thread that calls the method?

thorn isle
#

according to the documentation, it should always be completed by the main thread

quaint basin
quaint basin
thorn isle
#

eyeballing the code i'm pretty sure there is a race condition that allows thenX called on the getChunkAtAsync future to be completed on the thread calling getChunkAtAsync instead of the main thread

#

not an issue as long as you call getChunkAtAsync on the main thread

quaint basin
thorn isle
#

the documentation is wrong

quaint basin
#

lol

#

Did you test it?

thorn isle
#

well no, the documentation isn't wrong, but the guarantee it gives applies only to the future it returns, not any future created from it

vagrant stratus
thorn isle
#

the issue is that calling thenX on an already-completed future executes the lambda on the thread calling thenX

thorn isle
#

so even if the future returned by getChunkAtAsync is always completed by the main thread, there's a chance it gets completed by it before the other thread calls thenX

#

at which point, since the future is already completed, the lambda in thenX runs on the calling thread, not on the main thread

#

this seems extremely unlikely considering how long it probably takes for the chunk future to be completed vs how fast the caller can go from getChunk to thenX, but the thing with threading is that anything that isn't categorically impossible will happen eventually

slender elbow
#

just use the method that takes a callback ez

thorn isle
#

honestly yeah

quaint basin
thorn isle
#

the lambda in thenX gets called by whoever completes the future which thenX is called on; or the thread calling thenX if it's already completed

#

so if the future computed by the function in thenCompose is not completed, thenX will be executed by the thread that completes it

#

if it is completed, thenX will be executed by the thread that completes getChunkAt (the main thread)

#

so yes, it can be executed in the thread that completes the future within the thenCompose, but only if it isn't completed already

#

if it is completed already, it gets called by the same thread which runs the thenCompose function

#

or if you're calling getChunkAt off the main thread and there's a race, thenX could be executed by the thread creating the future chain

#

the reason why this is so convoluted is because the thenX methods are intended for scenarios where the executing thread doesn't matter

#

the only guarantee is that the stuff gets executed as soon as possible by someone

#

for control over which thread/context the lambdas run in, the intended way is to use the thenXAsync overloads, which take an Executor

#

the issue with this is that passing it the bukkit mainThreadExecutor means the execution could be delayed by a tick, which is enough time for the chunk to unload

quaint basin
#

I see now; the question is whether the thenAccept is chained before or after the CompletableFuture#completedFuture is executed. If it’s chained before (more likely), there’s no race condition; if it’s chained after, then the thenAccept will be executed on the thread of the CF#completedFuture

quaint basin
thorn isle
#

either way, for your particular case, for the thenAccept to be guaranteed to be run on the MT with the chunk loaded, two things need to be true:

  • you call getChunkAt on the MT
  • you return an already-completed future from the thenCompose
#

CF.completedFuture() returns a completed future, so as long as that if is true, it'll run on the MT with the chunk loaded

quaint basin
thorn isle
#

myes

#

but the future you return from the theCompose function still needs to be already-completed, or else the thenX lambda will be delayed

thorn isle
quaint basin
thorn isle
#

and to ensure that thenX runs on the main thread; if the future you return from the thenCompose function is completed e.g. by a database IO thread, then the thenX lambda will be run by that thread

quaint basin
#

i see

quaint basin
chrome beacon
thorn isle
#

doesn't sound right; profile it with spark or something, i suspect you're doing something strange in the utils method

#

iterating over every block in a chunk section is like sub-1-ms usually

quaint basin
#

i'll see on spark

quaint basin
thorn isle
#

you seem to be calling getChunkAtAsync 16*16 times for every chunk

#

that's why it takes so long

quaint basin
#

But that line shouldn't be causing it; because in my view the chunk is loaded

thorn isle
#

if i takes 50ish ms per call, you're almost surely not on the main thread

#

the way how it works off-MT is it enqueues a task to get the chunk on the MT next tick

#

which is going to block for 50ish milliseconds

quaint basin
quaint basin
#

https://pastes.dev/xXDjrpYU0Y I discovered the cause of the problem; the problem was in this method where, if it were an ocean, it returned the same result as if the location were invalidated because there was water in a single block, for example (the logic of being invalidated by a single block is in the ternary operator where the returned result was null, which is the same result if the chunk were ocean or had already been generated before). Thus, in the method that uses this particular method, I couldn't distinguish whether I should search for all the blocks in that same chunk or if I should simply try a completely random position; In this case, my code was simply iterating through all the blocks in a chunk that had been generated (in cases where this method in the attached message returns null because the chunk has already been generated), and if the chunk hadn't been loaded (which was what was happening), LocationUtil#getHighestSafeBlockYAt would take a long time to get the highest block (only for the first block, because it had to load the chunk; for subsequent blocks, the chunk was already loaded), thus causing the high time in findSafeLocationInChunkSync.

chrome beacon
#

?services

undone axleBOT
tender shard
quaint basin
#

I'm having a problem where, when a chunk is being generated to fill the buffer and I type /rtp, I'm teleported to a location that has already been generated and is in the buffer. However, the chunk I teleported to and the adjacent ones remain empty until the chunk currently being generated finishes generating. But supposedly, player#teleportAsync only teleports the player once the chunks are loaded. Why is this happening?

rotund ravine
quaint basin
vagrant stratus
#

skill issue

thorn isle
#

wdym empty

tender shard
#

it's not very hard to get banned there

#

just send a soundcloud link or two

tender shard
quaint basin
quaint basin
thorn isle
#

That's just the server taking a while to send them? Can't really rely on that; double-check with the api that they're generated

slender elbow
#

inb4 the chunks are unloading because no chunk ticket is added beyond the one for the callback

#

atp i'd just use the getChunksAtAsync(minX, minZ, maxX, maxZ, callback) and call it a day

thorn isle
#

💀

quaint basin
#

But actually, forget it; it's the player#teleportAsync that does that. I thought that using that I wouldn't see empty chunks when teleporting, but it must be the client taking a while to interpret the message that arrived from the server or smth like that

thorn isle
#

i hate the ticket system

slender elbow
#

i mean teleportAsync(target) is quite literally just getChunkAtAsync(target).thenApply(_ -> player.teleport(target))

slender elbow
thorn isle
#

i wish the ticket system accepted namespaced keys or something instead of a plugin instance

#

suppose for example this exact scenario

#

you have two systems which load chunks and have to keep them loaded for a few ticks

#

how do you make sure both can register tickets without stumbling over one another? you only have one plugin to pass, but two systems which should hold their own tickets

#

so now you end up doing your own ticket system to drive the bukkit ticket system

#

a perfect example of an api nobody bothered to try using in practice before standardizing and finalizing it as part of the api

slender elbow
#

isn't that just every api in the whole of the spigot ecosystem?

thorn isle
#

for all the shit i give paper about them marking everything as experimental, at least they're doing right in principle to keep things experimental until adoption can recognize needed changes

#

it's just that they never un-mark anything as experimental

lilac dagger
#

Ah yes

#

I had to register commands for paper and everything was a warning due to the experimental annotation

#

I guess they did add later a register command in java plugin that didn't had it

vagrant stratus
#

lol rip

onyx fjord
dark moth
#

I get the error 'ClientboundAddEntityPacket(net.minecraft.network.RegistryFriendlyByteBuf)' has private access in 'net.minecraft.network.protocol.game.ClientboundAddEntityPacket'

while using ClientboundAddEntityPacket(ServerPlayer serverplayer)

#

what could be the issue that i need to solve ?

onyx fjord
#

if you can use packetevents for your packets

#

thats my suggestion if doing more than 1 packet related thing in a project

vagrant stratus
#

^ NMS Packets are a bitch to work with

onyx fjord
#

oh the horror

vagrant stratus
#

If this is for your own server, just fork paper or spigot and add API lmfao

dark moth
cloud perch
#

Be a real programmer and make ur own

vagrant stratus
onyx fjord
#

ill migrate to PE fully someday

#

now its a hybrid

#

there were reasons ive done it that way

cloud perch
#

Someone should make it so that we can use blueprints to make plugins if it does not exist currently

onyx fjord
#

but its a nightmare when suddenly paperweight has to re-pull and decompile all the minecraft binaries

vagrant stratus
#

Thankfully I don't have to use PE. I'm already forking paper, so I can just add API as necessary lol

thorn isle
#

nms packets are pretty nice to work with in conjunction with protocollib + mojang mappings

onyx fjord
thorn isle
#

or well they are, as long as you only need to support one version at a time

cloud perch
thorn isle
#

that said everything is ass to work with with multi version support

vagrant stratus
#

That is why i stick with the latest version only kekw

onyx fjord
#

plib has performance issues

thorn isle
#

eeeh not really if you use the nms packets directly

lilac dagger
thorn isle
#

the perf issues mostly come from the reflective packet wrapper nonsense

lilac dagger
#

I don't use any reflections too

#

I just write and read from the codec

cloud perch
#

Everything is nonsense if we didn't make it

thorn isle
#

imo hooking into netty directly to send/receive your own packets is always unnecessary and overkill, unless you need to hook into a specific spot in the pipeline, like after packets are transformed into raw bytes, or before/after viaversion transformers

#

whether its packetevents or protocollib, using an existing solution is cleaner if you don't need to customize exactly where you hook into

vagrant stratus
thorn isle
#

i just disguise villagers with libsdisguises 🤡

onyx fjord
#

ld is ass trash

vagrant stratus
onyx fjord
#

its a plugin? but its a lib? but the plugin is limited?

thorn isle
#

the codebase is and many things about it are, and the dev seems slightly incompetent, but it does work and it does a lot of things out of the box without trouble

vagrant stratus
#

I have the Mannequin, so i use it lol

onyx fjord
#

10 billion command aliases

lilac dagger
#

Probably have to kill change type and show and intercept packets

onyx fjord
#

"premium" libraries always bother me

vagrant stratus
#

I'd compete with ld, but I have enough projects to work on lmfaooo

onyx fjord
#

that model library especially

#

old me used to reverse engineer that shit on every update

thorn isle
#

you only need the "premium" if you use the ingame commands

#

it works for free as a library/api for other plugins

onyx fjord
thorn isle
#

not necessarily

onyx fjord
#

the plugin part of it could be a different plugin using the lib

#

not something baked in

thorn isle
#

there are many advantages to having a service loaded on the server as a plugin

onyx fjord
#

not saying it shouldnt be in plugin form

#

they could just be separated

#

so much less bloat at minimal effort

thorn isle
#

doesn't really seem like a problem to me honestly

onyx fjord
#

old me wouldnt be bothered either, but these days i keep my stuff minimal

#

my rule is - if something overwhelms the server dev/owner, it will certainly be even more pain for the player

thorn isle
#

either way, it has many useful things to depend on, e.g. an integration to auto-upload skins to mineskin, an entity property parser so you can configure your things in plaintext with setters like setSitting true, and it can automatically reflect a player's equipment, just to name a few

onyx fjord
#

so i just skip stuff like this

onyx fjord
#

ive never really used the plugin part of it other than pranking my gf

thorn isle
#

btw it's not called libsdisguises because it's part library part plugin

#

it's just a plugin

#

by someone called libraryaddict

quaint basin
#

How can I make a player invincible for 5 seconds when teleporting with my rtp plugin? Is there a potion for that?

#

Or do I need to intercept the damage events, etc.?

smoky anchor
#

just give them resistance 255 lul

dark moth
#

thanks

thorn isle
#

some also give brief low level levitation in case the player somehow ends up falling through the world before it loads, but that's not something that "should" happen anymore

young knoll
#

Isn't there also setNoDamageTicks

thorn isle
#

it's a bit fiddly, since it's not really "no damage" ticks but more like a "Math.max(damage)" ticks

#

basically what it does is it takes all of the individual damage's dealt over the course of the ticks, and totals it to max rather than sum

#

so if you get hit for 10 damage and have your no damage ticks set to 5, then if you get hit for 15 damage again within those ticks, that'll do 15 - 10 = 5 damage; for a total of 15 over the course of the ticks

#

so maybe if you set the previous damage record to Double.POSITIVE_INFINITY or something and then apply no damage ticks, it'd work

vagrant stratus
#

isn't Entity#setInvulnerable good enough?


    /**
     * Sets whether the entity is invulnerable or not.
     * <p>
     * When an entity is invulnerable it can only be damaged by players in
     * creative mode.
     *
     * @param flag if the entity is invulnerable
     */
    public void setInvulnerable(boolean flag);
thorn isle
#

does that work on players?

vagrant stratus
#

It might?

#

It'd be silly if it didn't

worldly ingot
#

Yeah it works fine for players

thorn isle
#

neat

#

is it persistent? if it is, i'd stick with the potion effect still, since otherwise if the player e.g. quits in between you applying and revoking the invincibility, they might get stuck permanently invincible

vagrant stratus
#

Just do a quick isInvulnerable check on login

thorn isle
#

i dislike anything persistent on players because then you need separate "uninstaller" logic

quaint basin
#

The problem is then the server owner removing the plugin or something like that xd

thorn isle
#

myeah

quaint basin
#

I thought about that persistence thing too

#

Is it normal for world#getChunk to take 500ms? (The chunk has never been generated before)

thorn isle
#

where are you measuring it

quaint basin
thorn isle
#

on the MT or async

quaint basin
#

long start = System.nanoTime();
location.getChunk();
System.out.println("(0) " + formatTime(System.nanoTime() - start));

#

MT

quaint basin
thorn isle
#

sync-generating a chunk can definitely be very expensive, it's not something you generally ever want to do

slender elbow
#

2c/2t celeron ddr2?

quaint basin
thorn isle
#

that said 500ms is a bit high

thorn isle
#

my advice would be to not call it

quaint basin
#

I'm just doing some benchmarks

#

But getChunk is inevitable

thorn isle
#

make it not inevitable

#

nothing should ever sync load chunks

quaint basin
#

Plugins always use getChunkAtAsync, but when this method runs on the server tick, it will take the same amount of time as if I use getChunkAt no?

thorn isle
#

not really

quaint basin
#

I thought it was the same

#

what are the differences?

thorn isle
#

it's the same but the other way around

#

getChunk is getChunkAtAsync().join()

#

getchunkatasync can process dozens of chunks in parallel, and almost all the work is done off the main thread

#

doing getChunk means the server is waiting for a single chunk at a time

slender elbow
#

-# not directly like that but it achieves the same effect

thorn isle
#

myes

quaint basin
#

And what about getChunkAt in older versions?

#

And in modern Spigot because Spigot 1.21 doesn't have getChunkAtAsync from what i know

thorn isle
#

before async chunk loading/generation, it's probably a bit faster than getChunkAt is now, because now it has the overhead of reordering the queue and making all the chunk thread shit bricks trying to handle the urgent ticket asap

#

no clue how it behaves on spigot

quaint basin
#

But then that explains the 500 ms, so it's not my PC's fault

slender elbow
#

chunk gen is still threaded pretty sure, just, spigot has no api to request it non-blocking

quaint basin
#

getChunkAt should be removed lol

#

on really can be used in enable/disable so yea

thorn isle
#

paper even has a mode to record every sync chunk load's stack trace so you can debug what is causing them in order to eliminate them

quaint basin
thorn isle
#

Thread.dumpStack()

#

not just which plugin but the class and exact call stack leading to it; basically the same way you'd locate an exception being thrown

quaint basin
#

I have no idea how I can use this xd

thorn isle
#

i don't remember how to enable it

#

it's some startup flag i think

quaint basin
#

i see but I'm fine because I won't need it in any case 😅

#

unless a plugin like luckperms does it which I doubt

thorn isle
#

i mostly bring it up to put into perspective how aberrant and undesirable it is for a plugin to call it and do a sync chunk load

quaint basin
#

yea i see

#

134.9 µs to iterate 16 * 16 blocks, and for each block I'm using getHighestBlockAt. Reading blocks is incredibly fast xd

#

How does getHighestBlockAt work internally? Is it 100% accurate?

#

He doesn't need to iterate through all 320 blocks of the world to see the highest block

thorn isle
#

it's a heightmap

#

basically as part of world generation and bookkeeping (updates when the blocks are changed) the server updates a blockcolumn -> height mapping

#

so it's updated whenever the blocks change, but querying it is essentially free, just an array/map read

#

there are a number of different heightmaps for different purposes, not just one

#

some of them are used for e.g. sky light, others play a part in navigation and mob spawning

quaint basin
#

I see in forums that they say getHighestBlock only works for chunks that haven't been modified but apparently it's a lie

#

Either way, it's not relevant to me because my RTP only allows it for chunks that have never been generated

thorn isle
#
    public static enum Types implements StringRepresentable {
        WORLD_SURFACE_WG(0, "WORLD_SURFACE_WG", Heightmap.Usage.WORLDGEN, Heightmap.NOT_AIR),
        WORLD_SURFACE(1, "WORLD_SURFACE", Heightmap.Usage.CLIENT, Heightmap.NOT_AIR),
        OCEAN_FLOOR_WG(2, "OCEAN_FLOOR_WG", Heightmap.Usage.WORLDGEN, Heightmap.MATERIAL_MOTION_BLOCKING),
        OCEAN_FLOOR(3, "OCEAN_FLOOR", Heightmap.Usage.LIVE_WORLD, Heightmap.MATERIAL_MOTION_BLOCKING),
        MOTION_BLOCKING(4, "MOTION_BLOCKING", Heightmap.Usage.CLIENT, state -> state.blocksMotion() || !state.getFluidState().isEmpty()),
        MOTION_BLOCKING_NO_LEAVES(
            5,
            "MOTION_BLOCKING_NO_LEAVES",
            Heightmap.Usage.CLIENT,
            state -> (state.blocksMotion() || !state.getFluidState().isEmpty()) && !(state.getBlock() instanceof LeavesBlock)
        );
#

and in particular, this is LevelChunk::setBlockState, which is the main route all chunk modifications post-generation go through:

    @Override
    public @Nullable BlockState setBlockState(BlockPos pos, BlockState state, @Block.UpdateFlags int flags) {
        int y = pos.getY();
        LevelChunkSection section = this.getSection(this.getSectionIndex(y));
        boolean hasOnlyAir = section.hasOnlyAir();
        if (hasOnlyAir && state.isAir()) {
            return null;
        } else {
            int i = pos.getX() & 15;
            int i1 = y & 15;
            int i2 = pos.getZ() & 15;
            BlockState blockState = section.setBlockState(i, i1, i2, state);
            if (blockState == state) {
                return null;
            } else {
                Block block = state.getBlock();
                this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING).update(i, y, i2, state);
                this.heightmaps.get(Heightmap.Types.MOTION_BLOCKING_NO_LEAVES).update(i, y, i2, state);
                this.heightmaps.get(Heightmap.Types.OCEAN_FLOOR).update(i, y, i2, state);
                this.heightmaps.get(Heightmap.Types.WORLD_SURFACE).update(i, y, i2, state);
                boolean hasOnlyAir1 = section.hasOnlyAir();
                if (hasOnlyAir != hasOnlyAir1) {
                    this.level.getChunkSource().getLightEngine().updateSectionStatus(pos, hasOnlyAir1);
                    this.level.getChunkSource().onSectionEmptinessChanged(this.chunkPos.x, SectionPos.blockToSectionCoord(y), this.chunkPos.z, hasOnlyAir1);
                }
#

it does seem to update most of the heightmaps, except the Usage.WORLDGEN ones

young knoll
#

Which is what its meant to do

#

Idk why it wouldn't

quaint basin
#

i see

quaint basin
smoky anchor
#

255 is max

quaint basin
#

The problem is if the player uses invisibility to kill someone xd

#

So maybe I need to have some additional logic

thorn isle
#

weakness 255 also 🤡

#

i don't know, if the spot is pregenrated and you've done your checks, i don't know if you'll need resistance or anything of the sort

#

the worst i see happening in practice is someone having a poor connection and lagging for a few seconds after teleporting, in which time some newly spawned mob could kill them

quaint basin
thorn isle
#

eeeh lava is pretty slow and doesn't flow far in the overworld

#

i wouldn't worry about it

quaint basin
#

Well, 2 potions effects don't cost anything

thorn isle
#

plus if they do end up in lava somehow, resistance for a few seconds is probably not going to save them

#

you can give the potion effects, that's an acceptable level of extra complexity; but i wouldn't start writing some pvp combat toggle listeners or anything of the sort

quaint basin
#

They have the reaction time to type /spawn

#

i see

young knoll
#

What about fire resistance

#

Doesn't matter as much for PvP and protects from lava

thorn isle
#

what if you spawn on top of a cave with a sand ceiling and flowing water causes a block update and you fall down with the sand and suffocate in it 🤡 you never know

quaint basin
#

I also like resistance because sometimes the location is valid, but a block in front is a hole, for example, and the player used RTP and may have moved forward unintentionally and ends up falling to death

young knoll
quaint basin
#

why moveEvent#getTo is nullable?

worldly ingot
#

It's something to do with it being inherited from another event, I think the portal event

#

Or the other way around

#

Yeah. It's nullable in PlayerTeleportEvent which extends PlayerMoveEvent

quaint basin
worldly ingot
#

I don't remember for what reason that location can be null PES_Think

#

There was a case where it is, but it's been so long

umbral ridge
#

my gateway 206hours uptime nice XD

#

restart time

wet breach
#

really shouldn't need to be resetting it very often

brisk estuary
#

anyone having this problem?

thorn isle
#

they haven't used destroystokyo in years

vagrant stratus
#

this is also the wrong server to ask for paper support

thorn isle
#

https://repo.papermc.io/repository/maven-public/ is the current one i think

#

i don't remember, they keep changing it every 2 months

vagrant stratus
#

?whereami

thorn isle
#

everybody here is banned on paper probably

young knoll
#

no help for you then ¯_(ツ)_/¯

orchid brook
#

is there an event that i can listen to detect if player click YES button after trying to open a link from chat (from the confirmation interface)

chrome beacon
#

Doubt it

#

But it it's your website it's not too hard to figure out

rotund ravine
rotund ravine
#

Seen so many paper questions here lol

orchid brook
orchid gazelle
umbral ridge
#

still adding things, this is just a start

distant cosmos
#

how the heck do plugin licenses work?

lilac dagger
#

Do you want to add a license system?

#

If so it has to work offline and without manual steps

chrome beacon
vagrant stratus
#

also know that it'll likely be defeated by EOD lol

chrome beacon
#

This is easily bypassed

vagrant stratus
#

^ if there's no obfuscation it'd take <10 minutes. If there's obfuscation, it'll take longer but it can still be outright removed, bypassed, or disabled

chrome beacon
#

Bro got compromised @vagrant stratus

distant cosmos
lilac dagger
#

hashes then

#

spigot tho modifies classes on download

vagrant stratus
#

only for premium resources

#

also paper does modifications as well i believe

stone flax
#

No license needed really

thorn isle
#

But this requires the people publishing the jar to do it, you can't do it on your own

#

In practice, most CI systems display checksums for any artifacts they serve, which you can use to check integrity

lilac dagger
#

i have a etoken with which i can sign jars

mortal hare
#

am i the only one who hates generic type parameter naming convention of doing one letter name or T prefix

#

why not just use something like dollar sign, it makes your autocomplete better since that doesnt collide with the actual class imports

#

and looks cleaner to look at

#

class Main {
    public static void main(String[] args) {
        System.out.println(new Foo(5).id());
    }
    
    public static class Foo<$Id> {
        private final $Id id;
        
        public Foo(final $Id id) {
            this.id = id;   
        }
        
        public $Id id() {
            return this.id;
        }
    }
}
#

isnt this just cleaner to look at

thorn isle
#

💀

chrome beacon
#

Yeah no

#

$ is used for internal classes after compiling

sly topaz
#

I would argue that / is a better symbol

#

but that's used for division

#

|Id|

#

I don't believe generics need any symbolic delimiter tbh, they're supposed to blend in with actually typed params

#

only time I have found them confusing is when people use whole words for their generic param and I end up trying to find the class for it

weak wasp
#

<T> never bothered me...

slender elbow
#

never had an issue with single letter type params

#

think I've done whole words for type params, like, once

#

sometimes i do CH when I need to parameterize over various socket channels but that's about it

thorn isle
#

it can get a bit ambiguous when you have a lot of them

#

<F,T,A,X> where all the letters are like the first character of something they refer to, like From,To,Accumulator,whatever would start with x, is not very nice to work with

#

but imo uppercase whole words like <FROM,TO> are a better option than throwing weird delimiters like $ at it or naming them like regular classes From,To

mortal hare
#

and that's where it might get problematic

mortal hare
meager wadi
#

Hello everyone. I am trying to setup hotswap for plugin development. I was successful in turning debugging on, breakpoints are working; however hotswap brings following error message: Hot Swap failed <name>: delete method not implemented <name>: Operation not supported by VM

My environment in short: IDEA, Paper (i know, it is not exactly spigot, but my question is universal)
Internet says hotswap should work and idk if something is unsupported in my configuration

Also tried this
https://plugins.jetbrains.com/plugin/14832-single-hotswap/versions/stable
However it also fails with the same message

So i am wondering what i may have missing? I see for someone more qualified then me, since i dont know how all of that happening internally (building artifacts, running configurations, debug connection establishing) and what can be a reason (maybe something abvious)

I can provide more details if needed

thorn isle
#
    public @NotNull <THIS extends VarList<NEXT, E>, NEW_ELEMENT> VarList<THIS, NEW_ELEMENT> add(@NotNull NEW_ELEMENT b) {
        return new VarList<THIS, NEW_ELEMENT>((THIS) this, b);
    }
smoky anchor
#

that's a screenshot from my run configuration

meager wadi
smoky anchor
#

yes, that too is unsuported

#

wait maybe I misunderstood what you just said lol

meager wadi
#

When i change

myMethod("hello")
to
myMethod("hello23") for example?

smoky anchor
#

that should work perfectly fine

meager wadi
#

I am just guessing maybe it cant hotswap method in running plugin because when it tries to do so it uses different building tool then was used for initial plugin creation (i did that through artifacts) - how can i ensure it is the same?

chrome beacon
#

artifacts 😭

thorn isle
#

hotswapping is ass

meager wadi
thorn isle
#

make sure you're only compiling the class you're trying to hotswap

#

if your ide build and the code on the server don't match exactly, the agent is going to try deleting and creating methods and other things on the server to make them match, which will fail

#

especially terrible when there's reobf involved

chrome beacon
#

Run your server directly from IJ and that should let you hotswap (iirc)

thorn isle
#

that is definitely much more reliable

#

debugging in general is much easier when the debugger is connected locally

meager wadi
chrome beacon
#

Can be a bit hard to tell sometimes

chrome beacon
meager wadi
chrome beacon
#

I meant with Paperweight userdev

#

/the runServer gradle plugin that test plugin comes with

meager wadi
chrome beacon
#

Yes

#

Clone it and you're pretty much good to go

meager wadi
#

Thanks, i will try to

thorn isle
#

or manually depend on id("xyz.jpenilla.run-paper") version "2.3.1" or whatever the current version is

chrome beacon
#

There are some other advantages to userdev

thorn isle
#

especially for debugging, since it'll add mojmapped sources to your ide so you can actually see what's happening in nms as you debug it

mortal hare
#

shouty boi

thorn isle
ivory sleet
#

for example T_IN, T_OUT

dapper walrus
#

For a chat-radius plugin, how am I meant to use the bukkit api (in order to check world and distance between sender and recipient) in AsyncPlayerChatEvent since PlayerChatEvent is deprecated?

chrome beacon
#

PlayerChatEvent is still fine if you want to run on the main thread

#

The deprecation is a warning to let users know they should use the async version when possible

cloud perch
#

Heh isn't that on paper

chrome beacon
#

No it's deprecated on Spigot as well

vagrant stratus
cloud perch
#

Damn I never knew ts existed on Spigot too

#

Wait so it is or it isn't

#

Ok it is

prime tartan
#

why do i get Cannot resolve method 'getProperties' in 'GameProfile' ?

#

i have compileOnly("com.mojang:authlib:3.13.56")

lilac dagger
#

game profile is a record in newer versions

#

properties() for example

thorn isle
#

if you're using intellij, ctrl-click or middle mouse click the class to see what's in it

lilac dagger
#

^

thorn isle
#

if something isn't resolving, it's better to take a look at what's there instead of shooting blindly in the dark

prime tartan
#

whoops! i tried to use properties() and got this error? 🤔

java.lang.UnsupportedOperationException
at com.google.common.collect.ImmutableMultimap.put(ImmutableMultimap.java:506)
...
profile.properties().put("textures", new Property("textures", b64));
thorn isle
#

records are immutable

prime tartan
#

i guess the library i used is outdated 🙁

thorn isle
#

and it is good practice to make their properties immutable also

lilac dagger
#

the properties map is immutable now hmm

thorn isle
#

so the profile has an immutable map for properties

lilac dagger
#

let me see how i deal with this

thorn isle
#

copy the map and the properties and change what you need, then construct new ones

lilac dagger
thorn isle
#

or just create a new one from scratch as above, but be aware that profiles could in principle have more than just the textures property

prime tartan
lilac dagger
#

if you need a new profile with the textures it's fine

prime tartan
#

im rly stupid guys 😭

#

all i want is a head from a base64 🥹

lilac dagger
#

you could use the playerprofile api in spigot

thorn isle
#

or paper

solar slate
#

When I updated CCTV for someone I had to fix the player heads and this is all I did:

lilac dagger
#

yeah, you could just skip the base 64 and provide urls instead

prime tartan
#

oh!

solar slate
#

Wasn't my idea to use base64. CCTV's Author did. He had like 20+ heads as base64 saved as strings and I was just trying to get the update out haha

lilac dagger
#

yeah, makes sense then

solar slate
#

The author ended up asking for the updated jar so he could post it and he never did 😅

lilac dagger
#

oof

solar slate
#

Eh, I was updating it for someone else that wanted to use the plugin anyways

echo basalt
#

eugh skulls changed as of lately

#

like 1.21.7 or something

#

you either pass texture + signature or a name / uuid for it to fetch from

#

paper's api has ResolvableProfile, no idea what spigot's alternative is

quaint basin
#

https://pastes.dev/pofTU2jui1

If the server owner types /stop, the item might not be given and the money removal operation in the database might still be executed.

I thought about, for example, removing the item and then scheduling the operation in the database (if it fails due to an offline SQL query, etc., then the method will keep trying). The problem is that this method can also fail due to insufficient money, meaning the item might be given and the database operation simply not be performed, and it's not worth trying to execute the method (unless the player ends up with a negative balance and in doubt, but I don't want that). What should I do here? I really can't access, for example, a cache (this way it would be done in the main thread and would be synchronized with the item give) to check if the player has enough money, since the cache is only for read operations like /money <another player name>, but this cache isn't always 100% synchronized since it's updated between different servers. In other words, this cache isn't used to check if the player has enough balance to buy items, etc

rotund ravine
#

Database operations should happen fast enough that items should be given sub second if everything is set up correctly

quaint basin
#

If so, it's not possible because this method can fail simply because the player doesn't have money, and I can't verify this synchronously because the cache isn't secure for these things

#

The problem here is that the Bukkit#getScheduler#getMainThreadExecutor schedules a task, but that task is only executed on the next tick: it's possible that the /stop command is interpreted before that task executes. It's not a question of whether the database performs the operation quickly or not

rotund ravine
quaint basin
vagrant stratus
#

?services

undone axleBOT
young knoll
#

No caching of the values so you don’t need a database call?

young knoll
#

Load the players balance into memory so you can check/modify it instantly from the main thread

#

And then save it async

quaint basin
# young knoll Load the players balance into memory so you can check/modify it instantly from t...

I can't retrieve the player's balance from memory because this might happen:

long balance = fetchPlayerBalance(...); // this is 500 for example
if (balance >= 100) {
giveItem(...); // let's say that at this moment another process modifies the player's balance (not exactly in this line of code because this isn't measurable, but you understand)
withdrawPlayerBalance(...) -> // fails because the player doesn't have enough money (another process changed the amount)
}
young knoll
#

What other process is touching the players money

quaint basin
#

If you have 500 coins on server A, then you must have 500 coins on server B

vagrant stratus
#

You'll need to pull from a DB every time then

#

that, or regularly push to it

quaint basin
vagrant stratus
#

See eventual consistency

quaint basin
#

https://pastes.dev/pofTU2jui1 I'm retrieving the player's balance from the database - if I'm doing that, it's because the database always has the most up-to-date value - that's not the problem

vagrant stratus
young knoll
#

Keep track of the futures and block on them in onDisable

#

And give the items

vagrant stratus
#

and that too

quaint basin
vagrant stratus
#
if (hasBalance(...)) { // Optional check
  if (withdrawPlayerBalance(...)) {
    giveItem()
  }
}
#

As this is multiple servers, you'll have to look into eventual consistency and program around that, which isn't easy

quaint basin
vagrant stratus
#
a distributed system design where data replicas converge to the same value over time, ensuring high availability and low latency by allowing temporary, brief inconsistencies. It is widely used in CDNs, social media, and e-commerce, ensuring that if no new updates occur, all reads will eventually return the latest value.```

Given your circumstances, you're likely gonna have inconsistencies regardless of what you do. You'll just have to plan things out so things are *eventually consistent* across all of the servers
quaint basin
#

I have no idea how I can implement this. I'll try Jishuna's solution

vagrant stratus
#

You're not really gonna be able to stop two servers from modifying the balance at the exact same time without implementing some sort of DB lock (which isn't guaranteeing consistency either). You're better off looking into how a game like WoW handles things like this

quaint basin
#

Jishuna's solution seems good to me, and that way I won't need locks

vagrant stratus
#

ig this is a possible solution, as multiple servers = more or less what this paper covers

buoyant viper
#

be me

#

load economy on server start

#

save economy on server stop

#

(this is Horrible, dont be me)

vagrant stratus
#

I mean, that's good for a single server but iirc they're using multiple servers which requires some sort of eventual consistency or other form of authority on what is considered the most up to date info or whatever tf

buoyant viper
#

even on single server its a bad idea

#

one crash and my economy is reset

chrome beacon
#

(this is Horrible, dont be me)

buoyant viper
#

just end up with latency waiting on db

vagrant stratus
chrome beacon
vagrant stratus
#

fuck the world saving lol

buoyant viper
#

when we getting the WorldSaveEvent

chrome beacon
buoyant viper
#

im using SQLite for rn :P

vagrant stratus
#

I store in memory & just save on player quit, plugin disable, and on ocassion lol

buoyant viper
#

honestly disk IO time is like Nothing compared to network imo

#

at least for small files

#

esp since im running on an SSD

vagrant stratus
buoyant viper
#

yeah i should be saving on player quit honestly

#

rn i keep all users in memory until /stop

vagrant stratus
#

skill issue

buoyant viper
#

quite literally

hushed kiln
#

Hey. Does anyone know how to get the spigot-mojang.tiny file for the development of servers?

chrome beacon
#

🤔 Tiny?

#

Are you making a Spigot fork or are you trying to make a plugin

hushed kiln
chrome beacon
#

Aight yeah now you're going to have to figure out how to make one of those mapping files

#

Or at least convert the maps Spigot uses

hushed kiln
patent prairie
#

Hi guys, quick question (as I can't test with spigot right now). Is the BlockBrushEvent called only when the brushing is complete or does it get called for each dusting stage?

buoyant viper
#

?jd-s

undone axleBOT
buoyant viper
#

i do want to go with every brush step

#

?stash

undone axleBOT
buoyant viper
#

it might be on fully brushed

meager wadi
# chrome beacon See https://github.com/PaperMC/paperweight-test-plugin as a base

I learned more about gradle (important stuff), made build through it and launched server through IDE (as I earlier did for breakpoints) - and hotswap works (yay)! So I suppose it was something about different building workflows (through artifacts or gradle). It wasnt just different names of resulting jar package as i noted were different - I tested with renaming to the same name. Internals of the jars seems to be the same except Manifest file - I dont know was that important or not. Maybe different names still matter internally somehow. I think something in building workflow was different, probably different paths for classes/jars or parameters

I made it work without those two gradle plugins you recommended, however I think I will setup those too. run-paper will make process perfect: I am not sure, do Paperweight userdev have this quick server run flow by itself? "Use this. Will help a lot" - I read about it (userdev) and didnt fully get it yet, what are main advantages of using it?

Thanks everyone

ivory sleet
#

w

patent prairie
# buoyant viper oh

The thing is that I looked at the code above that and it patches the brush method as well (so it seems to be called at every brush). That's why I can't understand

spare crypt
#

I've got kind of an odd situation, probably for a Resources Moderator.. I've been mostly the sole developer for a set of plugins for some time. They are posted on Spigot under another user (they manage the Spigot pages, I develop). That user has gone MIA. Is there a path I can go through to get ownership of the plugin pages to keep things up to date? Or am I forced to create new pages for the plugins?

chrome beacon
#

I don't think Spigot does transfers without the original authors permission

#

but you can try contacting support

#

?support

undone axleBOT
spare crypt
#

Yeah. Kind of hard to do when I can't get in touch with him 😂 I'll reach out to support!

vagrant stratus
chrome beacon
#

Yeah thought so

vagrant stratus
#

w/ the author being MIA they're kinda SOL

spare crypt
#

Yeah, that's too bad 🙁 I assume even with a new post, I'd have to make it a slightly different name? Anything against posting comments on the current pages directing users to the new ones?

prime tartan
#

hi, what is the event called when a player like clicks to switch spectate target state ?

young knoll
#

Apparently it’s the teleport event with the SPECTATE cause

worldly ingot
#

For future reference, Javadocs typically, including ours, have a search bar. Searching for "Spectate" yielded 1 result, which was the teleport event

vagrant stratus
#

?whereami

young knoll
#

Someone does in fact have events for it

#

You could make the event yourself by comparing Player#getSpectatorTarget each tick

round finch
#

?How

#

?When

mortal vortex
#

guys i gotta tell yall

#

Haze is actually an alt

#

the big Crozono himself

lilac dagger
#

Who's crozono?

thorn isle
#

rip bozono

cloud perch
slender elbow
#

frozono?

young knoll
#

What

#

Why is that a whereami

tender shard
#

I dont get it either

tender shard
vagrant stratus
tender shard
#

thx

thorn isle
#

TIL

quaint basin
#

when i say shut down i mean a forced shutdown

tender shard
#

?whereami

quaint basin
#

i alr fixed the msg

thorn isle
#

i think it might eventually get killed by the watchdog, but i wouldn't rely on it

#

i don't think the watchdog is in play during startup or shutdown

quaint basin
#

I think is it

thorn isle
#

30 seconds should be fine

#

just make sure it gets disabled eventually

quaint basin
#

Because I did Thread #sleep in ondisable and the server forced the shutdown

tender shard
#

Paper's watchdog stops when the server is shutting down when the server shuts down but not sure if that happens before or after disabling plugins

#

just do Thread.sleep for a minute in onDisable and try it out

quaint basin
thorn isle
#

off the cuff i think the watchdog has already stopped by that point , i remember having a server getting stuck for hours during an automatic restart because something like this blew up on disable and never returned

#

then again it could've been in onEnable, my memory is bad

#

tryitandsee

tender shard
#

chunk save during shutdown*

#

but no clue if that is/was before onDisable or not

thorn isle
#

myeah same, though that's far after onDisable's

young knoll
#

Multicraft used to kill stuff eventually

#

So I assume the server itself wouldn’t

quaint basin
#

Do you know how many seconds the watchdog allows the thread to be sleeped?

tender shard
#

but there's an env variable or setting to change that

#

anyway, today I learnt that mariadb has basic json functionality builtin

UPDATE job_users
SET collections = JSON_SET(
        collections,
        '$.walk',
        CAST(JSON_VALUE(collections, '$.walk') AS DECIMAL(20,2)) * 50
                  )
WHERE job = 'explorer'
  AND JSON_VALUE(collections, '$.walk') IS NOT NULL;

Works fine on a regular TEXT column with json data

thorn isle
#

however server shutdown is not normal uptime

#

i'm pretty sure the watchdog won't do anything there

#

even if something does kill the server eventually if shutdown gets stuck, it's definitely longer than 5 minutes by default

quaint basin
thorn isle
#

if that's a plugman reload it doesn't count

quaint basin
#

oh

thorn isle
#

that's not server shutdown

#

that's just plugins doing whatever at runtime

#

currently writing autocomplete suggestion support into my intellij agent harness, and I have a plan

quaint basin
thorn isle
#

i'll have a cheaper model running shitting out suggestions based on the original file contents and incremental diffs

#

but since it's a high throughput thing, it needs to be fast and snappy and therefore dumb

#

so i'll have another model running in parallel, actually paying some thought toward the diffs and try to figure out what i'm trying to do

#

i originally thought about making that reasoning visible in a chat sidebar so i can stay up to speed what it's thinking i'm thinking

#

however, the obviously superior solution is clippy

young knoll
#

Reloading a plugin with plugman just reloads it

thorn isle
#

i will have a fucking clippy gif popup going HEY IT LOOKS LIKE YOU'RE TRYING TO WRITE A LISTENER

young knoll
#

It doesn’t put the server into the shutting down state

quaint basin
#

ohhhh

#

it make sense now

thorn isle
#

now the only question left is whether the modal notification popups in intellij support playing gif's

quaint basin
#

~stop works as expected yea thank you

young knoll
#

How long does it take for your database transactions to complete anyway

#

Is your database on the moon

tender shard
#

must be on mars

#

moon is only like 1.5 seconds

thorn isle
#

looks like i can only include an animated icon

#

how small do you figure i can make clippy before it becomes unrecognizable

#

mmm there's no size limit on icons it doesn't seem like

slender elbow
#

i'm assuming sides of powers of two here

#

maybe 8x8 is doable

thorn isle
#

i don't think there's a power of two restriction for icons, i remember seeing weird ass resolutions like 13x13

slender elbow
#

but 16x16 is definitely doable

thorn isle
#

i'll see if i can load in a 128x128 icon, not sure what animated formats it supports though

knotty gale
#

can someone help me? I am trying to get this plugin to depend on another one, and I put the file into the external libraries folder. It is even filling in the blank when I try to refrence it but when I install the finished project it keeps telling me it cant find the packages of the plugin

tender shard
#

Simply declaring the dependency in plugin.yml is not enough

knotty gale
#

no no no I have both and I made both, I said I put the file into the external library

tender shard
#

please share both your plugin's plugin.yml files

#

also showing your server latest.log would be helpful

knotty gale
#
name: ScoreTracker
version: 1.0
main: me.datshrek.scoreTracker2.Main
author: datshrek
api-version: 1.20

depend: [BasketballMode]

commands:
  score:
    description: Score command
    usage: /score
  ref:
    description: Ref command
    usage: /ref
    permission: ref.use

permissions:
  ref.use:
    description: Allows referee commands
    default: op

the depending file

name: BasketballMode
version: '1.0-SNAPSHOT'
main: me.datshrek.basketballMode3.Main
api-version: '1.20'
author: datshrek

commands:
  bball:
    description: Start or end basketball mode
    usage: /bball <start|end>
  pos:
    description: Use different positions
    usage: /pos <guard|forward|center>
  startgame:
    description: Start the "Game mode"
    usage: /startgame
  practice:
    description: Pull up the practice GUI
    usage: /practice

the original

tender shard
#

looks good, share log please

knotty gale
#

okay, im new to this so how do I exactly get this log

tender shard
#

in your server directory there's a "logs" directory

#

inside is a file "latest.log"

#

you can open that with any text editor and just copy/paste it or upload it here directly

knotty gale
tender shard
#

your server doesn't start because yo uhave not accepted the eula

#

open the file "eula.txt" in your server folder and put "eula=true" instead of "eula=false" there

#

then server should start

knotty gale
#

no bro my server works and so do the plugins, the dependacy I am working on in an update isnt

tender shard
#

then you sent the wrong log file

#

the log file you sent clearly shows that eula wasn't accepted

knotty gale
#

I mean I havent even put these plugins into the server at its latest so matter what its going to be irrelavent

tender shard
#

eula.txt needs to be accepted no matter what plugins you install

#

you are using paper, do you have both a plugin.yml and a paper-plugin.yml in your plugin?

#

try with spigot or ask on paper's discord

thorn isle
#

what are you trying to do?

knotty gale
# thorn isle what are you trying to do?

I made these plugins a while ago in eclipse and they worked fine, now I want to update them and they are depended on each other. The dependancy wont work even though I have the file in the external jars and the ide is literally filling in the blanks for it

#

idk why this guy seems to be asking and trying to see the log as if it matters here

#

I legit js need to get this dependancy to work, nothing else

tender shard
thorn isle
#

are you failing to find a class at runtime or at compile time?

tender shard
#

hence they use legacy material names and fail to use modern material names

thorn isle
#

fosho

#

kind of got the impression that they're not having some dependency show up in their ide/build

#

but there definitely is a problem loading those plugins as well

tender shard
#

how are you building? maven? gradle? or through IDE directly?

knotty gale
#

maven

thorn isle
#

unzip the jar and look at the plugin yml in it

tender shard
# knotty gale maven

run mvn clean package, and then unzip the .jar and show the contents of plugin.yml

#

alternatively upload one of those plugins to github and share link

knotty gale
#

alright

wet breach
knotty gale
#

my power just went out im on my phone but thanks for all the help I appreciate the effort, ts is hella annoying

quaint basin
#

But sometimes the plugin might shut down when MySQL is turned off or something like that

scarlet crest
#

yo

lilac dagger
#

if the database queries are done via an executor you can just executor.awaitTermination(5, TimeUnit.MINUTES)

#

it'll block until transactions are finished

#

so you can close the database after safely

quaint basin
umbral ridge
#

XD

#

integer max HOURS

quaint basin
#

It's better not to have time out xd

buoyant viper
#

i mean 30 seconds is reasonable

lilac dagger
#

It's just a completely arbitary value i came up with

#

30 seconds does sound more than enough

lilac dagger
#

You could also pass an executor you want your completable future to use

ivory sleet
ivory sleet
#

actually probably not anymore, u could get away with virtual threads just

#

and then a semaphore to ratelimit

slender elbow
#

^

#

VTs and a semaphore to bound

lilac dagger
#

I didn't know about semaphores

#

Pretty cool

slender elbow
#

iiiii would place the acquire inside the VT runnable

#

but yeah

lilac dagger
#

Looks pretty nice

#

I still personally prefer executors

#

I just submit a query

slender elbow
#

sure you can do that too

quaint basin
slender elbow
#

you can also use an ExecutorService that spins a VT for each task

#

and bound it by semaphore

#

but pooling VTs is absolutely useless and counterproductive

lilac dagger
#

Yup

slender elbow
#

using an ExecService & semaphore you can also await for termination nicely

slender elbow
#

but you fire threaded tasks during runtime, then await termination in onDisable

#

but specifically when using hikaricp you don't really need a semaphore, as the library will already block when trying to acquire a connection but there are none available

umbral ridge
#

if player's inventory is full, does that mean item is dropped on the ground?

#

i forgot how this is usually handled, or if you need to manually handle this

smoky anchor
#

The returned HashMap contains what it couldn't store, where the key is the index of the parameter, and the value is the ItemStack at that index of the varargs parameter. If all items are stored, it will return an empty HashMap.

umbral ridge
#

thank you

#

so basically

#

XD

smoky anchor
#

well no

#

if some part of the itemStackReward was given to the player, this way you'd drop that as well
You gotta take the result of addItem method and drop the items from there

lilac dagger
#

Yeah, if the inventory can take 3 from the item stack and you had a reward of 64 you should only drop 61 and not 64

#

Which was the init reward

slender elbow
#

just do …addItem(reward).values().forEach(item -> world.dropItem(item))

lilac dagger
#

Pretty much :d

umbral ridge
#

😭

lilac dagger
#

What's this device?

umbral ridge
#

my ups

lilac dagger
#

What's a ups? Sorry if it sounds dumb

umbral ridge
#

power supply

lilac dagger
#

Oh

umbral ridge
#

if you lose electricity it can power up your devices for a certain time

lilac dagger
#

Oh that's amazing

umbral ridge
#

my network was running off from the battery

lilac dagger
#

I actually wanted something like this

umbral ridge
#

yeah its awesome

#

can be expensive

lilac dagger
#

Looks like it's out of juice

umbral ridge
#

no its good now

#

recharging

lilac dagger
#

Expensive purchase or maintenance?

umbral ridge
#

purchase

lilac dagger
#

I see

#

Yeah maintenance shouldn't be too hard

umbral ridge
#

PowerWalker vfi 2000 crm lcd if you google it

#

its a really nice ups

lilac dagger
#

It's a batttery with an cc to dc

#

Let me see

#

Looks nice

umbral ridge
#

yeah heavy too XD around 20kg

lilac dagger
#

Nice io

#

Yeah battery is quite heavy

#

You'd need quite a beefy one for a pc

umbral ridge
#

i guess yeah

#

i use it only for entire network, cameras etc

lilac dagger
#

Oh good

#

That's gonna last a while without power

umbral ridge
#

yeah around 3 hours..

lilac dagger
#

I expected more tbh

#

Camera aren't that power intensive

umbral ridge
#

i have nvr plugged in and one switch, one poe switch, rack fans and rack lights.. which are always on

#

also the main router

lilac dagger
#

Ah

umbral ridge
#

XD

#

i love it, im doing a plugin now which reads the entire network data, specifically ups power state, and if i lose electricity, plugin detects if ups is running on battery, and sends a warning in the global chat

#

really cool stuff

lilac dagger
#

Yeah thay sounds nice

#

I really like tinkering with stuff too

umbral ridge
#

yeah

#

i spend my entire weekends on this, when im at home

lilac dagger
#

Did you get it working?

umbral ridge
#

im working on it, right now im doing another plugin.. voting... adding this:

lilac dagger
#

Oh yeah

umbral ridge
#

since all is stored on db its a little more work

lilac dagger
#

You said something about making a vote service

umbral ridge
#

I already did it, but its for me for now really, and for my friends who play

lilac dagger
#

Still pretty cool

umbral ridge
#

yeaa XD

tender shard
#

does anyone know the correct CoreProtect repo / groupid / artifactId for their latest version? because their docs don't mention it and theit discord is dead

slender elbow
#

the repo is listed in the api docs 🤔

tender shard
#

I don't have enough free time to go the repo link manually and search it for possible artifacts, it should be provided in the docs directly

#

Imagine saying "yeah here's our api: [link to maven central]"

eternal night
tender shard
#

where?!

#

google "Coreprotect api" and you'll find this

eternal night
#

google skill issue idk, maybe google hates you

tender shard
#

oh yeah you're right, they do mention it on github

#

but not in the docs

#

weird

eternal night
#

docs are hard apparently ¯_(ツ)_/¯

tender shard
#

if one cannot keep up with writing proper docs, they shouldnt make any in the first place imho

#

especially since they are selling that piece of shit plugin

eternal night
#

Thank god we have AI for that now

young knoll
#

AI still can’t help me fix my problems

#

:/

tender shard
#

are your problems related to coding?

young knoll
#

Yes

tender shard
#

RIP coreprotect doesnt seem to support logging moving items between custom containers

ivory sleet
#

doesnt it have an api to log stuff like that?

tender shard
#

they seem to only support logging into actual containers and a diff between "inventory now" and "inventory next tick"

tender shard
ivory sleet
#

😭

tender shard
#

don't even question why "user" is a String instead of UUID

ivory sleet
#

goofy ah api

#

mb i really had the impression their api would be slightly more sophisticated

tender shard
#

their api for lookups is great

#

their API for logging things yourself is utter shit

#

guess we'll have to write our own logging shit plugin

#

because that's useless

ivory sleet
#

:,)

sly topaz
#

I think CoreProtect is the kind of thing nobody wants to replace because it is too annoying to do so

tender shard
#

yeah seems so

#

like PlotSquared