#[MEGA THREAD] Get Your Code Reviewed or Review Others
1 messages · Page 8 of 1
that is definitely one of the solutions of all time
heh
I mean I just think its a pity that ImmutableCollections doesn't expose its nested types for one
rad this is the 3rd time you've sent this screenshot
potentially
when we don't have mapOf(k to v, k1 to v1,...) so we need ImmutableMap.Builder 
yeah but its much more verbose (ofEntries() )
well not that the builder isn't but mye
yes but it only goes up to like 9 entries 
fr
I mean you have to be a little crazy to hardcode more than 13 entries by hand
yeah
unless its like a lookup table or something
yup
this is why there should be syntax sugar for pairs
and just have it be a vararg of pairs
well kotlin has the first class higher order infix (maybe inline) to function
tbh im lil jealous
infix is super cool
yea I mean I get it can be a bit confusing also, but it has its place
perchance
haven't found a good usecase for custom infix yet
I mean the way its used in the gradle api is nice
i so badly want to find a usecase for abstract extension functions
that would be really cool probably
same
it probably doesn't work
but you showed it to me
so now i am in two minds
There’s Map.ofEntries
yes but its so verbose
kotlin stdlib ❤️
Map.ofEntries(Map.entry(k1,v1),...) 
smh

warm take: every two letter combination should be a tld
maybe even three letter but that's a stretch
.rad
based
https://paste.md-5.net/dapiyupibu.java
Could I get some feedback on this? Practicing with some abstraction and generics
Looks solid to me
i would specify what semantics RegistryInterface::getRegistry() has in that class
immutable, unmodifiable view etc
your.mom
damn
also whats te point of that logging
you're using the abstract/base design pattern slightly wrong
usually u'll see sth like this:
public abstract class AbstractRegistry<T> implements RegistryInterface<T> {
protected abstract Map<String,T> getBackingMap();
@Override
public Map<String, T> getRegistry(){
return Collections.unmodifiableMap(this.getBackingMap());
}
/**
* Registers an object with an associated key.
*
* @param key The key to assign to the value.
* @param object The object to register.
*/
@Override
public void register(String key, T object){
if (key == null || object == null) {
throw new IllegalArgumentException("Key or Object cannot be null");
}
this.getBackingMap().put(key, object);
}
/**
* Unregisters an object with associated key.
*
* @param key The key to unregister.
*/
@Override
public void unregister(String key){
if (key == null) {
throw new IllegalArgumentException("Key cannot be null");
}
this.getBackingMap().registry.remove(key);
}
/**
* Get an object from the registry.
*
* @param key The key used to get the object.
* @return Returns the object found with associated key.
*/
@Override
public T get(String key){
T object = this.getBackingMap().registry.get(key);
if (object == null) {
Bukkit.getLogger().severe("Object with key " + key + " not found in " + this.getClass().getSimpleName());
}
return object;
}
}
also ur singletons are not thread safe in case u're gonna access it across multiple threads
smth like this:
one minute later, still waiting on what comes after the this
haha yea idk discord editing mode is so goofy
also you may wanna life cycle a root registry that holds all the other registries, that way u don't need to have the arbitrary lazy initialization but use a more defined initialization stage
RegistryRegistry :}
just use nms registries bro
they're nice but they're a bit too tied to minecrafts need
i love em
I mean obv u can just grab ur own mapped registrty instance, but like u'll need to define lifecycles, intrusive holder possibilities etc
i copied some of yarn's mapped registry code and improved it for bukki
t
like changing Identifier/ResourceLocations to NamespacedKeys
yea

yeah i could NOT be bothered to rewrite them in kotlin
too many lambda and nullability errors
- generic errors

and then i just
ah java code is just that bad u say?
java and kotlin in the same module !?!!
hehehe
i do that too 👉👈
i feel like thats way nicer if u write it with interoperability in mind
this is why i write all my libs in kotlin
so java users feel left out
like they should /j
banned*
tf are those first three statements in your constructor
💀
if only we ahd unsafe::ensureLoaded
class.forName(AceRaceGameData.Companion::class.java) then
it's currently still json, but will be nbt soon™
i could probably improve a lot there
now i see why people hate on kotlin
i mean this looks so nested, but yea I suppose some nicer formatting would make it looks more beautiful than java (ever would)
doubt
🤨
this better
no
stfu
💅
maybe remove explicit type
why open ij when you have nvim
because kotlin lsp is so fucking shit
hehehe 🤡 🤡
fabric
ig
no plugin
oh yh sry
Gotcha, also what makes the system unsafe for multithreaded actions? I mean I tossed some synchronized keywords around as well as using concurrent maps
Really gotta get this netty lesson from trooper lol
ur singletons are not atomic
Like if two threads access the singletons concurrently there’s a chance u get two instances instantiated or even more
Hmm alright got it, how does the design look?
OOP wise I mean, I think it’s pretty good, reusable, expandable, and when I fix a couple things thread safe.
This
RegistryInterface<T> is such a terrible name imo. should be IRegistry<T> or just Registry<T>
And also you may wanna explicitly rely on CononutMap blah = new ConcurrentHashMap
CononutMap
^
Noted, I will fix those things. Whatcha think of the idea?
Everyone loves a good registry
net.minecraft.registry on top
sh.miles.pineapple.collection.registry on top
coconut map
Is that like coconut mall
no its like the coconut nut is a giant nut
What
A Catchy, Silly Song. . .
Real Video: https://www.youtube.com/watch?v=w0AOGeqOnFY
Love that song
I made my own event that fires every time a player's equipment changes which I'm using for an NPC that copies a players actions. I appreciate any feedback especially if I made mistakes that ruin performance.
Event: https://pastes.dev/Jhr9RUkqts
Listeners: https://pastes.dev/dThl1udkoJ
It's pretty long so thanks in advance for anyone trying to read it
Don't use EnumSet as that might break in the future also you can use tags to find armor items
Oh I didn't know that thanks, I tried using tags but tags like ITEMS_HEAD_ARMOR on the javadocs don't exist inside my IDE
They might be too new for the version you're using
https://paste.md-5.net/awojimenaz.java
good organisation?
are you really extending craft bukkit classes
// Adjust this value to control the shake intensity
chatgpt intensifies
also don't hardcode skin textures
EntityPig isn’t a craftbukkit class
is it not?
yes
i just saw a import net.minecraft.server.v1_16_R3.*; and thought it was
craftbukkit is CraftEntityPig
EntityPig is an NMS class
// Adjust the interpolation factor as needed
this sounds literally like something chatgpt would write
but genuinely why the fuck star-import all of nms
well chatgpt is bad when using NMS
I did not
the IDE did
yeah then disable that
literally just google it lmfao
people cannot google to save their fucking lives
look at #help-server
yea
why google when you can ask chad gpt?
you forgot chatgpt
I haven't used YT for dev stuff that often really. But ChatGPT is completely absent in my dev workflow
best thing ever ^
im not gonna write things 255 times over using ai to generate it
Probably ends up making it less efficient
yeah
shit
if you ened to do that, then there is something going wrong
opcodes
This is my last time using chatgpt, which one is better?
public void before(List<EntityData> list){
List<EntityData> clone = new ArrayList<>(this.list);
List<EntityData> result = new ArrayList<>(list);
Set<EntityData> removal = new HashSet<>();
for (EntityData data : list) {
for (EntityData d : clone) {
if (d.getIndex() == data.getIndex() && d.getType() == data.getType()) removal.add(d);
}
}
clone.removeAll(removal);
result.addAll(clone);
this.list = result;
}```
```java
public void after(List<EntityData> list){
List<EntityData> result = new ArrayList<>(list);
for (EntityData data : this.list) {
if (result.stream().anyMatch(d -> d.getIndex() == data.getIndex() && d.getType() == data.getType())) continue;
result.add(data);
}
entityMetaData = result;
}```
the goal is to add this.list to list, without duplicates because I'm using metadata packets so I have to open up the EntityData and compare the index and dataType
You could just put it in a Set if you want to not have duplicates.
Depends if the values properly implement equals and hashcode
no because i'm not comparing the objects, but values inside the objects
That’s what equals and hashcode are for :p
ah, probably not because entityData contains an index, dataType and value. And I only need to compare the index and datatype and the value can be unique
I mean maybe ai can optimize certain functions, but the reasons for why you made those functions in the first place may be wrong, so all AI is gonna do is polish a turd
im not saying thats what happened it this case cus I havent read it
its just from what I know tends to happen
Yeah the only reason it works for me is because I'm intermediate, if you've been programming for years you are probably better than the currently available AI chatbots
and obviously I don't just copy paste AI's code, I read it, compare it and logically conclude which is better for what I want
not too difficult to be better
rn it's pretty mediocre, but eventually it will be better than everyone
doubtful
it has nothing more to learn
it can only be as good as the combination of everyone humans have already done
lets agree to disagree lmao
sure
even for that you generally do not need to do so - unless you are reinventing the wheel there
yeah i hate that second one
why?
unreadable
java collection/stream operations look terrible and suck
kotlin.collections >>
thanks
- don't use single letter variable names
I asked "why" for learning purposes and you answered in a respectable way. That's why I thanked you
cancelTaskForPlayer(player);
Inventory inventory = player.getInventory();
BukkitRunnable task = new BukkitRunnable() {
@Override
public void run() {
for (int i = 0; i < inventory.getSize(); i++) {
ItemStack item = inventory.getItem(i);
if (item != null && item.getType() == Material.ECHO_SHARD && item.hasItemMeta()) {
if (item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().contains("§aʀᴇʟɪᴄ ᴏꜰ §3§lᴛʀᴀᴠᴇʟ")) {
tickTravelTask(player, getRLevel(item));
}
if (item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().contains("§aʀᴇʟɪᴄ ᴏꜰ §c§lᴇᴍʙᴇʀ")) {
tickEmberTask(player, getRLevel(item));
}
if (item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().contains("§aʀᴇʟɪᴄ ᴏꜰ §6§lᴛʀᴇᴀsᴜʀᴇ")) {
tickTreasureTask(player, getRLevel(item));
}
if (item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().contains("§aʀᴇʟɪᴄ ᴏꜰ §1§lᴍᴀss")) {
tickMassTask(player, getRLevel(item));
}
if (item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().contains("§aʀᴇʟɪᴄ ᴏꜰ §4§lᴄᴏᴍʙᴀᴛ")) {
tickCombatTask(player, getRLevel(item));
}
if (item.getItemMeta().hasDisplayName() && item.getItemMeta().getDisplayName().contains("§aʀᴇʟɪᴄ ᴏꜰ §2§lᴛʀᴀᴅᴇ")) {
tickTradeTask(player, getRLevel(item));
}
if (item.getItemMeta().hasDisplayName() && item.getItemMeta().getCustomModelData() == 10) {
item.setAmount(0);
}
}
}
}
};
playerTasks.put(player, task);
task.runTaskTimer(WardenRelics.getInstance(), 0L, 5L); // Repeat every second (20 ticks)
}```
use the scheduler instead of summonining random bukkitrunnables
whats a scheduler can u send a link to some docs or something
are like schedulers better performce or something?
i mean just use the scheduler method (Bukkit.getScheduler().runTaskTimer()) instead of creating random bukkitrunnables for no reason
it's ?scheduling
there are three ways to represent inheritance trees in sql databases:
- a table for the whole tree (base + child classes)
- table per child class
- table for base, which stores the id of the child and a discriminator and the child data is stored in another table
Tell me if you find any possible optimizations
Or problems
src/shadow contains the actual optimizable code
remove .idea
you can simplify package names "AlixSystemBungeeSupport" -> "bungee"
oouch
Why the option "compact packages" should exist ?
exactly
Oh..
That's even a bigger problem imo 💀
should have a seperate api package and a core package
would make the codebase so much cleaner :D
Separated api in a separated project ?
Such separation is usually overkill - instead try to treat everything that is public as public API
Or just use JPMS/jigsaw
Well ideally you do both
Modules
make it AutoClosable if it really needs to be closed
actually makes more sense for "short" lived objects though
That Map<String, PunishmentData> part could be its own result class
okay maybe its just me, but I've never understood @NotNull inside of Maps an arrays and such. Shouldn't it be implied, especially within a map that your key can't be null and neither can your value. In which case its just redundant to type
Nullability within array types seems excusable but outside of that it seems like it just clogs up unecessary space and makes things harder to read
riddle me this
if the key can be null
how do you identify the value of the null key
you should also not really ever have null values within the value of the hashmap
that's the wildest thing ever. Still such and edge case do you use it? If not its pretty much redundant
I don't think anyone expects such behavior
why
there can't actually be a good reason for such a key
I was just wondering why people did that
its always been the reason I use java5 annotations
because they can't go on those subtypes and IntelliJ doesn't try to coerce me to use them as such
no just at your entry in discor
nothing about your code seems wrong or seems like it needs to be tweaked though
ig my only question would be to the benefit of SavedPunishment itself
@night knoll ^
what is the ID related to?
player UUID or what
I mean you usually wanna shutdown, await termination (that is wait for any tasks that are still running to complete) and then in worst case scenario you can shutdownNow
now it highkey sucks because shutdownNow gives any tasks that weren’t finished, so u dont rly know how far they came before they were forcibly shutdown, i mean u could rerun eventual tasks given by shutdownNow, but eh, I mean I’d try to just have some sort of policy for the tasks I’m submitting to the ES in the first place
and yes this is what thread interruption lowkey “tried to address partially” but it’s cumbersome and often comes in the way so goofy java (ES being a prime example)
Hey, could someone tell me if this code to add enchantments via PDC is great or not?
I think it looks decent, but cache your namespacedKeys
wdym
public int getEnchantmentLevel(ItemStack item, String enchantName){
if (item == null || item.getType() == Material.AIR) {
return 0;
}
ItemMeta meta = item.getItemMeta();
if (!item.hasItemMeta()) return 0;
NamespacedKey key = new NamespacedKey(plugin, enchantName);
return meta.getPersistentDataContainer().getOrDefault(key, PersistentDataType.INTEGER, 0);
}
For example you create a new key object here when gathering enchantment level from an enchantment (presumably this enchantment already has a namespacedkey)
I would think newly registered enchantments to be the only ones getting "new" namespacedKeys
no kotlin :(
we men solve it with @Contract(pure=false)
I think this works?
It is being created just 1 time right?
Once per instance of customEnchant
static importing plugin instance
I should do this too lol
is it wrong? xd
Not something you usually see thats for sure
dEpEnDeNcY iNjEcTiOn
someone wants to extend your plugin, nope they cant without modifying getInstance
well you get it (i hope)
I usually do that, but there are some classes where i don't
This looks like a decent key registry
Just a bit
Yea, but i need those keys in other parts
bloat?
ever heard of bloatware
nope
Which is the point of a registry, just query your regitry for the keys you need
Shouldn't I cache those keys?
i mean its just gross and pollutes your own with unnessecary things
but what's that
Again the point of a registry
duplicated code, code you dont need and such
In computer programming, code bloat is the production of program code (source code or machine code) that is perceived as unnecessarily long, slow, or otherwise wasteful of resources. Code bloat can be caused by inadequacies in the programming language in which the code is written, the compiler used to compile it, or the programmer writing it. Th...
well creating the key, the container.set call, the getInstance
could do java <T> void register(String key, PersistentDataType<T>, T data)
or how that looks in java, my brain is fried by kotlin generics
One of the biggest OOP things is abstraction, when you start to understand it a bit better you realize that some functions could have been turned into single line functions rather than a whole method filled with duplicated code
Everything is an object
Yea, i haven't really looked into abstraction
reminds me of how entities get serialised
Also instead of manually container.put's, you would rather just register whatever it is you need when you create that object
So when creating a custom enchantment, the key can be created with it then registered, this allows some paths for server ops to create their own enchantments and whatnot
also why not use the 1.21 api for that
That being said, you'll still probably want some default enchantments to show the structure, it really depends on if you want that sort of QOL... could be handled through like a yaml or ingame just depends what you are up for
Yea, ik
I'll try what you have told me, thanks
Try to practice with some generics as well
These are keys to abstraction
some resource or video I can look to improve?
Full tutorial for using Generics in Java!
☕ Complete Java course:
https://codingwithjohn.thinkific.com/courses/java-for-beginners
Generics in Java can be very confusing for beginner Java learners. Generics are one of the coolest features in Java, but the syntax may not make a lot of sense at first.
In this beginner's Java tutorial video, we'...
thanks
What are abstract classes and methods in Java, and how and why would you use them?
Also, what's the difference between an abstract class and an interface?
Abstract classes can seem like a wacky, complicated Java concept, but they're pretty simple. We'll explain them in just a few minutes in this beginner Java tutorial video lesson.
How do I ma...
Yeah no worries
I just have static fields for my namespaced keys
https://paste.md-5.net/ucibecoxip.java
I need more advice on this, I think it's alright but what can I do to make it better?
getRegistry() should be annotated with UnmodifiableView
Maybe its ImmutableView idr
Consider using a util class to assert invariants on incoming arguments
For example Preconditions::checkArgument or Objects::requireNonNull
Could you elaborate on that a bit more?
I'm a bit confused by this
ah so invariants just mean conditions
Ohhh ok gotcha
assert means check that the conditions are valid/satisfied, in ur case non null
Also I'm not seeing either of these
It's UnmodiableView
That being said, make sure you use the normal annotations artifact
The annotations-java5 artifact does not include it
I have had little practice with annotations, where do I configure this?
I assume latest for this is fine?
I really need to learn more about maven kek
Or GrAdLeEeEEEEeeeee 🐘
I personally use scope = provided and optional = true (which is equivalent to gradle's compileOnly configuration), in order to not mess with transitive deps
Only project I have with gradle is my netty practice I did with retro
Eh I mean gradle is best of them all if u need a customized work env setup
but like
its not good
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>24.1.0</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
This works yeah?
? 🙂
What exactly dou want us to look at?
Nah not really, i mean there’s not a lot of code to discuss lol
Is there anything that might be beneficial to add?
code structure, variable naming, hardcoded methods
Lol what's wrong with the docs
idk I mean registries can be a hard topic if u allow it to
Gradle's only weakness is it's forwards and backwards compatibility - or rather said, the lack thereof.
If it had that, it'd be great. But I'd still stay that gradle (like maven) is quite good, but I can mainly say that because I've used other buildsystems in the past
When you start to consider ownership, deferred population of entries, multithreading, serialization and deserialization of entries over file IO and network IO, versioning, reverse lookups etc nuclearkat
ok ok I get it
Yea, I also think their builtin plugins are poorly designed to the consumer
The fact that we had to include our own shading and relocation plugin is just insane
for years
@Override
public T get(String key){
Objects.requireNonNull(key, "Key cannot be null");
return this.getBackingMap().get(key);
}```
Should I keep the if (object == null) check here?
ofc it makes sense cuz in the real world its rarely the case where u shade and relocate a standalone jar that doesnt have a proper manifest etc
Oh, not being able to define custom variants is another gripe of mine (or rather said, only through gradle plugins, but not via the buildscript), but I'm probably one of 0.1% of people that actually need/want to use gradle variants
but still, it shouldn’t be so hard as to having to apply third party plugins
ye
requireNonNull does it foru
U can have ur own class for it
Its just that u kinda wanna boil down the verbosity of checking incoming arguments are valid
Is that needed if it's already written into the abstract registry methods?
wdym
Objects.requireNotNull already means the key/values can't be null so moving these to a util class provides what benefit is what I'm trying to get at
oh I mean like
class Asserts {
static void notNull(Object o) {
if (o == null) throw new NullPointerException();
}
}
U just have ur own instead
and use that
What's the problem with using the JDK-provided classes here?
There’s no problem with using it
but its often more flexible to just have ur own, lets say u wna inject a logger to it for debugging, or whatever, if i use preconditions, verify or objects the only issue is that I’d have to use some stupid tools to do that
Also, I'd personally annotate the registry keys argument as @NotNull if you perform the null check here
^
That’s true, or have like a @ArgumentsNonNullByDefault type of annot
I know some annot libs provide those
I personally don't like those as eclipse doesn't know too many nullability handling annotations
Good thing I use intelliJ
lol
Well I still assume it knows of @DefaultQualifier
and other known big annot libs
It only knows it's own null annotation handling library
So Nullability, NonNull and NonNullByDefault
NonNullByDefault looks good enough
Well you can configure it, so it's not too much of a problem
btw geol I got a completely off topic question for you
what's the difference between NotNull and NonNull?
none
Nothing 
oh kek
sure, hit me up
I just saw it while I was typing @No kek
Dou know any editor or extension in any ide that lets me take a decompiled class, edit it and generate me the edits by a set of mixins?
That unlikely exists plainly because mixins are too case-by-case dependent
Yea true
I would really wanna attempt writing such a program
think it’d very useful, just was curious if one already existed
Ah you probably have javax.annotations or some other library on the classpath. I hate when libraries don't use optional = true here
I thought I even put that on the annot depend
Or is that lib specific?
Yeah, it's the API providers that need to define that
Ah
You could manually exclude the dependency, but that is a little bit overkill
I am not really bothered by it
That being said, I've heard that the MinecraftDev plugin for IJ can get you ridiculous efficiency when writing mixins, but I never checked it out
Yea it mostly auto completes suggestions
Also, intelliJ is yelling at me here
When typing out the long names of classes and method signatures
oh

12 am for me :P
public void unregister(@NotNull String key) { is what you should be doing instead
I've only been awake 22 hours now
Yeah I just realized that lol
That being said, you might need to kill the default annotations-java5 library from the classpath as it has slightly different semantics when it comes to NotNull and Nullable
Do I find that in proj struct?
nah, you need to exclude the dependency, it's a bit complicated so we'll only really do that once you need to annotate a type and annotations-java5 forbids you from it (on the other hand, you probably could just reorder the dependencies in the pom methinks)
Do you mean generic in this case or just any type?
The type target includes generics, but also variable declarations
Hey, it's me again xdd
So i'm making this api for a currency and trying to adapt it to use database and file depends on the option.
https://paste.md-5.net/ozotefigab.java
I've made this code and was wondering if it is great and doesn't affect that much the performance of the server
what do you think?
whats even the point of that useDatabase
To use database or files
use inheritance or smth
if useDatabase = true | database
and youre never closing your statements
why?
true, done that already
makes more sense to have two classes with their own responsability imo
But the way I manage the data is okay? Or can happen memory leak or something?
you arent saving either if you do a config.set
use a try with resources
oh
Read it 👍
make folder names lowercase
extend TabExecutor instead in your commands if you want both executor and tabcompletor
if an user types command aaa they will get the reload completion either way
use StringUtils.copyPartialMatches
look at its internals
also public mutable variables, hell na
saveDefaultConfig() instead of this
tf is this nesting
so thats had pyramids were built then
The aliens didn't do it, some dev just wasn't following proper oop
copied metrics class contains some nonsense too
what about my cloud commands tho, which one's worse
idk
the commands are atleast somewhat organised
Make sure to actually apply the habits
You seem to toss everything in your main class, repeat function calls all the time (getConfig()), get values from the config instead of caching them into fields, the list goes on
The habits applied are wildly inconsistent too (guard clauses deeply nested)
I'd give it maybe a 3/10
I am doing it rtn
@jagged rock
Can you help me with the nesting?
I am so lost.
its just instead of if condition you have if not condition return or continue
if(thing){
DoThings()
}
Guard clauses
if (!thing){
return
}
doThings();
put that return on the same line
I believe I cover that on the thread
Otherwise, #help-development , check pins
i see a missing !
nuh uh
It is also missing a semicolon :p
trueeeeeeeee
Kotlin
```java
if(thing){
DoThings()
}
```
Guard clauses
```java
if (!thing){
return
}
doThings();
```
Exposed
I smell someone using illegal discord modifications
mongo 💀
hey I like mongo too
what
why double getter
why no kotlin
fuck kotlin
because?
ignorance
i hate kotlin as much as i hate dogs
why
personal preferences
buddy never used c
lombok is 10x worse
So fuck that lombok horse you rode in on, do us a favor and delombok ur code
Alt insert is in shambles
holy shit you actually said the normal person keybind
Eclipse and IntelliJ have the same keybind there I think
i was going for the fact you use vsc keybinds
It's eclipse Base
I changed to some vsc for a few things but it's mostly eclipse
end your plugin class name in Plugin
and why use an instance of ConfigUtils, a real utility class is stateless, which isnt the case here
inheritance
not sure if you want to store punishments in a list
do not share mutable collections
why use final in parameters
imagine using classes for plugins
couldn't be me
why CommandAbstract and not AbstractCommand
these sound pretty vague to a new reader
why end with Plugin, is that the style guide?
could use Map.of
i always do it, i mean what kind of name is BetterPunishments
if someone didnt know we were working with plugins, they would have no clue
take a look at StringUtils.copyPartialMatches
why BanArg if it extends CommandAbstract?
and i would inject the punishment manager instead of the plugin instance, you dont even need it
theres not even a reason CommandAbstract is an abstract class
this feels like a usecase for a Punishment::fromX factory method, also mismatched responsability
I would probably rename it to BaseCommand or something then
same thing: inject config utils instead then 🤷♂️
also why does class MySql not extend Database or smth
wait MySqlData does, what kind of name is that
and return something in loadData()
maybe a boolean, maybe a future if you decide to do it async
like that MySqlData class should be renamed to just MySql[Database] and that MsqlData class shouldnt even exist then, put everything in that one class
and i dont really think its the responsability of a data loader to load the data into the punishmanager that it holds, it should just return it imo, and the caller decides whether it wants that data in the punishment manager
i think you can just close it without writing, set truncate bit
why
time for dinner now
lemme post this here http://www.javapractices.com/home/HomeAction.do
Some good bacon hehehe
saveDefaultConfig() 🗿
Shouldve let it marinade more
And add fewer salt
Shall we make this a cooking channel?
🖕 lombok
https://github.com/eliottlebot/thetowersplugin
Hello, like I said in the main channel, I'm new to making plugins, and i coded a The Towers plugin to play with my friends. I have some basics in Java coding, but I wanted to know if my plugin is well structured (i don't think so), I'll take any suggestions. Thanks !
If this plugin is only for you honestly it looks fine.
My only criticism comes from the lack of expandability of the code, that being said I guarentee many people in this chat will opt for you to abstract things more. While I agree it's good advice if this minigame is only for you I see no issue leaving it how it is. Very well done for being new.
my turn
That being said if it's for others I think a first small step that's nice I'd putting all the messages in a configuration file.
you missed the
Objects.requireNonNull(Bukkit.getWorld(Objects.requireNonNull(plugin.getConfig().getString("map_towers")))).getPlayers().forEach(player -> {
player.playSound(player.getLocation(), Sound.ENTITY_EXPERIENCE_ORB_PICKUP, 1F, 1F);
});
GameManager::startGame is just a piece of garbage
uh oh constructive feedback
Mmm I forget intellij is over zealous by default. Id say that's not on them but moreso an overzealous IDE reccomendation
split it up into functions cuz theres so much duplication
you cloned it?
also instantiating pointless bukkitrunnables, use the scheduler instead
might even want to write proper classes for those tasks
For beginners I think it's actually much more constructive to point out specific things and explain why instead of lazily throw things out. It's likely they don't even know the scheduler exists or don't know why lambdas are better
I'm on my phone and at work if needed I'll actually thoroughly give more feedback later
oh youre at work
which messages ?
end user visible messages
like this one ? ```
Bukkit.broadcastMessage(ChatColor.GOLD + "[The Towers] " + ChatColor.GRAY + "Annulation du lancement");
y
how could i make it better ?
use functions that explain whats going on
instead of writing big blocks of code ?
use a countdown task or smth instead of spawning random bukkitrunnables
and you forgot a return here
also so much duplicated code
for both teams
yeah I used them because I thought it was easy but if it is not optimized i'll try to use schedulers
its literally the same thing but its merely a syntax difference
just passing a callback or an instantiated task class is way cleaning that randomly doing new BukkitRunnable() { some huge pile of code }.run()
are schedulers less resource-intensive?
literally the same thing, scheduler simply spawns a task
ok so for example i'll create a runnable class that starts the game
ye
i see
its cleaner and separates different parts of your code
yeah
its just advice do with it what you want
https://github.com/RaydanOMGr/ForgeLikePackets not very spigot but who cares right?
fuck its java
lmao
example doesnt even compile
kek
I forgor to finish it dw
hope you don't mind
it's all written on gh and I have never tested it lol 💀
there a reason PacketInstance isnt a record/ has all its fields final?
because I forgor records exist
and id probably make packet registry a singleton withoit getinstance
understandable
putifabsent
there is putIfAbsent???
so if forge jumps from a bridge, youll also jump my mom would say
lol
does that tell the user they fucked up tho?
also, what do you think of dynamically generating a Identifier/ResourceLocation from the class name instead of prompting the user to think of their own?
make it optional
hmm, well, I think I'll do that later
for now, make a record and get rid of the supplier, right?
Guys can you please visit this page and tell me if i have done description good or not https://www.spigotmc.org/resources/hider-plus-ultimate-nametag-hider.118185/
Name
👍
Couldn't find any other name
That would go with "hider plus+" name
hider plus pro max deluxe extreme edition
Yup
With price of $420.69
And no special feature
Buy my plugin and getout...
Does anybody have any ideas, or recommendations on optimizations i could add to this?
https://paste.md-5.net/asidubiher.cs
Just an immediate thing I can pickout... getGUI(EnchantType, ItemStack) Is there any reason this isn't done in EnchantType in some capacity? You could save yourself a switch
If it's an enum, a Function<ItemStack, EnchantGUI> in your EnchantType constructor would be fine, you could pass in SwordEnchantGUI::new, LeggingsEnchantGUI::new, etc. etc.
If it's a class, even better. Make an abstract method
Oh it's in a switch, of course it's an enum lol (unless you're using Java 21 features 👀)
java 8 😢
I changed the function
fuck java 8, was gonna say methodhandle
never heard of it
what type is enchantGUI? class?
ig what choco said also applies here then
How so?
why not make it abstract?
why not make it protected?
why not get rid of it?
make what abstract?
the point of having the class be abstract?
ye
ah wait thats another class
Heres the updated
EnchantGUI.java
https://paste.md-5.net/arizupeqal.cs
EnchantType.java
https://paste.md-5.net/ivojiqoqeq.java
Tag?
check the api, their are tags for things like axes, pickaxes, hoes, whatever
rly?
yes so replace getEnchantType with tag.isTagged(material) ? enchanttype : continue
you get the idea
enum EnchantType { Shovel(ShovelThing.class, Tag.SHOVELS_OR_SMTH) }
Then id have to create a new Tag
wdym
Yeah the tags are fairly limited
From what package is the tag
declaration: package: org.bukkit, interface: Tag
#ImSorryImOn1.8
at that point id just fork cb and implement it all myself
Thats why im justing having a list of all the materials under that category
oh no grandma
J8 supports MH I believe
Oops, meant to quote the post above it, whatever
Does java 8 not have Function
Whats method handle tho
Reflection but a bit different
It does, yeah. Along all other common functional interfaces
ty
So Choco’s original suggestion still stands :p
why are you using the console sender btw
(i agree with this approach)
why not biconsumer
Why BiConsumer of all things?
Will you do a BiConsumer<ItemStack, AtomicReference<EnchantGUI>> or what?
kotlin pilled
i would just do block: (ItemStack, EnchantGui) -> Unit in kotlin
which is effectively a BiConsumer
Yeah, but you want an ItemStack go in, EnchantGui go out - not ItemStack and EnchantGui go in, nothing go out.
public class DatabaseAdapter {
public static DatabaseSettings fromConfig(ConfigurationSection section) {
String path = "database.sql.";
return new DatabaseSettings(section.getString(path + "host", "localhost"), section.getString(path + "port", "3306"),
section.getString(path + "database", "simplepenalty"), section.getString(path + "username", "root"), section.getString(path + "password", ""),
section.getString(path + "table-prefix", "simplepenalty_"), SQLDialect.valueOf(section.getString("database.type", "SQLITE").toUpperCase(Locale.ENGLISH)),
section.getStringList(path + "properties").stream().collect(Collectors.toMap(str -> str, str -> section.getString(path + "properties." + str, ""))));
}
}
Is it correct or i need to remove static and do my class singleton?
looks awful to read
and why is a DatabaseSettings factory method located in an adapter class?
For long constructors like that I tend to like doing this type of formatting:
public class DatabaseAdapter {
public static DatabaseSettings fromConfig(ConfigurationSection section) {
String path = "database.sql.";
return new DatabaseSettings(
section.getString(path + "host", "localhost"),
section.getString(path + "port", "3306"),
section.getString(path + "database", "simplepenalty"),
section.getString(path + "username", "root"),
section.getString(path + "password", ""),
section.getString(path + "table-prefix", "simplepenalty_"),
SQLDialect.valueOf(section.getString("database.type", "SQLITE").toUpperCase(Locale.ENGLISH)),
section.getStringList(path + "properties").stream() // I prefer stream() on the same line, but you can put it on the next
.collect(Collectors.toMap(
str -> str, // You can use Function.identity() here if you wanted instead. I sort of prefer the quick readability
str -> section.getString(path + "properties." + str, "")
)
)
);
}
}
Makes reading things a little bit easier to follow. Though I think at this point it might be worth investigating a proper builder pattern, especially if your settings object is immutable. That way you can have a more readable way to construct your object... something like this instead:
public class DatabaseAdapter {
public static DatabaseSettings fromConfig(ConfigurationSection section) {
String path = "database.sql.";
return DatabaseSettings.builder()
.host(section.getString(path + "host", "localhost"))
.port(section.getInt(path + "port", 3306)) // Make this a getInt(). Just makes more sense
.database(section.getString(path + "database", "simplepenalty"))
.username(section.getString(path + "username", "root")) // Maybe join this and password() into credentials(String, String)?
.password(section.getString(path + "password", ""))
.tablePrefix(section.getString(path + "table-prefix", "simplepenalty_"))
.dialect(SQLDialect.valueOf(section.getString("database.type", "SQLITE").toUpperCase(Locale.ENGLISH)))
.properties(section.getStringList(path + "properties").stream()
.collect(Collectors.toMap(
Function.identity(),
str -> section.getString(path + "properties." + str, "")
))
)
.build();
}
}
I guess my last recommendation, instead of prepending a path, you can get a configuration section with the path.
public class DatabaseAdapter {
public static DatabaseSettings fromConfig(ConfigurationSection config) {
ConfigurationSection dbConfig = section.getConfigurationSection("database.sql");
return DatabaseSettings.builder()
.host(dbConfig.getString(path + "host", "localhost"))
.port(dbConfig.getInt("port", 3306))
.database(dbConfig.getString("database", "simplepenalty"))
.username(dbConfig.getString("username", "root"))
.password(dbConfig.getString("password", ""))
.tablePrefix(dbConfig.getString("table-prefix", "simplepenalty_"))
.dialect(SQLDialect.valueOf(config.getString("database.type", "SQLITE").toUpperCase(Locale.ENGLISH)))
.properties(dbConfig.getStringList("properties").stream()
.collect(Collectors.toMap(
Function.identity(),
str -> dbConfig.getString("properties." + str, "")
))
)
.build();
}
}
Okay I'm done spamming lol
thanks
renamed DatabaseAdapter into DatabaseSettingsFactory
public static DatabaseSettings fromConfig(ConfigurationSection section) {
ConfigurationSection dbSection = section.getConfigurationSection("database.sql");
return DatabaseSettings.builder()
.host(dbSection.getString("host", "localhost"))
.port(dbSection.getString("port", "3306"))
.database(dbSection.getString("database", "simplepenalty"))
.username(dbSection.getString("username", "root"))
.password(dbSection.getString("password", ""))
.tablePrefix(dbSection.getString("table-prefix", "simplepenalty_"))
.sqlDialect(SQLDialect.valueOf(section.getString("database.type", "SQLITE")
.toUpperCase(Locale.ENGLISH)))
.properties(dbSection.getConfigurationSection("properties")
.getValues(false).entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey,
value -> value.getValue().toString()))
)
.build();
}
why is a database factory producing settings and not databases
i should rename it into DatabaseSettingsFactory?
You could also put that method in DatabaseSettings itself. Nix the factory all together 👀
DatabaseSettings.fromConfig()
thats what i was implying
is it correct?
public class NumberFormatException extends RuntimeException {
public NumberFormatException(CommandSender sender, String message) {
Messages.NUMBER_FORMAT.send(sender, message);
}
}
int amount;
try {
amount = Integer.parseInt(args[4]);
} catch (RuntimeException e) {
throw new NumberFormatException(sender, args[4]);
}
I mean it's unconventional. What's wrong with just this?
int amount;
try {
amount = Integer.parseInt(args[4]);
} catch (NumberFormatException e) { // The one Java provides by default and throws on parseInt()
Messages.NUMBER_FORMAT.send(sender, args[4]);
return true; // Presumably this is in a command sender
}
java has that class already
and that constructor is clearly a mismatched responsability
saving one line
I mean meh. You're sort of abusing exceptions to wrap a message send call
Exceptions are meant to be used as "I cannot possibly recover from this"
^
Ints.tryParse my beloved
nice
out params
This isn’t C#
too bad
I'm more of a NumberUtils.toInt() type guy
In js you do: +"5"
it exists????
That's great
Can we get an string to int parser that uses OptionalInt
You could definitely wrap that yourself
public static OptionalInt tryParse(String input) {
try {
return OptionalInt.of(Integer.parseInt(input));
} catch (NumberFormatException e) {
return OptionalInt.empty();
}
}```
Isn't throwing and then catching an exception kinda expensive tho
I do that stuff off-thread
What matters is how relatively expensive it is
how relatively expensive is it tho
I dunno. Are you doing database queries? If so, your exception handling isn't gonna matter lol
Besides, there's literally no other way to do it unless you reimplement parseInt() I guess
Guava reimplements it 
Yeah use that with the ofNullable wrapper :p
A problem i see with this, is if this for sqlite there is no host, port, user or password for sqlite.
I know, i have check is database type sqlite and use directory
and .db file format
https://github.com/TheNewEconomy/TNML/tree/main/Core/src/net/tnemc/menu/core Always love feedback
Guava has Ints.tryParse that has the same code as Integer.parseInt but it returns null instead of throwing an exception.
public static OptionalInt tryParse(String input) {
final Integer integer = OptionalInt.of(Integer.parseInt(input));
return integer == null ? OptionalInt.empty() : OptionalInt.of(integer);
}
Do you want it for that directory specifically
oh nvm
I'm dumb lmao
that's the core, the other ones are just the platform implementations for sponge/paper/etc
Yeah ic
Do you use checker framework or annotations? Useful for someone that may use your library to check what methods could return null
For the nullable/notnull annotations?
I use the jetbrains ones, because intellij
just don't look at the convaluted item library that powers the cross-platform icons :3
https://github.com/TheNewEconomy/TNML/blob/main/Core/src/net/tnemc/menu/core/constraints/impl/IntConstraint.java You can use Ints#tryParse here since catching the exception might be expensive.
https://github.com/TheNewEconomy/TNML/blob/main/Core/src/net/tnemc/menu/core/constraints/impl/DoubleConstraint.java Same here but for Doubles#tryParse
You should use final on method parameters too (even when it's obvious that the var won't change, cause for the future). I honestly just have an Intellij plugin insert final whenever it's possible for easier readability. It applies not to just fields but everything tbh
For some of your methods, consider creating more variables for readability. For example, https://github.com/TheNewEconomy/TNML/blob/4c22d6fb167f0577e7b2637f3f0cf1ead58ff252/Core/src/net/tnemc/menu/core/icon/action/impl/SwitchMenuAction.java#L54 maybe create a Player variable so you don't have to call handler.player() three times.
Honestly for the most part my suggestions are just tiny changes and the code looks fine.
cheers
the constrains feature is probably something I'll end up removing, it's kinda meh, final on params definitely nice to have added the variable part I don't even remember what I was thinking at the time XD
I disagree that they all should be final
It gets messy and hard to read
He literally already uses final
But I don’t agree with how it gets hard to read. It’s good knowing that the variable won’t be reassigned somewhere else
its true that final is verbose by nature to use, buut I think it still adds readability and reduces bug-proneness which is good
They should really be final by default and then you'd have to add mutable or something to make it, well, mutable :p
Or, hear me out, stick with the same vibe as non-sealed...
non-final
isn't that what rust does or am I mixing something up
A few languages are immutable by default yes
But I think that's everything
I just mean local vars
I hope, but I sincerely doubt it
just use kotlin
use serde::Serialize as Serial my beloved
#define System.out.println println when
typealiases my beloved
just use kotlin
bad example but yes thats rust
The day Java adds preprocessor statements is the day I kill myse-
Actually one does exist already lol
It's terrible. Please don't use it
But it exists
typealias NMSItemStack = net.minecraft.something.ItemStack
sounds good
import net.minecraft.something.ItemStack as NMSItemStack
wait is that a thing?
yes
oh damn
You wouldn't be able to wildcard import type alias lol
I think it was js where you could do import * from './request.js' or something like thag
python isnt dynamically typed
it is optionally statically typed
you can add type annotations but it doesn't use them by default
typescript is great
no
These weird "interfaces"
this how it works?
I'm taking about how you have to unsafe cast jsons to interfaces and stuff
just learn to copy and paste correctly smh
write a script to do that for you
I have
yes
C# is weird, but I'd say it's okay
atleast its better than java
Just another OOP language with some weird conventions
Is it tho
but ive never cared enough to use it
Java is pretty decent if you think about it
c on its best
And generally JVM langs
odin 💀
C# is a bit more ergonomic than Java at least
oh no conclure joined
C# is an interesting lang
ref structs 
I've been planning to work on my terraria mod for ages, great opportunity to learn C#
mind you its Conclube!
I have heard three times about that lang and it was from you lol
😔
Yes
Java is great, TypeScript is great, JavaScript is great, Python is shit, Kotlin is shit
you have the worst fucking opinions on this discord server
Lmao
no language is shit
uhh, besides python
but no language is shit besides that
So is kotlin
Java > Kotlin U Java = Scala
idk if I got my maths writing thing right
but should be
scripts i said
im not gonna leave the user behind with some class files
isnt it the other way around
since Kotlin was (partly) created bcuz of lacking features from both Scala and Java?
kotlin > java and i cant form an opinion on scala
scala looks a bit cringe tho but im happy to learn new things
Scala is the first thing that brought me happiness in years 😭
oh
Anyways
i also should try it out then
i still dont get what this word means
and learn how it works otherwise your code is slow as shit
"the best"
sounds quite like the opposite
anyways if you learn it you can make very safe, beautiful and (relatively) fast code
saying "fast" on interpreted langs has no meaning to me
there is scala native
goat = greatest of all time
rust
now read that again
rust actively hurts me

