#dev-general
1 messages ยท Page 461 of 1
fun spin(producer: (Thread) -> KryptonServer): KryptonServer {
val reference = AtomicReference<KryptonServer>()
val mainThread = Thread({ reference.get().start() }, "Server thread")
mainThread.setUncaughtExceptionHandler { _, exception -> LOGGER.error(exception) }
val server = producer(mainThread)
reference.set(server)
mainThread.start()
return server
}
```this should be the way I instantiate `KryptonServer` now
as this PRINCIPLE states: a class should REPRESENT ONE thing and ONE thing only !!! in your "practical" example, this is clearly not practical at all because you are VIOLATING the principle by representing many things with one class !!!
nah jokes, im just chatting shit now
are you serious rn?
I guess you did do this for CombatStats
so I'd assume you are
wha
"chatting shit"
my classes are all separate
reminds me that you're british
who thinks that spin good
oh missed this one.
bri'ish innit
nah using spin will get me a big fat Copyright (c) 2009 Mojang AB
Its the opposite of spun
.
oh never saw this
Kotlin translation of MinecraftServer.spin
When krypton will take over the world they'll try and take you down if you use that. Don't give them the advantage
fun youSpinMeRightRound
you spin up a Minecraft server
wdym relocate
did you shade the lib?
shade that's what I meant
shadowJar {
relocate 'me.mattstudios.mf', 'me.remence.minecraftchallenges.mf'
}
I have that
you have to run gradlew shadowJar instead of gradlew build
Where do I see that? usually I build through the gradle menu
?
shadowJar button
yeeeeeeeeeeeeeee
okie thank you
tf is "knows" lmao
who knows
it always knows
Like I'm supposed to know 
sorry Kaliber, I don't get it
yeah it was funny. Took me a second to get it but damn when I got it I couldn't stop laughing
Really weird easter egg task
only smart people get it
๐ฆ
is that the "only the shadow knows" or something like that?
https://paste.helpch.at/xukomujilo.java
Should I have the OWNER job in a different class? I am planning on adding more, is it bad practice to put them as final static in the same class?
lmao
that's cool
pfff
I've seen people make entire first person shooter games using nothing but a terminal and ASCII text
So I'm using the mf-cmd obviously, and when I type my default command and gibberish I get this error
Um
Is there a way to customize this?
yeahg

How
Remence have you tried reading the wiki? xD
I haven'
oh btw, as you're here Yugi, isn't this actually kinda smart?
the way it works
I haven't read it all ๐ฅฒ
it handles circular dependencies very well
What's the point of mf-msg
messages lib that supports markdown in mc
lightweight
hex support and discord markdown
in mc
so __message__ would be italic etc.
cool project but I personally don't use it for my plugins. All I need is hex
also gradients
I think
Why atomic?
yo @ocean quartz when is MF-Config coming to the wiki?
Can I use multiple Annotations?
It doesnt look like it needs to be an atomic reference
When I finish the new wiki
yeah could probably be a lateinit var
yes?
.... It used to work for me before the shitty update
How would that look like
well it depends what annotations ur after
Yeah
Permission, Alias to name a few
@Permission("maincommand.sub")
public void subcommand(blah)```
for example
can I see? Or is it just local for now?
Can I not use @Permission for the default command?
u can
So why is it rejecting me
ugh
use it on the method?
oh
yeah
Why not just
fun spin(producer: (Thread) -> KryptonServer): KryptonServer {
val server = producer(mainThread)
val mainThread = Thread({ server.start() }, "Server thread")
mainThread.setUncaughtExceptionHandler { _, exception -> LOGGER.error(exception) }
mainThread.start()
return server
}
not necesarely
Local only, writing it from scratch
you can use Alias and other stuff for it
I dont see a benefit of using atomic there
ah yeah that would work
oh niceee. dark theme. love it
as I said, that was a vanilla thing
annotations must be applied to the specific cases, e.g @Command annotates classes, @SubCommand annotates a method etc
Yes Im comment on vanilla's usage as well
Was this decompiled?
?mf
Looking for useful libraries/frameworks?
Here are some which have been deemed useful by the community and are used daily.
-> Menus: https://mf.mattstudios.me/mf-gui/gui
-> Commands: https://mf.mattstudios.me/mf/mf-1/getting-started
-> Messages: https://mf.mattstudios.me/message/mf-msg
Man I forgot I even have a website... Now I want to go back at html css js ๐ข
Use react, it's pretty fun
https://helpch.at/mf when
public static <S extends MinecraftServer> S spin(Function<Thread, S> serverProducer) {
AtomicReference<S> serverReference = new AtomicReference<>();
Thread serverThread = new Thread(() -> serverReference.get().runServer(), "Server thread");
serverThread.setUncaughtExceptionHandler((thread, exception) -> LOGGER.error(exception));
S server = serverProducer.apply(serverThread);
serverReference.set(server);
serverThread.start();
return server;
}
```here's vanilla's btw Yugi
.
yes, but I fixed it
Thats probably it
there is no way that a compiler would create an AtomicReference if it didn't need one
what message?
the logs show nothing
what in the fuck
oh that one is still here
Not the compiler, but rather the decompiler may
i am so confused rn
checks bytecode
It wasn't deleted xD
Atleast I assume its not the compiler
do check
let me know what you find
bytecode from both deobfuscated and even the obfuscated one use AtomicReference
man I love Glare's web page
Same, it's really nice
new java/util/concurrent/atomic/AtomicReference
dup
invokespecial java/util/concurrent/atomic/AtomicReference.<init>()V
astorel
I think I'll steal it and say I had it before him
Mine is not bad so far but I feel like its so crowded for no reason... I have no projects to actually display on there xD
so its just a bunch of Lorem Ipsum projects
xD
Make a few blitz
I'd like a reason first mr trump
wow
uh
ban?
well I would only display stuff that actually wold be useful there. And I've got no idea what to make that will be usefull xD
@sacred hollow <- this dude
nice ๐
lol rip
@chilly zenith or @frail glade whichever of you are around
please ban.
thank you
they gone
banned
https://i.imgur.com/SLaS3Mi.png lol Spigot
lit
what
so useful
oh wait
ban that guy. check message logs
๐
gg
took u all day to nice lol
I didnt notice the color
Spoogot at it again with more useless shit
Poof.
ty grand judge
Ya'll are in all shades everyday
hmmmm
xD
๐
sendMessage is the same bardy
no look at the class
public LightningStrike strikeLightning(@NotNull Location loc, boolean isSilent) {
throw new UnsupportedOperationException("Not supported yet.");
}
```lol
oh wait what
yeah
๐ฅฒ
also can we just address md_5's awful fetish for just not letting anything fail silently? lol
yeah its overwritten, but still... just why lol
That's the API
not the actual server
What else are you supposed to do?
Leave it empty
yes
well I guess you could do that
I swear Spigot isn't overridden
Dude it is
it is...
Anything you see on the API
is overwritten
lol
bardy, everytime u send a message, do u get a UOE lol, didnt think so
why don't they make it an interface then?
They just reference what is implemented on the server side
smooth brains bardy, smooth brains
should be an interface if it's always overridden and requires all of the defined methods to be overridden
So how can I get somebody to type a players name after the default command
that doesn't fit the structure of what is actually on the server side
md5 4head tho
like tab complete?
Would I still use a subcommand?
you what
Yeah I see that on the wiki
but I'm not sure if that's what I need to be using
on the server it's not an interface, so to reflect that, it's also not an interface in the api
get all players on the server, and get their names
then override the onTabComplete method
and return that
that's like saying World should be a class in Bukkit because CraftWorld is a class in CraftBukkit lol
it's an implementation of world
Okay, but we're not talking about implementations
just the reference to the existing object in the api vs the server
implementations are children to the existing object
Spigot should be an interface in the API
there's no reason to not have it be an interface
Okay sure
that's not what im arguing
You may be right
in fact I agree
but md4 0head
what are you arguing then?
the reason it's not an interface on the api side
is because it's not on the server side
as I said earlier though, that literally makes 0 sense lol
how is it not.. it's extended on the server impl and every method overridden lmao
^^^
hold on a second
this is just md5 being a 3head as usual
who in their right mind made it in an inner class in the first place?
m
d
5
oh come on
it makes 0 sense
im losing braincells just looking at this now
md5 = a stupid hashing algorithm orange slime
md0
one thing I do love when I browse through Paper sometimes though is that all of his commits show up as just "5" in the blame lol
someone should really make a new functional mc server implementation... :p
I love how that wouldn't work, just actually looking at it
cough Krypton cough
oh no
or "a"
Krypton, a lightweight, fast, Minecraft Server made from scratch
OH NO
in Kotlin*
SOMEONE said it
lol
Why not?
found it!
look at it
ah
does my plugins for krypton have to be kotlin or can they be java
gimma a min
val server = producer(mainThread)
val mainThread = Thread({ server.start() }, "Server thread")
Yea my bad
Server#stop
Can I use the api to do something like item.addNbt(tag);
i think bardy is trying to make it java compatible
#dev-general message
Would anyone like to enlighten me?
they can be Java, your experience with Java might not be that great (I've tried to make it as idiomatic as I can, but it's not perfect and still needs improvement), but I highly recommend using Kotlin for the best possible experience
What's up with @Command not being recognized?
maybe have it as an enum?
Are you importing the right one?
perhaps if you wanted to add other roles
import me.mattstudios.mf.annotations.*; right?
I also want people to be able to make their own though
ew wildcard imports
import *;
Why not use wildcard
confusion and ambiguity
Post your entire code
Please use a paste service to share configs, errors, code and long logs.
โข HelpChat Paste
import org.bukkit.command.Command;
not yet
not sure whether NBT should be an implementation detail yet or not
Ah thank you
depending on the server is really easy though anyway, and even encouraged if you want implementation-specific stuff or to make your own domain-specific optimisations
@onyx loom fix bug
#bestbugreportof2021
It's broken
ok cool
If no work
ok cool
It no work
ok cool
You gonna help fix bug?
This guide talks about How To Fix Autosell Bug
NO
make it a class then
ig
So it's dev stuff
then there is #development
@SubCommand("test")
@Completion({"#players", "#range:1-20"})
public void tabExample(final CommandSender sender, final Player player, final Integer number) {
}
So if I use this, would Player player be the player selected in the completion?
don't even bother using the sender argument there, just take a player
The owner field?
yea
first param isnt an argument afaik
cause i feel like it doesnt need to be a singleton?
ah he wants to take a player as an argument
hm
yes
It's an example in the docs
I'd only take the player
Somebody got experience with DeluxeCombat?
yeah nvm, I got confused Remence
I just wanna know if it's gonna be whoever is selected in the completion
?help
ยป Give the helpers some details
ยป Ask suitable questions
ยป Be polite
ยป Wait
?help
ยป Give the helpers some details
ยป Ask suitable questions
ยป Be polite
ยป Wait
..
read it
also not asking to ask
1 week ago
Spigot linking doesn't exist?
Still not accepted.
Why can't I see it
the channel is removed once u link ur spigot
DeluxeCombat isn't even a HelpChat thing
DeluxeCombat send me to here tho
Kaliber i did that, one week ago.
Cant see any services
To talk on for premium.
?
My bad sheesh,
I wonder who's gonna make it though SIT.
DeluxeCombat has its own support discord
I can name someone who I think won't.
ur right, none of us will :kekw:
Bm likely will
zSkcTz3
nice one yako
stroke
second stroke
ok ๐ฅฒ
does /dc have conflict with /dc (deluxecombat & deluxechat)?
@prisma wave I'll send some ยฅ if you know a fix btw ;)
Kaliber could you help at all
dc isnt an alias of deluxechat
with
If you get denied, is there no feedback on why you got denied?
I'd like to know why I was denied so I can work on my flaws.
ask cube ig
I knew it was gonna be denied tbh
Hey, so I wanna make a command where you type a command with a players name, and that player will get a message with the original command senders name. For example I type /helpchat Kaliber and kaliber gets a message saying "Remence is in HelpChat"
So how would I do this with mf-cmd
send the player arg a message of the CommandSender's name
(Player sender, Player target)
i would love some yen
But for real I'm struggling on the plugin because it is so temperamental with the selling
@Default
fun default(sender: Player, target: Player) {
target.sendMessage(Component.text("${sender.name} is in HelpChat!"))
}
```ez
Component.text ๐
ewwwwwww
Couldve done that in java 
not enough monads
ikr
nah I thought I'd go for an objectively superior language instead
using adventure in kotlin is yuck
I agree
we need a kotlin dsl
where
adventure-extra-kotlin
o
also, the DSL won't show up nice colours because kashike refuses to use DSL marker on it because "there's no official documentation saying you should use it on functions"
net.kyori:adventure-extra-kotlin:4.7.0
is there no source for this?
oh you want source
that came from the top of my head lol
I might put some money down for someone who knows a fix to this thing I'm having issues with.
fixed
Idk what a fair amount would be, it should be a small fix tho.
#837974312451440661 question mark
or just #development and actually state what u need help with
I'd pay someone to sort it
ah it was hidden in plain sight bardy
i went on the main repo but couldnt find the module
lol
wait which is supposed to be better
lmao
Pretty nice
might help to mention what the issue actually is
Why are my colour codes not working in my command?
This is my util
public class ChatUtil {
public static String color(String message) {
return ChatColor.translateAlternateColorCodes('&', message);
}
}
I put a request paid thing out, I'll see who wants the money ๐
are u calling the method remence
yea no
might help to mention what the issue actually is
It's the stupid citizens plugin
no it was designed so that I could just use &c or whatever code
yes very stupid plugin
The thing has a mind of its own
well yea but u still have to call the method to whereever ur using the colour codes remence
amazing
You tell it to register something and it does something totally different
Thats not a issue, thats an invention! we have sentience!
Oh yeah I'm being an idiot
thanks
this makes a bit more sense
lol
i see nothing wrong.
Since I'm op, the &4 is overriding the &e, how can this be fixed?
are u using displayname or smth?
It's like you're on my computer ๐ณ
lol
Player#getName() should just return their name unformatted, unlike getDisplayName()
Idk you're the support guy
nah this is where the "in training" comes in
๐คซ
someone needs to train me
I'll train you ๐๏ธ
๐ณ
Also
Is there a way to have my @Completion({"#players"}) the subcommand itself?
or can I just leave it with @Completion and it'll be a subcommand
eh
Huh? What does completion have anything to do with subcommand?
Ok like
If I have /greet as my default command
I could use /greet <player right? because of my @Completion({"#players"})
So does the Completion only take effect after the default command by itself?
probably
probably
Yeah but I wanna make sure you understand what I'm talking about ๐
Meh, if something goes wrong then I'll know
just ad it as an argument in your default method
@Default
public void default(CommandSender sender, @Completion("#players") Player target) {
// Greet Target
}```
When ur class is over 1k lines and you know you should refactor it, buuuut
They are virtually the same, in fact default is just a hidden subcommand
Well, I guess this question could be applied to any method
?mf
Looking for useful libraries/frameworks?
Here are some which have been deemed useful by the community and are used daily.
-> Menus: https://mf.mattstudios.me/mf-gui/gui
-> Commands: https://mf.mattstudios.me/mf/mf-1/getting-started
-> Messages: https://mf.mattstudios.me/message/mf-msg
-> Config: COMING SOONโข๏ธ
its already made for the most part apparently
MF-Spigot
MF-Bungee
MF-Krypton
MF-Minecraft
MF-IP Grabber
intellij's duplicate checker is a bit...
MF-Valorant 
dkim why do you hate kotlin ?:
i forget about it
MF-pp
Therefore you hate it
Because Kotlin bad, haskell good
haskell has ?:
Maybe monad
infact, haskell has any symbol!
Hold on a second ...
Yea?
๐คจ
Okay done
Umm
troll
Lol
i was waiting for u to say smth then go to sleep
I wanted to check something on the internet but my ISP is betraying me today ๐ฅฒ
๐ฅฒ
now ive missed out on 7 minutes of sleep ๐
Ive missed out on 7 mins of pretending I can sleep
Its almost 5 am
Class in an hour
๐ซ
that sounds great
dude
stay up for class!
you're telling me that your class starts a t 6AM?!
u make a good point
Yes because time zones
makes sense
You live in qatar but go to school in india?
he walks from qatar to india every day, its a small journey
My uni is in India, my family is in qatar so I returned there coz we cant stay at uni coz corona
Ah that makes sense
yugi ping me again with that emoji pls
mfw not yugi who pinged: ๐ฅฒ
i didnt get a noti from ur ping emily ๐
my phone had the invalid emoji icon in the notification :smiling_face_with_tear:
terrible phone doesnt have latest Android/ emojis ๐ซ
get the player, get their inventory, additem
you're the luckperms guy
you helped me transition from ultrapermissions to luckperms lol
anyway thanks
lol
What's this itemstack stuff I'm hearing about though?
The ItemStack is the time you want to give to a player
?materials
@Default
@Permission("challenges.sword")
public void defaultCommand(final Player player) {
player.getInventory().addItem("DIAMOND_SWORD");
}
Does this look wrong?
There's a red line under ("DIAMOND_SWORD")
Says cannot resolve method
You need to create an ItemStack from the Material, then add the item to the player inventory
ItemStack itemStack = new ItemStack(Material.DIAMOND_SWORD);
player.getInventory().addItem(itemStack);
What if I wanted to do a bunch of items?
Would I have to create an itemstack from each material?
Surely not
you can loop/streams
if you want to convert List<Material> -> List<ItemStack>
getItemMeta
ItemMeta
Oh boy ItemMeta....
๐ฌ
What a dark zone
lol
What's wrong with ItemMeta
Unnecessary bullshit everywhere
So what's the replacement
None
Yikes
๐ฅฒ ok
๐
:smiling_face_with_tears:
You can come here and bully people as a coping mechanism
Anti ping only works on support channels
I guess so
Except #development
the neglected son
๐
enums are so damn misused lol
A heap bunch of crap that would be waaaaay better replaced with generics and registries
Annotations as args?
Wdym by that?
public void swordOther(final Player player, final Player target, @Completion({"#players"})) {
player.sendMessage("yes");
}
Basically I just want a command where you type the default command, and then any online player name
But I think I know how to do it
That makes no sense lol
swordOther(final Player player, @Completion("#players") final Player target)
Yep I realize that now
But that's what I was told ๐คทโโ๏ธ
Do I need a seperate method for lore or no?
Because I'm seeing these examples on spigot have these giant methods to add lore
d;spigot ItemMeta#setLore
void setLore(@Nullable List lore)```
Sets the lore for this item. Removes lore when given null.
lore - the lore that will be set
Ayyy, working fine
What's that for?
ayy
Not much right now, well it's kinda responsive since Material UI is responsiveish by default
looks great
My new wiki ;p
That's awesome
You moved from kotlin react to typescript react?
When I do the sword command, it gives me a diamond sword but it's not named, why is that?
@Default
@Permission("challenges.sword")
public void defaultCommand(final Player player) {
itemStack.getItemMeta().setDisplayName(ChatUtil.color("&cThis sword belongs to &4" + player.getName()));
player.getInventory().addItem(itemStack);
player.sendMessage(ChatUtil.color("&6There's your sword kid."));
}
Yeah, Kotlin react was very limiting since most things aren't compatible yet
The most important was material ui, which I can't live without anymore
setItemMeta
getItemMeta returns a copy
Typescript is odd
Oh?
ohh thanks dkim
Ooh that's pretty cool, Vue also has it but isn't compatible with Vue 3 yet
๐ฎ
This indentation hurts me
setItemMeta then what..
..give the item?
haskell style ๐
Actually that convention may have derived from ML
Im not sure
But its actually quite nice to use
@Default
@Permission("challenges.sword")
public void defaultCommand(final Player player) {
final ItemMeta meta = itemStack.getItemMeta();
meta.setDisplayName(ChatUtil.color("&cThis sword belongs to &4" + player.getName()));
itemStack.setItemMeta(meta); // btw where is the "itemStack" variable?
player.getInventory().addItem(itemStack);
player.sendMessage(ChatUtil.color("&6There's your sword kid."));
}
@oak raft Imagine messing with ItemStacks like modifying someone's DNA, you extract their blood (getItemMeta), modify it (do your changes), then you need to inject the blood back in the person (setItemMeta), then they die
interesting example ๐
Very interesting ๐
?paste
Paste Services
When asking for help with a config/menu/code issue please use one of these:
(However we do prefer if you used our paste :))
โข HelpChat Paste - Usage
โข Hastebin
But also very helpful
It's horrible, I probably wouldn't mind it, but ๐ฉ
Then you extract it again, make more changes and inject it again, then they come back alive
And at the end of the day, it's all suffering
I dont think that format is compulsor
It supports indentations as an alternative like haskell
This makes a lot of sense after reading Matt's example lol
Thanks to you both
That's actually not bad, it's kinda similar to Kotlin react
div {
h1 {
+ "Title"
}
}
yea I feel like its core concept is pretty much that of react, it just builds onto that
Here you dont control anything, you define the view once, and then the only thing you can do is modify the model on events
Does it compile to wasm?
Compiles to js I think
That's actually pretty cool
yea its really nice
The compiler is actually much more helpful than ghc
It pretty much instructs you what to do to fix something xD
"Seems you mispelt Lsit. Maybe you meant: List or Lisp"
"Cant find Model in current project scope, Maybe you want to depend on x?"
๐
React be like:
Error: Objects are not valid as a React child (found: object with keys {children}). If you meant to render a collection of children, use an array instead.
render a collection of children
I'm sorry but I don't collect children
Wait for about 20~30 years and you will get started
xD
Oh god
imagine having runtime exceptions ๐
Someone please shoot me
Just spent 15 minutes trying to find why the css wasn't working, I didn't apply the class ๐ฅฒ
Hey matt, it's completely valid to only have @Cmpletion({'#players'}) as an annotation right?
Yeah
Pain ๐ฉ
interesting
By any chance do you know why this method isn't being recognized? When I type the default command as well as a player name I want this to run but instead I get "This command does not exist"
@Completion({"#players"})
public void swordOther(final Player player, final Player target) {
meta.setDisplayName(ChatUtil.color("&cThis sword belongs to &4" + target.getName() + "&c."));
lore.add(ChatUtil.color("&cGiven to &4" + target.getName() + " &cby " + player.getName()));
itemStack.setItemMeta(meta);
target.getInventory().addItem(itemStack);
player.sendMessage(ChatUtil.color("&6Sword successfully sent."));
target.sendMessage(ChatUtil.color("&6Sword received from " + player.getName()));
}
Oh, i mean yeah you need either @Default or @SubCommand those are required
Ah okay that makes sense
Do I need to fill the SubCommand() value though? I don't want another word besides from the target player name
Yeah if you do subcommand you need to fill
Can you show me an example of your command?
So basically if I type /sword it'll give me a custom sword. However if you type /sword <player> it'll give them a sword
Or do you wanna see what I've written
Oooh
@Default
public void sword(final Player player, @Optional @Completion("#players") final Player target)
Yeah
๐ฅฒ
Okay so under the method, I would write as if the player is typing the command by itself right?
If target is null it means the player did either /sword or /sword invalidPlayer
Visual representation of my brain when working with recursion
Lol, Maybe a couple sub menus too many
Still looking good ๐
And thanks
I'll try this out
@Default
@Permission("challenges.sword")
public void defaultCommand(final Player player, @Optional @Completion("#players") final Player target) {
if (target == null) {
meta.setDisplayName(ChatUtil.color("&cThis sword belongs to &4" + player.getName() + "&c."));
itemStack.setItemMeta(meta);
player.getInventory().addItem(itemStack);
player.sendMessage(ChatUtil.color("&6There's your sword kid."));
} else if (target != null) {
meta.setDisplayName(ChatUtil.color("&cThis sword belongs to &4" + target.getName() + "&c."));
lore.add(ChatUtil.color("&cGiven to &4" + target.getName() + " &cby " + player.getName()));
itemStack.setItemMeta(meta);
target.getInventory().addItem(itemStack);
player.sendMessage(ChatUtil.color("&6Sword successfully sent."));
target.sendMessage(ChatUtil.color("&6Sword received from " + player.getName()));
}
}
Is this what you mean matt?
Yes, but can be done a lot better
I'm still a beginner so it's the first solution that came to my head lol
Although, in game there is no lore that shows up.
List<String> lore = new ArrayList<>();
I also have this
You never set the lore to the meta
Did they actually add an executable message to it, that's so extra, i love it
Now itโs setting lore when you type /sword which isnโt what I want ๐ฅฒ Iโm done for today
"Drink Water"
"WhAT DoEs ThIs MeaN"
Thank you for ur consistent help today Matt
They actually did yeah lol I guess most of the fabric/forge community expects an executable installer lmao
That's actually not a bad idea tbh
aaaaaaaaaaaaaaaaa
my java course
has 19 hours left
aka 400 hours because debugging
this is gonna be fun
https://paste.md-5.net/oyuwefijef.java daily spigot developer standards
excuse me
System.out.println("yes"); ๐
up to you
also, https://paste.helpch.at/atubosatel.sql someone rate this profiler report
lol
it bloody well should be
no
yes
k
Ya'll just need some haskell in your life
it gets Maven artifacts from the moon efe
You have a local maven repository in your UserHome/m2 folder
.m2*
You can publish artifacts there if you want to use it
where do you think all those dependencies get downloaded to?
for Maven, it's .m2
for Gradle, it's .gradle
You ussually dont need to look into them yourself,
If you have a library you want to use that doesnt provide a hosted repository, you can publish it there to use it across projects on the same pc
The thing that you've admitted to not doing?
yeah I should try it
who needs unit tests when you've got pure functions and a repl ๐ฅฐ
๐
import kotlin.math.*
fun main() {
val one = Vector(128.7584973, 128.7598947, 128.7599732)
val two = Vector(129.7589385, 129.7503284, 129.7542847)
val dot = (one.x * two.x) + (one.y * two.y) + (one.z * two.z)
val length = sqrt((one.x * one.x) + (one.y * one.y) + (one.z * one.z))
val otherLength = sqrt((two.x * two.x) + (two.y * two.y) + (two.z * two.z))
println(acos(max(min(dot / (length * otherLength), -1.0), 1.0)))
}
data class Vector(val x: Double, val y: Double, val z: Double)
```someone please tell me why that last `println` always returns `0.0` no matter what I seem to change those coordinates to
acos(1.0) = 0.0
yeah ik that, but why do we always end up with 1 there
Bukkit doesn't use absolutes though (got this from Bukkit's Vector)
and I'm gonna guess it's doesn't always return 0
by | I mean the euclidian norm here
you calculated it
oh
What this implies is that your thing you call min/max on is always <= 1
ah, I thought that said >= lol
Also you probably want to swap min and max there?
I struggle reading those inequality signs sometimes for whatever reason
what is it that you're trying to calculate exactly?
ah yes, that'll be it
the angle between two vectors
Why min max
that's just what Bukkit uses
Doubles.constraintToRange (from Guava)
public float angle(@NotNull Vector other) {
double dot = Doubles.constrainToRange(dot(other) / (length() * other.length()), -1.0, 1.0);
return (float) Math.acos(dot);
}
this is from Bukkit
Idk what the point of this is exactly, but you don't need it for the angle
jesus christ
I wonder why Bukkit forces it between that range
wait a minute... isn't the cosine of an angle always between -1 and 1? the same as all the other trigonometric ratios?
arc cosine takes a cosine as an argument
"inverse", yeah
Special cases:
- `acos(x)` is `NaN`, when `abs(x) > 1` or x is `NaN`
yeah that might explain it
yeah it shouldn't, but ya know, floating point rounding errors
because of the inequality I mentioned earlier
fair enough
the same as all the other trigonometric ratios?
tanwould like to have a word with you
can the tangent of an angle be above 1?
lol
tan is literally the worst
It tends to infinity at 90
goes from -inf to inf all the time
^
seems legit
NaN
not that kind of infinite lol
infinite infinite
xD
NaN isn't a mathematical concept (afaik), it's a CS concept
also, I wonder why Bukkit has an EPSILON value (0.000001) that accounts for floating point errors
lemme show you what I mean
because they've decided on that delta /shrug
is that a normal thing to do?
yes
Yes'
so I shouldn't be using == to check floating point numbers then?
absolutely not
mhm
(I mean Kotlin's ==, which calls equals under the hood, a.k.a object equality in this case, not reference equality, just for clarification)
doesn't matter in java either if we're talking primitives
equals doesnt do a range check either
override fun compareTo(other: Position): Int {
if (x == other.x && y == other.y && z == other.z) return 0
if (x > other.x && y > other.y && z > other.z) return 1
if (x < other.x && y < other.y && z < other.z) return -1
return 0
}
```this is `Position`'s current `compareTo` function
pretty terrible ik, and could definitely do with some improvements, but I guess it works
That is a bad idea
which part?
3 dimensional vectors do not have total order
so they shouldn't be comparable then?
because I use that to check if the new location sent by the client has changed since the last position sent by them lol
then you check equality
maybe interms of distance from the origin
with an epsilon
still wouldn't do that, sort of arbitrary
and I believe it violates the contract of comparable
d; Comparable
public interface Comparable```
Comparable has 38 sub interfaces, 1 methods, and 200 implementing classes.
This interface imposes a total ordering on the objects of each class that implements it. This ordering is referred to as the class's natural ordering , and the class's compareTo method is referred to as its natural comparison method .
Lists (and arrays) of objects that implement this interface can be sorted automatically by Collections.sort (and Arrays.sort). Objects that implement this interface can be used as keys in a sorted map or as elements in a sorted set, without the need to specify a comparator.
The natural ordering for a class C is said to be consistent with equals if and only if e1.compareTo(e2) == 0 has the same boolean value as e1.equals(e2) for every...
This description has been shortened as it was too long.
I need to check if the X, Y and Z coordinates have changed, that's it
It is strongly recommended (though not required) that natural orderings be consistent with equals
I would adhere to that
mm
yeah just check that then and don't say which is less or more
yeah calin has a solution for that
lmao
lol
so just fun areEqual(first: Position, second: Position) = first.x == second.x && first.y == second.y && first.z == second.z should do then?
I'm not bothered here about being 0.000001 out lol
the client will never send a position change that would cause problems with those inaccuracies
That's not what it's for
Its not an issue with the client
It's the opposite
ah, checking if they are equal
0.000001 is to tolerate mistakes
if you don't do a comparison like this it breaks for every fp error
Floats loose precision from normal operations because of how floating point numbers are represented in memory
It doesnt have infinite precision
so what should it be then? abs(first.x) - abs(second.x) > 0.000001 for all 3 coordinates?
subtract, then abs
^
ah right
actually maybe I can use == here, since equals is the one that is overridden to use the epsilon
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Vector
return abs(x - other.x) < EPSILON && abs(y - other.y) < EPSILON && abs(z - other.z) < EPSILON
}
๐
maybe you can make an extension function for Double
dunno why kotlin doesn't already have that
kotlin bad ๐
also, when you realise that you overrode equals and hashCode for Vector but you didn't for Location lol
actually I just overrode equals, not hashCode
we need to check equality with a fuzzy error term to account for floating point errors
noob
overriding hashCode isn't trivial, I actually don't know what's best practice there
since equality implies same hash code
deriving (Eq, Hashable)
I just let the data class determine the hash code
๐
well that probably breaks it
public int hashCode() {
long var10000 = Double.doubleToLongBits(this.getX());
int var1 = (int)(var10000 ^ var10000 >>> 32) * 31;
long var10001 = Double.doubleToLongBits(this.getY());
var1 = (var1 + (int)(var10001 ^ var10001 >>> 32)) * 31;
var10001 = Double.doubleToLongBits(this.getZ());
return var1 + (int)(var10001 ^ var10001 >>> 32);
}
```this is the generated `hashCode` function
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as Location
return world == other.world &&
abs(x - other.x) < EPSILON &&
abs(y - other.y) < EPSILON &&
abs(z - other.z) < EPSILON &&
abs(yaw - other.yaw) < EPSILON &&
abs(pitch - other.pitch) < EPSILON
}
```I think that should do for `Location`
World equality is defined by two world objects having the same UUID associated with them
the hashCode question remains
what would I even override hashCode with?
that's the question
but the way data classes do it currently violates the contract
how?
