#help-development

1 messages · Page 1343 of 1

ivory sleet
#

i believe so

quaint basin
#

yes but i would like know the difference between tooltip display and hidden components

#

item.setData(DataComponentTypes.TOOLTIP_DISPLAY, TooltipDisplay.tooltipDisplay().addHiddenComponents(DataComponentTypes.ENCHANTMENTS).build());

#

i think im doing well

kind hatch
#

Seems pretty straightforward.
Tooltip display is the parent for all data that is displayed in it.
Enchantments, Damage, Unbreakable, Lore, Trims, etc

Hidden components are what you want to hide from that list.
Certain items will be different since they have different components to begin with, but it's just hiding what you don't want to show.

quaint basin
#

i see

#

a enchantment is a component?

kind hatch
#

Yes

#

I believe everything on items is a component now (at least for vanilla), but don't quote me on that

young knoll
#

Yes

quaint basin
kind hatch
#

Couldn't tell you. I don't use paper, but just reading that and taking from context, it looks like how you would set it to hide all enchants on the tooltip.

quaint basin
kind hatch
#

Yes and no.
I don't run a server, but I like contributing to spigot. So I need to run them for testing.

quaint basin
young knoll
#

Yes it will hide all enchantments

quaint basin
#

how can i change this?

kind hatch
#

I don't get it, is that not what you wanted?

#

Are you trying to hide all enchantments or just one specific enchantment?

young knoll
#

It’s all or nothing

#

Unless you manually add enchantments to the items lore

quaint basin
young knoll
#

Why do you want to hide just the one

quaint basin
young knoll
#

There’s a component for that

quaint basin
#

this maybe item.setData(DataComponentTypes.ENCHANTMENT_GLINT_OVERRIDE, true);

slender elbow
#

enchantment_glint_override moment

quaint basin
#

yea

#

thanks

#

ai moment

#

AI led me to error

quaint basin
#

Is it possible to prevent an item from being renamed using components or something similar?

#

or need use listeners?

young knoll
#

Probably listeners

quaint basin
#

ItemEnchantments.Builder enchantsBuilder = ItemEnchantments.itemEnchantments()
.add(Enchantment.EFFICIENCY, 5)
.add(Enchantment.UNBREAKING, 3)
.add(Enchantment.MENDING, 1);

    if (id == AmethystItemId.TREE_CHOPPER) {
        enchantsBuilder.add(Enchantment.SILK_TOUCH, 1);
    }

    item.setData(DataComponentTypes.ENCHANTMENTS, enchantsBuilder.build());

Enchantments are applied without calling the build call. Should I keep the build call?

chrome beacon
#

Yeah it just calls build for you

quaint basin
#

oh i see

sullen marlin
#

Doesn't setting the system line ending property work? I'm sure does from command line but idk if from within pom.xml properties

#

line.separator or whatever

quaint basin
#

@Override
public EconomyResponse withdrawPlayer(OfflinePlayer player, double amount) {
return withdrawPlayer(player.getName(), amount);
}

The vault uses the player name for this. Isn't that dangerous?

chrome beacon
#

Depends

#

There won't be two users with the same name online at the same time

quaint basin
#

Let's say a premium player with nickname A puts an item up for auction. Then they change their nickname to B, and a premium player registers nickname A. Another player buys the item initially from A, and I do a vault#depositMoney to player A because A sold the item. The wrong player receives the money, and player B, upon entering the server for the first time with the new name, the item is sold and is left without the money (B sold the item because I assume the auctionhouse plugin uses the UUID)

thorn isle
#

that's a default implementation that can be overridden by the economy provider, i think

#

it's impossible to say without me actually looking up the class because i have no idea what you sent an excerpt of

#

but the answer basically is "depends"

chrome beacon
#

It's the AbstractEconomy class

#

It's up to the economy plugin implementation to decide what happens

chrome beacon
#

Vault is just a bridge. It may or may not actually use the player name when you pass the offline player instance

quaint basin
#

yea i see

#

thanks

kind hatch
#

Idk, that feels kinda hacky to me now that I think about it

kind hatch
#

Yea, it's MAVEN_OPTS, but how can you set it within maven? Specifcally through one of its plugins.

buoyant viper
#

oh

#

idk

#

u might be able to put a .mvn folder in the project root? idk

kind hatch
#

So, this was weird.

#

Running mvn clean package -Dline.separator=\n in the IDE still results in differences.

#

Setting the env var fixed the issues with the diff that it created, but still has differences in the pom.properties.

quaint basin
#

[02:11:10 WARN]: Couldn't look up profile properties for 5fd75f1a-4f6f-354e-b204-6affa1df39bd
com.mojang.authlib.exceptions.MinecraftClientHttpException: Status: 403
at com.mojang.authlib.minecraft.client.MinecraftClient.readInputStream(MinecraftClient.java:100) ~[authlib-7.0.61.jar:?]
at com.mojang.authlib.minecraft.client.MinecraftClient.get(MinecraftClient.java:56) ~[authlib-7.0.61.jar:?]
at com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService.fetchProfileUncached(YggdrasilMinecraftSessionService.java:197) ~[authlib-7.0.61.jar:?]
at com.mojang.authlib.yggdrasil.YggdrasilMinecraftSessionService.fetchProfile(YggdrasilMinecraftSessionService.java:167) ~[authlib-7.0.61.jar:?]
at com.destroystokyo.paper.profile.PaperMinecraftSessionService.fetchProfile(PaperMinecraftSessionService.java:40) ~[paper-1.21.11.jar:1.21.11-131-6d5b910]
at com.destroystokyo.paper.profile.CraftPlayerProfile.complete(CraftPlayerProfile.java:289) ~[paper-1.21.11.jar:1.21.11-131-6d5b910]
at com.destroystokyo.paper.profile.CraftPlayerProfile.complete(CraftPlayerProfile.java:278) ~[paper-1.21.11.jar:1.21.11-131-6d5b910]
at net.minecraft.server.network.ServerLoginPacketListenerImpl.callPlayerPreLoginEvents(ServerLoginPacketListenerImpl.java:329) ~[paper-1.21.11.jar:1.21.11-131-6d5b910]
at net.minecraft.server.network.ServerLoginPacketListenerImpl.lambda$handleCustomQueryPacket0$2(ServerLoginPacketListenerImpl.java:406) ~[paper-1.21.11.jar:1.21.11-131-6d5b910]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1090) ~[?:?]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:614) ~[?:?]
at java.base/java.lang.Thread.run(Thread.java:1474) ~[?:?]

#

should me worries?

hybrid spoke
#

?whereami is hunting a lot today

hybrid spoke
#

but looks like a rate limit, did you perform many calls?

young knoll
#

Shouldn’t that be http 429

hybrid spoke
kind hatch
# sullen marlin line.separator or whatever

Yea, it doesn't seem to matter what I do here, I'm still getting differences in the pom.properties files.

  • Running mvn clean package -Dline.separator=\n in the IDE
  • Setting the MAVEN_OPTS environment variable
  • Setting <line.separator> in the custom pom properties
    It is just not affecting the file for whatever reason.
foggy void
#

I'm making a plugin for a minecraft smp thats starting soon, and I'm basically making mythic items (such as the dragon egg, which increases your health from 10 hearts to 15 hearts) and I was wondering if there was a way to check the inventories of players that are offline. I need a command (for admins) that checks who holds the dragon egg and other mythics (like the only netherite set) and sees if these items have been destroyed, and I need help 🙁

thorn isle
mortal vortex
#

100%

pseudo hazel
#

or maybe explain what you actually need help with

#

aside from "write the plugin for me"

sand pasture
#

https://imgur.com/a/8oHnexy

Thru what can I achieve to make a clickable wall like as shown on the image, with custom mob icons, fonts, progress et cetera?

thorn isle
#

that is a bunch of item frames with custom map rasters drawn on them for the mob icons and fonts; the clickability is done by listening to the player interact event and raytracing/projecting the interaction point onto the image, then handling it as desired

#

the arrow icon on the right looks too high resolution to be a map raster, so i suspect it's a text display with some unicode arrow glyph, or a custom font glyph from a server resourcepack

quaint basin
#

I want to ensure that completablefuture doesn't remain stagnant forever

sly topaz
thorn isle
#

infinite nested futures

#

you should use composeAsync or whatever it is

#

basically any time you're creating a future within a future you're already off-track

sly topaz
#

that would still end up with a gigantic method doing too much, they need to rework that in order for the responsibilities of each callback there to be more clear

thorn isle
#

personally i prefer virtual threads

#

i don't know, the method is doing like 5 things with maybe 20 lines of actual business code

#

the rest of it is try-catch-finally and future/scheduler noise

sly topaz
#
public CompletableFuture<Boolean> addPlayer(UUID playerUuid, String name) {
    if (isFull(1) || playerNameByUuid.containsKey(playerUuid)) {
        return CompletableFuture.completedFuture(false);
    }
    if (!tryReserveSlot(playerUuid)) {
        return CompletableFuture.completedFuture(false);
    }
    return checkExtraSlots(ownerUuid)
            .thenComposeAsync(
                    extraSlots -> persistMember(playerUuid, name, extraSlots),
                    Bukkit.getScheduler().getMainThreadExecutor(BoxPlugin.plugin)
            )
            .thenCompose(pos -> publishAndApplyLocally(playerUuid, name, pos))
            .exceptionally(ex -> {
                BoxPlugin.plugin.getLogger().log(Level.SEVERE, "Error adding player " + playerUuid, ex);
                rollback(playerUuid);
                return false;
            });
}

if the word was sane this would basically be it

#

though I don't love that code, at least it is less of a burden in my eyes

thorn isle
#

much better, though i might propagate the exception to the caller

#

it's always a bit troublesome with futures to decide where to handle your exceptions

sly topaz
#

but then you can't handle rollback the add player action, it's annoying yeah

thorn isle
#

you could rethrow it in exceptionally after handling it 🤡

sly topaz
#

if that method was made to return the added value then maybe it'd be better to propagate the exception

thorn isle
#

or, more reasonably, branch off a separate future that you don't return which will handle the rollback

sly topaz
#
public CompletableFuture<Boolean> addPlayer(UUID playerUuid, String name) {
    if (isFull(1) || playerNameByUuid.containsKey(playerUuid)) {
        return CompletableFuture.completedFuture(false);
    }
    if (!tryReserveSlot(playerUuid)) {
        return CompletableFuture.completedFuture(false);
    }

    var future = checkExtraSlots(ownerUuid)
            .thenComposeAsync(
                    extraSlots -> persistMember(playerUuid, name, extraSlots),
                    Bukkit.getScheduler().getMainThreadExecutor(BoxPlugin.plugin)
            )
            .thenCompose(pos -> publishAndApplyLocally(playerUuid, name, pos));

    future.exceptionally(ex -> {
        BoxPlugin.plugin.getLogger().log(Level.SEVERE, "Error adding player " + playerUuid, ex);
        rollback(playerUuid);
        return false;
    });

    return future;
}

I guess this works

#

not sure how to feel about it

thorn isle
#

my preferred method with coordinating threaded behavior like this is by spawning a virtual thread and joining other futures

#

this is pretty clean as-is since it doesn't need any flow control within the futures

umbral ridge
#

how do you deal with stuff like that "Villager was squished too much"

[22:50:33 INFO]: Villager Villager['Villager'/73656, uuid='24215612-f89b-4df1-8acc-376e543dac05', l='ServerLevel[world]', x=-2483.30, y=44.00, z=-3207.12, cpos=[-156, -201], tl=30703, v=true] died, message: 'Villager was squished too much'```
how can you prevent from villagers being spawned in the first place. isnt it kind of tricky? spawn limit per chunk for entity is a mess.. because there are multiple ways to spawn them.. and for some ways its weird if you limit it but they all fall in the same "reason"
quaint basin
quaint basin
sly topaz
quaint basin
#

So I don't have to worry about it then?

sly topaz
#

for JUL, it reports to ErrorManager iirc

#

not that it cannot happen, but it shouldn't happen under normal circumstances

slender elbow
#

lol

#

remember that printf has a return code

#

most useless thing ever

thorn isle
#

this is why instead of completing futures manually, you use the factory methods and return from them

#

if anything throws within a future, the future is completed exceptionally

#

in this case, instead of passing a task to BoxPlugin.plugin.getRedisExecutor() which manually completes a future at the end, use the redis executor as an executor for an async future

sly topaz
#

I think the issue is that you're trying to rollback at every stage of the chain

thorn isle
#

and simply perform the task within the future

sly topaz
#

if you're using futures and propagating exceptions properly, you should just commit/rollback at call-site

young knoll
#

If the logger encounters an exception it has to pass it to the logger logger

#

Duh

sly topaz
#

mfw when the logger exception causes the logger logger to throw, so logger logger logger has to step in

#

I think there's a chinese proverb about this

young knoll
#

It is in fact loggers all the way down

thorn isle
#

and then you have paper adventure which makes player.sendMessage throw if it sees a §

quaint basin
#

I think I'm doing well

thorn isle
#

which, given how frequently that occurs in legacy codebases and configs, totally never happens

slender elbow
#

i love lying on the internet

thorn isle
#

and has totally not resulted in item duplication issues or anything because inventory.takeShit runs after a player.sendMessage in 1000 places of random business code

quaint basin
#

so yea

#

but i think 2nd is better

thorn isle
#

that's better

#

now also use the bukkit executor instead of scheduling a task with try catch and manual future completion in it

quaint basin
#

will not change nothing bc the method is called on a CF yk

#

but yea is better

young knoll
#

I thought it was minimessage that throws in that situation

thorn isle
#

same principle as with the redis executor

young knoll
#

At least that’s where I’ve encountered it

thorn isle
thorn isle
quaint basin
#

u say to do that bc is more clear?

thorn isle
#

try catch manual complete = bad

quaint basin
#

i see

thorn isle
#

use executor = good

sly topaz
#

but it is only enabled on test environments such as the ones generated by run-task, not by default

#

and it only prints it, doesn't throw

thorn isle
#

i think it might be minimessage or something, i don't remember the stack trace

quaint basin
sly topaz
#

it does print a stack trace, but it doesn't throw 😛

quaint basin
#

37 to 16 lines

thorn isle
#
[13:15:05 ERROR]: Could not pass event TownyBuildEvent to SiegeWar v${project.version}
net.kyori.adventure.text.minimessage.internal.parser.ParsingExceptionImpl: Legacy formatting codes have been detected in a MiniMessage string - this is unsupported behaviour. Please refer to the Adventure documentation (https://docs.advntr.dev/) for more information.
#

it throws

#

at least on whatever version i'm on; i'm on some random paper build of 1.21.11

#

i wouldn't care if it didn't throw

#

^ this was me doing player.sendRichMessage with a string pulled from a config

#

but the config value had a § in it

#

so the event handler threw before it could check perms or cancel, and suddenly everyone was able to build in every town

#

another plugin had a similar issue except it sent a success message from a config in between giving crate reward items and consuming the crate key

#

which resulted in the key being infinitely reusable

sly topaz
#

oh the MM parser does throw separately from the legacy nag property

#

that's fun

thorn isle
#

very fun

thorn isle
#

sendRichMessage was supposed to be the super useful and friendly and convenient formatted message facility that legacy colorcode guys like me who liked the old concise color codes would migrate to

#

now i have to wrap every call of it in try catch ignore throwable

#

which is neither friendly nor convenient

#

i can't even run the strings through the minimessage legacy string parser, because that will escape the actual minimessage tags

sly topaz
thorn isle
#

fucking ajan

#

jesus christ

#

@rough sonnet

#

i swear i will fly to turkey and shit on his bed

sly topaz
#

the fact that you know is hilarious

thorn isle
#

we've collaborated on some projects

sly topaz
#

could just PR to adventure to see if they put the MM nag behind the same system property as the one in TextComponentImpl tbh

rough sonnet
#

HAHAHAHAHAH

sly topaz
#

and make it an actual Nag, not a throwing exception

young knoll
#

I think I got around that by leaving them as & codes, minimessage parsing, then converting that to legacy and then using translateAlternateColorCodes

#

Yes that’s very janky

#

I’m aware

sly topaz
#

I think you're not the first one to do that because I have a dejavu feeling about that solution

#

it is what it is

quaint basin
#

https://pastes.dev/fwiAbmHvOX If an exception occurs in Redis, the member is removed from the database, but Redis and the local cache retain it. How should I handle this?

#

BoxPlugin.plugin.getBoxService().removeMember(ownerUuid, playerUuid) is the database call

#

BoxPlugin.applyBoxListEntry() is the redis call

echo basalt
#

I'm more concerned about your project structure than mystical db failure

fathom fable
#

or what you can do idk your structure behind is trying to change the relationship for the entities.. alternatively

quaint basin
fathom fable
#

You got the exact error message?

#

Maybe im able to help you out now

sly topaz
#

to be fair I am also questioning the redis usage here lol

#

you got a bit too many layers tangled up there

fathom fable
#

It could happen that you need to refetch the parent entity to have the updated users, it's pretty weird whats happening there..

quaint basin
#

very good question too

#

let me see

fathom fable
#

If you can provide an actual error message i believe it's easier to help you

#

thanks

quaint basin
fathom fable
#

Can you debug throug hthe lines ?

quaint basin
#

i just want do some good practices

fathom fable
#

ah

#

doesnt need redis, nothing, has caching and all u need 💀

quaint basin
#

😂

fathom fable
#

okay your plan is to remove something of that boxservice?

quaint basin
#

i really cant understand me sometimes

#

lol

fathom fable
#

its fine at some point you will understand

#

just a learning process

quaint basin
fathom fable
#

You could also try to ask AI what's wrong there and how it could be improved

#

I mean i would need the error message in order to fix it..

it seems some error in your database query is happening

#

Can you debug live through the lines?

#

and check what's in variable ex?

#

if that doesnt work, go to the database request where removemember is happening and debug there through

#

sometimes database issues just get sucked up silently

quaint basin
fathom fable
#

No

#

You have it ideally inside a cache

#

a hashmap or something

#

wait i can show you how i did it in my oneblock system

quaint basin
#

Maintaining this in a local cache might be a difficult task

fathom fable
#

You should then handle it in a way where it should only be fetched once then on player join or something and work with it on that given server

quaint basin
#

What I did was keep this in Redis so that whenever someone wants to go to a friend's box, it's a query in Redis and not in MySQL. But I don't know if this is advantageous at all

fathom fable
quaint basin
fathom fable
#

How could it get out of sync?

quaint basin
#

I think the best solution here would be to have local caching + redis pub

fathom fable
#

if you just update the cached version only

quaint basin
fathom fable
#

and send it over to the db to update

#

ah nvm

#

thats how i find my island

    public @NotNull CompletableFuture<Optional<Island>> findByOwnerAndRegionAsync(
            @NotNull UUID owner, @NotNull RegionType regionType) {
        return query()
                .and("ownerUuid", owner.toString())
                .and(FIELD_REGION_TYPE, regionType)
                .firstAsync();
    }

and before fetching it im checking if its inside the Cache if so use it otherwise fetch it.

im using Caffeine for that

#

maybe a alternative for you

fathom fable
#

Yea i do use local caching

#

i never used redis before

quaint basin
#

your island plugin supports multi server setup

#

?

fathom fable
#

Could support it

#

but its orginally made just for one server

#

Because it has great performance, all islands will be on the same world

quaint basin
fathom fable
#

with multiple worlds depending on the size

quaint basin
#

I'm considering not using caching just for simplicity

fathom fable
#

Do what you prefer, i never used redis so can't really say anything about it

thorn isle
#

more like plebis

young knoll
#

Who needs redis when you can encode the data into json and then email it between servers

remote swallow
#

Why email when you could carrier pigeon it

mortal vortex
#

mqtt >>>

#

Given that you’re not saving anything

wet breach
#

Best part of that is that the OS maintains that so as long as it knows you are a retaining a descriptor for it and if your app crashes the OS will close it out for you after a period of time.

mortal vortex
#

mfw it’s time to migrate to a containerised setup and the intern used memory mapping..

muted elk
#

Anyne know a way to replicate this in 1.21.11?

thorn isle
#

hypickle does it by listening to player interact events and replacing the item in your hand with a sword with a rotated model

#

this is ass however because it is jittery and latency prone

#

you could perhaps try adding the blocks attacks data component on it, and then iirc there is a model predicate that allows you to use a different model for the item while it's "blocking" like a shield

#

i could be wrong, i can't find the list of all item predicates, the wiki is ass

muted elk
#

thanks

buoyant viper
#

i thought that they just use the component system that lets u set swords as blockable

#

although i guess that the client probably doesnt? have that specific animation anymore

thorn isle
#

there never was an animation, it was just a model swap

#

that is, the client would just change the rotation/translation of the model when holding rmb

#

that's still doable through the component system through the blocks attacks data component and item model predicates

#

i don't know why hypickle doesn't use it; they just replace the item in the player's hand with another using the same model+texture but different transformation

#

which makes it bob up and down with the "swap held item" animation each time, and since it's serverside it happens however many ms too late

#

i guess they don't care because their playerbase is mostly 1.8 pvp sweats anyway

young knoll
#

No they don’t

#

Hypixel doesn’t use a resource pack

#

*for most games

thorn isle
#

hm maybe i'm talking about some other big server

#

i was there like once because someone invited me

#

but it definitely was a sword with a custom transform

young knoll
#

Last I checked hypixel puts a shield in your offhand

thorn isle
#

i don't think i saw a shield

#

is hypixel the one with the zombies minigame?

young knoll
#

Yes

buoyant viper
young knoll
#

Though that one does use a resource pack

thorn isle
#

i don't remember which gamemode it was where i saw the sword

#

there was this big wooden platform with a big hole in the middle of it

#

i accidentally walked on a pressure plate and got blasted into oblivion 1000 blocks away

buoyant viper
#

i know last i played skywars on 1.21 it had a normal blocking animation from 1.8 (aka shitty one that insta transitions between blocked and unblocked)

worldly ingot
#

We use the blocking animation

slender elbow
#

consumable component use animation block :nodders:

worldly ingot
#

I think actually we use blocks_attacks now? I might be wrong though

slender elbow
#

something like that

worldly ingot
#

I dunno. One of those two lol

#

No more shield, basically

#

Yeah it's still the consumable component

slender elbow
#

woah

#

hacker

worldly ingot
#

kirbywoah hax0ring

slender elbow
#

just for funsies

worldly ingot
slender elbow
#

come onnnn

#

imagine you go to block and now it becomes a party

worldly ingot
#

I don't want that kind of party while I'm blocking

slender elbow
#

i'll block you

#

means hug in spanish

worldly ingot
#

Woah. So culturally diverse, you are

ancient plank
#

yay

young knoll
#

Ah the consumable component

#

Clever

foggy void
#

yo I'm making a plugin and i need help
basically I'm using the OpenInv plugin's api as a dependency to get the player's inventory, loop through it, see if I can find the dragon egg in his inventory (this is for offline players, its pretty simple for online players) and I'm not sure how to do this as there is no documentation that i can find for OpenInv's API

chrome beacon
#

Can just take a look at the api module on github

#

You're mostly interested in the IOpenInv interface that's implemented by the plugin instance

thorn isle
#

it isn't very clearly indicated (and i have no idea what an ISpecialInventory is in practice), but i think the intended approach is to load an OfflinePlayer into a Player and then use the regular bukkit inventory methods on it

foggy void
#

wha

sly topaz
#

@ancient plank

thorn isle
#

mrbreast

ancient plank
#

?ban 400934694843056140 bot/hacked acc

undone axleBOT
#

Done. That felt good.

round finch
#

why do i see these weird symbols?
btw im using putty and ssh into a vps

#

how can i avoid these issues in code?

young knoll
#

Looks like the result of the colour characters

round finch
#

thank you

fathom fable
#

Yes

wet breach
#

Just change the encoding and it should fix some problems

#

Putty for example will use ISO-8859-1 also known as latin-1

#

Then there is the issue of colors. Most terminals including putty only support 8 bit colors. Ironically I have a project that converts colors for console

ancient plank
#

cowors

buoyant viper
foggy void
#

thats good to know ig

foggy void
#

wait but like do u just do something like

for (OfflinePlayer offlinePlayer : offlinePlayers) {
  Player player = new Player(offlinePlayer or something idk);
  for (ItemStack item : player.getInventory().getContents() {
    if (item.getType() == Material.DRAGON_EGG) {
      player.getInventory.removeItem(item);
    }
  }
}```
#

im really new to java (just started learning java like a month ago lol) so im not very familiar with spigot api

lilac dagger
#

Nope

#

Not valid

foggy void
#

hhhhhhh ok

#

that figures

#

then how would u even instantiate a player object thats offine 😭

mortal vortex
#

thats the crazy part...

foggy void
#

would it be a better use of my time to just use OpenInv

mortal vortex
#

yes.

foggy void
#

ok

#

💀

#

I cant find the documentation 😭
where is ittttttttttttt

inner mulch
#

im trying to create a world, which works but when teleporting players to World#getSpawnLocation() it doesnt do anything

smoky anchor
#

?nocode

undone axleBOT
#

It’s hard to answer a programming question without code
Oh no! You ran into a problem. But no worries, people are willing to help, but first they need to see your code. This is because otherwise, they would be providing help based on guesses instead of concrete knowledge. Whether it be a compile error, runtime error, or an unexpected output, I'm sure that if you were to provide code, you'd receive a quick solution.

thorn isle
#

e.g. on IOpenInv.java

  /**
   * Load a {@link Player} from an {@link OfflinePlayer}. If the user has not played before or the default world for
   * the server is not loaded, this will return {@code null}.
   *
   * @param offline the {@code OfflinePlayer} to load a {@code Player} for
   * @return the loaded {@code Player}
   * @throws IllegalStateException if the server version is unsupported
   */
  @Nullable Player loadPlayer(@NotNull final OfflinePlayer offline);
inner mulch
#

im using the worldloadevent to detect the world finsih loading

buoyant viper
#

dont know why u deleted the teleport code screenshot, but getLocation() returns a copy of the location i believe

slender elbow
#

I mean the whole process is synchronous so world loading will be finished already by the time createWorld returns

inner mulch
#

i now know why it doesnt work

#

the player has passengers

#

and that isnt supported

#

is there a workaround?

slender elbow
#

unmount, teleport, mount

#

recursively of course

inner mulch
slender elbow
#

yea of course

#

and that's where the "recursively" comes in

inner mulch
#

is there are way i can auto detect "pre teleport" and when its finsihed, cuz i dont want to manually do taht every teleport

slender elbow
#

as those entities might themselves have passengers

#

no not really

#

just shove it in a util teleport function and call that instead

buoyant viper
#

someone should make an API method for that

inner mulch
buoyant viper
#

well? get to it.

inner mulch
#

idk how to use github

buoyant viper
#

ur the developer here.. smh

#

spigot aint even on github

slender elbow
#

:Clueless:

thorn isle
#

doesn't paper teleport with passengers by default now

slender elbow
#

can't do across worlds

#

or, not players anyway

slender elbow
#

same world is fine

thorn isle
#

right

buoyant viper
#

?jd-s

undone axleBOT
fathom fable
# inner mulch idk how to use github

i did something like

        service.getSpawnLocation(player).thenAccept(location -> {
            if (location == null) {
                PlatformScheduler.of(plugin).runSync(() ->
                        R18nManager.getInstance().msg("spawn.spawn_not_found").prefix().send(player));
                return;
            }
            PlatformScheduler.of(plugin).runSync(() -> {
                ensureSafeLanding(location);
                player.teleportAsync(location);
                R18nManager.getInstance().msg("spawn.teleported").prefix().send(player);
            });
        }).exceptionally(ex -> {
            PlatformScheduler.of(plugin).runSync(() ->
                    R18nManager.getInstance().msg("spawn.teleport_failed").prefix().send(player));
            return null;
        });

/**
     * Creates a Bukkit world honoring per-world plot generation overrides.
     * Pass {@code null} for any override to fall back to the global config.
     *
     * @param name              the world folder name
     * @param environment       the world environment
     * @param type              the multiverse world type
     * @param plotSizeOverride  per-world plot size (PLOT only), or {@code null}
     * @param roadWidthOverride per-world road width (PLOT only), or {@code null}
     * @param schematicName     per-world schematic name (PLOT only), or {@code null}
     * @return the created Bukkit world, or {@code null} on failure
     */
    public @Nullable World createBukkitWorld(@NotNull String name,
                                              World.@NotNull Environment environment,
                                              @NotNull MVWorldType type,
                                              @Nullable Integer plotSizeOverride,
                                              @Nullable Integer roadWidthOverride,
                                              @Nullable String schematicName) {
        try {
            var creator = new WorldCreator(name)
                    .environment(environment);

            var generator = getGeneratorForType(type, plotSizeOverride, roadWidthOverride, schematicName);
            if (generator != null) {
                creator.generator(generator);
            }

            var world = creator.createWorld();
            if (world != null) {
                world.setKeepSpawnInMemory(false);
                logger.info("Created Bukkit world '{}' (env={}, type={}, plot-override={}/{}, schematic={})",
                        name, environment, type, plotSizeOverride, roadWidthOverride, schematicName);
            }
            return world;
        } catch (Exception e) {
            logger.error("Failed to create Bukkit world '{}'", name, e);
            return null;
        }
    }
#

but i also set the spawnlocation always manually lol

inner mulch
fathom fable
quaint basin
#

how can i get the new world on PlayerChangedWorldEvent ? Maybe player#getWorld ?

young knoll
#

Yes

quaint basin
#

Is there any upgrade animation I can create? In older versions it's usually just sound and title, but I think the newer versions allow for a cooler animation, like adding an item to the screen. How can I do that?

smoky anchor
#

Totem animation ?
You can change the item somehow, at worst just use item model data

slender elbow
#

yeah any item can bear the totem use animation if that's what you're talking about

#

or maybe you're talking about sprite object components?

quaint basin
#

need resourcepack?

smoky anchor
#

But it shouldn't require resourcepack

smoky anchor
#

I have no idea lol
But it is 100% possible in some form :)

quaint basin
chrome beacon
#

Yeah that needs a resourcepack

#

You can popup existing items but if you want text like that a resourcepack needs to add it

quaint basin
#

how can i do that?

buoyant viper
#

hey guys how do i

thorn isle
#

i recommend you skim over this whole page, because it basically answers 80% of "what/how can i do" questions pertaining to items, or at least gives you a starting point

quaint basin
#

im just receiving the item

thorn isle
#

yeah, give gives you an item

quaint basin
#

and how can i play the anim

tender shard
#

yes but they specifically asked about DataComponentTypes

smoky anchor
#

But there is some plugin that does this

tender shard
#

are you talking about the totem of undying animation?

smoky anchor
#

yes

tender shard
#

wait a sec

#

can't you just do player.playEffect(EntityEffect.PROTECTED_FROM_DEATH)

#

that's the totem animation thingy

young knoll
#

How does it determine which item

tender shard
#

for custom model?

#

It'll use the default totem textures unless you got a totem with custom model data in your hand

#

If you wanna force a specific model data, you'll simply have to fake it, e.g.

    fun totemAnimation(player: Player, modelData: Int, numStopSounds: Int) {
        val item = player.inventory.itemInMainHand
        val totem = ItemBuilder(Material.TOTEM_OF_UNDYING).setCustomModelData(modelData).build()

        stopSound(player)

        player.inventory.setItemInMainHand(totem)
        player.playEffect(EntityEffect.PROTECTED_FROM_DEATH)
        player.inventory.setItemInMainHand(item)

        stopSound(player)
young knoll
#

Nah you can give any item the death protection component now

tender shard
#

yes I know

young knoll
#

And I think it’ll play the animation with that item

tender shard
#

but you won't have the animation

young knoll
#

Ah

tender shard
#

no it won't

young knoll
#

Rip

tender shard
#

only totems will show the animation, others will just "silently" revive you

#

(at least that's the case when forced through the EntityEffect)

ivory sleet
#

pretty sure it plays the animation if it has the component

#

but yea if u wna just send the animation on its own, then u needa do it that way

smoky anchor
quaint basin
ivory sleet
#

myea the item model itself id assume is provided by the resource pack

smoky anchor
# quaint basin but this need resourcepack right

No, you can use any model from vanilla
If you want custom textures/model then yes, it would require resource pack
Example from alex uses custom model data, you just need to use item model component instead

sly topaz
buoyant viper
slender elbow
#

mcsrc.dev/1/26.1.2/net/minecraft/client/multiplayer/ClientPacketListener#L1210

#

bro forgot to check mcsrc.dev

#

membrillo

sly topaz
#

-# and yes my ign is Membrillo, it’s an investment

young knoll
#

Man just got sponged

open night
#

How do I appeal a ban on my Spigot MC account?

chrome beacon
#

?support Email support

undone axleBOT
buoyant viper
#

someone should make a totem system but it uses player heads

#

like lifesteal i guess? but not

#

idk ive never played a lifesteal server

weak isle
#

I wanna make a Minecraft server I need a dev

young knoll
#

?services

undone axleBOT
quaint basin
buoyant viper
#

probably only wants the animation and not the totem pop noise

#

idk

quaint basin
#

why i need 2 stop sounds call?

#
  private void totemAnimation(Player player) {

        ItemStack item = player.getInventory().getItemInMainHand();
        ItemStack totem = ItemStack.of(Material.GRASS_BLOCK);

        player.getInventory().setItemInMainHand(totem);

        player.playEffect(EntityEffect.PROTECTED_FROM_DEATH);
        player.stopSound(Sound.ITEM_TOTEM_USE);

        player.getInventory().setItemInMainHand(item);

    }
#

this is not working perfectly

#

just showing a totem on the anim instead grass

echo river
#

probably cuz the animation is hard coded with totem no ?

quaint basin
#
private void totemAnimation(Player player) {

        ItemStack item = player.getInventory().getItemInMainHand();
        ItemStack totem = ItemStack.of(Material.POISONOUS_POTATO);
        totem.setData(DataComponentTypes.DEATH_PROTECTION, DeathProtection.deathProtection());
        totem.setData(DataComponentTypes.ITEM_MODEL, new NamespacedKey("minecraft", "netherite_upgrade_smithing_template"));

        player.getInventory().setItemInMainHand(totem);

        player.playEffect(EntityEffect.PROTECTED_FROM_DEATH);
        player.stopSound(Sound.ITEM_TOTEM_USE);

        player.getInventory().setItemInMainHand(item);

    }
#

this is working for me

#

just need this: totem.setData(DataComponentTypes.DEATH_PROTECTION, DeathProtection.deathProtection());

mortal vortex
#

right i forgot, been a while

quaint basin
mortal vortex
#

yeah i know its ass code

#

ty mr ligma

quaint basin
#

you're welcome

#

3200 players running this

#

lmao

#

Does anyone know why player#isOnline in GameProfileRequestEvent returns false when I log in with a premium user-bedrock? I'm using geyser-standalone and velocity.

buoyant viper
#

?jd-s wtf is that event even

undone axleBOT
buoyant viper
#

oh not a spigot one, got it

echo river
#

Is there a way to get the amount of invincibility frame a player has ?

#

im using 1.8.9 btw

lilac dagger
#

Nodamageticks maybe?

inner mulch
#

im making a permission manager any ideas on how to model permissiongroups having a title or not (some groups like admin are displayed, while others only serve the permission purpose)? I dont really like the idea of nullable fields

echo river
#

oh ty I found it

#

player.getNoDamageTicks() btw

lilac dagger
#

Yes this one

echo river
#

Its so weird the noDamageTicks says 20 but u can damage a player again at 10 ticks

#

like

#

tf

lilac dagger
#

Hmm that's weird

echo river
#

Like it should be 10 ticks cuz its half a sec

#

But I dont get it

#

1.8 is pure madness

quaint basin
#

if I do event#setKeepLevel(true) on PlayerDeathEvent then the xp will be dropped?

inner mulch
quaint basin
smoky elk
#

how do i regenerate classes csrg mapping

smoky elk
young knoll
#

What

smoky elk
# young knoll What

i want to port bukkit to a snapshot and it seems like the last thing i need is a classes mapping file for that snapshot

quaint basin
worldly ingot
#

Never hold an Optional field

#

They're meant only as return types

sullen marlin
lilac dagger
#

Hear me out, optional field that is null and we use a method to assign it

#

What could go wrong

echo river
#

Hey, I want to add protocollib v 1.3.5 (1.8) to my plugin, but the repo is not available on spigot, how can I add a custom repo for the dependency in the maven config file ?

buoyant viper
umbral ridge
young knoll
echo river
#

just 1 question how do I know what the id is ?

smoky elk
#

Anyway im not gonna care its not your responsibility to make a bukkit port for every version that ever existed

#

I will just rewrite all plugins for sponge

sullen marlin
echo river
#
<repository>
          <id>dmulloy2-repo</id>
          <url>https://repo.dmulloy2.net/repository/public/</url>
      </repository>


<dependency>
            <groupId>com.comphenix.protocol</groupId>
            <artifactId>ProtocolLib</artifactId>
            <version>3.6.5</version>
            <scope>provided</scope>
        </dependency>


I'm trying to add protocol lib as a dependency but I get this error : Could not find artifact com.comphenix.protocol:ProtocolLib:pom:3.6.5 in spigotmc-repo (https://hub.spigotmc.org/nexus/content/repositories/snapshots/)

#

It's not even using the right repo no ?

#

wait

#

am I a chungus

#

I just dont understand how that works

mellow edge
ivory sleet
#

it just kinda doesn't fit well with Java, since its just a null wrapper anyway

#

u dont get method overloading, and then u still have to evaluate at runtime if an optional is empty/present

#

but I think it can be plenty fine to use Optional more than just on return types if that's your style/convention preference for whatever reason

echo river
#

Ok so I cant add protocol lib as a dependency via maven cuz its in an old version, but how can I do it manually ?

quaint basin
thorn isle
#

have you taken an allocation profile yet

wet breach
#

the issue derives from a native

#

its also possible that isn't the case as well since spark can't read the native calls properly

#

but the native in question is what java uses for sleep functions

#

but, it is also the native for input/output and networking

quaint basin
wet breach
#

which seems to make sense too

#

it can't teleport, and you are using forge?

quaint basin
wet breach
#

carbon-chat only affects chat which doesn't affect TPS or shouldn't anyways unless you are trying to do things sync but I didn't see any of that in the profile

wet breach
#

ok, it doesn't have issues

#

box-plugin is literally throwing NPE's every so often

thorn isle
#

that's the one he's writing iirc

wet breach
thorn isle
#

i'd also take an allocation profile just in case it's zgc backpressure or something, but eyeballing the spark report it doesn't feel like it

quaint basin
wet breach
#

if its already fixed then why are you showing old logs?

quaint basin
quaint basin
#

this just happened 2 times

wet breach
#

then its not fixed if its still throwing NPE's

quaint basin
wet breach
#

then why are you showing old logs that don't contain your fix?

quaint basin
thorn isle
#

it.unimi.dsi.fastutil.shorts.ShortArrays.forceCapacity()0.76%

libjvm.so.OptoRuntime::new_array_nozero_C()0.38%
    libjvm.so.ZCollectedHeap::array_allocate()0.38%
        libjvm.so.MemAllocator::allocate()0.38%
            libjvm.so.MemAllocator::mem_allocate()0.38%
                libjvm.so.MemAllocator::mem_allocate_inside_tlab_slow()0.38%
                    libjvm.so.ZCollectedHeap::allocate_new_tlab()0.38%
                        libjvm.so.ZObjectAllocator::alloc_object_in_shared_page()0.38%
                            libjvm.so.ZHeap::alloc_page()0.38%
                                libjvm.so.ZPageAllocator::alloc_page()0.38%
                                    libjvm.so.ZStatInc()0.38%
quaint basin
#

And that NPE error you're talking about isn't what caused the TPS to be at 1.

thorn isle
#

okay nevermind it does feel like zgc backpressure

#

have you taken an alloc profile yet

wet breach
quaint basin
thorn isle
#

no

#

it's the spark command i told you to run when you run into the issue

#

that profiles allocation rate

quaint basin
#

this? spark sampler start --alloc

thorn isle
#

more specifically i asked you to run a profile when the server is running normally, to get a baseline

#

and run a separate profile when the issue is occurring, to compare

thorn isle
quaint basin
#

i didn't yes

thorn isle
#

but also pass --thread *

quaint basin
thorn isle
#

yes

quaint basin
#

how many time should I run?

quaint basin
#

but how many time

thorn isle
#

enough to get an understanding of your baseline

quaint basin
#

like 5 minutes?

thorn isle
#

depends

#

take a report, look at it, try to get a grip on what's going on

#

if it isn't enough, take another

#

rinse and repeat until you have an understanding of your setup

#

that way when something like this happens and you take another report, you can tell what's going wrong and where

#

running a server, minecraft or not, without someone you can throw money at to disappear your problems is like working with an old car

quaint basin
#

maybe i'll try contact carbon support to see why the plugin logged many times

thorn isle
#

no-one can understand your specific setup and stack for you

wet breach
#

I doubt its the chat plugin

thorn isle
#

last time i saw something similar, it was with DhSupport

#

i.e. the serverside plugin for distant horizons, the level of detail type view distance extender mod

#

whoever wrote the plugin was a bumbling buffoon and was initializing some massive compression library anew for each individual block column when scanning the world for building the lod chunks

#

it was "async" but that doesn't help when you shit up the gc

wet breach
#

that is crazy

#

well they could enable gc output with a jvm argument

#

to help see what the gc is doing or if its overworked and requires more resources

thorn isle
#

fosho

#

the zgc stats on the spark profile look normal-ish, so i'm not sure if it's gc pressure

#

either an alloc profile comparison vs a baseline or a gc log would be needed to go further without it just being guesswork

#

that said i've never even looked at a zgc log so i probably won't be of much help there

#

last time i debugged this with dhsupport it was just a matter of taking another routine alloc profile and seeing massive bleeding red million-gigabytes-per-second allocs under DhSupport ArrayCache right at the top

fathom fable
#

Supp supp

slender elbow
#

net.minecraft.server.network.ServerGamePacketListenerImpl.handleMovePlayer() 927.73ms
org.apache.logging.slf4j.Log4jLogger.warn() 927.7ms

lol

rotund ravine
#

Seems fine

inner mulch
#

does adding an itemstack to an inventory lead to a copy of said item? does the item in that ui update if i change the itemmeta?

thorn isle
#

from what i remember, getting an itemstack from an inventory results in a craft mirror and modifications to the itemstack instance you get will be reflected in the inventory

#

but iirc, setting an itemstack into an inventory clones it, and changes made to the itemstack afterward won't be reflected in the inventory

#

generally i would advise doing defensive cloning and explicit inv.setItem regardless of how it behaves without those, as (as you can see) relying on the internal behavior is not easy to reason about

#

cloning itemstacks is very cheap nowadays as well

thorn isle
inner mulch
inner mulch
smoky elk
thorn isle
# inner mulch so if i change lore setitem, even though it should update?

twofold, basically; you want to get rid of the "should"s so that the code is easy to reason about without knowing the nit and grit of bukkit internals;

  • when you retrieve the item from the inventory, call clone on it, so you know for sure changes made on it won't ever be reflected in the inventory
  • after you make changes to the item, explicitly insert it back into the inventory with inv.setItem, so you know for sure the changes made will be reflected in the inventory
#

this way you aren't relying on nebulous presuppositions like "the itemstack i get from the inv should be a wrapper" or "the itemstack i set in the inventory should get cloned"

#

update some lore on the items and either the updating is failing or the display of said updates

also, make sure you call ItemStack::setItemMeta after modifying the meta and adding the lore

#

getItemMeta is always a clone and changes made to it won't be reflected on the stack until you call the setter with the modified meta

quaint basin
#

Is it possible to send a message to all players on a Bungeecord/velocity server on a backend plugin without a proxy plugin?

slender elbow
#

yes

inner mulch
#

really?

#

with redis

#

ofc

thorn isle
#

there's some bungee messaging channel for it iirc

slender elbow
#

^

thorn isle
#

the bungee proxy defines some builtin channels and request-response style "endpoints" through them, like listing online network players, sending players to backends, and sending chat messages

thorn isle
#

i forget exactly what the channels are, you can look them up in some bungee documentation for sure

#

myeah

quaint basin
#

There is nothing to send a message to all players; only to one player

slender elbow
#

Message/MessageRaw accept "ALL" as targets

thorn isle
#

what if i want to send a message to a player named ALL specifically 🤡

quaint basin
#

ohhhhhhhhh

#

perfect

quaint basin
#

but alr thanks

slender elbow
#

that's the bungee protocol for ya

quaint basin
#

this is not working

slender elbow
#

i would be surprised if it did

#

given that players can't join yet while plugins are enabling

quaint basin
#

so have online players

chrome beacon
orchid gazelle
#

lol

quaint basin
#

why is this spamming

#

The server that sent the message has 7 players, and the number of messages was 7. This is probably related

slender elbow
#

well, you are using ALL as target, and you are sending the plugin message to every player in the server (Server#sendPluginMessage will broadcast the payload)

quaint basin
slender elbow
#

so the message will get sent to every player for as many players there are

quaint basin
#

so should i use player#sendPluginMessage

slender elbow
#

myes

quaint basin
#

can i do this with server#sendPluginMessage ?

slender elbow
#

i mean, not really

#

if your goal is to send the message to every player in the network, then you need to send one payload, to one player, and that will do the MessageRaw to ALL players

quaint basin
#

ok ok

#

thx works

thorn isle
#

don't you already have redis messaging set up

#

i'd really advise against relying on the bungee messaging nonsense for anything in production if you can avoid it

slender elbow
#

i think it's a lost cause and just go and play ball with whatever he brings next

quaint basin
#

I don't like the fact that I have to have a plugin to listen the event on the proxy

#

Or else, if I don't use a proxy, I have to have a listener on all back-end servers

#

Since it's just a message to a player, I don't think plugin message is a problem

slender elbow
#

i mean, if you don't have a proxy then the pluginmessage approach will be useless

#

as the payload will be sent directly to the client, there is no mitm to intercept and process it

thorn isle
quaint basin
thorn isle
#

what does this have to do with redis

quaint basin
#

I'm thinking about using publish/addListener

thorn isle
#

currently, you are using the bungee proxy as a messaging broker; you send a message from one backend, have it delivered to all other backends, listen to it on each backend, and handle it appropriately

#

this is exactly, 1:1, what redis messaging does

#

except it doesn't need a player to be online and doesn't leak random plugin messages to the client

thorn isle
quaint basin
thorn isle
#

that's no different from what you're doing now

quaint basin
#

It's just boring to set up

#

and redis must add overhead no?

thorn isle
#

you already use redis

#

also no, not really

#

e.g. rabbitmq runs with like under 10mb memory

lilac dagger
#

oh wow

#

i actually wanna use rabbitmq

south pecan
#

hi

#

I need help with my minecraft Plugin

inner mulch
south pecan
#

I need help. Everything is basically correct, but it can't find plot.manager.Plot. Can anyone help?

slender elbow
#

Good evening, fellow plugin developer.

inner mulch
#

or is it ur own code

south pecan
#

here sorry its german

chrome beacon
#

Or is GPT code referencing something that doesn't exist?

quaint basin
inner mulch
quaint basin
#

I don't know, but either way I think it's simpler this way. It's just easier to set up the plugin

south pecan
inner mulch
#

public Plot

#

?

south pecan
#

no public class

inner mulch
#

ur package is wrong

slender elbow
#

the package at the top is wrong

south pecan
#

huh

lilac dagger
#

yeah, you're in a wrong package

south pecan
#

tf did i wrong

lilac dagger
#

you might wanna move the whole plot thing under the other package

south pecan
#

I don't get it right now.

inner mulch
#

did you copy that class around?

slender elbow
#

the package at the top of the file is wrong, it is not the same package the file is in

south pecan
#

Can I send all of this in here?

slender elbow
#

they need to match

chrome beacon
#

Yeah Intellij is also telling you what's wrong

inner mulch
#

that seems like the place it used to be

slender elbow
#

or change the package at the top to plot.manager

#

yeah

thorn isle
south pecan
#

me.Plot.plot.manager?

inner mulch
south pecan
#

Now it says that the package plot.manager is not present.

thorn isle
#

the modern intellij ui looks so terrible

#

a child's conception of a user interface

inner mulch
#

can i return to the old one

south pecan
inner mulch
#

i updated intellij and they forced me

thorn isle
#

there's a plugin that restores the old ui, but i'm not sure if it works on the 2026 builds

inner mulch
# south pecan

its not plot.manager, your package starts with me.bropro....plot...

thorn isle
#

eyeballing the metadata, it might work still

quaint basin
#

to do the setup easier

thorn isle
#

it's a fair point that using bungee messaging means less setup

inner mulch
#

at some point you need redis either way

quaint basin
south pecan
thorn isle
#

you're begging to get clown emoted

thorn isle
inner mulch
#

it seems like ur having trouble with some basic issues

#

?learnjava

undone axleBOT
#

For Beginners:

Codecademy - Learn Java: Interactive Java programming course from basics to more advanced concepts. Perfect for absolute beginners.
https://www.codecademy.com/learn/learn-java
JetBrains Academy - Java Developer Track: Learn by doing with projects and challenges. It covers Java fundamentals to advanced topics.
https://www.jetbrains.com/academy/
Udemy - Java Programming Masterclass for Software Developers: Updated courses that cover Java 8 to Java 17 features. Suitable for those who prefer structured learning.
https://www.udemy.com/course/java-the-complete-java-developer-course/

For Intermediate to Advanced Learners:

Oracle Java Tutorials: The official guides by Oracle for Java programming—great for understanding the depth of Java.
https://docs.oracle.com/javase/tutorial/
Baeldung - Learn Java and Spring: Focus on Spring Framework and modern Java technologies. Best for intermediate learners aiming to expand their knowledge.
https://www.baeldung.com/

Practice and Hands-on Learning:

Exercism - Java Track: Solve exercises and get feedback from mentors. Great for practicing coding skills.
https://exercism.io/tracks/java
LeetCode: Practice your coding skills and prepare for technical interviews with Java.
https://leetcode.com/

Free Resources and Documentation:

Java Programming and Documentation: A comprehensive collection of Java programming guides, tutorials, and API documentation.
https://docs.oracle.com/en/java/

Community and Support:

Stack Overflow: A vast community of developers. Great for getting help with specific problems or understanding concepts.
https://stackoverflow.com/questions/tagged/java
r/learnjava on Reddit: Join the community of Java learners and get advice, share resources, and discuss projects.
https://www.reddit.com/r/learnjava/

Remember: Learning to program takes practice and patience. Don't hesitate to experiment with code and participate in community discussions. Happy coding! 🎉

south pecan
inner mulch
south pecan
inner mulch
#

are you ai generating ur responses?

south pecan
#

yes im german

quaint basin
# thorn isle publish where the data comes from and listen where the data is needed

But let's say I want to send a message to the players on server A, server B, and server C that are behind proxy D.

There are two approaches to do this:

For example, I execute publish on server A, and then the proxy listens and goes through all the players on the proxy and sends the message (without listening to anything on servers A, B, and C).

Or:

I execute publish on server A, and then servers A, B, and C listen to the message and go through the players on each server and send the message

#

both will be the same thing?

inner mulch
south pecan
#

but can you help me with this

thorn isle
#

i recommend sending messages to players on backends rather than on the proxy

inner mulch
thorn isle
#

because:

  • backends have more context to e.g. parse papi placeholders
  • backends might have other plugins controlling or recording chat
south pecan
thorn isle
#

also, reloading plugins on backends is simpler than on the proxy

quaint basin
inner mulch
#

therefore its better to learn java

quaint basin
#

bc suppostly we should not use plugman xd

south pecan
thorn isle
#

using plugman is fine as long as you know your stack and know what you're reloading

#

personally, i write all my plugins to support reloads

#

to the extent where i don't even implement config reload commands; i just expect an admin to reload the whole plugin

quaint basin
thorn isle
#

yes

quaint basin
# thorn isle yes

But that really slows down the server, doesn't it? For example, when saving to the database after the plugin is turned off

thorn isle
#

a second-or-two lagspike when reloading a plugin is acceptable, especially if it's announced ahead of time; for certain more acceptable than minutes of downtime from a full restart

quaint basin
#

yes for sure

#

i agree with u

inner mulch
#

should i always locally cache global data, if i read it once, the 1ms from redis doesnt sound a like much, but its gonna build up isnt it?

#

cache global data, or use futures?

quaint basin
thorn isle
#

i mean we're talking about using it for messaging, not as a key value store

#

but yes, just 1ms for a key value access on the main thread is unacceptable

#

cache coherence is its own beast

inner mulch
quaint basin
thorn isle
#

in principle futures are the most robust solution, but they force your business code to always be threading-aware which can complicate things

inner mulch
thorn isle
#

my preferred approach was to put together a cache coherence system that maintains exclusive ownership of key-value pairs based on which server a player is online on

#

so if you have an online player, you're guaranteed to get up to date data from local memory

sly topaz
#

I would just go about it in a way that your global data isn't anything you need to be constantly querying

quaint basin
#

player.getInventory().clear(); does this include the armor contents and the cursor etc?

thorn isle
#

for offline players, i still use futures

sly topaz
#

just design things better™

inner mulch
thorn isle
#

i'd handle that on the proxy

quaint basin
thorn isle
#

easiest way to deal with distributed data is to not have distributed data

inner mulch
thorn isle
#

implement /ban and the ban checks on connect in a proxy plugin

quaint basin
thorn isle
#

backends don't need to know about it at all

inner mulch
inner mulch
quaint basin
thorn isle
#

it gets a bit hairy because according to the velocity proxy spec, a player can be online on two backends at the same time

inner mulch
sly topaz
inner mulch
#

my proxy is just bare bones

quaint basin
#

player.getInventory().clear(); does this include the armor contents and the cursor etc?

thorn isle
thorn isle
#

velocity is the #1 proof that paper should never have been given full control of the ecosystem in any project

inner mulch
#

im not sure what you mean by that

thorn isle
#

that said sometimes doing shit on the proxy is just worth the headache because it avoids several headaches elsewhere

inner mulch
#

yeah i dont like my proxy, it basically just routes my players, and kicks them from the proxy once it receives a redis message to do so

thorn isle
thorn isle
#

because yaml is too mainstream

#

no we MUST use the hippie bullshit config format that nobody knows about

inner mulch
thorn isle
#

it depends on what it is

quaint basin
#

that is needed on velocity

thorn isle
#

caching + invalidation still means there's a window where you can read stale data

#

for some purposes, this isn't acceptable

inner mulch
#

so tbh

#

it doesnt matter

thorn isle
#

suppose for example a player's balance; all operations on it must be atomic

quaint basin
thorn isle
#

if it's mostly read-only and brief windows of stale data are acceptable, caching + invalidation via e.g. redis is fine

inner mulch
thorn isle
#

the thing about being atomic is that you can't really have your cake and eat it too

#

if it truly is atomic, it can't be truly cached

inner mulch
#

yeah right

thorn isle
#

because another server could make a change to it and it won't be reflected on your end instantly

inner mulch
#

sounds like futures are the way, most of the data i read globally isnt even really important to have fast access

thorn isle
#

notwithstanding strategies like compare and exchange

quaint basin
#

My economy plugin performs real-time operations on db but uses caching for scoreboard and /money view reads, which tolerates inconsistencies

thorn isle
#

that's great until someone does /baltop on the main thread or something

quaint basin
#

purely database

inner mulch
quaint basin
thorn isle
#

my point is that this approach only works as long as you control all read call sites

quaint basin
thorn isle
#

if you have any plugin accessing it via e.g. the vault api on the main thread, you have only two choices: return potentially stale data, or block the main thread

quaint basin
#

im not using vault to my economy plugin

thorn isle
#

the first can be disastrous if it's used for something more destructive like a transaction

#

the second can be disastrous if it's done in bulk

quaint basin
#

I have no idea how to use Vault to create economy plugins with multi-server support

thorn isle
#

you can't basically

quaint basin
quaint basin
# quaint basin https://imgur.com/a/zKoY9gm

I'm querying the database for each page; perhaps this is a problem for high-end players because although the query cost is low because I use strategies like indexes + seek pagination, it's still a database query. Maybe this isn't scalable

thorn isle
#

database queries are the very definition of scalable

#

but they do have a base latency, so you don't want to do them on the main thread

#

a database query for baltop off the main thread is probably the best approach in principle

#

you could add a cache in between to avoid doing duplicate calls, but it isn't strictly necessary

quaint basin
thorn isle
#

the database will handle it much better than your minecraft server will, for sure

thorn isle
#

i'd probably just cache each baltop page for a minute or two

#

that way when players paginate back and forth you can reuse the already-fetched pages instead of doing new queries on each pagination

quaint basin
#

And since with seek it's log(n) where n = number of registered users, then it's fine

sly topaz
#

and you won't ever have 50k players so you don't have to worry about that

#

at least not in a single network lol

quaint basin
sly topaz
#

the limit for a new server is around the 10k

quaint basin
#

donut is not have like 1 year?

sly topaz
#

yeah but donut had massive reach due to the amount of youtubers playing in it

quaint basin
#

i think drdonut was already a famous streamer ye

gentle kraken
#

oh alright thanks

buoyant viper
#

?jd-s

undone axleBOT
inner mulch
#

anyone knows how i can serializers to my redisson client?

slender elbow
#

how you can what serializers

inner mulch
#

*add

#

i found that i can change the codec, altough i cant add serializers to the kryo5codec

#

i dont really want to write a full codec

#

just so i can add serializers

rotund ravine
#

Can you do something like

#
import org.redisson.codec.Kryo5Codec;

public class MyKryo5Codec extends Kryo5Codec {

    public MyKryo5Codec() {
        super();
    }

    @Override
    protected Kryo createKryo(ClassLoader classLoader, boolean useReferences)
            throws ClassNotFoundException {

        Kryo kryo = super.createKryo(classLoader, useReferences);

        kryo.register(MyClass.class, new MyClassSerializer());
        // orrrrr
kryo.addDefaultSerializer(MyClass.class, new MyClassSerializer());

        return kryo;
    }
}```
#

Excuse my formatting

inner mulch
echo basalt
#

yea that's how we do it at work

quaint basin
dry forum
#

is there an advantage to using nms vs normal bukkit for creating and moving entities in terms of performance

sly topaz
#

bukkit uses internals to implement its API, just how the server works

#

there are some instances where Bukkit/Spigot's wrapping might induce some performance penalty, but spawning of entities isn't one of them

dry forum
#

ok thanks

smoky elk
#

an upkeep that ranges from renaming the import to reading javadoc for a few minutes to figure out replacement

#

The general consensus is you minimise nms usage to take advantage of the magic of bukkit api that lets plugins from 1.8 work on 1.21

wet breach
#

there is some changes in the api though that even plugins relying only on that will still break from 1.8 to 1.21

lilac dagger
#

yep

#

sound for example

smoky elk
#

Because 1.8 to 1.21 is almost a new game

mortal vortex
#

freetolga isnt saying that using the API is failproof

#

but rather, that it is far less maintenance hungry than nms

smoky elk
#

Which tools were used to update bukkit mappings in the past

#

Whenever i tried using specialsource to compare 2 jars i ended up with a stack overflow

echo basalt
#

joe I think I just hit some kind of compiler freak error

#

.NoSuchMethodError: 'net.minecraft.world.level.storage.LevelData net.minecraft.server.MinecraftServer.getWorldData()'
LevelData is a whole different interface idk how it compiled to target that

mortal vortex
#

this is like discovering a new star homeboy

#

You get to name this error now

#

Illusion’s Illusion might work

slender elbow
#

you're doing some kind of remapping wrong or compiling & running on wrong mappings

#

ggwp

#

just don't reobf

echo basalt
#

Decomp output is not remapped

#

Only the interface call

#

I think papers remapping thing is getting in the way

#

Idk if paper-nms puts its mappings thing in the manifest

lunar tide
#

Hello someone can help me with Items in plugin multiversion?
I need to get Items from Inventory of InventoryCloseEvent, but in plugin multiversion, in my common module (spigot api version 1.8) the InventoryCloseEvent is triggered and filtered, so far, so good, but when I filter items with if (item == null || item.getType() == Material.AIR) items from 1.20 not are not detected as an item, they are detected as air, Can anyone help me with this dilemma?

I've already tried it, and it didn't work:

  • Send Inventory contents to my class of adapter and process it there
  • Send InventoryCloseEvent to my class of adapter and process it there

Thanks in advance

chrome beacon
#

Set your api version to 1.13 in the plugin.yml

#

See if that helps

topaz cape
#

rq since im a little outdated

#

26.1 spigot no longer obfuscates nms, right?

chrome beacon
#

Mojang no longer obfuscates NMS correct

topaz cape
#

true. next question, what about craftbukkit, its still being relocated right?

chrome beacon
#

Probably

topaz cape
lunar tide
topaz cape
#

will still work in 1.8

chrome beacon
#

That field didn't exist in earlier versions so they don't care

topaz cape
#

well

#

some stuff will break on newer versions and not older ones

#

like renamed material or whatever

lunar tide
topaz cape
#

or whatever?

lilac dagger
#

Yep

#

I just use bukkit.getversion and get the feature that way

#

Currently it works for 26+

#

Hopefully it won't need maintenance for the time being 😄

quaint basin
buoyant viper
#

what parts of the inventory arent clearing

#

?jd-s

undone axleBOT
thorn isle
#

if you are in creative, setCursor does nothing

quaint basin
quaint basin
#

i think im clearing everything

#

not sure

buoyant viper
#

but so... what isnt clearing?

slender elbow
#

i mean, Inventory#clear will already take care of the armour slots and stuff

#

you don't need like 80% of that code

quaint basin
quaint basin
slender elbow
#

you just need the Player setCursor() and Inventory clear()

winter scarab
#

the client is able to receive and process packets faster than 20 TPS right?

#

like it doesnt wait until the next tick?