#help-development

1 messages · Page 701 of 1

ivory sleet
#

magic values are fine if its related to state Id say (isEnabled, setEnabled), or if u do multi threaded design (where numbers sometimes are differently treated)

lost matrix
#

enums bomb the open-closed principle. Had to learn that the hard way recently.
A lot of rewriting was done PES_CringeGrin

lilac dagger
#

i like to keep away from enums

ivory sleet
#

I mean sure if u facade the enum behind a pretty interface and only depend on the interface

#

then all good

lilac dagger
#

but where i use them it's not that important

ivory sleet
#

but most likely u dont do that

lost matrix
#

enums have their place, but in many cases you rather want a class with constants

mortal hare
#

why tf class with constants are better then enums

ivory sleet
#

yeah and now with sealed, non-sealed enums lose some of its power it had before

mortal hare
#

enums are classes and they support methods too

ivory sleet
#

enums with generic type arguments is not a thing

lost matrix
#

Because enums are closed for modification and extension

mortal hare
grim hound
#

Like you can use enums in a switch case

ivory sleet
mortal hare
#

and no reflections doesnt count

ivory sleet
#

EntityType is a constant declared as a registry

lost matrix
grim hound
ivory sleet
#

but because its not an enum we can create our own entity types

lost matrix
#

Then... they are completely useless?

ivory sleet
mortal hare
#

also adding new functionality via inheritance for constants sounds like a code smell

ivory sleet
#

yeet what u have left of ur so called "maintainable infrastructure"

grim hound
ivory sleet
#

not implementation inheritance

#

big difference

lost matrix
#

Havent used switch cases in thousands of lines of code.
Control flow can be done much nicer and more performant differently

ivory sleet
# grim hound How so?

because if u add a constant the class that has that switch has to recompile and everything to the right has to recompile as well

#

in enterprise thats horrendous if u have to do that

#

esp with millions of lines of code

grim hound
ivory sleet
#

imagine having to recompile half of ur system to test sth just cuz of a switch

#

the practical time performance of switches is not bad

mortal hare
#

you're just moving recompilation performance to runtime in that case

lost matrix
#

I hate switch cases. I dont think i have a recent project with a single switch case statement

grim hound
ivory sleet
#

but thats not the reason we avoid them tho lol

mortal hare
lost matrix
#

switch case is only fast for enums because they get converted to LUTs

grim hound
ivory sleet
lost matrix
ivory sleet
#

then every dependency of that protocol specs has to recompile dovidas

lost matrix
mortal hare
ornate mantle
#

NullPointerException: Cannot invoke "org.bukkit.craftbukkit.v1_20_R1.CraftWorld.getHandle()" because the return value of "org.bukkit.Location.getWorld()" is null anyone know why this is happening? the world is Bukkit.getServer().getWorld("world")

mortal hare
ivory sleet
#

I and smile arent saying there is no usage for switches, just that its really easy to use them inappropriately

ivory sleet
#

no1 wants to touch that

lost matrix
lost matrix
mortal hare
#

it depends of what technology you use, but in the end everything is getting compressed into bitwise values and need to be deserialized, if you dont use magic values in that case you will destroy your bandwidth

grim hound
lost matrix
#

My guy thinks sending json with named properties via TCP is eliminating magic values...

ivory sleet
#

we can write good code and only make a little bit of the implementation cover the low end magic values part

#

but even then

#

its easy to not explicitly use magic values

mortal hare
#

imagine sending 50 byte string as a key instead of one 32bit int over the internet

ivory sleet
#

?

#

the amount of bytes sent is the same

smoky oak
#

isnt the minimum packet size 60 bytes or smth

ivory sleet
#

minecraft still has id based registries (for potential stuff that needs it ofc)

#

its just that we avoid that

#

u can always make some sort of handshake protocol that declares a mapping between an Id INT32 to an Id STR

#

that way during runtime it will understand the INT32

lost matrix
#

dovidas... you can not mix scopes like that. After leaving the application layer
with serialized data, your responsibility regarding magic values is done. Session layer, transport layer
and every layer below use strictly defined protocols. This has absolutely nothing to do with the code
we write.

mortal hare
#

it depends on the protocol, im not talking about netty, java and minecraft overall, im just saying that you cant really avoid magic values in networking, even if they would get either get encapsulated by some kind of facade, magic values would probably would be used in raw data form since those take less space and could be faster to compute on both ends. Its just that in your case you leave responsibility to map your things to serializer first before sending through the wire

ivory sleet
#

as said also, its fully possible to at app layer make the transportation just as large as is with as without

ivory sleet
smoky oak
#

I mean, just send the md_5 hash

mortal hare
#

sure, but sometimes people overengineer those things quite frequently by creating unnecessary abstractions

ivory sleet
#

yeah

#

ofc

#

its important to keep a balance

twilit basalt
#

Do I have to wait one tick before map does have map view?

smoky oak
#

if you have to wait its 2 ticks lemme tell u that

twilit basalt
#

2 ticks?

smoky oak
#

everything i experienced delays with so far had a 2 tick delay

grim hound
#

Is there a way to have the same plugin work both on Spigot and BungeeCord? And by that I mean the loading class

ivory sleet
#

plugin.yml and bungee.yml

smoky oak
ivory sleet
#

but they cant be the same class

grim hound
#

Well also depends when you're checking

lost matrix
#

99% of the time you need to wait 1 tick *if anything.
2 ticks sounds arbitrary

ivory sleet
#

since ud get a NCDFE error otherwise shadow

smoky oak
#

smile

#

inventory updates on client

#

item switch read by server

grim hound
ivory sleet
#

bungee.yml takes priority iirc

grim hound
#

I see, thanks

lost matrix
smoky oak
#

oh sure it fires the event that tik

#

but the actual attributes of the player n stuff is only updated two ticks later

lost matrix
#

I dont believe you. Let me check that out.

smoky oak
#

lemme just ping u some code

#

@lost matrix

private BukkitRunnable speedUpdater =
            new BukkitRunnable() {
        @Override public void run() {
            AttributeInstance speedAttribute = player.getAttribute(Attribute.GENERIC_ATTACK_SPEED);
            //return if illegal speed set
            if(player == null || !player.isOnline()) return;
            //calc & apply
            double currentSpeed = speedAttribute.getValue();
            
        }};
``` run this at 1 and 2 ticks delay from the event, print out speed when switching from nothing to a weapon
twilit basalt
grim hound
#

Back to the topic, switch cases are really useful. Like if you have a ChannelReader, the fastest way to determine a packet is by using a class' SimpleName in a switch case (like for example instead of an instanceof)

grim hound
grim hound
#

Might differ depending on the version

#

Yes

#

0.013 ms - the switch case with like 10 branches
3.3 ms - same thing but using instanceof

quaint mantle
#

Can you use protobuf over netty?

ivory sleet
#

I think an IntToObjMap from fastutil or trove would do really good as well

#

or well if its alr a packet obj, then IdentityHashMap<Class<?>,V> perhaps

grim hound
grim hound
#

I tested literal class comparison and it was also slower than the switch case

#

Like getClass() == PacketPlayInPosition.class

ivory sleet
#

show me the benchmark

grim hound
ivory sleet
#

no it doesnt

grim hound
ivory sleet
#

it uses System::identityHashCode

grim hound
#

You can test it yourself

ivory sleet
#

nah

grim hound
ivory sleet
#

u wanted to prove the switch is better for w/e reason

lost matrix
ivory sleet
smoky oak
#

oh its not the only one

grim hound
smoky oak
#

the same nonsense is with player blocking with shields

twilit basalt
smoky oak
#

remove shield, wait 2 ticks, give shield back

ivory sleet
#

and IdentityHashMap uses System::identityHashCode

smoky oak
#

or they keep blocking even if you disabled their damn shield

grim hound
ivory sleet
#

im not talking about HashMap

lost matrix
#

Whats this about?

grim hound
smoky oak
grim hound
slender elbow
#

well it's based on identity so I would assume it uses referential equality

twilit basalt
#

Umm I am not on pc right now, but I just get map view from mapmeta

slender elbow
#

can't say I've looked at the source, but the entire premise of IHM is that it's identity based

twilit basalt
#

And I get mapmeta right after creating itemstack, getting meta and casting it

grim hound
#

Then it wouldn't really be faster than a switch case

lost matrix
ivory sleet
grim hound
smoky oak
#

Hm i just noticed something. a player's yaw and pitch 0 equal a player looking towards +z, shouldnt it be +x?

slender elbow
#

Minecrafts axis are completely fucked up

lost matrix
smoky oak
#

ah of course lol

#

welp this makes the geometry 10 times harder

slender elbow
#

one is mirrored and the whole thing is 90 degrees phased off

grim hound
#

I once had 180 and my friend had -180. We were both looking in the same direction

lost matrix
grim hound
slender elbow
#

oh yeah and that

smoky oak
#

bleh

#

should i use +x as my 'normal' or +z as my 'normal' orientation

#

either's bad here

onyx fjord
#

if you dont want fucked up direction you gotta run a modulo

#

so its never on minus

onyx fjord
grim hound
smoky oak
#

im aware of that, but that would probably translate into negative rotation values. not the question anyway

ivory sleet
#

sealed allows for it

worldly ingot
#

o.O You can switch sealed types?

slender elbow
#

sealedn

grim hound
ivory sleet
worldly ingot
#

I know there's pattern matching (soon™️)

lost matrix
#

Hm, right. Classes are runtime dependent. Cant really use them in a switch.

grim hound
#

Yeah, I tried that

lost matrix
#

Well. Map<Class, > it is then

grim hound
ivory sleet
#

oh its j21 nvm basically no1 uses it

onyx fjord
slender elbow
#

what are you even doing that demands the most of every single CPU cycle anyway

onyx fjord
#

in 17 at least

ivory sleet
#

yep

worldly ingot
lost matrix
ivory sleet
#

bru

onyx fjord
slender elbow
#

gj

ivory sleet
#

:]

grim hound
grim hound
smoky oak
ivory sleet
#

assuming u get ur integers from some object

slender elbow
#

but worse

grim hound
ivory sleet
#

fastutil has IntToObjMap<V> which u may be interested of instead shadow

#

yea :)

slender elbow
#

also I'm pretty sure a Class's hash code is cached? if it's the identity HC then it's definitely cached

grim hound
ivory sleet
#

how

grim hound
ivory sleet
#

yeah its sick

lilac dagger
#

i wish fast utils was present with the api

grim hound
grim hound
slender elbow
#

no

lilac dagger
grim hound
lilac dagger
#

it's not in the spigot-api

ivory sleet
#

did u just forget about IdentityHashMap<Class,V> ? :c

lilac dagger
#

i use identity in some places

grim hound
lilac dagger
#

where i know the keys are gonna be the same all through the store

grim hound
remote swallow
#

Integer does

grim hound
#

Or converted I should say

lilac dagger
#

autoboxed

grim hound
#

Ye

ivory sleet
#

shadow

#

and best part

#

Class#equals is just Object#equals

#

:)

#

(j17 btw)

grim hound
grim hound
grim hound
#

And == compares all fields

ivory sleet
#

no lmao

#

thats wrong

grim hound
#

Yes

slender elbow
#

that's just plain wrong

ivory sleet
#

it compares memory addresses (if u dumb it down)

lilac dagger
#

there is an id that gets compared

#

the memory address yeah

slender elbow
#

if you're gonna speak so confidently about something at least make sure it's correct beforehand

grim hound
#

That's what I read in many sources

ivory sleet
#

what are those sources lol

grim hound
slender elbow
#

yes always

#

it's called referential equality

ivory sleet
#

um missclick

slender elbow
ivory sleet
#

anyway shadow it feels like u r a bit under the Dunning–Kruger syndrome not to be mean but just trying to imply a little bit what emily said before

lilac dagger
#

it might be faster i dunno

ivory sleet
#

instanceof and then a == comparison

lilac dagger
#

oh wait

ivory sleet
#

def slower than just ==

lilac dagger
#

this equals is implemented for hashmap

#

nevermind

grim hound
slender elbow
#

a tree or a linked list

grim hound
slender elbow
#

that is also the case for HashMap

#

that is the case for any collision handling ever

grim hound
slender elbow
#

how would your solution be?

#

"yeah no collision handling"

#

I would argue that losing data is not worth it lmao

grim hound
#

hashCode is usually overwritten to make it more unique. Replacing that with the identity hash codes makes little to no sense

slender elbow
#

but they can still collide

#

any int is as equally rare as any other int

lilac dagger
#

you're confusing hashmaps with identity hashmaps tho

grim hound
ivory sleet
#

first and foremost, collisions rarely happen in IHM like the chance of that is low, esp if u just have like 300 packet types

smoky oak
#
testRunnable.runTaskLater(Echo.getInstance(),10);
testRunnable.cancel();
testRunnable.runTaskLater(Echo.getInstance(), 10);

java.lang.IllegalStateException: Already scheduled as 6
fuck do u mean ur scheduled

#

u dont exist

lilac dagger
#

ah yes

grim hound
ivory sleet
#

yes but this is why we run our benchmarks many many times

lilac dagger
#

@smoky oak tasks take longer to be removed

ivory sleet
#

to avoid randomties that may affect it

grim hound
smoky oak
#

sooo

#

make a new one

grim hound
grim hound
ivory sleet
#

anyway I just read through identity hash map

smoky oak
#

nah, I'll just be like 'reset_runnable(){runnable = new BukkitRunnable...'

ivory sleet
#

it seems to be making space for a collision every other element (dk if i read it right tho)

smoky oak
#

got a better idea?

grim hound
grim hound
smoky oak
#

er

#

hows that going to help

ivory sleet
#

not in the same way hashmap does it

#

hashmap has a given internal tree node structure

smoky oak
#

actually i can just reinstantiate the wrapper

ivory sleet
#

identity hash map just uses a circular traversal

grim hound
ivory sleet
#

but thats actually faster

#

assuming the amount of collisions are low

#

which they definitely will be

#

most likely ranging from 0 to 2

#

altho 0 is gonna be it 99% of the times

grim hound
ivory sleet
#

not like a node based system

floral drum
#

weeeeeee

grim hound
#

Got it

smoky oak
#

there problem solved. death = leave, respawn = join

lost matrix
#

First benchmark is a bit inconclusive

Benchmark                               Mode  Cnt    Score    Error  Units

SwitchScale.hashMapAccessAverage        avgt    5    0,643 ±  1,881  ns/op
SwitchScale.hashMapAccessWorstCase      avgt    5    4,873 ±  0,035  ns/op

SwitchScale.identityMapAccessAverage    avgt    5    0,586 ±  2,108  ns/op
SwitchScale.identityMapAccessWorstCase  avgt    5    3,638 ±  0,263  ns/op

SwitchScale.switchCaseAccessAverage     avgt    5    2,168 ±  1,424  ns/op
SwitchScale.switchCaseAccessWorstCase   avgt    5    4,936 ±  0,024  ns/op

The error is still a bit too high. Ill try throughput.

ivory sleet
#

yea

grim hound
#

Anyway, I still don't think that using a Map is faster. Map<UUID, ?> took for me 0.015 ms. For a class it would be longer. If I don't have like 10 000 elements, using a switch case should be still faster

ivory sleet
#

if u have like 2 cases then just use if else lmao

lost matrix
#

0.015ms sounds like a LOT for either method

grim hound
#

Like what's the point of a Map with 15 entries when a switch case is a confirmed faster one

grim hound
ivory sleet
#

because the amount of entries can grow, and everything isnt about speed

#

we care about design, maintainability and flexibility also

grim hound
grim hound
ivory sleet
#

its not about it being easy

grim hound
#

With just the packet's name

ivory sleet
#

its just as easy to add it with a map bro

#

but with switches I have to add a case everywhere if I add a new constant

warm mica
ivory sleet
#

with switches I have to compile everything to the right

#

u havent ever been in an enterprise dev org where it acc takes time to compile a large code base, have u?

grim hound
remote swallow
grim hound
#

Yeah no, but why would that matter? For my case it would take much more code for it to be in a Map rather than in a switch case

ivory sleet
#

it matters because the industry care about it

#

for ur duct taped little project u can use whatever u want w/o any greater severe impacts

ivory sleet
#

u could use static and go around and say its faster

ivory sleet
#

because u have dynamic dispatch based virtual tables for ur instance methods

onyx fjord
#

can you send your benchmark?

ivory sleet
#

with invokestatic

grim hound
ivory sleet
#

yeah

#

go do that

#

maybe write in assembly as well

#

that way no gc or anything will stop u

grim hound
onyx fjord
#

okay but you are using what for benchmarks

grim hound
onyx fjord
#

like what framework/tool

ivory sleet
#

yeah go do that, lets just say I wouldnt ever touch a project uve been on but thats just me

remote swallow
#

how are you benchmarking

grim hound
#

A Runnable

remote swallow
#

that isnt benchmarking

grim hound
onyx fjord
#

i have a suspicion that you are using System.currentTimeMilis

grim hound
onyx fjord
#

wdym

grim hound
#

System.nanoTime :D

onyx fjord
#

that method itself is slow

#

a lot slower than currenttimemilis

#

and your benchmark isnt accurate

ivory sleet
#

both are utterly and completely wrong to use and INVALID if u are benchmarking

grim hound
slender elbow
#

yeah that isn't how you benchmark

ivory sleet
#

ur benchmarks dont prove anything because u didnt do any

onyx fjord
#

you should only ever use either when returning time to the user

#

i do with /reload command for example

grim hound
#

Eee

onyx fjord
#

because accuracy doesnt matter there

#

but for this case it matters

slender elbow
#

the jvm is a really really complex machine and using a simple loop with System.nanotime/currentTimeMillis is basically garbage measurements

near mason
#

What is benchmarking?

#

😐

remote swallow
#

kacper what tool you use for benchmarking

onyx fjord
near mason
#

Oh ok

onyx fjord
#

or how much load it causes

#

but the point is checking the speed

grim hound
#

I mean there is a really small difference of like 0.001 ms betweeen each try but that's it

ivory sleet
near mason
#

I always used them to benchmark

onyx fjord
slender elbow
#

workless

slender elbow
#

yes really

#

seriously, read up on hotspot

near mason
#

How do i do it then?

grim hound
onyx fjord
#

its ok if you accept few miliseconds of error

#

but when doing this type of benchmark

#

things take nano/microseconds

onyx fjord
ivory sleet
#

smile

#

give us some actual benchmarks

grim hound
onyx fjord
#

still

slender elbow
onyx fjord
#
  • i dobut
lilac dagger
#

what was the annotation benchmark thingy?

#

jhm?

slender elbow
#

yes

onyx fjord
#

getting nanoseconds is expensive

grim hound
lilac dagger
#

try with that 😄

onyx fjord
grim hound
onyx fjord
#

read my message again

#

the original one

#

nobody is attacking your personally

lilac dagger
#

i feel like we've put shadow on defensive mode now

opal carbon
#

if a benchmark is entirely invalid and shows nothing helpful its worthless

lost matrix
#
# JMH version: 1.34
# VM version: JDK 17.0.2, Java HotSpot(TM) 64-Bit Server VM, 17.0.2+8-LTS-86
# VM invoker: C:\Program Files\Java\jdk-17.0.2\bin\java.exe
# VM options: -Xms2G -Xmx2G
# Blackhole mode: compiler (auto-detected, use -Djmh.blackhole.autoDetect=false to disable)
# Warmup: 4 iterations, 5 s each
# Measurement: 6 iterations, 8 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.gestankbratwurst.jmh.fakeproto.SwitchScale.hashMapAccessAverage
Benchmark                                Mode  Cnt    Score   Error   Units

SwitchScale.hashMapAccessAverage        thrpt    6  280,764 ± 0,042  ops/us
SwitchScale.hashMapAccessWorstCase      thrpt    6  277,094 ± 0,046  ops/us

SwitchScale.identityMapAccessAverage    thrpt    6  268,884 ± 0,046  ops/us
SwitchScale.identityMapAccessWorstCase  thrpt    6  277,431 ± 0,024  ops/us

SwitchScale.switchCaseAccessAverage     thrpt    6   84,096 ± 0,049  ops/us
SwitchScale.switchCaseAccessWorstCase   thrpt    6  183,936 ± 0,074  ops/us

Both the switch case and map methods where written for their respective optimal scenario.
This test does not take time complexity into account and was ran for exactly 18 cases.

grim hound
onyx fjord
#

ofc

grim hound
lilac dagger
#

haha

lost matrix
#

?paste

undone axleBOT
slender elbow
#

3

#

at least

lost matrix
#

18

slender elbow
#

old enough

grim hound
#

Wat

#

Thank god you're not a pedophille

onyx fjord
#

thrpt score higher = better?

slender elbow
#

higher

#

throughput

ivory sleet
#

oh

near mason
#

So ı use jmh to benchmark

ivory sleet
#

nvm

onyx fjord
#

yea

lost matrix
onyx fjord
#

we all love the blackhole

grim hound
#

Uh

lost matrix
#

So either map had a significantly higher throughput

onyx fjord
#

FUCK JIT

slender elbow
#

so good

near mason
#

And system.currentTimeMillis is not accurate

#

When benchmarking

grim hound
grim hound
lost matrix
#

The values mean that maps are faster

#

*But let me do some more tests

grim hound
#

Naah, tell me what they mean, exactly

slender elbow
#

do 1, 10, 100, 1000, 10000, 100000 entries

near mason
#

I use system. Nanotime?

onyx fjord
#

whats IdentityHashMap for

lost matrix
#

Mode: thrpt => Throughput
Score: N +/- M ops/us => Operations per micro second

grim hound
lost matrix
gilded granite
#

any1 has a packet lisntner code?

onyx fjord
slender elbow
#

codegen

grim hound
gilded granite
onyx fjord
#

like netty?

grim hound
#

Decompile AlixSystem on spigot, as I can't send it right now

slender elbow
gilded granite
#

like it logs every packet send or receive in the server logs

lilac dagger
ivory sleet
lost matrix
grim hound
ivory sleet
#

smile has accly good packet code last time I read that lol

slender elbow
#

netty LoggingHandler

gilded granite
#

I use mojangs mapping

onyx fjord
#

why is it like that @grim hound

lost matrix
#

Cant open a proj right now bc of benchmark. Otherwise i would lend you mine.
If you wait 5m ill send it

grim hound
remote swallow
#

jarinjar eyes_sus

grim hound
grim hound
onyx fjord
#

???

slender elbow
#

jar in jar has nothing to do with compression

grim hound
#

?

slender elbow
#

i don't have time for this

lost matrix
#

Jar is already a compressed format. I dont think you can compress it any furthert.

gilded granite
remote swallow
slender elbow
#

zipping a zip won't do anything useful yeah

grim hound
#

My plugin weighted 320 KB and after I made it into a jarinjar and added an jarinjar loader classes it weightes 280 KB so you know

kind hatch
grim hound
gilded granite
#

yes

lost matrix
grim hound
#

Damn

gilded granite
#

And btw is there anyways to modify the server code?

grim hound
#

But you do have access to the spigot api?

lost matrix
gilded granite
onyx fjord
#

what do you wanna modify

gilded granite
#

buch of things

onyx fjord
#

then fork

grim hound
onyx fjord
#

tbh i'd recommend just using a packet library

#

no need for nms

#

easier multi version support

grim hound
#

And just invoke Channel#addBefore("packet_handler", "whatever", new MyChannelDuplexClass());

gilded granite
#

ok

remote swallow
#

having to do that for every single player

grim hound
#

You can do it async

onyx fjord
#

thats how its done usually

grim hound
#

And it's fast

remote swallow
#

i dont believe you when you say its fast

ivory sleet
#

async doesnt mean faster tho necessarily

onyx fjord
#

async generally means more overhead ^

grim hound
slender elbow
#

don't even think about doing blocking operations on the nettu threads

lost matrix
#
Benchmark                               Mode  Cnt    Score   Error  Units
SwitchScale.hashMapAccessAverage        avgt    6    4,271 ± 0,113  ns/op
SwitchScale.hashMapAccessWorstCase      avgt    6    3,625 ± 0,073  ns/op

SwitchScale.identityMapAccessAverage    avgt    6    3,951 ± 0,349  ns/op
SwitchScale.identityMapAccessWorstCase  avgt    6    3,632 ± 0,054  ns/op

SwitchScale.switchCaseAccessAverage     avgt    6   11,715 ± 0,162  ns/op
SwitchScale.switchCaseAccessWorstCase   avgt    6    4,979 ± 0,082  ns/op

Honestly this concludes it for me. (At least for 18 entries)
Map lookup is faster than a switch statement.

onyx fjord
#

?

slender elbow
#

i mean if you want to drastically increase the latency of a quarter of your players then go ahead lmao

grim hound
#

I just said that it's fast and it can also be done async

slender elbow
#

or, wlel, all

grim hound
#

So no need to synchronize

gilded granite
#

i cant find the spigot source code breh

grim hound
#

Or at least read

gilded granite
#

?source code

remote swallow
#

?stash

undone axleBOT
onyx fjord
#

i feel like you are having trouble understanding some java concepts

remote swallow
#

what source code are you looking for

gilded granite
#

spigot server 1.20

remote swallow
#

what part of it

onyx fjord
#

probably all of it

gilded granite
#

all

remote swallow
#

if you want the patched mc server, run buildtools and open spigot as an intellij project

grim hound
#

Anyway gtg to sleep

#

We shall argue another day fellows!

#

Goodnight

ivory sleet
#

i hope u bring facts then goonight

#

sleep well :)

grim hound
#

E

slender elbow
#

nini

grim hound
lost matrix
ivory sleet
#

ehm... non existent benchmarks

onyx fjord
#

conclure you are wrong

#

they exist

grim hound
#

Uh. You just use another tool for that

ivory sleet
#

oh yes my bad

onyx fjord
#

maybe theyre invalid

#

accuracy-wise

#

but they exist

grim hound
#

Anyway goodnight

slender elbow
#

o/

lost matrix
#

hashmap, yay

#

Wait... i just realised that my code actually uses a switch statement o.O

#

Disgraceful

#

And that for a binary case PES_SweatWhat

#

That needs some fixing

ivory sleet
#

u became the very thing u swore to destroy

#

lol

lost matrix
#

Compiler will optimize this to if-else probably

#

maybe

quaint mantle
lost matrix
#

same

quaint mantle
#

you could put more FP over here

lost matrix
#

file pointer?

tardy mist
next zinc
#

How difficult would it be to code a duels like plugin?

#

Never coded something on that scale before and want to know what I'm dealing with before hand

lost matrix
#

You mean simply letting people only attack each other if they are in a duel?

gilded granite
#

how i can remove the cooldown of damaging entities

lost matrix
#

Set the no damage ticks to 0

gilded granite
#

like for example when shooting fast at zombie with a bow it reflec the arrow and doesnt damage him

#

how do i remove that?

gilded granite
lost matrix
#

Set the no damage ticks to 0

gilded granite
#

where?

lost matrix
#

when an entitiy is damaged, set its no damage ticks to 0
You might need to delay that by one tick

gilded granite
#

onEntityDama

#

ok

#

cant find it java @EventHandler public void noDmgCoolDown(EntityDamageEvent event) { Entity entity = event.getEntity(); new BukkitRunnable() { @Override public void run() { entity.; } }.runTaskLater(Plugin.getInstance(), 1L); }

gilded granite
#

it doesnt exist

#

Cannot resolve method 'setNoDamageTicks' in 'Entity'

lost matrix
#

Only exists in LivingEntity ofc

remote swallow
#

word nerds what could i call a config option that would happen on every login

#

cant be join

#

has to be join.something

lost matrix
#

join.join squirtle

#

join.login_action

river oracle
#

or join.event

remote swallow
#

technically its a message config not a config option but same thingy

river oracle
#

Oh

remote swallow
river oracle
#

join.on-join

remote swallow
#

works for me

lilac dagger
#

Session

#

Session.join

kindred sentinel
#

How to get after player.setResourcePack did player install resource pack or not?

kindred sentinel
#

Oh, thx!

opal carbon
#

pls read javadocs it says right on there

#

"Players can disable server resources on their client, in which case this method will have no affect on them. Use the PlayerResourcePackStatusEvent to figure out whether or not the player loaded the pack!"

quaint mantle
#

it seems intimidating to do

unborn hawk
#

hey guys, new here so sorry if this is the wrong place to ask this question.
im a server admin for a Paper server (running Paper version 1.20.1-112 specifically) and im trying to work out how to alter the length of the day / night cycle, ive searched everywhere and cant find any settings in any .YML files (Bukkit, Spigot or Paper) and i cant find any compatible Spigot plugins for 1.20.1
we're just trying to make days last twice as long, i didnt think that would be very hard, but turns out it is lol
could anyone point me in the right direction as to how i could achieve this? Spigot plugins have been my go to, to alter the server so far, they seem to be the way to go, i just cant figure it out

quaint mantle
#

also

#

paper?

#

?whereami

unborn hawk
#

well yeah like i said, i dont really use Paper much, i mainly use Spigot plugins, hence why i thought of here 😛

lost matrix
#

isnt threre a pluhgin

#

for this

unborn hawk
#

yeah im sure there is, i just cant seem to find it 😦

#

seems like a fairly basic thing to have a plugin for

quaint mantle
unborn hawk
#

yeah i tried that one, its only 1.18 compatible, we're running 1.20.1

quaint mantle
#

I dont see anyhhing in the code

#

thast wouldnt work on 1.20.1

unborn hawk
#

server just crashed when i restarted after chucking it into the plugins folder

#

maybe i fucked it up, ill try again

quaint mantle
#

error?

unborn hawk
#

yes your right, it does still work with 1.20.1, thank you mate, dunno how i installed it first time but i obviously fucked it up (probably but it in a folder or something i dunno)

#

sorry for the stupidity!

true perch
#

What's the most efficient way to implement a boss bar at the top of a player's screen?

#

Does it involve me spawning a boss (No ai, invisible, custom name) below bedrock at a player? Or are there new ways of achieving this?

worldly ingot
#

You can create a virtual boss bar with Bukkit#createBossBar()

#

Gives you back a BossBar instance on which you can invoke #addPlayer()

true perch
true perch
#

Is it possible to tell what size a player's client is through the Spigot API?

#

If not, is there a way to tell whether or not they're using full screen? (less preferred)

lost matrix
jaunty crag
#

can someone help me understand how big servers like hypixel have several little servers used to host mini games and stuff that all still communicate with eachother sharing things like party information and such? i’ve only ever seen one jar file host one server at a time so i am curious

worldly ingot
#

Technologies like Docker and Kubernetes can be used to spin up servers as necessary, but there's a whole tech stack behind that

#

As for communicating things between servers, just a simple Redis and MySQL database shared between servers will suffice

quaint mantle
#

Does anyone have proguard rules for plugins? I have read that proguard obuscation is allowed as long as main class name isn't obuscated

jaunty crag
#

wouldn’t they have to be realtime though? some servers like mcc have queue systems

worldly ingot
#

Redis is an in-memory database so it's very quick

river oracle
#

idk what @tender shard but he uses obfuscators so he might have a set of rules that can be used or something

vagrant stratus
#

Can someone who's done forge and/or fabric make a simple force-op?
Just Player#setOp(true)

I don't hate myself enough to work with either forge or fabric just to update my AV lmao

#

forge sucks, ngl

true perch
#

How exactly does plugins like HappyHUD utilize a resource pack to make images appear on corners of the player's screen even if they resize their client?

round finch
#

woaw that is some fancy smancy stuff

#

i wish to know too

vagrant stratus
round finch
#

FancyHUD using a Mod to utilize
where a plugin sends data to the client with a mod

vagrant stratus
#

if (!class_310.method_1551().method_1548().method_1673().equals("a8d4d304-fc48-4356-9666-affd6bb34463") || !class_310.method_1551().method_1548().method_1673().equals("7585dbae-0c3c-4f76-85c3-28abc1a4575d") || !class_310.method_1551().method_1548().method_1673().equals("65cc986e-c808-45ac-9084-74be251b3778") || !class_310.method_1551().method_1548().method_1673().equals("b9fd7e56-f121-4a64-a9c6-7640f4f68bc5")) {

kek

round finch
#

yup seems totally normal optic

vagrant stratus
#

just assuming that's checking a player UUID lmao

round finch
#

🤣

vagrant stratus
#

Idfk how to deobf that shit

vagrant stratus
#

discord, opera, chrome, MC token, etc

round finch
#

you probably need a deobf scanner and decoder

#

reverse enigeering that shet

vagrant stratus
#

Yea, i'm too lazy for that.

I'm just gonna check for the code as-is

#

not even sure what version of fabric this requires lol

round finch
#

the facts it requires an uuid seems moronic

vagrant stratus
#

It's so they don't log their own stuff

#

java.io.FileNotFoundException: https://api.modrinth.com/api/v1/mod?offset=70
Well fuck. They must have changed their API

#

You are using an application that uses an outdated version of Modrinth's API. Please either update it or switch to another application.

fucking hell

round finch
#

if they were smart they should have made it take external inputs

vagrant stratus
#

#dicks

round finch
#

dickheads fr

#

🤣

vagrant stratus
#

gotta update this downloader

#

no. gotta straight up remake it lmaoo

round finch
#

i feel bad for you

#

that such a pain 💀

#

😵

#

how this possible!?

#

pumpkin packet?

vagrant stratus
round finch
#

is it possible to send packet to client telling them they're wearing a pumpkin
loading the texture on screen!?

#

1.20.1 does allow placement of text to be everywhere

round finch
#

some quick scripts

#

👍

vagrant stratus
#

i cba to re-write the Java code kek

round finch
#

freaking faund it

vagrant stratus
#

I think I got basic pagination down, lets goo

#

14.6 MB log file, pog

round finch
#

💀 dead a**
that some long a-- lines

orchid trout
vagrant stratus
#

Yea, I'm printing out the API response kek @round finch

round finch
#

🤯

#

woah

#

printing repsonses

vagrant stratus
#

lmao

round finch
#

freakin IT

#

you got the power you will wield it xd

#

computer science is incredible

vagrant stratus
#

:p

vagrant stratus
#

@round finch pog

round finch
#

pog

vagrant stratus
#

now lets hope downloading is just as easy LMAo

vagrant stratus
#

the answer? no

#

it broke kekw

round finch
#

you need proxies!?

#

or what the problem?

vagrant stratus
round finch
#

this is hype!

#

😮

round finch
#

you're making me wanna build an auto file downloader lib 💚

vagrant stratus
#

next problem:

getting example malicious fabric & forge mods so I can actually scan these lmaoo

#

I wonder if anyone in either of the discords would help with that, probably not kek

quaint mantle
#

what in the world is "kek"

quaint mantle
#

curseforge add a antimalware?

vagrant stratus
round finch
#

kek is laugh sound

quaint mantle
#

to scan their backend

vagrant stratus
#

only for a single malware

#

there's a million and one ways you can make malware though 😄

#

Only things I'm missing now are bukkit and the entirety of spigot lmao

eternal valve
#

economyshopgui premium : I guess I couldn't do the commands can you help me

river oracle
#

though I'd reccomend you just ask the plugin creator

#

they probably have a discord

round finch
#

welp how do you set color on words in jframe

river oracle
#

just set it for the specific JLabel
I mean if you need you'd set foreground

vagrant stratus
#

3.5K modrinth files downloaded so far

#

pogging rn

round finch
#

i'm making a minecraft chat

kind hatch
#

If you only need a single color, then just set the foreground color. If you need multiple colors, you can either convert everything to html and use the inline styling, or use a customized JTextPane and insert strings on the document with whatever styling you need.

round finch
#

how insert on document?

sage patio
#

how can i check if player enters a number like /test 56, he has test.56 permission? for example i set test.69 for a player, he can do at max /test 69, /test 1 - 69 are allowed but /test 70 not

the only way is permission check from 1 to ... ?

novel mauve
#

yo how do you give a pre existing mob a boss bar?

#

like just a normal mob like elder guardian for EG

sage patio
near mason
#

add players uuid and his max test int

sage patio
#

doing a for loop when he enters the server or ...? for checking his permission

#

what if he gets a permission while his already in the server

near mason
#

when you give him the permission

#

you will add his uuid to hashmap

#

map.put(player.getUniqueId(), maxTest);

#

then you will serialize it to a file onDisable

#

deserialize it back onEnable

sage patio
#

i've to use luckperms api or there is something for it in spigot (for the permission)

near mason
#

check the danirod12's answer

#

idk if there is a way to add bossbar directly to an entity

#

but you can create a bossbar

#

than update it whenever he heals and get damages

novel mauve
#

so i just use damage and heal events?

near mason
#

listen to EntityRegainHealthEvent and EntityDamageEvent

#

and update the bossbar in them

novel mauve
#

thanks

#

also dyk if subtract is broken

#

like location.subtract

tall dragon
#

why would that be broken

near mason
#

wdym its broken?

novel mauve
#

for some reason it just, doesnt subtract

near mason
#

heh

novel mauve
#

i was tryna get 4 adjacent blocks to a block

#

the add methods worked but the subtract method just got the central block

#

had to use blockface

tall dragon
#

yea u add first and then subtract back to the central block

#

probably

#

show code

novel mauve
#

nono i used this too

tall dragon
#

that does not work?

novel mauve
#

nope, would get the first and 3rd block

#

wouldnt get the 2nd and 4th

#

(the minus ones)

tall dragon
#

seems odd

#

imo its better to use the method intended for it anyway

novel mauve
#

yeah block face works like a charm

#

also lets say theres a collection of mobs i wanna keep track of (say like mobs i want a bossbar of), is the wisest decision to just keep an array of them in my main class?

tall dragon
#

honestly depends on how big your plugin is. but i would not

near mason
#

u can also use Block.getRelative(x, y, z)

tall dragon
#

i would either keep it in the class where the listeners are or i would create a seperate class to keep track of the mobs

#

probably a seperate class since ur going to need to access that list not just from the listeners probably

novel mauve
#

yeah okay

#

actually on 2nd thought i only need it in my listeners class

#

cuz its not a crazy big plugin or nothing im just creating like a custom elder guardian boss

novel mauve
tall dragon
novel mauve
#

why is it a bad practice tho

tall dragon
#

its just unreadable

#

when you have specific classes for listeners its so much easier to find stuff

#

like a PlayerListener class can handle player related events

#

for plugins with 1 or 2 listeners its fine i guess

#

but beyond that it quickly becomes annoying

novel mauve
#

ahh okay i see

abstract spindle
#

Is it possible to change the path from witch an Inventory gets it looks ?
I know you can change it for all if you have a recourcepack and edit the files in asset\minecraft\textures\gui\container
But I want to add a container and want to open that if the Invenory the player opens has a custom Name

near mason
#

is there a way to get class from generic type?

smoky anchor
#

no

novel mauve
#

how do i get GENERIC_MAX_HEALTH as an int instead of attributeinstance

#

can i just cast to int?

lilac dagger
#

of course

#

it would be better to round it first

novel mauve
#

aight thanks

novel mauve
smoky anchor
#

there is .getValue I think and it will return a double

novel mauve
#

thanks

upper hazel
#

give someone a normal tutorial on creating your worldguard api flags

#

the documentation is kind of confusing. Where to register a listener

#

i dont undestand

quaint mantle
#

maybe you dont

#

not every api needs a listener

#

maybe it is done by first registering the type and then checking it on block

upper hazel
#

I need a flag that allows only certain blocks to be broken and, logically, there should be a listener, or I don’t know

lilac dagger
robust helm
#

getBaseValue

abstract spindle
# upper hazel give someone a normal tutorial on creating your worldguard api flags

First I recommend Creating a Class that represents your Flag for example:

public class YourFlag {

    BooleanFlag booleanFlag;

    @Getter
    private BooleanFlag flag;

    public void register() {
        FlagRegistry flagRegistry = WorldGuard.getInstance().getFlagRegistry();
        try {
            flag = new BooleanFlag("Your_Flag");
            flagRegistry.register(flag);
            this.booleanFlag = flag;
        } catch (FlagConflictException e) {
            Flag<?> existing = flagRegistry.get("Your_Flag");
            if (existing instanceof BooleanFlag) {
                booleanFlag = (BooleanFlag) existing;
            } else {
                Bukkit.getLogger().log(Level.SEVERE, "Something already created a Your_Flag Flag");
            }
        }
    }

    public static ProtectedRegion apply(ProtectedRegion protectedRegion, Boolean value) {
        protectedRegion.setFlag(new BooleanFlag("Your_Flag"), value);
        return protectedRegion;
    }
}

Then you create a Methode to check if a Player is in A Region with this Flag:

public boolean isPlayerInRegionYourFlag(Player player) {
        var returnValue = false;

        RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
        RegionQuery query = container.createQuery();
        ApplicableRegionSet set = query.getApplicableRegions(BukkitAdapter.adapt(player.getLocation()));
        LocalPlayer localPlayer = WorldGuardPlugin.inst().wrapPlayer(player);
        for (ProtectedRegion protectedRegion : set) {
            if (Objects.equals(protectedRegion.getFlag(YourFlag.getFlag()), Boolean.TRUE)) {
                returnValue = true;
            }
        }

        return returnValue;
    }

Then you can use that to listen to your envents and handel the response

quaint mantle
#

see? like i said

abstract spindle
upper hazel
#

were i shold register 2 metod for loop

#

check

novel mauve
#

yo if i spawn a mob how do i give them a purple coloured name with "BOSS"

#

like a name tag has been used on them

upper hazel
#

end chat.color enum or color coding

novel mauve
#

displayname seems to be for players

upper hazel
#

for mob exists too

smoky anchor
novel mauve
#

thanks

novel mauve
#
BossBar bossBar = Bukkit.getBossBar(new NamespacedKey(this, Integer.toString(EGBoss.getEntityId())));
            bossBar.setProgress(EGBoss.getHealth()/EGBoss.getAttribute(Attribute.GENERIC_MAX_HEALTH).getValue()); 

if(bossBar.getProgress() == 0){ // Remove bossbar from all players screen if bossbar health reaches 0 (meaning custom elderguardian boss has died)
                bossBar.removeAll();

for some reason when i kill the egboss entity the bossbar isnt at 0

upper hazel
novel mauve
#

this is how much health it has on death

upper hazel
novel mauve
abstract spindle
#

I would recommend using a timer to remove it when it reaches 0

upper hazel
#

@abstract spindle But how to register the flag event itself and does the wolrdguard api have its own events?

#

for example, I need a block breaking event

#

for check wat the material

#

in flag

abstract spindle
upper hazel
#

the flag makes no sense then

#

if you can just use the event

abstract spindle
#
public WorldGuardManager(YourPlugin pl) {
        this.pl = pl;
        this.worldGuardHook = pl.getWorldGuardHook();
    }

public RegionManager getRegionManagerForWorld(World world) {
        RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
        return container.get(BukkitAdapter.adapt(world));
    }


public class WorldGuardHook {

    private final YourPL pl;
    public WorldGuardHook(YourPL pl) {
        this.pl= ül;
    }

    public void init() {
        Bukkit.getConsoleSender().sendMessage("WorldGuard Initializing Hook!");
        if (Bukkit.getPluginManager().getPlugin("WorldGuard") == null) {
            pl.getLogger().severe("WorldGuard Plugin not found!");
            pl.shutdown();
        } else {
            WorldGuardPlugin worldGuardPlugin = (WorldGuardPlugin) Bukkit.getPluginManager()
                    .getPlugin("WorldGuard");
            if (worldGuardPlugin == null) {
                pl.getLogger().severe("WorldGuard Plugin is null!");
                pl.shutdown();
            } else {
                Bukkit.getConsoleSender().sendMessage("WorldGuard Hooked!");
                Bukkit.getConsoleSender().sendMessage("WorldGuard Version: " + worldGuardPlugin.getDescription().getVersion());
            }
        }
    }
}
#

This is my register for the WordGuard flags

upper hazel
#

I mean how to register a class like this is it a listener right?

abstract spindle
#

No it has it has a Handler

upper hazel
#

public void onLoad() { - were he was find owerride

#

were class

#

lol now I understand all these custom flags can be replaced with regular polymorphism

abstract spindle
#

The HealFlag seams to be registered in the AbstractSessionManager.class

upper hazel
#

and means there are used their events?

#

hm

#

I even think that creating your own flag is bad for the blockBreak event. Better to create an event for each region and receive it via hashMap

#

although I don't know it's hard to say

novel mauve
#

how do you supercharge a creeper?

#

.setPowered() doesnt come up as an option in my IDE

eternal oxide
#

its only available IF you cast to a Creeper

sage patio
#

how i can teleport a player behind another player?

eternal oxide
#

Player#teleport 😄

novel mauve
smoky anchor
#

Creeper ent = (Creeper) ...

novel mauve
#

Im so dumb

#

thanks

smoky anchor
#

If you have this and hover over the Creeper, your IDE will tell you what is wrong

sage patio
smoky anchor
#

do some vector math with the players look direction

chrome beacon
#

Otherwise you will spawn then charge

#

Instead of spawning charged

novel mauve
#

thanks but what do u exactly mean takes a consumer

eternal oxide
#

look or just location

chrome beacon
novel mauve
#

okay thanks

sage patio
#

something like this 2 - 3 behind

#

in the direction player1 is looking

eternal oxide
#

target.getLocation().subtract(target.getLocation().getDirection().multiply(-3))

#

or 3 depends on usind add or subtract

gilded granite
#

how do i create a 1.8 plugin with the minecraft development plugin

chrome beacon
#

You manually switch the dependencies in your pom

gilded granite
#

ok

chrome beacon
#

The development plugin does not support 1.8

smoky anchor
eternal oxide
#

not using getLocation

#

has no Pitch

smoky anchor
#

wait what

eternal oxide
#

getLocation is the players body/feet

smoky anchor
#

huh never knew that, good to know

eternal oxide
#

getEyeLocation is the players head

gilded granite
#

1.8-R0.1-SNAPSHOT good?

chrome beacon
#

At least use the latest 1.8 version 💀

gilded granite
#

1.8.8?

near mason
eternal oxide
#

?jd-s yes

undone axleBOT
near mason
#

oh thank you

#

i didnt knew it existed man

sage patio
eternal oxide
#

you are using eye location

#

getLocation() not getEyeLocation()

sage patio
zealous osprey
#

I just read "teleportScuffed" XD

eternal oxide
#

player#getLocation() is the location of their feet. It has no pitch

#

it does not matter where the player is looking

#

why are you teleporting the target?

#

teleporting the target behind the player

sage patio
#

the names are weird rn, i'm confused too

#

i just want to cuff someone

#

and the cuff plugin teleports him behind me

smoky anchor
#

can't wait to stand with my back to a wall

zealous osprey
sage patio
#

well thats a weird way to cuff someone

#

1.19.4

zealous osprey
sage patio
#

its very weired for a cop to carry someone in a roleplay server

eternal oxide
#

your code is fine. you must be doing something else odd.
Player#getLocation() is the location of the players feet. it has a zero pitch.
Player#getEyeLocation() is the players head which is where they are looking and will have pitch

smoky anchor
#

it is also very weird that the cop has the ability to teleport players into a wall

#

were it me, I would make a "bubble" from which the player can not escape
if the player does try, it pushes them towards the cop

sage patio
zealous osprey
sage patio
#

yea

#

for sure lol (why emojies are disabled in this server)

zealous osprey
#

If you rotate quick enough, you could maybe even fly away like a helicopter uwu

sage patio
#

uh god

#

just tell me how can i teleport him

#

without changing the Y location

#

it works fine rn except the Y

eternal oxide
#

that is already how you teleport without changing Y

smoky anchor
#

create a variable from the player.getloc.getDirection
set the y to 0, normalize the vector, multiply by whatever
do the rest of the math

eternal oxide
#

If are getting a different Y when the player looks down you are not using Spigot

zealous osprey
#

If you want them behind you, take the vector of the direction the player is looking and invert the x and z components, multiply by some distance value V and set y to the y-level of the player?

Make sure to norm the looking direction vector

eternal oxide
#

lol so ott

#

Just use Spigot and not whatever fork you are using

#

a Player#getLocation() has zero pitch

sage patio
eternal oxide
#

This is Spigot

#

?fork

undone axleBOT
#

SpigotMC maintains the Spigot server. If you are using a fork of Spigot (such as Paper, Airplane, Purpur, or other derivative works), you should seek support in the appropriate Discord servers.

gilded granite
#

?export

eternal oxide
#

however, if you ask how to do it using teh players Eye location, then that will work on all forks too 🙂

sage patio
#

why should the paper change the methods they shouldn't?

gilded granite
#

?exporttoserver

smoky anchor
smoky oak
#

1sec

sage patio
smoky anchor
#

do you not have localhost to test your plugins ?

gilded granite
#

localhost but i just forgeted the sitre

smoky oak
#
<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.3.1</version>
                <configuration>
                    <outputDirectory>D:/.../Server/plugins</outputDirectory>
                </configuration>
            </plugin>
gilded granite
#

no ik

eternal oxide
#
public void teleportTarget(Player player, Player target) {
  Vector eyeDirection = player.getEyeLocation().getDirection();
  eyeDirection.setY(0).normalize();
  target.teleport(player.getLocation().subtract(eyeDirection().multiply(2));
}```
sage patio
#

it was because of paper or what?

eternal oxide
#

probably

#

you don;t need to zero pitch on Spigot as the player body/location has zero pitch on Spigot

smoky anchor
#

Honestly surprised the body has yaw or whatever at all.
thought only eye loc has it

eternal oxide
#

I can;t believe paper actually adds a pitch to the player location though

sage patio
#

when they cuff each other at the same time i've 2 supermans in my server

eternal oxide
#

server is single threaded for ticks so two players will never do it at the same time

sage patio
#

i know they just get teleported behind each other each tick

eternal oxide
#

you need to not allow a player to cuff another if they are already cuffed

sage patio
#

yea sure

tender shard
#

publishing proper maven artifacts from gradle is a pain