#development
1 messages ยท Page 70 of 1
though at that point, I don't really see why you would need a whole Spring server, you could just use Redis as a nice cache
what are you using this data for?
I got it to work...
profile = profile.update().getNow(profile);
oh yeah I would totally leverage Redis in this case
since the data should be cached anyways
Not the most ideal setup, but that's what I'm currently using
then you don't need to get it on demand and the servers themselves can just lazy update whenever stuff changes
Yeah but I usually need the data as-is
don't really want to deal with updating it
and haven't really used Redis
How would you reliably update information like online player numbers
Decrement on player leave, increment on player join?
update whenever player joins or leaves
and refactoring all of this would be (probably) pain
two spigot event handlers, they're basically just jedis.incr("online_players") and jedis.decr("online_players")
what kind of data
surely you should be caching this anyways
might as well put it in a shared memory storage that can just be checked by everything whenever for basically no cost
i've never touched redis and even i can see there's probably some use for it here
I've come to heavily rely on Redis for stuff like this, it's just so useful as a separate memory storage sytsem
we use it for stuff that should persist past server restarts, logs so that they can be lazily collected, etc.
admittedly i've never really understood how redis works for more complicated data like that, my interpretation was it's mostly k-v, and when I think of k-v i always think primitive variables n shit
Player data (playtimes, balances, bank balances, other server-related data, statistics), punishment information (bans, kicks, mutes, etc.).
Server data (TPS, online staff, players)
Some methods are used just for QOL, such as broadcasting, changing player ranks, balances, etc.
That's obviously not everything that's going on.
msot of that sounds like stuff that should just be in the database
which you can just then connect to from your website or whatever needs it
Some of it is stored in memory until server restart
it's key-value but you can do basically anything with that, you can store json blobs, have queues, etc.
then that stuff you should store in redis
and the other stuff is already in the database
howtf does that work?
how do you mean?
queues etc
Redis is just a Map<Object>
oh you meant that type of queue
something like rabbitmq or apache pulsar?
for some reason i had in my mind some sort of messaging system
uh not as reliable inherently, but yes this basically can be used like that
you just lpush whenever you have new stuff, and rpop whenever you want to get it
you usually just have a loop constantly waiting for rpop to return a result basically, then you have realtime communication
can also do stacks with the same thing ๐
anyways yeah
i have centralized most of my external data just already in a separate website, so stuff like punishments and ranks and balances and stuff is already on a separate website
then the rest I use redis as a communication/caching layer between
how would you store like unique player data in redis tho
uuids?
i'm imaginging some sort of nosql uuid -> json document kinda vibe, but redis doesn't have separate like databases n shit right? so how do 'scoped' keys work
set player-stats:d40ded56-881d-4317-9615-b221a96ff8e5 {"joins": 15, "deaths": 20}, etc.
you just make it part of the key
interesting
or, even better, you could have a player-stats hashmap
then have the key be the uuid and the value be the json
and what would that look like
hset player-stats d40ded56-881d-4317-9615-b221a96ff8e5 {"joins": 15, "deaths": 20}
hget player-stats d40ded56-881d-4317-9615-b221a96ff8e5
ok yeah that style makes a lot more sense in my brain
so the hset/get is basically a nosql/mongo kinda vibe then
yeah the hashes have some limitations, so sometimes you have to do the first style
i mean not really
it's basically a hashmap kinda vibe
yeah but isn't mongo, with it's key -> json thing basically just the same thing, with a hell of a lot of extra steps?
i guess kinda
i've never really used mongo/any nosql system if that wasn't clear
it's just better to think about it as a Java HashMap just in a different memory heap basically lol
what sort of limitations
can't do timeouts is the one that impacts me the most
if you do a set, you can have it just delete after a certain time
when would you want that
yeah no i got you
first thought that came to mind was expiring map/cache kinda vibe xD
can redis so it's own data pulling? I assumed it was push only
I mean not really, the point is that you push to it from your application
and the cache persists and is centralized
so if you have 5 instances of your website, they don't each cache some expensive operation, they all just share the same one
and when it expires, the first one to check it refreshes it
ah so lazy loading- i was imagining a timer-based thing
ok that makes a bit more sense
you mentioned rabbitmq earlier, i've heard of that, isn't that one kinda like the MC ecosystems plugin messaging channels?
it's a completely separate message queue
ik they're separate, i'm just trying to grasp concepts
it's super overkill for minecraft servers basically, the point is to have millions of events that are guaranteed to be processed once and only once
i've never heard of those last two :p
We use Pulsar where I work
the principle is pretty simple, you have listeners/clients and publishers
you publish a message to a topic, the clients listen to the topic and consume/acknowledge the message, removing it from the queue
I was about to ask if it was a pub-sub / bukkit event system kinda model (that's how i kinda understand it in my head anyway) or more something you had to constantly poll
I suppose there is a similarity
Plugin manager calls X event -> publisher creates a message in X topic
EventHandler listens to X event -> listener/client listens to X topic
different words but yeah that's how i sorta interpreted it
though once the message is consumed (successfully) it will be removed, unlike how the Event is passed to other listeners
ig if we didn't have plugin messaging systems in MC proxies, something like this is probably what we'd be using, huh?
possibly, though there might be some better solutions, cant tell really
or i mean to put it another way, the plugin messaging system is just a rudimentary version of something like this
PMS is so annoying ๐ฆ
plugin messages where originally intended for communication between server and client
yeah, tho from my understanding it's quite worse (I suppose by trying to keep it "simple") than the other mentioned solutions
as Star said, using Pulsar/Kafka would probably be overkill
i think i recall that LabyMod uses them to communicate with the server- i suppose Badlion Client does too since ik they have a server-client api thing
yeah Redis queues are generally a good in-between for being external queues but not being crazy complicated and resource-intensive
I'd probably try using Redis if not the limitations of where we host our website
yeah that's where it makes sense
because I don't have control over the software that's installed
https://web.archive.org/web/20220711204310/https://dinnerbone.com/blog/2012/01/13/minecraft-plugin-channels-messaging/ seems like the original blog is offline
ah weird, we just rent dedicated servers from OVH for a bunch of stuff so it's super easy to host our own everything
Also star you mentioned before with the expiring cache that the next site that tried to access the expired data would load it, would that be: specific site loads the data then pushes it to the cache?
yea
yeah well the owner is using the same host for probably over 10 years now
been telling him that we should move the forums
though that's a lot of work
you literally just have like python data = redis.get_data("data") if data == None: new_data = generate_new_data() redis.put_data("data", new_data) return new_data return data
yeah that's what i figured, just wasn't certain
isn't there a small risk of overwrites tho, if 2 websites access and load it at the same time?
like, if you're working with data that could change in the (milli)seconds between the two
who cares
the whole point of a cache is that it's a snapshot of a moment in time
it doesn't really matter if that moment in time is a few ms later
ig
so, reddis for caching data accessed by external services and which isn't available from another external service like a database?
as like the primary reason to use it
i mean it's a shared heap basically
man i didn't do computer science i don't fully grasp those terms
memory that multiple things can access
throughout the years of reading diff forums n discords I've seen references to using reddis as a cache in front of SQL (I think you or someone else here has even suggested that for me in one or two cases)?
How does storing relational data work for a mostly non-relational thing? Ig you'd have to convert it to json or smth?
it's a per basis, usually you only want certain parts of the data, so you just fetch, for instance, a User entity and their relationships that you care about and then yeah serialize to JSON and store it
then the other end can deserialize it and have all the things it needs
for some reason i just got this image in my head of a service running next to redis which takes the requests and converts the data, essentially using redis as its local cache
is that like a thing that people do or am i just tripping hard
uh that just seems wasteful lol
either the service requesting or the service providing can just directly use it
depends on how you need the data to be refreshed
like this hypothetical service would probably be responsible for loading data into the cache too
like a caffeine/guava loading cache wrapped around redis basically
I mean you wouldn't use a different service for that
just whatever needs the caching would do it, I'm sure there's a framework like that for Java and stuff, and like you can cache web requests generically in certain cases
but like, that pattern is so easy to implement, it's not really worth trying to have a whole separate thing for yk
i get what u mean, for some reason it just seems like something that ur multiple website examples would want to use to ensure consistent data across all, if that's important to them
the whole point is that redis is the consistent data
yeah but i'm saying for the loading part
if you really want to be specific about it, you could have a cronjob or something that requests a load from just one of them every set interval
but like 95% of stuff it doesn't matter if it's a few milliseconds early or late or whatever
the race condition doesn't affect anything
what sort of expiration times are we talking about, cus i'm probably imaginging different things
5 minutes, could be hours depending
it all depends on what you're caching and how often it updates
sessions are a good example, usually those last days and don't change often, so just whichever website instance the person happens to log into just stores the session data
like, if you need realtime updates and to have the latest data, then you just don't use a cache
you just have it actually fetch the data every time lol
yeah that's true, i'm conflating two different ideas in my head
on the one hand i'm imagining the cache in-front of a database, and on the other i'm imagining it as the only data source accessible by external services (like MC server player count data etc)
"in front of" is not a good way of putting that
wot would be a better way
idk like, to the side of? lol
like you just check it and if it's not there, you go fetch the data and update it
in front of works if we pretend it has contextual transparency xD
but no i get ur point
yeah there's a difference between an internal cache and an external cache
one you use in your own app just to save time and one you store data for others to consume
i suppose the idea that the thing storing the data somehow doesn't also retrieve the data is throwing me off
yeah that would not be the same scenario as the python code I showed
that would just be one server updates a value whenever it changes, and another unrelated server reads it whenever it needs it
so in that case you wouldn't use expiration timers
cause you just always want something there
right that's what i was kinda thinking too
but yeah the main use-case i'm imagining I could maybe ever use Redis for is stuff like server info for consumption by discord or websites
i feel like if i was storing stats or other things accessed from discord etc i'd also cache it in redis, just so it's always available to them in an easily accessible format (json or whatever)
yeah that's a common usecase, then the website/discord can just always use that as the source of truth
and it's like 1000x faster than a relational database for instance
ig for the stats example, which is already being stored in the database too, i'd just have the plugin/whatever push the data to redis at the same time as the db?
yea
probably want an expiration on that kind of stuff though
or well, it depends
if it's a lot of stats, you don't want to store too much in redis, so just caching it for a few hours could be good if there's a lot of repeat visits
basically you have to understand your viewer patterns
for instance, if it's the kind of thing you check once in a while and only once, then you don't really want to cache it
if it's a thing where lots of people want to check it, then it makes sense to cache it for a while
and if it's something small like online player count or something, then yeah you can just store that only in redis just all the time cause it takes up a few bytes
mentally i just really struggle with the idea of services pushing to or pulling from two data sources at the same time
like, the expiration meaning the website etc would have to manually pull the data from the db directly
yea
that's probably what it should do anyways
you want to start with the simple stuff, then add caching on top of it
if i'm using something like redis as the "source of truth", i would've thought i'd want it to be, the source of truth
you wouldn't use it as the source of truth for data that you're caching lol
true
that's the whole point, it's a cache
you just can use it as a shared memory pool for other stuff, like the online player counts
i suppose it's kinda moot since i doubt i'd ever have stuff big enough to where accessing the data directly from the db is undesirable
I mean it's just about latency and stuff right
like for instance, I use Redis on one of my websites to cache a relatively expensive SQL query that does some data calculation, so it caches it for an hour whenever someone runs it just to reduce the number of times it could possibly be run in a day to 24
which is like, basically nothing right
a lot of the times, yeah you just want to get it directly from a database
but like, for instance sessions on a website, you read that on every single HTTP request, so it makes sense to cache it
and they can also be ephemeral, so it doesn't matter if redis crashes and deletes all the sessions, you can just have people log in again
hm yeah
that reminds me, for the 'source of truth' data like player count, how would you deal with server shutting down? cus the player leave event doesn't always get called does it?
on shutdown set it to 0
^
unless it somehow crashes without calling onDisable
on shutdown, or on startup, or both? cus what about crashes that don't safely shutdown
then you probably have bigger problems
and it'll fix itself when it restarts anyways
๐
๐
it's a cube and a piglet
shush
make me tier 5 i dare yall
so ur saying both then, i take it?
i mean yeah, it probably doesn't really matter that much if it's wrong anyways
just a visual issue
really depends on the actual scenario
yeah case by case basis for basically everything lol
well i'm just imaginging that if you don't reset it on startup and your server has crashed without resetting the count to 0, when each player rejoins you're adding to the number that was on before
cache, well, is always gonna be a cache, meaning it's not always up-to-date data
redis is just a super useful tool
yeah I mean you would definitely reset on startup lol
yeah, that just sounds like a bad impl if not
it would probably be even smarter to just set the number to whatever the actual playercount is on any event, rather than separately incrementing and decrementing it
that way it couldn't be out of sync if it tried
so = rather than ++
yes
again, depends
what sort of scenarios could you think up where that wouldn't be a preferable situation
if the value is hard to get
playercount, for instance, is literally just an int you can request from the server and it's already in memory at any point
it has basically no cost to get, so you might as well just set it every time
๐
but if you have to calculate something for instance, or if you're keeping a running total, you don't want to recalculate the whole thing every time
so you just increment it as you go
or, if it's maintained by multiple clients (atomic counting)
right so like block placements for example (for some reason that's the idea that just came to mind)
no like the count of blocks ever placed for example
oh sure yeah
again random ass thing you'd probably never store but you get the idea
cause you don't want to get everyone's and add them together, you can just add them as they come
Hello, i need help with Deluxemenus requirments, can any1 help me please?
yeah ok that makes sense
i feel like this reminds me of some sort of issue discord ran into
they made their own snowflake service that calculates snowflakes or something for messages i think
idk it was on some blog post they made
yeah that kind of stuff is different
once you get to super high concurrency stuff like that, you need some new tricks that shared state would just make too slow
i think that's where i got the idea for the service wrapping reddis
their snowflake service kinda served a similar role iirc
except not around the cache, obviously
i wish i could have more converastions like this
where i actually learn shit
idk, maybe a bad example, but, say some sort of rate-limiter, you set the initial value N, per-request decrease it and increase it every X seconds
so that would be a increase/decrease rather than a set every time. Of course you could just re-set it back to N after some time too.
Generally inc/dec is better for concurency. (IMO)
yeah in an environment where concurrency is at play like that i could see its usefulness
yeah that's a scenario where you initially set it to 1 or whatever with a 5 minute expiry, then check and increment it each time until it gets to the cap, then once it expires you start at 1 again
could do cap then decrement
i'd probably do that, but then you need to worry about if you change the rate limit ig?
yeah that doesn't really matter
the nice part of incrementing is just that you can define the cap in code and it changes instantly if the code changes
true
but if you had something more long term and changed the code with it decrementing, the value would still be the same for the people before the update
which i suppose could be good or bad
depending on just how long term it is and whether the new cap is lower or higher
and potentially the reason for the change
anyway thanks for the explainer, you've given me a bit to think about
Hey good people, so i am in the beggining of minecraft plugin develpement. I have already made a spawn plugin, and now i am trying to make a home plugin. I've got it good so far, with gui, teleporting when clicking a bed.
My problem is that when clicking a TNT block in the home gui, you would get a new gui with home deleting. I have not managed to solve the problem, i made the code, but when clicking nothing shows up. Nothing in console, no command at all. I want the TNT_BLOCK to execute /delhomes. Can anyone help me with this problem, i already tried in a few days, but I ended up asking for help this time around, thanks. The Main Class Code:
https://pastecode.dev/s/FG8IuyXI
didnt you ask this yesterday
no one could help and wrong channel ๐
and asked at diff
anyone knows how to replace this message in 1.20.2?
used to work fine in 1.19 with packets, stopped working fsr.
Isn't it Bukkit help message or something?
can I read or modify Entity PersistentDataContainer in EntityDeathEvent?
try
can't find it anywhere
public void onPreCommand(PlayerCommandPreprocessEvent event) {
if (!event.isCancelled() && (ht = Bukkit.getHelpMap().getHelpTopic(event.getMessage().split(" ")[0])) == null) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', this.wat.getConfig().getString("UnknownCommandMessage")));
event.setCancelled(true);
}
}
```Is what I've used in the past.
tf is this ht = Bukkit.getHelpMap().getHelpTopic(event.getMessage().split(" ")[0])) == null
why not just Bukkit.getHelpMap().getHelpTopic(event.getMessage().split(" ")[0])) == null
Its super old code lol. It was meant as a cache.
I'm pretty sure it's minecraft's command systrm
Brigadier I think?
Idk why packets wouldn't work tho
u can instead remove all bukkit garbage
spigot too
just refl
and set everything to ""
what r the benefits to using PDC instead of file (json) storage?
easier
thats it? just easier to use?
cause im using PDC right now but i need to switch to JSON so just wanna know what ill lose
you NEED?
you just have to do a bit of effort loading and saving files
the pdc is saved in the data file of the player under world folder
now ... it depends on what you use PDC for
it can't entirely replace a DB
at that point use a DB
i really dont like SQL
- Why.
- How.
- NoSql then?
idk i just tried it before and did not have a fun time ๐
what are some DB that arent sql?
MongoDB is one
users would need to have one set-up tho
storing data in a flat file is not any better, especially if you plan to store A LOT of data
it depends how you define "better"
anyways, have fun with this
just use json files
SQL is great
u'll be fine
most shared hosts offer databases, usually MySQL, and for those that self host their server, it should not be a problem
well its your choice to not use SQL xd
doesnt matter unless u have a bazillion entries
SQL you can easily support SQLite and MySql
he can buy a mongodb lol
let me quickly read this 5gb file to load player's x data
its for a public plugin
simply dont get a 5gb file
yeah
mongo just allow u to store objecs
maybe instead sarlizie them to string
and backwards each time
which .. is .. what .. databases .. do? Store data
seriously, it's very easy to avoid this, even with a ton of data
separate files solve most problems
mongo allow u store object as object
and async loading solves the rest
depending on size that might take huge processing power
SQL is just good cause you can request just what you need
is it possible to put the sql statements behind a library?
and not a whole god damn object
that you then have to deserialize
and get whatever you need
then use memory
yes, I think it is called an ORM
yeah there are several
yeah of course thats why i said separate files
you shouldnt have any files that big in the first place
hibernate and JOOQ are some options of java ORMs
i used to sperate players data by A B C (as first letter in name)
ended up with 1 gb of A
yeah I was just joking 
hmm alright ill take a look
that's just... dumb xd
performance to dogshit
i know...
it was when i started coding couple of years ago
i was thinking its a easy way to split
to many files
but yeah ^^ these are the most famous for java I think
Afonso i got a question do u use a library for settings player names (display over head)
if not what do u do scoreboard? packet manipulation?
https://ormlite.com/ this is one - it has an example of how it works
you mean modifying player's names? (either just display or both)
only display name
not actual name
if u modify actual name it will mess up with many other things
actually, the library I used once, allows that without issues
or at least, I didn't see any
1s
i dont want to use scoreboards anymore to add prefix for users... i think instead to manipulate with packet to players side only
https://github.com/iiAhmedYT/ModernDisguise it has skins and mob disguises but I only used the name part
ill check it rn i hope it doesnt depend on ProLib
it doesn't
seems promoisng thanks alot!
i dont know why i hate protocolLib so much
like maybe beacuse its dependecy
I hate it too lol
I hate it because of the huge amount of performance issue I already had to deal because of it
lol
also just saying, even if you had a comically large file, the performance wouldn't be that bad (take these numbers with a large amount of salt though)
and the funny part is usually you can't find out which plugin is doing it easily since Spark profile trigger ProtocolLib instead of the plugin using it xD
I mean... 2s for one file is quite a bit
imagine loading that file for 100 players at the same time
lmao
sure, but consider why the file would be that big in the first place - that's presumably all the data you'd ever need
if you have 1gb of data per player you're doing something very wrong
1gb for 100 players isn't too bad though
a database query could take close to that just from network overhead
have you?
what?
lmao
local db 
๐
(it was a one commission thing)
that sounds more like they have an infinite loop somewhere
they should clear old users data or move to different file
thought so too, but apparently not
at least their main dev says they don't xD
the server had started a new season like 3 weeks ago at the time
lol
I have no idea what th they are storing
unless they are like tracking EVERYTHING a player does
or smt
idk
biggest data file ive worked with was 2.5 GB in yml
god
server did not have a fun time (if players spammed modifications it'd lag a ton)
i dont use protocollib to send packets anymore, legit only used it to modify packets that the server sent that i wanted to modify before hand
like chunk data packets,
65,829 lines
wtf
it cant be 2.5gb then
no caching
it must be long af lines or something
2,588 KB is 2.5 GB no?
shit
๐คช
its small
i had couple of million lines
on my file which was 1gb
anyway also if we mention big files here
ok yeah sorry i misconverted somehow
i mustve converted to MB
thats more than 3 GTA 5s
yeah alot of data
of what tho????
i love that error!!!!!
๐
but the software which reads the file
was written so well
math tricks are amazing behind it
haha
i love using flatfiles for small things
like settings and etc] in my personal projects tho
that's what flatfiles SHOULD be used for lol
who th uses a db for some settings
xd
I mean, in some cases yeah, useful, but most...
imagine bro i still encrypt them so user can change things only via commands
average user data be like
its way longer yeah
now my encryption have a seed i take from host property so if someone try load files via other server he wont get data and wont be able to reverse without trial and error for hours
to get the data inside (even tought thats just user data not important data)
why though
I am so confused on why you need this
xd
yeah not sure what the benefit of this is
if someone gets access to the files to be able to load them somewhere else, surely they can also get the host property at the same time
main benefit i know if someone steals my resource without decompiling and reversing it he wont be able to use the plugin
nah u wont be able to even load plugin on different IP from what it was compiled for
petrotactyl does not allow me to allow , to block people from downloading an spesfic file
and i allow many people to accses server panel
yes java is open source sort of
but at least it wont be so easy for someone once i feel i had enough with it ill publish it but for now i want to stay unique with my plugin lol
think about it whats make some rocks like diamond so valuable , that they are rare/unique... if the server plugin will get leaked many pirate copies of the server will appear and it wont be special anymoe like it is now
u wont be able i take machine IPv4 from web server and some other data. to make a part of the seed of encryption
sec ill shortly explain with a picture from the code
then just encrypt it on the same machin?
decrypt u mean
yes
ig atleast with the player data being encrypted a rogue admin couldnt modify the data secretly without pain
like changing their currency amount value or smth
What happens if you have to fix something?
you die ig
if an admin has access to the filesystem then they probably also have access to the console tho
but maybe there are some very niche benefits still idk
that's kinda a dumb logic
it makes it harder for that to easily happen yes, but anyone can just copy your features themselves
either by paying another dev to do it
or coding it themselves
its actually not dumb logic
dunno why you cant see the difference between many hours of work or many working hours' money spent and git clone
Also not everyone has the resources to copy it effectively
re creating will take alot of time u dont need the resouce to re create it..
and also finding the tricks that were used to create some illusions and etc
i dont care if someone recode it he is more then welcome
it depends on the problem usually if an dupe bug / big mess happens i do have rollback of all data for 3 days backwards (every server restart all files get copied and stored in sperate file/folder with date/hour of save
Idk is just dumb to encrypt data of a public plugin, idc what you want to do with plugins you make for your own server 
its not public... and if its public there nothing bad in it if devoloper doesnt want the plugin users to modify different data begin saved on the flatfile manually
I would not install a plugin who's data I can't edit LOL
thats true, but modifying a player's data file would leave no logs
You said that you use something from the host as a seed, what happens if the user changes the server (e.g. for an upgrade, better price)?
its not a public plugin though
it doesn't make a difference, you can also change the server ๐
yeah but at that point you have access to the code and you just change it
and compile it again
what even is the idea behind encrypting the data?
if you don't trust those that have access to your server files, perhaps don't give them access in the first place 
is not possible to set user read access per directory?
not in ptero

if you're encrypting the data where exacty are you storing the private key?
from what I understood the private key is derived from client specific metadata like IP etc.
average dkim comment deletion
well bc u already sent-
smhmhmhmhmh
ok i can just decompile the plugin (or just hook into it / read the memory) and find it
yeah
I don't think it's meant to be super secure, just enough to make it harder
because there really isn't a place to put a private key
unless you manually enter it on server boot
yeah there really isn't a great way to do it
hi dkim
since you're basically trying to protect the user from themselves
what happens?
i cache data
and rewrite files on save
there no key. i use server IPv4 as license
inside the plugin i dropped different checks some are even in events not on plugin launch and executed in delay
i tested it
i dropped around 30 checks
different ones to see if it should not run on the other machine
if someone gonna be able to decompile reverse it and etc he should be able to rewrite is own resource too
suddenly there no much u can do , but at least making it harder..
so im not worried if someone will just download the plugin and think to publish it as a revenge or something , since once it will happen my server will be worthless , same as imagine someone get his hands on hypixel skyblock server
pretty sure ton of replicas that will offer different shit will appear and it will damage hypixel playerbase
Just use Kotlin 
And good luck to anyone trying to decompile into something
I mean, they still will be able to edit the bytecode, but you knowโฆ good luck with that 
Is Kotlin harder to decompile?
At that point just run and open in gdb
I meanโฆ
You will have a hard time doing that
The best you will get some broken Java code
With a lot of garbage
oh, interesting
I had a client coming up with an old plug-in I have made for them, which I had no source code for at that point, so I literally just edited the byte code in the place of function which caused a bug 
It was a lot of fun
Yea
I'm imagining it was a pretty complex plugin
With coroutines 
What kind of code did you inject into it?
I was playing around for an hour until figured out how to not break the coroutine the code was inside of
I just had to remove a function call
I see
But due to Kotlin stuff it was much harder than should have been
Good for you ๐
I wouldnโt want to be in that situation either
But had no choice
๐ฏ
๐
someone give me maths how much data would it be if I'd track player movements every 3-5 seconds and save it to the database with 150~ players online
Like a scheduler that gets the location every 3s?
depends on what data you actually save
Near to nothing
Sounds like smth very easy to handle 
I don't need yaw pitch
just general location
easy - yeah, will I flood my database? questionable
doesn't sound like that much
Clear records older than x days if you don't need them
yeah I'd probably keep the week worth of it
if my calculations are correct it would probably be like ~250k bytes/hour
with 150 online players, on a 3s interval you get 180,000 entries per hour
to do some quick math, a uuid is 16 bytes, then x y z together are 4*3 bytes, then world ideally is an enum so idk maybe 1 byte based on impl + timestamp of 4 bytes = total of 33 bytes per row ignoring overheads
oh, forgot about timestamp
150 players at one entry every 3 seconds is ~50 entries a second
i guess it's kinda doable
this is 5,760,000 4,320,000 entries every day if my math is right
which is 184 138mb of data per day (again before db overheads)
hm, so it'd be like ~1.5gb for a week worth of data
databases can probably also compact that data
Definitely more data than I estimated at first, thanks for doing the maths dude...
alternatively, you could store deltas, might make sense especially for timestamps, but that depends on what you want to do with that data afterwards
ever heard about watson mod?
basically uses data from CoreProtect/LogBlock and displays it in the world itself
I have an idea to make it be able to display player movements aswell
Saving World UUID in each entry seems a little bit expensive, instead you could create a table that associates each world uuid with an int (TINYINT if SQL), and then use that integer to identify the world, then you can save some bytes
i was assuming the world would be stored as an enum
That makes sense
not world uuid
world name
but yeah, another table with worlds would make sense too
Use cache
It will be real light weight
I store way more data
Per second without problems
About 600 objects a second
Just use a db they will do all the math tricks for u
To save data
And add some performance checks like if user didnโt move donโt update
It wonโt be heavy anyway if itโs the question
I would suggest u if itโs something to save disk space and u donโt mind to execute expensive disk , cpu tasks
Compress older files
To save memory on disk
If u think problem is within something else make bulked updates to sql after reaching X requests
Thatโs the solution if itโs too much
It will be a lot of data if he doesnโt do much about it
Idk Iโm just overthinking sorry
Dumb Tony
That's so cool
yeah, very useful
@sonic nebula as usual, slow down with the spam 
spam more
but yeah, dumping the week of data in a very efficient byte format and compressing it with xzip or whatever thats called at the highest compression should give you fairily good recoverability
so i saw an cool API
but
i will better manually implement his entire resource then using a sperate jar
and yes its opensource if anyone wonders
just shade and relocate if you have to do a fat jar
doing only one is bad practice regardless
can anybody understand timings report? Our server has some massive TPS issues.
i prefer a fat jar ngl
then 3 sperate jars
thanks ill try and see what the results
^^
but not sure if its gonna work since its probably not gonna run the main class
since its like a sperate jar like protocolLib
ew ew
lightweight model languages? with API
send timings log and also is minecraft general plugins chatt
also i dont mind to do it depending on web req and responses
Chat gpt charges cash lol
classic tony falk shizo rants
schizo
tony's our local terry davis
You lose independent and dynamic redeployment if you bundle everything into one obese jar, not that it matters if you code a little spigot plugin but Aki has a point to some extent.
wheres the difference between obese jars and shade & relocate
shading is just making a fat / obese jar no? And then relocate is just if it happens to be the case where some classes are already used and loaded up in the jvm so you avoid chaos by changing the fully qualified name (i think its called this right?) of those classes, since your jar would load them up a second time. Although iirc there is sone classloader hackery to make it work w/o relocating (to some degree)
thats exactly what i thought
But tony made it seems like those are different things
I believe the usecase of relocation is highly specific, donโt think its used a lot outside of for instance mc dev.
i donโt know, toni is toni
Someone able to help me fix this?
java.lang.NullPointerException: Cannot invoke "me.clip.placeholderapi.PlaceholderAPIPlugin.getLocalExpansionManager()" because the return value of "me.clip.placeholderapi.expansion.PlaceholderExpansion.getPlaceholderAPI()" is null
I'm using gradle. compileOnly 'me.clip:placeholderapi:2.11.5'.
I check the plugin is loaded before registering. I have it as a depend also.
Latest PAPI + Java 17.
XY problem?
How so?
I've looked at other people's issues. Shading was their concern.
Yeah that is the most common problem.
This is the full stacktrace. https://pastebin.com/KkSW11ue
Your plugin / expansion shade PlaceholderAPI. Here's how to fix that:
- For Maven, set
<scope>toprovided - For Gradle, use
compileOnlyinstead ofimplementation
Shading and not depending on it are the most common issues but I would assume you already tried that
Yes ofc.
Try to add papi as (soft) depend
I'll give it a go
actually can you show the code you use to register? Or did I misunderstand and you are trying to do something else?
Also, are you using Paper plugin system by any chance?
I am using paper 1.20.2
not what I asked
if(Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
new ServerStatusExpansion(this).register();
Bukkit.getConsoleSender().sendMessage("Successfully registered Expansion!");
}```
Errors on the #register
name: ServerOnlineStatusSpigot
version: '1.0.0-Beta'
main: me.sean0402.serveronlinestatusspigot.ServerOnlineStatusSpigot
api-version: '1.20'
author: "Sean0402"
softdepend: [PlaceholderAPI]```
Tried depend. with & without.
Double check that your jar doesnt contain papi
^^
Ok
well it's on compileOnly
so it shouldn't
uh?
Would ShadowJar override compileOnly?
do gradle clean shadowjar
could this be caused by not matching papi version in the server?
just random thought
although I would assume not much would change between versions
yeah ignore that
So the shadowJar only contains my classes. No libs.
But for some reason it's building with all :/
Send your built config
Not like they are very different, especially for basic configs.
Paste Services
When asking for help with a config/menu/code issue please use our paste bin:
(we prefer it over pastebin.com)
โข HelpChat Paste - How To Use
idk why you have all these options in shadowjar and dependsOn etc.
Does anyone have any resources for how to write a simple (I hope this gets clasified as simple ๐คฃ ) parser in java?
I need to turn a string like Result: {#math}5+5{math#} into [LiteralStringElement(value: "Result: "), MathElement(value: "5+5")] (string representation of List<Element>)
It gets more complex, as tags should allow attributes as well, basically XML tags with different symbols for opening/closing. {#math precision=3}100/3{math#}
since u have { } u basically can loop
and get the context and do a switch case of the input
if i understand u correctly
open switch case close and thing to do with context between
how is that useful
I agree with tony
loop chars, once you detect a { and } you can use switch case to know what to do and stuff (ex #math = run parseMath())
should have a method like readTextUntilBracket, etc
idk how to explain well without just writing the code
but that's like how I made a json parser - lemme see if i can find
it's in kotlin but should be readable
https://i.imgur.com/UwcRFJI.png
json uses { and [ to identify between types of inputs, but it is the same concept with #math and whatever else (when in kotlin is based off of java's switch)
although i feel like you might just be able to use an xml parser somehow
also this is very very very similar to minimessage
just saying
ยฏ_(ใ)_/ยฏ
- I think you can use xml parser after doing some basic Regex replacing
Using MM for this sounds like a bad idea if that's what you mean dkim, an idea I had 
Plus the arguments syntax (<click:_action_:_value_> for example) is different from what I would want
Ive started with xml, but it doesn't preserve whitespaces, so that example will turn into Result:10
o
I've seen the basic concept of a parser that works that way, but I have a hard time how to store the values I read so I can come back to them when I read a nested tag for example, and then I need to grab the parent tag to close it ๐ฆ
Although I think I have an idea... after {#math} I just read everything as a raw string until the closing tag {math#} and then I parse the string separately
should make a json parser ๐
no replacing with regex
no reason.
wait, what if you have a math in a math
well idk if thats realistic depending on your tags but
I meant replacing {#math}5+5{math#} to {math}5+5{math/} to just be able to use an XML parser
oh i see
I was just thinking about that 
nvm I didn't see that the ending tag has hashtag at the end
I'm feeling like you will have to deal with some recursion :d
just use string builder
Yeah I will do some testing tomorrow
It does, but I need to get the right closing tag {#math}2+2+{#math}5+5{math#}{math#} - just an absurd example
you can just have an int variable to count how much nesting there is or you can do what i do in https://github.com/dkim19375/JsonParser/blob/main/src/main/kotlin/me/dkim19375/jsonparser/JsonParser.kt where it just parses it as it goes (although since json tags are 1 character - [, (, ", etc, it'll be a bit different)
both should work fine
is this a hobby project or do you really use your own JSON parser in your projects (very cool :d)
someone in a discord server made by Brister Mitten loves json parsers for some reason so I made one ๐
I still use GSON in my projects tho
lemme see if i can find performance comparison
unfortunately it lost every time :(
Jackson 
what is the best way to create a skull with a player skin (will use in a gui)
I saw some ways that uses reflection but I think there should be better ways (https://www.spigotmc.org/threads/skull-texture-issimilar-npe.418897/page-2#post-3709604)
vs thing to create GUI's with that has a gui
its like copy paste buttons and shit
and u can put pics as background how its called?
edit: nevermind I completely misunderstood
5-6 years ago i used something in visual studio that allows really easy interface design
like for android apps
i need to design nice UI for my chat bot
also i found out how to make a language model + -
i assume it is , also ended up with ton statements lmao
and doing good design with JavaFX is hell
Android Studio (not vs) has an app interface designer thingy (then it automatically converts it to xml)
if that's what you meant
yeah but its not android studio
i just givd it as an example
its for windows
hmmm dunno
i hate xml hate hate hate
dkim nah its 5am i guess im no tin 100% state yeah i read it now nah i meant it simillar to android studio
nah i work only night shifts haha its all gucci
tbh i have no friends ;[
all always sleep
once i wake up i appear again at wok
work
and loop
12h shifts
what is this designer thing for?
i made a chat bot
like langauge model
and i want nice interface because mf's eat with their eyes firstt
its not like gpt level or something
but for its goal it works pretty well
because if it's just for a website, then you can just use figma to design the site or just dive right into writing the html stuff
nah i will later on convert it into tg/whatsapp support
but I don't think theres a javafx/android studio-like thing to auto convert it to html
nah there wont be interface later on its just for now
maybe ill put font for textt
beautiful
๐ฆ
i love how those are the only two options though
eh i remember i used to have an american friend i used to stay awake till late just to call her haha
haha
k getting better
i guess
some how
also added back send button
to capture space
instead of listening to key
sex?
it says se
oh yes
sexy
ill make app crash if it doesnt have WiFi since ill load all pics from web 
i dont keep tthat heart background
ill put cat with whiskey instead i think this is painful for eyes
i dont get sponsored by whiskey but i think its like belongs to the app
i mean client will like it
i wont send any updates due server rules since its against the policy o rwhat ever
what java version do you guys use for development
depends on the software
17 for mc, 21 for other stuff
ye i just found out that 21 didnt work for minecraft :/
Gradle 8.5+ supports Java 21
ooof thats why i dont mess w coding stuff
i just now pushed to my old pr a deluxemenus fix
You just need to change the version in .gradle/something.properties iirc and then reload gradle
yeah i m trying rn
u havee to update
the jar file
anyway nvm
i use java 7/8/16
it really depends on the project
Thatโs a bit odd, usually 8/11/17/21 is preferred since lts
Do deluxemenus have api?
Is there any docs?, i mean list of event etc.
Yo if someone can help me with something dm me please
Can someone help me with something important about other plugin?
ยป Give the helpers some details
ยป Ask suitable questions
ยป Be polite
ยป Wait
There are no events, I think the only thing you can do is to open a menu
chatgpt says they are called apps or applications and they use the .app extension
Anyone familiar with kotlin that can help me? I'm using this api https://github.com/Auxilor/EcoBits/blob/master/eco-core/core-plugin/src/main/kotlin/com/willfp/ecobits/currencies/Currency.kt but I'm not sure how I would get a players balance or set it, because the api uses kotlin extension functions
ill ask chatgpt how can i convert an jar to .app
ill search on how to run it in first tplace
Instead of giving you the answer straight away, let me help you understand it
You can see at the top the annotation @file:JvmName("CurrencyUtils")
That means that in Java this class is called that
So for example fun OfflinePlayer.getBalance(currency: Currency) in Kotlin offlinePlayer.getCurrency(currency)
and in Java CurrencyUtils.getCurrency(offlinePlayer, currency)
Without @file:JvmName it would be the name of the file + Kt = CurrencyKt btw
Ahhhh that's actually very nice, thanks!
I'm yet to learn kotlin, but it actually seems quite nice
Can you not make custom enchants in 1.20.4 spigot?
it was never officially supported
๐คฆ NVM issues with static/private
I see what you mean now. Can't find out how to register the enchants anymore. Hmm...
i suppose updating my plugin is gonna be fun
It is now a registry that emily said you supposedly could unfreeze
Yeah it goes deeper than that. I can't just new <enchant>(Namespacedkey) anymore either. And there is no method to set the key...
I'm surprised md_5 did this because he usually tried keeping backwards compatibility
Or forwards no one knows which is which
๐คท
Java has backwards compatibility
Pretty sure someone on the staff wanted to convert everything to registry. They were saying it for awhile. When that happened it prevented backwards.
for things that are supported, yes
And there is no method to set the key...
Fuck!
@Override public NamespacedKey getKey() {return null;}
Another half hour wasted lol
waiting for paper to hard fork be like
Hmmm yeah still not applying...
ItemStack stick = new ItemStack(Material.STICK);
stick.addUnsafeEnchantment(GlowingEnchant.glow, 1);
player.getInventory().addItem(stick);
before that happens Hanger or Modrinth have to support paid plugins xD
They said they won't
why?
Also, wrong.
Idk about Modrinth but Hangar never officially said it wouldn't have paid plugins
it's actually something they are looking into for the future.
They just want to make the infrastructure as good as possible
And besides that, Polymart and BuiltByBit probably would support paper plugins
so...
Yeah Ik
I just think that having Hangar and Modrinth on the train would be better
I mean it's not like anybody is using Spigot anymore
Contradicting statements from paper staff...
i mean 2 months have passed but yeah
we love lying, yes
thats what i saw too
oh shit
one is from 2022 the other is from 2023 
yeah i JUST saw that... craazy
Yeah I haven't been in that discord for ages just searched up "paid resources" lol
what you cannn
wdym
not with offical API but with NMS
guys should i use completablefutures with files or is it overkill
depends
is this file creation or file reading/writing
if you're doing it a lot, like a lot of lot it cant hurt but
Well, I got told by the Hangar devs that there are plans for it. Just not big priority.
๐
Any reason why java ConsoleOutput.instance.debug(data.getClass().getName()); Arrays.asList(data.getClass().getMethods()).forEach(m -> { StringBuilder sb = new StringBuilder(); Arrays.asList(m.getParameterTypes()).forEach(t -> sb.append(t.getName()+",")); ConsoleOutput.instance.debug("Name: "+m.getName()+" Return: "+m.getReturnType().getName()+" Params: "+sb.deleteCharAt(sb.length()-1).toString()); }); Would only be displaying 2 methods when there are clearly more? I also tried getDeclaredMethods() ```
DEBUG >> net.minecraft.network.syncher.DataWatcher
DEBUG >> Name: b Return: java.lang.Object Params: net.minecraft.network.syncher.DataWatcherObject
DEBUG >> Name: b Return: void Params: net.minecraft.network.syncher.DataWatcherObject,java.lang.Object
man what is this code
peepeepoopoo
Debug to figure out why it wasn't providing the method.
Still have no reason as to why it's not.
have you tried using a debugger?
oh jeez
Nope just the strings at the moment. I have this code in another plugin running fine so it's weird that it's not functioning here.
always move io into a seperate thread
unless you are loading on launch etc
So any ideas why it doesn't show the other methods?
i personally just say fuck it and manually add the enchants using nms to a seperate enchantments list
under a different compoundtag name