#help-development
1 messages · Page 952 of 1
does it exist on bedrock too?
that would be pretty okay I guess
since I could just link all the necessary information to an ID in json file
do I want to make separate class and method for creating inventory GUI as a template?
Don’t think so
Silverfish block projectiles tho so
such as parameters as dimensions and what blocks are supposed to be what
i guess i need to use packets 😔
Have fun making an entirely packet side entity
i alr made that, i wanted to switch to the api and it doesnt work i guess
getting weird jetty errors
so it seems like it even does that even tho the entity know each other, just the viewer (player) doesnt know 1 of them
?
i set a different enttiy as the silverfish passenger
and then hide the silverfish
and same behaviour
do you have experience with coding plugins?
or r u looking for a plugin taht does that for you?
Aww man how am I gonna slay mobs then
Gotta annihilate mobs instead
Looking for something that I can make minimal adjustments to in order for it to work
Not wanting to put a lot of effort in I just want duct tape solution
😐
I have cmi and griefprevention on the server already but it doesn’t look like I can do what I want with those
So u want a plugin that will ban a specific player when they say a specific word
I think he wants to prevent some players from typing that word
Basically a permission based word blacklist
Unless he doesn't have a permission plugin
Can I turn off the Q button? Throwing out so that there is no animation
Listen to the drop item event probably, then cancel it and remove the item
There remains an animation that he wants to throw away
You can't remove that
It's client sided
Listen to the player chat event, iterate the message for any word from your list and cancel said event
Oh if you want a permission to bypass, just do so with a simple if p.hasPermission and dont cancel the event
Might be best to use a Trie or HashSet and use string tokenization
Probably so, but that’s the simplest way
You might also want to consider alternative spellings etc for your blacklisted words
its just to prevent one person from saying slay and i want it to be perpetual
A single person?
yes
Then don’t check against a permission
what do you mean?
If !p.hasPermission(xyz) return;
If event.getMessage.contains(blacklistedWord) or something like that
Then if the only person you want to block said word for, just give them that permission
So now anytime they chat and their message contains the blacklisted word, that chat event will be cancelled
ohhh okay
It’s also a good note that anyone with that permission will have their message blocked given it contains the blacklisted word, ie: server operators
(Ops) for short
So it might actually be better to see if they don’t have the permission, but that means everyone whom you don’t want to be blocked will need that permission
Is it possible to link a blacklisted word to a luckperms group and just give it to him?
Yeah probably, I haven't really messed with lp's api tho
I'm trying to make a sign editor pop up on the player's screen. I was wondering if my approach is correct, or what I should change to improve my approach
- use buildtools to get a remapped jar and find the name of the packet
- use NBT API and get that packet and give it the position of the sign i need to edit.
- as I don't want an actual sign, I can instead send a block update packet (?) and make that "block" my editable sign
- get the player handler, to get the player connection (i can find out the name of this as well using the mapped jar)
- send the packet to the player (idk if I need to delete that placed block packet)
- use an event to check the sign's content when the done button is pressed.
Never done this before so, again, hoping someone can correct me if my approach is wrong.
How does Bukkit.getScheduler().runTaskLater(() -> {}, 69L) work?
How does it wait time
Ticks
Basically there's the "main loop"
That loop basically says "A perfect tick lasts, at most, 50ms" (1s / 20 ticks per second)
So it starts processing the tick, gets how long it took
Let's say it took 15ms to process
And waits the 50 - 15ms
So 35
Then it ticks everything again
And waits again
The scheduler keeps track of what tick it's on and has a task queue to process
"In 5 ticks I have to run task 123 once"
Once the 5 ticks are up it just runs it
I just looked into the source for you. They set a fixed timestamp on the CraftTask and put it in a PriorityQueue.
Eg the current tick is 5000 and you scheduled it for 40 ticks in the future, then it gets a timestamp of 5040.
They then poll from the top of the priority queue until all tasks for the current tick are executed.
So if we currently have the time of 5005 and the queue contains:
- 5005
- 5005
- 5007
- 5010
- 5020
Then it will poll the first two tasks and stop looking at the rest because the tasks inside the Queue are ordered ascending by their execution time.
Meaning if you hit one task that is not due, then you dont need to check any more tasks, as they are all scheduled for the future.
This is another reason why you shouldnt constantly start/stop tasks but have a single task and add elements to it.
Adding/Removing tasks is O(log(n)) at best (without collisions).
so i've been doing this optimally a long time ago?
but a thing still has me questioning
if you poll a repeating task, don't you have to reschedule it?
putting it back to log n?
Unless it is scheduled every tick, in which case you can just put it on top of the queue
But true, rescheduling takes O(log(n)) at best again
oh mine is every tick
Hm. Shouldnt we have access to this? Looks to me like a decent alternative to System.currentTimeMillis() if we can just measure a time
in terms of ticks.
It counts up every tick. This is essentially how long the server has been running in ticks.
for some reason int seemed much smaller in my mind
it'll take a long time to wrap around
So I have this problem: I'm doing a pvp plugin that has healing based on damage done to a killed player. My Problem is that I have this custom ability that casts lightning to a player. I need to somehow get the caster's UUID to my plugin's main to add it to calculations. I cant seem to get out but only the target's UUID and the CraftLightningStrike's UUID. Any ideas?
LightningStrike is an entity. You can just add the casters UUID in his PersistentDataContainer.
*And then get it back when the lightning damages someone
Alternatively you can also just use a Map<UUID, UUID> to map lightning IDs to their caster IDs
well.. you want to see it for a bit, no ?
It has always been an entity as far as I know
It interacts with the world tho
changes entities into different entities
I think my problem is accessing the data between main class and the LightningStrikeAbility class :D I always mess up the basic things after coding too much in a row
but so is an explosion
so setting a display entity, it seems to rotate around the point from where its original point is instead of the y-offset point. is there a way to make it rotate around its y-offset point instead of its original point
But if not entity, then particle ?
it's not like it matters, i just find it weird that's all
The same way primed tnt and area effect clouds are entities
They live in the world, for a certain amount of time
It only makes sense to make them an entity
Hey, I am making a plugin where you can set your own prefix, but it doesn't show in the Tablist nor the NameTag nor when you type sth in the chat.
https://hastebin.skyra.pw/bexabedelu.csharp
you'll have to use Team from scoreboard
What do you mean by that?
As my scoreboard I have private static Scoreboard scoreboard = Bukkit.getScoreboardManager().getNewScoreboard();
do you mean scoreboard.createNewTeam()?
yes
that doesn't seem to exist...
use player setscoreboard scoreboard
Hello! I want to create a plugin that, on command, starts dropping yellow concrete blocks every 10 ticks. I have made dropitemnaturally, and I need to drop blocks exactly from the player's legs, but they drop somewhere left from the player.
final Item item = player.getWorld().dropItemNaturally(player.getLocation(), new ItemStack(Material.YELLOW_CONCRETE));
item.setVelocity(player.getLocation().getDirection());
item.setGravity(true);
item.setPickupDelay(1000);
It still didn't work
https://hastebin.skyra.pw/hosixejodi.csharp
Well it is something like this: &6[&3Hey&6]
item.setVelocity(player.getLocation().getDirection());
->
item.setVelocity(player.getEyeLocation().getDirection());
And the characters in the brackets are custom
Yeah I have made another plugin to manage the Tablist
alright, I'll try that!
If I want to contribute to Spigot, which of these do I fork?
Depends.
API visible methods are added into Bukkit
Implementations of those methods are added into CraftBukkit
Changes to the server implementation are added into Spigot
Download buildtools cli to setup the workflow
And then you can easily make changes from there
Thats if it still works the way it did a few years ago
I see now it just gives you a jar with the gui version
:/
Usually for PRs your would fork Bukkit and CraftBukkit and reference the correlating changes in each other.
I shouldnt dox myself...
Hey @lost matrix, you recommended using Timestamps for timing functionality. Were you referring to java.sql.Timestamp or something else?
Just a long ususally
I forked the Spigot repository but when I run ./applyPatches.sh it is not happy because this script refers to something outside of this directory
So I assumed it is not a root project
did you run it in git bash
Sure?
Run BuildTools for the latest version. This makes sure you have everythin needed in your local maven repo.
It tries to do something in ../Bukkit which doesnt exist in my working enviroment
Ah you need to reference some files
You didnt reccursively clone the submodules
One moment
Lol
Or
Wait nvm why is it one level lower

It used to be all in the same directory…
Does it want my to fork all of these repos?
Spigot progressively becoming more aids to contribute to speedrun
I mean, I've considered that
But
How do I push it to my fork and then do PR?
If I understand correctly, the cloned repo which BuildTools creates is connected to the main repo
aka https://hub.spigotmc.org/stash/scm/spigot/*.git
Yeah just add/update remote
Non flickering darkness effect? Does someone know if it's possible?
Either tell the user to change an Accessibility setting, or force a RP that edits a shader.
Those are the two things that come to my mind
I may be wrong, but I think you need to modify protocol packages for that
So it's impossible with packets?
I'm trying to make a horror game. It pisses me off this game isn't giving dev much space to work with
For example roblox does
Oh, no
ok.. But how would I do that? do you have like a tutorial or so?
oh, so just use the scoreboard api and with that, modify the name tag?
don't see how packets could help in any way
You could try to see if the flickering is somehow tied to the remaining time, then just set the effect time to a specific value every tick
Would be wonky tho
And again, you can probably use RP to change it, this game is customizable as fuck.
And it's only getting better week by week
Okay, so now I just fork these repos in the stash and change these local repos remotes to my

Hm, okay, easier than I though, but I cannot imagine how people figure that out on their own
Yea its a bit non trivial, i think there is a wiki page on it tho ^^
If I use an advanced loop, can I start at a different index instead of 0?
Basically: i want to paginate my onlinePlayersGUI.
The first page is supposed to have player 0-35, the second 36-71 and so on. I could somehow do it with a simple loop but Idk how I'll get from Collection<? extends Player to a Player[]-Array
Not that hard to convert it
I know, but I tried and failed
Cast to list and just get by index
Player[] players = onlinePlayers.toArray(new Player[onlinePlayers.size()]);
Would that be a way as well?
Give it a try it might complain about casting
So what exactly are you having troublr with pagination?
Should be pretty straight forward
It contains about Call to 'toArray()' with pre-sized array argument 'new Player[onlinePlayers.size()]'
complains*
LOL
Well, the second page should not have player 0-35 again but player 36-71
and for looping through the online players I need to change the starting index somehow
Tf is an advanced loop lol
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {}
A foreach loop?
yeah call it want you want, lol
You can easily convert that to use index
nvm not advanced. it's called enhanced for loop
that's what i'm trying to do with the List<> now
List<Player> players = new ArrayList<>();
for (Player onlinePlayer : Bukkit.getOnlinePlayers()) {
players.add(onlinePlayer);
} isnt that basicly what youre looking for?
List<player> blah blah blah
for(int i = n * 35; i < (n+1)*35; i ++)
yeah that's essentially what i did now
List<? extends Player> onlinePlayers = Bukkit.getOnlinePlayers().stream().toList();
Hello! I have created a plugin that on command /spit, make from player's head llama spit but It damage other players. How can I cancel damage on spit?
Youll have to listen to EntityDamage event and cancel it if the damage source is a spit projectile
thanks
Hey fellas! How do you make it so that you can Right click globally. I've used PIE up until this point, but that doesnt work when in close proximity to entities. Could anyone help me pls?
Wdym by globally?
Welp, when rightclicking air, blocks and/or entities
basically merging PIE and PIEE into one
PlayerInteractEvent is the parent event, yes.
tbh i also needed some time until i got that
So this would fire?
public void onPlayerInteractEvent(PlayerInteractEvent event) {
if(event.getAction() == Action.RIGHT_CLICK_AIR || event.getAction() == Action.RIGHT_CLICK_BLOCK) {
It should, yeah
ItemsAdder entities
that was the issue
thanks! now gotta figure out how will that work
Idk exactly how itemsadder works but pretry sure it’s clientside entities, if thats the case youll need a packet listener
if(e.getCause() == EntityDamageEvent.DamageCause.PROJECTILE) how can i set projectile llama spit here?
I took a quick look and it seems that the ProjectileHitEvent is the correct event
You can use either
anyone knows a plugin for commpressed items
1.20
sry
okay tbh i have no idea rn how you check exactly for the llama spit, i can't find it, lol
public void OnHurt(ProjectileHitEvent e) {
if (e.getEntity()instanceof LlamaSpit) {
LivingEntity entity = (LivingEntity)e.getHitEntity();
if (e.getEntity().getShooter() instanceof Player) {
I have made something like this but how can i cancel damage?
Can anyone tell me if I need to execute this line? I believe that bukkit saves all schedulers and I believe that I need to execute this line so that the list has fewer objects and frees up memory
mhhhhhhh paragraph symbols (idk sadly, sorry)
Heyo, I would love some feedback for this:
I want to implement a custom weapons system using an entity component system to have a versatile and customisable system.
It would have two parts:
Abilities/Data: This is the data it will display when a component is applied. Something like lore or a display name.
Effect: The actual effect that will be triggered via an event.
Following issue(s) arise:
How do I handle events?
Do I have a listener in every effect which checks for events?
Do I have an external system that parses events to effects (sounds annoying)?
Other options?
will probably give you a NPE
Or some other exception about it already being canceled
^^
the most of methods in a task throw a exception if is not started
NPE?
NullPointerException
well, the task id might be come null once it's cancelled
i'm not sure since i don't have a copy of the bukkit src atm
task id is integer
integer not can be null
can still be null
wtf?
I want to schedule some tasks. Is it a better idea to use the Bukkit scheduler or a java.util.Timer? Im guessing that Bukkit is based off of ticks rather than actual time, so I think using a Timer is probably a better bet. Is that right?
is a int
bukkit
Depends on what you wanna do but mostly bukkit
Alright. Im scheduling tasks like a countdown to the start of a game
Would you mind elaborating as to why?
use bukkit then
You probably want to use bukkit then
oh you were responding to me XD
i like your profile picture lol
Can anyone tell me if I need to execute this line? I believe that bukkit saves all schedulers and I believe that I need to execute this line so that the list has fewer objects and frees up memory
LOL
?»????
probably throw an exception*
i do, in fact, know java
resume.. you already cancel the task not need call again that... is like call cancel two times.
If the server lags and performs for example at 9 tps, but your task is running with java timer and is bosically at 20 tps, it's going to outrun the server. Not the best example i could provide but basically for smoother gameplay you want to sync your plugin with server time quote unquote
.
^
what the fuck is this convo
I appreciate the response :D.
Don't use java timers in the context of bukkit
so how gettaskid will returns null if is a integer?
Two different convos, both about scheduling
You can use executor services if you're doing your own thing outside
...
You cancel the task twice
i literally said it might be a possibility
i don't have the implementation in front of me atm
Im making a Timer class that will begin scheduling checks upon creation so I can make one for anything tha tneeds to schedule, like a Game object
"Frees up memory" is not the perfect term but it's still good practice to cancel stale tasks in order to not cause weird exponential issues
Is that a good idea?
So you're making your own scheduler
uh
but task.cancel doesn't fully free up the memory, but damn it
Or is it just tracking scheduled tasks so you can cancel them all at once?
but task.cancel doesn't fully free up the memory, but damn it
Do you even know what you're talking about?
no need to say the same thing twice
task.cancel and Scheduler#cancelTask do the same thing
which is actually wrong lol
yes
You know what? I just realized I might not need to.
I'm scheduling multiple tasks like countdowns for starting games.
no no
yes
but the two methods are the same...
the task.cancel already call the Bukkit.getScheduler().cancelTask its like i said yyou call the cancel two times
Oh thank you
I didn't see that part, forget it
Thisll take a bit for me to wrap my head around
yes, im sorry
thx

The repo's basically a whole minigame engine
no need to get rude though
Figured it might help your case
I see
Thank you
Im slowly building up my understanding of different topics as I go along building this
The first time I built it, it was a mess
So would you say you made your own scheduler?
Not really, no
Oh
The GameTask interface just wraps "a task"
oh right
Then I have a bunch of impls that delegate to the bukkit scheduler
i'm guessing they're just extending a bukkittask/bukkitrunnable
I do keep references of every task that's ever been scheduled
So that when the game / phase disposes so do the tasks
You could theoretically just have a single async and sync task running all the time that you subscribe/unsubscribe stuff to
It was recommended to me to build a priority queue to schedule tasks, but Im realizing I dont need to do that
sounds like something smile would say
It is what he said
I dont think that was necessary at all
I guess I should look more into how the Bukkit Scheduler works first
voodoo
I think that's similar to what 7 had suggested.
at least based on how I understood it
XD Now I mean how to use it and what not
meanwhile I made a quest system
Can't understand what's wrong here. I have created a plugin that on command /spit, make from player's head llama spit but it damage other people. And I need to cancel damage.
public class OnSpitHurt implements Listener {
public void OnHurt(ProjectileHitEvent e) {
if (e.getEntity()instanceof LlamaSpit) {
if (e.getEntity().getShooter() instanceof Player) {
LivingEntity entity = (LivingEntity)e.getHitEntity();
entity.damage(0.0D);
Nice!
Is the projectile source defined as the player?
I tried but it just cancel event doesn't work
oh wow, that's pretty cool, Illusion
pov: I got bored
XD
how you tried that?
You should follow naming conventions and also you forgot the EventHandler annotation
That'd be cool
I need to rework my timer idea
I do want to get better at modelling
My towers look cool being made with just block displays, but custom models would be even cooler
oh fuck really
thanks now all works
yes
just ripoff cubecraft's old TD game and do my own shiz
bro
I do want to work on my own minigame network
same
Tf was money wars
Still figuring out color schemes and stuff
hm i'm working on one actually
Everyone is working on the next hypixel
EggWars but the gens were in areas that mobs would attack you in and it was a wither skeleton instead of eggs
But strangely we don’t see many new hypixel’s
rather server instead of network but yeah
🤔
high barrier of entry
nah, the next mcci™️
coming to a minecraft in your area, soonTM
ive never even heard of mcci
lol
sadly
Let's see there are only 2 things I need to figure out in order to make a really good network
Yeah it does look quite nice
One of them is the whole vibe and identity of the server
But idk it just isn’t hitting the mark I guess
The other thing is the live deployment infra
I have a great name for a mini-game server
I already have a name for it too
and youll never get it from me
Two is copying hypixel and everything they do
Illusion, may I shadow you?
Two is the auto instancing stuff
you seem like a good dev
uh
ez
my vibe is kinda like
tf is that about
i can do it in my sleep
resource pack magic fuckery
what do you mean?
:)
You can shadow me I'm basically illusion if he had 10 less years of experience and American
yeah
Pretty sure hypixel still manually provisions servers
lol
I only have like 8 years of spigot :(
tf is shadowing
nah they have 1k dedis
They mentioned it in a dev blog a while ago
Mb 4 less gears of experience
They manually provision new machines
like 13 years of coding exp :)
But not the actual server instances
You seem like an experienced and active dev. I figured I could learn some stuff from you
They manually provision new machines with the help of some scripts
Ironically, I started in Java, but I have very little experience with it
but the instances themselves yeet into existence automagically
Gotcha
And I've got like 4 different versions of that
But it's complex as it involves minecraft plugins + 2 services
And yeah coming up with a general vibe for a server is hard
At least
yeah fr
I have a name for it, Trying to think of a color scheme
Who needs auto provisioning when you have cheap child labour in a third world country
Make it militaristic style
But I'm also thinking of the style
I know I want something night related
But is it a city night or just a fantasy night
Minigame network?
ye
It worked for them because they already had an established name
use a color scheme picker
And what games will I have
I've been pressing space for the past 15 mins
bro
Pp wars
please bring back MicroBattles
lol
alright
back to scheduling
I'm not going full cosmic
Cosmic PvP XD
But I do feel like my lobby would be in the end dimension
Id love to help you brainstorm, but Id rather use my ideas myself XD
Guys this is the signal of UART transfer
lol
There is a dev named cosmic
and he fucking died?
i feel like there's not enough servers with resource pack magic fuckery
there's like
- mcci
- mcbrawls
- cubecraft
- cytooxien
but that's about it
no
Idk who knows
we were talking about the server
Maybe ask him
those are the popular ones
add Wynn Craft. They are amazing at it
Origin realms, wynn
true
I've worked for servers doing way more resourcepack fuckery than you can think of
WynnCraft is probably the most impressive server Ive been on
Theres a few, they are just super hard to implement well with a small team
Ik another programmer called Illusion
he sucks
Origin Realms is impressive, but boring
brawls is made by a friend of mine alone :p
he's pretty good
out of curiosity Y2K is your pfp solo leveling?
definitely the innovators or resource pack stuff
Yeah
damn thanks for the spoiler
wasn't that mineclub?
It's not a spoiler it's fan art :P
its not taken from the manhwa?
Never heard of it
never heard of it
Jinx
pretty small tbf
I dont think so?
No
They were called minecraft realms before mojang sent a cease and desist
they only have two games atm soo
maybe youre saying that so i dont get spoiled 
I mean the image itself spoils nothing so that's not really the intention.
Would be cool if they went for a more rpg approach
So if I make a BukkitRunnable class that acts as a countdown timer, would it make sense to decrement the time left every time it's ran?
lol true its not as if i know what arc it is
Read the manhwa the art is crazy
its true that i have no patience to wait 3 years for the full episodes to come out but i still want to see the anime without knowing whats gonna happen plus i dont really read manhwas or mangas so i might just end up ruining the fun of the upcoming seasons
Ahhh, season 2 is announced already luckily
2024 release
yeah i thought we'd have to wait 1-2 years lol
bruh
u read the manhwa didnt u
May I politely ask that you guys take this to general?
Yeah I read a lot of everything I enjoy reading
I did
It disappeared XD
Ill post it again
So if I make a BukkitRunnable class that acts as a countdown timer, would it make sense to decrement the time left every time it's ran?
Then link it
Yes
Otherwise you can't track your timer
im hardly stopping myself from seeing whats gonna happen next in the manhwa ngl
I'm reading konosba rn too
My favorite anime tbh
oh i havent heard of it before
Tho I'll say that the light novels def aren't as funny and engaging as a manga
It's a show that basically just mocks isakai
did u read mashle
Yes
damn u know whats gonna happen in all the animes im waiting for lol
I've watched a bit of anime
Ironically I've only ever read Mashle, and Solo Leveling
Still reading konosuba
you should probably watch season 2 of mashle and solo leveling theyre good
I always do
I love to see stuff animated plus anime changes thinfs
ah yes manga readers always talk about the anime changes lol
the Igris fight ended too quick and didnt end in such a good way but i heard it was made better in the manhwa
so i could read the parts i already watched
I liked Konosuba, but not the spin offs
Agreed
Igris battle is just him getting tossed for a long time xD
A well drawn beating
in the manhwa?
Yeah
Same way pretty much
if u watched the episode youd see that even the mc himself knows that he won non-sensely lmao
im getting hyped up for it all the time, cant believe i gotta wait like 7 months FOR the first episode and then weekly episodes
After episode 7 I read the entire manwha in 2 days
Yeah I'm moving more to reading the Manga than watching Anime now.
takes too long for new episodes
AHAHAHAHAHAHA thats what A LOT of people did. You'd need like 3+ years to see what you saw in 2 days otherwise
True I always buy my manga tho too I'd say it's worth ti support the smaller creators especially
Getting it translated and for sale is not easy for most
i should try reading some manga to see if i like it so that i can do that too cuz waiting for the episodes is annoying
Ik is the sad part there are some obscure LN I'm on the look for
how do i implement protocollib in my plugin?
it tells you on its wiki/github
can anyone help me im having map issues, im trying to create a map but its generated on a void map and i want it on a standard vanilla infinite terrain how can i do that
ive been strugging for 2 days trying to figure that o ut
I have made message sender for player when he use /spit which makes him to spit like llama. And after he spit at other player plugin sends message of player's nickname in which he spat. How can I do the same for second player. "The player: nickname spat at you"
if (e.getEntity().getShooter() instanceof Player) { Player shooter = (Player) e.getEntity().getShooter(); String shootername = shooter.getName(); entity.sendMessage("Player " + shootername);
What exactly are you trying to do
i did it but i get this error
Youve just given an xy problem
so i have this map on world painter but itds on a void background essentally and i want it to be infinite generated terrain but idk how to do it
so like i have my custome area but the rest i want natural generation
?codeblock
You can use the discord code block format to display code or just text in a more pleasing way:
```java
public class MyPlugin extends JavaPlugin {
@Override
public void onEnable() {
}
}```
Becomes:
public class MyPlugin extends JavaPlugin {
@Override
public void onEnable() {
}
}```
ask on #help-server this channel is for coding.
Either way it’s not really spigot related does worldpainter have a discord
If I wanted to run a callback when the timer is ran out, what would be the best way to go about this?
Pass a lambda function as a parameter
ok
how do i do this:
To use this library, first add ProtocolLib.jar to your Java build path
Alright, thank you
Are you using maven or gradle?
You can use the discord code block format to display code or just text in a more pleasing way:
```java
public class MyPlugin extends JavaPlugin {
@Override
public void onEnable() {
}
}```
Becomes:
public class MyPlugin extends JavaPlugin {
@Override
public void onEnable() {
}
}```
maven
in the set equipment packet, where would i set the saddle/armor for a horse? the EntityEquipment bukkit class does not cover these
public class SpitHitEvent implements Listener {
@EventHandler
public void onProjectileHit(ProjectileHitEvent e) {
if (e.getEntity()instanceof LlamaSpit) {
LivingEntity entity = (LivingEntity)e.getHitEntity();
if (entity != null) {
if (e.getEntity().getShooter() instanceof Player) {
Player shooter = (Player) e.getEntity().getShooter();
String shootername = shooter.getName();
entity.sendMessage("Player " + shootername);
} else {
e.setCancelled(true);
}
}
}
}
}
you forgot "java"
You realize you have the shooter variable don't you, just send them the message
thats what i did but it still says Cannot resolve symbol 'comphenix'
try reloading maven
how?
I need to send the same message but for another player that he got spat from player.
and his nickname
ok that worked thanks
Invalidate cache then reload
can you elaborate more i got a little confused
does anyone know this?
I reckon it reuses one of the existing slots for horse
Just a shot in the dark though
i dont care to test it
i just need to know
it came with this note
so it might contain more entries than the usual
I have created plugin with command /spit. When player uses /spit the llama spit comes from his head, so he spits like llama. And when he spat on player in chat writes. "You spat on and player's nickname". And I need to do the same but for another player so: "You got spat by player's nickname".
Testing is ur only option rn
aint nah way
You have both the variables, just flip them
Yeah you have the entity variable for the guy who got shot, and shooter for the guy that shot it, just send each one a message
how do i create a fake player that shows up in tab and everything using protocollib?
You have to make a dummy GameProfile
Then just send the player join packet with the profile
?nms
Plenty of tab plugins you can reverse engineer
cool
how do i do this?
is this code good enough to be used?
I need to parse the player's nickname
who spat on another
Nickname? you mean Player.getName?
yeah
yeah you already have the shootername stored in a variable?
something like this
if (e.getHitEntity() instanceof Player) {
Player shooted = (Player) e.getHitEntity();
String shootedname = shooted.getName();
entity.sendMessage("1" + shootedname);
should i use a WrappedGameProfile with protocolib?
And I need also the player who spit on another nickname
Yeah that works, although you should follow naming conventions
?conventions
yeah then just call getName on the shooter?
which already did
String shootedname = shooted.getName();
??
thats the shooted not shooter
but it don't work for some way
oh
eh?
get it from the command handler
Here try this
public class SpitHitEvent implements Listener {
@EventHandler
public void onProjectileHit(ProjectileHitEvent e) {
if (e.getEntityType() != EntityType.LLAMA_SPIT) return;
ProjectileSource shooter = e.getEntity().getShooter();
if (shooter instanceof Player playerShooter) {
Entity hitEntity = e.getHitEntity();
if (hitEntity == null) return;
if (hitEntity.getType() != EntityType.PLAYER) return;
Player hitPlayer = (Player) hitEntity;
hitPlayer.sendMessage("You got hit by " + playerShooter.getName());
playerShooter.sendMessage("You hit " + hitPlayer.getName());
}
}
}```
update on this: the saddle is its own field and armor is just equipped on the chest. no other equipment slots exist besides the ones bukkit provide
do i understand it correctly that it is mandatory to use protocollib when trying to spawn npcs?
Bukkit definitely covers this at least on the server side
Unless you're doing this with a packet for a reason
https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/inventory/HorseInventory.html#setArmor(org.bukkit.inventory.ItemStack)
https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/inventory/AbstractHorseInventory.html#setSaddle(org.bukkit.inventory.ItemStack)
Could have looked at implementation of those to find the slots though
Not really it is just easier for most of the users. I prefer a custom way,
Would have revealed slots 0 for the saddle and 1 for the armour
java: pattern matching in instanceof is not supported in -source 8
(use -source 16 or higher to enable pattern matching in instanceof)
How can I set source 16? Can't find it.
Maven or Gradle?
lol i assumed you were using a modern java version, then use this
@EventHandler
public void onProjectileHit(ProjectileHitEvent e) {
if (e.getEntityType() != EntityType.LLAMA_SPIT) return;
ProjectileSource shooter = e.getEntity().getShooter();
if (shooter instanceof Player) {
Entity hitEntity = e.getHitEntity();
if (hitEntity == null) return;
if (hitEntity.getType() != EntityType.PLAYER) return;
Player hitPlayer = (Player) hitEntity;
Player playerShooter = (Player) shooter;
hitPlayer.sendMessage("You got hit by " + playerShooter.getName());
playerShooter.sendMessage("You hit " + hitPlayer.getName());
}
}```
If you're using anything prior to Minecraft 1.17, you probably shouldn't. If after the fact, depends on your build system
how do i make a fake player using protocollib?
Thanks, now all works.
does this create a fakeplayer which I can join to my server? java WrappedGameProfile gameProfile = new WrappedGameProfile("621b1c38-75bf-47e2-97e5-04362248e9bb", "PlutoCraftNet");
Spigot updates to java 21 minimum when???? kek
CraftBukkit will. Bukkit probably will never need to for any reason because the features just aren't at all necessary
These are the only features of note added between J17 - J21
- UTF-8 by default
- Code snippets in Javadocs (
{@snippet}), actually handy but we can just generate Javadocs with a J21 JDK - Sequenced Collection interfaces
- Record pattern matching (
if (someRecord instanceof Point(int x, int y))) - switch pattern matching (
case Integer i ->)
Downstream will with 1.20.5
Bukkit will likely use none of those
Yet can't wait to use all of these in the ultimate bukkit pr of the century
You would have to try really hard to use these features in Bukkit given its comprised almost exclusively of interfaces
Code cleanup could be done using Java 21. Old features can be improved.
It's often not at all worth it
For now 😈
And prone to breaking things
Remember the commit we did last year replacing all instances of Validate and if (x == null) with Preconditions which is now CraftBukkit's standard? And the like 10 commits that came after it having to fix all the inconsistencies and bugs?
The only thing really worth it is string templating which is a God send
hey guys, i fall in the problem is when i use itemmeta#addAttributeModifiers, the default of minecraft attribute got disapear like Attack Speed and Attack Damage, and when i enchant sharpness, it doesn't work can someone tell me how to set custom Attack Attribute without remove the minecraft default one?
Like I said. These are the only features of note
Lameeee
They are in 21, they're just behind the preview flag lol
Huee my first PR to Spigot
My P-Fork uses Java 21 features already. Otherwise code would be little less readable. 😄
soneone help plsz
CabernetMC will exclusively use Java 6
And running on running on Debian 3 ?
No that's way too new
I'll be building from an old Linux kernel and create my own from selected old and trusted software
java.lang.IllegalStateException: Duplicate recipe ignored with ID
am i not allowed to have 2 different items with 2 different recipes but same namespacekey?
No
bruh
Xy problem moment
what
That doesn't even make any sense
its not xy problem
.
Why would you be allowed to have 2 recipes under the same unique key
cuz they're different items
but same key
A key is A unique identifier
So that still makes 0 sense the items aren't the identifier
.
Well idk but anyways thanks
But why it says that my commit is not signed, is that an issue?
It's not an issue unless you're drafting commits that get directly merged into the master branch, which seldom happens, especially for first time contributors
md tends to squash and rebase commits anyways so it's signed under his key
For a future and general knowledge, how to I enable signing? Github yells at me all the time for the same exact reason
You would have to either have a GPG key or SSH key which you can then add its private key to the Stash
always a good idea to sign your commits
Obviously they're explaining how to upload it to GitHub, but the process is largely the same up until you have to upload it to BitBucket instead, which is just a different page under the settings
If on windows; Im pretty sure the git credential manager handles that for you
don't want someone else to pretend to be you
how can i add a new player to the tablist and online count?
can i disable collision on entities?
declaration: package: org.bukkit.entity, interface: LivingEntity
thanks
I'm currently sending a lot of netty ByteBufs, which are just Particle packets but flushed directly before the compression channel handler. I was wondering whether I could somehow just send them in just one big ByteBuf, since the compression seems to be Gzip, and according to netty it's possible to do so
Yes, the online count can be changed by modifying the outgoing server list ping packet.
Adding players to the tablist requires NMS and creating new GameProfiles.
Anyone know how to do the worledit //replace block with another block. Ive done the select region but cant figure out how to do the rest
hey guys, i fall in the problem is when i use itemmeta#addAttributeModifiers, the default of minecraft attribute got disapear like Attack Speed and Attack Damage, and when i enchant sharpness, it doesn't work can someone tell me how to set custom Attack Attribute without remove the minecraft default one?
Through their API?
I cant figure out how to. its so confusing
how do i create a gameprofile?
Add the mojang authlib as a dependency and call the constructor.
You will need NMS btw
Adding custom attributes always removes the default. This is vanilla behavior.
how do i importal nms?
?nms
Im assuming you are talking about the API. In which case:
https://worldedit.enginehub.org/en/latest/api/index.html
:Clueless:

Im using multiverse core to have seperate world and I was going to have a timer to reset the world I have that all working but I need a way to safly teleport the players out before it resets the api doesnt seem to have a way to get all the players in a world is there something in spigot to get a list of players in a specific world to teleport them out?
Yeah and i dont understand at all how to do the replace with the api
World#getPlayers gets you all players in a world
what do i need to put here?
GameProfile gameProfile = new GameProfile();
All parameters the GameProfile constructor asks for.

After that you need the ClientboundPlayerInfoUpdatePacket
Or PacketEvents
Im thinking about adding a constructor here which lets you pass a List<Entry> directly.
This way you dont need a pesky custom ServerPlayer implementation with a spoofed connection.
That always bothered me.
Which would allow us to add more API where you can actually send fake entries in the tablist by using spigots PlayerProfile class
anyone know how to close this huge cap between the file selector and the editor?
probably git blame?
+ // CraftBukkit start
+ public ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action action, List<ClientboundPlayerInfoUpdatePacket.Entry> playerUpdates) {
+ this.actions = EnumSet.of(action);
+ this.entries = playerUpdates;
+ }
+ // CraftBukkit end
nope
Ah very nice
?stash
If you add that I can drop that in my P.fork. 😄
Should I link you to other ctors that probably are good for that pr?
can anyone tell why this is not workingoptions:
Sure, if they make sense in the context
options:
prefix: &2Auto&aCompress
timeorpickup: 1
time: 1 second
autopermission: autocomp.use
permissionmessage: &fUnknown command. Type "/help" for help.
getautopermission: staff.getautocomp
## timeorpickup: Set to 1 for the check to occur every {@time}, and set to 2 to check on every pickup (may not work with auto pickup)
command /autocompress [<text>]:
permission: {@autopermission}
permission message: {@permissionmessage}
trigger:
if arg-1 is set:
if arg-1 is "on":
set {autopickup::%player's uuid%} to true
send "{@prefix} &aSet automatic compressions to &etrue&a."
else:
if arg-1 is "off":
set {autopickup::%player's uuid%} to false
send "{@prefix} &aSet automatic compressions to &efalse&a."
else:
if arg-1 is "check":
if {autopickup::%player's uuid%} is not true:
send "{@prefix} &aYou currently have automatic compressions set to &efalse&a."
else:
send "{@prefix} &aYou currently have automatic compressions set to &etrue&a."
else:
if arg-1 is "toggle":
if {autopickup::%player's uuid%} is true:
set {autopickup::%player's uuid%} to false
send "{@prefix} &aSet automatic compressions to &efalse&a."
if {autopickup::%player's uuid%} is not true:
set {autopickup::%player's uuid%} to true
send "{@prefix} &aSet automatic compressions to &etrue&a."
else:
send "&cInvalid usage. Correct usage:
what
Ask in Skripts discord
this is the script i got from a spigot skript
99.99% of people here use Java for plugins you will not get adequate help here
alr
The other 0.01% use kotlin
bruh
What
nothing
?
more like 10%
0.01% is a bit unrealistic don't you think
Eh we have no way to accurately check
Hey guys!
(I don't really want to be spoonfed) but what would be the best way to make the equivelent of a JavaScript's SetInterval? Basically something that runs every X ticks and can be stopped when the objectives are met... Here's as far as I got...
boolean running = true;
while (running) {
Bukkit.getScheduler().runTaskLater(this, () -> {
// code
if(Stop Condition) {
running = false;
}
}, 20L);
}
(obviously that doesnt work)
spigot developer survey? 🤔
Use a BukkitRunnable which has a cancel() method and schedule it as a repeating task.
new BukkitRunnable() {
@Override
public void run() {
if(condition) {
this.cancel();
return;
}
// Do something
}
}.runTaskTimer(plugin, 20, 20);
But i would honestly just start a single task when the server starts, which never stops and keeps a collection of elements in it.
You then tick the elements inside your task and remove them when they should no longer be ticked.
But i would honestly just start a single task when the server starts, which never stops and keeps a collection of elements in it.
💀
That is 100% the way to go. It is cleaner and more performant than constantly scheduling random tasks.
cue the 500 line bukkittask
Thanks a lot!
Also, yeah the second option would be better, tho I'm crunching and the tasks wont occupate a lot of time/resources sooo I will proceed on being negligent :p
Idk what that means but such a task would be maybe 30 lines of code
Here is a resource that explains how to write tasks which only take a fixed amount of time per tick.
And some other stuff
Also how would I go on to pass variables onto the runnable? Imagining that it is running inside of an if with local variables and I needed to pass those onto the runnable... Could it be possible or do I have to go through mutually accessible variables?
For which case? Scheduling multiple tasks or adding elements to a single task?
I'm guessing adding elements to a single task
Either way i would not pass variables through lambdas of scheduled resources.
Create a concrete class implementation and pass them through the constructor.
Ideally those variables should be kept in a manager if they have semantic meaning.
Like this for example
var foo; //Defined here
new BukkitRunnable() {
@Override
public void run() {
if(foo == bar) { //Access it here
this.cancel();
return;
}
}
}.runTaskTimer(plugin, 20, 20);
Whats the actual use case?
A... weapon where theres a Location and a Vector, and each iteration adds Vector to the Location
Yes, a weapon that send a Projectile sorry
how do i use ClientboundPlayerInfoUpdatePacket?
In that case i would write a ProjectileTask which keeps track of all fired projectiles.
So create an abstract representation of your Projectile (the implementation doesnt matter, can be whatever you want)
public interface Projectile {
void tick();
boolean isDone();
void onHit(Block block);
void onHit(Entity entity);
void onTimeout();
}
And a Task that starts with the server:
public class ProjectileTask implements Runnable {
private final List<Projectile> projectiles;
public ProjectileTask() {
this.projectiles = new LinkedList<>();
}
@Override
public void run() {
this.projectiles.removeIf(projectile -> {
projectile.tick();
return projectile.isDone();
});
}
}
Every tick, all projectiles get ticked, and if isDone() returns true, then they are removed from the tick list.
This way all you need to do is add your Projectile implementations (Like FireBallProjectile, CanonBall, etc) to this ProjectileTask, and
write a robust implementation. Add and forget.
Thats amazing! I kinda feel bad to have to get to the point of spoonfeeding, but hey, free code :)
Thanks a lot for explaining and being awesome overall!
i have a gameprofile, how do i send the pack to all players so they see it as another player in tab?
Thats a bit tricky and im currently writing a PR to make it easier. You need to basically either use reflections to set the fields, or write directly into a byte buffer.
ProtocolLib might be easier for this.
oh ok, i have protocollib do you know how i can do it with that?
Barely anybody will partake unless it's in like #announcements or a forum post by md 5
does java CommandMap.register(String fallbackPrefix, Command command) already call something like this ```java
for (Player player : Bukkit.getOnlinePlayers())
{
player.updateCommands();
}
No :3
Reload does horrid things
Which is precisely why
#announcements might be cool, sadly there's no @developer or something. anyway, something like that isn't happening, but would still be cool
so to be clear, when i inject commands at runtime, its best to update all clients command list?
xD
Yea
aight🙏
public PacketContainer createFakeTablistPacket(String displayName, UUID fakeUid) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
WrappedGameProfile profile = new WrappedGameProfile(fakeUid, "FakePlayer");
int ping = 0;
EnumWrappers.NativeGameMode gameMode = EnumWrappers.NativeGameMode.SURVIVAL;
WrappedChatComponent wrappedName = WrappedChatComponent.fromText(displayName);
PlayerInfoData playerInfoData = new PlayerInfoData(profile, ping, gameMode, wrappedName, null);
Set<EnumWrappers.PlayerInfoAction> actions = Set.of(
EnumWrappers.PlayerInfoAction.ADD_PLAYER,
EnumWrappers.PlayerInfoAction.UPDATE_LISTED
);
packet.getPlayerInfoActions().write(0, actions);
packet.getPlayerInfoDataLists().write(0, List.of(playerInfoData));
return packet;
}

soz for needing to spoonfeed, Set.of and List.of gives this error: Usage of API documented as @since 9+
Sounds like you are using java 8. Which you shouldnt.
oh, doesnt this mean i use java 17 tho?
Need to update in maven as well
oh ok i got it thanks
i got this error when loading it up
What version are you on?
1.20.1
And Plib?
5.1.0
Can I shoots effects as projectiles. Like do a llama spit with hearts or llama spit with fire?
this:
public PacketContainer createFakeTablistPacket(String name, String displayName, UUID fakeUid) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
WrappedGameProfile profile = new WrappedGameProfile(fakeUid, name);
int ping = 20;
EnumWrappers.NativeGameMode gameMode = EnumWrappers.NativeGameMode.SURVIVAL;
WrappedChatComponent wrappedName = WrappedChatComponent.fromText(displayName);
PlayerInfoData playerInfoData = new PlayerInfoData(profile, ping, gameMode, wrappedName, null);
Set<EnumWrappers.PlayerInfoAction> actions = Set.of(
EnumWrappers.PlayerInfoAction.ADD_PLAYER,
EnumWrappers.PlayerInfoAction.UPDATE_LISTED
);
packet.getPlayerInfoActions().write(0, actions);
packet.getPlayerInfoDataLists().write(0, List.of(playerInfoData));
return packet;
}```
and then this in onEnable:
```java
createFakeTablistPacket("PlutoCraftDev", ChatColor.GREEN + "" + ChatColor.BOLD + "DEV " + ChatColor.RESET + "PlutoCraftDev", UUID.fromString("14aec651-52d7-422f-a218-1543f611a0ee"));```
Not natively. You need to write a bit of code for this.
Try EnumSet.of instead of Set.of
still get this error: Caused by: java.lang.ClassCastException: Cannot cast java.util.ArrayList to java.util.EnumSet
How can I do this? Like launch snowball and change it to a particle?
Is there any way of creating an explosion that only damages hostile entites and not players? Maybe using teams or something, the most reasonable idea right now is to create a fake explosion with particles and going through all nearby entities 💀
it says the error is happening on this line:
packet.getPlayerInfoDataLists().write(0, List.of(playerInfoData));```
If you create an explosion, you can be sure that the next BlockExplodeEvent is the one you have caused with this explosion.
This might help, but actually getting the entities damaged by this explosion is the next issue.
I dont see a trivial way for a targeted explosion.
Uhm, try writing into the index 1 instead of 0.
Its just a guess, but the only solution i could think of rn.
Yes, I forgot to mention that I also thought of using an Damage event for the player and to cancel any explosion related ones, but I might need explosions that also damage the player in the future, so thats out of the question... Ok thanks!
same with this line or no?
packet.getPlayerInfoActions().write(0, actions);```
tried it, it loaded but nothing happened on enable
What's your current code?
@civic sluice its this
Sounds good, no?
No exception means something went right
well the player didnt get added to the tablist
When did you send the packet to players?
onEnable

What
During your onEnable there is literally nobody on the server.
So you didnt send the packet to anyone
https://paste.md-5.net/ixipewokev.cs
Here is my code getting datas from database and mojang api but It seemed to slowdown server for sometick even it got put in another thread
could anyone explain for me

You hereby have an embargo for anonymous classes and lambdas.
Go rewrite this by using actual classes and come back after the rewrite.
public UsefullyNamedTask extends BukkitRunnable {
}
Do it on PlayerJoin
well there is a lots to write there :l but it does have everything
All of this code should be split into dozens of methods and several classes.
It is completely convoluted and hard to read. I personally dont want to touch this at its current state.
ohhh so should i be sending it like this?
@EventHandler
public void onJoin(PlayerJoinEvent event) {
createFakeTablistPacket("PlutoCraftDev", ChatColor.GREEN + "" + ChatColor.BOLD + "DEV " + ChatColor.RESET + "PlutoCraftDev", UUID.fromString("14aec651-52d7-422f-a218-1543f611a0ee"));
}```
Im still not seeing the code where you actually send the packet to anyone.
*But close
?nbt
oh should i be doing something like player.sendPacket or something?
you can't send a craftplayer a packetcontainer
but i believe there's methods on the packetcontainer
Yeah, you need to pass the player as well that will get the packet.
It was another one I saw yesterday that showed the arg I needed for remapped build tools jar
?nms
Ah oops ty
like this?
protocolManager.sendServerPacket(player, createFakeTablistPacket("PlutoCraftDev", ChatColor.GREEN + "" + ChatColor.BOLD + "DEV " + ChatColor.RESET + "PlutoCraftDev", UUID.fromString("14aec651-52d7-422f-a218-1543f611a0ee")));```
Looks more promising.
Yeah, but now format it by creating a several variables. Putting all that mess into one line is dirty
Probably best to handle it using Scoreboard Teams.
@young knoll When adding new files for changing the server impl, do i add remapped ones to craftbukkit for building patches or the obfuscated ones?
remapped
k
Guys
Can anyone help me making a plugin? I’m blocked rn
I would love to make a hover plugin, when a player hovers with his mouse on a player who sent a message, he could see which role that player has
blocked?
not sure what being blocked has to do with coding
Banned from IJIdea
well its not the only IDE
I’m blocked, I mean I can’t go further, I’m in front of a cup de sac
I suppose it means he hasn't got time
Cul*
You can raytrace in the direction the player is currently looking in. This will return the entity if the player looks at one, or null otherwise.
I think he means to hover the name in chat
Yea
not the actual entity
Wait
Ah
any way to fix this error https://paste.md-5.net/kidekoguku.sql ?
im using CommandAPI
Makes sense. Then replace the name with a hoverable component i guess
why CommandAPI doesn't work on 1.20 D:
Update to 1.20
i downloaded the latest version
How would you know? You are on 1.19
Ribble
how do i do that?
what
is it possible to give my fake player a rank with a weight and stuff just like with luckperms/vault?
wdym rank with weight
like a display name basically
soooo... npcs?
fake players in tab like this:
public PacketContainer createFakeTablistPacket(String name, String displayName, UUID uuid) {
PacketContainer packet = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
WrappedGameProfile profile = new WrappedGameProfile(uuid, name);
int ping = 20;
EnumWrappers.NativeGameMode gameMode = EnumWrappers.NativeGameMode.SURVIVAL;
WrappedChatComponent wrappedName = WrappedChatComponent.fromText(displayName);
PlayerInfoData playerInfoData = new PlayerInfoData(profile, ping, gameMode, wrappedName, null);
Set<EnumWrappers.PlayerInfoAction> actions = EnumSet.of(
EnumWrappers.PlayerInfoAction.ADD_PLAYER,
EnumWrappers.PlayerInfoAction.UPDATE_LISTED
);
packet.getPlayerInfoActions().write(0, actions);
packet.getPlayerInfoDataLists().write(1, List.of(playerInfoData));
return packet;
}```
is it true that the entity id assigned to entities is just a counter?
doesnt it reach a limit at some point?
or at least reset?
Kinda yes, but before the limit is reached your server is kinda dead or the entity ids count from zero because the old entities are despawned long before.
ok that worked thanks, how do i change the order its in in tab, for example i want people's whos display name starts with "OWNER" or something to show up before
i guess, but what if
it just seems so insecure
i don't quite know how tablist sorting works, but i guess you could hide the entries and show them in a particular order again
65k entities or more is needed.
More if it's a long instead of an int.
ist the limit 2 billion or something
for int
You don't fetch the entity by their entity id , you do by uuid.
the id is used in packets though
they depend on the world AFAIK
The likelihood that it clashes is too small to even be considered.
how can i put usage message for CommandAPI, because withUsage("usage") doesn't seem to be working
it does nothing
how do i send the packet to all the players online instead of only the one which joins?
Iterate over online players and send or use plib broadcast
ok, how do i remove the player now?
Send the remove packet