#dev-general

1 messages ยท Page 345 of 1

static zealot
#

I don't even know if I'll start watching season 7

old wyvern
#

ep 2 is a pretty shitty excuse to get them out of a situation they couldnt get out of

#

Yea 6 was left incomplete coz of covid

#

They are going to wrap up the s6 story by s7 ep 3 apparently

#

The mirror master arc

static zealot
#

The Boys was a good show. I can't say it was great but good

old wyvern
#

||Earth 1 Wells is back, not thawn, the actual Wells who we saw thawn kill in the flashback||

static zealot
#

wait what?

#

also they diged his bones...

#

and confirmed its him

old wyvern
#

Yup

#

But

#

well

#

watch

#

xD

static zealot
#

Sherlok is an interesting show but idk if I like it

#

oh Lost in space was nice tho

old wyvern
#

Umbrella Academy is nice

static zealot
#

yeah

#

also my first show that I actually watched and loved was Altered Carbon

#

idk why

#

I didn't really like shows until that one

old wyvern
#

Whats that about?

static zealot
#

a future where our conscience is stored on some kind of disks that are put in our necks and we don't really need the bodies anymore we can just change them

old wyvern
#

O.o

#

Have you seen upload?

static zealot
#

I don't think I have

old wyvern
#

Similar concept, In the future people who die can be downloaded into a VR world

static zealot
#

oh seems interesting

#

well in AC you can actually change bodies after you die if you have money

old wyvern
#

๐Ÿ˜ฎ

static zealot
#

its pretty good anyways

#

you should watch it

old wyvern
#

Yea, will do PlusOne

static zealot
#

yeah idk why I really liked it

lunar cypress
#

In the beginning it was ok imo, but it got really dull and just centered around excessive violence later on

static zealot
#

I love excessive violence

#

xD

stuck harbor
#

blitz have u played katana zero?

static zealot
#

nope

stuck harbor
#

its very violent

static zealot
#

Ic

#

I don't think I've actually played a lot of 2d games

lunar cypress
#

I also do love me some violence, but AC just takes itself too seriously while it remains rather superficial story-wise

#

gotta love the atmosphere though

stuck harbor
#

atmosphere

#

i love when pixel art games immerse me more than high quality ray traced AAA games

#

always fun

static zealot
#

well idk a lot of shows that have actually good story for all seasons. Most of them are good in the beginning but just go bad after a while

#

idk I don't play a lot of AAA games either. I'm not really a "Gamer" I just play games that I can afford lmao xD the only games I bought because I liked them were the Tomb Raider games. the new ones

lunar cypress
static zealot
#

maybe. tbh a lot of shows I watch and I just remember the feelings. Not the actual shows xD

#

for AC I do remember some stuff and usually that's because I liked them

jovial warren
static zealot
#

I just see a lot of stuff so I'm going to say it won't work

jovial warren
#

lol

#

what that does is this:

  1. Load the plugin.conf file from the plugin's JAR
  2. Create the data folder if it doesn't exist
  3. Retrieve the main class attribute from the plugin's JAR manifest
  4. Construct a new URLClassLoader for that plugin
  5. Load the plugin's main class reflectively and instantiate it with the plugin's context
static zealot
#

idk I'm to lazy to read it watching yt videos xD

old wyvern
#

You could use apply on the folder instead of the first init block

#

And move the loader up if thats whats used by load I guess

jovial warren
#

good point

old wyvern
#

The field right below it

#

Didnt look into what it was

#

just saying by name

jovial warren
#

yeah I've removed that map now

#

list*

#

it was unnecessary

old wyvern
#

ah ok

jovial warren
#

each plugin has its own URLClassLoader instance

old wyvern
#

Also you dont need the exist check for the file iirc

#

Just call mkdir instead

#

It just returns false if it didnt get created

jovial warren
#

oh yeah

lunar cypress
#

no parent class loaders?

old wyvern
#

Also why the map to pluginloadstate

jovial warren
old wyvern
#

Could just be a fieldin the plugin class

jovial warren
#

yeah

jovial warren
frail glade
#

Clean

jovial warren
#

thanks ๐Ÿ™‚

#

@prisma wave can I steal your repo just to put the Krypton API on until I get my request to register org.kryptonmc on Maven Central approved btw? xD

#

they fixed highlighting?

#

about fucking time

#

right, here we go, moment of truth

onyx loom
#

wym

#

isnt that normal highlighting?

ocean quartz
#

Wdym fixed the highlighting?

jovial warren
#

the blue

#

I haven't seen blue there in ages

#

I always get method call is ambiguous lol

#

big pog

static zealot
#

load Terrible Plugin on that

jovial warren
#

terrible plugin is written in Java and uses Bukkit ๐Ÿ˜”

static zealot
#

well can't you just shade in java?

#

and Bukkit

jovial warren
#

you know Java is included in the JRE right?

#

the JDK is in the JRE

#

and for Bukkit

static zealot
#

why?

#

I'll just PR

#

it

jovial warren
#

Bukkit is absolutely diabolical

#

also, I'm stupid lol

#

imagine making an initialize method and not making it open

#

๐Ÿฅฒ

#

finally, Krypton isn't fully useless anymore

#

still gotta test what happens if you instantiate another class in the constructor

#

actually that doesn't need loading

#

oh btw, on the topic of plugins, anyone up for making some simple plugins using the new Krypton API and giving me some feedback? ๐Ÿ™‚

static zealot
#

how much you paying? /s

jovial warren
#

lol

#

๐Ÿฅฒ

#

just about to push the server update

winter iron
#

is lombok bad?

jovial warren
#

?plsnolombok

compact perchBOT
#
FAQ Answer:

Why is Lombok bad?

  • It's a compiler hack - the Java compiler isn't designed to modify code, so it can cause difficult to debug errors, or worse
  • It requires an IDE plugin, so unless you've properly configured Maven, Gradle and your IDE, you'll get hundreds of compilation errors. This process takes time too, it's not easy
  • Lombok'd code won't show in Javadocs
  • The code generation is often unpredictable and difficult to debug, and often you'll have to do it "the hard way" anyway
  • Java is supposed to be explicit, Lombok hides a lot of key functionality into a subtle annotation which can be easy to miss
  • While IDEs support it with a plugin, it's usually more difficult to find specific things, like usages of a getter because they don't exist in the source code
  • Finally, Lombok'd bytecode doesn't match the source code, so it causes a pretty annoying warning in IntelliJ
static zealot
winter iron
#

damn got a whole ass bot made to answer the question

#

any more reasons why

static zealot
#

yep

#

its bad

jovial warren
#

oh btw, a few notes when making Krypton plugins:

  1. Every plugin needs a description file, called plugin.conf, on its classpath (basically plugin.yml without main)
  2. Every plugin must have its main class set in the manifest (can be done with the application plugin in Gradle)
  3. Every plugin's main class must take context: PluginContext as an argument to its constructor
winter iron
#

krypton bad

jovial warren
#

wow

winter iron
#

bukkit 1.7.10 good

jovial warren
#

what kinda rock you been living under for the past like 8 years lol

winter iron
#

im gonna become a hater

#

krypton bad

#

elara bad

#

kotlin bad

jovial warren
#

Krypton good

winter iron
#

clojure bad

jovial warren
#

Elara good

#

Kotlin good

#

Clojure kinda meh

winter iron
#

down bad if ur using clojure

jovial warren
#

lol

#

Krypton is not bad though

old wyvern
winter iron
#

might start programming my plugins in html

old wyvern
#

Even more so after upcoming changes

#

๐Ÿ˜Œ

onyx loom
#

say its dogshit rn

winter iron
#

๐Ÿ‘€

jovial warren
#

okay, Clojure bad

old wyvern
jovial warren
#

now make me a plugin lol

old wyvern
#

Pay me

onyx loom
#

what for

old wyvern
#

Orrrrr add embeded elara suppourt

#

For now till it compiles to jvm ๐Ÿฅฒ

jovial warren
#
repositories {
    mavenCentral()
    maven { url 'https://libraries.minecraft.net/' }
    maven { url 'https://repo.bristermitten.me/repository/maven-public/' }
}

dependencies {
    compileOnly 'org.kryptonmc:krypton-api:0.11.1'
}
```ez
#

(top 2 repositories required because Kotlin and other dependencies of the API are in Maven Central and Brigadier has its own library)

old wyvern
#

Shouldnt that resolve itself if you have them in them transitively in the compiletime classpath from your repository declarations?

jovial warren
#

wat

#
    repositories {
        mavenCentral()
        maven { url 'https://libraries.minecraft.net' }
    }

    dependencies {
        api 'org.jetbrains.kotlin:kotlin-stdlib'
        api 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3'

        api 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0'
        api 'org.jetbrains.kotlinx:kotlinx-serialization-hocon:1.1.0'

        api('net.kyori:adventure-api:4.6.0') {
            exclude group: 'org.checkerframework', module: 'checker-qual'
        }
        api('net.kyori:adventure-extra-kotlin:4.6.0') {
            exclude group: 'org.checkerframework', module: 'checker-qual'
        }

        api 'com.mojang:brigadier:1.0.17'
        api 'me.bardy:admiral:1.0'

        api 'org.apache.logging.log4j:log4j-api:2.11.1'
    }
```my dependencies
#

oh btw, @ocean quartz, you'll be happy to know that Krypton's CommandManager has a register method that directly accepts a LiteralArgumentBuilder ๐Ÿ™‚

old wyvern
#

According to docs, api is transitive so those depndencies should be available to any project depending on this

jovial warren
#

ยฏ_(ใƒ„)_/ยฏ

#
override fun register(command: Command) {
    val commandNode = dispatcher.register(literalArgument(command.name) {
        executes {
            val permission = command.permission ?: return@executes 1

            if (it.source.hasPermission(permission)) {
                CommandScope.launch { command.execute(it.source, it.input.split(" ").drop(0)) }
                1
            } else 0
        }
    })

    command.aliases.forEach { dispatcher.register(literalArgument(it) { redirect(commandNode) }) }
}
```this is the `register` function for commans btw lol
old wyvern
#

Have you tried without the repos specified?

jovial warren
#

oh it does actually work

#

maybe because it's cached, idk

#

Could not find org.jetbrains.kotlin:kotlin-compiler-embeddable:1.4.31. without repo

#

without Minecraft libraries: Could not find com.mojang:brigadier:1.0.17.

#

whatever kinda docs told you api is transitive, transitive my backside

prisma wave
winter iron
#

never

#

fight me

#

then ill consider

prisma wave
#

I'd love to

#

Send your address

winter iron
#

bet

#

ill send u a waypoint on google maps and u can get ur mom to drop u off

prisma wave
#

sounds good

#

see you tomorrow

jovial warren
#

lol

#

BM

#

me made it work

jovial warren
#

lol

winter iron
#

ill bring all my python2 buddies

prisma wave
winter iron
#

ur finished

jovial warren
prisma wave
prisma wave
winter iron
#

ill body ur bum ass

prisma wave
#

Try

winter iron
#

built like a twig

jovial warren
prisma wave
winter iron
#

i get paid to headbutt children

#

but u can get one for free

prisma wave
#

I nolife a minecraft discord

#

Try me

errant geyser
#

I read that as "ill bum your ass"... yeah gn

winter iron
#

Lmao

#

gay as hell

#

i play roblox

#

minecraft aint shit to me

prisma wave
#

Ew

#

Subhuman

winter iron
#

3rd worlder

jovial warren
#

oh yeah, BM, write me a plugin pls

winter iron
#

ye do as he says

#

b i t c h

errant geyser
#

Leave senpai alone

jovial warren
jovial warren
winter iron
#

๐Ÿ˜ 

#

im on smoke

jovial warren
#

not surprised lol

winter iron
#

whats that supposed to mean

#

:/

#

im getting off, my mom told me i need to rest before i beat bm

#

pce

jovial warren
#

๐Ÿ‘‹

ocean quartz
jovial warren
#

because you asked for Brigadier colour support lol

#

iirc

#

the coloured argument thingies

#

remember?

ocean quartz
#

I think you're thinking Frosty

obtuse gale
#

doesn't matter

#

that orange support dude

distant sun
#

mf with brigadier support would be amazing

obtuse gale
#

and on hover tooltips :partyparrot:

ocean quartz
#

With hover tooltips

jovial warren
#

though my command system doesn't handle sub commands

#

but that's why you can register Brigadier literal argument builders lol

#

and why Admiral is embedded

#
literalArgument("time") {
    literalArgument("set") {
        literalArgument("day")
        literalArgument("noon")
        literalArgument("night")
        requiredArgument("time", integer)
    }
    literalArgument("add") {
        requiredArgument("time", integer)
    }
    literalArgument("query") {
        literalArgument("day")
    }
}
#

๐Ÿ˜Ž

#

should probably just remove the Argument suffix from those top-level functions tbh

surreal quarry
#

probably cleaner without them

obtuse gale
#

literalArgument("time", integer)
wat

#

I'll assume you intended requiredArgument instead

surreal quarry
#

lol

jovial warren
ocean quartz
obtuse gale
#

Think of it like a directory tree

jovial warren
#
literal("time") {
    literal("set") {
        literal("day")
        literal("noon")
        literal("night")
        required("time", integer)
    }
    literal("add") {
        required("time", integer)
    }
    literal("query") {
        literal("day")
    }
}
#

how's that instead?

ocean quartz
#

Still ugly

onyx loom
#

mf monopoly will never be topped

jovial warren
#

"monopoly"

obtuse gale
#

I quite like the tree structure

jovial warren
#

cmd.getName().equalsIgnoreCase() monopoly will never be topped xD

onyx loom
#

๐Ÿคจ

fierce jewel
#

anyone have plugin for blocking 2nd hand on 1.16 ??

jovial warren
#

I got Haskell! yay!

fierce jewel
#

doesnt work

onyx loom
#

?

prisma wave
obtuse gale
#

tf is brigadier

#

Brigadier is a command parser & dispatcher, designed and developed for Minecraft: Java Edition and now freely available for use elsewhere under the MIT license.

jovial warren
#

One of those fake wiki page links gets posted when you ask a question in the wrong channel

obtuse gale
jovial warren
#

Stfu

obtuse gale
#

nah thanks I'm good

jovial warren
#

Lol

distant sun
#

is possible to create a SHULKER inventory that has a certain color, eg red_shulker?

surreal quarry
#

its probably similar to leather if i had to guess

glossy relic
#

What's the command to get a workup on where server resources are going?

#

Like ram usage etc.

surreal quarry
#

if there isn't like RED_SHULKER or something, it would probably be setting a meta property?

glossy relic
orchid crescent
#

then you are avaible to use setColor and getColor methods

#

wait are you asking creating inventories or just shulkers

#

and can you see the which color is it in inventory?

cunning oriole
#

Hey, I was looking for someone who could update a jumppads 1.8.8 plugin to 1.12.2, it should use same configs and have same permissions. I can pay with Skrill or maybe paypal.

hot hull
jovial warren
#

Krypton has commands now ๐Ÿ™‚

hot hull
#

brigadier support?

#

as in colored args

jovial warren
#

two of the register methods take LiteralArgumentBuilders lol

#

and it uses Brigadier internally

#

so if you want coloured arguments, you can just directly use that

#

for now anyway

prisma wave
#

Ew API methods taking builders

jovial warren
#

that's what Brigadier takes internally

hot hull
#

oh god

obtuse gale
#

it literally calls the method that takes the built node though so lmao

jovial warren
#

the thing I could do I suppose is call root.addChild and take a LiteralCommandNode I guess

obtuse gale
#

ArgumentBuilder#then also takes a built CommandNode too (that's the method the one that takes the builder calls)

#

Frcsty just had a deep orgasm

hot hull
#

:moan:

#

Show the abomination that is the code for that Fefo

obtuse gale
#

Needlessly long af name

#

eeeeeeeeeeeeeee

stuck harbor
#

no

#

we wouldn't

obtuse gale
#

it would have good structure if it evolved, advanced and moved forward over time instead of being stuck and unwilling to improve like it is

#

the day paper hard forks

#

god I'm gonna have kids that day

stuck harbor
#

man

#

just fork paper

#

and make a better one

#

called

#

cardboard

#

cardboardspigot yes

#

make it run on go

obtuse gale
#

with tnt optimized for pvp righT?

stuck harbor
#

idk I'm not a pvper

#

so sure

obtuse gale
#

right

#

1.8ers are happy with that decision

stuck harbor
#

lol

jovial warren
#

yeah I'll change that now lol

#

thanks for reminding me

obtuse gale
#

lol

#

also that packet id is wrong lmao

#

unless you do your own internal woes

jovial warren
#

it is wrong, correct

#

that is because it has not been updated since BM wrote it for 1.15 lol

prisma wave
#

๐Ÿ™„

obtuse gale
#

lol

errant geyser
#

Every time I click here there's something really dodgy now

#

why

hot hull
#

wdym why, colored arguments!

jovial warren
#

can anyone here help me understand some Mojang whack please?

#

I've renamed the variables according to what I think they are

old wyvern
#

What part do you want explained?

#

its a breadth first search through the provided node

jovial warren
#

isn't breadth first search when you take a tree and you expand as far across as you can before moving down?

old wyvern
#

Yes

#

Think of that snippet's execution like this:
Pass #1

Queue: RootNode

->Poll

Queue: 
Current: RootNode

Use result from Current;

-> Add children

Queue: RootNode#Child1, RootNode#Child2

Pass #2

Queue: RootNode#Child1, RootNode#Child2

->Poll

Queue: RootNode#Child2
Current: RootNode#Child1

Use result from Current;

-> Add children

Queue: RootNode#Child2, RootNode#Child1#Child1, RootNode#Child1#Child2

.... continue till queue is empty

jovial warren
#

ah right

#

any idea if there's a cleaner way I can do that in Kotlin?

#

also since assignments in while statements aren't allowed

lunar cypress
#

you never need that though

#

you can also do it recursively

old wyvern
#

Break if empty

jovial warren
lunar cypress
#

yes

jovial warren
#

so it's both clean and fast

old wyvern
#

uh

#

not dfs

#

bfs

lunar cypress
#

yes

old wyvern
#

We need a queue not a stack tho

#

You could hack things together, But i assume its only going to end up more complicated

jovial warren
#

I just need a map of elements to their respective indices

#

(a Map<CommandNode<*>, Int>)

lunar cypress
#

"hack things together" if you say so

#

There's a pretty standard recursive implementation afaik

old wyvern
#

Can you link me to an example?

jovial warren
lunar cypress
#
BFS(start_node, goal_node)
    return BFS'({start_node}, โˆ…, goal_node);

BFS'(fringe, visited, goal_node)
    if (fringe == โˆ…)
        return false;
    if (goal_node โˆˆ fringe)
        return true;
    return BFS'({child | x โˆˆ fringe, child โˆˆ successors(x)} \ visited, visited โˆช fringe, goal_node);
```from german wikipedia
jovial warren
#

BFS'? isn't that the inverse of BFS?

lunar cypress
#

I recently had to implement it as well though I did it iteratively because java

lunar cypress
#

it's just the recursive helper

jovial warren
#

ah right

#

any examples of that implemented in code that I might understand? lol

#

actually nvm, seems I have a Java example on this page I linked

#

but that still seems to use iteration

#

it's maths

lunar cypress
#

pseudocode

jovial warren
#

yeah that's mathematical-based pseudocode I think

#

โˆ… is the empty set iirc, and โˆˆ means the left thing is an element of the right set

old wyvern
lunar cypress
#

no

#

there is no order there

old wyvern
#

The adding order

#

The union does pretty much the same thing here

lunar cypress
lunar cypress
old wyvern
lunar cypress
#

I do not think it assumes anything in terms of order

jovial warren
#

also, if I was to go with iteration here btw, couldn't I just use a for loop? or will that not work

lunar cypress
#

it should work with any set type

jovial warren
#

actually no that won't work

lunar cypress
#

what kind of for loop? you can't remove elements from the queue in kotlin when you do that

jovial warren
#

true

lunar cypress
jovial warren
#
private fun RootCommandNode<*>.enumerate(): Map<CommandNode<*>, Int> {
    val result = mutableMapOf<CommandNode<*>, Int>()
    val queue = ArrayDeque<RootCommandNode<*>>()
    while (queue.isNotEmpty()) {
        val element = queue.poll()
        if (result.containsKey(element)) continue
        val size = result.size
        result[element] = size
        queue += element.children
        if (element.redirect != null) queue += element.redirect
    }
    return result
}
```that's the translated code I think
#

but that's ugly lol

#

I mean, saying that, chunkInSpiral is literally unreadable, so ya know

lunar cypress
#

the "problem" with the recursive implementation is that you need immutable sets

jovial warren
#

would my Kotlin code actually work btw?

lunar cypress
#

Considering we're talking about very small graphs here (or so I assume) this probably won't matter but still it is something to take into consideration

jovial warren
#

very small graphs? er... this may or may not include every single command that has been registered with the dispatcher on the server

#

idk about you, but that ain't small

lunar cypress
stuck harbor
#

when you try to write pseudocode but end up writing python

#

that's me

#

๐Ÿฅฒ

jovial warren
old wyvern
lunar cypress
jovial warren
lunar cypress
#

We might have different ideas of what small is too

jovial warren
#

that's an example graph from wiki.vg

#

(open that in the browser and zoom lol)

lunar cypress
#

oh well that is considerable

stuck harbor
#

maaaan

#

that's thicc

jovial warren
#

and that's just the default map

#

not including all the custom commands from plugins

stuck harbor
#

damn

old wyvern
jovial warren
#

I just ideally need something that can be computed at least relatively fast

old wyvern
#

Otherwise that should work

lunar cypress
#

yeah I think the code works

prisma wave
#

seems like recursion would be nicer here no?

jovial warren
#

oh btw, in Kotlin's ArrayDeque, is it firstOrNull I want instead of poll btw?

jovial warren
#

Johnny said that

lunar cypress
#

nicer yes, but too inefficient probably

jovial warren
#

I just need something that can be computed extremely quickly

#

actually, thinking about it, if commands aren't registered after startup is complete, then I should only really need to compute this once

lunar cypress
old wyvern
#

yes

jovial warren
old wyvern
#

Wait really?

#

1.4 thing?

old wyvern
#

oh it existed from 1?

#

Didnt notice welp

jovial warren
#

ยฏ_(ใƒ„)_/ยฏ

jovial warren
#

so ```kotlin
private fun RootCommandNode<>.enumerate(): Map<CommandNode<>, Int> {
val result = mutableMapOf<CommandNode<>, Int>()
val queue = ArrayDeque<CommandNode<
>>()

while (queue.isNotEmpty()) {
    val element = queue.removeFirst()
    if (result.containsKey(element)) continue
    val size = result.size
    result[element] = size
    queue += element.children
    if (element.redirect != null) queue += element.redirect
}

return result

}

#

still not sure about removing the contains or null check

old wyvern
#

Why not?

#

It doesnt visit a node more than once

jovial warren
#

alright, I'll remove them

old wyvern
#

Actually the queue would require the null check huh

jovial warren
#

also, the redirect can be null, and if it is, we don't want to add it

old wyvern
#

yea nvm about that one

jovial warren
#

I'll remove the contains check though

old wyvern
#

Yea my bad, I was thinking from the Java perspective where it would just ignore the null value

prisma wave
jovial warren
#

if you wanna help me make this cleaner and just as fast if not faster, be my guest BM

lunar cypress
#

Yeah well. One of those doesn't exist in kotlin unfortunately

jovial warren
#

which one?

prisma wave
#

there's ktx.persistent afaik

old wyvern
#

persistent data structures

jovial warren
#

what are those?

old wyvern
#

really?

prisma wave
#

which adds persistent data structures

#

yeah

lunar cypress
#

Oh there is? Interesting

prisma wave
#

yup

#

never used it

old wyvern
jovial warren
prisma wave
#

but it definitely exists

jovial warren
#

so it's basically where the data structure preserves its previous state when it's modified?

lunar cypress
#

The idea is, to dumb it down, have immutable data structures that don't need to copy everything when you "modify" them

prisma wave
#

yeah

#

immutable but pretty much constant time "copying"

old wyvern
#

for an example git handles commits like a node of a persistent tree I think

jovial warren
#

so basically just immutability where it only copies the changes

old wyvern
#

A bit more than the changes bard

lunar cypress
#

I wanna see how kotlin's persistent data structures compare to clojures now

old wyvern
#

The usefulness is that you dont need to copy the entire structure

jovial warren
old wyvern
#

But you still need to copy more than the changes you made ussually

jovial warren
#

first result for kotlin persistent data structures lol

lunar cypress
#

The most beautiful (imo) persistent data structure is the classic singly linked list

#

Or cons

#

Even though it isn't very powerful it's perfect in a sense because you really do reach constant time and memory with addition/removal at the front

#

And it's the simplest list implementation that exists as well

prisma wave
#

linked lists are great

lunar cypress
#

Gonna benchmark this I think

#

It has something like transient in clojure as well i see

jovial warren
#
private static CommandNode<SharedSuggestionProvider>[] getNodesInIdOrder(Object2IntMap<CommandNode<SharedSuggestionProvider>> nodes) {
    CommandNode<SharedSuggestionProvider>[] result = new CommandNode[nodes.size()];
    for (Object2IntMap.Entry<CommandNode<SharedSuggestionProvider>> entry : Object2IntMaps.fastIterable(nodes)) {
        result[entry.getIntValue()] = entry.getKey();
    }
    return result;
}
```trying to think what the purpose of this might be
#

actually maybe the client wants the nodes in ID order

#

that would make sense

#

is there a better way to basically reverse a map than that?

#

I was thinking that one of Kotlin's map extension functions might be the answer, but I can't seem to find one

old wyvern
gentle coyote
#

o7, I am currently digging into the data conversion stuff using Mojangs DataFixer API.
I want to convert a (serialized) 1.12 item stack NBT data to a 1.16 one. The following code works:

NBTTagCompound converted = (NBTTagCompound) DataConverterRegistry.a().update(
        DataConverterTypes.ITEM_STACK,
        new Dynamic<>(DynamicOpsNBT.a, sourceCompound),
        -1,
        CraftMagicNumbers.INSTANCE.getDataVersion()
).getValue();

But it works just great for "normal" item stacks. As soon as the source Item Stack is a shulker chest it does some strange things :/

#

The biggest problem is the lack of documentation for this stuff. I also tried using the data converter type for a block entity, arranged it in different ways but everytime it either says that minecraft:black_shulker_box or shulker_box would be an invalid (namespaced?) key

jovial warren
half harness
#

How would I remove one of the tab completers?

jovial warren
#

also, you can't call associate on a Map btw

old wyvern
#

on the entries

#
theMap.entries.associate{ it.value to it.key }
jovial warren
#

right, then what?

old wyvern
#

You only wanted to reverse the map right?

jovial warren
#

lemme see

old wyvern
#

oh wait you wanted an array

jovial warren
#

lemme see if I can work with the map

distant sun
#

map.toMap()

jovial warren
#

lol

old wyvern
jovial warren
#

I think the reason why it's converted to a list is because I couldn't care less about the integer value, that's just used for ordering

old wyvern
#

I see

jovial warren
#

the ID is only used to order them in the array

old wyvern
#
theMap.entries.associate{ it.value to it.key }.let { map -> Array(map.size(), Map::get) }

This should give you the same result as from the snippet

#

Probably not the most efficient way to do it tho

jovial warren
#

yeah

old wyvern
#

Maybe just use map

#

Wait nvm

#

hmm

jovial warren
#

anyway, lemme test this out

#

seemed to work

#

the client now highlights the commands

old wyvern
#

great

jovial warren
#

oh btw, since I'm loading plugins myself and stuff, would it be necessary to add a shutdown hook to unload things?

#

just not sure if/what I need to ensure is safely closed

old wyvern
#

To let the plugins know of their shutdown?

#

Yes

#

Please do

jovial warren
#

also will add console parsing soon

#

it's just a thread right?

#

I just create a new thread and add it as a shutdown hook

old wyvern
#

huh?

jovial warren
#

Runtime.getRuntime().addShutdownHook()?

#

or is there something else I can use

old wyvern
#

Yea ig, then unloading each plugin sends the unload event I assume?

jovial warren
#

yeah it'll fire an event

old wyvern
#

alright

jovial warren
#

there's no filtering to say which plugin it goes to though

#

so it'll go to all plugins

old wyvern
#

Should be fine

#

Does it unregister all other "listeners" registered by the plugin after unloading?

jovial warren
#

oh also, would you know of a way that I could remove the while (true) in the start method in server btw?

jovial warren
old wyvern
jovial warren
#

it's all reactive

old wyvern
#

Thats still a listener

#

That would run after a plugin is disabled

jovial warren
#

yeah but there isn't really a way to unregister that

hot hull
#

Gotta love spigot plugins

jovial warren
old wyvern
#

You can filter with the plugins loadState or whatever that was

jovial warren
#

yeah true

jovial warren
#

if I remove it, the main thread stops executing and so the JVM dies

#

in vanilla, this is solved by the runServer method, which calls ticking methods that tick the server

#

but that's not how Krypton is built, since everything that's done there I expect to do when I receive the data

old wyvern
#

NettyProcess#run is blocking right?

jovial warren
#

it's suspending yeah

#

that just sets up netty

quiet depot
#

bardy you need to use non daemon threads

jovial warren
quiet depot
#

no clue

#

another thing you could do though is have a queue of runnables and run them in that while loop

old wyvern
#

Use runBlocking

old wyvern
#
finally {
    workerGroup.shutdownGracefully()
    bossGroup.shutdownGracefully()
}```
quiet depot
#

bardy why is your formatting so fucked

jovial warren
#

also, I hardly wrote that netty process code btw, that was mostly BM

old wyvern
#

Yea that part woudl be called when netty shuts down

quiet depot
#

u've got newlines under your classes and objects

old wyvern
#

withContext is suspending

quiet depot
#

except it's inconsistent

#

not all declarations have a newline

#

huge fan of the no newline btw, highly recommend going that route

old wyvern
#

use runBlocking and just call the blocking netty call at the end

jovial warren
#

yeah the override fun initChannel should probably have a new line above it

old wyvern
#

with an IO dispatcher if you really want to

#

Doesnt really matter

jovial warren
#

wait what

#

how do I do that?

quiet depot
#

I'm only talking about the class you linked first

old wyvern
#

runBlocking

quiet depot
#

KryptonServer

jovial warren
#

where Yugi

old wyvern
#

One sec

jovial warren
quiet depot
#

it's inconsistent

jovial warren
#

ik it's a mess, but it's basically just shoot first, ask questions later lol

quiet depot
#

no newline looks better

#

i hate the newline

#

lots of people do it though

#

you do you ig

prisma wave
#

is that github?

quiet depot
#

yes

prisma wave
#

hot theme

quiet depot
#

it's github's dark theme

prisma wave
#

is it?

quiet depot
#

no addon

#

ye

prisma wave
#

oh

#

lol

jovial warren
#

I think it separates the declaration from the stuff inside of it nicely tbh

prisma wave
#

looks different for me

jovial warren
#

idk, I just like it

quiet depot
#

oh nvm

#

I think I have both on

#

the gh dark theme and the extension

jovial warren
#

I'll fix up the horrible code later anyway

#

for now, I'm operating under "shoot first, ask questions later"

quiet depot
#

yeah I've got both on

jovial warren
#

also, the spacing above the start function is inconsistent because of the way I group things

#

two things that go together get put next to each other

#

and things that don't go together are separated by a new line

quiet depot
#

I don't see anything inconsistent about the start function

jovial warren
#

no, above it

old wyvern
#

Try this bard

quiet depot
#

nor above it

#

in general I'm not a fan of this class

jovial warren
#

you agree with my grouping?

quiet depot
#

there's so much going on

#

way too much

jovial warren
#

yeah I agree

#

not really all that much I can do about that though

quiet depot
#

oh are you talking about these?

#
override fun player(uuid: UUID) = players.firstOrNull { it.uuid == uuid }
    override fun player(name: String) = players.firstOrNull { it.name == name }```
#

and there's always things you can do

jovial warren
#

no, not those

#

just the fields

old wyvern
#

Bard

jovial warren
quiet depot
#

idk grouping seems fine for the most part except for the fact that there's a good chance 99% of these fields simply shouldn't be here

jovial warren
#

most of them are here because of the API

#

look at the interface this implements

quiet depot
#

if your api forces you to write bad code then you need a new api

jovial warren
#

no, that's not what I'm saying

#

just look at the class this implements, then you might understand why there's so many things in this class

quiet depot
#

ig it all has to come together somewhere (unless you use guice like a pro)

jovial warren
#

not saying you're wrong for calling me out for writing bad code, just saying there's an explanation

#

efe tf?

#

oh also, Piggy, what do you think of native Adventure support?

old wyvern
#

You could also split up all the properties in the Server interface ig

jovial warren
#

or group them better

quiet depot
#

or use guice

old wyvern
#

group them better as in?

quiet depot
#

native adventure is good

jovial warren
#

e.g. isOnline, isHardcore, difficulty and gamemode could all be grouped into some sort of server settings

quiet depot
#

did you figure out reloading?

old wyvern
#

Is that not what I just said xD

jovial warren
jovial warren
#

the API is still a massive W.I.P anyway, so feedback is greatly appreciated

#

oh also, what do you guys think of the logger names for plugins?

#

they're currently Plugin - Name (to differentiate from Krypton classes)

#

%d{HH:mm:ss.SSS} %style{%-30.-30thread}{bright,cyan} %style{%-24.-24logger{0}}{bright,green} %highlight{%-6level} %msg%n that's my logging pattern lol

quiet depot
#

ew

#

what logger is that

jovial warren
#

it's a custom format I stole from JDA lol

quiet depot
#

no

#

what logger

jovial warren
#

it used to be a Logback format, but we're using Log4j2 now

quiet depot
#

I'm a firm believer that logback is the best logger

jovial warren
#

Log4j2 is apparently faster, supports logging more than just strings, and also can log async

#

if it was Log4j vs Logback, Logback all the way

#

but Log4j2 vs Logback, Log4j2

quiet depot
#

%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%level) %cyan(%logger{36}) - %msg%n

#

my format

#

i like it

#

relies on symbols rather than spacing for separation

jovial warren
#

looks quite similar to Spigot's tbh

#

just with colours

#

lemme translate that to Log4j2 format and see it

jovial warren
#

ooo

quiet depot
#

just noticed a typo in the file policy

#

oh well

jovial warren
#

might use [PluginName] to indicate plugins instead of Plugin - PluginName

quiet depot
#

change the thread colour

#

or change the info colour

jovial warren
#

yeah because it clashes

quiet depot
#

don't want them matching

jovial warren
#

also, is saving logs to a file like vanilla does a good idea btw?

quiet depot
#

it's basically essential

#

here's what mine looks like

lunar cypress
#

and it's trivial with all major logging frameworks

jovial warren
#

yeah Log4j2 should have no issues

#

also, Krypton doesn't support SLF4J natively btw, it uses Log4j2's API (basically SLF4J++)

quiet depot
#

yeah that's not smart

#

I think

jovial warren
#

I mean, you can add SLF4J compat by depending on log4j-slf4j-impl if you really want it, and it'll work fine

quiet depot
#

actually there might not really be downsides to that with an app like krypton

jovial warren
#

yeah, since all logging is managed centrally anyway

lunar cypress
#

I don't see an issue with it because users are not supposed to choose a logger implementation

jovial warren
#

^

quiet depot
#

yeah it's more of a mistake for something like jda where you're expected to provide an impl

lunar cypress
#

yeah

jovial warren
#

yeah

#

oh also, Piggy, any ideas on what style I should use for the thread?

lunar cypress
#

although I would only expose the slf4j api to the plugin api in case you want to change it

jovial warren
#

I can use any ANSI colour

quiet depot
#

I've posted my format

#

that's what I use

#

it's my favourite

#

so that's my recommendation ig

jovial warren
#

lemme see what blue looks like

#

oh that's nice

quiet depot
#

nah change the info to blue

jovial warren
quiet depot
#

why's the name green?

jovial warren
#

that's cyan lol

#

apparently

quiet depot
#

should look like this

jovial warren
#

according to Atom OneDark anyway

#

oh btw, Log4j2 has a Logback preset for highlighting

#

that might be nice

quiet depot
#

try that

#

and change cyan to light blue

#

maybe that'll fix it

#

and thread back to green

jovial warren
quiet depot
#

that atom one dark thing must just fuck with it

jovial warren
#

yeah

#

oh also, actual programming question, lemme just bring up what I mean so I can try and explain this

#

for whatever reason, if I use that, the folder generates in the root directory, not in the plugins folder

old wyvern
#

"/plugins/"

#

Remove the first /

prisma wave
#

imagine not using .resolve

#

๐Ÿ˜ฌ

old wyvern
#

wait no

#

hmm

jovial warren
#

resolve instead of walk?

prisma wave
#

no

#

instead of file constructor

jovial warren
#

didn't know that existed lol

quiet depot
#

o wait

jovial warren
#

wait so what's the function?

quiet depot
#

use a util from nio files

#

or if this "resolve" thing is a better alternative in kotlin, use that

prisma wave
#

they do the same thing

jovial warren
#

walk is basically the Kotlin equivalent of Files.walk

quiet depot
#

idek know what that does

prisma wave
#

walks over a directory

jovial warren
#

^

#

basically collects everything inside of a directory into a sequence

quiet depot
#

ah that clears it up

#

yugi the jdk is the default one

old wyvern
#

piggy

quiet depot
#

no need to explicitly declare it

old wyvern
#

ah

#

Anyway

#

Cna you make it not delete the msg it if fails

#

Or atleast delay the deletion

jovial warren
#

what message?

quiet depot
#

make an issue pls

jovial warren
#

oh right lol

old wyvern
#

Alright

quiet depot
#

I'm super busy with school work atm, haven't been able to open the ide in weeks

old wyvern
#

I see

quiet depot
#

and when I do get a little free time

prisma wave
#

im gonna be extremely petty here and just say "collecting into a sequence" doesnt make sense

quiet depot
#

don't usually spend it on coding

old wyvern
#

Shall I fork and PR then?

quiet depot
#

sure

#

yes pls

old wyvern
#

Alrighty ๐Ÿ‘

quiet depot
#

make sure to test it though

old wyvern
#

Sure

quiet depot
#

sorry it's a little bit of a hassle if you don't already have an environment setup

#

you need mysql

jovial warren
old wyvern
#

Yea, I do have mysql

jovial warren
#

where is it?

quiet depot
#

when you first run the bot it'll make a config and shit

#

populate it with db details

prisma wave
old wyvern
#

Ah alright

quiet depot
#

it'll create the schematic, u just need to create a db and user

jovial warren
old wyvern
#

Wait is it going to index everything? xD

quiet depot
#

no

prisma wave
old wyvern
#

phew

#

Alright

quiet depot
#

ur only modifying the bot right?

old wyvern
#

Yes

#

Oh those are separate

quiet depot
#

you can just use the public docdex instance then

old wyvern
#

yea nvm

#

Alright

quiet depot
#

just make sure that link is in the bot config

jovial warren
old wyvern
quiet depot
#

even if it did index everything it'd only fry your cpu for a couple mins

#

assuming it wasn't a potato

#

no biggie

old wyvern
#

It aint a potato, but internet tho

quiet depot
#

it doesn't index remotely

old wyvern
#

wdym?

#

oh it comes with it

#

I see

quiet depot
#

it'd either
i) crash
ii) take a really long time
iii) get you banned from the site, or by your isp, for an attempted dos attack

jovial warren
#

@prisma wave oh right, ik where you want this now

quiet depot
#

so it can realistically only index local javadocs

old wyvern
#

I might get flagged by my isp but the other cases shouldnt happen I assume

quiet depot
#

anyway none of that matters since you're only running the bot

old wyvern
#

Yup

jovial warren
quiet depot
#

i'll consider switching on my next project

jovial warren
#

for those who can't be assed to read, basically, Log4j should not be used by anyone ever again ever, Logback is nice and better than Log4j but it has a few flaws, and Log4j2 is the best out of the three that improves on both

prisma wave
#

elara/logging outdoes them all

jovial warren
#

I second this notion

#

well, it will

quiet depot
#

would elara/logging be a package for elara's package manager?

prisma wave
#

probably

jovial warren
#

indeed

stuck harbor
#

elara/dotnet hmmm?

prisma wave
#

maybe in stdlib

quiet depot
#

u should start using random symbols in elara package manager

#

instead of using / in packages

#

elaraยถlogging

jovial warren
#

when Elara is at least functional enough to do things, I'll start making the package manager

quiet depot
#

makes perfect sense

stuck harbor
#

elaraรŸlogging

jovial warren
#

lol

prisma wave
#

speaking of

#

we are reworking elara to be purely functional

#

ez

onyx loom
#

lol

stuck harbor
#

mmmm

jovial warren
#

I swear it already is purely functional

prisma wave
#

not purely

stuck harbor
#

but wheres the data oriented?

#

no love for data oriented programming

#

sadge

quiet depot
#

I thought data oriented was basically exclusively used for games

stuck harbor
#

๐Ÿ‘€

jovial warren
#

oh btw, as you're here Piggy, you wanna see how I got plugin loading to work in the end?

onyx loom
#

well yes, elara/game has u covered

quiet depot
#

sure

jovial warren
stuck harbor
#

when I see ::
is this a c?

jovial warren
quiet depot
#

loading was never the hard part?

jovial warren
#

yeah it wasn't lol

quiet depot
#

it's just everything after loading

prisma wave
jovial warren
#

it was way easier than I thought

#

oh btw Piggy, you might be able to answer this

#

if I load the main class and that class calls constructors of other classes, those will be auto-loaded right?

#

actually I think I've already answered this myself but whatever lol

prisma wave
#

monads in elara ๐Ÿ˜ƒ

jovial warren
#

oh btw, wdym by all the stuff that comes after loading?

quiet depot
#

d;urlclassloader

ruby craterBOT
#
public class URLClassLoader
extends SecureClassLoader
implements Closeable```
URLClassLoader has 1 extensions, 1 implementations, 11 methods, 2 all implementations, and  1 sub classes.
Description:

This class loader is used to load classes and resources from a search path of URLs referring to both JAR files and directories. Any jar: scheme URL (see JarURLConnection) is assumed to refer to a JAR file. Any file: scheme URL that ends with a '/' is assumed to refer to a directory. Otherwise, the URL is assumed to refer to a JAR file which will be opened as needed.

This class loader supports the loading of classes and resources from the contents of a multi-release JAR file that is referred to by a given URL.

The AccessControlContext of the thread that created the instance of URLClassLoader will be used when subsequently loading classes and resources.

The classes that are loaded are by default granted permission only to access the URLs specified when the URLClassLoader was created.

quiet depot
jovial warren
quiet depot
#

you need to ensure there aren't any references to any of the classes of that plugin

jovial warren
#

reloading is a no go for the moment, as I really don't want whatever kinda hacks we explained the other day to haunt me in my nightmares lol

quiet depot
#

then close its classlader

#

god my o key is just not working today

jovial warren
#

so if it's stored in a set that counts as a reference right?

quiet depot
#

yep

jovial warren
#

so I remove it from the set and then bam

quiet depot
#

nope

#

well

jovial warren
#

well, I remove it from the set and close the loader

quiet depot
#

if it's only reference is in the set then yes

#

in an ideal world that's it

#

the garbage collector will come along and send it to purgatory

jovial warren
#

do I need to do anything when the server is shut down btw?

#

or will the GC yeet the classes for me anyway

quiet depot
#

they'll be yeeted

jovial warren
#

so you're only talking about unloading the plugin whilst the server is still running then, right?

quiet depot
#

yes

jovial warren
#

yeah I ain't doing that yet

#

no chance

quiet depot
#

how does .class in java work?

#

e.g.

#
System.class```
#

is class a static variable generated at compile?

obtuse gale
#

Compile time yes

quiet depot
#

is it a static field?

obtuse gale
#

Uh

quiet depot
#

just thinking

#

imagine changing a classes class via unsafe lol

#

if System.class returned Class<String>

obtuse gale
#

I mean 80% of Java is runtime reflection anyway lmao I wouldn't be surprised if that was too

obtuse gale
quiet depot
#

only if it's a field

obtuse gale
#

Well it's gotta be somewhere lmao

quiet depot
#

yeah but I don't see a method in unsafe which allows you to find the address of anything that isn't a field

ocean quartz
#

Lol request paid is great, "Advanced java programmer" budget $5-$10

obtuse gale
#

I can make an advanced Hello World for that

jovial warren
#

actually that's excluded isn't it

#

mainly because loads of articles cropped up about why it was dumb for Oracle to remove it lol

quiet depot
#

yeah been doing some research I don't think what I originally described is possible

#

I'm gonna keep researching this

#

I refuse to believe that reliably unloading classes is simply impossible

jovial warren
#

okay wtf ```
Exception in thread "DefaultDispatcher-worker-1" java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.io.FilesKt__UtilsKt.resolve, parameter $this$resolve
at kotlin.io.FilesKt__UtilsKt.resolve(Utils.kt)
at org.kryptonmc.krypton.plugin.KryptonPluginManager.load(KryptonPluginManager.kt:45)
at org.kryptonmc.krypton.plugin.KryptonPluginManager.<init>(KryptonPluginManager.kt:24)
at org.kryptonmc.krypton.KryptonServer$start$1$1.invokeSuspend(KryptonServer.kt:96)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)

#

the parameter given to resolve is non null

#

that error is literally impossible

onyx loom
#

๐ŸŒš

jovial warren
#

@prisma wave was your idea to use resolve, any ideas?

#

val dataFolder = pluginsFolder.resolve(description.name) this throws an NPE

jovial warren
#

oh btw, also, is there a way I can use centralised versioning that I can access in code?

#

e.g. I have Krypton's version exposed to the API in the KryptonServerInfo object, but hard coding this value means I have to remember to update it on every release

#

is there a way I can just use gradle.properties or something to have Gradle able to read and use the version and also have it readable in code?

obtuse gale
#

do how spigot does it and relocate the entire package just to add the version to it

#

you'll always carry the version in every class name that way ๐Ÿ‘

jovial warren
#

that's not what Spigot does

#

Bukkit uses pom.properties in META-INF to get the actual Bukkit version

obtuse gale
#

sure, it definitely doesn't relocate org.bukkit.craftbukkit.Whatever to org.bukkit.craftbukkit.{nms}.Whatever

jovial warren
#

idm updating the server version manually, since that's only in code

#

it's just the actual project version

obtuse gale
#

it was sarcasm bardy because spigot is utter shit

jovial warren
#

ah

#

maybe Gradle has a way to generate a pom.properties

errant geyser
jovial warren
#

wdym?

errant geyser
#

In an old Spring project I had the version info pulled from the build.gradle using something Gradle has, I'll see if I still have it somewhere

#

It's part of Spring Boot, nvm

#
springBoot {
    buildInfo()
}```
Then I could use `BuildProperties.version`
jovial warren
#

I could use Gradle to generate a krypton.properties file in META-INF or something and then read that at runtime

errant geyser
#

Seems like the better way to do it

#

Unless you make a publicly accessible text file somewhere that you update that contains the version info that you download and read at runtime....
But that's horrible.

jovial warren
#

that's not what I want either

#

I want to read Gradle build properties and write them to a file

#

I swear I'm gonna just add it to the manifest in a minute lol

#

there seems to be nothing on the net about how to do something like this

errant geyser
#

How does Wolfram do stuff so quickly

#

I was writing a crappy Go program to find the factors of a number. It took like 20 minutes to complete for 600851475143 and Wolfram did it in about 6 seconds wtf

prisma wave
#

Really good optimisations

#

Probably parallel computation too

#

And caching a lot of shit

jovial warren
#

ah, BM, can you help me?

#

you know Gradle better than I do

paper kite
#

hey, you all

#

I'm trying to make a plugin that randomly eliminates all the blocks in a column x,z of the world, close to a player

#
//x and z are the coords x and z close to the player, and y is the coord y of the player
 for (int i = (int)y; i < -1; i--) {
                Location block_location = new Location(world, x, i, z);
                Block block = block_location.getBlock();
                block.setType(Material.AIR);
            }
#

I tried to do this, but java is giving me an warning

#

"Loop executes 0 or one billion times"

stuck harbor
#

idk but can you cast y to an int?

paper kite
#

I actually don't know, good question

stuck harbor
#

also, less than -1

#

and u do i--

paper kite
#

yeah, bedrock is usually at y = 0

oblique heath
#

should be greater than -1 ^

paper kite
#

oh

#

wait

stuck harbor
#

yeah

paper kite
#

you are right

#

miss typed

stuck harbor
#

if i starts below one, then it will be infinite

paper kite
#

aaaaand the warning is gone

#

thank you!

#

I think you can cast from int to double, since double has a bigger storage

#

not sure, though

jovial warren
#

and should probably be >= 0 instead of > -1

paper kite
#

oh

jovial warren
#

also, beware of the fact that the bedrock level will change in 1.17

paper kite
#

yeah, yeah

oblique heath
#

=0 does the same thing as > -1 if it's an int

jovial warren
#

yeah ik, just a bit cleaner imo

paper kite
#

but why should I change > -1 to >= 0?

oblique heath
#

i suppose

paper kite
#

oh

#

all right

#

I think It makes sense

#

all right, I think It's done. I'll test it

#

btw, this is how I did It

#
@Override
    public void run() {
        System.out.println("Task has been run");
        player_list = Bukkit.getOnlinePlayers();
        for (Player p : player_list) {
            Location loc = p.getLocation();
            double x = loc.getX();
            double y = loc.getY();
            double z = loc.getZ();
            World world = loc.getWorld();
            x += rand.nextInt(11) - 5;
            //y -= rand.nextInt(2) + 1;
            z += rand.nextInt(11) - 5;
            for (int i = (int)y; i >= 0; i--) {
                Location block_location = new Location(world, x, i, z);
                Block block = block_location.getBlock();
                block.setType(Material.AIR);
            }
            //p.sendMessage("Bloco em " + x + " " + y + " " + z + " foi removido");
        }
    }