#help-development

1 messages · Page 1339 of 1

buoyant viper
#

does parseDouble parse the literal "Infinity" as Double.POSITIVE_INFINITY ?

worldly ingot
#

I'm missing out on a lot of context I'm sure, but what's wrong with this?

public double parseDouble(String input, double defaultValue) {
    try {
        return Double.parseDoublue(input);
    } catch (NumberFormatException e) {
        return defaultValue;
    }
}
lilac dagger
worldly ingot
#

Other than the glaringly obvious typo

thorn isle
#

hey i found the regex recommended by the javadocs

#
 final String Digits     = "(\\p{Digit}+)";
 final String HexDigits  = "(\\p{XDigit}+)";
 // an exponent is 'e' or 'E' followed by an optionally
 // signed decimal integer.
 final String Exp        = "[eE][+-]?"+Digits;
 final String fpRegex    =
     ("[\\x00-\\x20]*"+  // Optional leading "whitespace"
      "[+-]?(" + // Optional sign character
      "NaN|" +           // "NaN" string
      "Infinity|" +      // "Infinity" string

      // A decimal floating-point string representing a finite positive
      // number without a leading sign has at most five basic pieces:
      // Digits . Digits ExponentPart FloatTypeSuffix
      //
      // Since this method allows integer-only strings as input
      // in addition to strings of floating-point literals, the
      // two sub-patterns below are simplifications of the grammar
      // productions from section 3.10.2 of
      // The Java Language Specification.

      // Digits ._opt Digits_opt ExponentPart_opt FloatTypeSuffix_opt
      "((("+Digits+"(\\.)?("+Digits+"?)("+Exp+")?)|"+

      // . Digits ExponentPart_opt FloatTypeSuffix_opt
      "(\\.("+Digits+")("+Exp+")?)|"+

      // Hexadecimal strings
      "((" +
       // 0[xX] HexDigits ._opt BinaryExponent FloatTypeSuffix_opt
       "(0[xX]" + HexDigits + "(\\.)?)|" +

       // 0[xX] HexDigits_opt . HexDigits BinaryExponent FloatTypeSuffix_opt
       "(0[xX]" + HexDigits + "?(\\.)" + HexDigits + ")" +

       ")[pP][+-]?" + Digits + "))" +
      "[fFdD]?))" +
      "[\\x00-\\x20]*");// Optional trailing "whitespace"
 if (Pattern.matches(fpRegex, myString))
     Double.valueOf(myString); // Will not throw NumberFormatException
 else {
     // Perform suitable alternative action
 }
#

it's only like 50 lines which is primarily comments

buoyant viper
#

but my NaN idea is basically that but with defaultValue == NaN

worldly ingot
#

I mean surely you've got some sort of bounds, no?

#

What's your input?

buoyant viper
#

a number

#

xx.yy

worldly ingot
#

Obviously

#

What's the purpose?

buoyant viper
#

money

#

currency

thorn isle
#

iirc the context is an eco transaction

ivory sleet
worldly ingot
#

Does negative currency make any sense in that case?

buoyant viper
#

no, but i early return in transaction methods if n is negative anyway

thorn isle
#

so yeah uh after taking this into account, you maybe do want to do primitive double and check for NaN/infinity instead

buoyant viper
#

so negatives are handled later on

worldly ingot
#

So then you're fine!

#

Default to 0!

#

Or -1, whatever

buoyant viper
#

fuck ur so right

thorn isle
#

because unless you or someone else validates the input, the player could enter the string NaN which is going to give you a NaN

#

which, again, if you do like receiver.deposit() on it and deposit just does balance += amount, it'll nuke the player's balance

buoyant viper
#

truth nuke

#

(literally)

thorn isle
#

i think vault probably guards against nans and infinities

#

or well i don't know if vault is in a position to guard anything, it's just a service registry

buoyant viper
#

i made the naive decision to write the eco implementation myself and at this point im in too deep to turn back

#

sunk cost fallacy

sullen marlin
#

Just make your economy communist

buoyant viper
#

TRUE!

#

everyones balance is getting nuked

buoyant viper
#

i looked at Essentials once i dont remember much

#

but im pretty sure Vault is all interfaces

ivory sleet
#

iirc they got specs abt not using negative numbers

#

but thats about it

thorn isle
#

anyhow yeah, try catch and if it throws, return nan

#

then explicitly check Double.isFinite

buoyant viper
#

what if i add the finite check to the parser lowk

thorn isle
#

this will nicely represent "not a number" without boxing, and will also guard against someone trying to /pay me infinity

#

but since you will then be dealing with nan's, you have to take very good care to always check that it is finite

buoyant viper
#

doing the finite check outside of the parse and if its false i kill the player

thorn isle
#

so if you're planning to expose this to "outside callers", like other classes, maybe dependencies, other plugin modules, i'd still go with null in place of nan

buoyant viper
#

perhaps

slate mortar
#

is this my fault or some 26 jank

#

doesnt show my plugin at least

buoyant viper
slate mortar
#

oh fun

#

never seen that myself

buoyant viper
#

yeah its like relatively common actually

slate mortar
#

aight glad, since i'm currently messing with join & quit stuff, so i wouldnt have been surprised

buoyant viper
#

so its per-plugin to make sure they dont nuke the balance

#

the good part is im in charge of all the plugins that will use it (since its for My server)

#

the bad part is Im in charge

thorn isle
#

writing your own eco backend isn't a bad thing

#

i've had to do the same because all the plugins out there seem to either be terrible, bloated, feature creepy dumpster fires like TheNewEconomy (recommended by towny) or otherwise nice and simple, but don't work with towny

#

so i ended up writing one that specifically doesn't fuck shit over when used by towny, and is just a plain and simple uuid -> double store

buoyant viper
#

does Towny not hook Vault?

thorn isle
#

it does, but it has had trouble with uuid's ever since they were introduced

buoyant viper
#

oof

thorn isle
#

and since it needs to register non-player accounts for towns, shit gets whack and the uuid resolution differs from backend to backend

#

many backends like essentials eco do weird evil uuid version checks that prepend npc_ to accounts or something, and that makes it not work with towny

buoyant viper
#

i do like mine bc it has a pseudo-bank system where players have their on-hand/wallet balances, but can also store and access balances in an infinite amount of "bank" accounts

#

i just have no way of making more than one bank rn... so its just one Central bank

#

im like the federal reserve fr

#

User

  • Wallet

Bank

  • AccountHolder
    • Owner (User reference)
    • Collection<Account>
#

eventually ill think of a way to manage multiple banks but

#

maybe just like

BankRegistry

    • Collection<Bank>
buoyant viper
#

ive never touched SQL even with a 39.5 foot pole until now

#

never had a system that benefitted enough from having a storable database to constitute learning SQL

#

had to spend yesterday evening fixing my queries bc my initial database structure didnt work properly to let me use UPSERT in SQLite

#

and initially i had 3 separate queries (UPDATE on SELECT else INSERT)

slender elbow
#

remember CRUD
Celect
inseRt
Update
Delete

young knoll
#

I thought it was
Chatgpt
gRok
claUde
Deepseek

topaz cape
#

yo how do you detect if the damager is anchor block explosion?

EntityDamageByBlockEvent#getDamager returns null cuz block alr gone

#

but it still calls the event

slender elbow
#

would probably need to chain some logic with the BlockExplodeEvent

topaz cape
#

Ah

topaz cape
#

this does not make sense but.. BlockExplodeEvent is called AFTER EntityDamageByBlockEvent??

thorn isle
#

i don't know if there is any sensible implied order for them

topaz cape
#

BlockExplodeEvent is cancellable

#

so it should be called first no?

thorn isle
#

yeah, it will prevent the blocks from exploding if cancelled

#

it doesn't cancel the explosion itself

topaz cape
#

exactly

#

huh

#

thats dumb

thorn isle
#

well, not really

#

suppose for example that you want to prevent some blocks from exploding

#

but still want it to damage mobs

#

perhaps you have an indestructible custom block that you don't want to be explodable

topaz cape
#

blockList#clear?

thorn isle
#

cancelling the event shouldn't make the explosion not deal damage to nearby entities

topaz cape
#

blockList is a mutable list

thorn isle
#

sure

topaz cape
#

so yes, its stupid

thorn isle
#

not really

topaz cape
#

yes it is

#

@-@

wet breach
#

Entitydamagebyblock event is not inherently tied to blocks exploding. There is other blocks that can damage. The reason blockexplode event comes after is because otherwise you would not be able to cancel the damage to entities as blockexplode event does not have entity list.

#

@topaz cape

slate mortar
#

what is the commonly used way to align multiiline-text properly, since apparently tabs aren't a thing, and spaces just don't work at all, i assume due to different character lengths

thorn isle
#

there's a MapFont class or something that you can use to calculate the rendered widths of text in the minecraft default font

#

using this and spaces and bold you can manually align things

slate mortar
#

the problem is that apparently with only spaces, it is impossible to align

#

sec

thorn isle
#

there's a magic trick

#

making a block of text bold makes it 1 pixel wider

#

so you can make your spaces bold to get pixel-perfect adjustments

slate mortar
#

this for instance.

#

when i move the "<name>" from the "enter" line one to the right, it does not seem to work either

thorn isle
#

yes

#

you need to make some of the spaces bold

slate mortar
#

oh the spaces

thorn isle
#

different characters have different widths, and you have to adjust the width of some of your spaces to account for it

#

a cleaner way of doing this is to use a custom font with spaces of widths 1, 2, and 3 pixels in addition to the default 4 of the regular space

#

but messing with bold also works, it's just more clunky

slate mortar
#

but that would involve a custom resourcepack i guess

#

which is always ass

thorn isle
#

well, it's fairly simple to set up, but it does mean that people without the pack will be seeing random squares in place of some spaces

slate mortar
#

yea i know how to do custom fonts, but custom rp's itself are smt i always avoid, since people do not like those, for a reason

thorn isle
#

myeah that is fair

slate mortar
#

welp i guess ima see about that custom formatting. thanks for the help

thorn isle
#

spaces it is then, but it will be fucked if anyone has unicode font enabled or uses a custom font, since then the character widths will be different

slate mortar
#

ugh

#

yk what, i'm just going to use comic sans

#

or just use no spaces at all the same mojang does.

thorn isle
#

dots can get you sorta close

#

that's what worldguard has been using for its /wg flags list for like 20 years

#

it's not pixel perfect, but each one is like 2 pixels i think, so you'll be 1 pixel off at worst

slate mortar
#

meh that should be enough, kinda same as the existing "help" command

young knoll
#

Make a custom monospaced font :p

thorn isle
#

unicode has a monospaced block and it does render ingame, but it looks kind of weird

frosty bolt
#

I'm facing a weird issue where getPersistentDataContainer() highlighted in red (Cannot resolve symbol) in IntelliJ IDEA. However, my pom.xml seems correct and I'm targeting Spigot 1.20.1.

echo basalt
#

zero width spacing or something

echo basalt
chrome beacon
#

Make sure Intellij is up to date and that you have a modern JDK set for the project

frosty bolt
echo basalt
#

crazy

frosty bolt
#

Oh, sorry, I was just trying to insert a picture.

frosty bolt
thorn isle
#

do you maybe a have a bukkit 1.8 as a transient dependency from worlguard or something

frosty bolt
#

No, I don't think there's anything like that, but I have an api vault in my pom.

thorn isle
#

that could do it, vault is ancient and does depend on bukkit

#

print your dependency tree

#

if you use intellij, you can see it in the maven sidebar; expand "dependencies" and look for bukkit/spigot

frosty bolt
#

<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>com.github.MilkBowl</groupId>
        <artifactId>VaultAPI</artifactId>
        <version>1.7</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>org.spigotmc</groupId>
        <artifactId>spigot-api</artifactId>
        <version>1.20.1-R0.1-SNAPSHOT</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

</project>

#

@thorn isle Indeed, as soon as I removed the vault dependency from the pom, everything worked.

#

@echo basalt Sorry if I offended you, I just wanted to send a pic.

thorn isle
#

you can exclude it

#

shove

            <exclusions>
                <exclusion>
                    <groupId>org.bukkit</groupId>
                    <artifactId>bukkit</artifactId>
                </exclusion>
            </exclusions>

within the vault dependency tag

frosty bolt
#

thank you

grim hound
#

anyone knows why I can't "Go to declaration" (like being transferred to where the method/variable/class resides) in IntelliJ 2026.1 with the middle mouse button?

#

worked in IJ 2024

#

but it doesn't support gradle 9.4 so had to transfer

thorn isle
#

My case about some stupid gradle plugin requiring gradle 999.99 for no discernable reason in point

#

It's in the settings somewhere, but good luck finding it

#

My personal recommendation is to give up and just run gradle through the command line instead of the ide

#

26.1 is fucking horrible

#

Or even better, switch away from gradle altogether

#

I can run every maven build under the sky from IJ 2019.1

#

Since I maintain an intellij plugin and target everything from 19.1 to 26.1, I frequently see and use each version, its mych more apparent to me how it has evolved (and I have about 100gb of gradle garbage and IJ platform shit in my build cache, but thats besides the point)

#

But switching the versions to runIde and test the plugin on each is like watching a timelapse of Rome turning into ruins

#

Every time it gets worse and worse

#

The buttons get bigger and bigger, the ui gets rounder and rounder, all the tool tips and in-ui button texts disappear and get replaced by big fat icons that I have to guess what they do

#

More and more ai buttons and "start free trial" shit appears

grim hound
#

will just keep the 2024.2 version Ig

grim hound
#

but still terrible navigation

#

I don't think it'd be easy to configurate that

mortal hare
#

why java doesnt support compact source files outside main class?

#

it would be so useful to have as an utils alternative

slender elbow
#

i feel like a broken record

thorn isle
#

"compact source file"

#

gb2 python

mortal hare
#

currently i use lombok's

@UtilityClass
public class UsernameValidator {
}

for this

#

but it would be quite nice to drop class level too

thorn isle
#

what's the issue again?

sullen marlin
#

Costs an extra AI token or two

buoyant viper
#

true

green mauve
#

is there an exploit when player can close inventory without sending a packet (or not close it and send a packet) and this way duplicate items?
ive heard of it and im using invenotryCloseEvent to remove the inventory from a set

slender elbow
#

to dupe items? unless it's a poorly coded plugin and the server has no anticheat, no

echo basalt
#

Delaying the close packet on top means they get to open a menu before closing another

#

For example, if you have a gui that saves when closed and renders its items when open it'd result in a dupe

#

because you can take your item, reopen the menu and get it again before the old version saves

drowsy helm
#

Speed check doesn't account for anything like ice, speed effect etc

drowsy helm
#

uuuh

pliant topaz
#

?services

undone axleBOT
quaint basin
#

Does Component#translatable not distinguish which plugin is running?

chrome beacon
#

??

#

That's just a translatable component it has nothing to do with plugins really

#

They're a vanilla thing

#

so no it doesn't care what plugins are running

quaint basin
#

I thought that two different plugins could use the same key

chrome beacon
#

I mean yeah if you have two plugins trying to define the same key that's not going to work

quaint basin
#

ok thanks

#

One more thing: if a world unloads, are all chunks at the time of unloading called in the ChunkUnloadEvent?

chrome beacon
#

Try it and see

quaint basin
#

My plugin is behaving strangely, I imagine that's not

#

And what about the EntityRemoveFromWorldEvent? Do you have any idea if the EntityRemoveFromWorldEvent is called when the entity is in a world that is unloaded?

chrome beacon
#

Try it and see

quaint basin
#

This error appeared when shutting down the server.

chrome beacon
#

?whereami

quaint basin
# chrome beacon ?whereami

[15:56:06] [Netty Epoll IO #1/ERROR]: Thread Netty Epoll IO #1 failed main thread check: Cannot perform command async
java.lang.Throwable
at org.spigotmc.AsyncCatcher.catchOp(AsyncCatcher.java:9) ~[aspaper-1.21.11.jar:1.21.11-17059-496f794]

#

I see org.spigotmc

chrome beacon
quaint basin
#
Block block = world.getBlockAt(cx + dx, cy - 1, cz + dz);
Material type = block.getType();

I'm doing this in EntityRemoveFromWorldEvent and I'm getting this warning: Cannot update ticket level while unloading chunks or updating entity manager

What can I do?

chrome beacon
#

I mean that's a Paper thing

#

you should be asking them about it

quaint basin
#

So I'm screwed lol

chrome beacon
#

This channel is for development

vestal carbon
#

thx

#

sorry

rotund ravine
umbral ridge
dry hazel
#

looks like cockroachdb but mysql instead of the postgres wire protocol

thorn isle
#

raft
nice

#

and written in go

#

looks very impressive, though i don't really need something like this

umbral ridge
#

yeah

#

cool stuff!

pliant topaz
# quaint basin So I'm screwed lol

Despite the fact this is not spigot, reading the trace, its about a command being called async. What excactly are you doing in your onDisable?

thorn isle
#

i don't see any plugin classes in the stack trace, and it looks like it's just a command packet being received and processed normally

#

does it happen every time? if it was just an one-off thing, maybe someone sent a command right as the server was about to shut down, and that isn't handled correctly by the server internals?

#

it does seem to try to pass it to the BlockingEventLoop which i think should schedule it to run on the MT, but it's a common pattern for schedulers to short circuit on shutdown

grim hound
#

Does RIGHT_CLICK_AIR in PlayerInteractEvent not work anymore? (1.21.11)

quaint basin
chrome beacon
grim hound
#

no, when not holding

chrome beacon
#

Then no the client doesn't send the interact packet

#

It's been this way for a long time

thorn isle
#

you need either a block at the crosshair or an item in your hand for an interact packet to be sent

#

the client doesn't expect anything to happen if it has nothing to interact with, so it just doesn't send an interact packet

chrome beacon
#

Or just constantly have an interaction entity infront of the player

thorn isle
#

yes a block or an entity at the crosshair to be more specific

chrome beacon
#

I mean yeah any entity will work

thorn isle
#

however i'd recommend against doing it with the interaction entity as that will take priority over targeting actual blocks at the crosshair

chrome beacon
#

that's also true

thorn isle
#

so you'll have to move it around as the player looks and moves around, which then in turn is latency sensitive

#

someone has suggested adding a fully transparent texture for an item and then filling all hotbar slots with that item, but i think that will make the player's hand disappear

#

so the best approach is i think just switch your input button to left click for whatever you're trying to do

grim hound
#

ah okay

#

tested, and ye, doesn't send

#

easiest to check would probably be making a large hitbox ride the player at all times and just reproducing the interactions with the api

#

not sure about mining blocks

#

will just use items then

sly topaz
sly topaz
#

those values are increased by 2 in creative mode, but I doubt anyone cares about creative

thorn isle
thorn isle
#

you could increase it with an attribute and then manually check the range on entity interact packets, and drop any that exceed the normal range, but i suspect that might cause issues with anticheats; it's worth a shot however

slender elbow
#

can't remember if it was a component or a resource pack thing on the item model definition

thorn isle
#

i know you could do that with core shaders, but i guess they added some special model that just renders the actual player hand?

green mauve
#

is it possible to get 1 tick of redstone? normal repeater's smallest interval is 2 ticks which is = 1 redstone tick apparently
so for example play a noteblock 2 times in 2 ticks

quaint basin
#

Is the EntitiesLoadEvent called on a tick after the associated chunk has been loaded? And what about ChunkUnloadEvent? Are the entities unloaded on the same tick that the chunk is unloaded?

thorn isle
#

not strictly related to repeaters, and i'm not sure but i'd guess, that blocks like noteblocks perform their behavior only when their redstone power goes from zero to nonzero

quaint basin
thorn isle
#

so it'd take 2 ticks either way, one tick to power it, another tick to depower it

thorn isle
quaint basin
thorn isle
#

they are not the same and have no well defined relation

#

and yes, it is ass, and it makes everything more difficult

#

entities could load several ticks after the chunk is loaded

#

not sure how unloading works

quaint basin
#

Yeah, I need to know about unloading

thorn isle
#

either way your error comes from the chunk being unloaded, or being in the process of being unloaded, at the time the code runs

thorn isle
umbral ridge
#

hi hd luna

thorn isle
#

they separated, i.e. decoupled, i.e. made it not coupled anymore, between entity and chunk loading

#

entities and chunks are stored in completely separate files

quaint basin
thorn isle
#

i don't know

pliant topaz
quaint basin
pliant topaz
thorn isle
#

they aren't

#

i think they could be unloaded already by that point

quaint basin
#

I don't know if this is a problem

quaint basin
#

then yea this is a problem

green mauve
#

?

thorn isle
#

i think you might be able to deal with it through nms, i suspect this is bukkit being dumb

#

bukkit only considers the highest, entity ticking chunk ticket level to be "loaded"

quaint basin
#

If the entity is unloaded before the chunk is unloaded, then I shouldn't get that error about getting a world block if the chunk is still loaded

chrome beacon
#

You really shouldn't have gotten yourself banned from the Paper discord

thorn isle
#

yeah but then you have no entity to call that getBlock logic on

chrome beacon
#

They heavily change how chunk loading works

thorn isle
quaint basin
chrome beacon
#

not to mention the events you're using are Paper specific

thorn isle
#

so you should be able to get the chunk with nms and read the block with nms

chrome beacon
thorn isle
#

i got banned for trying to help people with 1.8

#

two thirds or more of the people here are paper users who either dislike the community or have been banned from it

chrome beacon
#

Yeah I know a lot of you have been

quaint basin
umbral ridge
thorn isle
#

i'm fairly sure he also got banned for asking for help with 1.8

umbral ridge
#

guys i need help with 1.0 beta how do i add plugins

quaint basin
#

It was because I said "lol" in response to a message and people thought I was mocking them. Something like that

thorn isle
#

either way, try nms

quaint basin
#

And then they muted me for a month. I spoke to the admin and they told me that next time it's a ban, and I told them to ban me

#

And so I got banned

pliant topaz
# green mauve can i print current tick to console on event handler

I'm not aware of another way in spigot, but maybe you could try the Bukkit Scheduler and reapeatingly schedule a sync repeating task every tick? Whats the xy for powering the noteblock every tick? I assumed it was only a general redstone question at first, but since you're asking about doing it with a plugin, what's your plan?

green mauve
#

just noteblock songs

quaint basin
#

What I find strange is that getting the block is possible, but getting the block type isn't

green mauve
#

xy problem is probably not the case

quaint basin
#

yea i see now

thorn isle
#

it just creates a new CraftBlock pointing at those coordinates

#

same with chunks

quaint basin
#

It simply creates an object with x, y, z, etc

#

yea

thorn isle
#

only when you try using them to read the state does it e.g. trigger a chunk load

pliant topaz
green mauve
#

yeah i know

#

but im thinking of noteblocks right now

pliant topaz
#

Then probably either the scheduler or some special redstone circuit, sadly my knowledge there isnt too great so i cant help you with that :/

green mauve
#

yeah thanks anyway you helped

quaint basin
thorn isle
#

cast the world to craftworld and get the handle and get the nms chunk and get the nms block

chrome beacon
#

So what are you even doing with the block?

quaint basin
chrome beacon
#

for what purpose?

quaint basin
thorn isle
#

here's a thought

chrome beacon
#

Do you not already know the efficiency on removal??

thorn isle
#

do that on chunk load

#

it's not like the blocks are going to change while the chunk is unloaded

quaint basin
thorn isle
#

yeah that's worth a try

quaint basin
#

I can't do it in chunk load yea

thorn isle
#

i mean with chunk borders and pistons, adjacent chunks might change between the entity unloading and loading if it's on the chunk border, but i don't think it should be an issue

quaint basin
#

I could do this with timestamps/time differences, but yeah, that's a big refactoring

quaint basin
#
 public Material getType() {
        return this.world.getBlockState(this.position).getBukkitMaterial();
    }
thorn isle
#

possibly

#

bukkit and nms chunk load levels aren't 1:1 however

#

so it's still worth a try

quaint basin
#

The difference is that Bukkit uses the world to obtain the state block, while I use the chunk

#

getChunk will load the chunk if it is unloaded

thorn isle
#

i'm guessing it is loaded, but not at the entity ticking level

#

which bukkit considers "unloaded"

#

either way, try it and see

#

if you get the error, then it is actually unloaded

quaint basin
#

I haven't had that error for a while now

thorn isle
#

if it doesn't happen consistently, what i'd do is just schedule the block get to happen a tick later if the chunk isn't loaded when the code runs

#

this would be bad if it does happen consistently, as loading the chunk would make it unload again and it'd loop indefinitely

#

but if it's a 1 in 100 thing, it's fine

quaint basin
#

Or are you telling it to load the chunk one tick later?

thorn isle
#

it also tries loading it here, but the problem is the code is called from nms code that's already doing chunk loading/unloading status shit

#

and you can't load chunks under that code

#

loading the chunk a tick later under the scheduler will work as normal

quaint basin
#

I set this to true in EntitiesLoadEvent

#

With this if statement, I have a guarantee that the getBlock call will be made for a chunk that is not loaded

thorn isle
#

don't use bukkitrunnables for stateless behavior

#

those are meant for self-cancelling tasks and tasks with state

quaint basin
#

Actually, the chunk might have been loaded, but the entity hasn't been loaded yet, but I don't think that's a problem

thorn isle
#

just use a regular runnable and pass it to the scheduler

thorn isle
#

your bukkit runnable

quaint basin
#

yes but why

thorn isle
#

it's redundant and not as readable

quaint basin
#

Do you advise doing this instead?


 Bukkit.getScheduler().runTask(BukkitMinionPlugin.INSTANCE, () -> {

            if (!bukkitMinion.isLoadedChunk()) {
                bukkitMinion.getMinionState().onMinionUnload(cx, cy, cz, radius, world);
            }

        });
thorn isle
#

yes

buoyant viper
quaint basin
#

you are using this yet?

#

they have a dupe

#

If you drop an item and restart the server, your item will be on the ground and in your inventory

lilac dagger
#
SEVERE: FlatLaf: Using JProgressBar.setIndeterminate(false) not on AWT thread may throw NPE in FlatProgressBarUI.paint(). Use SwingUtilities.invokeLater().
java.lang.IllegalStateException
    at com.formdev.flatlaf.ui.FlatProgressBarUI.lambda$installListeners$0(FlatProgressBarUI.java:127)
    at java.desktop/java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:343)
    at java.desktop/java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:335)
    at java.desktop/java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:268)
    at java.desktop/java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:310)
    at java.desktop/java.awt.Component.firePropertyChange(Component.java:8690)
    at java.desktop/javax.swing.JComponent.firePropertyChange(JComponent.java:4598)
    at java.desktop/javax.swing.JProgressBar.setIndeterminate(JProgressBar.java:916)
    at org.spigotmc.gui.panels.general.GeneralPanel.lambda$buildButtonActionPerformed$1(GeneralPanel.java:197)
    at java.base/java.util.concurrent.CompletableFuture.uniWhenComplete(CompletableFuture.java:884)
    at java.base/java.util.concurrent.CompletableFuture$UniWhenComplete.tryFire(CompletableFuture.java:862)
    at java.base/java.util.concurrent.CompletableFuture.postComplete(CompletableFuture.java:531)
    at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1794)
    at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1781)
    at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:511)
    at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1450)
    at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:2019)
    at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:187)
#

am i the only one getting this error

#

it happens right at finish

thorn isle
#

judging by the one line in the stack trace that seems to be vaguely related to spigot, i assume you're talking about buildtools?

young knoll
#

?services

undone axleBOT
slow skiff
#

is there a way not to send teams to client until they see a player of that team without manually sending packets?
it looks like when a player joins they instantly get told of all teams and their members

thorn isle
#

not only that, but the entire scoreboard, with tags and scores and all

#

this is sort of "doing it manually with packets"-adjacent, but you could maintain a per-player scoreboard with player::setScoreboard, and assign only nearby people to teams based on the real scoreboard

lilac dagger
#

Forgot to mention

#

Something with the laf theme

kind hatch
#

Leaf theme?

buoyant viper
#

im gonna assume maybe the icon to use the theme is a leaf lol

young knoll
#

I thought we had a sun and a moon

kind hatch
#

See, that's what I thought

buoyant viper
#

maybe they autocorrected LaF

#

idk

mortal vortex
#

yeah i think he meant LAF

slow skiff
#

sleeping mannequin disappears when player is >19 blocks away ignoring tracking range, why? hard coded client side?

umbral ridge
#

is it possible to modify for how long the action bar message stays visible after showing it

#

or is that kind of hardcoded

#

@vagrant stratus

slow skiff
#

but you can extend by just sending it multiple times and sending empty to clear or shorten it

mortal vortex
#

yeah but it will disappear abruptly and not fade

#

(i think the actionbar fades, cant remember)

slow skiff
#

yes but its possible to calculate when it should fade and send the last one some time before that

lilac dagger
#

Yes laf

slow skiff
#

is it possible to make mannequin walk normally without packets or teleporting
can goals be added to them?

young knoll
#

Doesn’t look like it

#

They don’t extend Mob

echo river
umbral ridge
chrome beacon
thorn isle
#

My personal recommendation is libsdisguises

echo river
thorn isle
#

they need to ban these gooner guilds

#

what is this shit

echo river
#

Ppl are too horny 😔

fickle spindle
#

there is any good library for config handling becuase i don't like the fuct that as right now all my config is messed up when i push a new update

thorn isle
#

are you the guy to whom i explained how to config.set and save for like half an hour a few days back

civic mica
#

Does anyone need plugin development ... xD

rocky locust
#

How can I protect my plugin against leakers? I've already tested ProGuard and Skidfuscator but apparently it's not that useful

lilac dagger
#

Proguard is the best you can do afaik

#

There's sone better paid obfuscators

worldly ingot
#

I just wouldn't bother. Anyone with enough time and dedication will deobfuscate it

#

Or they'll copy/paste your obfuscated code. It's not like it doesn't work just because it's obfuscated

#

Your code isn't high-value enough to need to be obfuscated

rocky locust
#

I'm about to open a paid plugin store and with my own licensing, you know, I just want to protect it as best I can, isn't there any alternative to make it as difficult as possible?

chrome beacon
#

The plugin will be leaked regardless of what you do

#

You're just making it a fun challenge to crack

hybrid spoke
#
  • obfuscating won't stop people from sharing the jar. it just makes it more fun to read the code
slow skiff
#

but i dont recommend it, just make good content, good updates, and dont worry about cracks

chrome beacon
#
  • now you run in to the classic problem of the plugin being better and more reliable if you pirate it
#

Actively making the experience worse for paying users is not the way to go

clever kraken
#

piracy doesnt need active prevention as the ceo of steam said "piracy is almost always a convenience problem"
make your store easy to use and everyone who is willing to pay will pay, everyone who isn't willing to pay just wont use your software even if there's not a pirate

chrome beacon
#

^

#

WATCH A SLIGHTLY LESS CRAPPIER VERSION OF THIS ON ODYSEE: https://odysee.com/@postscriptreal:e/Gabe-Newell-on-Piracy-(Full-Version-HQ):2

This is the un-abridged, web-exclusive version of ABC Good Game's interview with Gabe Newell, which contains the full version of Gabe's take on Anti-piracy.
Despite what the title and YouTube says, this video ...

â–¶ Play video
fickle spindle
#

how can i check if the player have played the server before? i used to use PLAY_ONE_MINUTE but it isn't working properly now...

chrome beacon
fickle spindle
chrome beacon
#

delete the player data

mortal hare
#

is there any decent gui client like dbeaver which doesnt have clunky java ui

#

specifically searching something for redis

onyx fjord
remote swallow
#

Datagrip probably does, free for non commercial

buoyant viper
#
    public CompletableFuture<Response> sendAsync(Request request) {
        return CompletableFuture.supplyAsync(() -> {
            try {
                return send(request);
            } catch (IOException exc) {
                throw new CompletionException(exc);
            }
        }, threadExecutor);
    }``` does this look correct for passing an exception to the CompletableFuture?
#

which is then used like ```java
sendAsync(args).whenComplete((response, throwable) -> {
if (throwable != null) {
/* handle err */
return;
}

/* do stuff */

});```

ivory sleet
#

yea thats fine

#

u can also handle the error on its own with exceptionally

lost matrix
#

Im not sure i would throw a CompletionException.
Probably a RuntimeException, since the CF will wrap it in a CompletionException on default.

buoyant viper
#

i tried using exceptionally and it had an issue with return types

ivory sleet
buoyant viper
#

i havent used CFs much tho so i probably just had the wrong method used before it

lost matrix
buoyant viper
#

would i need to like return null and then in a .thenAccept check if null?

slender elbow
#

god I hate CF's handling of CompletionException it's absolute ass

#

in some cases it wraps exceptions in it, in other cases it doesn't, but it never unwraps them

lost matrix
#

There are like 10 methods that let you handle exceptions in some way.

buoyant viper
#

my alternative idea is sendAsync takes a Request + Consumer<Response> and Consumer<Throwable> lol

slender elbow
#

so you always end up having to run a stupid conditional unwrap method somewhere to get the actual exception you want

lost matrix
#

Dont mix functional forwarding with CompletableFutures. Your approach is fine.

slender elbow
ivory sleet
slender elbow
#

so yes it does pass the result downstream

buoyant viper
#

something like java public void send(Request request, Consumer<Response> onSuccess, Consumer<Throwable> onThrow) { threadExecutor.execute(() -> { try { onSuccess.accept(send(request)); } catch (IOException ioe) { onThrow.accept(ioe); } }); }

ivory sleet
#

i like it

#

though, if its always an IOException u're catching, why not Consumer<IOException> ^^

buoyant viper
#

i could change the type ig

sly topaz
#

why not just use Java's HttpClient

buoyant viper
#

because im on java 8 😔

ivory sleet
#

my condolences

random grove
#

I've been working on a custom inventory GUI system and ran into what I think is a gap in the InventoryClickEvent API.

When MOVE_TO_OTHER_INVENTORY fires (shift-click), the event tells you the source slot but not the destination. The destination is computed at the NMS level before the event fires, so plugins have no reasonable way to access it without diving into NMS — which kind of defeats the point of having a Bukkit API.

This makes it really difficult to write a slot-based inventory library that correctly handles shift-clicks without either blanket-cancelling everything or reimplementing item routing logic that ultimately doesn't match what NMS actually does.

Would it make sense to expose the destination slots on the event? Something like event.getDestinationSlots(). Since the information already exists at that point, it feels like a natural addition.

Has anyone else run into this, or is blanket-cancelling really the accepted approach?

sly topaz
#

and yes, people have ran into this before but it is niche enough of a problem that nobody has bothered to fix the API around it

random grove
#

alr

mortal vortex
#

alr

umbral ridge
#

alr

pliant topaz
#

alr

echo basalt
#

alr

#

I did make an nms based slot thing but even then I often find myself emulating slots because everyone and their mom wants to have display items that represent "empty slots"

potent crescent
#

alr

onyx fjord
#

did you know

autumn zinc
#

Does anyone know how to use ClientboundSetEntityMotionPacket ?

lilac dagger
#

you give it an id and a vector @autumn zinc

autumn zinc
#

one min i'll send code

lilac dagger
#

show code

#

((CraftPlayer) player).getHandle().connection.send(new ClientboundSetEntityMotionPacket(id, new Vec3(x, y, z)));

#

this is exactly how i'd send it

autumn zinc
# lilac dagger show code
        Display.ItemDisplay entity = new Display.ItemDisplay(
                EntityType.ITEM_DISPLAY, ((CraftWorld) player.getWorld()).getHandle());
        entity.setItemStack(CraftItemStack.asNMSCopy(new ItemStack(Material.STONE_SWORD)));
        Location location = player.getLocation();
        entity.setPos(location.getX(), location.getY(), location.getZ());

        ServerGamePacketListenerImpl connection = ((CraftPlayer) player).getHandle().connection;
        connection.send(new ClientboundAddEntityPacket(entity));
        connection.send(new ClientboundSetEntityDataPacket(
                entity.getId(), entity.getEntityData().getNonDefaultValues()));

        Bukkit.getScheduler().runTaskLater(
                plugin, () -> connection.send(new ClientboundSetEntityMotionPacket(
                        entity.getId(), new Vec3(0, 1, 0))), 20L);
autumn zinc
lilac dagger
#

i don't think item displays tick for this to work

#

try it on a villager

autumn zinc
#

i also tried with default zombie

autumn zinc
autumn zinc
# lilac dagger try it on a villager
        Villager entity = new Villager(
                EntityType.VILLAGER, ((CraftWorld) player.getWorld()).getHandle());
        //entity.setItemStack(CraftItemStack.asNMSCopy(new ItemStack(Material.STONE_SWORD)));
        Location location = player.getLocation();
        entity.setPos(location.getX(), location.getY(), location.getZ());

        ServerGamePacketListenerImpl connection = ((CraftPlayer) player).getHandle().connection;
        connection.send(new ClientboundAddEntityPacket(entity));
        connection.send(new ClientboundSetEntityDataPacket(
                entity.getId(), entity.getEntityData().getNonDefaultValues()));

        Bukkit.getScheduler().runTaskLater(
                plugin, () -> connection.send(new ClientboundSetEntityMotionPacket(
                        entity.getId(), new Vec3(0, 1, 0))), 20L);

same thing

lilac dagger
#

looks correct

#

but is there a reason why you'd do it with nms?

autumn zinc
lilac dagger
#

no no

#

do you need per player entities?

autumn zinc
#

yes, it is necessary

young knoll
#

I mean, the api can technically do that too

autumn zinc
young knoll
#

Entity#setVisibleByDefault
Player#showEntity

lilac dagger
#

interesting

#

so this doesn't add it to the world?

#

or no

#

it just hides it

#

pretty cool

#

my guess is you need to send the packet in small chunks over a period of time

autumn zinc
#

i know, but it is very important to implement my system using packets
without creating a real entity or something else

autumn zinc
autumn zinc
#
        Bukkit.getScheduler().runTaskTimer(
                plugin, () -> connection.send(new ClientboundSetEntityMotionPacket(
                        entity.getId(), new Vec3(0, 0.2, 0))), 20L, 3L);

Like this? if yes it doesn't work ...

lilac dagger
#

yes

#

try it

autumn zinc
#

i tried to intercept set motion packet when a default zombie was moving, and i got this data

#
[15:20:25] [Server thread/INFO]: X: -372 Y: -627 Z: -329
[15:20:25] [Server thread/INFO]: X: -364 Y: -627 Z: -339
[15:20:25] [Server thread/INFO]: X: -357 Y: -627 Z: -347
[15:20:25] [Server thread/INFO]: X: -356 Y: -627 Z: -348
[15:20:26] [Server thread/INFO]: X: -355 Y: -627 Z: -350
[15:20:26] [Server thread/INFO]: X: -192 Y: -627 Z: -192
[15:20:26] [Server thread/INFO]: X: -105 Y: -627 Z: -104
[15:20:26] [Server thread/INFO]: X: -105 Y: -627 Z: -104
#
        String stringBuilder = "X: " +
                packet.getXa() +
                " Y: " +
                packet.getYa() +
                " Z: " +
                packet.getZa();

        Bukkit.getScheduler().runTask(plugin,
                () -> Bukkit.getLogger().log(Level.INFO, stringBuilder));
``` used this code
#

but i know that these values are already converted

lilac dagger
#

try new ClientboundMoveEntityPacket.Pos(

autumn zinc
#

oh

lilac dagger
#

it's 26.1

autumn zinc
#

yes

lilac dagger
#

not sure how it's on lower

autumn zinc
#

there are i'm sorry

autumn zinc
lilac dagger
#

one second, let me try

autumn zinc
lilac dagger
#

just got the server going

#

let me see

#

it doesn't spawn at all @autumn zinc

#

might be something related to 26.1 tho

autumn zinc
#

can you?

lilac dagger
#

i can't rn

autumn zinc
#

do you thing it is because of vesion?

lilac dagger
#

might be something new in 26.1

autumn zinc
#

are you sure that your way of creating the entity is okay?

lilac dagger
#

server entity is required in newer versions

#

give me some more time to check

#

ah nvm

#

i got it

#

i had to move the position above server entity

autumn zinc
#

holy 26.1

lilac dagger
#

they don't move indeed

#

might be something else as well

#

server entity seems to hold the vector data

autumn zinc
#

set motion packet constructor

    public ClientboundSetEntityMotionPacket(Entity var0) {
        this(var0.getId(), var0.getDeltaMovement());
    }

    public ClientboundSetEntityMotionPacket(int var0, Vec3 var1) {
        this.id = var0;
        double var2 = 3.9;
        double var4 = Mth.clamp(var1.x, -3.9, 3.9);
        double var6 = Mth.clamp(var1.y, -3.9, 3.9);
        double var8 = Mth.clamp(var1.z, -3.9, 3.9);
        this.xa = (int)(var4 * (double)8000.0F);
        this.ya = (int)(var6 * (double)8000.0F);
        this.za = (int)(var8 * (double)8000.0F);
    }

maybe it will help you? 🙂

lilac dagger
#

it's not related to the move packet

autumn zinc
lilac dagger
#

the packet itself is a vector and entity id

autumn zinc
#

we are trying to move the entity using the move or motion packet?

lilac dagger
#

those are just logic for transfering

#

yes

#

but the constructor does work to prepare it to send it to the player/players

#

hmm

lilac dagger
#

movement is really complicated for some reason

#

i think there's multiple packets you need to send first

#

why wouldn't a move packet not move an entity

#

@autumn zinc really sorry, i don't think i have enough time to debug this

#
                 
  if (this.entity.needsSync || this.trackDelta || this.entity instanceof LivingEntity && ((LivingEntity)this.entity).isFallFlying()) {
                        Vec3 vec31 = this.entity.getDeltaMovement();
                        double d0 = vec31.distanceToSqr(this.lastSentMovement);
                        if (d0 > 1.0E-7 || d0 > (double)0.0F && vec31.lengthSqr() == (double)0.0F) {
                            this.lastSentMovement = vec31;
                            Entity entity2 = this.entity;
                            if (entity2 instanceof AbstractHurtingProjectile) {
                                AbstractHurtingProjectile abstracthurtingprojectile = (AbstractHurtingProjectile)entity2;
                                this.synchronizer.sendToTrackingPlayers(new ClientboundBundlePacket(List.of(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.lastSentMovement), new ClientboundProjectilePowerPacket(abstracthurtingprojectile.getId(), abstracthurtingprojectile.accelerationPower))));
                            } else {
                                this.synchronizer.sendToTrackingPlayers(new ClientboundSetEntityMotionPacket(this.entity.getId(), this.lastSentMovement));
                            }
                        }
                    }```
#

i found this

#

but it doesn't tell me much

autumn zinc
autumn zinc
lilac dagger
#

all this does it checks if it's higher than a value and if it's a projectile it sends 2 packets, otherwise just one

autumn zinc
lilac dagger
#

well, this is what i found

#

i'll try to look for 20 more minutes

lilac dagger
#

let's try seeing which packets get sent during movement

#

it has to be more complex than just this packet

autumn zinc
# lilac dagger let's try seeing which packets get sent during movement

I understood, that smooth movement can be achieved without motion packet - you just have to send move.pos packet every tick

like calculate offsets using this code

short x = (short) (entity.getX() * 4096D - previous.getX() * 4096D);
short y = (short) (entity.getY() * 4096D - previous.getY() * 4096D);
short z = (short) (entity.getZ() * 4096D - previous.getZ() * 4096D);
new ClientboundMoveEntityPacket.Pos(entity.getId(), x, y, z, false);

previous it is a last location of the entity

well if you want to move an entity 5 blocks along X+ in 1 sec (20 ticks), you have to calculate offset per tick:

double distance = 5; // 5 blocks
double time = 20; // 1sec
double offsetPerTick = distance / time;

and then every tick send pos packet with adding an offset per tick

lilac dagger
#

delta time for the win

#

but i wonder why this packet doesn't work

#

it should do pretty much the same thing

chrome beacon
#

?services

undone axleBOT
lilac dagger
#

so add entity takes a motion

#

doesn't work

#

entity set motion doesn't work

#

i can't pick anything during packet sniffing related to this

#

i assume the pos is when the villager tries to move while on the ground

#

and it's also not every tick

thorn isle
#

last i checked the protocol, entities do send pos/posrot every tick, regardless of whether they actually changed position or not

#

not sure when they send motion packets, i think that might be up to the entity property data sync whatever the fuck logic

lilac dagger
#

hmm

#

let me try one thing

#

send a motion packet and then a pos

#

it still doesn't feel as fast to be per tick in my testing

#

i am actually stubborn

#

i wanna figure out what mojang did exactly

#

my guess is they use the set entity motion to smooth out in between position changes

thorn isle
#

that's handled through regular interpolation

#

motion is for clientside predictions for the next tick

lilac dagger
#

that might be it yeah

#

well, that's sad

thorn isle
#

what were you trying to do?

lilac dagger
#

trying to help iwust above

#

he went with position update and delta time

#

i hoped there was a way to cut that packet

chrome beacon
#

I already told you where to post

#

?services

undone axleBOT
buoyant viper
autumn zinc
# lilac dagger trying to help iwust above

i wanted to move entities smoothly, and i achieved this buut it works perfect only with living entities such as zombies or villagers, when i try to do it with item displays their movement is still jerky

buoyant viper
#

the funny part is originally i started the project as just the Server portion, and on a newer Java version (like 17 i think), but eventually downgraded to java 8 after i started building the Client code, since it wouldve been redundant to have mine + the built-in client

#

i should split them really but u never know when ur gonna need a HTTP Server on java 8..

#

however, not having access to features like record does negatively impact my health

lilac dagger
#

what do you use the http server for?

#

😄

buoyant viper
slender elbow
lilac dagger
#

cool :d

buoyant viper
#

and there have been a few times ive embedded the server code into other programs for callbacks with api tokens like Spotify

buoyant viper
#

id just use the built-in http client over my own

slender elbow
#

why downgrade to java 8 to begin with tho?

#

strange choice

buoyant viper
#

wanted to write client, wouldnt make sense if i stayed on newer java that already had a client framework

slender elbow
#

so you downgraded for the sole purpose of writing a client? and you wrote a client because you decided to write for java 8?

buoyant viper
#

kinda yeah

#

i do still have some other projects on 8 that could benefit from having a nicer api instead of rawdogging HttpURLConnection so it wasnt a complete waste

#

and thus have switched to my client framework, instead of rawdogged HUC

#

i could split the projects, me no wanna

#

regardless of the java version though... i need to learn how to properly read the full channel rather than relying on hoping everything fits in my initial buffer

#

so some server functionality is half-baked bc i dont bother to read past N(bufsize) bytes (reading content body in a request)

slender elbow
#

neat

buoyant viper
#

a non-issue when i was on java.io, but NIO has ever so slight differences bc of the Buffers that i lost some correctness when i initially moved over

#

actually

#

i have an idea now

#

i think i can just allocate a second (larger) buffer, copy the remaining from the first, and then read from the channel again

#

dealing with variable-length input when u have to use fixed-length apis sux idk how C devs do ts every day

lilac dagger
#

literally the one thing keeping me away from learning nio sockets

#

the buffer is so weird to use

#

netty is non blocking and it has a nice byte buffer to work with

#

(old io)blocking sockets too

buoyant viper
#

it's my own fault really, that i didn't think to redesign more when i decided to switch to nio. this is the consequence of my actions

lilac dagger
#

well, you did good tho

#

i have to get to learn nio sockets as well

#

even if i don't like working with them as much

#

probably once i figure them out i'll like them

buoyant viper
#

its a nice api honestly

cunning flare
#

jag dog och skule hemta mina saker och blev banad i 30 dagar för grov stöld??

lilac dagger
#

ja ja

#

seriously tho, keep it english please

buoyant viper
#

its not vastly different from using regular .io at the end of the day (at least for me), and being used to nettys bytebuf will probably give u an edge

cunning flare
#

men får man inte hemta sina saker utan att bli banad??

chrome beacon
slender elbow
#

i mean the jdk http client will give you the raw response as a List<ByteBuffer> (or, well, you pass a Flow.Subscriber<List<ByteBuffer>>), you can do the same really

#

or if you want to keep it in a contiguous buffer you'd need to realloc and copy

buoyant viper
#

im talking for the server portion rn

slender elbow
#

sure

buoyant viper
#

the client is still using .io actually lol

slender elbow
#

but it's all the same

#

regardless of whether it's the client or the server, you have a SocketChannel, and you need to read data into a ByteBuffer, or a collection of ByteBuffers

buoyant viper
#

yes

slender elbow
#

i'm just saying that's what the jdk http client chooses to do

#

not a strategy only to be employed in such setting

buoyant viper
#

i think i can get away with 2 buffers if i give ample leeway for the http head

#

i will still enforce a max size for the content body (i think this boils down to arrays in java not? being able to exceed 2^31 - 9 in length)

lilac dagger
#

i wonder how the header and body are placed from a client

buoyant viper
#

http makes heavy use of newlines as a delimiter

#

\r\n specifically i believe

lilac dagger
#

so header here\r\nbody here?

buoyant viper
#

the split between head and body is when u have 2 consecutive newlines

lilac dagger
#

oh i see

#

interesting

buoyant viper
#
HEAD
Key: Value

Body```
lilac dagger
#

so each key and value come with a \r\n?

#

and when it comes to body twice?

slender elbow
#

now do chunked encoding!

buoyant viper
#

fukckkkk that

#

one request or nothing big dog

lilac dagger
#

what's chunked encoding?

slender elbow
#

it's still one request!

buoyant viper
#

yeah but its split up :(

slender elbow
#

:)

lilac dagger
#

oh so like multiple requests in one

#

insteresting

#

how does that work?

buoyant viper
#

thats above of my pay-grade

lilac dagger
#

doesn't sound impossible tho

slender elbow
#

instead of passing the content-length header, the body is split up in chunks that are length-prefixed (plus crlf)

lilac dagger
#

oh

buoyant viper
#

HTTP 1.1 feature iirc right

lilac dagger
#

you got this winpixie

slender elbow
#

in the case where you don't or can't know the full body length ahead of time

buoyant viper
#

and then HTTP 2.0 builds on that with multiple requests in one socket i believe

slender elbow
#

so you choose to stream it instead

buoyant viper
#

my saving grace if the client detects i dont support chunking i think i can avoid it

#

i will need to stop reporting as HTTP/1.1 though, pretty sure

#

maybe 0.9 or 1.0

#

clients are pretty smart at adapting their function to the server

#

sadly, i am not smart at adapting to the client

lilac dagger
#

wait, does this work for anything that's not application/json?

buoyant viper
#

chunking can apply to anything i believe

#

u can reconstruct any content type so long as u have the data u need

lilac dagger
#

i assume application/json is just a header for the processor

#

nicee

#

i might make a http client

buoyant viper
#

Content-Type just tells the client/server... the type of the content being sent

lilac dagger
#

ye, i kinda figured it as i said

buoyant viper
#

ye

#

u could omit the field, but ur not gonna have a nice time, like, anywhere

lilac dagger
#

tbh, the http protocol is not as complicated as i thought

#

i mean sure there's chunking and such

#

but with enough tinkering you can get it to work

buoyant viper
#

just wait until u deal with HTTP/2 and HTTP/3

lilac dagger
#

lol

buoyant viper
#

jk those r probably "easy", im just dumb lol

lilac dagger
#

nah, you just need to get into hyper focus and add those features

buoyant viper
#

im not sure what HTTP/3 looks like since its not on TCP anymore

#

it uses QUIC (UDP)

lilac dagger
#

oh udp

buoyant viper
#

requests might look relatively the same, but chunking i imagine is a must-have bc of the lossy nature of UDP

lilac dagger
#

ye

#

well, if i have time i'll give it a try tbh

buoyant viper
#

or well not lossy, but... limited single transmission size

#

(but also a little lossy)

buoyant viper
#

i still have no SSL support tho 😿

lilac dagger
#

that's for securing http no?

buoyant viper
#

yes

lilac dagger
#

you can try it tbh

buoyant viper
#

my server can only serve HTTP rn, not HTTPS (unless u cheat and hide it behind a secured proxy) (cough cough cloudflare) (or on-site nginx reverse proxy cough cough)

lilac dagger
#

well, did you look into the implementation?

buoyant viper
#

nah

#

my server implementation is mostly based on reading RFCs addressed for HTTP and observations from what my own browser sends

#

not so much how others chose to impmement

lilac dagger
#

spring boot has a nice client impl

buoyant viper
#

waow

#

i should try and add a function (similar to newer javas HttpClient) that can apply a content mutator for u to use when building the request

#

rn i have a method in the Response class thats "good enough" that looks like java <T> T getBodyAs(Function<byte[], T> mutator)

lilac dagger
#

pretty cool

buoyant viper
#

javas client has BodyHandlers that u use when sending the request i think

#
<T> HttpResponse<T> send(HttpRequest request, HttpResponse.BodyHandler<T> handler)```
lilac dagger
#

i might at first try to use java to do this

#

and see how it goes

robust helm
#

how can i get the itemstack when throwing an trident?
im using ProjectileLaunchEvent with getShooter().inventory.itemInMainHand but that doesn't seem to work

#

probably because the trident is already in the air when the event is called and no longer an item

#

ngl i didnt try adding a debug message

#

but maybe someone knows from the top of their head

buoyant viper
#

?jd-s

undone axleBOT
buoyant viper
#

cast projectile to Trident i believe @robust helm

chrome beacon
#

getItem on the Trident

robust helm
#

thanks that should work :)

buoyant viper
slender elbow
#

what if I send way too many headers to fit in your initial buffer

buoyant viper
#
SocketChannel channel = getChannel();
ByteBuffer initialBuffer = ByteBuffer.allocate(8192); // 8KB buffer for header

channel.read(initialBuffer);
initialBuffer.flip();

// do processing with head buffer
doStuff(initialBuffer);

// read content body
int contentLength = getContentLength();
int remaining = contentLength - initialBuffer.remaining();
ByteBuffer contentBuffer = ByteBuffer.allocate(contentLength);
contentBuffer.put(initialBuffer);

while (remaining > 0) {
  remaining -= channel.read(contentBuffer);
}```
sly topaz
#

is the project you're making an http client

#

because otherwise I don't understand why you're spending time with this lol

buoyant viper
sly topaz
buoyant viper
#

i like reinventing the wheel

#

even if there are significantly more squares

sly topaz
#

I just thought it'd have some relation to minecraft since well, this is spigot in the end

buoyant viper
#

it can

#

ie. embedded web server for a control panel

sly topaz
buoyant viper
#

(even if there are much better frameworks for such goals)

slender elbow
#

good luck?

buoyant viper
#

if ur sending a header over 8KB i implore u to reevaluate ur life choices

#

thatss so many bytes

#

(cookies can easily become an issue)

#

there is a way to tell the client they sent a header or content body too large to be processed so i could just do that

#

i think im calculating my remaining bytes wrong actually

#

and i think it does have to do with the buffer potentially filling up without completing

#

so contentBuffer might accidentally fill up with data from headers

buoyant viper
#

ok so ive added a safeguard against that for now

buoyant viper
#

ill need to rethink how i read headers, or just tell the client "hey, this is 2 large 4 me"

#

ill need to rewrite my readLine function though to let me know when i lose the buffer midway through a line read

mortal vortex
mighty wind
#
        <dependency>
            <groupId>me.libraryaddict.disguises</groupId>
            <artifactId>libsdisguises</artifactId>
            <version>11.0.0</version>
            <scope>provided</scope>
        </dependency>
#

just switched pcs

#

loading up an old project

#

anyone know why this might be really angry

#

and red

lilac dagger
#

did you change the repo?

#

<repository>
<id>libraryaddict-public</id>
<name>libraryaddict repo</name>
<url>https://mvn.lib.co.nz/public</url>
</repository>
@mighty wind

#

<dependency>
<groupId>me.libraryaddict.disguises</groupId>
<artifactId>libsdisguises</artifactId>
<version>11.0.16</version>
<scope>provided</scope>
</dependency>

#

i use this version

#

but there might a newer one

mighty wind
#

this is from like a year ago

#

so idk

mighty wind
#

1.21.8

#

nvm it works now i think

lilac dagger
#

yay 😄

#

just reload maven so it pulls the dependency from the repo

thorn isle
#

libraryaddict can't into maven so he keeps changing the artifact coordinates every 3 days

lilac dagger
#

i just put my stuff on jitpack

#

but libsdisguise had to change the repo since it was hosted on md5's repository

thorn isle
#

and then on mythic's repository

#

and then changed the artifact id and org 5 times

#

and even then 80% of the time the deployed artifact doesn't match what you'll get from spigot/ci

#

there's a good chance he's changed some internals in a breaking way and just pushed it under the same version/snapshot without a corresponding spigot update, or vice versa

#

i've entirely given up trying to depend on the artifact from the repo, i just build the plugin myself and deploy it on the server and to my maven repo

half gust
#

does anybody know how, in a datapack, how to replace the lava in the nether with blue ice? I was able to replace all the lava pools, but not the lava generated ontop of basalt deltas.

slender elbow
#

saw the invite layout and thought it was another hot women camgirl egirl nude 18+ sexy spam

vagrant stratus
#

ngl i almost jumped to banning them lmfao

idle quarry
#

hey, does anyone knows why I can't compile my plugin.

I updated from 1.21.11 to 26.1.2 and now I can't compile it (maven)

First error was java 25 since I had j21 but now the error is just can't find any code

young knoll
#

?notworking

undone axleBOT
#

"Does not working" is a useless statement. Please describe what exactly is not working, what you expect it to do, and what actually happens. If you get any console errors, also ?paste the entire stacktrace.

idle quarry
#

The error literally says can't find [piece of code]

#

i suspect something to do with Lombok but getters are working fine in the ide

young knoll
#

Does your ide show an error at that line

idle quarry
#

nope

#

same version of the code can be compiled with 1.21.11 and java21

#

I was trying to update it for latest version but ....

chrome beacon
#

Try not setting Java 8 as your Java target

idle quarry
#

I tried in pom 25

#

same error

sullen marlin
idle quarry
#

i did to the latest version

#

Latest is .44 (?)

sullen marlin
#

Oh you also need to add it as an annotation processor

#

See maven compiler plugin

idle quarry
#

Thanks, i'll take a look soon

idle quarry
#

?paste

undone axleBOT
idle quarry
chrome beacon
idle quarry
#

okay it is fixed thanks everyone

#

also anyone can explain why is that needed for newer versions

#

i feel like every new version there is going to be something new that will fuck up my compiling process

#

does gradle have the same issues?

fickle spindle
#

which is the configuration library most used in plugins / public and private, because i'm starting to have the problem that it get all organised wrongly (i know i did a similar question in the past but today is the day i need the final answer)

chrome beacon
#

They break stuff all the time

#

Anyways yes that would have happened in Gradle too

young knoll
#

The solution is to not use Lombok

pastel swan
#

What’s the first farm you build every new world?

idle quarry
#

😭

worldly ingot
#

I mean your IDE can auto generate them in one click :p

#

The solution REAL developers don't want you to know about: Make all your fields public! 🤫

idle quarry
#

haha, I'm so used to private fields

worldly ingot
#

As you should. I'm memeing

#

Encapsulation is important lol

idle quarry
#

yeah maybe not that important in plugins but in other aspect is 100%

fickle spindle
idle quarry
#

checkout packetevents

lilac dagger
worldly ingot
#

I just type the field name, but yeah, whatever floats your boat

lilac dagger
worldly ingot
#

Takes a split second to generate them, or you can use an actual dedicated menu for it to generate all of them at once for all your fields

lilac dagger
#

this is better

#

thx, i'll type the field name instead

remote swallow
#

If your on intelllij iirc default generate keybjnd is alt+insert and you can generate getters settings equals hash code override etc

lilac dagger
#

it generates it

#

but not where i want it

#

oh nvm

#

it generates at cursor position

#

perfect

#

@remote swallow thx sir

#

this is the way

remote swallow
slim wigeon
#

As you know, I came from SA-MP with player ids like the yellow text. So what I asking here, is there a api like Vault that assigns player ids and I get that from the api into my plugins I create?

mortal vortex
#

SA-MP
?

slim wigeon
#

San Andreas MultiPlayer

sullen marlin
#

What do you mean player id

mortal vortex
#

Who the fuck knew that, who are you addressing with "as you know"

sullen marlin
#

Groups?

mortal vortex
#

player ids like the yellow text
That yellow text looks like a level system, seeing as YOU are on 0, and someone with "OG++" is 201.

slim wigeon
mortal vortex
#

Why do you need an API for 10 lines of code?

slim wigeon
#

That is possible but last I heard, the data don't transfer between plugins. Yes, there is this api like Vault that made this possible but I don't know what they did

mortal vortex
#

i have literally never heard of this

mortal vortex
#

It's not like you're losing integration because, given how I have literally no idea of an API like this existing, its likely that not many plugins are hooking into whatever this API might be.

#

You might as well make the API urself.

slim wigeon
# mortal vortex Make ur own API then.

I looking at my source code and found this: private boolean setupShop() { if(getServer().getPluginManager().getPlugin("MGN_ServerShop") == null) { return false; } this.shop = (com.mrnategeek.serverShop.Main) Bukkit.getPluginManager().getPlugin("MGN_ServerShop"); return true; }That is one way which I going to use. Don't mind me, my mind. Its been a min since I worked on this. Don't mind me, sorry

mortal vortex
#

I'm not sure what you're trying to say

quaint basin
#

https://pastes.dev/w2LD9C2fP0 How can I guarantee that PlayerJoinEvent will be called if AsyncPlayerPreLogin is called? Perhaps this isn't possible, and I need to remove the map key from the cache if the player doesn't log in within x seconds (where x = timeout seconds)?

#

I imagine that if a plugin uses event#disallow, then the playerjoinevent will not be called

slender elbow
#

join event is not called if async pre login doesn't go through

#

so you already have that guarantee

#

join event is already after the login process when the player entity is being spawned and the player data broadcast to other players

#

if the login events are disallowed, then none of that can happen as there is no player to spawn

mortal hare
#

nice glitch

quaint basin
sly topaz
#

so they don't join the server

#

this kind of thing is easy to test though, you can just give it a try

lilac dagger
#

If you disallow it won't go further

#

Player join event is happening at a later stage

dark arrow
#

hello I had a question
like I know all note block states and mushroom block state textures can be altered in texture pack , what else can I alter to get more textures that I can cutomize

chrome beacon
#

I believe there are some note block states you can use

thorn isle
#

waterlogged double slabs are unobtainable in survival and can be safely replaced (but they will act as water source blocks)

#

the age:0 sapling states appear identical to the age:1 saplings and can be safely replaced, although it's more complicated as you want a protocol level filter that replaces natural age:0 saplings with age:1 saplings

#

the nice part about saplings is that they're not solid and so won't occlude any adjacent block faces

random grove
#

If I schedule an async task, and it's runnable is in the middle of running, and the server shuts down while the runnable is running, will the server wait for the runnable to complete?

thorn isle
#

kind of, but not in any proper or controlled way

#

after the server is otherwise completely shut down, it will wait an extra 10 seconds for bukkit async scheduler threads to complete

#

they will not be interrupted and bukkit does nothing to signal to them that the server is shutting down; you can't rely in InterruptedException and have to manually check on a loop whether to exit the thread

#

if the threads don't complete in that 10 extra seconds, they just get killed and the jvm terminates

#

this is one of my major pet peeves, making long-running and blocking async tasks much more annoying to write correctly, as bukkit doesn't use the first class language feature specifically intended to notify threads to clean up and terminate that's been in the language for like 20 years

random grove
#

Alright, thanks. I will just have to make something on top of it then.

thorn isle
#

my personal recommendation is either using your own executor/scheduler and terminating it in onDisable, as this will fire interrupts correctly

#

or manually propagate interrupts to your bukkit async task threads, but that's kind of ass

thorn isle
#

in bukkit what you have to do instead is

long started = System.currentTimeMillis();
Response response = null;
while (System.currentTimeMillis() < (started + 60_000) && !Bukkit.isShuttingDown()) {
   try { response = future.orTimeout(5_000, TimeUnit.MILLISECONDS).join(); }
   catch (TimeoutException ex) { continue; }
}
#

which is as you can see SO much easier than just try catch interruptexception

#

i asked about this at paper once, and it still makes me mad

#

"we don't want to do interrupts because they're hard to get right and confuse plugin developers, and then you'd have to check for and catch interrupts everywhere in async task code"

#

YEAH that's kind of the point of the exception; if you do something that blocks the thread, it's your main (and sometimes only) mechanism to pull back

#

what, are we intended to try catch ignore it in async task code instead and ad-hoc it in 200 different ways with manual boilerplate?

young knoll
sly topaz
#

I vaguely remember that one just cancelling tasks when terminated, don't remember if it awaits or not (though I imagine it should? How do you deal with classloaders closing before the task is finished otherwise)

buoyant viper
#

(i dont like the current way i load my central bank)

#

what would be a good way to manage them in database? im thinking a table that has bank names, and generated tables for each bank

CREATE TABLE IF NOT EXISTS banks (name VARCHAR(255) PRIMARY KEY)

CREATE TABLE IF NOT EXISTS TABLE bank_bankname (owner VARCHAR(36), account VARCHAR(255), balance BIGINT, UNIQUE(owner, account))```
grave abyss
#

is there a way to decompile a minecraft client class when working on a plugin? (ping on answer pls)

young knoll
#

You’d have to add the client as a dependency

grave abyss
young knoll
#

Or just do it externally

mortal vortex
worldly ingot
mortal vortex
worldly ingot
#

Relatively. Fabric people

young knoll
#

Wait that’s really nice

ivory sleet
#

is there a way to switch between vineflower and cfr?

young knoll
#

It even works on mobile for when I get those brain blasts in bed at 3am

mortal vortex
#

bruh istg ur always on mobile

slender elbow
paper crest
#

Hey, when I switch to Java 25 Lombok is not working. I have the latest version.
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.44</version> <scope>provided</scope> </dependency>
On Java 21 works fine.

dry hazel
#

did you add it as an annotation processor?

#

maven doesn't scan the classpath for annotation processors for projects targeting JDK 23+ anymore

dry hazel
quaint basin
#

https://pastes.dev/5d8kHeL59a Do I have a guarantee that the value of serverId on line 97 will have the value initialized on line 78 (the value read from the redisExecutor thread) if I never redefine it anywhere else except on line 78?

hazy parrot
#

yes

quaint basin
#

the JVM model?

hazy parrot
#

it is going to read static variable every time it is executed

#

so yeah, if you are not modifying it elsewhere, it is guaranteed

paper crest
#

is not abstract and does not override abstract method

quaint basin