#dev-general
1 messages ยท Page 345 of 1
ep 2 is a pretty shitty excuse to get them out of a situation they couldnt get out of
Yea 6 was left incomplete coz of covid
They are going to wrap up the s6 story by s7 ep 3 apparently
The mirror master arc
The Boys was a good show. I can't say it was great but good
||Earth 1 Wells is back, not thawn, the actual Wells who we saw thawn kill in the flashback||
Umbrella Academy is nice
yeah
also my first show that I actually watched and loved was Altered Carbon
idk why
I didn't really like shows until that one
Whats that about?
a future where our conscience is stored on some kind of disks that are put in our necks and we don't really need the bodies anymore we can just change them
I don't think I have
Similar concept, In the future people who die can be downloaded into a VR world
oh seems interesting
well in AC you can actually change bodies after you die if you have money
๐ฎ
Yea, will do 
really?
yeah idk why I really liked it
In the beginning it was ok imo, but it got really dull and just centered around excessive violence later on
blitz have u played katana zero?
nope
its very violent
I also do love me some violence, but AC just takes itself too seriously while it remains rather superficial story-wise
gotta love the atmosphere though
atmosphere
i love when pixel art games immerse me more than high quality ray traced AAA games
always fun
well idk a lot of shows that have actually good story for all seasons. Most of them are good in the beginning but just go bad after a while
idk I don't play a lot of AAA games either. I'm not really a "Gamer" I just play games that I can afford lmao xD the only games I bought because I liked them were the Tomb Raider games. the new ones
true, but with AC I didn't particularly like it in the beginning either
maybe. tbh a lot of shows I watch and I just remember the feelings. Not the actual shows xD
for AC I do remember some stuff and usually that's because I liked them
https://paste.helpch.at/wisagafesa.rb bets on this working first time?
I just see a lot of stuff so I'm going to say it won't work
lol
what that does is this:
- Load the plugin.conf file from the plugin's JAR
- Create the data folder if it doesn't exist
- Retrieve the main class attribute from the plugin's JAR manifest
- Construct a new
URLClassLoaderfor that plugin - Load the plugin's main class reflectively and instantiate it with the plugin's context
idk I'm to lazy to read it watching yt videos xD
You could use apply on the folder instead of the first init block
And move the loader up if thats whats used by load I guess
good point
wdym?
ah ok
each plugin has its own URLClassLoader instance
Also you dont need the exist check for the file iirc
Just call mkdir instead
It just returns false if it didnt get created
oh yeah
no parent class loaders?
Also why the map to pluginloadstate
good point
Could just be a fieldin the plugin class
yeah
Clean
thanks ๐
@prisma wave can I steal your repo just to put the Krypton API on until I get my request to register org.kryptonmc on Maven Central approved btw? xD
https://i.imgur.com/6mlhkvl.png wait wtf no way
they fixed highlighting?
about fucking time
right, here we go, moment of truth
Wdym fixed the highlighting?
the blue
I haven't seen blue there in ages
I always get method call is ambiguous lol
https://i.imgur.com/0hU9mDr.png BOIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
big pog
load Terrible Plugin on that
terrible plugin is written in Java and uses Bukkit ๐

you know Java is included in the JRE right?
the JDK is in the JRE
and for Bukkit
Bukkit is absolutely diabolical
also, I'm stupid lol
imagine making an initialize method and not making it open
๐ฅฒ
finally, Krypton isn't fully useless anymore
still gotta test what happens if you instantiate another class in the constructor
actually that doesn't need loading
oh btw, on the topic of plugins, anyone up for making some simple plugins using the new Krypton API and giving me some feedback? ๐
how much you paying? /s
is lombok bad?
?plsnolombok
Why is Lombok bad?
- It's a compiler hack - the Java compiler isn't designed to modify code, so it can cause difficult to debug errors, or worse
- It requires an IDE plugin, so unless you've properly configured Maven, Gradle and your IDE, you'll get hundreds of compilation errors. This process takes time too, it's not easy
- Lombok'd code won't show in Javadocs
- The code generation is often unpredictable and difficult to debug, and often you'll have to do it "the hard way" anyway
- Java is supposed to be explicit, Lombok hides a lot of key functionality into a subtle annotation which can be easy to miss
- While IDEs support it with a plugin, it's usually more difficult to find specific things, like usages of a getter because they don't exist in the source code
- Finally, Lombok'd bytecode doesn't match the source code, so it causes a pretty annoying warning in IntelliJ
short answer: yes, long answer: yes
oh btw, a few notes when making Krypton plugins:
- Every plugin needs a description file, called
plugin.conf, on its classpath (basicallyplugin.ymlwithoutmain) - Every plugin must have its main class set in the manifest (can be done with the application plugin in Gradle)
- Every plugin's main class must take
context: PluginContextas an argument to its constructor
krypton bad
wow
bukkit 1.7.10 good
Krypton good
clojure bad
down bad if ur using clojure

might start programming my plugins in html
๐
okay, Clojure bad
Die
now make me a plugin lol
Pay me
what for
repositories {
mavenCentral()
maven { url 'https://libraries.minecraft.net/' }
maven { url 'https://repo.bristermitten.me/repository/maven-public/' }
}
dependencies {
compileOnly 'org.kryptonmc:krypton-api:0.11.1'
}
```ez
(top 2 repositories required because Kotlin and other dependencies of the API are in Maven Central and Brigadier has its own library)
Shouldnt that resolve itself if you have them in them transitively in the compiletime classpath from your repository declarations?
wat
repositories {
mavenCentral()
maven { url 'https://libraries.minecraft.net' }
}
dependencies {
api 'org.jetbrains.kotlin:kotlin-stdlib'
api 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3'
api 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.1.0'
api 'org.jetbrains.kotlinx:kotlinx-serialization-hocon:1.1.0'
api('net.kyori:adventure-api:4.6.0') {
exclude group: 'org.checkerframework', module: 'checker-qual'
}
api('net.kyori:adventure-extra-kotlin:4.6.0') {
exclude group: 'org.checkerframework', module: 'checker-qual'
}
api 'com.mojang:brigadier:1.0.17'
api 'me.bardy:admiral:1.0'
api 'org.apache.logging.log4j:log4j-api:2.11.1'
}
```my dependencies
oh btw, @ocean quartz, you'll be happy to know that Krypton's CommandManager has a register method that directly accepts a LiteralArgumentBuilder ๐
According to docs, api is transitive so those depndencies should be available to any project depending on this
ยฏ_(ใ)_/ยฏ
override fun register(command: Command) {
val commandNode = dispatcher.register(literalArgument(command.name) {
executes {
val permission = command.permission ?: return@executes 1
if (it.source.hasPermission(permission)) {
CommandScope.launch { command.execute(it.source, it.input.split(" ").drop(0)) }
1
} else 0
}
})
command.aliases.forEach { dispatcher.register(literalArgument(it) { redirect(commandNode) }) }
}
```this is the `register` function for commans btw lol
Have you tried without the repos specified?
oh it does actually work
maybe because it's cached, idk
Could not find org.jetbrains.kotlin:kotlin-compiler-embeddable:1.4.31. without repo
without Minecraft libraries: Could not find com.mojang:brigadier:1.0.17.
whatever kinda docs told you api is transitive, transitive my backside
Take that back you waste of flesh
lol
ill bring all my python2 buddies
made what work
ur finished
plugin loading ๐
I'll chokeslam all of them
trรจs bien
ill body ur bum ass
Try
built like a twig

A very strong twig
I read that as "ill bum your ass"... yeah gn
3rd worlder
lol
oh yeah, BM, write me a plugin pls
Leave senpai alone
ikr
not surprised lol
whats that supposed to mean
:/
im getting off, my mom told me i need to rest before i beat bm
pce
๐
Why would that make me happy? xD
because you asked for Brigadier colour support lol
iirc
the coloured argument thingies
remember?
I think you're thinking Frosty
mf with brigadier support would be amazing
and on hover tooltips :partyparrot:
It's planned ;p
With hover tooltips
though my command system doesn't handle sub commands
but that's why you can register Brigadier literal argument builders lol
and why Admiral is embedded
literalArgument("time") {
literalArgument("set") {
literalArgument("day")
literalArgument("noon")
literalArgument("night")
requiredArgument("time", integer)
}
literalArgument("add") {
requiredArgument("time", integer)
}
literalArgument("query") {
literalArgument("day")
}
}
๐
should probably just remove the Argument suffix from those top-level functions tbh
probably cleaner without them
literalArgument("time", integer)
wat
I'll assume you intended requiredArgument instead
lol
haha yeah lol
That's extremely ugly
Think of it like a directory tree
literal("time") {
literal("set") {
literal("day")
literal("noon")
literal("night")
required("time", integer)
}
literal("add") {
required("time", integer)
}
literal("query") {
literal("day")
}
}
how's that instead?
Still ugly
mf monopoly will never be topped
I quite like the tree structure
cmd.getName().equalsIgnoreCase() monopoly will never be topped xD
๐คจ
anyone have plugin for blocking 2nd hand on 1.16 ??
I got Haskell! yay!
doesnt work
?
A great achievement
tf is brigadier
Brigadier is a command parser & dispatcher, designed and developed for Minecraft: Java Edition and now freely available for use elsewhere under the MIT license.
That's the point
One of those fake wiki page links gets posted when you ask a question in the wrong channel
Stfu
nah thanks I'm good
Lol
is possible to create a SHULKER inventory that has a certain color, eg red_shulker?
its probably similar to leather if i had to guess
What's the command to get a workup on where server resources are going?
Like ram usage etc.
if there isn't like RED_SHULKER or something, it would probably be setting a meta property?
maybe /timings
thanks
cast it to Shulker
then you are avaible to use setColor and getColor methods
wait are you asking creating inventories or just shulkers
and can you see the which color is it in inventory?
Hey, I was looking for someone who could update a jumppads 1.8.8 plugin to 1.12.2, it should use same configs and have same permissions. I can pay with Skrill or maybe paypal.
Krypton has commands now ๐
two of the register methods take LiteralArgumentBuilders lol
and it uses Brigadier internally
so if you want coloured arguments, you can just directly use that
for now anyway
Ew API methods taking builders
that's what Brigadier takes internally
oh god
it literally calls the method that takes the built node though so lmao
the thing I could do I suppose is call root.addChild and take a LiteralCommandNode I guess
ArgumentBuilder#then also takes a built CommandNode too (that's the method the one that takes the builder calls)
Frcsty just had a deep orgasm
The only thing that makes it disgusting is the BukkitBrigadierCommandSource https://paste.helpch.at/ucuniyikos.java
Needlessly long af name
eeeeeeeeeeeeeee
it would have good structure if it evolved, advanced and moved forward over time instead of being stuck and unwilling to improve like it is
the day paper hard forks
god I'm gonna have kids that day
man
just fork paper
and make a better one
called
cardboard
cardboardspigot yes
make it run on go
with tnt optimized for pvp righT?
lol
ew
@hot hull Here are your colored commands :kekw: https://github.com/KryptonMC/Krypton/blob/master/server/src/main/kotlin/org/kryptonmc/krypton/packet/out/play/PacketOutDeclareCommands.kt
it is wrong, correct
that is because it has not been updated since BM wrote it for 1.15 lol
๐
lol
wdym why, colored arguments!
Is that commodore?
can anyone here help me understand some Mojang whack please?
I've renamed the variables according to what I think they are
What part do you want explained?
its a breadth first search through the provided node
isn't breadth first search when you take a tree and you expand as far across as you can before moving down?
Yes
Think of that snippet's execution like this:
Pass #1
Queue: RootNode
->Poll
Queue:
Current: RootNode
Use result from Current;
-> Add children
Queue: RootNode#Child1, RootNode#Child2
Pass #2
Queue: RootNode#Child1, RootNode#Child2
->Poll
Queue: RootNode#Child2
Current: RootNode#Child1
Use result from Current;
-> Add children
Queue: RootNode#Child2, RootNode#Child1#Child1, RootNode#Child1#Child2
.... continue till queue is empty
ah right
any idea if there's a cleaner way I can do that in Kotlin?
also since assignments in while statements aren't allowed
Break if empty
could I use tail recursion here?
yes
so it's both clean and fast
yes
We need a queue not a stack tho
You could hack things together, But i assume its only going to end up more complicated
I just need a map of elements to their respective indices
(a Map<CommandNode<*>, Int>)
"hack things together" if you say so
There's a pretty standard recursive implementation afaik
Can you link me to an example?
https://www.techiedelight.com/breadth-first-search/ looks like there is
BFS(start_node, goal_node)
return BFS'({start_node}, โ
, goal_node);
BFS'(fringe, visited, goal_node)
if (fringe == โ
)
return false;
if (goal_node โ fringe)
return true;
return BFS'({child | x โ fringe, child โ successors(x)} \ visited, visited โช fringe, goal_node);
```from german wikipedia
BFS'? isn't that the inverse of BFS?
I recently had to implement it as well though I did it iteratively because java
no
it's just the recursive helper
ah right
any examples of that implemented in code that I might understand? lol
actually nvm, seems I have a Java example on this page I linked
but that still seems to use iteration
it's maths
pseudocode
yeah that's mathematical-based pseudocode I think
โ
is the empty set iirc, and โ means the left thing is an element of the right set
Is that not just building a queue in an argument?
well, depends on what your api looks like but this pseudocode is set-based and the operators can be understood fairly quickly
โ
- empty set
โ - element of
\ - set difference
โช - set union
{child | x โ fringe, child โ successors(x)} means essentially fringe.map(successors)
I don't think it requires that
wdym?
I do not think it assumes anything in terms of order
also, if I was to go with iteration here btw, couldn't I just use a for loop? or will that not work
it should work with any set type
actually no that won't work
what kind of for loop? you can't remove elements from the queue in kotlin when you do that
true
https://haste.devcord.xyz/ekopusopep.java here's my iterative implementation (it additionally constructs a path)
private fun RootCommandNode<*>.enumerate(): Map<CommandNode<*>, Int> {
val result = mutableMapOf<CommandNode<*>, Int>()
val queue = ArrayDeque<RootCommandNode<*>>()
while (queue.isNotEmpty()) {
val element = queue.poll()
if (result.containsKey(element)) continue
val size = result.size
result[element] = size
queue += element.children
if (element.redirect != null) queue += element.redirect
}
return result
}
```that's the translated code I think
but that's ugly lol
I mean, saying that, chunkInSpiral is literally unreadable, so ya know
the "problem" with the recursive implementation is that you need immutable sets
would my Kotlin code actually work btw?
Considering we're talking about very small graphs here (or so I assume) this probably won't matter but still it is something to take into consideration
very small graphs? er... this may or may not include every single command that has been registered with the dispatcher on the server
idk about you, but that ain't small
hmm true
do you want to traverse every node in the graph?
I don't even really understand what the point of the code is, I just know I need it
He needs to traverse each one, yes
that is pretty small in terms of depth I presume
We might have different ideas of what small is too
oh well that is considerable
and that's just the default map
not including all the custom commands from plugins
damn
You shouldnt need the contains check and the null check
I just ideally need something that can be computed at least relatively fast
Otherwise that should work
yeah I think the code works
seems like recursion would be nicer here no?
oh btw, in Kotlin's ArrayDeque, is it firstOrNull I want instead of poll btw?
yeah maybe
Johnny said that
nicer yes, but too inefficient probably
I just need something that can be computed extremely quickly
actually, thinking about it, if commands aren't registered after startup is complete, then I should only really need to compute this once
isn't that just java.util.ArrayDeque
yes
no, they have their own impl that extends MutableAbstractList
ยฏ_(ใ)_/ยฏ
removeFirst is closest I think, no need for the null check after already checking if the queue is empty
so ```kotlin
private fun RootCommandNode<>.enumerate(): Map<CommandNode<>, Int> {
val result = mutableMapOf<CommandNode<>, Int>()
val queue = ArrayDeque<CommandNode<>>()
while (queue.isNotEmpty()) {
val element = queue.removeFirst()
if (result.containsKey(element)) continue
val size = result.size
result[element] = size
queue += element.children
if (element.redirect != null) queue += element.redirect
}
return result
}
still not sure about removing the contains or null check
alright, I'll remove them
Actually the queue would require the null check huh
also, the redirect can be null, and if it is, we don't want to add it
yea nvm about that one
I'll remove the contains check though
Yea my bad, I was thinking from the Java perspective where it would just ignore the null value
wouldnt be that bad with tail recursion and persistent data structures
if you wanna help me make this cleaner and just as fast if not faster, be my guest BM
Yeah well. One of those doesn't exist in kotlin unfortunately
which one?
there's ktx.persistent afaik
persistent data structures
what are those?
really?
Oh there is? Interesting
Version based "immutable" data structures
https://en.wikipedia.org/wiki/Persistent_data_structure oh that's kinda cool
but it definitely exists
so it's basically where the data structure preserves its previous state when it's modified?
The idea is, to dumb it down, have immutable data structures that don't need to copy everything when you "modify" them
ah right
for an example git handles commits like a node of a persistent tree I think
so basically just immutability where it only copies the changes
A bit more than the changes bard
I wanna see how kotlin's persistent data structures compare to clojures now
The usefulness is that you dont need to copy the entire structure
https://github.com/Kotlin/kotlinx.collections.immutable maybe this is what BM was referencing
But you still need to copy more than the changes you made ussually
first result for kotlin persistent data structures lol
Depends on the structure but yeah you can't reach that in most cases
The most beautiful (imo) persistent data structure is the classic singly linked list
Or cons
Even though it isn't very powerful it's perfect in a sense because you really do reach constant time and memory with addition/removal at the front
And it's the simplest list implementation that exists as well
linked lists are great
yep thats it
Gonna benchmark this I think
It has something like transient in clojure as well i see
private static CommandNode<SharedSuggestionProvider>[] getNodesInIdOrder(Object2IntMap<CommandNode<SharedSuggestionProvider>> nodes) {
CommandNode<SharedSuggestionProvider>[] result = new CommandNode[nodes.size()];
for (Object2IntMap.Entry<CommandNode<SharedSuggestionProvider>> entry : Object2IntMaps.fastIterable(nodes)) {
result[entry.getIntValue()] = entry.getKey();
}
return result;
}
```trying to think what the purpose of this might be
actually maybe the client wants the nodes in ID order
that would make sense
is there a better way to basically reverse a map than that?
I was thinking that one of Kotlin's map extension functions might be the answer, but I can't seem to find one
Use associate on the entries and return the reversed pair in it
o7, I am currently digging into the data conversion stuff using Mojangs DataFixer API.
I want to convert a (serialized) 1.12 item stack NBT data to a 1.16 one. The following code works:
NBTTagCompound converted = (NBTTagCompound) DataConverterRegistry.a().update(
DataConverterTypes.ITEM_STACK,
new Dynamic<>(DynamicOpsNBT.a, sourceCompound),
-1,
CraftMagicNumbers.INSTANCE.getDataVersion()
).getValue();
But it works just great for "normal" item stacks. As soon as the source Item Stack is a shulker chest it does some strange things :/
The biggest problem is the lack of documentation for this stuff. I also tried using the data converter type for a block entity, arranged it in different ways but everytime it either says that minecraft:black_shulker_box or shulker_box would be an invalid (namespaced?) key
so ```kotlin
associate { it.value to it.key }
How would I remove one of the tab completers?
also, you can't call associate on a Map btw
right, then what?
You only wanted to reverse the map right?
lemme see
oh wait you wanted an array
lemme see if I can work with the map
map.toMap()
lol
map.toReversedMap()
I think the reason why it's converted to a list is because I couldn't care less about the integer value, that's just used for ordering
I see
the ID is only used to order them in the array
theMap.entries.associate{ it.value to it.key }.let { map -> Array(map.size(), Map::get) }
This should give you the same result as from the snippet
Probably not the most efficient way to do it tho
yeah
anyway, lemme test this out
seemed to work
the client now highlights the commands
great
oh btw, since I'm loading plugins myself and stuff, would it be necessary to add a shutdown hook to unload things?
just not sure if/what I need to ensure is safely closed
also will add console parsing soon
it's just a thread right?
I just create a new thread and add it as a shutdown hook
huh?
Yea ig, then unloading each plugin sends the unload event I assume?
yeah it'll fire an event
alright
there's no filtering to say which plugin it goes to though
so it'll go to all plugins
Should be fine
Does it unregister all other "listeners" registered by the plugin after unloading?
oh also, would you know of a way that I could remove the while (true) in the start method in server btw?
link to the class?
there are no registered listeners
wdym?
it's all reactive
yeah but there isn't really a way to unregister that
Gotta love spigot plugins
lol
You can filter with the plugins loadState or whatever that was
yeah true
if I remove it, the main thread stops executing and so the JVM dies
in vanilla, this is solved by the runServer method, which calls ticking methods that tick the server
but that's not how Krypton is built, since everything that's done there I expect to do when I receive the data
NettyProcess#run is blocking right?
bardy you need to use non daemon threads
yeah not sure how to do that with coroutines
no clue
another thing you could do though is have a queue of runnables and run them in that while loop
It suspends till the server needs to stop?
Use runBlocking
finally {
workerGroup.shutdownGracefully()
bossGroup.shutdownGracefully()
}```
bardy why is your formatting so fucked
what formatting?
also, I hardly wrote that netty process code btw, that was mostly BM
Yea that part woudl be called when netty shuts down
u've got newlines under your classes and objects
withContext is suspending
except it's inconsistent
not all declarations have a newline
huge fan of the no newline btw, highly recommend going that route
use runBlocking and just call the blocking netty call at the end
yeah the override fun initChannel should probably have a new line above it
I'm only talking about the class you linked first
runBlocking
KryptonServer
where Yugi
One sec
yeah that's basically my style lol
ik it's a mess, but it's basically just shoot first, ask questions later lol
no newline looks better
i hate the newline
lots of people do it though
you do you ig
is that github?
yes
hot theme
it's github's dark theme
is it?
I think it separates the declaration from the stuff inside of it nicely tbh
looks different for me
idk, I just like it
I'll fix up the horrible code later anyway
for now, I'm operating under "shoot first, ask questions later"
yeah I've got both on
also, the spacing above the start function is inconsistent because of the way I group things
two things that go together get put next to each other
and things that don't go together are separated by a new line
I don't see anything inconsistent about the start function
no, above it
you agree with my grouping?
oh are you talking about these?
override fun player(uuid: UUID) = players.firstOrNull { it.uuid == uuid }
override fun player(name: String) = players.firstOrNull { it.name == name }```
and there's always things you can do
Bard
https://paste.helpch.at/ifapucihel.cs seemed to work
idk grouping seems fine for the most part except for the fact that there's a good chance 99% of these fields simply shouldn't be here
if your api forces you to write bad code then you need a new api
no, that's not what I'm saying
just look at the class this implements, then you might understand why there's so many things in this class
ig it all has to come together somewhere (unless you use guice like a pro)
not saying you're wrong for calling me out for writing bad code, just saying there's an explanation
efe tf?
oh also, Piggy, what do you think of native Adventure support?
You could also split up all the properties in the Server interface ig
or group them better
or use guice
group them better as in?
native adventure is good
e.g. isOnline, isHardcore, difficulty and gamemode could all be grouped into some sort of server settings
did you figure out reloading?
Is that not what I just said xD
nope lol
actually, yeah lol
the API is still a massive W.I.P anyway, so feedback is greatly appreciated
oh also, what do you guys think of the logger names for plugins?
they're currently Plugin - Name (to differentiate from Krypton classes)
%d{HH:mm:ss.SSS} %style{%-30.-30thread}{bright,cyan} %style{%-24.-24logger{0}}{bright,green} %highlight{%-6level} %msg%n that's my logging pattern lol
it's a custom format I stole from JDA lol
it used to be a Logback format, but we're using Log4j2 now
I'm a firm believer that logback is the best logger
Log4j2 is apparently faster, supports logging more than just strings, and also can log async
if it was Log4j vs Logback, Logback all the way
but Log4j2 vs Logback, Log4j2
%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%level) %cyan(%logger{36}) - %msg%n
my format
i like it
relies on symbols rather than spacing for separation
looks quite similar to Spigot's tbh
just with colours
lemme translate that to Log4j2 format and see it
ooo
yeah because it clashes
don't want them matching
also, is saving logs to a file like vanilla does a good idea btw?
and it's trivial with all major logging frameworks
yeah Log4j2 should have no issues
also, Krypton doesn't support SLF4J natively btw, it uses Log4j2's API (basically SLF4J++)
I mean, you can add SLF4J compat by depending on log4j-slf4j-impl if you really want it, and it'll work fine
actually there might not really be downsides to that with an app like krypton
yeah, since all logging is managed centrally anyway
I don't see an issue with it because users are not supposed to choose a logger implementation
^
yeah it's more of a mistake for something like jda where you're expected to provide an impl
yeah
although I would only expose the slf4j api to the plugin api in case you want to change it
I can use any ANSI colour
I've posted my format
that's what I use
it's my favourite
so that's my recommendation ig
nah change the info to blue
why's the name green?
should look like this
according to Atom OneDark anyway
oh btw, Log4j2 has a Logback preset for highlighting
that might be nice
try that
and change cyan to light blue
maybe that'll fix it
and thread back to green
https://i.imgur.com/Ti39cnL.png this is with green thread and same cyan with Logback preset
also, https://i.imgur.com/ukcLeaI.png wow I must've been tired last night
that atom one dark thing must just fuck with it
yeah
oh also, actual programming question, lemme just bring up what I mean so I can try and explain this
for whatever reason, if I use that, the folder generates in the root directory, not in the plugins folder
resolve instead of walk?
didn't know that existed lol
o wait
wait so what's the function?
use a util from nio files
or if this "resolve" thing is a better alternative in kotlin, use that
they do the same thing
walk is basically the Kotlin equivalent of Files.walk
idek know what that does
walks over a directory
piggy
no need to explicitly declare it
ah
Anyway
Cna you make it not delete the msg it if fails
Or atleast delay the deletion
what message?
make an issue pls
oh right lol
Alright
I'm super busy with school work atm, haven't been able to open the ide in weeks
I see
and when I do get a little free time
im gonna be extremely petty here and just say "collecting into a sequence" doesnt make sense
don't usually spend it on coding
Shall I fork and PR then?
Alrighty ๐
make sure to test it though
Sure
-_-
sorry it's a little bit of a hassle if you don't already have an environment setup
you need mysql
how do you do this btw?
Yea, I do have mysql
where is it?
File.resolve
Ah alright
it'll create the schematic, u just need to create a db and user
you sure that exists?
Wait is it going to index everything? xD
no
absolutely
ur only modifying the bot right?
you can just use the public docdex instance then
the only resolve functions I can find do not match what I want at all
oke ๐
even if it did index everything it'd only fry your cpu for a couple mins
assuming it wasn't a potato
no biggie
It aint a potato, but internet tho
it doesn't index remotely
it'd either
i) crash
ii) take a really long time
iii) get you banned from the site, or by your isp, for an attempted dos attack
@prisma wave oh right, ik where you want this now
so it can realistically only index local javadocs
I might get flagged by my isp but the other cases shouldnt happen I assume
anyway none of that matters since you're only running the bot
Yup
oh btw Piggy, here's the comparison of the three logging frameworks for you: https://stackify.com/compare-java-logging-frameworks/
i'll consider switching on my next project
for those who can't be assed to read, basically, Log4j should not be used by anyone ever again ever, Logback is nice and better than Log4j but it has a few flaws, and Log4j2 is the best out of the three that improves on both
elara/logging outdoes them all
would elara/logging be a package for elara's package manager?
probably
indeed
elara/dotnet hmmm?
maybe in stdlib
u should start using random symbols in elara package manager
instead of using / in packages
elaraยถlogging
when Elara is at least functional enough to do things, I'll start making the package manager
makes perfect sense
elaraรlogging
lol
lol
mmmm
not purely
I thought data oriented was basically exclusively used for games
๐
oh btw, as you're here Piggy, you wanna see how I got plugin loading to work in the end?
well yes, elara/game has u covered
sure
when I see ::
is this a c?
literally went to Nicole last night, told her I got plugin loading working and she was like https://i.imgur.com/kVso37H.png lol
loading was never the hard part?
yeah it wasn't lol
it's just everything after loading
no previously it was very multiparadigm (return statements, while loops, no guarantee of purity) but we're reworking it a lot
it was way easier than I thought
oh btw Piggy, you might be able to answer this
if I load the main class and that class calls constructors of other classes, those will be auto-loaded right?
actually I think I've already answered this myself but whatever lol
monads in elara ๐
oh btw, wdym by all the stuff that comes after loading?
d;urlclassloader
public class URLClassLoader
extends SecureClassLoader
implements Closeable```
URLClassLoader has 1 extensions, 1 implementations, 11 methods, 2 all implementations, and 1 sub classes.
This class loader is used to load classes and resources from a search path of URLs referring to both JAR files and directories. Any jar: scheme URL (see JarURLConnection) is assumed to refer to a JAR file. Any file: scheme URL that ends with a '/' is assumed to refer to a directory. Otherwise, the URL is assumed to refer to a JAR file which will be opened as needed.
This class loader supports the loading of classes and resources from the contents of a multi-release JAR file that is referred to by a given URL.
The AccessControlContext of the thread that created the instance of URLClassLoader will be used when subsequently loading classes and resources.
The classes that are loaded are by default granted permission only to access the URLs specified when the URLClassLoader was created.
reloading/unloading
if they're accessible
what should I do for unloading?
you need to ensure there aren't any references to any of the classes of that plugin
reloading is a no go for the moment, as I really don't want whatever kinda hacks we explained the other day to haunt me in my nightmares lol
so if it's stored in a set that counts as a reference right?
yep
so I remove it from the set and then bam
well, I remove it from the set and close the loader
if it's only reference is in the set then yes
in an ideal world that's it
the garbage collector will come along and send it to purgatory
do I need to do anything when the server is shut down btw?
or will the GC yeet the classes for me anyway
they'll be yeeted
so you're only talking about unloading the plugin whilst the server is still running then, right?
yes
how does .class in java work?
e.g.
System.class```
is class a static variable generated at compile?
Compile time yes
is it a static field?
Uh
just thinking
imagine changing a classes class via unsafe lol
if System.class returned Class<String>
I mean 80% of Java is runtime reflection anyway lmao I wouldn't be surprised if that was too
Mm surely you can change the Class object at the address of the other one.. I would assume?
only if it's a field
Well it's gotta be somewhere lmao
yeah but I don't see a method in unsafe which allows you to find the address of anything that isn't a field
Lol request paid is great, "Advanced java programmer" budget $5-$10
I can make an advanced Hello World for that
gl using unsafe in Java 11
actually that's excluded isn't it
mainly because loads of articles cropped up about why it was dumb for Oracle to remove it lol
yeah been doing some research I don't think what I originally described is possible
I'm gonna keep researching this
I refuse to believe that reliably unloading classes is simply impossible
okay wtf ```
Exception in thread "DefaultDispatcher-worker-1" java.lang.NullPointerException: Parameter specified as non-null is null: method kotlin.io.FilesKt__UtilsKt.resolve, parameter $this$resolve
at kotlin.io.FilesKt__UtilsKt.resolve(Utils.kt)
at org.kryptonmc.krypton.plugin.KryptonPluginManager.load(KryptonPluginManager.kt:45)
at org.kryptonmc.krypton.plugin.KryptonPluginManager.<init>(KryptonPluginManager.kt:24)
at org.kryptonmc.krypton.KryptonServer$start$1$1.invokeSuspend(KryptonServer.kt:96)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)
the parameter given to resolve is non null
that error is literally impossible
๐
@prisma wave was your idea to use resolve, any ideas?
val dataFolder = pluginsFolder.resolve(description.name) this throws an NPE
oh btw, also, is there a way I can use centralised versioning that I can access in code?
e.g. I have Krypton's version exposed to the API in the KryptonServerInfo object, but hard coding this value means I have to remember to update it on every release
is there a way I can just use gradle.properties or something to have Gradle able to read and use the version and also have it readable in code?
do how spigot does it and relocate the entire package just to add the version to it
you'll always carry the version in every class name that way ๐
that's not what Spigot does
Bukkit uses pom.properties in META-INF to get the actual Bukkit version
sure, it definitely doesn't relocate org.bukkit.craftbukkit.Whatever to org.bukkit.craftbukkit.{nms}.Whatever
idm updating the server version manually, since that's only in code
it's just the actual project version
it was sarcasm bardy because spigot is utter shit
You can do it from Gradle cant you?
wdym?
In an old Spring project I had the version info pulled from the build.gradle using something Gradle has, I'll see if I still have it somewhere
It's part of Spring Boot, nvm
springBoot {
buildInfo()
}```
Then I could use `BuildProperties.version`
I could use Gradle to generate a krypton.properties file in META-INF or something and then read that at runtime
Seems like the better way to do it
Unless you make a publicly accessible text file somewhere that you update that contains the version info that you download and read at runtime....
But that's horrible.
that's not what I want either
I want to read Gradle build properties and write them to a file
I swear I'm gonna just add it to the manifest in a minute lol
there seems to be nothing on the net about how to do something like this
How does Wolfram do stuff so quickly
I was writing a crappy Go program to find the factors of a number. It took like 20 minutes to complete for 600851475143 and Wolfram did it in about 6 seconds wtf
Really good optimisations
Probably parallel computation too
And caching a lot of shit
hey, you all
I'm trying to make a plugin that randomly eliminates all the blocks in a column x,z of the world, close to a player
//x and z are the coords x and z close to the player, and y is the coord y of the player
for (int i = (int)y; i < -1; i--) {
Location block_location = new Location(world, x, i, z);
Block block = block_location.getBlock();
block.setType(Material.AIR);
}
I tried to do this, but java is giving me an warning
"Loop executes 0 or one billion times"
idk but can you cast y to an int?
I actually don't know, good question
yeah, bedrock is usually at y = 0
should be greater than -1 ^
yeah
if i starts below one, then it will be infinite
aaaaand the warning is gone
thank you!
I think you can cast from int to double, since double has a bigger storage
not sure, though
and should probably be >= 0 instead of > -1
oh
also, beware of the fact that the bedrock level will change in 1.17
yeah, yeah
=0 does the same thing as > -1 if it's an int
yeah ik, just a bit cleaner imo
but why should I change > -1 to >= 0?
i suppose
oh
all right
I think It makes sense
all right, I think It's done. I'll test it
btw, this is how I did It
@Override
public void run() {
System.out.println("Task has been run");
player_list = Bukkit.getOnlinePlayers();
for (Player p : player_list) {
Location loc = p.getLocation();
double x = loc.getX();
double y = loc.getY();
double z = loc.getZ();
World world = loc.getWorld();
x += rand.nextInt(11) - 5;
//y -= rand.nextInt(2) + 1;
z += rand.nextInt(11) - 5;
for (int i = (int)y; i >= 0; i--) {
Location block_location = new Location(world, x, i, z);
Block block = block_location.getBlock();
block.setType(Material.AIR);
}
//p.sendMessage("Bloco em " + x + " " + y + " " + z + " foi removido");
}
}

