#help-development

1 messages · Page 866 of 1

tender shard
#

but overall it's really much better than java

eternal night
#

the language is perfect kekwhyper

river oracle
#

I am learning kotlin

shadow night
#

Everybody here knows some kotlin lol

young knoll
#

Apparently learning faster than Alex

river oracle
young knoll
#

Gottem

viral temple
eternal night
#

I mean, some of the syntax is fucking cursed xD

shadow night
eternal night
#

true

tender shard
river oracle
#

I'm not smart I just use google

viral temple
#

Let's make a new language that combines some good shit from java and some good shit from kotlin and call it a day

river oracle
tender shard
#

because baboons invented them!

river oracle
#

its annoying, but whatevs

young knoll
#

Can we combine good shit from other languages too

shadow night
tender shard
#

can't we just... combine the bad things of all languages and combinethem into one?

#

oh nvm php already did that

shadow night
#

Lmao

eternal night
#

I mean, stuff like return@ is a bit funky

shadow night
#

Poor php

tender shard
eternal night
#

Yea the functionality is great

#

the syntax is fucking cursed

shadow night
#

Ł

young knoll
#

return@ what

#

return@young knoll

river oracle
eternal night
#
fun foo() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return
        print(it)
    }
    println("hi there")
}
#

do you think hi there prints

young knoll
#

Uhhh

river oracle
#

spoiler it doesn't

eternal night
#

spoiler it doesn't

young knoll
#

Imma guess no

eternal night
#

LOL

tender shard
eternal night
#

well, its a lable they need because their lambda syntax for last param just

#

does a LOT

tender shard
young knoll
#

I see

shadow night
young knoll
#

Kotlin says no

eternal night
#

for you'd have to instead do

fun foo() {
 listOf(1).forEach {
   return@forEach
 }
 print("hi")
}
#

like this works again

#

and its just fucking cancer xD

#

especially when this goes nested

#

and then you get absolutely wild syntax if you need to return a value

#

e.g. retuirn@lable obj

#

which just

#

bleach my eyes

slender elbow
#

omw

shadow night
#

Can I please just use java

young knoll
#

Sure

eternal night
viral temple
eternal night
#

it has great shit, I long for their delegation syntax

young knoll
#

Stop edating

#

Smh

viral temple
#

Saves you 1 year of your life

#

Or more, if you are me.

tender shard
#

i want to get a cake on my birthday and somebody of you people here will be responsible for it

young knoll
#

Not it

tender shard
shadow night
#

It looks cursed to me in general

tender shard
#

in IJ the the colors at least match a bit lol

eternal night
#

Yea I mean, syntax highlight makes it a bit better

#

but yea

#

cursed as fuck syntax

tender shard
#

now this is cursed

eternal night
#

no

#

you are missing a return

#

use like, a Function or something

tender shard
#

i wish kotlin would allow running code in constructors before calling super

#

and java should allow that too ofc

young knoll
#

Isn’t that planned

river oracle
#

planned for javA

#

not kotlang

tender shard
#

stupid java default methods don't contain proper javadocs

#

where's the @params

#

oh wait, that one is private

#

why can't i just pass in a file object into a FileNotFoundException D:

#

how annoying

#

btw here's another nice kotlin feature: singletons using object

#

that's basically this

#

but one can access it just using ModuleJarFileFilter as if it were an object

#

wasnt it somehow possible to unregister all listeners belonging to a class?

sullen marlin
#

yeah HandlerList or somewhere

tender shard
#

aight thx

#

that's great, then I keep track of all listeners a module has registered in my AbstractModule class and then auto-unregister them

#

it feels like I'm writing a plugin api for spigot haha

tender shard
#

RIP I spent 20 minutes finding out why my regex inventoryholder detection isn't working, even though the console said it worked. I was like "hmmm there must be another event that still sorts the inventory". Then I looked at my code again:

#

F

river oracle
#

you know java 21 has enhanced EMOJI support!

#

finally we can return 😈

minor junco
#

Regex 😭

tender shard
#

regex are great! Instead of having to add support for 29 different plugins, I can just people to fucking edit their config lol

river oracle
#

think if plugins actually propery implemented menu's too you wouldn't even have to do this!

tender shard
#

usually I always told people that it's the other plugin's jobs to hook into chestsort

#

but I think this regex list is by far the easiest option

#

also who knew this?

#

i wonder which other "tempaltes" github has for markdown

#

can normal java classes also be referenced as KClass in kotlin?

#

Or do I hve to use the regular java.lang.Class class for java classes?

slender elbow
#

nah, Whatever::class will always give a kclass

tender shard
#

I'm using Class.forName(...)

slender elbow
#

there's probably some extension method for j.l.Class to convert to kclass

eternal night
#

something something ClassMappingKT

#

or I think yea

#

extension method probably

#

indeed

tender shard
#

ah great

#

thx

#

then my ModuleJarClassLoader can return a proper KClass instead of a stupid boring Class :3

young knoll
#

How much Kotlin adoption would it take for spigot to shade the std lib :p

eternal night
#

the library loader already shares that stuff right ?

young knoll
#

Well yeah

eternal night
#

Yea

#

sounds like the way better way to do this kekwhyper

young knoll
#

But we shade SQLite and MySQL drivers!

eternal night
#

who knows why tbf

#

cancerous

young knoll
#

Oof

tender shard
#

spigot's library feature is stupid

#

because it only supports central

#

why can't it just support giving custom repos too

#
libraries:
  - id: com.jeff-media:custom-block-data:1.0.2
    repo: https://repo.jeff-media.com/public
young knoll
#

Because then optic and his scanning would cry

#

:p

tender shard
#

well then one just downloads the file via code?

young knoll
#

His poor hard drive

eternal night
#

Yea I mean

tender shard
#

being able to use the library feature would be nice as one wouldn't have to rewrite stuff like caching, updating snapshots, etc etc (if it even supports snapshots, idk)

eternal night
#

it is kinda a bit weird

young knoll
#

Yes I know if it’s shaded it would be on his hard drive anyway

river oracle
#

I mean the thing is what stops a plugin from using libby

eternal night
#

its another attack vector that isn't too cool

river oracle
#

which is legit just the library feature

young knoll
#

Well Libby has to do some runtime hacking

#

But yeah

river oracle
young knoll
#

For now

eternal night
#

Like, preferably we just add checksum to third party libs

#

and gg wp

tender shard
eternal night
#

Yea but I mean, that also isn't good practice

#

at least imo

river oracle
#

I doubt a malicious plugin cares for best practices lol

young knoll
#

You also need to inject said downloaded bytes

#

But yeah

eternal night
#

Well no, I am not saying you are downloading a malicious plugin

#

I am saying you download a plugin that uses library loader correctly

#

they link their repo

tender shard
eternal night
#

their repo password is mfnalex and password123

#

some fucker gets in

#

starts replacing their release builds with malicious BS

#

the plugin isn't malicious

tender shard
#

the same thing could happen if my plugins downloads something from my repo manually using java

eternal night
#

the author never intended it to be

#

which is again why I don#t think you downloading things at runtime is a good practice unless you validate that its the correct shit you are getting

tender shard
#

well spigot could ofc also raise the upload limit

eternal night
#

I mean, downloading isn't the issue.

tender shard
#

or people should learn how to upload their stuff to central, I'm tired of seeing jitpack all day lol

eternal night
#

The issue is validating that what you get is what you expected

tender shard
#

well then libraries.yml could also contain a hashsum

eternal night
#

supply chain attacks aren't anything new, andthey are getting a more common attack vector by the day lol

#

yea

#

thats what I suggested above

tender shard
#
libraries:
  - id: com.jeff-media:custom-block-data:1.0.2
    repo: https://repo.jeff-media.com/public
    sha256: awfiugfwa2972<whatever>
young knoll
#

I don’t think I’ve ever come close to the upload limit tbh

eternal night
#

I mean, there is a reason every competent developer like, pins their docker base image to a checksum

slender elbow
#

you've never heard of kchat?

#

best 80 mb chat plugin

young knoll
eternal night
#

mining your crypto takes some space

#

thanks

tender shard
young knoll
#

How much of that is Kotlin Stalin

#

No

eternal night
young knoll
#

Kotlin stdlib

slender elbow
#

bro

tender shard
eternal night
tender shard
#

stalin is about 4.7 mb

eternal night
#

LMAO

young knoll
#

You can libraries that can’t ya

#

Just sayin

tender shard
#

(that's without minimize() though)

#

let's check stalin with minimize()

river oracle
#

So not really

young knoll
#

Wut

river oracle
#

You kinda have to shade

eternal night
#

oh right

tender shard
#

with minimizing, stalin is down to less than 1mb

eternal night
#

spigot classloaders are a fucking mess

#

right

tender shard
eternal night
#

tho I think like, the library loader is consulted before asking the global plugin classloader

young knoll
#

I believe so

eternal night
#

so should be fine ™️

tender shard
#

the classloader is fine, I looked at it yesterday

#

what's wrong with it?

eternal night
#

I mean

#

its not isolated

#

while it checks in order

tender shard
#

yeah it is obviously not as glorious and great as my custom classloader cough

eternal night
#

it falls back to the giant "whatever the fuck I can find in plugins"

young knoll
#

I mean

tender shard
eternal night
#

yes

tender shard
#

and paper also killed the opportunity to use softdepend properly

young knoll
#

Is it not better to take the shot in the dark than just go /shrug idk good luck

eternal night
#

Well no because taking the shot in the dark might mean you load something you don't wanna load

tender shard
#

if two plugins softdepend on each other, paper fails to load them, doesnt it?

young knoll
#

The alternative is nothing though

eternal night
#

well gg

#

cyclic dependencies

tender shard
#

they are not dependent on each other

eternal night
#

aight

tender shard
#

they only "softdepend" on each other to avoid the warning in console

eternal night
#

ehm

#

okay

young knoll
#

I love seeing paper-help posts with like a 10 plugin dependency loop

eternal night
#

let me boil that down

#

plugin A soft depends on plugin B and does logic A1 if plugin B exists onEnable, otherwise A2

#

plugin B softdepends on plugin A and does logic B2 if plugin A exists onEnable otherwise B2

#

if both plugins exists, one has to be loaded first

#

which one is it

tender shard
#

the classloader should accept plugins loading classes from other plugins without complaining, then softdepend can continue to fail for cycling dependencies.

or the plugin manager should not fail for cyclic dependencies, which makes little sense for softdepend as it literally means "the other plugin is not required anyway", so why fail if they both softdepend each other?

eternal night
#

this has nothing to do with classloader

#

like, literally 0

tender shard
#

it has. people add all plugins they use classes from to their softdepend

eternal night
#

you can share a classloader no issue

#

but that is not what softdepends promises

#

soft depends promises that you enable after the soft dependency if its available

tender shard
eternal night
#

Yea

#

exactly

#

aRbiTrArilY

#

ggwp

tender shard
#

loaded arbitrarily != just failing

eternal night
#

it is literally worse than failing

tender shard
#

no it's not

eternal night
#

I-

#

your skull sometimes is rather thick

#

This like, might depend on the file system

#

might depend on the jar name

tender shard
#

if two plugins depend on each other, then ofc it shall fail. if they only softdepend on each other, then what's the issue with simply loading one of them first? after all both plugins would also have loaded if the other one weren't there?

eternal night
#

this might change by literally just changing the jar file name

#

because the behaviour can change for 0 apparent reason for the end user

tender shard
eternal night
#

the alternative is to properly split apart the concept of a load before and load after

#

and a shared classloader

young knoll
#

Simply load them at the exact same moment

#

Little bit of quantum computing

eternal night
#

✨ async startup ™️ ✨

young knoll
#

What are we, forge?

eternal night
#

we hope to be

young knoll
#

Oh

tender shard
slender elbow
young knoll
#

So who’s writing the coremod system that uses js

#

Oh wait no one uses that anymore

eternal night
#

sounds like you should be using spigot then

tender shard
#

lol ofc

#

I'm always using spigot

eternal night
#

yea so gg, stop complaining xD

#

its a dumb design

#

needs fixing

young knoll
#

I thought about redoing the spigot loader

eternal night
#

idk why it was never touched tbh

tender shard
#

then fix it i nyour paper-plugin.yml and stop messing with bukkit's version

eternal night
#

nah

#

thats boring

young knoll
#

Then I thought about how to correctly resolve dependency chains and my brain hurted a bit

eternal night
#

we do offer a flag too btw

#

to actually go back to spigots global classloader

slender elbow
#

bukkit's behaviour was left untouched, paper-plugins loading needs not to follow the same rules

eternal night
#

Well now it is untouched xD

#

initially it wasn't lol

tender shard
#

also it does not need fixing. it would be nice to add a loadafter but that does not mean that softdepend is broken. It says "softdepend = required to have full functionality" and that it's loaded after these plugins, if possible

#

nothing broken with that all

eternal night
#

again

tender shard
#

it's only broken if one considers this to be a loadafter

#

which it never promised to be

eternal night
#

arbitrary anything is fucking dumb

young knoll
#

Alright new plan

#

No dependency system

eternal night
#

smart

young knoll
#

Done

tender shard
eternal night
#

by their dependecy tree ?

tender shard
#

what if I got two plugins

#

no dependencies

eternal night
#

mhm

slender elbow
#

so, you are pointing out the thing to fix: load order and dependency are two separate concepts

tender shard
#

which one is loaded first

#

A.jar or B.jar

#

do you just use the result of listFiles?

#

because that's arbitrary

eternal night
#

Yea, no depdencies exist, plugin loading can be done in alphabetical order

tender shard
#

can be done or is done?

eternal night
#

I believe it should be ?

tender shard
#

pretty sure it just loops over listFiles

eternal night
#

not that it matters, the plugins do not declare a depdency

young knoll
#

By jar name or plugin.yml name

eternal night
#

¯_(ツ)_/¯

young knoll
#

:p

tender shard
young knoll
#

What if we go the other way

eternal night
#

let me revise it then

#

so you can be happy

young knoll
#

Load plugins in a random order every startup

tender shard
#

TL;DR not loading a plugin because they have themselves as "OPTIONAL" dependencies makes 0 sense

eternal night
#

again

#

the fact that my plugin execution logic can change because of arbitrary reasons is the issue

#

if two plugins remain isolated, they can load in whatever order they want

tender shard
#

but that is not the case?

eternal night
tender shard
tender shard
#

as they're obviously all loaded at once, and only after that get enabled

river oracle
#

Why are 2 plugins soft depending on eachother

#

Sounds like L development moment

tender shard
#

and plugins will obviously check getPlugin(...) != null and not otherPlugin.isEnabled

#

and getPlugin will obv return notnull even for disabled plugins

eternal night
#

mhm yea sure plugins will only do that

#

tbf, even fucking worse

#

What if plugin A expects B to be in a specific state

#

and B expects A to be

tender shard
#

the current solution to be able to support paper is to simply not use softdepend at all

eternal night
#

or just use the flag

slender elbow
#

or properly design your plugins

eternal night
#

or that

#

and don't have a mystical cyclic dependency

tender shard
#

How is that bad design lmao

river oracle
#

I'm still confused on in what natural reasonable way a dependency loop would happen why is this a problem? Are developers too stupid to not have cyclic dependencies

eternal night
#

A cyclic dependency is literally just bad design

slender elbow
eternal night
#

like

young knoll
#

You’d be surprised

eternal night
#

this is not something you can remotely argue

young knoll
#

Often its long loops and who knows where the blame falls

#

I guess technically to all of them but yeah

tender shard
#

it's a "nice to have", not a "required to have"

eternal night
#

it is a dependency the second said plugin exists on the server

#

a full dependency

tender shard
#

no

#

just read the docs

eternal night
#

it is treated as such

slender elbow
#

we are not arguing the definition of softdepend

eternal night
#

idc about the docs

#

i care about how it WORKS

slender elbow
#

you are avoiding the fact that there is a cyclic dependency

tender shard
#

if you don't care about the docs, then there's no point talking about it at all. You simply claim that your definitino of softdepend is the only correct one, completely ignoring what the official docs as pe the wiki is, and then you claim that it should behave differently. If you would just stick to the definition from the wiki, there'd be no issue

river oracle
#

Are we just gonna ignore that no matter what you do any form of cyclic depenendencies will just break shit

eternal night
#

it isn't about a definition

slender elbow
#

my brother in christ

eternal night
#

you can publically define soft depends to whatever the fuck you want

river oracle
eternal night
#

when it RUNS it is a cyclic dependncy

tender shard
#

but if you absichtlich ignore the official definition of softdepend, then what's the point of talking about this in the first place? This discussion is pointless if you just make up random definitions for things that are officially defined as sth else

eternal night
#

?????????????

slender elbow
#

are you even reading?

#

hello??????

tender shard
eternal night
#

no

#

it fucking can't

tender shard
eternal night
#

it cheeses out with an "oh but shit might just be abitrary"

#

that is not a definition

full laurel
#

🍿

eternal night
#

that is a "fuck, concept is flawed, lets put it there"

river oracle
tender shard
#

cyclic dependency = both need each other. softdepend does not say "need each other" but only "gives additional features if other plugin is also there"

eternal night
#

i

tender shard
#

so your whole idea of saying softdepend between two plugins is a cyclic dependency is already wrong

eternal night
#

okay 👍

tender shard
#

if two plugins would have each other as depend, then obv it's a cyclic dependency

eternal night
#

okay 👍

tender shard
#

glad that you understand it now

eternal night
#

okay 👍

sterile token
young knoll
#

Alright I’m sick of this

#

New plugin loader

eternal night
young knoll
#

Does not load plugins

#

The end

eternal night
#

mixins

#

das the solution

#

who needs dependencies when you can just fuck with the internals

river oracle
#

The real solution is nuking everyone and going raw on nms

eternal night
#

perfect

young knoll
#

Raw dog the NMS

eternal night
#

call it rawgot

#

and bam

young knoll
#

Maybe I’ll look in to redoing the plugin loader one day

#

Partially because I want registry api :(

river oracle
#

Please

eternal night
#

tbf, the new enchantment tag stuff looks promising

#

I wonder how many more releases we get

river oracle
#

It does

eternal night
#

till enchantment reg is synced

tender shard
# eternal night okay 👍

Just to summarize again. The name "softdepend" is misleading, as it's not meant to describe things actually "depending" on each other. a better name would be "profits-from" or sth.

eternal night
#

idc, please just drop it

tender shard
#

k

eternal night
#

thanks 👍

tender shard
#

chrome should have an option to have a second line for tabs

eternal night
#

do you at least have the plugin to like

#

sleep tabs youi don't use

inner mulch
#

does somebody know how i get the full amount exp points a player has, the methods that im aware of (player.getExp && player.getExpToLevels) arent useful in this case

slender elbow
#

that's nothing

tender shard
eternal night
kind hatch
eternal night
slender elbow
#

thx

kind hatch
eternal night
#

no problem

#

🥷

tender shard
kind hatch
#

My internet slow. D:

eternal night
tender shard
#

yk what's weird, on my PC i only get ~400mbit but on my macbook throgh WIFI I get over 1 gbit

#

how the hell can that happen

#

it's a CAT7 cable and my ethernet card says 1gbit

#

and another computer that's also connected through LAN does get 1gbit

kind hatch
#

Difference in drivers more than likely

tender shard
#
tasks.shadowJar {
  minimize {
    include(libs.kotlin.stdlib)
  }
}

If I do this but I also depend on another dependency that also depends on stdlib, does shadow still minimize stdlib or not?

#

@river oracle our classloaders are currently cmopletely independent, do you think we'd ever need to allow a module to access another module's classes? and if yes, I guess we should probably add some kind of interface registration system instead of just arbitrarily loading classes from the other classloaders?

young knoll
#

That’s so many tabs wtf

tender shard
#

unused ram is wasted ram

young knoll
#

How often do you actually go back to some of them

tender shard
#

sometimes

young knoll
#

I get like

#

Cold sweats when I have 10 tabs open

tender shard
#

on mac it's even easier, just do cmd+space

#

i think I'll get an m3 imac when I move to my new place

#

wtf imac only goes up to 24GB RAM?!

#

guess I'll not be getting an imac then

river oracle
#

the point of the modules is the independence as soon as we have modules depending on other modules thing will go to shit everything that needs to be a core dependency should go in core

young knoll
#

What about third party stuff

river oracle
#

if you don't like the configurations of a default module you can always replace it type deal

young knoll
#

Mmm just thinking of a case where a module wants to be an addon to another module

tender shard
#

ocelots and cats don't share a common super class? 😮

river oracle
#

we could do that, but i'd take the stance of only allowing hard dependencies

tender shard
river oracle
#

again i'd be hard against something like soft-depend or something

tender shard
#

shouldn't be hard, we'll just create another classloader that combines the two existing ones

river oracle
#

if you wanna extend something depend is good enough further than that replace the dependency

tender shard
#
classpath:
- basics:tpa

e.g. this would then allow to access all classes from the builtin tpa module

#

it will however not check if that module is actually running or anything. It's only purpose would be to add those classes to the modules classloader?

river oracle
#

meh I'd be inclined to have depend but only hard depend. Any circular dependencies just turn off the modules and say circular dependencies etc

#

the modules themselves should tend to be small features etc so we really shouldn't need to ball out on an advanced loading system that accounts for a lot of logic

tender shard
#

yes I fully agree that it shouldn't be needed anyway

#

but if we ever had to add sth like this, I would opt for a simple list of modules which classes one wants to access and those will get added to the classloader then

#

hm I wonder, if I got a classloader, I can ofc set a parent classloader.

But let's imagine I got two classloaders, both are URLClassloaders:

A.jar and B.jar

Now I want to have a classloader that combines both - would I just create a new ClassLoader from scratch that just delegates findClass(...) to both, and returns whatever of the underlying classloaders returns for findClass?

#

or is there a better way?

#

@worldly ingot you might know more about this maybe?

#

sry for ping

#

otherwise I'll have to ping geol

worldly ingot
#

No clue. Not done much class loading, personally

river oracle
#

I'm going to load your class into Wisconsin if you're not careful

tender shard
young knoll
#

Chichi makes other people load his classes

#

Wtf is chichi

#

Choco

tender shard
river oracle
#

And culvers

tender shard
#

oh btw we still need to figure one thing out:

#

I'll give an example

#
@CommandAlias("test")
@CommandPermission("test")
class Hello{
  @SubCommand("hello")
  fun hello(p: Player) { p.sendMessage("hello") }
}

// in another class:
@CommandAlias("test")
class World{
  @SubCommand("world")
  fun world(p: Player) { p.sendMessage("world") }
}

Both commands are "test", but only the first one has CommandPermission set. I know that declaring subcommands like this works fine, but I wonder if now /test world also requires the test permission

#

if someone is bored, maybe try it out? I'm again rewriting the module loading logic rn because I'm still unhappy with how it was split up between plugin and core

#

also I'll make it much easier and more straightforward

river oracle
#

that's what ACF example insinuated

tender shard
#

you mean it would require the perms for both commands, or only require them for what's in Hello?

river oracle
#

perm would be required in both

tender shard
#

i mean, we could easily test it out, but I'm currently on my branch that doesn't have working module loading logic lol

tender shard
#

I don't know whether I like this, or not

river oracle
#

you should otherwise it'd be inconsistent

#

for eample test hello requires test perm so should test world

#

they are both a subset of "test"

tender shard
#

true

#

yeah anyway, both possibilities wouldnt be an issue as one usually declares perms per subcommand anyway, and the main command would simply show a help message with @foggy boughssage and @Default

#

oh hello HelpMe

#

btw we can enable per player locales and automatic help generation in ACF but I currently dont remember how

river oracle
#

That's later problem xD

young knoll
#

Can also try their brig support

river oracle
#

It's old asf with no updates I doubt it'll work well

#

Could try but like skull emoji

young knoll
#

😩

tender shard
#

java plebs be like: "oh nooo, I have to print out a file, it's so annoying, uuugh D:"

public class FileReadingJava {
    public static void main(String[] args) {
        try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }
}

kotlin superiors be like: ok

fun main() {
    File("example.txt").forEachLine { println(it) }
}
young knoll
#

Smh how far he has fallen

#

:p

tender shard
#

optic destroyed me

river oracle
#

Java nio >>>>>

young knoll
#

Take that Kotlin

#

Clearly all the best basics modules will be in java

river oracle
#

Lol

#

Don't think it's gonna be possible cuz the interfaces have fields

paper viper
#

Who even uses normal io these days 🤮

#

The nio channels are also so good uwu

young knoll
#

The what have fields

#

That’s illegal

noble lantern
tender shard
noble lantern
#

gradle is giga_chad though

tender shard
#

especialy buildSrc

noble lantern
#

im still drag and dropping in 2024 pigcry

young knoll
#

Gotta be real gigachad and force a reload command

tender shard
#

it will automatically depend on shadowJar because it uses its outputs

#

if you don't use shadow, just replace the from part to use tasks.jar instead of tasks.shadowJar

noble lantern
#

or only local files

#

always assumed that was strictly local

young knoll
#

You can make winscp sync a directory

noble lantern
#

ooo not a bad idea

tender shard
#

if you got an SSH key setup that doesn't require a passkey, I'm sure you could just create an URI like ssh://user@server:/home/minecraft/ and turn that into a file or sth?

#

but I'm not sure

#

i mean it's 100% possible, the qeustion is just whether it's one line or 7

#

in the worst case you'd just have to throw it into scp

#

I also hereby wanna publicly apologize and admit i was ignorant earlier: gradle is superior to maven and kotlin is superior to java

young knoll
#

Blink twice if you are being forced to say this

tender shard
#

kek

tender shard
#

oh wait, their solution is horrible

#

I'll write a blog post about how to properly do it tomorrow. it's much easier than creating random ant tasks

#

for example with the SSH plugin: https://gradle-ssh-plugin.github.io/

but instead of using from: "filename.jar" I'd rather use an output of an existing task, e.g.

plugins {
  id 'org.hidetake.ssh' version 'x.y.z'
}

remotes {
  webServer {
    host = '192.168.1.101'
    user = 'jenkins'
    identity = file('id_rsa')
  }
}

task deploy {
  doLast {
    ssh.run {
      session(remotes.webServer) {
        put from: tasks.shadowJar.archiveFile, into: '/remoteDir/'
      }
    }
  }
}
#

that will also properly set the outputs so gradle can cache it etc

noble lantern
noble lantern
#

i got a whole bookmark tab for em XD

tender shard
#

I will show one kotlin > java snippet per day.

object ModuleJarFileFilter : FileFilter {
    override fun accept(pathname: File?): Boolean {
        return pathname?.name?.lowercase()?.endsWith(".jar") ?: false
    }
}

Usage: ```kotlin
myDIrectory.listFiles(ModuleJarFileFilter)


Java:
```java
    public class ModuleJarFileFilter implements FileFilter {
        
        public static final ModuleJarFileFilter INSTANCE = new ModuleJarFileFilter();

        @Override
        public boolean accept(File file) {
            return file == null ? false : file.getName().endsWith(".jar");
        }
    }

usage: ```java
myDirectory.listFiles(ModuleJarFileFilter.INSTANCE);

#

the object keyword basically is a singleton and one can access the instance using just the class name. One also doesn't have to worry about creating the instance

knotty aspen
#

What I see there is that if you only have 4KB of storage space left and need to prioritise the code length over readability you should use Kotlin

tender shard
#

if you worry about 4kb, then you should much rather use java lol

#

the kotlin stdlib is like 5MB

#

and the compiler is also slower

#

also I dont think that kotlin is less readable

#

only thing that bothers me is that it uses names before types

#

but that's valid because usually you don't need to specify types

#

var and val automatically detect the types

#

why for example would you need to do final String name = "asd"? Obviously it's a string. In kotlin you just do val name = "asd"

#

what does bother me though is the lack of a proper static keyword

#

however in 99% of cases, static methods can be replaced with extension functions, and for the remaining stuff, the companion object basically is the same as declaring a static method

#

another example

river oracle
#

U shud starting using var in Java Alex :P

#

Tbh java shoulda also just added Val but it's whatevs

#

final var string = "fun"

tender shard
#

Java

public class NumbersToString {

    private static final Map<Integer, String> NUMBERS_TO_STRING = new HashMap<Integer, String>() {
        {
            put(0, "zero");
            put(1, "one");
            put(2, "two");
            put(3, "three");
            put(4, "four");
            put(5, "five");
            put(6, "six");
            put(7, "seven");
            put(8, "eight");
            put(9, "nine");
        }
    };

    public static String replaceNumbersToStrings(String input) {
        for (Map.Entry<Integer, String> entry : NUMBERS_TO_STRING.entrySet()) {
            input = input.replaceAll(entry.getKey().toString(), entry.getValue());
        }
        return input;
    }
    
    public static void main(String[] args) {
        System.out.println(replaceNumbersToStrings("I am 5 years old."));
    }
}

Kotlin

val NUMBERS_TO_STRING = mapOf(
    0 to "zero",
    1 to "one",
    2 to "two",
    3 to "three",
    4 to "four",
    5 to "five",
    6 to "six",
    7 to "seven",
    8 to "eight",
    9 to "nine"
)

fun String.replaceNumbersToStrings(): String {
    return map { NUMBERS_TO_STRING.getOrDefault(it.code, it) }.joinToString { "" }
}

fun main() {
    println("I am 5 years old.".replaceNumbersToStrings())
}
tender shard
river oracle
#

Oof

#

Java 8 is so ild

#

I'll never be a Java hater it's such a great language obv doesn't mean it's perfect but it's def not horrible

tender shard
#

sure, java is great

river oracle
#

I could be coding in C++ or something

tender shard
#

kotlin is just java with extra cool features

river oracle
#

Oh God my job I have an emphasis in embedded systems

#

C++ incoming

tender shard
#

oh shit it's 5.30 am and my bf comes back home in 12 hours

#

maybe I should snack a clonazepam and go to bed

river oracle
#

My bf never came home

#

He went to get some milk never saw him again

tender shard
#

fake, you're not even bi

#

wtf my paperless is now using german forbidden msgs even though the rest of the app is in engish lmao

molten hearth
#

📣 CSRF WARNING 📣

#

pov: laravel when i forgot @csrf

rare rover
tender shard
tender shard
halcyon hemlock
remote swallow
#

i only see 1 brace used

halcyon hemlock
#

but i dont use java anymore so thats irrelevant ig

ashen quest
halcyon hemlock
ashen quest
#

Hell yeah

cobalt thorn
#

Im trying using a custom command with setblock ~ ~ ~ minecraft:dirt 0 replace {nbt} how can i manage to do it in code without calling the command with the exact result?

tender shard
# halcyon hemlock

if only there'd be a similar language that'd avoid all these things... OH WAIT

remote swallow
#

weve lost alex

shadow night
#

"We have lost the battle, but not the war" - No idea who said that tbh

halcyon hemlock
#

kotlin?

#

never tried it

tender shard
#
mapOf(
  "mfnalex" to 28,
  "oliver" to 17,
  "frostalf" to 33
)```
#

yes, kotlin

sullen wharf
#

And an extra amount of clutter for no reason

#

🫠

ashen quest
#

Kotlin >>>>>> Java in all aspects except being bad

#

Kotlin readibility is quite good, it's not bad, it's just that Java readibility is too good.

Which isn't that good itself since this just makes shit more verbose

frail willow
torn shuttle
#

there is no way jetbrains is not losing money with the way they're currently doing their AI stuff

#

I know for a fact that if you're going by the normal api rates I am costing them at least $20 a day in queries, even if they're incredibly discounted for some reason their yearly ai plan is still just $10/mo

shadow night
#

Damn

upper hazel
#

Is it possible to create a custom system for melting objects in the furnace like craft system

#

?

torn shuttle
#

added my mixtape, now the jukebox is on fire, send help

echo basalt
torn shuttle
#

the intellij ai integration is straight up wacky

#

it's really, really good

#

I recommend trying it

echo basalt
#

I have the github copilot chat

#

you actually think I'm gonna update my ide?

#

hell no

torn shuttle
#

me two weeks ago

#

when my ide was 2 years behind

#

or 3

echo basalt
#

I was using 2016 intellij until like 2021

buoyant viper
#

hey past me, wtf did u write this line for?

ashen quest
#

I used intellij community during the start of my Java dev journey
Got GitHub edu pack
Switched to intellij ultimate
Then also had webstorm, pycharm and datagrip

Now I dont really program but when I get back I'll start doing stuff in go or rust, so will either install the Go or rust jetbrain ides
Or neovim with nv Chad which is straight up ultra smaxing

remote swallow
#

incase its a fake player

ashen quest
shadow night
buoyant viper
#

¯_(ツ)_/¯

#

no clue

ashen quest
torn shuttle
#

now this is what I call a certified website

buoyant viper
#

i wonder if i caught some bizarre edge case or something, or was just genuinely braindead when i wrote it

torn shuttle
#

among all the websites this is the one

frail willow
# sullen marlin Add a record

Thanks for the reply, but I found that I can use debugstick to change its value to true without adding record. How do I make has_record true in the plugin?

ashen quest
# buoyant viper no clue

Now do u know what will happen?
U will remove it, with some other changes, and ur code will stop working, after a few hours you will realize it was that it statement and add it back

buoyant viper
#

its like tf2 pineapple.jpg

sullen marlin
remote swallow
buoyant viper
#

oh was it coconut

ashen quest
# sullen marlin The value doesn’t do anything though

Md I have a question.

When u started spigot, what was ur mindset, did u ever expect it to be as big as it is rn, and were there any other members with you in the starting days.
Also with spigot are u able to make a living out of it or do u still work on other stuff

buoyant viper
#

tf2 coconut.png then yeah

remote swallow
#

ahh

frail willow
remote swallow
#

cancel the interact event instead

frail willow
glacial narwhal
#

hey, does anybody know how to add UTF-8 to my plugin?

lost matrix
#

Or just use them

glacial narwhal
lost matrix
#

Make sure your plugin is compiled using UTF-8 as a file encoding

glacial narwhal
#

How do i compile my plugin with UTF-8?

eternal night
#

What build system are you using ? maven ? gradle ?

lost matrix
#

^

glacial narwhal
eternal night
#
tasks.withType<JavaCompile> {
        options.encoding = Charsets.UTF_8.name()
        options.release = 17
    }
    tasks.withType<Javadoc> {
        options.encoding = Charsets.UTF_8.name()
    }
    tasks.withType<ProcessResources> {
        filteringCharset = Charsets.UTF_8.name()
    }
#

pretty much

glacial narwhal
#

Thx

remote swallow
#

ew gradle kotlin

eternal night
quiet ice
#

The charset is technically even optional

shadow night
quiet ice
#

The default is UTF8

eternal night
#

okay but

quiet ice
#

At least according to the Java 20 javadocs

eternal night
#

in java 21 you could also just drop the public class and public static void

#

just void main() it

shadow night
#

hmmm

#

"throws Throwable" ah yes, the floor here is made out of floor

quiet ice
#

Yep, but I stayed with Java 7 java code

eternal night
#

Well java 8

lost matrix
eternal night
quiet ice
#

Well Java 11, for Java 7 you'd use Paths#get instead of Path#of

eternal night
#

ah

eternal night
#

true

sullen marlin
#

?jira

undone axleBOT
shadow night
#

also, anybody ever encountered a Scanner(System.in) with a while loop being slow as fuck? It just happened to me randomly and it takes like two seconds for the scanner to put out a string

quiet ice
# tender shard hm I wonder, if I got a classloader, I can ofc set a parent classloader. But le...

I'd honestly just copy minestom's hierarchical classloader (https://github.com/Starloader-project/Starloader/tree/54310449fcb963ceeef5cba83ef50bbd10eabd1e/src/main/java/net/minestom/server/extras/selfmodification) and remove all the features you don't need or want.

Otherwise if you really want to do it from scratch you'd probably be better of overriding loadClass. After querying findLoadedClass‎ and the system (under Java 8 or below) or the platform (under Java 9+) classloader [and then the parent classloader, if you wish to support that], you can call the loadClass method of the child loaders. The only real catch is that if the child classloaders have your parent classloader as their parent set (without any further logic, that is the child loaders are bog standard URL classloaders) a stack overflow will occur as the child loader will first query the parent loader, then itself - such conditions could be mitigated via ThreadLocals that will NOP attempts to load a class in twice.

remote swallow
#

no way its fourteen brush

vernal oasis
#

How do I make something only execute on the first run of a plugin?

echo basalt
#

save some kind of config file

#

see if the data folder doesn't exist or sumn

vernal oasis
#

I want to have it run a command to disable some default minecraft stuff on first run but only the first time it's run

tardy delta
eternal oxide
#

at startup, if the flag is there your plugin has been run before with this world

quiet ice
tardy delta
#

mye

quiet ice
#

This could pose problems in case of shaded dependencies - although now that you mention it these problems would still be present for as long as the child classloaders are stock URLClassLoaders

upper hazel
#

Has anyone done protection against incorrectly configured config values ​​in the plugin? Can anyone else add anything else to this class who has done this?
https://paste.md-5.net/qimiveyero.java

vernal oasis
#

wdym?

ocean hollow
#

What is the best way to store a list of killed players in MySQL for a player, while still having the ability to add and remove them (for example, for 2000 players at once). Or should I come up with some other way to solve my problem?

eternal oxide
#

Why do you need to store killed players?

ocean hollow
#

I'm making a bounty hunter plugin, when I kill a player I need to save the head in the "case with heads", and then I will need to hand over this head to the NPC, and remove the head from all players

eternal oxide
#

seems an odd way to do it

#

do the players all get a list of every bounty head?

ocean hollow
#

do not quite understand

eternal oxide
#

It seems to me the only one who needs a full list would be the NPC

#

player kills someone, takes head to NPC and gets bounty if there is a bounty to be paid

ocean hollow
#

the player writes the command /case, and an inventory is generated with heads that are in mySQL, in the format "Elgar MrTvist ..."

#

I just did this before, but now I plan to rewrite the plugin for optimization purposes

#

the plugin has not been adequately tested

eternal oxide
#

Doing it your way I'd not give the heads to each player

#

Make an inventory in your plugin which has the heads, and open it for the player upon command

#

that way teh player never has the heads inventory so you only have one inventory to update

eternal night
#

I meams. if you have to end up persisting the data anyway inventory would be a meh idea

ocean hollow
#

you will still need to create a database or file to save inventory after shutdown

eternal oxide
#

giving out heads to every player is a bad idea

#

you don;t need to save inventory, you nly need a list of UUIDs

ocean hollow
eternal night
eternal oxide
#

just store all bounty UUIDs in your database

#

don;t give them to the players

eternal night
#

you can't take them from there
They aren't 😭

eternal oxide
#

create an inventory to hold them, which the players can all open.

#

when a player kills someone, give them a head of that player.

#

they take that head to the NPC, and exchange the head for a reward.

#

You then remove that UUID from your db, and remove the head from your inventory

ocean hollow
#

okay thank you

#

thanks for the advice

eternal oxide
#

how you store the UUIDs is upto you, be it as Longs or VARCHAR(36).

smoky anchor
#

Yo, some time ago someone posted a link to a website I think.
There was a description of how to do one big thing over several ticks in smaller parts. (For example placing a lot of blocks)
Anyone knows where I can find that ?

eternal oxide
#

there is a ? for it but I can't remember. ?distr something

#

?workdistro

eternal oxide
#

remembered 😉

smoky anchor
#

ah thankyou very much

topaz cape
#

apparently this is the IP that the player used to connect from

#

not the players IP

#

where can I access the Player's IP? (this is bungeecord btw)

eternal oxide
#

Try getSocketAddress() not getVirtualHost()

#

it has getInetAddress()

topaz cape
#

apparently this is the problem

topaz cape
#

okay so how do i blacklist linux players

#

lmao

buoyant viper
#

./hack.sh

topaz cape
#

nah, too illegal

eternal night
#

linux players ? xD

buoyant viper
#

theyll be too busy installing a web browser to play minecraft anyway

topaz cape
#

which is a problem cuz

#

there is no ip involved

eternal night
#

Yea but that is on the server

topaz cape
#

Well, I still cannot blacklist Unix based connections like that

lost matrix
#

?

#

What did i just join to?

eternal night
#

your server is the one that would have to bind to a unix socket

#

clients cannot just magically use a socket on your system

topaz cape
#

That's most likely the case w/ bungeecord though

eternal night
#

it isn't

quaint mantle
#

Hey guys, how can I set player the shaking animation, like shivering?

steady pelican
#

that was true with IE

#

and a little bit true with Edge

buoyant viper
#

couldnt be me

#

i installed Chocolatey then installed Firefox

eternal night
#

but you'd have to be the one that sets that up

buoyant viper
eternal night
#

it is by far not a common thing

buoyant viper
#

yeah i run Linux (Windows) see i have a package manager

steady pelican
#

i need to wait for my account to be deleted

topaz cape
#

ill just add an option to disallow Unix-Based connections

eternal night
#

Sure yea

steady pelican
#

bro why can't websites just make a fucking button "delete my account" ?

remote swallow
steady pelican
#

jk

remote swallow
#

its probably the fact xf is like over 10 years old

buoyant viper
topaz cape
#

would look like this probably

#

with some messages

eternal oxide
steady pelican
#

but not all

topaz cape
topaz cape
ocean hollow
#

I’m making a private system in chunks, the principle of operation is:
the player creates a city through a command, I start private from this chunk by chunk, I made a system for expanding private, but there is a very main problem, how to save it all, so that the next time you turn it on, everything loads stably, because this is an entity. I came to the conclusion that with EntitiesLoadEvent, I create a CityChunk for each chunk, and in it I create entities that are stored in the pdc of the chunk (if side == true - create a wall). The problem is that it does not restore correctly, can you give me some advice? What if we can somehow avoid creating entities every time? Initially, I wanted to save the UUID entity in the pdc, and then turn on/off their visibility, but they were always null

hushed spindle
#

does anyone happen to have a reliable Player#isOnGround() alternative

#

isonground is deprecated because its client defined

ocean hollow
eternal oxide
#

Towny maintains it's own database

ocean hollow
#

???

eternal oxide
#

nothing is in the world for Towny

ocean hollow
#

Are the coordinates of chunks stored in the database?

eternal oxide
#

yes

ocean hollow
#

that is, I won’t be able to come to such a system if I have entities?

hollow oxide
#

I want to store a string in an item using NBT. but I didn't find much info about it. can anyone help me?

hushed spindle
#

PersistentDataContainer is what you're looking for

#

assuming you're using 1.14+

hollow oxide
#

yup

hushed spindle
#

?pdc

hollow oxide
#

got this

if (meta != null && meta.getPersistentDataContainer().has(new NamespacedKey(Wamasterv3.plugin, "command"), PersistentDataType.STRING)) {
            String valeurCommande = meta.getPersistentDataContainer().get(new NamespacedKey(Wamasterv3.plugin, "command"), PersistentDataType.STRING);
            Bukkit.broadcastMessage("La valeur de la balise 'command' est : " + valeurCommande);
        } else {
            Bukkit.broadcastMessage("L'ItemStack ne contient pas la balise 'command' ou la valeur est null.");
        }

but i can't get the plugin to give me the string, its always null

eternal night
#

how are you setting it ?

hushed spindle
#

first you should define the namespacedkey separately and not make a new one every time you're accessing the pdc

#

and yeah how are you setting the value to the item

hollow oxide
remote swallow
#

that isnt how pdc looks like

eternal night
#

pdc isn't custom NBT

remote swallow
#

i dont remember what it exactly is but its like PersistentBukkitValues {k:v}

eternal night
#

Yea but like, just code in spawning this via your plugin

remote swallow
#

^^

#

its much easier and you dont have to deal with any version change jank

tender shard
#

can you give me an example of what exactly you cannot read?

tender shard
tender shard
#

why is this not just the default

eternal night
#

I mean, it uses the system default

tender shard
#

ah that explains why I only have to change it on windows

eternal night
#

xD

#

Yea, if you run hot garbage for an OS, that tends to happen

tender shard
#

yeah but tbf why does gradle not use UTF8 by default?

eternal night
#

¯_(ツ)_/¯

tender shard
#

it's about "reproducible builds" and stuff and hence should not even take a look at what's the systems default

eternal night
#

hence why you specify it

#

o.o

tender shard
#

yeah sure but it could also just use utf8 as default if not specified

#

maven has the same stupid problem

eternal night
#

If you need it to be utf 8 specifying it as such is a good idea

#

like, if you need java 17 to compile, you define it too

tender shard
#

yeah but imagine a life where utf8 is considered the default because why not

eternal night
#

Yea would be nice xD

#

but like, then you argue for utf 16

#

or something

#

and yea

#

its a never ending escalation with the "make something the default"

tender shard
#

as long as the default is not windows-bullshit, I'm good lol

eternal night
#

Like, e.g. eastern asian chars are a lot better in utf 16

#

so arriving at the "best" default is just, kinda hard

#

idk what the fuck windows does tho

#

like, the fuck is CP1250

hushed spindle
#

im seeing that it's possible to use PlayerStatisticIncrementEvent with Statistic.JUMP to effectively make a playerjumpevent happen, is there any reason I should avoid using that? like is it maybe also defined by the client or something

eternal night
#

Well, statistic increment event is rather hot

hushed spindle
#

💦

#

what does that mean lol

eternal night
#

but yea, probably would work

#

like, it is called a lot

hushed spindle
#

the alternative would be PlayerMoveEvent though, yeah?

#

which is also pretty hot

eternal night
#

Yea

#

I mean, statistic is fine ™️

#

technically you can hack around with EntityExhaustionEvent

hushed spindle
#

also works yeah

#

reckon thats a bit less hot than a statistic event

eternal night
#

Yea xD

#

actually

#

probably not lol

hushed spindle
#

are you serious

eternal night
#

I presume it is also called for like

hushed spindle
#

this is calculated by the CENTIMETER

#

BROTHER

eternal night
#

yesss

tender shard
hushed spindle
#

little bit overkill I WOULD THINK

#

very important to have the 1cm precision

eternal night
#

Yea I mean, complain to mojang xD

tender shard
#
GitHub

Avoid writing the same code over and over again - use JeffLib for your Spigot plugins! - mfnalex/JeffLib

eternal night
#

Yea, stat even probably is fine xD

#

or yea, on paper, the respetive event

#

with that said tho, the onGround stuff is kinda meh

#

it is client controlled, so hack clients can cheat around there

hushed spindle
#

is there some way i can force a Player to use the Entity implementation of isOnGround though

eternal night
#

I don't think so xD

hushed spindle
#

god damn it

tender shard
#

you can use reflection to get the method from entity and then invoke it

#
        try {
            // Use reflection to get the isOnGround method from the Entity class
            Method method = Entity.class.getDeclaredMethod("isOnGround");

            // Invoke the method on the Player object
            boolean result = (boolean) method.invoke(player);

        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
#

obviously you should cache the method instead of getting it everytime

hushed spindle
#

seems fair

#

thanks man

tender shard
#

gotta love the Scheduler interface boykisserdead

pine forge
#

How do you ban someone infinitely, the ban function only takes in duration, instants or date and im not sure how to set these to 0

pine forge
#

Okay is that the same thing for thje Player#ban function then?

#

just nullify it?

tender shard
#

yep

river oracle
#

Everything is nullable besides the player

pine forge
#

okay thanks 👍

tender shard
pine forge
young knoll
#

Cast the null to date or instant

pine forge
#

nice, that worked

#

lol

#

didnt know you could cast nulls

shadow night
#

(Date) null
You have a date with nothing

pine forge
#

yum

kindred valley
#

Isnt there any way to make a block unique without db

young knoll
#

?blockpdc

undone axleBOT
pure stag
#

how do I get the amount of experience that will fall from the ore?

eternal night
#

given that value is random and computed on break

#

not much to do

young knoll
#

Isn’t it available in the break event

eternal night
#

ye

tender shard
#

day 2 of me trying to get libs working

eternal night
#

but like, that is reactive. I read their message as a proactive "how much would that drop"

tender shard
tender shard
young knoll
#

Hey that rhymes

remote swallow
#

not allowed

tender shard
pure stag
# pure stag

Do you have any ideas how this can be implemented?

tender shard
#

the amount of XP the block would have dropped?

pure stag
#

how do I get experience from the block? Maybe there is some interface to which I need to instanceof?

river oracle
tender shard
#

hm I don't think you can get the vanilla XP amount for blocks

young knoll
#

You could mark the block and then listen for the break event

#

And then callback after the event

pure stag
#

hm

tender shard
#

will you be my callboi?

#

it's on 22nd feb btw

eternal oxide
#

I'll call you. I don't believe it's the 22nd. I think you are lying.

tender shard
#

oooh

#

that's what you're saying, aha

#

yeah well

#

joke's on you then

#

Eat this @eternal oxide

eternal oxide
#

faked 😛

tender shard
#

uuugh D:

#

yeah anyway, I don't care as long as I get my soup

eternal oxide
#

Soup? I can send you soup, but it may be cold by the time it gets there, and spilled

tender shard
#

Wrong channel mfnalex

rotund ravine
eternal oxide
#

I was going to comment I would CSI magnify the reflection on his thumb to get the number. Then I realized he hadn't covered it up.

civic sluice
hollow oxide
#

is there a way to change console_sender to command_block_sender (like a fake command block)?

Bukkit.dispatchCommand(Bukkit.getConsoleSender(),cmd);```
pure stag
minor junco
# pure stag xd

@ivory sleet need you help here, wouldn't it be smarter to just use a hashmap? I mean EnumMap allocates an array based off of the size of the Material enumeration, which is huge considering how many enum fields there are. So only having a couple ores there wouldn't make much sense no? It's like allocating a huge buffer, from which you only use 10 or so fields

tender shard
pure stag
tender shard
minor junco
echo basalt
#

whys he using a function if he never passes the thing

#

make it a supplier instead

minor junco
#

I think for future extension no?

#

I mean yeah true lol

pure stag
tender shard
icy beacon
#

Holy shit