#help-development

1 messages · Page 725 of 1

sage patio
#

i return a custom variable using a getter and modifing it like this, the main variable gets modified too?

List<Gang> gangs = new ArrayList ...

public static List<Gang> getGangs() {
  return gangs;
}

public static Gang getGang(String name) {
  for (Gang gang : getGangs()) if (gang.getName().equals(name)) return gang;
  return null;
}
Gang test = getGang("someGangWhichExistsAndItsNotNull");
test.setName("newName");
#

is the name of the gang from gangs array list gets updated?

young knoll
#

Yes

#

Also if you want to get the gang by name, use a map

sage patio
#

what is the gangs are final?

#
private static final List<Gang> gangs = new ArrayList<>();
young knoll
#

They will still change

#

That makes the list final, not the contents of it

sage patio
#

and if that Gang changes somewhere else, the test gets updated too?

young knoll
#

Most likley, yes

#

Everything is just a refrence to the actual gang object stored somewhere in memory

timid hedge
#

?

sage patio
lilac dagger
#

java basically has pointers for almost everything

#

i think primitives are the only ones that are copied every call

sage patio
#

can we talk about it for a few minutes in a voice chat? i want to share my screen and explain the problem

#

@young knoll sorry for ping, can i talk to you for a few minutes?

young knoll
#

I do not dos the voicecalls

timid hedge
#

Anyone?

sage patio
sage patio
#

do you shade the Citizens into your plugin?

timid hedge
#

No, i dont know how to. Can you show me?

sage patio
#

how much is the size of your plugins .jar file?

young knoll
#

You shouldn't shade citizens

#

It's meant to be run standalone

timid hedge
#

So is there another fix?

young knoll
#

?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.

young knoll
#

Are you trying to initialize citizens somewhere

lilac dagger
chrome beacon
timid hedge
young knoll
#

That does not answer the question

timid hedge
#

No i dont

chrome beacon
sage patio
#

uh can someone just join the voice and watch my live for a minute, i can't explain the problem in the chat

young knoll
#

I see

#

Are you doing new CitizensMainClass somewhere

#

Idk what the main class it actually called

#

Probably just Citizens

timid hedge
#

Sorry if i misunderstood your question but i do this

    @EventHandler
    public void onNPCRightClick(NPCRightClickEvent e){
        Player player = e.getClicker();
        if(e.getNPC() == null) return;
        NPC npc = e.getNPC();
        if(e.getNPC().getName().equalsIgnoreCase(VagtLevel.getInstance().getConfig().getString("testNPC"))){
            if(GaurdManager.isHired(player)){
                new AfleverNpcGui().open(player);
            }
        }
    }
young knoll
#

Alright lets go back to the start

#

Show the actual error

#

?paste the entire thing

undone axleBOT
timid hedge
chrome beacon
#

VagtLevel.java:7

young knoll
#

Show us that line of code

timid hedge
#

Thats: public final class VagtLevel extends JavaPlugin {

young knoll
#

Show us your plugin.yml

timid hedge
#
commands:
  ansæt:
    usage: /<command>
    description: Hire a person as a gaurd.
  checkansæt:
    usage: /<command>
    description: Check who is gaurd.
  vagtlevel:
    usage: /<command>
    description: Opens the vagtlevel gui.
young knoll
#

The entire thing

timid hedge
#
name: VagtLevel
version: '${project.version}'
main: my.server.vagtlevel.VagtLevel
commands:
  ansæt:
    usage: /<command>
    description: Hire a person as a gaurd.
  checkansæt:
    usage: /<command>
    description: Check who is gaurd.
  vagtlevel:
    usage: /<command>
    description: Opens the vagtlevel gui.
young knoll
#

Alright that looks fine

river oracle
#

minecraft command support non ascii characters?

timid hedge
#

Do you need pom.xml or?

chrome beacon
#

?paste

undone axleBOT
timid hedge
young knoll
#

I mean

#

That also looks okay

#

Granted idk why you have 2 static plugin variables

#

You don't even use one

timid hedge
#

Okay yeah i see that, i removed one of them now. But i use it in another class

molten hearth
#

Epic

young knoll
#

Let's see the pom I guess

timid hedge
#

Everyting or just repositories and depencies?

young knoll
#

all of it

#

Use the paste site

timid hedge
young knoll
#

Add <scope>provided</scope> to Citizens

#

You shouldn't be shading it, just like spigot

timid hedge
#

Sorry dont point me out for this but what do you mean with im shading it like spigot?

chrome beacon
timid hedge
worldly ingot
#

EntityInsentient (and derivate types) should have a setPersistenceRequired() method

#

Not really sure why you're using NMS for this though

#

That'd be because armour stands are not EntityInsentients

#

So ArmorStand#setRemoveWhenFarAway() doesn't work either

#

Because we have no direct mapping to EntityInsentient, so it's on LivingEntity instead

#

In reality it does nothing for non-insentients

timid hedge
#

It is fixed, but thanks

lilac dagger
#

as far as i know, you can't give ai to armor stands without serious work

#

which makes sense but it's sad

young knoll
#

If you want to remove them on chunk unload you can do that

lime stump
#

Anyone know how long I should expect to wait before Bungee issues are fixed?

lilac dagger
#

it doesn't even have to be each tick

#

i have a custom tracker and it works every 20 seconds

young knoll
#

Nah the event is probably the best way

lilac dagger
#

but if the chunks get unloaded then that's the best way

young knoll
#

I mean

#

You could make a custom NMS entity that doesn't get saved

#

But yknow, that's just a mess of NMS

lilac dagger
#

i heard a lot of hate on mojang, but if i'm honest they did better the way they did it

#

i don't think it would've been too fun if everything was functional

#

yeah

young knoll
#

Then request it be exposed by the API

#

:p

lilac dagger
#

and they don't provide getts and setters

#

you can do so?

#

by spigot i mean

#

the playerconnection shouldn't be private

#

or at least a getter

young knoll
#

The heck you doing with the pipeline

lilac dagger
#

i don't think i ever used the pipeline

#

what is that for?

young knoll
#

There are libraries for that

#

If you decide not to use them then yeah, ur on your own

lilac dagger
#

can't you just listen from the channel?

#

oh nvm

#

'i do use pipeline

mortal hare
#

guess who just overengineered its custom framework 😄

undone axleBOT
lilac dagger
#

but you shouldn't need the second reflection

#

i do it with just one

young knoll
#

Meanwhile protocolib is sitting over in the corner

lilac dagger
mortal hare
#

it looks nice when you declare programatically though

young knoll
#

Oh looks it's brigadier

mortal hare
#

its my api

#

i borrowed customizer concept from spring

#

😄

lilac dagger
#

yeah

#

but not the second one

#

so do i

#

look

#

but only 1 reflection call

#

it's up to you

#

it's just more hassle later on if the field name change

timid hedge
#

How do i get the onlinePlayers and use them as a arg?

lilac dagger
#

List<? extends Player> players = Bukkit.getOnlinePlayers();

timid hedge
#

I mean something like this
Player targetPlayer = (Player) Bukkit.getOnlinePlayers(args[0]); so the online players is a arg

remote swallow
#

no

#

that would be Bukkit.getPlayer(args[0])

lilac dagger
#

getOnlinePlayer()

young knoll
#

Bukkit.getPlayer(string)

lilac dagger
#

there you go^

#

mine work well as well

young knoll
#

They are probably on 1.old

lilac dagger
#

yeah

#

before mojmaps

undone axleBOT
timid hedge
# young knoll Bukkit.getPlayer(string)

Thanks but i dont know what to set targetPLayer to now

Bukkit.getPlayer(args[0]);
                    String targetPlayer = String.valueOf(Bukkit.getPlayer(args[0]).getPlayer());
                    if (targetPlayer == null || !targetPlayer.isOnline()) {
                        sender.sendMessage("The player isnt online");
remote swallow
#

why are you making it a string

lilac dagger
#

i do think that md still calls it networkmanager and playerconnection

#

unless i'm wrong

remote swallow
#

its not called anything anymore

#

its just obsfucated names

lilac dagger
#

oh it is?

remote swallow
#

the class has a name, the var doesnt

timid hedge
#

No becuase i dont got a option caleed args[0].isONline()

lilac dagger
#

oh right

#

i forgot

#

i dealt with the obfuscated names

remote swallow
young knoll
#

(And then null check it)

remote swallow
#

im not talking about access, im talking about name

young knoll
#

I just do it by index

lilac dagger
#

i'll probably end up looping though all the fields and check by name

#

at least i know the class name stays consistent

#

well then, guess i'm a 🤡

chrome beacon
#

Download and read mappings in your plugin

young knoll
#

You could do that

#

So far index has been fine for me

#

Spigot should put the mappings file in the jar

#

kek

lilac dagger
#

i'm sure md is smarter than that

chrome beacon
#

but the jar is built locally with BuildTools

#

would be interessting to see how Paper would handle that though

young knoll
#

Paperclip could just do it

lilac dagger
#

do they build their jar on mojmaps?

#

cause that would be a com problem for my plugins

remote swallow
#

they have a mojmap jar download on their website

young knoll
#

Yeah they offer both

lilac dagger
#

i hope they reshade plugins

#

tho my reflection call i doubt will get reshaded

remote swallow
#

reshaded?

#

remapped?

lilac dagger
#

you know, my nms that was built on md mappings

remote swallow
#

spigot mappings

lilac dagger
#

will need to be changed to support mojmaps

remote swallow
#

well yeah

#

its why the mojmap server isnt designed for prod servers

lilac dagger
#

well, it does make sense

young knoll
#

I mean spigot could just download the mappings at startup

#

Like libraries but mappings

lilac dagger
#

yeah but again would cause problems for some usages

#

where plugin remapping or reshading couldn't happen

young knoll
#

what

ocean hollow
#

how can I disable player nicknames in order to create the ability to display the nickname via TextDisplay

young knoll
#

Scoreboard teams

lilac dagger
# young knoll what

if you use reflection in a plugin, i doubt a reshade tool can tell what it is and fail to mojmap it

#

or nevermind, this could work if the mojmapping would be the only way

alpine swan
#

can someone explain me why SPESIFICALLY THE FIRST TIME YOU CLICK ON A BLOCK THROUGH AN ENTITY IT DOESNT CALL THE INTERACTEVENT FOR RIGHTCLICKBLOCK

https://medal.tv/games/minecraft/clips/1va3WRVRq2KzTn/d1337YrkdH1j?invite=cr-MSwxQ20sMTg1OTU0MDg3LA
(listen with sound for clicksounds and me complaining)

Watch Untitled and millions of other Minecraft videos on Medal, the largest Game Clip Platform.

▶ Play video
sweet flax
young knoll
#

what entity

young knoll
#

Just no tool for it yet

sweet flax
#

and EntityIronGolem

young knoll
sweet flax
#

there is no setX

#

never mind

twin venture
#

hi , anyone know how i can fix this?
there is a glitch with when a click on an item in the opned inventory , and just move it around without placeing it in another slot , after that i close the inventory , the item is completly vanished

#

if i for example pick the helmet , and close the inventory the item is removed .

quaint mantle
#

what causing this error?

twin venture
#

fix the glitch and prevent the item from being deleted , and add it again

#

to player inv

young knoll
quaint mantle
#

alright

#

thanks man

twin venture
#

where????????

wary remnant
#

🥄

twin venture
#

you didn't understand the problem ..

#

KitEditor , so player can edit the slot of the item

#

of the kit

#

and next time he get it , it will be in the slots he selected

#

yes

#

getting the items in the opned inventory , and just set the contents

sweet flax
#

u have dev on buildbybit

#

in desc

twin venture
#

and?

sweet flax
twin venture
#

few yes

hushed scaffold
#

hiya, when i have a basic command made, how do i change the default permissions of it?
so like lets say i want a command thatd be allowed to be used by all players, but lets say an admin decided to make it not allowed for all with luckperms for example , they could change it.
my problem is, that when i add player.haspermission, then the permission will be false by default unless the player has op. how do i make the permission true?

eternal oxide
#

add aliases in your plugin.yml

hushed scaffold
young knoll
#

Add the perm in your plugin.yml

#

and then add default:true

eternal oxide
#

you can assign more than one permission to a command

hushed scaffold
young knoll
eternal oxide
#

perm aliases I ment, not command aliases

crisp acorn
#

does anyone know how to allow the player to crawl without sending an invisible fake block to the client right in top of him?

young knoll
#

You can't

crystal sparrow
#

Hi, im trying to update my plugin from 1.19.2 to 1.20.1.
I ran buildtools and selected the new jar file: "Spigot\Spigot-API\target\spigot-api-1.20.1-R0.1-SNAPSHOT-shaded.jar"
But its not working (error at every org.bukkit import) , if i switch back to "Spigot\Spigot-API\target\spigot-api-1.19.2-R0.1-SNAPSHOT-shaded.jar" everything is working fine.
Can anyone tell me what im missing?

hushed scaffold
undone axleBOT
#

Bootstrap Jar
The main spigot-1.18.jar is now a bootstrap jar which contains all libraries. You cannot directly depend on this jar. You should depend on Spigot/Spigot-API/target/spigot-api-1.18-R0.1-SNAPSHOT-shaded.jar, or the entire contents of the bundler directory from your server, or use a dependency manager such as Maven or Gradle to handle this automatically.

Please read the release notes for further information: https://www.spigotmc.org/threads/9-years-of-spigotmc-spigot-bungeecord-1-18-1-18-1-release.534760/#post-4305163

young knoll
hushed scaffold
young knoll
#

true is accessible by everyone

#

op is ops only

hushed scaffold
#

thank you

crystal sparrow
river oracle
young knoll
#

Because that requires maven

#

or gradle

crystal sparrow
#

Yes, it was always easier for me to just use buildtools and change the project settings to the new jar

river oracle
#

I didn't for like my first ever java project, but then I swiched over

mortal hare
#

is there any way to convert list to array without copying?

wise mesa
#

Is 1.20.2 cool or cringe

#

The configuration stuff seems intriguing

mortal hare
#

that still involves copying from stream to array, no?

sweet flax
#

?mappings

undone axleBOT
wise mesa
#

You have to copy somehow

#

Without reflection you cannot get the mists internal array

slender elbow
#

not all lists are backed by an array either, fwiw; and even if they are, they array length might be larger than the list size etc

mortal hare
#

eh i've just decided to return collection in internal classes instead

lime moat
#

What could possibly cause this issue? java java.lang.ArithmeticException: Failed to check for ID 964595015638724670 in DB: Communications link failure The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server. at nekobox.es.nekoboxcore.SQL.SQL.IdExistsInDB(SQL.java:136) ~[NekoBox-Core-1.0.jar:?] at nekobox.es.nekoboxcore.Authentication.Listeners.AuthenticationDiscordListener.onMessageReceived(AuthenticationDiscordListener.java:45) ~[NekoBox-Core-1.0.jar:?] at net.dv8tion.jda.api.hooks.ListenerAdapter.onEvent(ListenerAdapter.java:442) ~[NekoBox-Core-1.0.jar:?] at net.dv8tion.jda.api.hooks.InterfacedEventManager.handle(InterfacedEventManager.java:96) ~[NekoBox-Core-1.0.jar:?] at net.dv8tion.jda.internal.hooks.EventManagerProxy.handleInternally(EventManagerProxy.java:88) ~[NekoBox-Core-1.0.jar:?] at net.dv8tion.jda.internal.hooks.EventManagerProxy.handle(EventManagerProxy.java:70) ~[NekoBox-Core-1.0.jar:?] at net.dv8tion.jda.internal.JDAImpl.handleEvent(JDAImpl.java:176) ~[NekoBox-Core-1.0.jar:?] at net.dv8tion.jda.internal.handle.MessageCreateHandler.handleInternally(MessageCreateHandler.java:136) ~[NekoBox-Core-1.0.jar:?] at net.dv8tion.jda.internal.handle.SocketHandler.handle(SocketHandler.java:39) ~[NekoBox-Core-1.0.jar:?] at net.dv8tion.jda.internal.requests.WebSocketClient.onDispatch(WebSocketClient.java:1014) ~[NekoBox-Core-1.0.jar:?] at net.dv8tion.jda.internal.requests.WebSocketClient.onEvent(WebSocketClient.java:900) ~[NekoBox-Core-1.0.jar:?] at net.dv8tion.jda.internal.requests.WebSocketClient.handleEvent(WebSocketClient.java:878) ~[NekoBox-Core-1.0.jar:?] at net.dv8tion.jda.internal.requests.WebSocketClient.onBinaryMessage(WebSocketClient.java:1053) ~[NekoBox-Core-1.0.jar:?] at com.neovisionaries.ws.client.ListenerManager.callOnBinaryMessage(ListenerManager.java:385) ~[NekoBox-Core-1.0.jar:?] at com.neovisionaries.ws.client.ReadingThread.callOnBinaryMessage(ReadingThread.java:276) ~[NekoBox-Core-1.0.jar:?] at com.neovisionaries.ws.client.ReadingThread.handleBinaryFrame(ReadingThread.java:996) ~[NekoBox-Core-1.0.jar:?] at com.neovisionaries.ws.client.ReadingThread.handleFrame(ReadingThread.java:755) ~[NekoBox-Core-1.0.jar:?] at com.neovisionaries.ws.client.ReadingThread.main(ReadingThread.java:108) ~[NekoBox-Core-1.0.jar:?] at com.neovisionaries.ws.client.ReadingThread.runMain(ReadingThread.java:64) ~[NekoBox-Core-1.0.jar:?] at com.neovisionaries.ws.client.WebSocketThread.run(WebSocketThread.java:45) ~[NekoBox-Core-1.0.jar:?]

    public boolean IdExistsInDB(String DiscordId) {
        try {
            boolean var6;
            try (Connection con = this.connectionPool.getConnection()) {
                PreparedStatement pstmt = con.prepareStatement("SELECT DisplayName FROM staff WHERE DiscordId=?");
                pstmt.setString(1, DiscordId);
                ResultSet rs = pstmt.executeQuery();
                boolean result = rs.next();
                pstmt.close();
                rs.close();
                con.close();
                var6 = result;
            }

            return var6;
        } catch (SQLException var9) {
            throw new ArithmeticException("\u001B[31mFailed to check for ID " + DiscordId + " in DB: " + var9.getMessage() + "\u001B[0m");
        }
    }```
#

it gives me the error the first time, but when I try to do it again, it works???

#

If needed, I can provide all the code to see if that might help.

austere cove
#

why are you throwing an ArithmeticException wth

lime moat
#

aha, don't mind that 👀

#

I have to convert everything to my logger hahaha

#

I really don't understand why this is happening, it's so weird

zealous osprey
#

btw, shouldn't the method return some kind of Future?

zealous osprey
#

Are you running your DB query on the main thread?

lime moat
#

I believe so

zealous osprey
#

Queries to a DB should (almost?) always be run on a seperate thread, otherwise the server has too wait for a response before continueing to the next game tick.
And for such Multi-threaded applications you can use something called a CompleteableFuture. This is an object which will run some code, after some async task has been completed.

lime moat
zealous osprey
#

Someone, I think mflnx has a very nice example here somewhere

#

ehhh

#

remove that

#

I can see your DB password and everything...

lime moat
#

the db isn't valid

zealous osprey
#

ok, just for the future anyways. Make sure not too keep "secrets" in public repos

lime moat
#

yeah, I know that xD

#

Everything is in my server's config that is secret

#

I'm genuinely bamboozled with these errors though, I could've sworn it worked fine at one point

zealous osprey
#

So:

  • I'd recommend to try and untangle your onEnable method. You have alot in there; Mainly creating seperate classes for your command logic.
  • Then, as I suspected, you are running your DB in the same thread as your normal code. Use the Scheduler from the spigot API to run the DB queries in a seperate thread. As I mentioned, you should then use CompleteableFuture too handle data coming from your DB and what should be done with it.
lime moat
zealous osprey
#

And your generateCode function could be better

zealous osprey
lime moat
#

Do you reckon the scheduler thing will fix my issues?

zealous osprey
# lime moat May I have an example of using the scheduler to run a query?
public CompletableFuture<Boolean> isPlayerRegistered(final OfflinePlayer player) {
    final CompletableFuture<Boolean> complete = new CompletableFuture<>();

     plugin.getServer().getScheduler().runTaskAsynchronously(plugin, () -> {
            boolean exists = false;
            try (Connection con = this.connectionPool.getConnection()) {
                PreparedStatement pstmt = con.prepareStatement("SELECT DiscordId FROM staff WHERE DisplayName=?");
                pstmt.setString(1, player.getName());
                ResultSet rs = pstmt.executeQuery();
                exists  = rs.next();
                pstmt.close();
                rs.close();
                con.close();
            }
        } catch (SQLException var9) {
            // handle error
        }

        complete.complete(exists);
     });

  return complete;
}

Something like this ig

You could also create a ConcurrentLinkedList and cache incoming query requests and then have just a single thread for querying, instead of creating a new one every time you query something.

lime moat
#

Cannot resolve symbol 'exists'

young knoll
#

Why do you have 2 trys in that example

worldly ingot
#

Just in case!

remote swallow
#

try try

remote swallow
#

did md respond about downgrading sqlite

worldly ingot
#

Probably won't happen

remote swallow
#

sad

zealous osprey
#

whoops

#

copy pasta shenanigans

young knoll
#

As of 45 minutes ago

remote swallow
#

by who

young knoll
remote swallow
#

i see

zealous osprey
#

Btw, what do you think is the preferable approach too querying?
Caching queries and then getting them from a queue; So you only have one seperate thread for interacting with the DB
OR
Just using the scheduler too create a new task every time you query from the DB?

young knoll
#

Scheduler is fine

#

It uses a thread pool

remote swallow
#

i dont

#

im single threaded

lilac dagger
#

you can cache queries?

lime moat
#

I'll try out the code here shortly

lilac dagger
#

i'm single threaded too, i don't know how you'd handle update that might've come before insert

zealous osprey
#

So you let the query block the main thread while the DB responds?
Or is there a way too not do that in a single threaded app?

slender elbow
#

single thread doesn't necessarily mean the server thread

#

you just run the queries in a single thread, just, separate, but it's its own

worldly ingot
#

Get out of here with your logic

zealous osprey
#

yeah, that's what I meant aswell with the caching approach

remote swallow
#

my brain has 3 threads, 1 for eyes, one for mouth, 1 for everything else

zealous osprey
#

I have 2.
One is occupied for all daily activities and the other is wondering why some countries cut a pretzel in half, but not hoorizontal, rather vertical.

remote swallow
#

how do you breath and see

#

1st thread?

zealous osprey
#

yes

#

I switch between them

sterile token
#

something weird but sure if is not posible, juts wanna confirm. Is possible to detect when doing scroll, specially when doing up and down scroll with the mouse??

worldly ingot
#

No

#

Well, depends where I guess

#

Actually no I don't think anywhere exposes whether or not it was a scroll. I thought PlayerItemHeldEvent did

young knoll
#

I mean

#

You can assume it is if it's one more or less than the previous slot

#

But it's not guarenteed

tribal quarry
#

Hey there, i want to know are there any ways to place a lot of blocks using 1.8 without getting lighting issues? sometimes it makes some very dark places which will be fixed by placing a block, but it takes a lot of time in order to manually place/break blocks around in order to get it fixed. i tried getting far away from it, but the lighting issue remains.
(Again, its 1.8 and yea, Its up to you for the answer, thanks!)
here is my code: https://paste.md-5.net/arutekanek.cs
image: https://imgur.com/HIGUYXR

zealous osprey
#

do one layer after another and wait a tick before pasting the next layer?
Or maybe WorldEdit has a solution for this

young knoll
#

Yeah just distribute it

#

Idk if going top down or bottom up would be better

tribal quarry
#

well lemme try

zealous osprey
short pilot
#

heyo, what's a good way to store faction data on a sqlite?

dry forum
#

how would i use rgb in a chat message

young knoll
#

ChatColor.of("#123456")

dry forum
#

so its #rgb?

zealous osprey
dry forum
#

alr ty

zealous osprey
short pilot
#

ooh good question! Let me write it down real quick

#

The plugin I'm aiming to develop is a factions-esque type, just out of self interest. I have my objects made and commands work in the test server, but naturally nothing saves to file yet. The questions I have follow:

How can I implement saving to file, and what is the best practice to?

Should data be saved at regular intervals for a "faction" and then loaded in on plugin start?

For more large amounts of data such as chunks claimed for a "faction", should this be saved somewhere else other than the main faction file?

Finally, for each player, should I only save their data on logout or at certain intervals?

I really appreciate the help, thanks!

young knoll
#

A lot of data you can just save right away

#

Unless it's something that changes super often

dry forum
#
        component.setColor(ChatColor.of("#" + hex));
        return component.toString();``` is there not a way to get a textcomponent as a string?
lilac dagger
#

there has to be a way

#

otherwise make a util

#

shouldn't be too hard

#

there are like 3 components as of now

young knoll
#

?jd-bcc

young knoll
#

getText()

zealous osprey
#

You will almost always have to load some data into your plugin when starting it.
You could save some data in regular interavals, will surely be benefitial if the server ever crashes unexpectedly.
Saving and writing data is fine, aslong as you don't save and load multiple times a second. Then I would recommend caching the data temporarily and creating regular backups/updates.
I would save player data, factions data (including their settings) and claimed chunks in seperate files/tables and identify them via a certain ID.

Any objections from someone?

dry forum
lilac dagger
#

yeah as i said then

#

parse it yourself

#

it shouldn't be impossible

young knoll
#

BaseComponent.toLegacyText

lilac dagger
#

there you go, this has to be it

young knoll
#

Static method, takes vararg of components

lilac dagger
#

now it makes me wonder why adventure even exists when md did an amazing job

upper hazel
#

what wg api version for 1..12.2 i shold use?

upper hazel
onyx fjord
#

ill let you know in dms

#

really critical

#

@lime moat !!!

#

should i spam ping him

echo basalt
#

just shame them in public

#

but yeah they leaked their shit

onyx fjord
smoky oak
#

'quick' question, how do i initialize a filter predicate for a single player

echo basalt
#

~it has already been mentioned

smoky oak
#

rayTraceEntity hits the sending player

echo basalt
#

(input) -> !input.getUniqueId().equals(player.getUniqueId())

#

type deal

lime moat
smoky oak
#

ah u edited

smoky oak
# echo basalt (input) -> !input.getUniqueId().equals(player.getUniqueId())
RayTraceResult result = player.getWorld().rayTraceEntities(
                player.getEyeLocation(),
                player.getEyeLocation().getDirection(),
                reach * 0.5,
                (input) -> !input.getUniqueId().equals(player.getUniqueId()));
        if(result == null || result.getHitEntity() == null) {
            Bukkit.broadcastMessage("Result is null");
            event.setCancelled(true);
            return;}

guess what message i get

#

im querying for 50 blocks

#

i think doing () around the condition after the ! helped

#

it works now

echo basalt
#

go fucking figure

smoky oak
#

maybe it was like 'if this exists'

#

iunno

#

uuuh did i mess up my reflection?
java.lang.NoSuchMethodException: net.minecraft.server.level.EntityPlayer.attack(net.minecraft.world.entity.Entity)

#

the craftbukkit project says the method exists

lilac dagger
#

the nms in remapped to md

#

wait nvm

smoky oak
#

it happens with and without using remapped

lilac dagger
#

entityplayer

smoky oak
#

wym

lilac dagger
#

it's the md mapping

#

mojmap has it as Player and ServerPlayer

smoky oak
#

...sooo?

#

i do not recall that the mappings matter after building

#

is this because im using reflection?

#

?mappings

undone axleBOT
smoky oak
#

and how do i call a spigot method using reflection then?

#

also it's saying its not finding the method, not that its not finding the class

rough harness
#

any one know A claim plug in that works multiverse that can be per world

smoky oak
#

side note, I'm using the getHandle method, iirc that spits back out the md5 mappings

rough harness
#

ok

smoky oak
#

Bukkit.broadcastMessage("Player class: "+ nmsPlayer.getClass().getName()); -> net.minecraft.server.level.EntityPlayer
yea this is the md / spigot mapping

#

?paste

undone axleBOT
smoky oak
#

can i somehow get the spigot EntityPlayer class without the monajg obfuscated methods?

young knoll
#

wut

echo basalt
#

you're running a remapped server

#

somehow

smoky oak
#

say what now

#

is this a result of using --remapped with buildtools to get the remapped jars in .m2?

remote swallow
#

are you also running that jar as the server jar

smoky oak
#

yes? i wasnt aware it was an issue

#

why should i build twice

#

im just running buildtools --rev latest right now

#

if that fixes it thanks illusion, i would have NEVER figured that out

#

annoying that buildtools is so slow tho

young knoll
#

The jar you get from buildtools is always the obfuscated one

smoky oak
#

youre saying thats not the issue?

smoky oak
# smoky oak im just running buildtools --rev latest right now
Success! Everything completed successfully. Copying final .jar files now.
Copying spigot-1.20.1-R0.1-SNAPSHOT-bootstrap.jar to D:\Creation\Minecraft\.\spigot-1.20.1.jar
  - Saved as .\spigot-1.20.1.jar

Okay why is latest still 1.20.1 instead of 1.20.2?

young knoll
#

Because latest is latest stable

smoky oak
#

ah i see

#

anyways ive rebulit with no args except --latest, so lets see if that helped. you said it wont, illusion said i fucked up my pc

remote swallow
#

yep pc dead

#

throw it away

smoky oak
#

I'd like to use the md mappings because they're so stable and cannot understand why it would return those methods

#

getMethods and getDeclaredMethods return completely different sets of methods but neither is the set of methods i want urgh

young knoll
#

wut

smoky oak
#

tldr NMS stupid
i probably could just use the obfuscated method but that feels like giving up
also i checked, getCanonicalName returns the md mapping EntityPlayer

#

im out of ideas

young knoll
#

What are you trying to do

smoky oak
#

get a class instance (EntityPlayer) from spigot mappings and call a spigot mappings method in it

#

methods are obfuscated for some reason

#

like it spits out a EntityPlayer instance, but the fields in it are this

young knoll
#

Yes?

#

What did you expect

smoky oak
#

that if i get a spigot mappings object it has spigot mappings methods

young knoll
#

Spigot mappings are mostly gone now

smoky oak
#

can i get an answer thats not a 'you're doing it wrong' for once? please?

young knoll
#

Spigot mappings only exist for classes afaik

#

Methods and fields are all obfuscated

chrome beacon
#

^^

smoky oak
#

hm in that case

#

this is what displays on the mappings page

remote swallow
#

for method and variables its obsfucated

#

the only spigot mapping is class name

young knoll
#

I already said that nerd

smoky oak
#

how do i get a mojmap instance then?

remote swallow
#

?nms

smoky oak
#

i know that part

#

i meant how do i convert a Bukkit Player into a mojmap player

remote swallow
#

cast to craft player call getHandle

chrome beacon
#

getHandle?

young knoll
#

^

smoky oak
#

um

proven jay
#

Hi @echo basalt, I'm testing your scoreboard system out at the moment, is there a way to make it not flicker lol?

smoky oak
#
craftPlayerClass = Class.forName("org.bukkit.craftbukkit." + VERSION + ".entity.CraftPlayer");
Method playerHandle = craftPlayerClass.getDeclaredMethod("getHandle");
Object nmsPlayer = playerHandle.invoke(craftPlayerClass.cast(player));

Question
if getHandle is supposed to return the mojmap why do i get the spigot mappings class

echo basalt
#

p sure it's made to not flicker

#

show code and result

chrome beacon
remote swallow
young knoll
#

Yes reflection does not get remapped

remote swallow
#

because you have to compile to obsfucated, and special source doesnt remap reflection

young knoll
#

Wonder how hard it is to handle that

remote swallow
#

i think paper might be adding it

#

jmp has a remapper for refl

smoky oak
#

that makes it so much easier bleh

#

thanks yall ill try this and come back when it doesnt work

#

JavaLangClassNotFoundException

#

uuuuuuurgh

young knoll
#

I should make an API that wraps around mappings

remote swallow
#

i can do that

#

that is something i can actually do

young knoll
#

Bet

smoky oak
#

ah wrong import

#
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftEntity;
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;

can i somehow make those work for all versions without making a switcher? Thats probs why the example i found used reflection

young knoll
#

Modules

remote swallow
#

modules or reflection substringing Bukkit.getServer().getClass()

echo basalt
#

player.getClass()

#

I guess it breaks just a little

#

like

#

precaching

young knoll
#

Oh yeah you can just do that

#

:p

smoky oak
#

the real issue is that i attacked, it dealt a ton of damage, and i got a 'null' error filling like 800 lines lol

echo basalt
#

well shit I didn't work at all today

young knoll
#

Fired

young knoll
echo basalt
#

well I worked 40 minutes

young knoll
#

Don't make me ?nocode you

echo basalt
#

lemme code a lil bit

#

been procrastinating too much

remote swallow
#

more like ?noexception

#

or ?stacktrace

smoky oak
young knoll
#

player.getClass will be CraftPlayer

#

Then you can use that to cast

#

or just use that to get the getHandle method

echo basalt
#

but

#

if you're using reflections anyway

smoky oak
#

the idea is it wont break when a single subvesion changes

#

maybe it gets rid of that circular error too

young knoll
#
Player player = event.getPlayer();
Method getHandleMethod = player.getClass().getDeclaredMethod("getHandle");
Object nmsPlayer = getHandleMethod.invoke(player);
#

Something like that

remote swallow
#

no coll

#

bad coll

smoky oak
#

player.getclass.cast

remote swallow
#

private static final

young knoll
#

Where are you going to get a private static final player instance

remote swallow
#

new player

smoky oak
#

can i just do (Class<?>) in front of that?

#

like, will it throw an error?

young knoll
remote swallow
#

ok fine

#

asign it on first use

#

and reuse

young knoll
#

Yeah pretty much

young knoll
smoky oak
#

Entity.getClass

young knoll
#

No no

#

What is the type of the variable

smoky oak
#

probably LivingEntity

young knoll
#

...

#

You are the one declaring it, you should know what the type is

smoky oak
#

Entity hit = result.getHitEntity();
Object craftEntityClass = hit.getClass();

#

no i dont

#

rayTraceResult spits out Entity

young knoll
#

Object

#

Thank you

echo basalt
#

idiot

young knoll
#

use Class<?> instead

smoky oak
#

ah thats what you meant

#

ah fuck, i still get the spigot mappings if i use reflection

#

well getHandle

echo basalt
#

I hate this NotNull

#

it doesn't match the nullability type of the location constructor

compact haven
#

well isn't that in the Location class?

echo basalt
#

Vector.toLocation

compact haven
#

ah

#

yeah that is weird

#

should PR to remove that contract

young knoll
#

Just ignore it

#

kek

echo basalt
#

kek

compact haven
#

wdym by yell

echo basalt
#

ide warnings

compact haven
#

you mean an IDE warning, or does it throw some runtime message

#

ah okay

#

there's got to be some ignore annotation for that

young knoll
#

Just pr it smh

echo basalt
#

not signing cla

#

fuck off

young knoll
#

Okay well ask someone else to do it

compact haven
#

@tender shard alex

#

how is u

smoky oak
#

er
i get a error and the event isnt processed so it's reprocessed
but the target of the method still takes damage? wtf?

young knoll
#

Is this in a damage event

smoky oak
#

ye

young knoll
#

using .attack in a damage event

#

Will call another damage event

#

Also smh we have api for .damage

#

Stop using old versions :c

smoky oak
#

I'm using the internals so that the attack's simulated properly

young knoll
#

?

#

It's simulated properly with the api

smoky oak
#

as if the player would have attacked the targetted entity?

young knoll
#

yes?

smoky oak
#

wh

#

how didnt i find that

#

bruh

young knoll
#

It’s on LivingEntity

smoky oak
#

i am multiple levels of mad lol

smoky oak
#

dafuq

#

PlayerDeathEvent has getEntity() instead of getPlayer()

young knoll
#

Yes

#

It extends from EntityDeathEvent

smoky oak
#

ah i see

#

is there a simple way to see which player if any has killed another player?

#

i dont thikn there's a kill event

#

is it just getLastDamageSoruce or smth?

young knoll
#

Player should have a getKiller

smoky oak
#

oh ur right thanks

#

yo wtf
How can a hashmap throw a null if I query a value thats clearly existent
Caused by: java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because the return value of "java.util.HashMap.get(Object)" is null

#

I'm setting and querying using my player uuid

kind hatch
#

Values can be null, keys cannot.

smoky oak
#

it points to an 8

#

its supposed to return an 8

kind hatch
#

Then it might be that the input you have is somehow incorrect.
#get() expects a key and will use what you provide to look up that value.
If the key doesn't match or doesn't exist in the map, then it will return null.

smoky oak
#

additionally, the value i am querying with is the key thats pointing to that 8

#

ah

#

i swapped two methods apparantly

quaint mantle
#

how do u make it so dropped itemsdon't blow up

smoky oak
#

theres an event when they get blown up

#

cancel that

quaint mantle
#

what is that event

smoky oak
#

probaly something along ItemExplodeEvent or EntityExplodeEvent

kind hatch
young knoll
#

Should be able to cancel it for items if explosion

winter flower
#

Does anyone have an Idea on how to Copy a world?
I'm trying to duplicate a world with the String of islands/default and copy it to islands/playerUUID

My attempts have consisted of:
Copying the entire folder -> Failed to load the world even tho I ran Bukkit.getServer().createWorld().
Using the WorldCreator.copy(World) -> Copies the generator settings and not the builds inside.

young knoll
#

Should just have to copy the folder and then load it

#

Might also have to remove the uuid from it so a new one is generated

winter flower
young knoll
#

Define “didn’t work”

winter flower
#

If you mind giving me an example so I can check if I did it properly?

winter flower
#

It doesn't see a world with that name

young knoll
#

Interesting

#

Let’s see some code

winter flower
#
public static World CopyWorld(String query, String target) {
        File srcDir = new File(Bukkit.getServer().getWorldContainer(), query);
        if (!srcDir.exists()) {
            Bukkit.getLogger().warning("World doesn't exist");
            return null;
        }
        
        File destDir = new File(Bukkit.getServer().getWorldContainer(), target);
        if (destDir.exists()) {
            Bukkit.getLogger().warning("World already exists");
            return null;
        }

        try {
            FileUtils.copyDirectory(srcDir, destDir);
            for (File file : destDir.listFiles())
                if (file.isFile())
                    if (file.getName().equalsIgnoreCase("uid.dat"))
                        file.delete();
        } catch (Exception error) {
            Bukkit.getLogger().warning("Failed to copy worlds");
            return null;
        }

        return Bukkit.getServer().createWorld(new WorldCreator(target));
    }
sterile token
winter flower
#

query: islands/default, target: islands/playerUUID

#

using the org.apache.commons.io.FileUtils package

young knoll
#

Hmm

#

That looks alright

winter flower
#

It doesn't work tho lmao

young knoll
#

Does the folder get copied properly

winter flower
#

Yes

#

does it load it tho? No

#

which is what I'm trying to figure out

#

since I can't access the World using Bukkit.getWorld(String) unless it's loaded

young knoll
#

If you restart the server and then use the WorldCreator again to load it

#

Does it load

winter flower
#

Let me check

winter flower
#

So how do I make it load without the restart everytime

young knoll
#

Try delaying the load a while perhaps

winter flower
#

How so?

young knoll
#

Scheduler

winter flower
#

Alright

smoky oak
#

how do i ban a player using profile? It's not with BanList#addBan(Profile,message,date,reason)

young knoll
#

Uhh

winter flower
# young knoll Try delaying the load a while perhaps

Didn't work but in the process I found another fix:

// OLD
return Bukkit.getServer().createWorld(new WorldCreator(target));

// NEW
WorldCreator defaultIsland = new WorldCreator(target);
defaultIsland.environment(World.Environment.NORMAL);

return defaultIsland.createWorld();

In the Copy function ^

slate mortar
#

not really a spigot-related question, but... if mojang were to remove a method (non-replacable by myself without huge hassle) i'm using in a lib, what is the "best" way of removing it? straight up removing everything, commenting & deprecating?

smoky oak
#

nope

young knoll
#

It’s not static

smoky oak
young knoll
#

Bukkit.getBanList().addEntry

slate mortar
#
    /**
     * @deprecated "renderShadows" functionality was removed in 1.20.2
     */
    @Deprecated
    public OptionListWidget withShadows() {
        //this.setRenderHorizontalShadows(true); 
        return this;
    }

in my case, everything related to these shadows is now hardcoded instead

young knoll
#

Try casting the null to Instant

smoky oak
#

cannot resolve method (Profile, String, Instant, String)

#

that aint it either chief

young knoll
#

Generics are wack

smoky oak
#

id rather not use the deprecated ban method but im once again running out of ideas

young knoll
#

Try BanList<PlayerProfile> banList = Bukkit.getBanList…

#

And then use addBan with that object

smoky oak
#

bruh that did it

#

wtf

young knoll
#

Generics can be wack sometimes

smoky oak
#

im done for today lol

#

i need sleep

slender elbow
#

<T> BanList<T> getBanList(Type<T>) when 🙁

young knoll
#

Yeah it would have to take a Class as a param

echo basalt
#

make a weird generic enum

#
public class BanType<T> {

  public static final BanType<PlayerProfile> PROFILE = new BanType<>();
  ...

  private BanType() {

  }
}
#

bit of a weird pattern

compact haven
#

why in the world would BanList be generic

echo basalt
#

maybe have a Class<T> getBanType

young knoll
#

Could do that

compact haven
#

what types is BanList holding that it needs to be generified

#

wot in the world

young knoll
#

PlayerProfile and IP

compact haven
#

ah

#

ah ah ah

echo basalt
#

still a bad pattern

young knoll
#

Specifically

#

PlayerProfile, InetAdress

#

(And string but that’s deprecated)

young knoll
#

No

#

The game doesn’t support that

#

However pdc should be all you need

#

Combined with custom model data

lost matrix
#

Best you can do is add name, lore, pdc and a different model using custom model data via a resourcepack

young knoll
#

Not sure what more you would need than that tho

#

You could via the command event

#

But it wouldn’t show up in tab complete

echo basalt
#

Bro thinks spigot isn't about hacking together a solution by mixing the most janky features together

young knoll
#

Yeah sadly it’s all NMS

echo basalt
#

Even webdev is less gimmicky

young knoll
#

You could technically have your plugin deploy a datapack

#

But it’ll be too late, so you’ll have to restart the server after

#

Kek

echo basalt
#

It's probably for our own good that we don't have registry access tbh

young knoll
#

I don’t know if reload works with biomes

#

I know it doesn’t work with structures

echo basalt
#

Reload is bad

young knoll
echo basalt
young knoll
#

If you want it to be, sure

echo basalt
#

I've tinkered with unfreezing registries and using unsafe

young knoll
#

It’s not that hard to mess with registries

#

Hell you don’t even need unsafe

echo basalt
#

True

young knoll
#

public static void unfreezeRegistry(Registry<?> registry) {
        try {
            Field intrusiveHolderCache = getField(MappedRegistry.class, Map.class, 5);
            intrusiveHolderCache.set(registry, new HashMap<>());

            Field frozen = getField(MappedRegistry.class, boolean.class, 0);
            frozen.set(registry, false);
        } catch (ReflectiveOperationException e) {
            e.printStackTrace();
        }
    }
#

Don’t show MD that one

echo basalt
#

These are spigot registries right

young knoll
#

No

echo basalt
#

Never seen MappedRegistry before

#

Prob just a mappings thing

young knoll
#

Wouldn’t be hard to make an api to add custom biomes

#

But actually doing something with them is another story

young knoll
#

You should see some of the stuff I do after unfreezing them

proven jay
#

@echo basalt I have to update the lines in the scoreboard, then show the scoreboard to the player, right?

#

This is what makes the scoreboard flicker at the moment

river oracle
errant urchin
#

hi, is it possible to modify the entity of a spawner block with a custom one?

river oracle
#

yeah

#

get the BlockStateMeta or whatever its called

#

and provide CreatureSpawner blockstate

errant urchin
#

Well I have this

glad prawn
errant urchin
river oracle
#

also why add MetaData and not some for of PDC?

#

with metadata you'll lose track of it

errant urchin
#

what is PDC?

#

I'll have to see it then

river oracle
#

blocks don't have Persistent Data but mfnalex has a library

glad prawn
#

?morepdc

undone axleBOT
errant urchin
river oracle
#

?blockpdc

undone axleBOT
river oracle
errant urchin
#

well but for now I want to do the custom entity thing, do you have any post by chance or something?

#

change which mob is displayed in the spawner to make it look like a custom entity

#
    @EventHandler
    public void onSpawnerSpawn(SpawnerSpawnEvent event) {

        CreatureSpawner creatureSpawner = event.getSpawner();
        if (!creatureSpawner.hasMetadata("mythicMob")) return;

        event.setCancelled(true);
        String name = (String) creatureSpawner.getMetadata("mythicMob").get(0).value();
        Spawner spawner = spawnerManager.getSpawner(name);
        if (spawner != null) spawner.spawn(event.getEntity().getLocation());

    }```
This way I made it generate a custom entity, I would like to change the visible entity of the block
errant urchin
#

I wouldn't mind using nms, if you know that would be fine

river oracle
#

maybe @echo basalt would know

#

I've seen this sort of thing done on servers before so its gotta be possible somehow

errant urchin
#

okey

#

thanks

river oracle
#

that's one thing, but changing the actual entity to another texture is another

quaint mantle
#
import io.github.dungeonschem.Utils.XMapRenderer;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.MapMeta;
import org.bukkit.map.MapRenderer;
import org.bukkit.map.MapView;
import org.bukkit.Bukkit;

public class GenerateTicTacToeMap implements CommandExecutor {

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (label.equalsIgnoreCase("generatetictactoemap") && sender instanceof Player) {
            Player player = (Player) sender;
            ItemStack item = new ItemStack(Material.FILLED_MAP);
            MapView map = Bukkit.createMap(player.getWorld());
            MapMeta meta = (MapMeta) item.getItemMeta();

            for (MapRenderer renderer : map.getRenderers()) {
                map.removeRenderer(renderer);
            }

            map.addRenderer(new XMapRenderer());
            meta.setMapView(map);
            item.setItemMeta(meta);
            player.getInventory().addItem(item);
        }

        return true;
    }
}```

This was supposed to generate a map with a X mark but it doesnt do that netiher are any errors generated
#

it just generates an empty map

quaint mantle
#

any1 here?

solar sparrow
#

Does anyone have any idea how I can generate a void world in my code below? It simply creates a world but it is not void. I'm using spigot 1.8.8.


if (args.length == 1 && args[0].equalsIgnoreCase("gerar")) {
                if (!fazendaGerada) {
                    // Crie um novo mundo vazio (void)
                    WorldCreator worldCreator = new WorldCreator("FazendaMundo"); // Nome do mundo
                    worldCreator.generatorSettings("{\"name\":\"void\"}"); // Configura o tipo de terreno para "void"
                    World fazendaWorld = worldCreator.createWorld();

                    // Teleporte o jogador para o novo mundo da fazenda
                    Location spawnLocation = new Location(fazendaWorld, 0, 64, 0); // Defina as coordenadas desejadas
                    player.teleport(spawnLocation);

                    fazendaGerada = true; // Marque a fazenda como gerada

                    player.sendMessage("Mundo da fazenda gerado! Você foi teleportado para lá.");
                } else {
                    player.sendMessage("A fazenda já foi gerada anteriormente.");
                }

                return true;
            } 

ocean hollow
#

how can I get rid of this error?

#

I saw a solution with removeIf, but I still need to use the method after that

young knoll
#

Use an iterator

wraith dragon
#

does anyone know how to break the learning barrier? its like you just cant learn anymore bruih

lilac dagger
#

use for each and then clear()

tender shard
#

and you

lilac dagger
#

ah wait, nvm, this are streams

jagged thicket
#

what is the best way to make a team chat

halcyon hemlock
#

how do spigot plugins work

grizzled sable
#

Bungeecord or Spigot ?

echo basalt
quaint mantle
#

facing this error could anyone help?

echo basalt
#

You know how to read stacktraces?

#

your method is basically taking forever to run

quaint mantle
#
int height = width;

        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                mapCanvas.setPixel(x, y, MapPalette.RED);
            }
        }```
#

yessir

#
            for (int y = 0; y < height; y++) {
``` its this line
echo basalt
#

Looks fine

#

although setPixel is one slow heavy method

#

shouldn't take more than 60ms to run that unless your cpu is a literal potato

quaint mantle
#

can it be because of the java int height = width

#

like

echo basalt
#

eh no

quaint mantle
#

hmm

#

well 500% CPU

#

should be enough

glad prawn
#

huh

echo basalt
#

that just means you're giving it 5 cores

quaint mantle
#

yeah can say that

#

but that still

#

doesnt fix the problemo

echo basalt
#

pretty sure you can play with map canvases async tbh

#

It'll still be slow but won't destroy your tps

quaint mantle
#

hmm

#

alr ill give it a try

tawdry pilot
#

can i send a plugin message to spigot from bungeecord without anyone online

#

ok

halcyon hemlock
shadow night
halcyon hemlock
#

yeah but how does the server interact with the plugin and vice versa

#

jvm magic?

echo basalt
halcyon hemlock
echo basalt
#

More like CraftBukkit tbh

halcyon hemlock
quaint mantle
#

check dms

halcyon hemlock
#

I dont know a lot about the backend of spigot / bukkit

echo basalt
#

Basically Bukkit is this whole abstraction layer on top of NMS

quaint mantle
#

ill explain the entire thing there

echo basalt
#

Or well, Bukkit is the API

#

CraftBukkit is the implementation

halcyon hemlock
#

yeah but how do the interact?

#

I'm trying to make my own server in rust

#

and I would like it so players can make their own plugins in rust and do the same thing like spigot

echo basalt
#

Ehh this part doesn't matter then

#

Anyways the idea for plugins, in (craft) bukkit is that we scan the plugins folder and load the jars

#

Each one with their own classloader

halcyon hemlock
#

so java specific stuff?

echo basalt
#

We grab the plugin, check its contents for the plugin.yml file and parse it as a PluginDescriptionFile

#

We then grab the javaplugin class listed as main and init it with reflections

#

call onEnable n all

shadow night
#

I'm getting curious reading all this, how do the evnts work? Idk stuff about annotations

echo basalt
#

Annotations can be accessed with reflections

halcyon hemlock
#

pretty sure

shadow night
#

But like, how does it know what methods to run?

halcyon hemlock
#

java specific stuff

halcyon hemlock
shadow night
#

And how does it run them?

halcyon hemlock
#

i belive

remote swallow
halcyon hemlock
#

I did something similar with a command system

echo basalt
#

Make a RegisteredListener out of it

#

Priority is set in the eventhandler interface

halcyon hemlock
#

just curious

echo basalt
#

I don't write spigot (platform) code

remote swallow
#

hes just a nerd

eternal night
#

fucking nerds man

echo basalt
#

I've been making plugins for like

#

7 years now

shadow night
#

Most of us here only do plugins

remote swallow
#

lynx no paper 1.20.2 (megamind)

echo basalt
#

and have somewhat deep knowledge of the internals

remote swallow
echo basalt
#

not even

halcyon hemlock
halcyon hemlock
#

nerd pro max

shadow night
#

So many people here now

echo basalt
#

I just poke fun at messing with the internals

halcyon hemlock
#

if you know that much about the internals, can you tell me how the first play packet works

torn shuttle
#

I think I might've been working a bit too much, I can feel my wrist starting to strain again

echo basalt
#

if someone asks me a spigot question I just see how it works

eternal night
halcyon hemlock
#

I've done the server list ping

echo basalt
#

it's been a couple years

#

but it went like this iirc

halcyon hemlock
#

after the player joins the server, and the server sends back the login success packet

shadow night
#

Is it possible to write a plugin using only craftbukkit?

remote swallow
#

no

shadow night
#

why no

halcyon hemlock
echo basalt
#

There are multiple phases

  • Handshake
  • Login
  • Configuration (1.20.2)
  • Play

With handshake the client opens a connection and sends either a "status" or "login" packet

echo basalt
#

If it's a status packet the server replies with motd

remote swallow
echo basalt
#

If it's a login packet the server replies with something else and goes into the login phase

#

something like that

#

encryption happens after etc etc

#

might be getting phase names wrong

#

I haven't touched this since uhh

#

early 2021

shadow night
#

I remember I had issues getting the handshake packet to work while making bots

thorn crypt
#

Hello, i dont find any event to check if a playere started a raid so I'm wondering, is there an event for it ?

halcyon hemlock
jagged thicket
halcyon hemlock
echo basalt
#

Yeah so

halcyon hemlock
#

I've done this much

#

and you can join server and it gets to the "Joining world..." screen

#

but you have to send back some play packet with a lot of registry and nbt stuff

shadow night
# halcyon hemlock

There was this cool thing called eaglercraft and it relied on websockets, so I made a similar thing for it before

echo basalt
#

Client sends handshake (0x00)
VarInt - Client protocol version
String - Address used to connect
UShort - Port used to connect
VarInt (1/2) - Next state

1 - Status (send motd)
2 - Login

#

It can also send a legacy handhake (0xFE) which is just a 0x01 byte

#

make sure you don't catch your server on fire

halcyon hemlock
#

doesn't seem to affect anything

echo basalt
#

Anyways if it's login

#

The client sends a Login Start packet in the new phase, so packet ids reset

halcyon hemlock
echo basalt
#

0x00 - packet id
String (16 chars) - Player username
uuid - Player Id

halcyon hemlock
#

for the login success

echo basalt
#

The configuration phase is where plugin channels are enabled

halcyon hemlock
#

write the

total len
packet id
uuid
username len
username
echo basalt
#

So you sent login success

#

Now we need login acknowledged which is just an empty packet telling the client to switch to the Configuration phase

#

just a 0x03

halcyon hemlock
#

oh

#

when receive 0x03 on what state

echo basalt
#

You send a 0x03 on Login

#

and we switch to Configuration

#

the configuration phase is a bit icky

#

But it's basically just where you send all your registries and stuff

#

in nbt

#

You have pre-made json versions for the default registry data

#

But this is where you send your custom biomes and stuff

halcyon hemlock
#

im using 1.17.1

#

lul

#

what version should I even build the server for

#

latest = easier?

echo basalt
#

uhh no

halcyon hemlock
#

right now its neutral

echo basalt
#

let's see for 1.17

#

all the info I was giving is for latest rip

halcyon hemlock
#

i thin 0x03 login is same

echo basalt
#

Okay there's no configuration phase in 1.17

halcyon hemlock
#

when login is acknoledged then what

echo basalt
#

So you go straight into Play

halcyon hemlock
#

oh that'd make sense why it says joining world

echo basalt
#

Because there's still some data that needs to be sent so that the client can render the world

halcyon hemlock
#

its a very big packet

#

also can I add u

echo basalt
#

you already did

#

I don't remember the exact packets you needed to send

#

but I'm pretty sure it was uhh

#

chunk packets

halcyon hemlock
#

directly?

echo basalt
#

well you're in the play phase now

halcyon hemlock
#

yes

#

dont u need to send anvil stuff

echo basalt
#

anvil is just a storage format

#

chunk packets are picky

#

send a chunk packet and a teleport player packet iirc

#

or a respawn packet

#

might be both

halcyon hemlock
#

wait

#

what

#

whats the order

#

I sent the login succes

echo basalt
#

uhh

halcyon hemlock
#

then send chunk packets?

echo basalt
#

Login success -> Join game

#

starting to remember

halcyon hemlock
#

where is this

halcyon hemlock
#

ah ok

#

istg bro who coded minecraft

#

why is the entity id an int but the world count is a varint

echo basalt
#

gdrive completely fucked my old project folders grr

halcyon hemlock
#

oof

#

you made something similar?

echo basalt
#

I forked a server jar once

eternal night
#

Vector (1)

echo basalt
#

LOOHP's limbo

shadow night
#

Why are there (1) classes

halcyon hemlock
#

and restart intellij

#

should fix

echo basalt
#

lmfao