#[MEGA THREAD] Get Your Code Reviewed or Review Others
1 messages · Page 7 of 1
It's a separate class for a reason imo
That's why I did it
For example a lot of these are errors I throw for people making their bot script, so I want it to highlight red rather than white and I want it customizable to my liking
colored logs?
the server doesn't preserve colors in logs and instead logs the color codes along with whatever message
rather annoying sometimes, if there is anything you could do better in terms of logging is actually creating a log in your plugin directory of everything your plugin is doing 🙂
why
and idk what this does but have you thought about unsanitized input
and i dont see a reason to use a BotLogger and not a java.util.Logger
because the color strip color code does not strip the ampersands
why the String.valueOf
Yeah and no. It's the person who owns the servers input through the script file so if they wnana hack their own server they can
Y'know what, I'm not sure. I ripped that off spigot forms
It's supposed to strip the ampersand color codes
Actually no I didn't rip this from spigot forms sorry I just went into source code on how they did ChatColor#stripColors() and replaced the § with &
I wanted to have colored logs with the prefix so Java.util.Logger would not work. My BotLogger class works fine
Yeah, the Bukkit.getLogger() doesn't. However Bukkit.getConsoleSender() does so I wrapped it in a log class with my prefix 🙂
i mean what is the script engine supposed to do
They can make JS files
That they can use to make their own bots so it uses scriptengine for it
bruh, this runs a discord bot from a js file?
No it runs its own chat bot
In the mc chat
Similar to discord bot but nowhere near as powerful
So for example in the js file there would be something like this:
javascript out of all languages
What's wrong with JS?
yeah no it's all good
Not using LUA lol
Ah lol ok. Yeah JS can be funky
We use something like this at work so I thought it'd be interesting to implement it into MC in its own way
whats not wrong with js
There is nothing wrong with it if you're not an elitist which you are clearly showing in this chat. I get paid to use it at my job so clearly it has uses
it has its misuses
I agree, it should not be used in a backend web framework, but it also has its uses
I hate that every line in JavaScript can throw an error
i want my code to force me to handle errors by having errors as values etc
With JavaScript, that’s only partially possible without cumbersome design
how
glad you didnt ever throw a number in c++
you can throw anything you want there
me when typescript exists
I agree lol, I always found that weird. TypeScript fixes that though. I'd honestly not recommend js for modern applications
Beat me to it
It's not exactly a linter but in the basic sense I guess. TypeScript is very nice to code in
Way nicer than vanilla JS
im scared of stack unwinding :(
Ok I'll go ahead and write the front end of a website in c++ and tell you how it goes...
or a multi-platform app
i mean js, has its uses, web, thats literally it
You can use js without a framework
Clown reacts me lmao. Ok mr elite developer I'll step back into my cave of a novice and let the expert do his work
normal js is probably never ever used in developing any website, I mean you choose a framework?
You usually choose a framework yes but Vanilla JS is capable of almost everything JQuery does
That's your opinion
sure
I don't recommend using Vanilla js in websites but it can be done without JQuery
be realistic tho, in the industry and for personal projects, barely barely anyone uses vanilla
Well yeah for sure, I'm just saying JQuery isn't needed anymore if you opt to use vanilla
and I’m talking about real web devs, not the people who are there to just learn dom with js for their first time
Yea that is true
Anyway fourteenbrush I don’t think cpp has the best language design around error handling, but thats my personal opinion
just like JavaScript
whats design has it thats different from other languages? apart from being able to throw anything you want and catch by reference
I mean you referred to just exception throwing, error codes is imho much better, ofc if the eco system and the language is a proponent of it, else you land in an abstraction layer
Now yea, cpp is old so ofc its not fair to utterly flame cpp, or any other language for it
javascript was literally named javascript so that it would get more popular because of the word java
we can't not flame it
kotlinscript
imagine
result types wouldve been a good thing if they were integrated in the lang, like rust
I think the fact that JavaScript is dynamically typed makes the entire try catch and throw code control flow design so much worse
imagine
imagine a better world
Lol now I am not saying JavaScript isn't deserving of it's slander, I agree with all these points
It's always horrendous to see a catch(e) in the middle of some giga function someone wrote in 2016
legacy code moment
yea, I think TypeScript is generally a decent solution also, but it has some problems also :(
Yeah very true. Using TypeScript after JS for a while is like a huge load off your chest, but it comes with its problems
dont
Lol I know I was just saying its strange
what is it called, jython? Right?
Yes
i thought you were talking about a scripting engine again
I am
That's literally what a scripting engine is
It's built into Java
You just need to download the engines themselves
to me it seems like you gotta ask the question why you're uberhaupt trying to call python from java
just thoughts
sounds ideal
Sometimes people want to make it so they can modify their application for specific use cases by people or want people to be able to mod the code
Most of py is in C anyway or so, so native language invocation speed boost? (/s)
i mean if you would call lua from c++ for plugins for games, ok thats just happens, but why python
not saying lua aint crap
Well yeah that wouldn't be my first choice
can yo ugive me one usecase?
fun fact to know that all ml libs in python are written in c

so "python is good for ml" is nonsense
Sometimes people want to make it so they can modify their application for specific users without modifying the direct source code and having a bunch of branches to update
like code generators?
No, like making your application scriptable
tbh data generators could be fine having it in py
mmh fair
but i feel like the interoperability would suck, if anything
but imagine spigot had you write plugins in python instead of java
myea, imagine that
i'd kms
i mean if you wanna make your application scriptable, why not do it in the lang thats its written in, ive seem that so many times
non technical users ig then
idk if python is the ideal language for it
No I agree with that
but yea, having a separate language and system for things that can be “DSL-able” is sometimes a convenience
altho DSLs usually become a bit cumbersome and annoying to maintain in practice xD
to what point does that stay a concern?
you might think about it that way
1st class ticket to lobotomy
I mean I’ve seen it in practice on larger things
disagree
its great for ML mockups etc which is exactly what its used for. Just because the libraries are in C doesn't devalue its ML capabilities as a language
i meant to say "cuz python is fast for ml"
i mean you, woulve been a bit harder to call c
cant believe ur ghosting me
ctrl + click on EntityArmorStand i think
Do yourself a favour and use mojang mappings
If you need to access NMS classes from inside your Spigot plugin, it is a very good idea to use the so called Mojang mappings. Disclaimer: This post is written for 1.20.4. If you use another version, you of course have to replace every occurance of “1.20.4” with the version you actually use. What are...
very basic code, but if it can be upgraded... 👍
Huge room for improvement
ooh, perfect
We can start by arguing over consistency, caching config values
Single name variables
Naming conventions, all of that
Duplicate collection calls
single name ?
Single letter*
hmm
static abuse just for the sake of it
x)
There's a lot
no performance leak?
One or two but they're minor
which one?
Figure it out :)
...
yeah I was just bothered by the all caps manager variable names xD
should I remove config and always use getConfig?
Opposite
so always use config?
it doesnt need to be static
okay
but imo it doesnt really matter
like you are probably accessing it in a lot of places
on my plugin I have created a class that just loads the config.yml file so I dont have to search in the yml file manually everywhere its used
but thats more of a convenience thing
I need to access scheduler in other classes
?di
Guide to dependency injection: https://www.spigotmc.org/wiki/using-dependency-injection/
oh ok
It's almost as if you've never been in #help-development
it's much better doing that?
dont expose collections
What should I do instead?
inject some wrapper or somethinh
huh
like di
but that will update the local variable, not the imported one?
wrapper thing for your collection, maybe some extra logic associateted witj it
class
wrapper class
some manager thingi
we are not making a spaghetti, we are making a lasagna
hmm
whats the difference
between spaghetti and lasagna?
look when you are accessingthia collection from the outside and then see if maybe all you have to do is just add a few mthods in your static class
if you want to associate logic with modifying that collection
directly modifying it wont run said logic
yes I know
also outsiders shouldnt be allowed to change things direcctly
a la unrelated systems
but I think depending on where youare using this a wrapper might not be needed
conclure writing the bible
prefer Map::getOrDefault to Map::get null check if you're doing something with the value.
Some of your methods are really gigantic, like the one in RepairManager::initAutoRepair which also declares a fat callback, cut it down if you can.
Good that you use ur plugin logger and keep bootstrap logic to ur bootstrap/entry point function.
As pointed out by the others, but the static task scheduler can be questionable, esp since chances are big as you scale code you want to have different thread pools and ways of dealing with multithreading depending on module, sharing the same TaskScheduler could be problematic from a testability, maintainability and modular perspective. Let alone I saw some random static "singletons" floating around in different classes, reconsider that design choice.
Someone else may have pointed it out, but you rarely ever keep all the interfaces in a singular package named "interfaces", its a less ideal structure.
Your config manager sucks.
Me personally likes when instance methods and instance fields are called with this and super keyword though I have come to understand its more preference so this is soft.
Your command class can derive TabExecutor instead, it also has a goofy name, the acronym BTM may not be entirely given.
let's edit that
well I havent read every single line, but I thought I'd give you some advice on different levels :]
where is the map where I should use getOrDefault?
CooldownManager iirc
oh yeah
but, I can't use getOrDefault here?java public Duration getRemainingCooldown(UUID key) { Instant cooldown = map.get(key); Instant now = Instant.now(); if (cooldown != null && now.isBefore(cooldown)) { return Duration.between(now, cooldown); } else { return Duration.ZERO; } }
I usually just use this in constructors or naming conflicts xD
this is esp good when u work w ppl who may read ur code on lets say GitHub or on a paste/gist
well what do you want to happen when there is no cooldown for the key
yeah true
I never look at it from that perspective because usually its just me in my nice ide with rainbow colors
use Duration.ZERO
but Duration isn't Instant
I mean you have Instant.MAX and Instant.MIN/EPOCH
likely one of those that u wna use
hm
now no
right
no, now
so then it will also use duration.zero
but yea PauLem, fyi, I said prefer, ofc there are moments when a null check is more suitable, for instance in multithreading when you design thread safe classes you may opt for explicit null checks at times (tho more in general)
but ultimately it will be zero if you calculate the duration between probably
...but I'm not doing multithreading, right?
yes, that was just an example
logically
you have to decide for urself which one is better
I guess all you have to check is make sure there is no negative duration?
but idk how you handle removing stuff from the map anyways
i havent seen this file xD
well
public Duration getRemainingCooldown(UUID key) {
Instant cooldown = map.getOrDefault(key, Instant.now());
Instant now = Instant.now();
if (now.isBefore(cooldown)) {
return Duration.between(now, cooldown);
} else {
return Duration.ZERO;
}
}```
let's compact this
public Duration getRemainingCooldown(UUID key) {
Instant now = Instant.now();
Instant cooldown = map.getOrDefault(key, now);
return now.isBefore(cooldown) ? Duration.between(now, cooldown) : Duration.ZERO;
}```
oh yeah
so that they use the same yk yk
like this?
yea I suppose
my brain is a bit fried atm so maybe we got it logically invalid, but yea
can optimize this toojava public boolean hasCooldown(UUID key) { Instant cooldown = map.get(key); return cooldown != null && Instant.now().isBefore(cooldown); }
optimize is relative
been watching skibidi toilet lately?
you are arguably making it less readable to a point
// Check if cooldown has expired
public boolean hasCooldown(UUID key) {
Instant now = Instant.now();
Instant cooldown = map.getOrDefault(key, now);
return now.isBefore(cooldown);
}```
there is something thats easy to read about just the if else imo
I could
yes but this removes the duration
zero logic
idk the documentation for negative durations
like maybe thats not something you want
or maybe it doesnt matter
this is another method
to check if there is a cooldown
oh
yup, longest mewing streaks require true sigmas (/s)
oh, I re-found that```java
// I like spaghetti. (I'll improve this)
if(cooldownManager.getDefaultCooldown() == 0) {
useRepair(player, item);
} else if(cooldownManager.hasCooldown(playerId)) {
alertCooldown(playerId, player);
} else if(cooldownUses.containsKey(playerId)) {
isInMap(playerId, player, item);
} else {
// Put the player in map
cooldownUses.put(playerId, 1);
// Make repair
useRepair(player, item);
}```
lol
another brain hurt by the brainrot
wouldnt even know how that sentence makes sence tbh
x)
ssssh dont tell oliver
and that
i see config and think about what if you remove config key, is it also removes on player config when config is updating?
no
I think no
I think you need add this feature
yeah
Maybe this code will help you
for (String key : config.getKeys(true)) {
if (embeddedConfig.get(key) == null) {
config.set(key, null);
}
}
oh thank you
cant you cast GSON.fromJson to T instead of the cf?
oh you're right ty
You could use a MongoCollection<T> internally and avoid just gsoning stuff
have an abstract codec or something
do it the proper way
Hi can anyone help me with my plugin I am coding this is my first kinda big plugin so pls don't judge and don't say How i could tidy it up or put some thing in different classes. So anyway I feel like my test server is getting bad performance with this plugin enabled can anyone see anything obvious that is causing performance issues I think it might have something to do wtih the task scheduling but idk. Thanks
WardenRelics(Mail File): https://paste.md-5.net/rovuxokegi.java
RelicManager: https://paste.md-5.net/qogipeheli.java
Relic Of Travel(An example of one of the relics): https://paste.md-5.net/erayepefac.cs
dont register a new listener in RelicOfTravel constructor every time
imagine you ending up with thousands of those items
id say have a global listener, which keeps track of those items through a RelicManager and propagates the event to the correct items
also youre never doing any cleanup when the player leaves the server
like i assume your listener needs to get unregistered, its broken though
just so much code that i can barely see whats happening
you sure you cant do certain things event based rather than having a bunch of tasks checking for things every tick?
like cmon, a method?
i believe ive seen that code before
Calling item.getItemMeta() will tank performance if you do it too much
Every call creates a copy of the item data.
Create a temporary variable ItemMeta and call the getItemMeta just once, then do the checks.
This is not this method specific, you do it in several places.
Also, I would recommend using PDC to identify the items, not item name.
Ppl can change that (unless you specifically forbid the usages of anvils or something)
i mean just clean up that mess before you start thinking about anything else
Just the start of my ORM Entity System, just want some critique.
https://github.com/ignPurple/proxi
proxy is with an y
yea i know
oh well the thing is called proxi, cringe

yep
and do some proper exception handling
is a DefaultEntityFactoryMaker like a DefaultEntityFactoryFactory? 🤓
and i prefer doing direct initialization
ConcurrentMap /:o
I mean lowkey u probably don’t wna configure modular projects with allprojects/subprojects, instead use a convention plugin
Ur proxy singleton variable should be named lowercase like normal variables as its not a constant
You could probably allow class visitor to have separate methods for different types nodes rather than using the same callback for all types of nodes
first created data could be an Instant instead ofc u trade a bit of memory then but thats that
Instead of nested factories u may wanna look at abstract factory pattern
Why not one listener and just 2 methods for handling the stuff you want to do
That's fine? I mean the point is that it's a listener for the player join event so
Why make multiple listeners
Separate the concern by methods mane
If you want multiple listeners then go for it, but if they're not backed by heavy functions then I don't see a lot of benefit in multiple listeners
NuclearKat is correct here in that only one listener needs to be used
not sure why relation matters here, and you only need one method technically
this is why conditionals are a thing in code
setup an appropriate condition to be checked and you can decide what code needs to be ran lol
Yes
Has to deal with separation of concerns
If you have two very distinct systems, there's no reason why they should share the same listener
*unless they both have conditions which can be put in a single listener then the actions are delegated to both through listeners
Quite situational
yes
Or just use 1 listener and use multiple methods
Doesn't scale well when your codebase is like 30k+ lines long
using multiple listeners is fine
Depends
I've been making managers register their own listeners for removing residual data
It's not 100% ideal but it's self-sustained
It allows me to copy over the project and not have to worry about registering listeners
Honestly having multiple listeners will allow you to debug if there's lag or not with spark, as you can see which class it's coming from, rather than having to search a method for a specific line, specific method, etc.
init method 🤔
<init> go brr
Meow.<init>
innit
what
https://github.com/IslandPractice/universes/
note that i would like some actual feedback here instead of people hating on kotlin, not useful here
ehrm, what the sigma, why are you using kotlin? 🤓☝️ (/s)
well I like to use version catalogues, altho Ig that’s more of a preference
wdym?
oh yea
Your command object has one large register method that both registers and implements all of ur commands, not sure how much of an issue that is in kotlin infrastructurally speaking, but I mean you could probably extract that out for instance (i think I saw some other place where there is a bunch of nested higher ordered functions and first class functions)
gradle moment
yea fr
yeah ig so
commands aren't the prettiest to do
that’s true
its just gonna be input parsing one or another way at the end of the day
yea
i'm planning to add custom data tags
to schematics
like, adding in some other options to the nbt file
this schem is 12kb and 6.3k lines of nbt
i do like the format tho
ah yes
?
I just said that because it reminded me of working with schematic files, well that was long time ago but yup (i was a static abuser back then)
insert hadouken here
ha what
damn, sniped
oh i didnt know there was a gif
why lol
?gui
don't do a switch on the slot
@surreal peak whats ur opinion on using result objects in java?
Like not Optional cuz it sucks, but something similar
Yea I was thinking on that
as in the kotlin ones? https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-result/
I use Result especially with pattern matching I'd say it's very nice
But you use kotlin tho?
In Java
Ah okay
I use both java and kotlin
yea, well do u always substitute pattern matching on a result to using throwable control flows?
I've started to yes you still have to use try catch because of Javas api but I can just propagate forward a result
myea, well I was considering doing the same
Take a look I still throw errors rn but it's because I haven't introduced a proper logging and killing mechanism yet
I thought I’d just use exceptions as a means to represent stacktraceable errors, that is I convert the result into an exception and then send it to the slf4j api
but design wise relying on result objects entirely
well this is all very hypothetical, not sure how great it will scale w my app api and everything, but i really liked the idea of it at least
If you wanna take a look at how it generally applies my project above uses them pretty much exclusively I have a few things to switch over but it's almost entirely results
to what degree can we achieve something better in java?
Subtypable optionals I suppose
also what does better mean
sealed interface Option permits None, Some
I find errors as values generally nice
for example
would only introduce dynamic dispatch overhead
Ill have a look
and if Option.NONE is a static constant of class Option.None, that could cause a classloader deadlock
ofc it comes at a price
Use a sealed class instead INVOKEINTERFACE can't be optimized down
but just look at kotlin for instance, they have it built in (ofc its not nearly as powerful and semantic)
yea that’s true
Something like rust or go I presume
Kotlin has its nullability safety semantic
which get massacred by the jvm
if a type A equipped with a function B that returns C?
a subtype AA of A can return just C on that function B
yea but semantically it works quite well, presuming you handle it correctly
Yea and I mean rust is entirely built around Option and Result, whereas Java hasn’t really natively adopted Optional (which is the closest we get)
Javas optional implementation is subpar too
Yes
subpar?
basically not enough
Sure, this is true
Worse than par, in golf par is the reccomended hits to get the ball in the hole
but what I mean is this for example
what did that even mean? ofc AA can return C, is it supposed to return a subtype of C?
class A {
func B -> C?
}
class AA : A{
func B -> C
}
where C? means nullable of type C
ah
with Java there is no such semantic unless u invent it w some sort of polymorphic structure
like my goofy example w a sealed interface, or well with sealed abstract class
Anyway I was just curious what ur thoughts on using result objects over normal throwables in java are fourteenbrush
i dont like stack unwinding
i once saw smile returning throwables instead of throwing them
what kind of reaction is that
ofc
glad c doesnt have exceptions
not saying c is good, its still a pile of old crap thats still in use for whatever reason
something like this
Result(T success, F failure){
func raiseException() { /*throws something */ }
}
and then an Option class of some sort
but what was in the first place the point of throwing exceptions instead of simply returning an error object
these days kids just throw them exceptions, dont document it and expect us to do smth about it
i feel like with checked exceptions it can make sense since u’re forced to deal with it
as in returning error objects gives (in my eyes) a better guanantee that the end user actually handles those fault cases
but unchecked exceptions, oh jesus
in kotlin there isnt even a concept of checked exceptions iirc
No such thing UwU
Only unchecked
Yea because its annoying since we started to use exceptions for checking dumb invariants that may not even be true due to the programmer themselves messing things up
unwinding the stack to let the caller handle that either way, sounds familiar to a method return
and then having a checked exception for something that is rarely ever gonna be thrown but only if the programmer is dumb enough to forget about the invariants and state of the system
rust does a good job with Result<T, E>
IOException my beloved ♥️
UncheckedIoException 😳
UncheckedIOException 
yea
soo what’s ur actual opinion on it fourteen
it scares me how many times i see just a e.printStackTrace() on plugins code
opinion on Result?
I mean is it so much different than just dumping it to the logger
yea, a duct taped result design in a 100% java program
i mean there are no language design semantics around it
primary goal being to avoid the hassles of unchecked exceptions
yea sadly
having something like rust ? or odins or_return wouldve been great
definitely
but at some point we gotta realize that java isnt out destination
if let 
i mean java has the valhalla non nullable type jep that hopefully is released one day
building on a mountain of bad decisions doesnt mean the language is getting any better
but thats just my opinion
yea well its mostly to do with optimizing generics and enhancing its semantics and ergonomics
But well, fuck okay, without side tracking
Handcrafted java result class, valid or nah?
thats too abstract for me, i gotta know how well its usable
How do you evaluate usability?
you can go whateevr direction you want with that, what are you gonna do? write a gloried Optional and realize you just reinvented the wheel?
I mean yes but then again Optional doesn’t have subtypes to express absence/presence of a value
why would it need subtyping?
This for example
A::B returns Maybe<C>
AA::B returns Yes<C>
so in the case of having terms expressable in AA, we don’t need to evaluate Maybe::isPresent
how are you gonna know if you only know A exists (read as liskov)?
if A is abstract
I mean maybe you have an instance of AA?
and I mean it could be as simple as a type hierarchy of animals
Animal::getPrey -> Maybe<ResizableList<Animal>>
Bear::getPrey -> Yes<ResizableList<Animal>>
sounds like pattern matching
Well I mean what if we happen to just have a term of Bear, the at compile time we already know it will yield a list of preys
ye
instead of having to evaluate Maybe::isPresent => Maybe::unwrap
since ::unwrap may panic if ::isPresent yields false
Well Idk maybe its just me overthinking and all I need to do is to shove in those Optionals
@woeful pasture but u support it riiight?
ig compilers arent smart enough
Did u ever build one?
💀
i was working on some kind of assembly lang with a runtime but i abandoned it
started rewriting it in c++ and that didnt end very well
Sounds a bit masochistic, but at least u tried
also writing a partial c parser atm
partial as in?
I evaluate every time but I'm considering adding an unwrap method
unsafe { unwrap_unchecked() }
if only
ill unwrap you
😏
opinion about https://radio-weblogs.com/0122027/stories/2003/04/01/JavasCheckedExceptionsWereAMistake.html ?
tldr:
most exceptions in java are handled in one of two ways:
- either quietly swallow the exception
- wrap it into some kind of runtime exception
best argument against operator overloading:
That just makes code unreadable. You think it's a comparison, but someone on your team redefined it as a command to the coffee machine to give you tea next time.
Yes because when u force it with a go-to syntax to handle it with, people will do that, especially under pressure when u work on production code, i think checked exceptions make sense as long as u use it for the right thing, unchecked exceptions are dangerous because they can hypothetically be thrown from anywhere and everywhere making it a JavaScript playground
Yee, like then after some time u get to know the fucking + operator opens a file channel and invokes a socket channel
definitely does not start a bitcoin miner
This is so old as it is from 2003. Basically what i got from it they dont like the fact they are inconvenienced with checked exceptions. Their argument against such things was very weak.
https://github.com/radstevee/packed fonts might be ready for production use now. would like some opinions.
the example (example module) logs this:
i haven't actually tested out the other asset resolution strategies, should probably do that
i should probably add the namespaced key regex
Did you code this with regard to java interoperability by chance or nah?
not really, why?
i mean, feel free to make that
I was mainly curious, I mean apis and libs when written in kotlin do try to consider the java side of things
take moshi for example
we use kotlin internally and i think a lot of the audience for this would be kotlin users. it should still work flawlessly for java i hope
myea well one of the appeals with kotlin is that u can write it easily to fit both java and kotlin devs extending the overall appeal ^^
unless you use things specific to kotlin
does internal count
oh
i mean it still has to compile to .class files so you imagine it somehow becomes something that java supports
fun `some long name`() {}
goes poof in java
yeah
"you should only use it for tests" 🤓
idk the page
do you know about kotlin notebook
looks like a cool thing
idk how id find a usecase for it though
is that like pynb
maybe docs
Kotlin Notebook is an interactive tool that lets you mix code, visuals, and markdown in one document. You can use notebooks to write and execute code in sections known as code cells, see the results instantly, and write down your thoughts. This setup makes it an excellent tool for rapid prototyping, analytics, and data science.
idk pynb
like jupyter
idfk what jupyter is
well i know now
that it's pretty much kotlin notebook
but yeah i don't like py
good
good boy~
!!
common discord mobile l
real
@JvmName
yes but we want to use some long name
just dont?
wait wut
FACTS
MAKE FUNCTION NAMES THAT JUST WOULD NOT EXIST IN JAVA
SO THEY GO POOF
PLUGIN CREATORS WILL BE FORCED TO USE KOTLIN
DAFEIST IS SPONTANEOUSLY COMBUSTING!!!!!!!!!!
THE GOAL OF COMBUSTMC IS ACHIEVED
kwall
🤔
we only do it for some things
RANDOMLY
every time you make a new class you flip a coin whether it should be kotlin or java
Fuck it, why not just pseudo code
bc we gonna compile it
ok fair
fair
No documentation either
Been working on the database side of things - got the main start of it done, no functionality to it yet.
Just want opinions on the database and mongo project to see if it's laid out well or not. It's based upon Morphia, just making it custom for versioning support and such
https://github.com/ignPurple/proxi
https://pastes.dev/3KKXd3CV6k git works
cache the MethodHandles.lookup()
dunno how much that gets called but its a factory
yea probably a good idea if ur orm lib depends on class scanning and invoking those class members at runtime
also not a big fan of printing a stacktrace and simply returning null
Which class is that method in @surreal peak ?
uhh
Ctrl + k btw
Im on phone :(
dunno then
but yea the error handling can definitely be better
no funnier things to do on phone?
I think you got me good there 😒
lol
So caching it as a constant like this should be fine?
yes
aight cool
Aight I commit and pushed for that change, and instead of just printing the stacktrace and returning null, I'm just throwing the custom exception instead
Thanks bois
oh god damn it, don't you love it when you don't click the big push button
fair, I just use the intellij way
@sleek shard you may want to let the api consumer pass their own lookup instance
If they want to use it on non public stuff where strong encapsulation such as module encapsulation stops outer modules from messing with those
well just an idea
^^
What I mean is that the api user of ur library maybe have private constructors, which means u wouldn’t be able to access it
U’d get an illegal access error/exception
doest lookup() have full access?
in such a case, it may be beneficial to let the api user pass a lookup instance that is allowed to
only public stuff
i think?
but theres also publicLookup()
uh idk my browser always gives me that
public static MethodHandles.Lookup lookup()
Returns a lookup object with full capabilities to emulate all supported bytecode behaviors of the caller. These capabilities include full privilege access to the caller. Factory methods on the lookup object can create direct method handles for any member that the caller has access to via bytecodes, including protected and private fields and methods. This lookup object is created by the original lookup class and has the ORIGINAL bit set. This lookup object is a capability which may be delegated to trusted agents. Do not store it in place where untrusted code can access it.
Yea try it out
show code
Yea, idk maybe my brain is screwed
reflection
Yes cuz iirc it checks the class u obtain the method handle in
the so called lookup class
Well skinny I know of what an ORM is, I know the design patterns and things but ofc there’s stuff that I have to read to understand, when reviewing code its a process of trying to first understand what the thing does, then see if you think it can be improved, that can be in terms of optimization in terms of time and space footprint, readability, maybe just better infrastructure, or maybe the names of classes methods etc are lacking etc
But yea @sleek shard letting us pass our own method handle may not be a dumb idea
Yea
anyway iirc privateLookup works as long as its in the class itself
That is u need to call privateLookup inside the class itself somewhere
well, there are edge cases w modules, but eh basically what i said above
One thing I can do - since I use bytebuddy, I could add a default constructor automatically
I think so anyway
Unsafe::allocateInstance 🐸
And yea even reflection struggle with the same access privileges as method handles due to strong encapsulation
I meannn-
it would work 
@round fossil do you advise against using Unsafe#allocateInstance
because it WOULD work that way
no constructor needed at all
Ah okay
considering Unsafe is deprecated
well idk if its currently deprecated but its being replaced so
they gotta give us alternatives then
Wait it seems to
its not initialized in a constructor
Yea that's the point of the default constructor, just to create an instance of the class
That's what I wanted the whole time
print the uuid instead
if its final it should also be null
.
https://gist.github.com/conclube/ec44a58feff052a37142ba230cddc2fa
Feel free to pick on anything ^^, some notes just:
- I wrote a monadic Either union type to deal with pipelining the composition of functions
- I am mostly concerned about ExtensionLoader::collectExtension (its so clumsy just),
as well as thecandidatestemp map since ExtensionHolder just encapsulates ModuleReference and Extension right now (like perhaps its unnecessary?). In the way its coded a lot of these functions are barely unit testable.
ahem

lmao
while im here, do you nerd db schema
Spacing is inconsistent
i mean i know about the theory
where?
Usage of Eithers, left/right -> Dedicated calss
spaces after commas
ah yea
myea, well it is in another class, was mostly to fit the gist
okay so lets say i have a db, in this db i have tickets but each ticket can have different data, atm i just have common data as collumns and individual data as a json value can i design that better
Personal peeve of mine but I'm starting to dislike seeing new after ()'s
Solution for this is either a dedicated method, or the usage of static factory pattern
Ideally both
Especially because if the structure changes to a map or something there are a lot of calls you gotta rewrite
kotlin
no new if new doesnt exist
Started getting picky about it after writing my command system
yeah its ugly to have a direct instantiation but that class is encapsulated within the bounds of the package so it shouldn't be an issue, if I change the underlying data structure I'd have to refactor those lines regardless
does this need to be a set? What's wrong with a generic collection
ModuleFinder::findAll produces that type
Collection will still work
yes but I don't want to iterate through dupes
conclube use ur nerd brain when you get a magical spark of nerd at 2:24am
so u're blobbing it rn?
@jagged rock btw illusion, what's ur thoughts on this:
" I am mostly concerned about ExtensionLoader::collectExtension (its so clumsy just),
as well as the candidates temp map since ExtensionHolder just encapsulates ModuleReference and Extension right now (like perhaps its unnecessary?). In the way its coded a lot of these functions are barely unit testable."
because that's what I'm mostly fixated at
technically yes, atm its just pure json so i can read it while im testing but i might eventually blob it
how structured is this json?
like do u have set formats or do the formats vary too much?
for example can you structify the different formats of ur json?
i dont think so, each ticket type would have different data like i have a commission ticket which would have like budget, name, description etc etc or i could have a suport ticket would would have other data relating to that
do u think candidatescould be completely eliminated?
i mean if u got another design in ur head
I barely understand what half of this does anyways
i mean sounds like u could have a table of commission tickets, a table of support tickets etc
But I'd like to see more Result objects and less throwing data in a map somewhere to get it later
i did have that before
That way you can create controlled Result objects to unit-test specific methods
but one @late smelt and @woeful pasture said to just have 1 table
yea, its always ugly when u have to put it in a map aside
the Eithers become results too
yea epic there's ofc advantages and disadvantages
Maybe cache the empty ModuleFinder
in your case the advantages far outweigh the disadvantages
idk exactly what data u're storing epic
yea I mean maybe, it runs during bootstrap of the app so im not too worried
Any guarantee this won't be empty?
yea definitely
Ticket data, so all data related to tickets that a user inputs, mostly strings or numbers
it cant by the specifications of module-info.java classes
each ticket type has different questions to be asked just throw it in json and slap it into an entry in the column table and deserialize the json. The amount of tickets you are dealing with will not exceed the capacity that this system can handle
you would need thousands and thousands of simultaneous tickets to even maybe strain this system.
this sounds reasonable, ill see if I can eliminate the candidates field, thanks
epic tbh it sounds like u maybe dont even need to have it that relational here
so one table might be the solution
i mean think about it, will u ever need to exclusively fetch specific fields from that json structure?
or ru just gonna blob fetch it?
True theres no data in it that id need to fetch from so json blob would work
I've now got the mongo client functional in some ways, e.g. saving data, and find method to get the cursor/list of entities. There is no specific filtering or finding a single entity yet, as that will be added.
Inspiration taken from morphia
https://github.com/ignPurple/proxi
would appreciate stars if anyone like's the project
How is this different from using MongoDBs driver POJO?
Basically - with this, it's going to include versioning of fields and an integrated DAO system, it will also have redis support inside of it and you can use redis and mongo in the same dao to retrieve entities from the specified databases. It will try and receive the entity from redis first, and if it doesn't exist - then it will do it from the mongo.
The way that the versioning of entities will work inside of the dao is -
The IDEntityDAO #createDefaultEntity will have all the default fields defined when it's called. Allowing it to modify the retrieved entity from the database, and adding new fields which exist with their default values
Example-
public class TestDAO extends MultiDatastoreDAO<UUID, TestEntity> {
public TestDAO(Datastore redisDatastore, Datastore mongoDatastore) {
super(TestEntity.class);
this.addDatastore(redisDatastore)
.addDatastore(mongoDatastore);
}
@Override
public TestEntity createDefaultEntity() {
return new TestEntity(UUID.randomUUID(), "New String Field" /* Added after the entity is stored inside of the database */);
}
}
// Old Entity which is stored in the datastore
{
"_id": {"objectid"}
}
// Entity when it's retrieved from the database and versioned using the createDefaultEntity
{
"_id": {"objectid"},
"test": "New String Field"
}
It will also have a custom metadata field inside of the database, which stores what fields are currently in the entity.
Idk, I just don't see the usecase over just using Mongodb + Redis + POJO. I don't see what can't be achieved with just using those opposed to this?
One problem I noticed is - when retrieving an entity from the database, instead of having some fields which you NEWLY added inside of the entities as the value you want them - they will just be null because the data doesn't exist inside of the database.
If you understand what I mean by that
Unless you use some custom codec for the classes you grab from the databases, which is just a bigger pain instead of it being done automatically for you.
I mean you can just do migrations. Which is the industry standard way when adding/removing fields in a db.
Yea, and this is basically what this would do for you automatically - in a way
You could just use https://github.com/mongock/mongock
Personally I never heard of mongock
shouldve called it caveman
I mean I honestly made this project for some fun - just to have a better portfolio of working with db's and stuff like bytebuddy
does vanilla have codecs for entities?
surely for the world entity saving
so i don't get why you couldn't use that :p
dfu ❤️
Is there an absolute need to use Java 22?
I mean Java21 is LTS so its often nice when libraries support that yk
Other than that maybe you wanna make space for us to pick different random algorithms (instead of strictly and internally using Random)
Try to pick an initial capacity that’s relevant to ur collections when possible, not only when constructing one collection from another .
I personally don’t like when libraries expose the usage of lombok, since it can force the library user to support it if they depend on the source jar at compile time for example
also remove .idea
and exposing collections is like nah
there seem to be a lot of redundant lookups
and what on earth is this
O(n^3) how fun
what a monstrosity on its own
how would you do it then
well first of all use a norma loop, that makes that atomic int go away
also doing that isEmpty check is useless
hi nerds :D
nerd
I mean at least u could use ::getPlain and ::setPlain
yeah true
ill look into it, thanks
The real problem with using AtomicInteger and just using getAndIncement, set, get, incrementAndGet etc is that they follow semantics of memory ordering effects of volatile, which means that it also flushes local caches since the value of the variable should be as up to date as possible, which is useful in multithreading where memory visibility can become an issue, that is two threads observe different values for the same variable
Edit which is why getPlain and setPlain is recommended as they behave as normal variable reads and variable writes
nerd
uses lazySet with no knowledge of anything whatsoever
lazySet or weakSet?
how can a set be lazy?
I mean weak is for CAS
ah
yea well using opaque and release on the other hand is just so hard as there is usually so many invariants
I guess memory fences are a better way of lifting the constraints of memory ordering effects
But yea you could technically use lazySet to CAS also if you do it correctly
ig im not fully awake yet hold on lol
weeell idk if there’s so much to wake up to
I mean its just that volatile is nice, but its TOO ExpEnSIvvE, so java obviously has ways to decrease the constraints of memory ordering effects yk
So iirc there’s acquire, release and opaque (one behaves like atomic but for writes only, one behaves like atomic but for reads only, and idr the property of the third one)
and then there’s memory fences, which… well they do the same thing (decrease contraints, but its useful if you have multiple state variables that have invariants to each another)
yea
sounds like its time to watch another one of those two hour videos about javas memory model
Lmao
But then i think acquire and release were just the volatile ones with less contraints, right?
idk i only know those are for loads and stores
anyway the only mystery is weakSet which is like, it may fail for no reason on certain machines, so its unreliable unless you’re invoking until it eventually succeeds
:/
Tbh I think there’s a lot of info about this in the java concurrency book
maybe i should read it
the only book around concurrency i read is "operating systems in java" or smth
👀 java concurrency book?
didnt knew it either
Java concurrency in practice
Its written by a some of the java devs, brain goetz or whatever that omniscient java guy is called who knows everything
Allow me to break everyone with a single line
private final Set<ServerPlayer> trackingPlayers = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap());```
why you gotta be so hard?
Note: I have no idea if this even works
Generally speaking, a doing this on a normal ConcurrentHashMap fucks it up hence why newKeySet() is encouraged, iirc MapMaker specifies by default a concurrency level of 4 achieving similar semantical implementation to a normal ConcurrentHashMap, I think caffeine the cache library does support a weak concurrent hash set tho
Didnt read into it, does this use wave function collapse, or is the generation based on noise?
Nvm, it just generates a "main path" and then fills the rest with random stuff.
it needs to be procedurally generated, there are specific rules to be followed.
like no looping back on itself, add shapes, starting and ending room are only on the walls, and some other complicated rules.
I'm curious as to if it would be possible with wave function collapse
Sure, i remember reading a paper about that. Something something "Enhancing wave function collapse with constraints"
I'll do some research on that topic, thanks mate!
https://github.com/NukeCaps/CustomItemEffects/tree/master/src/main
Looking for some notes/suggestions rather related to OOP. Been practicing with trooper and just wanted to see what others think?
(The listener isn't registered kek, forgot to do that in the latest commit)
calling a variable customItemEffects literally says nothing for me
also please make a lookup thing
Elaborate please! (if you wouldn't mind <3)
also ItemStackCreation should be called ItemBuilder or smth
Yeah my naming is meh for sure
like why do those things exist if its a builder
Well the getCreatedItemStack is for some stuff elsewhere but yeah you're right
also cache that key
instead of a public list for your custom items :/
use kotlin
Also you just mean like some function that'll pull from the list instead of directly accessing when I need an item or wtv
well basically, and i see no reason to make it static
and List.of if you wanna go crazy
Gotcha gotcha
Love some review on this framework I’ve started on a while back
Specifically on the framework as an external asset, and command & menu systems as a whole
Remove the .idea folder
A lot of these utilities are nice but miss an edge to me. E.g. lack of component support. I think you should try and support components where you can we with spigot right now. And if you're willing to dip into nms support components on items etc
Component being the new string builder stuff with colors and that
cringe, use the scheduler
isn’t it exactly the same considering the Runnable#runTaskTimer calls the scheduler
kinda, looks way better
I can definitely say the other way to run tasks looks cleaner
yeah gotchu
Considering it's mostly small utilities it's hard to say there are any glaring issues
yeah i guess
menu practical system tho?
Yeah it's simplistic but practical
any improvement ideas?
Not really without dipping into nms
If you want ideas on something maybe a bit more powerful I have an api that uses 100% nms and I also have a partial nms one
Ares singleton field should be named instance without capitalization its not a true constant, work more with implicit else/guard clauses, your function in PlayerUtils makes little sense, TimeUtils is bad you should favor DateTimeFormatter, prefer boolean state to unregistering a listener via its handlers, what’s the point of BoardAdapter - it doesn’t seem to follow the adapter design pattern thus misleading name, split ur execute() method in CommandData - its too long, not sure why you suffix ur Listener derivatives to Handler - its misleading since they do not handle the event its fine to name it something such as CommandListener; rather they just listen and observe it, avoid abstract classes when there’s much state and many abstract methods that derivatives need to implement it causes tight coupling
yeah thats feedback i was looking for, thank you!
@Nullable
private ArtifactContentIndex generateArtifactContentIndex(@NotNull ProjectIndex project, @NotNull MavenVersion version) {
NavigableMap<MavenVersion, Changeset> changesets = project.changesets.getReadView();
Map.Entry<MavenVersion, Changeset> changeset = changesets.floorEntry(version);
if (changeset == null) {
return null;
} else if (changeset.getValue() instanceof FullChangeset fullChangeset) {
return fullChangeset.index;
}
MavenVersion currentVersion = changeset.getKey();
while ((changeset = changesets.lowerEntry(currentVersion = changeset.getKey())) != null
&& !(changeset.getValue() instanceof FullChangeset));
if (changeset == null) {
throw new AssertionError(project + "; " + version + "; " + currentVersion + "; No full changeset encountered.");
}
ArtifactContentIndex aci = ((FullChangeset) changeset.getValue()).index;
while ((changeset = changesets.higherEntry(currentVersion)) != null
&& !(currentVersion = changeset.getKey()).isNewerThan(version)) {
aci = changeset.getValue().updateContents(aci);
}
if (changeset == null) {
throw new AssertionError(project + "; " + version + "; " + currentVersion + "; changeset null.");
}
}
So people said I should nest less - are you happy now?
Well the return thing is caused by me forgetting a single line
Obtain the highest entry whoose key is below the currentVersion and whoose value is of instance FullChangeset
The code probably has a few bugs - we'll see whenever I put it into production.
Jk, I'm writing unit tests for this
we all know that last line is a lie
Well the last line should be return aci; - but that is a bit obvious, innit?
Okay after a bit more of unit testing here's teh final result:
@Nullable
private static final ArtifactContentIndex generateArtifactContentIndex(@NotNull ProjectIndex project, @NotNull MavenVersion version) {
NavigableMap<MavenVersion, Changeset> changesets = project.changesets.getReadView();
Map.Entry<MavenVersion, Changeset> changeset = changesets.floorEntry(version);
if (changeset == null) {
return null;
} else if (changeset.getValue() instanceof FullChangeset fullChangeset) {
return fullChangeset.index;
}
MavenVersion currentVersion;
while ((changeset = changesets.lowerEntry(currentVersion = changeset.getKey())) != null
&& !(changeset.getValue() instanceof FullChangeset));
if (changeset == null) {
throw new AssertionError(project + "; " + version + "; " + currentVersion + "; No full changeset encountered.");
}
ArtifactContentIndex aci = ((FullChangeset) changeset.getValue()).index;
currentVersion = changeset.getKey();
while ((changeset = changesets.higherEntry(currentVersion)) != null
&& !(currentVersion = changeset.getKey()).isNewerThan(version)) {
aci = changeset.getValue().updateContents(aci);
}
return aci;
}
Honestly, working with iterators is a fun exercise - especially when you're trying to produce code that is as unconventional as possible while doing so
should just be an else if anything
but they could just invert their condition instead
and just make it a single if
I generally do that to save a single line of code and from a logical perspective it's not all too bad either
https://github.com/Psikuvit/Friends
any tips before I finish?
dont call your main class Main, call it FriendsPlugin or smth
also what does class Friend say to me? FriendsManager maybeµ
in your main class
private MySQL mySQL;
private Database database;
what??
use dependency injection instead of a static instance
?di ^-^
Guide to dependency injection: https://www.spigotmc.org/wiki/using-dependency-injection/
FriendAdd -> AddFriendCommand?
unchecked casts commandsender -> player
comparing player instances with ==, i mean not an issue perse
I am using that
use the new instanceof syntax
not for your main class and mysql thing
ah nvm
id just use Arrays.asList of List.of ere
that is an absolutely useless arraylist right there 
loadHashMaps() and saveHashMaps() is like a terrible name? saveData()?
what even does local mean in this context? make it more clear
MySql has a hard dependency on ConfigManager, maybe try to avoid that, try to pass that config manager as constructor param or pass in a ConfigurationSection?
wdym
how do i explain this uhh if you ever get rid of that config manager thing, your code will be kinda hard to refactor assuming you use that class directly everywhere
uhh
cause its static?
uh thats one thing
its also kinda fucked cuz all it does it provide YourPlugin::getConfig()
like hoping that file trick works
and String::replaceAll is for regex btw, you want ::replace (in that same class)
like is this what coloring means lol?
also not a big fan of exposing collections in your Friends class, you have em private but share em public either way, whats the point then
addFriend(), removeFriend() no?
this contains/ put call can also be optimized, putIfPresent
maybe even consider map::merge to replace that whole block but idk the exact parameters out of my head
and doesnt List::remove already return a boolean?
@surreal peak
playerFriends.merge(playerUUID, friends, (oldValue, newValue) -> newValue);
that works?
I updated it
please look now
put already overrides the previous value
So both calls are meh
Watch me be picky:
-
Utils:10 Single letter variable, should be renamed to something a bit more specific
-
FriendsPlugin:19 Poor / confusing ordering of methods, put your static getter at the bottom
-
FriendsPlugin:31 Repeated method calls, unscalable if-else chain. You should use some sort of database registry / provider pattern
-
FriendsManager:11,12 HashMap -> Map. Hide implementation details, If you decide to change the data structure later on, you have less to change
-
FriendsManager:29,33 Return a defensive copy of the map (Map.copyOf), otherwise the method that calls it can mutate the map at will.
-
FriendsManager:41,57 The friends manager shouldn't be responsible for sending a message. Use a return true/false for that.
-
JoinListener:11 Single letter variable, should be renamed to something a bit more specific. The entire class is pretty much useless but I get this is unfinished work.
-
DatabaseType:4 SQLite -> SQLITE, Follow naming conventions
-
MySQL:16,17,18,19,20 msqyl -> mysql. You should allow for the option to use a connection string
-
MySQL:47-60 This class shouldn't be responsible for creating the tables with your very specific structure. It's only responsible for managing a mysql connection
-
SQLite (the whole class) This class should be renamed because it doesn't represent an SQLite database, but rather a flat-file (yml). It also saves everything in a single file, which is AWFUL for performance and should NEVER be done. (If you have ~100k entries your server takes up to 5 minutes to load)
Not much to comment about your command system. It's really primitive and could use some better naming here and there
Some of this could've been fixed had you read #help-development message (It's pinned)
Is Map.copyOf different from Collections.unmodifiableMap
Deep vs shallow clone iirc
the former creates a new map under the following conditions:
- The map is not an immutable map
- The map is not empty
Then it simply makes a new array of the entries, the objects within are still the same but you can edit each map indepentently
the other is just an unmodifiable view over the underlying map
1st one is so dumb since it assumes its gonna be that ImmutableCollections.ImmutableMap or sth