#help-development
1 messages · Page 757 of 1
mhmmmm
I have my own made for 1.8, approx 3 billion blocks per second it can reset
All async
Uncostomizable red- eye pain messages
No MSPT increases
why didnt you use worldedit
(from testing)
im debating on implementing my own reset system but idk if i can be arsed for that
"3 Billion blocks per second"
normal worldedit cannot handle 3 billion a second without lag mr purple
fawe or awe can
not 3 billion
Oh, I was quoting myself, I meant I created a reset system that can set like 3-6 billion blocks per second
Asynchronously, not effecting MSPT at all, all smooth
smh
lol
With this, I should be able to create a subdirectory in my plugin root folder right?
Eg.
PluginName/ - root
PluginName/data - subdirectory
File tempDir = new File(fileFolder);
if (!tempDir.exists() && !tempDir.mkdir())
throw new IOException("Cannot create a directory!");
If I pass in the usual stuff getDataFolder().getPath() + "/data" ?
it should work?
Nvm works now
How can I add a hex color in my msg string below?
private final Pattern pattern = Pattern.compile("[a-fA-F0-9]{6}");
public static String sem_perm = "You don't have permission";
You know
At this point
sun.misc.Unsafe
Be looking real sexy
hmmmm
What did you use for block setting? Only thing I can think of is NMS and directly editing the pallette
This is honestly for 1.8.8, the one that I made.
Ah
The way it works it creating a "Fake" world. I manage the chunks, I manage the blocks.
All packet based
Dang, my whole Discord changed on my phone😂
does cancelling a task nullify any references to it? like if I had a variable like BukkitTask task = new TaskClass(); and then ran Bukkit.getServer().getScheduler().cancelTask(task.getTaskId()); would that task variable become null or would that variable still be populated but not scheduled?
It would still be populated
okay cool that's what I thought
✨
Click on the emoji once, then on the pop-up long-press the sparkles
And then?
Long-press for like 5 to 10s until you get a pop-up
Then restart discord completely
Un-fucks the UI
really weird way to fix the UI
you can do it via settings as well, appearance -> show new layout
?learnjava! You don't need to be spoonfed, you are not a toddler any more
Here are some links to get you started on learning Java:
- https://www.codecademy.com/learn/learn-java
- https://www.sololearn.com/learning/1068
- https://www.learnjavaonline.org/
- https://programmingbydoing.com/
- https://docs.oracle.com/javase/tutorial/java/index.html
The last one is the only official one, however some of those concepts assume that you already know a bit about programming. https://media.discordapp.net/attachments/694661573125472256/998143126373941248/6n0v4g.gif
and i ask
a day later for
line code
/searchitem <player> <itemgamemode1>
for <player> -gamemode1
i little spn
?spoon
Spoonfeed a newbie for a day and they'll come back with more questions. Teach them to find their own answers and you'll both be better off: you won't get stuck answering the easy questions and they'll be much more productive than before.
2s i search line code
Brother just learn
Is there a way to make blocks only visible with nms?
my idea is make chests across the map that people can pick up once, so they can only be visible until u click on them and then they never appear again, and the player gets rewards for clicking on them
Uhh yeah
Player#sendBlockChange is a start
But you'll need to work with packets to detect clicks
i tried searching on google for it but all i found was thing for falling blocks and nothing else useful
can't i technically just check if they click on air and check if that coord is of a chest, and if they haven't gotten it before, they get rewarded for it?
well yeah but no
cause i just need the chest to be an illusion
The client will send a packet for whatever block it clicked on
i know the server will see it as a air block
oh fr? even if its fake?
Yeah
yes
thats useful then, just need to check if its a chest
I'd make something like a
That's how me and my friend made fake worlds
btw a different question, do fake entities lag as much as real entities to the players fps?
because real entites are the exact same as fake entities
Map<String, FakeBlockContainer> worldMap
and the FakeBlockContainer just being like a
String worldName
Map<Long, FakeBlockChunk> thing
and the FakeBlockChunk just being a
int chunkX
int chunkZ
Map<Integer, FakeBlock> where the int is the index within the chunk
yes
just curious
just fake entities are not actually ticked by the server
the client just handles them the exact same way
this is fun
thank you
lmao
is there a way for this to not happen? 🤔
@echo basalt @rough drift
you can just disable the flying thing on config
and impl a proper anticheat with fake block checks
i kinda dont want to disable the flying thing 🤔
will see how this goes, it takes a few seconds, hope nobody does it
even if they do it, they can just reconnect, the world where this happens it's 100% safe anyways
i rather keep the flying thing turned on for now
just render a fake barrier above as well
thought about this, they could go one block up
even if there's a barrier above, they might be able to jump above that, i would need to make more than 1 depending on the location
and if the chest is in the open, they could fly or jump from a mountain or smth and bug it
so for now i will just ignore it and see how it goes, if people want to mess up with it for their own disconnects, fine with me
is there a way for players to click on block AIR without hack clients?
with the PlayerInteractEvent
cause im noticing if there's nothing, the clickedBlock is null, but if it's a fake block, it returns as a AIR block, not null.
so i can check if they are clicking on air in this world for the chests, dont need to work around with nms packets.
if they are using an item, yes iirc
I mean yeah
so i was asking if there's a way for them to click without returning null
no
cause if there isn't, then i can use this for the chests interaction
i just need then to check if it's a location of a chest just to make sure
yeah i will then check if it's a chest location and if they havent gotten it
Can I somehow read/find properties file with the API?
Because it can be in a different folder
no I don't think so
Someone reported to me that it can be moved with an argument
--config
I wonder if it's a spigot, vanilla or paper thing
What is recommend to use for a database connectivity? JDBC? Or is there a better alternative?
Planning to use postgres for personal projects but I'd like to support multiple databases for other users.
But postgres would also work with jdbc correct?
It should according to https://docs.oracle.com/cd/E19226-01/820-7688/gawms/index.html
yes
I added a few DB types to GroupManager (via Hikari) a short while back, Postgresql was one of them
jdbc:postgresql://%HostName%:%Port%/%DatabaseName%?characterEncoding=utf8
And for people that don't know how to set up databases, should I use H2 or SQLite?
And would it be easy to export from those to an SQL database and vice versa?
is this overengineered?
H2 or SQLite makes no difference, other than SQLite driver is included in Spigot
Alright, I'll probably go with SQLite then
it's for the best
No not at all
awesome
I have a slightly more engineered one
you can use local databases that are non-sql
Basically, in file
why not sqlite
its the most commonly used one
H2 is good too
i don't like sql and everything that is nosql is better than any sql thing
Okay
my sql code will scare you
yeah
will give you nightmares
https://github.com/orang3i/Gangsenjoy ur nightmare
thats why i dont like sql becuz people cant even write sql also you are using java so use java for everything lol
it gets the job donee
if you use sql
one code for both sql and sqlite
just a single method for choosing which one
Not quite
for my project atleast
Sadly MySQL and SQLite have different syntax
i use ormlite
So you gotta be careful
MySQL and SQLite wouldn't be sql databases if they wouldn't follow the syntax and the general principle of the structured query language
They have the identical syntax, only the feature set differs
not quite teh same syntax
Because?
I don't understand what you are trying to say
is there a way to hide worlds from getServer().getWorlds()?
eg
Mysql has boolean where SQLite you have to use int
depending on driver of course
Whatever you want to call it, syntax or feature, the point is
i just use string for everything 💀
Ya gotta write different queries for each
yep ^
hey how to extends EntityCreature in nms 1.20 remapped?
?mappings
Compare different mappings with this website: https://mappings.cephx.dev
how to get Nms world in nms 1.20.1?
?mappings
Compare different mappings with this website: https://mappings.cephx.dev
How do particles work, so you can't see them from a certain distance or is it some sort of y level?
hello
how to avoid ConcurrentModificationException?
code:
https://pastebin.com/tL2ZUtY7
Collections are not thread safe on default. Meaning you cant just concurrently access them from async threads/tasks.
Pro’s use arrays
You send particles to a player which is in range of the view distance. The packet also allows forcing the client to render particles regardless of distance.
No lol
How can I make a code that would make cases depending on how much of them Id put in method?
As in, if my method took argument of 5, it would make five cases from 1 to 5
"took argument of 5" what do you mean by that
True pro’s use reflection to create / get individual variables
int 5
Sorta
Well not reflection that shits not the right thing
method(int amount);
But VarHandle
I give amount 5
Wait so the particles will appear regardless if the player is 100 blocks away from the particles or do I decide that distance?
I love reflection😭😭
I don't think you can make a switch case dynimically
It makes switch for 5 cases
You can deicde if they appear far or not
Runable👍
You must be the only person I know of to like it
Show me the code for a specifc amount (like 3) and i will dynamically scale it for any integer N
Wait i meant
I love nms reflection 😭😭
How can I make randomizer that would take into consideration weight value
okey, how do I do that? 🙂
We need not to be friends :>
I dont think that making array of 100 values is a good idea for that
Sad lore
Lol
iirc some of the spawnParticle methods will have a boolean argument
how to register MeleeAttackGoal in nms 1.20.1 remapped? i from 1.16.5 nms and now up to 1.20 but everythings look new and i can't register MeleeAttackGoal it has error The constructor MeleeAttackGoal(CustomZombie, double, boolean) is undefined also with RandomStrollLandGoal pls help 😭
I dont have any
Im on my phone
Before we go into weighted collections, just show us the code you want to dynamically scale for any integer N
Oh i know
Wait im not allowed to say😭
?mappings
Compare different mappings with this website: https://mappings.cephx.dev
Idk what you mean by it
Should tell you the proper names for stuff
Oh i am allowed
But can I decide how far this particle cell should be visible?
world.spawnParticle(Particle.EXPLOSION_LARGE, location, 10, 0.5, 0.5, 0.5, 0.1);
If you only would use the superior brain api instead 😔
Import
declaration: package: org.bukkit, interface: World
Only for noobs
No
I want to make lootbox plugin that would be more universal, takes amount of drops available and their odds to randomly pick one of them
The last arg is a boolean called force
So?💀
And im stuck on a point where the code could tell apart how many items in pool there is
and they wanna make everything data driven in principle it looks like
Wdym so?
What do you think all these api’s are based off
Only thing that comes to mind is arraylist
how to use it
brrr
it don't say how to use, requirements, covert,etc
Use the searchbar
This looks... very familiar
Based off?
Nms code
Stackoverflow moment
"force - whether to send the particle to players within an extended range and encourage their client to render it regardless of settings"? 🙂
yes
You dumb? I meant mojangs own apis
XD
the goalselector and target selector are gonna get yeeted off soon
Wha
Since brain replaces it totally
My newer Impl uses guavas RangeMap for this
Fancy
Ok but no
But yes lol
Its really not possible to make independent code?
wdym independant code?
Because its superior
They aint gon rewrite their whole ai system
They already done so lol
This is just a simple java class. It doesnt use any libraries.
Everything could in principle just be replaced with the brain api
So do I just copy it into code?
I wuv pathfindergoals😭😭😭
It would make sense for them to replace it
Just need to create a few more activity types and stuff, but in theory its plausible
See I want to tackle the pathfinding api in spigot again
But if Mojang has plans to yeet the old system it would be a waste of time
More and more mobs use them because its just a better way to support mob memories, mob activities and so on
Yea lol
That's called a list
Well whatever semantics
Wurden
ArrayList is basically a dynamic array
I make a thing and add things to it dynamically
Yes wurden 
Java5👍
what should i do?
Do all new mobs use brains?
Brrraaaan
iirc most
Okay I think I could work with that
Ask yourself if you really need to run this task async. What is your reasoning behind this task running async?
I mean a brain api for spigot is also possible
And it turned out its pretty much implementable with brain only
That it gonna be easier once its global for all mobs since its by nature data driven in principle
A lot of things are data driven
As all activities and memories are type based
i can run this task without async
but what should i do if i need to run task async?
yeaaa coll
Doesn't make an API for them easy 😩
No more of me screaming
The big hurdle atm
Is that datapacks load super fuck off early
And then the regestries all get frozen
Ah
Hey cube
Then its about time we get rid of these enums
Sup
That's been worked on
Hey cube, bff?
Nice
PotionType and Particle are already registry backed on prod
okay
Ensure that your infrastructure supports concurrency. We dont know how your structure looks like.
Omg brother
Coll, is the api gonna provide functionality to see original vs changed data
i have ConcurrentModificationException without async
Ill make code that would add as many values as stated to represent weight and then Id make random int from 1 to length of this arraylist, so if I want to make 25/75 odds of diamond and dirt Id just make [0,1,1,1], where 0 and 1 represent giving a specific item depending on that variable
Does that sound any optimal?
You know how we can change tags w/ datapacks
Changed as in modifyed by a datapack?
Cube😭
yeah, such that the api have a method to get the original tag, and the changed one’s state
You are so goofy
ah
Don’t reject me😭
Didn’t I do that like 10 messages ago?
ConcurrentModificationException isn't depend on is void .runTaskTimer or .runTaskTimerAsynchrously
Well
Conclure does his code look like it should throw a concurrent mod for modification while iterating?
I dont see the problem there.
More like 10 minutes
Only one of those runs in a different thread
I hate you now😭
The iterator should support .remove() while iterating
and what shouild i do, after all?
nothign in that code could CME, unless you insert elsewhere
Hard to tell with that little code
Does it work with all particles and is it just to write "true" after?
i can send extra code
It should
Good lol
Be aware thought that passing true is mostly a suggestion
It doesn't force the client to render it further
Was this a reply to me?
I mean. Nothing really forces the client to do anything. 🙂
It does what it wants
yes
Hey the client is forced to respond to keepAlive pings
Or it gets the boot
How does your combat.setDuration method look like?
So this should work or:
world.spawnParticle(Particle.CLOUD, location, 25, 1, 1, 1, 0.1, true);
world.spawnParticle(Particle.EXPLOSION_LARGE, location, 10, 0.5, 0.5, 0.5, 0.1, true);
world.spawnParticle(Particle.LAVA, location, 2, 0.5, 0.5, 0.5, 0.1, true);
Therefore I get null when I test
Can I just make methods and classes inside plugin java file?
You cant just randomly add classes or methods to an already compiled jar.
Your code needs to be compiled first. I mean there is a way but you should avoid that like the plague.
Did someone say ASM
In my .java file, not .jar file
Can I just make a method in here?
Or is it only for event handlers and listeners
well i think that the one right way is to add try/catch in my code
because idk what to do
You can write a method in any class. It might surprise you, but java is also used outside of spigot plugin development 🙂
100% dont do that
Do a clean compile and send the exception and your latest code pls.
Hi do someone know how to register AttributeInstance?
i tried using this code (worked in 1.16.5) but to 1.20 it got an error:
the code: AttributeInstance AttributeInstance = new AttributeInstance(attributeBase, AttributeInstance::getAttribute);
error: The type AttributeInstance does not define getAttribute(AttributeInstance) that is applicable here
Which line is CombatChecker line 14
public void run() {
Ah wait I see it
public void disable() {
player.sendMessage(TextUtils.hex(UltimateCombats.getInstance().lang().getString("combat_ended")));
bossBar.removePlayer(player);
UltimateCombats.getInstance().getCombats().remove(this); <-- CME HERE
}
Thats what i was looking for
But in the setDuration method...
To clarify this: You cant modify a collection while iterating over it
do i have to remove this line?
Since you already remove it with the iterator.remove
You should be fine to just delete that line
Unless you are calling disable from somewhere else as well
somebody help pls
Another fix would be to change
Iterator<Combat> iterator = UltimateCombats.getInstance().getCombats().iterator();
to
Iterator<Combat> iterator = List.copyOf(UltimateCombats.getInstance().getCombats()).iterator();
Lets say you have an average of 20 players on your server, then this wont cause any problems.
Copying 20 references is done in a hearbeat
I would help but the gym calls 
but what if i have 80 players average online?
Then you should hire a developer to rewrite everything as you are in the top 0.001% of all servers
And the outcome would be pretty much the same
Is 80 players really that much these days
Yeah
yep
Because there are developers better than you that can do stuff better and faster
There is always somebody better
dat is swo twue, weaw as fwick
Does that say real
ya
no one of your advicec helped me
i get this exception yet
public CombatChecker() {
new BukkitRunnable() {
@Override
public void run() {
Iterator<Combat> iterator = new HashSet<>(UltimateCombats.getInstance().getCombats()).iterator();
while (iterator.hasNext()) {
Combat combat = iterator.next();
if (combat.getDuration() != 1)
combat.setDuration(combat.getDuration() - 1);
else {
iterator.remove();
//combat.disable();
}
}
}
}.runTaskTimer(UltimateCombats.getInstance(), 0, 20);
}
guard clauses ftw
can someone help?
Don't remove while iterating or iterate a copy and remove from the original
can you help me after you free please?
with this?
yes
Is that NMS?
or where is AttributeInstance from? because it doesn't match the Spigot API
No need to be douchy
Da onwy mwagic in da bwukkit API is dat fish dwown when dey awe out of watew
Take a look at how vanilla does it
I'm in a server for modded mc and they have a mod help channel and for like 50% cases they say "take a look at how vanilla does it"
Yeah that is how you make mods
Takea look at how vanilla does things
and then use that
yub
But the other 50% or rather 15% of the time vanilla doesn't have a solution. 35% are "learn java mf"
Show the exception and your code pls
I was just asking if I can casually throw a normal method or class thats not strictly related to listeners or event handlers in plugin
How does @EventHandler, or rather, how do annotations even work
I never understood how annotations do stuff
You are essentially just writing pure java code while using spigot as a dependency.
Everything works like usual with a few exceptions:
- Your entry point is not a main() method but your JavaPlugin class
- Listener methods can be registered via annotations
Everything else is just normal java
Server-side mc client
Lots of reflection
You can access annotated elements with reflection
You register an instance of your Listener class and spigot uses reflections to scan for all methods with an EventHandler annotation.
They get put into a List and if the mc server creates an event, then it gets passed to every method in that list.
Annotations always confused me
Annotations are just a tag you can add to elements so that they can be read on runtime.
They have really no functionality outside of being readable in reflections.
*Putting aside annotation processors
Beat me to it
When making an annotation, what does all that code meam
Was seeing you writing something and just threw it in quickly 😛
Reflection
You mean like the retention policy and elements it can be applied to?
Annotating annotations do be weird tho
Do I look like I understand any of that advanced java gibberish
annotationception?
Annotations are tag or makes code shorter.
Annotations can annotate
Or longer
Useful
and static analysis hints, i.e. jetbrains annotations
And there is @FunctionalInterface as well
Not null and nullable are just decorations for future readers of code, right?
Which is just an information for the dev reading code
Right, and some IDEs use those to analyse your code and give you useful hints.
Useful hints as in "mf check for null before passing it there"?
Is this correct to set force to true for particles
world.spawnParticle(Particle.CLOUD, location, 25, 1, 1, 1, 0.1, true);
world.spawnParticle(Particle.EXPLOSION_LARGE, location, 10, 0.5, 0.5, 0.5, 0.1, true);
world.spawnParticle(Particle.LAVA, location, 2, 0.5, 0.5, 0.5, 0.1, true);
therefore I only get null.
[16:29:06 WARN]: [HubTeleport] Task #6 for HubTeleport v1.0-SNAPSHOT generated an exception
java.lang.IllegalArgumentException: data (class java.lang.Boolean) should be class java.lang.Void
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:435) ~[guava-31.1-jre.jar:?]
at org.bukkit.craftbukkit.v1_20_R1.CraftWorld.spawnParticle(CraftWorld.java:2114) ~[paper-1.20.1.jar:git-Paper-169]
at org.bukkit.craftbukkit.v1_20_R1.CraftWorld.spawnParticle(CraftWorld.java:2109) ~[paper-1.20.1.jar:git-Paper-169]
at org.bukkit.craftbukkit.v1_20_R1.CraftWorld.spawnParticle(CraftWorld.java:2098) ~[paper-1.20.1.jar:git-Paper-169]
at org.bukkit.craftbukkit.v1_20_R1.CraftWorld.spawnParticle(CraftWorld.java:2093) ~[paper-1.20.1.jar:git-Paper-169]
at wilmer.hubteleport.Utils.ActionUtils.rocket_particle(ActionUtils.java:62) ~[HubTeleport.jar:?] at wilmer.hubteleport.Action.Rocket.RocketTask.run(RocketTask.java:59) ~[HubTeleport.jar:?]
at org.bukkit.craftbukkit.v1_20_R1.scheduler.CraftTask.run(CraftTask.java:101) ~[paper-1.20.1.jar:git-Paper-169]
at org.bukkit.craftbukkit.v1_20_R1.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:480) ~[paper-1.20.1.jar:git-Paper-169]
at net.minecraft.server.MinecraftServer.tickChildren(MinecraftServer.java:1479) ~[paper-1.20.1.jar:git-Paper-169]
at net.minecraft.server.dedicated.DedicatedServer.tickChildren(DedicatedServer.java:446) ~[paper-1.20.1.jar:git-Paper-169]
at net.minecraft.server.MinecraftServer.tickServer(MinecraftServer.java:1393) ~[paper-1.20.1.jar:git-Paper-169]
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1170) ~[paper-1.20.1.jar:git-Paper-169]
at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:317) ~[paper-1.20.1.jar:git-Paper-169]
at java.lang.Thread.run(Thread.java:1623) ~[?:?]```
Particles are not entities?
So this should be right?
mhm
Thanks! 🙂
Guys, is there a method for making custom portals?
What is annotation
What makes a protal custom to you?
@EventHandler for example is an annotation. Same goes for @Override
What do they do
I mean as a hypixel example, that at the main hub there is a moon-shaped portal, can this be done with spigot bees or do we need to use nms?
Have you ever written plugins
They can be used to tag a method. You can read more about them here:
https://docs.oracle.com/javase/tutorial/java/annotations/basics.html
No idea what you mean but its probably possible with just spigot
Hm ok ok, thanks, now I'll do some research online
Thanks! I'll try that now
Yeah two
Why
Guy in tutorial just said to put it didnt explain what it does
Didnt know its called annotation as well
Well, it makes your event be an event
Basically
So from what I know, the event system in Spigot is done with reflection, which basically means that you can call code using only the names of something, e.g.
MyClass instance = new MyClass();
Method method = MyClass.getClass().getDeclaredMethod("someCoolMethod");
method.invoke(instance, parameters);
And the system that Spigot uses basically scans methods that are annotated with @EventHandler inside every registered listener (because you obviously wouldn't want to treat every function inside a class as an event, what if it's an utility or something totally unrelated).
Look up annotations in Java to learn more about their general premise
it probably loops annotations, checks the method params and then handles it
Can I check if a block is not a complete block, for example if it is a slab or a trapdoor, etc. in some simple way
Material#isOccluding will handle most of it
However some full blocks are also not occluding
Like glass
can you otherwise use solid or check solid for other blocks as well?
Just check if its a glass first then check if its occluding
isnt that unnecessary effort
I have a question about syntax, why do people provide help in such a way using # symbols?
# is used to note that it's an instance method
Material.isOccluding cound be confused as a static method
ah
so you need to do like
Material mat = idk how material is syntaxed;
and then you can do mat.isOccluding?
Material mat = Material.DIAMOND; ?
Hey, should I make it when they reload the server it loads the PlayerData onEnable or just say in red PlayerData won't load on Reload as I'm thinking to load player data on Join
Discourage people from reloading the server
Restarting it should always be the way
And if you want your plugin to be reloadable, make a command for your plugin specifically
Like /myplugin reload
And treat it as you wish
I want them to restart the server instead of reloading because I'm making a server core which provides alot of Data and player data
or even kick all the players on reload
a reload occuring can be difficult to determine. I'd say do your loading in onEnable do your saving in onDisable
the red?
ye
yes
you havent added it to git
and add a strong PSA to your plugins discription. You could also just add a message when /reload or /reload confirm is run telling the owner you aren't responsible for any data lossage as a result of reload
it means those classes aren't on git
I'm just trying to think what's the best way because I'm struggling atm with making an /ignore command because it has an hashmap that needs loading data
https://www.spigotmc.org/threads/guide-to-async-io.623371/
PS: Dont bother supporting reloads
is this normal
Wanted to post this...
Maybe it's indexing
Probably a good starting point for you:
https://www.spigotmc.org/threads/beginners-guide-to-itemstacks.623654/
Yeah generally
Yeah maybe
What
wdym what
Just saw you posting something about Materials and assumed you wanted to create ItemStacks
No
I was asking if I understood # symbol correctly
Since its present often
Hey, would it be wrong to store a hashmap inside of Value of a hashmap?
no
Its not wrong but very unclean. If you need to do that then its time to create a new class which encapsulates the inner Map.
How much data are you storing if you got a hashmap in a hashmap
I was going to store all the players ignores into a hashamp so when they join it will add the data from the PlayerData configs then I can grab that in AsyncChatEvent to make it ignore the message
Sure, do that. But create manager classes and dont let it dangle in random HashMaps
you're losing variable names which is why you don't see maps inside other maps that much
The intuitivety of the code is lost
Alright thank you
that's why mojang has a pair class
Using Pair is a sign of failure imo
Just an object with two objects in it
well, kinda useful
Write a proper class with a meaningful name for that
Map 2.0?
writing clean code's not easy
does anyone know an decent api for nicknames
or is it simpler in newer versions
all i find is 10 year old resources
they should work i think
What's the updated version of registerPacket?
no it doesn't?
Yes it does
6.5 Mb isn't that large
Anyways what is the newer version of registerPacket?
If it were to exceed a Gb then yeah, perhaps. But 6.5 Mb is peanuts
What are you loading there?
I'd more worry about the tokenizer/parser running out of memory than String length being a concern.
I mean for 6.4M chars it would have to be a pretty small server to run out of memory
Yeah, it's still a nonissue worry
was it deploy or install to get your code's API into .m2
deploy is a superset of install
lright
However deploy also pushes it to all other repos that you may or may not have
how do i put that dependency into the xml?
like i dont think i need the repo but the other part?
Where is that from?
Uh, wha?
nvm it was my own thing 😭
of course i want to use it in another plugin
Just register the dependency like any other dependency?
I am a little bit confused as you should already know that...
Dang, Eclipse logo.
Like
<dependency>
<groupId>{group}</groupId>
<artifactId>{artifact}</artifactId>
<version>{version}</version>
</dependency>
whereas those correspond to those declared in your API's pom.
Like, uh I don't know how to explain it to you
So?
with or without the trail after the numbers?
Old times for me xD
What trail after the numbers?
I'm saying <version>-dev to prevent it generating 100 different entries
<version>0.1-dev</version>
0.1-dev is your version string
You could also use [0,1) or other ranges - however 0.1 wouldn't work as it ONLY* matches 0.1
You may need provided but you could also used compile or test - depending on your needs
k
hey
what's better?
use WatchService to detect config.yml changes or
use a scheduler that periodically checks for changes
(I tried to use WatchService but I don't understand why it fires 2 times)
I listened for StandardWatchEventKinds.ENTRY_MODIFY
Generally just
the watchservice javadoc outlines this, a file modification may result in several events being fired; you'll have to deduplicate them, i.e. process only one within a given timeframe
i wish WatchService allowed to watch for file closing :/
Thank you. I took a quick look and it says it should fire once or more
It doesn't specify what "more" is and why
Got it. So I gotta code like a workaround
play with some booleans?
ints?
a fs impl may just dispatch a modify event on x bytes being written, not when the handle gets closed, hence multiple events
I know of a solution in go, never done it in java
I'll take a look thanks!

I know a little of go. had to study it in the university 🤓
I'm sorry to hear that
EMILY
It wasn't very pleasant
It has decent coroutines. And thats where my compliments end for the language.
@dry hazel never
I know you are secretly a rust fan
your knowledge is deeply flawed
😴
VHDL isnt really programming. (Same goes for Verilog if you are american)
it is beyond
Should I use Float#floatToIntBits or Float#floatToRawIntBits? What is the difference outside of different handling of NaN values, if any? Is one method faster?
I'm using them for a #hashcode method btw
You could try a benchmark
if i do .add(0, "afawga"); in a stringlist will that remove the previous 1st string or will it just move everything up a int
I'll go with floatToRawIntBits then as the non-intrinsic impl uses it either way
insert and shift everything else
int i = 0;
for(SkyBlockMaterial material : farmingMaterials.keySet())
{
int actualSlot = FarmingHelper.slots[i];
menu.getSlot(actualSlot).setItemTemplate(p -> {
ItemBuilder farmingMaterial = new ItemBuilder(material.getItemStack());
farmingMaterial.setName("§a" + material.getName() + " "+ CollectionHelper.getCurrentTier(p, material));
farmingMaterial.setLore(CollectionHelper.generateLore(material, p));
p.getInventory().addItem(farmingMaterial.toItemStack());
LoggerModule.getInstance().log(actualSlot + " " + material.name());
return farmingMaterial.toItemStack();
});
LoggerModule.getInstance().log(actualSlot + " " + material.name());
i++;
}
Why are some slots not showing up?
Looks to me like everything is showing up?
What do you expect to be different?
the three missing items
private static LinkedHashMap<SkyBlockMaterial, GUIMenu> farmingMaterials = new LinkedHashMap<>()
{{
put(SkyBlockMaterial.Farming_Wheat, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Seeds, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Cactus, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Cocoa_Beans, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Carrot, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Melon, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Mushroom, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Nether_Wart, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Potato, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Pumpkin, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Sugar_Cane, new PlaceHolderPage());
}};
I learnt basic syntax, OOP, polymorphism, inheritance, arrays and arraylists (yeah I can tell them apart lol), what else could I learn that would help me in plugin development out of java basics?
Print out their vanilla type and make sure its an item that can actually be shown as an ItemStack
just make projects now you can probably learn everything else as you go
Maps. And then just write a bunch of code.
I was thinking about trying to utilize databases right now
Concurrency, I/O
sounds like a good plan just get started with SQLIte
i switched the order of the list
private static LinkedHashMap<SkyBlockMaterial, GUIMenu> farmingMaterials = new LinkedHashMap<>()
{{
put(SkyBlockMaterial.Farming_Cocoa_Beans, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Carrot, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Melon, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Mushroom, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Nether_Wart, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Potato, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Pumpkin, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Sugar_Cane, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Wheat, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Seeds, new PlaceHolderPage());
put(SkyBlockMaterial.Farming_Cactus, new PlaceHolderPage());
}};
``` now three other slots arent showing
public class FarmingHelper
{
public static int[] slots = {10, 11, 12, 13, 14, 15, 16, 19, 20, 21, 22, 23, 24, 25, 28, 29, 30 ,31, 32, 33, 34, 37, 38, 39, 40, 41, 42, 43};
}
I am using the Canvas GUI
https://github.com/IPVP-MC/canvas
Canvas is a java library built for Bukkit to manage custom inventory based menus - GitHub - IPVP-MC/canvas: Canvas is a java library built for Bukkit to manage custom inventory based menus
does anybody know how to stop arrows from pushing buttons?
they essentially are the same, the difference is as you mentioned. One doesn't change the bits because of NaN the other will
how does Hypixel do their enemies that look and behave like players?
if you don't expect NaN or there isn't a possibility of it, then go with the normal one
otherwise use the raw
such as goblins in mines
Shouldn't it be the reverse?
ig u can use this https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/event/entity/EntityInteractEvent.html
declaration: package: org.bukkit.event.entity, class: EntityInteractEvent
but if you look in the source code for this method, literally there is almost no difference except the return
omg ty
I'll check it out
Yeah, though you can never be sure with intrinsic method - but I'd guess I am being a little bit too suspicius
lol
if only NaN had a standard
in what it was supposed to be
s111 1111 1a00 0000 0000 0000 0000 0000 NaN (this is the proper way according to IEEE 754)
0111 1111 1100 0000 0000 0000 0000 0000 FloatToIntBits NaN
Hi, I was just wondering, is there any way, to send player like packet with fake info about his position, so any client side mod would show this fake position? Or something like that?
sending such a packet would also show the player physically at that fake position as well. And then you will start encountering issues when they start moving, where the client realizes that isn't their real position tells the server or vice versa so you will get a lot of teleporting issues with it lol
ultimately will either result in crashing the players client or kicking them from the server
not sure if there is some other thing you can do except hide the player from the others
until they are in view
in doing this, the server will keep track of the players movements but won't send such info to the players they are hidden from
do any of you know how to make TextDisplay background transparent? 😮
I would just... set the background color with an alpha of 0
How do I do it? 😅
This is a bit freestyled
TextDisplay display = ...;
Color color = Color.fromARGB(0, 0, 0, 0);
display.setBackgroundColor(color);
Its deprecated because its still draft API
Thank you 🫶
@EventHandler
public void OnPlayerJoinGame(PlayerJoinEvent event) {
World world = player.getWorld();
Bukkit.broadcastMessage(String.valueOf(world.getPlayers().size()));
if (world.getPlayers().size() == 1) {
//THIS PART
}
}```
Why this gets called only 1/3 of the time
the if statement
the 1/3 chance is choosen when server reloads or restarts
I want to check if the player is the first person to join the world
<= 1
doesnt work
Why do you check the amount of players in a world instead of the whole server?
because the world is the only world in the server
Then check using the player count server wide
ok I will try it
still doesnt work 1/3 of the time
I have multiverse installed
does that cause issues?
What do you mean it doesnt work 1/3 of the time? Is that an exaggeration or an actual measurement?
Ok let me replicate this real quick
I have been trying to fix it for 3h
@EventHandler
public void onJoin(PlayerJoinEvent event) {
int playersOnline = Bukkit.getOnlinePlayers().size();
if (playersOnline == 1) {
System.out.println("First player joined");
}
}
Ok so this worked 100% of the time for me so far.
Send your full code again pls
@EventHandler
public void OnPlayerJoinGame(PlayerJoinEvent event) {
World world = player.getWorld();
Bukkit.broadcastMessage(String.valueOf(world.getPlayers().size()));
if (world.getPlayers().size() == 1) {
//THIS PART
}
}```
I will tell you more about my code
this is in abstract class
and another plugin that uses this plugin as a dependency
You are still not testing against all online players
I didnt want to show my actual code because its messy
@EventHandler
public void OnPlayerJoinGame(PlayerJoinEvent event) {
Player player = event.getPlayer();
World world = player.getWorld();
if (!world.getName().equals(name)) {
return;
}
Bukkit.broadcastMessage(String.valueOf(world.getPlayers().size()));
if (Bukkit.getOnlinePlayers().size() == 1) {
this.world = world;
points = new Points(player.getWorld().getPlayers(), maxPlayers);
//StartGame();
WaitForPlayers();
/*
if (!devMode){
StartCountDown();
} else {
GameStart();
}
*/
}
points.addPlayer(player);
player.sendTitle("Waiting for players", "", 10, 100, 10);
player.setLevel(gameLength);
player.setExp(1f);
/*
player.getInventory().setItemInOffHand(gps);
points.addPlayer(player);
*/
}```
here it is
Add a sysout in your if clause and check if its called
WaitForPlayers() does a thing that is noticible
how can we help someone without them showing their code
Add a sysout in your if clause and check if its called
Yeah, i suspected that
the way I checked before is I make a task output something
so its still something with tasks
urgh
I was trying to fix my tasks and then I tought its still in the if statement
I will go back to fixing my tasks
Hi, I am having an issue with my command, it is both in the plugin.yml (below) and registered in the onEnable() (also below) method, however, when I run the command in game I am simply given the usage instructions from the plugin.yml. The command previously worked but perhaps I have changed something that has broken it, any ideas would be appreciated. I have verified the onCommand method in ClaimListener is not called using a breakpoint and jdwp
plugin.yml
name: conceptc-claiming
version: "1.0-SNAPSHOT"
author: Dinoosawruss
main: com.github.dinoosawruss.ConceptCClaiming
api-version: '1.20'
depend: [conceptc-core]
commands:
claim:
description: Commands used to control claims
usage: /<command> <trust|untrust|info> [args]
ignoreclaims:
description: Admin command to ignore any claims
usage: /ignoreclaims
permission: conceptc.admin.ignoreclaims
onEnable() method
@Override
public void onEnable() {
logger = getLogger();
dbUtils = getPlugin(ConceptCCore.class).getDbUtils();
logger.log(Level.INFO, "{0}.onEnable()", this.getClass().getName());
this.getServer().getPluginManager().registerEvents(new BlockListener(), this);
this.getServer().getPluginManager().registerEvents(new ClaimBlockInteractListener(), this);
this.getServer().getPluginManager().registerEvents(new ViolationEventListener(), this);
this.getCommand("claim").setExecutor(new ClaimListener());
this.getCommand("ignoreclaims").setExecutor(new IgnoreClaims());
}
Neither the claim or ignoreclaims commands work and both just give the usage information in response when run in-game
^
everyone do a posture check
onCommand is not being called when the command is run
Although onCommand in this case would only return false when a message is also issued to the player which is also not happening
ur welcome
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
ConceptCClaiming.logger.info("Reached");
if (sender instanceof Player) {
Player player = (Player) sender;
if (args.length == 0) {
player.sendMessage("Insufficient args");
return false;
}
switch(args[0]) {
case "trust":
new ClaimTrust(player, args);
break;
case "untrust":
new ClaimUntrust(player, args);
break;
case "info":
new ClaimInfo(player);
break;
default:
player.sendMessage("Unknown argument");
return false;
}
}
return true;
}
"Reached" is never issued in the log when run - I have also verified with jdwp that the onCommand method is not being run
case "default": lmao
There’s a Player#getAddress
^
And then you can get the GeoLocation from his IP
Just download the GeoLite2 database. Its not too big i think.
23.10 21:04:50 [Server] [INFO] Dinoosawruss issued server command: /claim trust conceptc is the only log line given when the command is executed
And the very first line is not called? Then this is not the class you set as an executor. Double check if "ClaimListener" is really what you want there.
The GeoIP2 api reads this file in with their reider. Cant quite remember how it went.
Let me just check real quick
It is definitely ClaimListener
package com.github.dinoosawruss.commands.listeners;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import com.github.dinoosawruss.ConceptCClaiming;
import com.github.dinoosawruss.commands.executors.ClaimInfo;
import com.github.dinoosawruss.commands.executors.ClaimTrust;
import com.github.dinoosawruss.commands.executors.ClaimUntrust;
public class ClaimListener implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
ConceptCClaiming.logger.info("Reached");
if (sender instanceof Player) {
Player player = (Player) sender;
if (args.length == 0) {
player.sendMessage("Insufficient args");
return false;
}
switch(args[0]) {
case "trust":
new ClaimTrust(player, args);
break;
case "untrust":
new ClaimUntrust(player, args);
break;
case "info":
new ClaimInfo(player);
break;
default:
player.sendMessage("Unknown argument");
return false;
}
}
return true;
}
}
Imported to main class via import com.github.dinoosawruss.commands.listeners.ClaimListener;
jdwp shows ClaimListener being initialised as expected also
String ip = "your-ip-address";
String dbLocation = "your-path-to-mmdb";
File database = new File(dbLocation);
DatabaseReader dbReader = new DatabaseReader.Builder(database).build();
InetAddress ipAddress = InetAddress.getByName(ip);
CityResponse response = dbReader.city(ipAddress);
String countryName = response.getCountry().getName();
String cityName = response.getCity().getName();
String postal = response.getPostal().getCode();
String state = response.getLeastSpecificSubdivision().getName();
I would also reuse the DatabaseReader
Feeling a bit stalky today, are we?
You could probably scrap GeoIP then and query an external provider for that information
why not try something like sender.sendMessage?
is using database an optimal way to store information about player? as in lets say that on player join I would assign them in database base custom statstics such as attack, crit chance etc. and do it only once after they join to add them to database
Yeah that’s fine
You can also store data in their pdc
Advantage of a database is querying and all that fancy relational stuff
Also pdc isn’t available if they are offline
this is weird to ask when you consider something like google uses a database and obviously efficient
Files are fine, Databases as well. Just make sure to do it async
you know I never wondered how such things work
they just use a different kind of DB that suits their needs
that is really the only thing to consider
is the DB that suits what you need it for
Probably a paid one.
whats the difference in storing things in files or databases?
There are quite a few differences. When it comes to pure persistence, then Files and Databases are pretty equal until you reach a
bigger number of entries. The file system can be slower if it has to deal with thousands of files while Databases are optimized to
search for properties and even more optimized for primary keys and indices.
The file system also does not support queries. For example: "Collect all players with more than 100 kills"
Databases have the drawback of added complexity as they often come with their own API and SQL even
with its own turing complete language that needs to be learned first.
So if you are explicitly looking for only persisting data, then Files can be a very viable tool.
hm, so database management will be long term appreciated
especially could be extra useful on my programming classes
I want to universalize a few things in my server
such as adding custom enemies, lootboxes, statistics and such
Then write against interfaces. This lets you swap out different implementations whenever you want, without breaking your code.
But this is quite the task because designing for abstraction can be complicated.
could you provide any kind of information about "writing against interface"?
I dont really catch it
Yes, already writing an example
[Part I]
Given the interface
public interface PlayerDataAccess {
PlayerData load(UUID playerId);
void save(PlayerData data);
}
You can already write against this interface, without knowing how the implementation looks like.
You just define the input and output of your methods and trust that the impl will achieve what you expect:
public class PlayerListener implements Listener {
private final PlayerDataAccess access;
public PlayerListener(PlayerDataAccess access) {
this.access = access;
}
@EventHandler
public void onJoin(PlayerJoinEvent event) {
PlayerData data = this.access.load(event.getPlayer().getUniqueId());
}
}
[Part II]
Now if you want an impl which saves your data to Files, you simply implement this interface in a concrete class:
public class PlayerFileAccess implements PlayerDataAccess {
private final JavaPlugin plugin;
@Override
public PlayerData load(UUID playerId) {
File playerFile = new File(plugin.getDataFolder(), playerId.toString() + ".yml");
// Some loading from file
PlayerData data = ...;
return data;
}
@Override
public void save(PlayerData data) {
UUID playerId = data.getPlayerId();
File playerFile = new File(plugin.getDataFolder(), playerId.toString() + ".yml");
// Some saving to file
}
}
This impl can be used when creating an instance of the Listener:
@Override
public void onEnable() {
PlayerDataAccess access = new PlayerFileAccess();
PlayerListener listener = new PlayerListener(access);
Bukkit.getPluginManager().registerEvents(listener, this);
}
[Part III]
If you want to change your impl at any point later in time, you can simply write a completely different impl which uses a DB for example:
public class PlayerDBAccess implements PlayerDataAccess {
@Override
public PlayerData load(UUID playerId) {
Connection connection = DriverManager.getConnection(...);
PreparedStatement statement = connection.prepareStatement(...);
// Load PlayerData from DB
PlayerData data = ...;
return data;
}
@Override
public void save(PlayerData data) {
Connection connection = DriverManager.getConnection(...);
PreparedStatement statement = connection.prepareStatement(...);
// Save PlayerData to DB
}
}
And then change the impl you provide:
@Override
public void onEnable() {
PlayerDataAccess access = new PlayerDBAccess(); // This is now another impl
PlayerListener listener = new PlayerListener(access);
Bukkit.getPluginManager().registerEvents(listener, this);
}
The listener doesnt care what class he gets, as long as it implements PlayerDataAccess.
This makes it easy to swap out different implementations without changing anything in your code.
All you need to do is change this single line:
PlayerDataAccess access = new SomeCoolImpl();
A lot of big words. Not sure if it makes interfaces clear...
It is really important to actually write something like this for yourself and test it out. Otherwise the whole concept is quite abstract.
idk I feel like databases would be better
Well, you could just use an interface as a placeholder for now.
But if you think that learning Databases right away doesnt mess with the learning curve of your primary code then go for it.
Usually i ask for a justification from the person who decides to use a Database. Do you really need it, and what is your argument for using it.
thats the first type of data storing system that came to my mind, I want to store several values and their attributes which seems to be easily doable with MySQL's primary keys
do you have any resources about SQL database management in spigot?
cuz in Kody's video its more of a showcase rather than tutorial, basically saying "here you can do this and that" without any in depth explanation
guy just said "okay we gonna make constructor, getter and setter here and there" without any context
😭
?paste
https://paste.md-5.net/yumapaxanu.java im having trouble in like 24 for some reason it doesnt add it to the titles
but
printing it out works just fine
it just stops after that line
how do i play custom sounds from a resource pack from my plugin?
this is my code currently, the lines 340 to 346 are meant to play the sound https://paste.md-5.net/uresixaxat.cs
What's your config look like?
already fixxed it
https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/entity/Player.html#playSound(org.bukkit.entity.Entity,java.lang.String,float,float) insert the name of the sound
declaration: package: org.bukkit.entity, interface: Player
What's your resource pack structure look like?
probably because it's an immutable list
as in Collections.EMPTY_LIST type deal
also mutable lists are.. mutable
i cant add stuff to an empty list?
i dont want to work on a copy
i want to change one value then put it back into the database
so don't call setUnlocked
even then, you shouldn't expose mutable collections
I'd make an addUnlocked method on the TitleData class
Your main problem is how you're initializing the list
List.of() and Collections.EMPTY_LIST return an immutable list
so i cant edit it cause its empty?
because it's immutable
and its immutable cause its empty?
No
why then
They're meant to always be empty by design so adding elements would never be a good idea
you can have a non empty list that is immutable
think of immutable as a final but for elements in a collection
okay well how else should i do it then
I'd make the getters always expose immutable lists and just making methods to add data to the class itself
/**
* The TitleData class represents data belonging to a {@link Title}.
* @author Illusion
*/
public class TitleData { // TODO: Make this an interface, enterprisify the entire code structure
private final List<Whatever> list = ...; // Make sure you don't use List.of or whatever, but rather initialize a list object with the "new" keyword
/**
* Returns an immutable copy of the backing list
* @return an unmodifiable list.
*/
public List<Whatever> getMyList() {
return List.copyOf(list);
}
/**
* Adds an element to the internal list.
* @param whatever - The element to add to the internal list
*/
public void addWhateverToList(Whatever whatever) {
this.list.add(whatever);
}
}
You have full control over what gets added to your list because you never expose it directly
Should probably also add a comment about it returning a immutable copy. For the documentation and what not. :3
fuck you
gay moment
Wdym by handle data
scroll up
there you go
well, I mean you are allowed to do whatever with it 🙂
Lost.copyOf :woeisme:
done in discord so fuck indentation
fuck you, next
ly2
yh but everyone always complains about how i dont do stuff "the way its supposed to be done"
What does yh mean?
yeah
yeah
Seriously?
yeah
yeah
I mean ideally you should abide by conventions
ight
Ah yeah, there is proper ways, but I think it is probably important to learn to get it working then to worry about the variety of ways it could be done
Anyone know how to get started with server sharding?
Especially when it comes yo editing data
"what does idk mean"
tbh I did spent like 2 years of my life trying all kinds of different wacky ass ways before just sitting down for 5 minutes to learn about mutability, oop and data structures
i did i just read edging data 3 times before understandint it
Lol
now all of my code looks unreadable unless you have exact context of what you're looking at
because it's all just interfaces and generics
I feel that
just grab betonquest's codebase, pull up a random class and tell me what it does
Do you have any knowledge in networking?
you will basically have to create a whole new implementation unless you are trying to do this concept without doing so
and want like.. general tips
in which case good luck because there is no easy way to do that
Edging your data 🫢
🤔
A little bit
Yeah so you know about packets and stuff
Getting into it
I was thinking about forking multipaper
sharding works under the principle of there being a master server and many slave servers. Difference here is that if a slave goes down, the whole system doesn't go down just whatever that slave controlled. If slave doesn't come back you either just ignore whatever it had for the time being or you move the work from it to the rest of the shards
I'd rather do meshing where there's no master server and all the slaves gaslight each other
lol
How does server meshing work
or well, your "master" database is more of a redis cluster
Let's start with a basic player count plugin
Where you have, for example, a messaging queue of some sort (Redis pubsub for example, let's skip its caching functionality for now just to make it a little harder)
And each server you have, has an internal id, for example
how do i clear my database
Drop it. lmao
You can have, for example, a Map<UUID, Integer> playerCounts
Where the uuid is the server id and the int is the player count for that server
just be careful to not drop the table or db
unless you just want everything to be gone
drop database "dbname";
Now the idea is to have it so every single server has the map synchronized, so let's also add a long lastUpdateMS
When the server starts, ask "the network" for the latest data, which can just involve every single server sending its data and last update ms and we just filter it all
When a player joins, you add 1 to your own id, update your lastUpdateMS and send a packet to "the network" indicating new data
When a player leaves, you remove 1 etc
And when your server stops, you try to tell everyone to remove your data
Now, what if the server crashes? You can implement a heartbeat system where if I don't hear from you in ~5 seconds I just assume you collapsed and died
This is a bit too advanced for my coding skills, this is out of my league
Developing a sharding/meshing system
If this is advanced then multipaper is hell
But yeah you also want to make sure that every single server like
only contains its own data and minimizes the amount of data it knows about everyone else
Otherwise as you scale in server count, every instance gets more and more bloated
Yea. So what should I do in the predictable future
No clue what you're trying to do
Trying to figure out how to cram as many players onto a world as possible
multipaper is a start
didn't mrbeast's minecraft team make a plugin where you saw holograms of other players on clone servers?
that needs a ton of packet magic
I don't know
would you do this to sync ping?
Mr Beast can hire like the best networking professionals on the planet