#help-development
1 messages · Page 2018 of 1
what's that do
1.8 had no cooldown at all right?
in 1.8 you could hit 8 times per second
public class QuitEvent implements Listener {
@EventHandler
public void playerQuitEvent(PlayerQuitEvent e){
Player p = e.getPlayer();
World world = p.getWorld();
for (Entity entity : world.getEntities()){
if (entity instanceof Horse) {
if (horsealive.containsKey(p.getUniqueId().toString())){
if (((Horse) entity).getOwner().equals(p)) {
entity.remove();
}
}
}
}
}
}
So I have this code, and im trying to make it delete the players horse when the log out. Whats wrong here? Nothing seems to be happening when a player logs out.
https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/String.html#translateEscapes() actually, it is translateEscapes
declaration: module: java.base, package: java.lang, class: String
it shows a red line
so if u put the attack speed to a very big int, it could be even faster than 8attack ps
Dont do that... use pdcs. And listen for several other events like chunk and world unloading
Yeah, it's J17 exclusive but nowadays everyone is going to use it
yeah i did that once + i set the damage delay to 0 and it was very fun
Whats a PCD?
do i need to update my java or smth? i don't understand
i'm on java 17 it appears
I like how you did not react to the very inefficent world.getEntities()
Then you did an syntax error
prefix.translateEscapes();
?pdc
So I want to check the data of the horse instead of .getOwner?
save the data in the pdc
JavaPlugin#getResource("duels/inventories/combo.yml") returns null??
🤦 misspelled, I just saw it
🥲
what database should i use
i have absolutely no clue on how to use a database
so i cant really choose
I mean there are a couple significant ones
SQLite
H2
MySQL, MariaDB and PostgreSQL
MongoDB
(Redis)
I mean there are tons more than what was mentioned but those are the most common ones around here to my knowledge
maow what are you lexing/parsing?
You should take a look at RedLex, it makes it pretty trivial
RedLex?
My lexer generator library
lol. A good start would be to learn SQL
You give it bnf and it gives you a lexer that can take in a file of any context-free format and spit out an abstract syntax tree
I used it to make a json parser in 60 lines and a tinybasic interpreter in 400
is SQL the name of it or is it like MySQL or PostgreSQL
SQL is the way you talk to MySQL
SQL is the language
etc
MySQL, SQLite, all the different implementations of it have slight variations on the syntax and behavior
^ but at a basic level they’re pretty identical
so i should learn SQL first right
Yes
okay
SQL is pretty easy to learn
And just pick either SQLite, MySQL or MariaDB or PostgreSQL
MariaDB is MySQL though
Gotta start somewhere (c
They’re not entirely the same
Each one has slightly different syntax just to mess with you
Whats the difference in bukkit runnable between runtasklater and runtasktimer?
I thought mariadb was just an implementation of the mysql server
One repeats
The other only runs one time
ok
@EventHandler
public void onAsync(AsyncPlayerPreLoginEvent e) {
UUID profileTwo = UUID.randomUUID();
for (Field f : e.getClass().getDeclaredFields()) {
if (f.getName().equalsIgnoreCase("uniqueId")) {
f.setAccessible(true);
try {
f.set(e, profileTwo);
} catch (IllegalArgumentException e1) {
e1.printStackTrace();
} catch (IllegalAccessException e1) {
e1.printStackTrace();
}
f.setAccessible(false);
} else {
System.out.println(f.getName());
}
}
System.out.println("SPOOF: " + e.getUniqueId() + " | " + profileTwo);
}```
I'm trying to create multiple profiles for each player i use many plugins like mcMMO, auction houses and others
[18:28:03] [User Authenticator #17/INFO]: UUID of player MYNAME is 59XXX20-4XX0-4aXX-86XX-1e3XXXe718```
worked for a second*
I tried doing it another way
That is so bad
wait databases are stored locally right
They can be remote
Is there another way?
but they can also be local right
yes
okay
Why do you need to "create another profile"?
To allow ranked players to create multiple profiles like hypixel skyblock
Just doing it properly by interfacing with all your plugins would be better
^
And yes I understand that is more work
You could have a plugin that swaps inventories and such per profile
It's more work but it's a way better solution
Agreed
Trying to hack it like that is going to cause so many issues
The problem is not here, it's on support for other plugins like as i said mcMMO, etc
redempt dont you have a config api util whatever thing
or is that a command framework
I want to hack it tho?
cant remember
Take an example quests plugin it gets weekly updated
I have to weekly update it
Or be stuck at old version
So hacking it is the only way
@waxen plinth
RedLib has a config API
i would not fuck with the gameprofiles
I can change uuids with it?
I tried changing the "id" in gameprofiles didn't work too
You should not do that. The UUID is used for a ton of internal mappings. Just changing the UUID of a GameProfile doesnt cut it.
If anything it will just break stuff.
I have both
Config and commands
Why?
wanted to check it out but didfnt know which one it was
i looked at the redlib github
it looks really clean ill give it a try
Do you actually write plugins or do you just write libraries all day?
mlao
I write more libraries than plugins not gonna lie
At some point you should attempt to write your own lib too. Teaches you quite a bit.
I've got a support discord you can join for questions, otherwise feel free to DM me but I'm travelling today so response time may be slow
For me its similar. I always love designing the libraries, apis and bases of plugins/core but
have less fun with actual content creation
Exactly
I'm very much a backend guy
I like making all the cogs and the frameworks to support things, but when it comes to actually implementing features I drag my feet because it's so much more annoying
You have to worry about appearances and such
same
bump
Anyone here know if it's possible to get the time a packet from the client was sent using Protocollib? For instance the BLOCK_PLACE packet
?learnjava
You can get the time a packet was received
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.
listen for the packets and get the systems ms
back end is pog
But that would give you the time the packet was received right?
I can only do front-end guis in minecraft inventories
if you want to have the time the client actually sent the packet, you would need to do it clientside
I see
Ehh the closest you got is subtracting the ping from the current ms
i need a lib idea im bored
Library have the ability to change uuids
like copying chunks?
difficulty level?
anything
Fine, library has the ability to store any object, get any object efficiently stored in sqlite
Make a library that allows you to spawn any NPC and take control of it
hm
Basically operating multiple accounts in one
idea milked
Oh wait
I tried but it's like impossible
u mean morph into npcs?
So you do like
ChunkSnapshot 
i didnt know that existed but i have a lib on that Lmao
its really easy to use tho
thats like
really hard
or impossible
probabl
and how would u morph into it
or you do it entirely through packets
/override one spawns a copy npc of you
and teleports you to the other player
and sends skin packets
yeah
despawn the NPC, change players skin and name, set NPC once done
syncs permissions, inventory
yeah thats like impossible, to completely copy it
something like it
Freshly made
worldql shards a minecraft world
I mean copypasting player data
much like a funky controllable spectator mode
bump anyone? i've been trying to do this in the last 4 hours
If you want to spoof the UUID of a player then you have to do that very early when handshaking.
And there are probably some implications regarding authorization you have to keep in mind.
ill try protocollib
Like somewhere in here
Well i thought of it at the first when i started but i was like what it has to do with packets
And you probably would want the server to never receive any unspoofed packets at all. So this should
preferably done at proxy level (bungee, waterfall, velocity)
Either way you have to let the player re-login
https://wiki.vg/Protocol#Handshake
There is no uuid?
Not sure where you have seen this but supporting multiple profiles is usually done on fully custom servers that
have this feature in mind from the beginning. A mapping UUID -> AccountOwner where AccountOwner contains multiple accounts.
The problem is: The client still knows it own UUID. So you need to listen to all incoming packets on proxy level
and use a Map<UUID, UUID> to translate them for your server.
I'll lean out the window and say that something like this would take at least 4 months to develop.
Can i boost this process by making the server offline/making it on bungee?
Why when this event executes nothing happens?
public class PlayerMoveListener implements Listener {
TestPlugin plugin;
@EventHandler
public void onMovement(PlayerMoveEvent e) {
Player player = e.getPlayer();
World world = player.getWorld();
Block block = player.getLocation().subtract(0, 1, 0).getBlock();
Material type = block.getType();
if (type != Material.GLOWSTONE && type != Material.AIR) {
block.setType(Material.GLOWSTONE);
new BukkitRunnable(){
public void run(){
block.setType(type);
}
}.runTaskLater(plugin, 60L);
}
}
}```
Did you register the listener?
is plugin null?
no
wdym?
I mean if you registered an instance of the listener using the PluginManager
how would i send a player to a different server with bungeecord while using a bukkit plugin
plugin messages
could you elaborate on that
yeah i did that
everything works except bukkitrunnable
The home of Spigot a high performance, no lag customized CraftBukkit Minecraft server API, and BungeeCord, the cloud server proxy.
ok thank you
Add some debug messages
So how do i change uuid in bungeecord?
This is only thing that doesnt get executed
public void run(){
block.setType(type);
player.sendMessage("asd");
}
}.runTaskLater(plugin, 60L);```
Either use a packet listener or inject your own packet handler into the netty pipeline
Makes no sense. Any console errors?`
Also add a debug message right before you create the runnable.
@Override btw
lol
Is there any info of how long the swing animation takes?
You know how to prevent that?
Make it private final and pass it via the constructor.
decreases the chance of it being null by a lot
singletons do the same right
Nevermind, seems to be around 200ms
im setting a permission attachment to a player and when they relog it removes the permission entirely, does anyone have an idea?
when they relog its a new player object. you have to apply the attachment every time they join
Does event.getCommand(); for ServerCommandEvent return the command and the arguments, or just the base command?
?tas
And does it return the / too?
Can we detect if an inventory is not a default inventory in spigot with packets or else ? (an inventory created on the client side)
thank you 🙂
shouldn't
mob.targetSelector.addGoal(0, new NearestAttackableTargetGoal<>(mob, Player.class, 10, true, false, entity1 -> !entity.getUniqueId().equals(player.getUniqueId())));
make it so it'll choose a target nearby where the entity uuid does not equal a player uuid
Is there a packet to set a player a spectator target? (That the player is going inside the entity in gamemode 3?)
what is with people wanting to only mess with packets o.O
how about search the api next time instead of just assuming the hard way is the best way -.-
declaration: package: org.bukkit.entity, interface: Player
playerData.getStringList("players." + player.getUniqueId().toString() + ".treaties").add(clickedPlayer.getUniqueId().toString());
playerData.getStringList("players." + clickedPlayer.getUniqueId().toString() + ".treaties").add(player.getUniqueId().toString());
When setting the data, its not updating at all.
Even with EmeraldsPlugin.data.saveConfig();
Did I do something wrong?
I mean not with the spigotApi with Minecraft Protocol (Packets)
why do you need to use packets for it?
Because I have packet based entities
and that means you can't use the API?
to answer your question yes there is a packet for it
Anybody?
say my config is yml cmdInfo: hugthem: description: "gib a hug" permission: "example.hug" senderMessage: "" receiverMessage: "" what would I need to do to read everything command under cmdInfo
getStringList was empty and get apparently returns a configuration and I cant loop those
You need to make a copy of that list then add whatever you need. Then save the copy using #set()
Ah oky
(I tried List<String> commands = pluginConfig.getStringList("cmdInfo"); with no luck)
Thank you.
Since you are dealing with a list based config, you need to loop through #getConfigurationSection().getKeys(false)
I guess I can't apply the API to a Custom entity because I need to provide an entity but only have the entityID
So? You can still wrap the entity with your custom class.
Oh nvm you have packet based entities
If you want to use the API then you have to implement the spigot interfaces i guess
My event, InteractEntityEvent, takes more than 1 item if they have more than 1, when interacting (2)
Any way to stop that?
hmm?
The event is fired 2 times. Once for each hand.
How do I prevent that?
You wouldnt want to prevent that
Check to see if the item they are holding is in their main hand.
Okay.. then how do I make it only take 1 item?
How you handle this depends on how you check for items. Show your listener pls.
@EventHandler
public void interactEntity(PlayerInteractEntityEvent event) {
ItemStack item = event.getPlayer().getInventory().getItem(event.getHand());
}
instead of
@EventHandler
public void interactEntity(PlayerInteractEntityEvent event) {
ItemStack item = event.getPlayer().getInventory().getItemInMainHand();
}
This way you support both hands
but wont it take the item twice still?
Only if you hold the custom item in both hands.
You could also compare the hand the player uses with PlayerInteractEvent#getHand(). That way you can only make specific things work if it's in the main hand or the off hand.
oh :P
i.setPickupDelay(-1); how come this doesnt work?
i thought that was how to make items non-pickup-able
Set it to the max value instead.
Yea, Integer.MAX_VALUE.
ah cool beans
nvmd
java.lang.IllegalStateException: No API implementation set. Is Holographic Displays enabled?
at com.gmail.filoghost.holographicdisplays.api.internal.BackendAPI.getImplementation(BackendAPI.java:36) ~[Plex-1.0-SNAPSHOT-all.jar:?]
at com.gmail.filoghost.holographicdisplays.api.HologramsAPI.createHologram(HologramsAPI.java:46) ~[Plex-1.0-SNAPSHOT-all.jar:?]
at net.plexpvp.core.combat.BountyHologram.draw(BountyHologram.java:24) ~[Plex-1.0-SNAPSHOT-all.jar:?]
at net.plexpvp.core.combat.CombatCore$1.run(CombatCore.java:58) ~[Plex-1.0-SNAPSHOT-all.jar:?]
at org.bukkit.craftbukkit.v1_18_R1.scheduler.CraftTask.run(CraftTask.java:101) ~[paper-1.18.1.jar:git-Paper-177]
at org.bukkit.craftbukkit.v1_18_R1.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:483) ~[paper-1.18.1.jar:git-Paper-177]
at net.minecraft.server.MinecraftServer.tickChildren(MinecraftServer.java:1547) ~[paper-1.18.1.jar:git-Paper-177]
at net.minecraft.server.dedicated.DedicatedServer.tickChildren(DedicatedServer.java:480) ~[paper-1.18.1.jar:git-Paper-177]
at net.minecraft.server.MinecraftServer.tickServer(MinecraftServer.java:1470) ~[paper-1.18.1.jar:git-Paper-177]
at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1264) ~[paper-1.18.1.jar:git-Paper-177]
at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:317) ~[paper-1.18.1.jar:git-Paper-177]
at java.lang.Thread.run(Thread.java:833) ~[?:?]```
public void draw(Player p, Double bounty) {
ThreadLocalRandom random = ThreadLocalRandom.current();
double dx = random.nextDouble(-0.75, 0.75);
double dy = random.nextDouble(0.5, 2.0);
double dz = random.nextDouble(-0.75, 0.75);
long until = System.currentTimeMillis() + 1500;
Hologram hologram = HologramsAPI.createHologram(Main.get(), p.getLocation());
//colorize("&6&l$${round(bounty).toInt()}")
hologram.insertTextLine(0, "&6&l$" + round(bounty));
BukkitTask task = new BukkitRunnable() {
double i = 0.0;
@Override
public void run() {
i += 0.2;
if (System.currentTimeMillis() > until || !p.isOnline()) {
hologram.delete();
cancel();
return;
}
hologram.teleport(p.getLocation().clone().add(dx, dy + sin(i), dz));
}
}.runTaskTimer(new Main(),0L, 1L);
}```
cloning a players location is obsolete in newer versions
wdym by obsolete
literally obsolete
Anyways this looks like a problem with Holographic Displays...
new Main() 
Oh yeah. Dont do that for once.
Also important: Do not shade in Holographic Displays
Show your dependency just to be safe
not a shade
dependencies {
compileOnly 'org.spigotmc:spigot-api:1.18-R0.1-SNAPSHOT'
compileOnly 'me.clip:placeholderapi:2.11.1'
compileOnly 'com.github.MilkBowl:VaultAPI:1.7'
compileOnly 'net.luckperms:api:5.4'
implementation 'com.github.Redempt:RedLib:66b8ea8'
implementation 'com.gmail.filoghost.holographicdisplays:holographicdisplays-api:2.4.9'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
compileOnly 'com.sk89q.worldguard:worldguard-bukkit:7.0.6'}
def targetJavaVersion = 17
java {
def javaVersion = JavaVersion.toVersion(targetJavaVersion)
sourceCompatibility = javaVersion
targetCompatibility = javaVersion
if (JavaVersion.current() < javaVersion) {
toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion)
}
}```
Output less information about var in config
smh naming conventions
?
Meh, preference there
or am I Csharping
i mean, yes that makes sense but there is no convention about it
it's the only thing given in the devapi wiki
oh then I am csharping
I doubt it says anywhere in bukkit about the naming of event methods
Nah java in general is what I meant
and even then
your method/var names should describe what they do
it is more of an unwritten convention if anything
yeah ^
I think compileOnly would be fine for that, Wally
I don't know why they're suggesting implementation
interactEntity doesnt describe that its an event for entity interaction
You don't need that at runtime (because Bukkit handles runtime dependencies)
But I think it is more of a byproduct of descriptive method naming
i feel like we should use on
since
i might have a method called
interactEntity(Player player, Entity entity)
for making a player interact with an entity
so it doesnt make sense for an event to be named like that
onEntityInteraction would tho
as well as 'item', I think it should be named 'itemUsed'
it can be any item
pog that worked
I think a variable having 2 words is a decent rule of thumb
I'd notify filo about that because that should definitely not be implementation
lol yeah
how i do that?
u have his discord or smth
PRing is an option, yeah, or creating an issue on GitHub if it's in the wiki and not publicly editable
Or just sending them a message on Spigot. I believe they have an account 🤔 If not, they have a DBO one for certain
yeyeye
why is there a CloneNotSupportedException? Why would someone implement Cloneable if it's not supported?
yeyeye
I mean it becomes supported if you implement it and use super.clone()
try, so I wonder why does Object even have a clone() method?
true*
why did I write try
its native in java.lang.Object lol
I wonder - in what circumstances would there be a public clone() method if clone() is not supported
Anyone see this error before, if so any suggestions? I've removed all plugins.
Exception Connecting:QuietException : Unexpected packet received during server login process! Followed by a string that looks like a UUID.
who would ever make something implement Cloneable just to throw a CloneNotSupporteException?
looks weird
if you don't have any plugins installed, go to #help-server and paste your full log
I have no idea how it works, that's why I asked 😄
so a new object with the current fields?
so when would the exception be thrown?
smh just closed my ide
how can you call it if its protected
why not just... not implement it in the first place?
java weird lol
subclasses can call it
super.clone()
yes the clone thing is a bit weird altho justifiable
smh right
imagine #clone only works if you implement Cloneable and call super.clone in the public method
and I've never seen a clone() implementation that looks differet from either
clone() throws CloneNotSupportedException { super.clone(); }
or as you sent it with Location where it catches the exception itself
does that makes sense 👉👈
like the entire design resolves around encapsulation and defensiveness
since unnecessary clones are, well... not necessary
is clone exception thing unchecked?
imho it's a bit like making something ConfigurationSerializable, then making a static serialize() method that throws the exception
why not just stop implementing ConfigurationSerializable then
I don't understand it lol
how would I type in the player's chat bar when they click a message?
a command or just normal text?
oh perhaps its SUGGEST_COMMAND
well I mean doesnt a command count as normal text lol
ye that will paste a command to the chat but not execute it until the player hits enter
basically im gonna send a text that says ```
/xyz``` and if they click it I want their input to autofill to /xyz
alright thats what im looking for then thank u
if the superclass implements Cloneable but the child classes cannot be cloned. This is rarely needed due to noone implementing cloneable in the first place
hm but that doesn't really make sense, does it? why would someone make a class cloneable but not its child classes?
I mean sure, maybe someone decides to do that, so yeah it makes sense a bit, but it's weird nonetheless imho
API Classes or something idk. The whole cloneable interface is too outdated that this is likely one issue
maybe I should finally buy a java book
Or if it is just physically impossible to clone because the superclass has private fields with no direct accessor
Unless you were to use reflection but eh
For me that suggests bad API design - but in our days you cannot be sure to what bad design actually is so ¯_(ツ)_/¯
It's a similar case with the serialisable interface though arguably you have a even larger reason to throw an exception there
Hi, I tried making a plugin with the mojang mappings and the server doesnt keeps saying NoClassDefFoundError to every import, how can I fix?
you have to reobfuscate your code
I might be wrong, but it seems that there's no builtin cooldown is there
Player.setCooldown(Material)
that's e.g. how the cooldown works for throwing enderpearls etc
my bad, for commands
Don’t forget the int
oh yeah
you have to do that yourself
ok thnx
are there any libraries for it lol
It's not that hard to write it anyways
It's just a simple hashmap and a System.currentTimeMillis
that perhaps add something neat like @Cooldown(time="30")
it's just a few lines. Create a Hashap<UUID,long> with the player's UUID and the timestamp when they ran the command
pain but that works too
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(args.length == 0)) {
try {
OfflinePlayer oPlayer = Bukkit.getOfflinePlayer(args[0]);
try {
if(args.length >= 2){
StringBuilder message = new StringBuilder();
for(int i = 1; i < args.length; i++){
message.append(" ").append(args);
}
message.toString();
WebhookPresets.NewReport((Player) sender, oPlayer, message.toString());
}
} catch (NullPointerException e) {
sender.sendMessage("§cPlease state a reason!");
}
}catch (NullPointerException e) {
sender.sendMessage("§cMust be a player");
}
} else {
sender.sendMessage("§cUsage: /report <player> <reason>");
}
return false;
}```
anyone know why it doesnt detect the arguments?
it doesnt throw an error if the player isnt defined
or if any of the arguments arent defined
nor does it work if all the arguments are defined appropriately
well you're just passing null to your NewReport method
if the player isn't found
just do a nullcheck yourself
if oPlayer == null { showError(); }
alright
there's no reason why that code would throw an error itself
normally if an exception isnt properly defined in a try catch it throws an error
or atleast thats how it worked for me
odd
i changed the trycatch to a nullcheck and its still not detecting the argument
how do i set the output directory for the plugin? I just started using Maven
in the maven-jar-plugin, in configuration section you can do <finalName> and <outputDirectory>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<outputDirectory>C:\mctest\plugins\</outputDirectory>
<finalName>MyAwesomePlugin</finalName>
</configuration>
</plugin>
</plugins>
</build>
np 🙂
how do i cancel not a player casting their rods,
but cancel them actually fishing?
maybe check the state?
isn't there some kind of getAction in PlayerFishEvent?
cancel the PlayerFishEvent when the event's getState() == PlayerFishEvent.State.CAUGHT_FISH
Someone should listen to that event, check for FAILED_ATTEMPT, and then call them slow in chat
or reward them for being friendly to the fish
just gonna bump this
if (!(args.length == 0)) {
OfflinePlayer oPlayer = Bukkit.getOfflinePlayer(args[0]);
if (oPlayer != null) {
try {
if(args.length >= 2){
StringBuilder message = new StringBuilder();
for(int i = 1; i < args.length; i++){
message.append(" ").append(args);
}
message.toString();
WebhookPresets.NewReport((Player) sender, oPlayer, message.toString());
}
} catch (NullPointerException e) {
sender.sendMessage("§cPlease state a reason!");
}
} else {
sender.sendMessage("§cMust be a player");
}
} else {
sender.sendMessage("§cUsage: /report <player> <reason>");
}
return false;``` and heres the updated code in question
what does the update part do in findOneAndUpdate from mongo?
what does it actually update
I dont think you can without saving the inventory when the player leaves
How can i trigger a Listener only in one world?
ew
just dropping this for you lol: https://blog.jeff-media.com/avoiding-the-arrow-anti-pattern/
how does the server do it?
wtf 😭
catching a NullPointerException
it doesnt I think
or do you mean saving the inventory?
The only thing is it’s not detecting any arguments
where would it even throw one?
nah how does it retrieve a player's inventory when they join?
i dont know and im not reading it to not cry
but yeah about the NPE, I got another link lmao: https://blog.jeff-media.com/dont-jump-off-bridges-or-why-you-shouldnt-use-exceptions-to-control-code-flow/
from the players savedata
its normal minecraft, not spigot
you can store information in the player's PersistentDataContainer
ik
well offlineplayers are not loaded
so of course you can't access their inventory etc
but...
you have to serialize it and save it in a file yourself
like...
the data is THERE
y'know?
can't i just access it the same way mc does?
good luck with that lol
if you want to parse the binary data from the hard disk, sure
Alright welp time to rewrite some code
im just confused
how?
i'd rather make a stash a player can access when they login rather than getting their inventory while offline
depends on the event
when a player joins, what happens that makes that data suddenly accessible?
'nother reason: Raising an exception is an expensive task for the JVM.
minecraft loading the file?
(or so I've heard)
how does offline player get the bed spawn location?
I actually read much stuff about that and it seems like if the exception is not thrown / created, it's not really much of a problem
but yeah sure, that's another reason
what do you mean with raising? throwing or catching it?
wdym?
Throwing
throwing
creating the exception alone is already heavy IIRC
OfflinePlayer#getBedSpawnLocation()
how?
could the same thing be done for inventory?
I don't know where it gets that from
some data stays loaded most probably
you can always go ahead and decompile nms code
also i was thinking about a website idea that runs buildtools online for you
and you can input whatever version you want
completely clean, clientside
no setup required
there's already a website with decompiled nms code i think if thats what you mean
nah
i meant like, instead of hosting spigot downloads illegally, just legally run buildtools on browser
if you mean actually downloading the decompiled code i'm pretty sure it's illegal
oh not sure how would that work but
seems like it doesn't really return the bed location
only when the player is actually online
but not sure
You'd have to rewrite BuildTools in JS so it could run client-side
Running it on the site's server would require downloading, which doesn't solve the problem
Either way the best solution is what Paper did
well and also javac, etc, right? 😄
Yeah
after all buildtools only calls maven
this is the implementation on 1.18 in craftofflineplayer
which then calls javac
i thought you could run jars with applets?
on the server, not the client i mean
but still it's fine
Yeah they're dead now
but there are other ways probably
and if you run it on the server, you'd still provide the download to other people
anyways if you manage to get an instance of PlayerDataStorage you can call a method to get the playerdata
is this more appealing to your eyes
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length == 0) {
sender.sendMessage("§cUsage: /report <player> <reason>");
return false;
}
OfflinePlayer oPlayer = Bukkit.getOfflinePlayer(args[0]);
if (oPlayer == null) {
sender.sendMessage("§cMust be a player");
return false;
}
if (!(args.length >= 2)) {
sender.sendMessage("§cPlease state a reason!");
return false;
}
StringBuilder message = new StringBuilder();
for(int i = 1; i < args.length; i++){
message.append(" ").append(args);
}
message.toString();
WebhookPresets.NewReport((Player) sender, oPlayer, message.toString());
return true;
}
}```
which is getPlayerData
Although what I would do is:
- Provide a BuildTools-like jar for developers
- Provide a Paperclip-like jar for server owners
that's waaaay better
but you shuldnt return false
if you send a message, return true
also yeah ur right about the stagnation
yeah
its a lot better without the staircasingh
Btw I would not recommend this !(args.length >= 2)
Do like
< 2 iirc?
you should also not use §c for color codes
and said, return true instead of false
This is good for like, when you need to read messages from a config
returning false will show the command description as defined in plugin.yml
You can also use ChatColor.RED and such for the colors, which you would then concatenate with your message
And, if you want, there's also the Bungeecord Chat API and Adventure for a "component" style.
lmao yeah
I'm wondering what all of those warnings from IntelliJ are
Well I know what the one about args is
"could be final"
You can't directly use args's toString method
It would just output some nonsense, I think it's like <type>:<hashCode>
You'd have to use Arrays.toString(args)
args is highlighted because no for loop is needed
this will make u cry lmfao
This is what all my old code used to look like lol
Imo never try catch if you can avoid it
but i dont have time to do that
also wait
yeah I wanted to mention that too
There's a lot of situations where you can't avoid it tho
oh hey thats some progres
Plenty where you can.
or just make every method "throws Throwable" lol
and you shouldn't allow something like NumberFormatException to propagate
and yeah i think your right cause it doesnt output anything
actually this is what it outputs
[Ljava.lang.String;@738206d2
Ah I was correct
[Ljava.lang.String; is so odd I dunno why Java stylizes it like this
I mean I know where it comes from
it's a weird combination of binary names (java.lang.String) and internal descriptors ([L<reference type>;)
They should just pick one
Go full descriptor like [Ljava/lang/String; or go full readable like java.lang.String[]
hmm
Are there tutorials on how to make a server w/ a lobby and gamemodes?
I cant find any.
in confused
isn't that always like that for arrays?
java.lang.Object@3b9a45b3
[Ljava.lang.Object;@7699a589
there isnt really tutorials for that
first is an object and second is an array of objects
hmm
what does PotionEffect.hasIcon do?
I assume checks if it has a display icon
Hides the icon in the top right
damn i didnt know thats something you can control
?paste code rather then sending files please
thats a large chunk of code
not sure how to narrow it down
There is a lot of functionality in this method that shouldnt be in there. Create new classes and methods with specific tasks.
Okay, but how would I check to see if it should run a spesific task?
With another method
Ill see if I can.
Example nr 1:
private void clickEvent(PlayerInteractEvent event) {
switch (event.getAction()) {
case RIGHT_CLICK_AIR -> handleRightClickAir(event);
case RIGHT_CLICK_BLOCK -> handleRightClick(event);
}
}
private void handleRightClickAir(PlayerInteractEvent event) {
}
private void handleRightClick(PlayerInteractEvent event) {
}
Would I then split those handlers into other functions by doing checks?
first thing that comes to my mind: create your namespacedkeys on init and reuse them
no need to create a new key every time
Sure thing
Yes you want to split up your code as much as possible. Every method should have only a single task.
also yeah as others said, I'd probably have at least 20 methods for this instead of just one
20???
Sounds about right. But at least 10 more
for the namespacedkeys I usually just have a public class or a static inner class that holds all the keys, like this
public final class Keys {
public static final NamespacedKey NAME = new NamespacedKey(myPlugin, "name");
public static final NamespacedKey AGE = new NamespacedKey(myPlugin, "age");
public static final NamespacedKey SEX = new NamespacedKey(myPlugin, "sex");
public static final NamespacedKey ADDICTION = new NamespacedKey(myPlugin, "addiction");
public static final NamespacedKey WEIRDNESS = new NamespacedKey(myPlugin, "weirdness");
public static final NamespacedKey PING_FOR_HELP = new NamespacedKey(myPlugin, "conclure");
}
I just made it a dataClass
package me.emerald.emeraldsplugin.data;
import org.bukkit.NamespacedKey;
import java.util.HashMap;
public class NamespaceKeyList {
static HashMap<String, NamespacedKey> keyList = new HashMap<String, NamespacedKey>();
public NamespaceKeyList(NamespacedKey key, String identify){
keyList.put(identify, key);
}
public static NamespacedKey getKey(String identify){
return keyList.get(identify);
}
public static NamespaceKeyList addKey(NamespacedKey key, String identify){
return new NamespaceKeyList(key, identify);
}
}
And add all the ceys on startup
then retrieve them later on
oh you could make that way shorter if you want
private final HashMap<String,NamespacedKey> keys = new HashMap<>();
public NamespacedKey getKey(String name) {
return keys.computeIfAbsent(name, s -> new NamespacedKey(PLUGIN, name));
}
this creates a new key if required or returns the already existing one
damn
also i need a bit of help
What is the ideal way of getting a Material from a ResourceLocation
in a sec
i.e. minecraft:stick -> Material.STICK
?
public class InteractionEvent implements Listener {
Player p;
ItemStack item;
ItemMeta itemMeta;
PersistentDataContainer itemPerst;
Block block;
TileState blockState;
PersistentDataContainer blockPerst;
@EventHandler
private void clickEvent(PlayerInteractEvent event){
p = event.getPlayer();
getItem(event);
getBlock(event);
switch(event.getAction()){
case RIGHT_CLICK_AIR -> handleRightClickAir(event);
case RIGHT_CLICK_BLOCK -> handleRightClick(event);
}
}
private void getItem(PlayerInteractEvent event){
item = event.getItem();
if(item != null){
itemMeta = item.getItemMeta();
itemPerst = itemMeta.getPersistentDataContainer();
}else{
itemMeta = null;
itemPerst = null;
}
}
private void getBlock(PlayerInteractEvent event){
block = event.getClickedBlock();
if(block != null){
if(block.getState() instanceof TileState){
blockState = (TileState) block.getState();
blockPerst = blockState.getPersistentDataContainer();
}else{
blockState = null;
blockPerst = null;
}
}
}
private void handleRightClickAir(PlayerInteractEvent event) {
}
private void handleRightClick(PlayerInteractEvent event) {
}
}
no we're all still on 1.6.4
Am I setting this up correctly?
you could parse the string for the stick portion, and then use Material.valueOf();
erm tbh imho this is very dirty, you use instance fields to store stuff that will change on every event, right?
while that will work, I don't think it's a good idea although I can't explain why I think that
should I use this.(object) instead?
that doesn't change anything
oh
well it'll work, I just don't think it's a nice way of doing things
Doesn't even remotely work
it should, valueOf takes in a string o.O
formatting of the materials class and the minecraft vanilla keys are very different
isn't it always just the same thing but in uppercase?
you could do String.toUpperCase()
I am 99.9% sure that it's always the same name just in uppercase
anyone know why this does not work
import org.bukkit.plugin.java.JavaPlugin;
public class Main extends JavaPlugin{
@Override
public void onEnable() {
new HelloCommand(this);
}
}
what is it supposed to do?
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class HelloCommand implements CommandExecutor{
public HelloCommand(Main plugin) {
plugin.getCommand("hello").setExecutor(this);
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
if(!(sender instanceof Player)) {
sender.sendMessage("Only players may execute this command!");
return true;
}
Player p = (Player) sender;
p.sendMessage("Hi!");
return true;
}
}```
when you do /hello
it send back "Hi"
and what happens instead?
nothing
there must happen something
I am very new to plugin dev
your console probably tells you during loading your plugin, there's a nullpointerexception at "plugin.getCommand(..." because you did not register your command in plugin.yml
when you do /plugins, does it list your plugin at all? is it green or red?
how do i spawn an item in the world with a velocity
i'm trying to make the illusion of a player dropping items out of their inventory
without actually removing any items from it
if it doesn't apper in /plugins, your plugin.yml is probably invalid
declaration: package: org.bukkit, interface: World
use the consumer to apply velocity
can I copy and paste my log here?
?paste
there's a huge error that tells you what's wrong
[23:14:17] [Server thread/INFO]: Using epoll channel type
[23:14:17] [Server thread/ERROR]: Could not load 'plugins/HelloWorld.jar' in folder 'plugins'
org.bukkit.plugin.InvalidDescriptionException: name is not defined
at org.bukkit.plugin.PluginDescriptionFile.loadMap(PluginDescriptionFile.java:898) ~[patched_1.8.8.jar:git-PaperSpigot-445]
at org.bukkit.plugin.PluginDescriptionFile.<init>(PluginDescriptionFile.java:232) ~[patched_1.8.8.jar:git-PaperSpigot-445]
at org.bukkit.plugin.java.JavaPluginLoader.getPluginDescription(JavaPluginLoader.java:157) ~[patched_1.8.8.jar:git-PaperSpigot-445]
at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:136) [patched_1.8.8.jar:git-PaperSpigot-445]
at org.bukkit.craftbukkit.v1_8_R3.CraftServer.loadPlugins(CraftServer.java:293) [patched_1.8.8.jar:git-PaperSpigot-445]
at net.minecraft.server.v1_8_R3.DedicatedServer.init(DedicatedServer.java:202) [patched_1.8.8.jar:git-PaperSpigot-445]
at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:563) [patched_1.8.8.jar:git-PaperSpigot-445]
at java.lang.Thread.run(Thread.java:826) [?:1.8.0_312]
Caused by: java.lang.NullPointerException
at org.bukkit.plugin.PluginDescriptionFile.loadMap(PluginDescriptionFile.java:891) ~[patched_1.8.8.jar:git-PaperSpigot-445]
... 7 more
you didn't define a "name" for your plugin in plugin.yml
how do i apply velocity though
[23:14:17] [Server thread/ERROR]: Could not load 'plugins/HelloWorld.jar' in folder 'plugins'
item.setVelocity(...)
do you actually expect people here to help after you started insulting people in DMs for net sending your a spigot.jar?
oh ok
._.
?ban @fallow hare slur
Done. That felt good.
rood
thanks
mine
I wanted to do it
Hello my fellow spipos, can anyone explain when exactly the ban check happens?
bans imagine
i havent banned someone in months
Demoted!
Also, how can I override the ban check logic
what does this mean
show your plugin.yml
this
send full error
ok
Had you been here last night you'd have had the easiest ban of ur life
he already did, they don't have "name" in their plugin.yml
guys how do you craft hearts tell me pls
commands:
hello:```
you're missing like all the properties
your plugin also needs a "name: PluginName" and "version: 1.0"
how do craft hearts
The home of Spigot a high performance, no lag customized CraftBukkit Minecraft server API, and BungeeCord, the cloud server proxy.
ask the dev who made your lifesteal plugin
1.8.8 💀
Bad tutorial then
Well, it was wrong
k ser
Name and version are not optional
god that's like the billionth person asking how to craft hearts
._.
whos dev
how would I know, you didnt even mention you were tlaking about a plugin
lifestealpluguin
so I need name and version, for yml
people join here all the time because you wrote they should "see discord" for the recipe
yes
Why do you ask here?
I should really do a series on plugin dev once I get a good enough mic setup 😂
There's a dedicated server
yeah but you have do understand people are stupid
yes
okok I will try
somehow lifesteal plugins attract a large amounts of the biggest noobs
Is that why they keep coming here?
good idea lol
Ike please make a huge section on your description saying "click here for discord" in big letters
reflection proxies 🙈
well
PlayerLoginEvent
has a setResult method
you can set it to ALLOWED, KICK_BANNED, etc etc
declaration: package: org.bukkit.event.player, class: PlayerLoginEvent, enum: Result
Ah-ha, okay
go away, paper user
What
OMG IT WOOORKS
And how do I disable the original ban list?
That ain't a paper
oh different name
AsyncPlayerChatEvent -> spigot
AsyncChatEvent -> paper
just set the event result to ALLOWED
very sadge
it works like this:
- player tries to join but he is banned
- server calls the (Async)PlayerPreLoginEvent with the Result already set to KICK_BANNED
- you set it to ALLOWED
- player SHOULD be able to join now
Alternatively if you want to ignore the vanilla ban list, just don't use it
yes that's also a viable solution lol
true
if my account gets hacked just know i was downloading gta 5 mods 😙
Do you not have 2fa
I'd just grab popcorn
or a mod
we should test if adelemphii can ban me
mods are higher rank than helpers
Yeah I think the sidebar order is all the hierarchy
if a helper gets hacked u go to a mod, if a mod gets hacked u go to md
where do we go to if md gets hacked
So Choco should be able to ban optic, optic can ban adele, and adele can ban me
if md gets hacked then grab popcorn
abandon ship
Run away
With popcorn, of course
salty popcorn
does anyone know why
this
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
public class Main extends JavaPlugin{
@Override
public void onEnable() {
new HelloCommand(this);
Bukkit.getServer().getConsoleSender().sendMessage("potato");
}
}
does not print potato
in chat
Bukkit.getServer().getConsoleSender().sendMessage("potato");
int cooldownTime = 30;
if(cooldown.containsKey(sender.getName())) {
long secondsLeft = ((cooldown.get(sender.getServer().getPlayer(sender.getName()).getUniqueId())/1000)+cooldownTime) - (System.currentTimeMillis()/1000);
if(secondsLeft>0) {
sender.sendMessage(ChatColor.RED + "Your on cooldown for " + secondsLeft + " seconds!");
return true;
}
}
cooldown.put(((Player) sender).getUniqueId(), System.currentTimeMillis());```
anyone know why the cooldown does not work?
that only prints it during onEnable to console
System.out.println("potato");
what
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.
that would print to console
cause I thought that was for terminal
so how would I get it in the chat
like miencraft chat
player.sendMessage
i have this code which is meant to drop a ton of soul sand (that's unable to be picked up) rapidly:
for (double i = 1; i <= iterations; i++) {
scheduler.runTaskLater(main, () -> {
Location playerLocation = player.getLocation();
player.getWorld().dropItem(playerLocation.add(0, 1, 0), throwupItemStack, (Item item) -> {
item.setVelocity(playerLocation.getDirection().multiply(.45));
});
}, (long) (i * THROW_UP_DELAY_SECONDS * 20));
}
This works as intended, however how would i then remove all the items after 3 seconds or so? The soul sand all "merge" together into one stack on the floor, how would i target this?
in a command
sender.sendmessage("potato")
to everyone not just the player
broadcast
Bukkit.broadcastMessage
yes
okok, thank you
How can I increase someones heart cap? and decrease it
his heart rn 💓
he deserves it
attributes confuse me
they suck
fr
player.getAttribute(Attribute.GENERIC_MAX_HEALTH).setBaseValue(20);```

note: 20 means 10 hearts
yeah
mhm
thats the conversion factor
bump pls
big boi problem guys
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
public class Main extends JavaPlugin{
@Override
public void onEnable() {
new HelloCommand(this);
Bukkit.broadcastMessage("potato");
}
}```
did not print potato
Bukkit.broadcastMessage
= no working
you must learn basic java
you print potato during onEnable
yeah. your doing it on enable
theres usually no players on when the server enables
if you want it to do stuff in your command, obviously you have to put it into the commandexecutor
you have to do it when players are on
also it's pretty weird to register your command inside the commandexecutor class
console doesnt see it
yes
do broadcasts even print to console
yes
what is a comandexecutor
?jd
this.getCommand("hello").setExecutor(new HelloCommand(this));
thats not a commandexecutor
the command ?jd <class> would be nice
your HelloCommand class
ok
public class HelloCommand implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
someLogicHere();
}
}```
basic command class
so I always put it in there
huh
yes
ok well i just tried something, and it works.. is this efficient though?
for (double i = 1; i <= iterations; i++) {
scheduler.runTaskLater(main, () -> {
Location playerLocation = player.getLocation();
Item item = player.getWorld().dropItem(playerLocation.add(0, 1, 0), throwupItemStack, (Item item2) -> {
item2.setVelocity(playerLocation.getDirection().multiply(.45));
});
scheduler.runTaskLater(main, () -> {
item.remove();
}, 60L);
}, (long) (i * THROW_UP_DELAY_SECONDS * 20));
}
how would I create a playerHead as an ItemStack?
specifically the part where the items are removed
w/ a username attached to it
create the itemstack, cast it's itemmeta to SkullMeta
//main class
public class Main extends JavaPlugin{
@Override
public void onEnable() {
this.getCommand("hello").setExecutor(new HelloCommand(this));
}
}
// command class
public class HelloCommand implements CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
Bukkit.broadcastMessage("potato");
}
}```
declaration: package: org.bukkit.inventory.meta, interface: SkullMeta
thats how you broadcast it
i would rather store them somewhere and just iterate through that collection after 3 secs instead of starting a new task for every item to just remove it
ah
WHAT THE HECK
SINCE WHEN DOES THIS EXIST https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/profile/PlayerProfile.html
declaration: package: org.bukkit.profile, interface: PlayerProfile
gonna bump this
good idea
?
thanks
refactor -> introduce variable
then share again
why such complicated math?
when 2 items merge together, are they considered 1 item or no?
we can finally get player's textures, and their cape, and change them using API 😮 😮 😮 https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/profile/PlayerTextures.html
declaration: package: org.bukkit.profile, interface: PlayerTextures
for example when i drop 2 diamonds next to each other
and they merge into one stack
make a resource about it and gain likes
it's one Item, holding an ItemStack with amount 2
uuugh cosmetics plugins
nah, i mean a "how to" resource
in the dev forums
aaah ok
hm tbh I doubt that changing the textures actually works
because it's gotta be signed after all
try it and be the first
ping me if it works 👍
will do 🙂
does anyone know how to get player who typed the commands name