#help-development
1 messages · Page 838 of 1
im trying getList right now
now its this
Caused by: java.lang.NullPointerException: Cannot invoke "java.util.List.toArray(java.util.function.IntFunction)" because the return value of "org.bukkit.configuration.file.YamlConfiguration.getList(String)" is null
at mondlw.laserserver.laserservermanager.util
its returning null because buildinventory was never saved
Yeah
Prob nothing wrong with the type part, just that the value at said path is null lol
but thats also what im checking for
if(buildInventory == null) {
player.getInventory().clear();
} else {
player.getInventory().setContents(buildInventory);
}
so i dont know why its erroring this. I already check if its null
?mappings
Compare different mappings with this website: https://mappings.cephx.dev
for me?
Na its not
ok
Too little code to know whats the issue :>
should i sent you code from the whole file
and its setBuildMode im currently having the issue with
Sorry - internet went out (amateur sysadmin thought it was a good idea to touch the router):
Strange, in that case you could use new ItemStack[0] instead of ItemStack[]::new
Hm, is this some IJ analysis stuff?
yes
I do mean to keep your .toArray() the same, just write new ItemStack[0] instead of ItemStack[]::new
yes
ive done that
ItemStack[] buildInventory = (ItemStack[]) ((List) storage.getList(uuid + "." + world + "." + "buildinventory")).toArray(ItemStack[0]);
You forgot the new part
And in that case you can do ItemStack[] buildInventory = ((List) storage.getList(uuid + "." + world + "." + "buildinventory")).toArray(new ItemStack[0]);
but dont i need to cast it to a ItemStack[]?
Although ordinarily even the code that I gave initially should work without a cast
No, because of how .toArray works when you give it an array
so its optional?
more useless than optional
ok
so build set on works, but build set off returns this mess:
at mondlw.laserserver.laserservermanager.utils.BuildUtils.setBuildM```
it ain't mess, it just means your list is null (not contained) within the configuration at your given path
and why is that bad?
erm because it causes an exception, you cannot use / access object members when the object you're trying to access is null
okay, so i need to initialize it with a empty inventory or what?
you need to check against whether your list is null or not, before you call .toArray(...), and if it is null, you return an empty ItemStack for example
so ```java
if(ItemStack[] buildInventory = (ItemStack[]) ((List) storage.getList(uuid + "." + world + "." + "buildinventory")) != null) {
ItemStack[] buildInventory = (ItemStack[]) ((List) storage.getList(uuid + "." + world + "." + "buildinventory")).toArray(new ItemStack[0]);
}```
this code isn't valid
you cannot create locals (or variables in general) within if clauses
but in theory, yes
yeah ik
im already doing this though=
if(buildInventory == null) {
player.getInventory().clear();
} else {
player.getInventory().setContents(buildInventory);
}
If the player doesnt have anything in the build/normal inventory it should just clear his current inventory
I'd recommend reading through java basics, since this is quite a basic issue you have right now, not to be judgmental.
You first get your list: storage.getList(...)
then you call toArray on the list (which is a class member of that list).
But what happens when your list is null, as in not contained in the configuration?
A nullpointer is thrown (since you tried to operate upon a null object)
You need to check for null before invoking any members of the object (in this case the list)
so I'll write it down for you in your example:
List<?> inventory = storage.getList(...);
if (inventory != null && !inventory.isEmpty()) {
player.getInventory().setContents(inventory.toArray(new ItemStack[0]));
} else {
player.getInventory().clear();
}
^ I'd recommend cleaning up this code a bit, depending on what your surroundings are (this if-else clause isn't very cleanly implemented, but totally valid [... I hope so lmao])
bool is wheater or not to enable or disable build mode
if(bool) {
storage.set(uuid + "." + world + "." + "normalinventory", player.getInventory().getContents());
List<?> buildList = storage.getList(uuid + "." + world + "." + "buildinventory");
if(buildList != null && !buildList.isEmpty()) {
player.getInventory().setContents(buildList.toArray(new ItemStack[0]));
} else {
player.getInventory().clear();
}
storage.set(uuid + "." + world + "." + "buildmode", true);
} else {```
schnitzel?
why is always false?
if bool is true, build mode should be "enabled". look at the last line in if block. you set the build mode to true
yes
because get will never return null
buildmode is a boolean
because you use optionals, in which #get never returns null
so whats the problem?
currently
because get() will throw NoSuchElementException if it's "null"
a error i had earlier
how i can get if is null?
Arena.arenas.stream()
.filter((x) -> x.containsPlayer(player))
.findFirst()
.ifPresent((arena) -> {
// TODO your code
});
@scenic onyx
tnx
call isPresent()
can you send an error
i try, tnx
nws
well the error is solved now. The problem i have now, is that its not loading the inventories right
you didnt post the code for inventories so i cant say what could it be
?paste
I need to go @tender shard @hazy parrot will probably help 
is their any other plugins I need for decent holograms / holographic displays to work? I just come back for having a long break. and I didint remember and they arent working.
is good code?
fst snd
well the fact you access the colletion elsewhere its not really the best
why Arena.arenas
is a List<Arena>
yeah you're not supposed to expose lists like that
is not my fst and snd
why?
is their any other plugins I need for decent holograms / holographic displays to work? I just come back for having a long break. and I didint remember and they arent working.
Why is it saying it might be null, im literally checking beforehand if its null?
I personally use HolographicDisplays API
And no, I dont use any other plugins
The reviews for DecentHolograms all say they are waiting for 1.20.4 support. Sooooo
@molten cloak iirc holographicdisplays doesnt work on anything above 1.20.1
there no other plugins required?
ah then what hologram plugin I use for 1.20.4...
You could try FancyHolograms, although it's on Hangar.
No clue, my server's on 1.20.1
I dont update to minor versions, too much effort and plugins break
Ew
why
Decent holograms is updated on GitHub
But I don’t think any pre built releases are out
I just come back to minecraft / server making. cuz I HAD a long break cuz no motivation. & my friends hosting was 50% off so I bought from him. and I made it newest version
I'm still a bit clueless why its only working half the time
If i enable build mode it clears my inventory, but doesnt save it
this should save it
storage.set(uuid + "." + world + "." + "buildinventory", player.getInventory().getContents());
but its not
wait
oh it makes sense
was 2nd guessing myself there for a second
okey
mhh
Both can be used depending on what ur doing
Well a bucket isn’t a block
The docs will tell you what's what lol
So, ive implemented some error finding and ive got these results:
Server restart:
- Have something in inventory
-> Build on
BOOL TRUE, NOT EMPTY BUILDLIST - Nothing in inventory
-> Build off
BOOL FALSE, EMPTY BUILDLIST - Nothing in inventory
-> Build on
BOOL TRUE, EMPTY BUILDLIST
After this i still dont have anything in my inventory, the items i had from the beginning werent saved..
Again these are the links to my code and my command
Code: https://paste.md-5.net/kixipeguve.cs
Command: https://paste.md-5.net/utaxubavon.sql
I don’t see you save storage anywhere
Oh my Lord. For starters please make a method to set/get so you don't have to copy paste your "key".
Or at least extract it into a variable
when ur overlapping methods whats the order it goes
most complex to least complex or other way
This code could probably be reduced and made easier to read.
me?
This code #help-development message
public static YamlConfiguration storage = YamlConfiguration.loadConfiguration(new File(plugin.getDataFolder(), "buildData.yml"));
public static void saveBuildMode() throws IOException {
storage.save(new File(plugin.getDataFolder(), "buildData.yml"));
}```
its not like nothing is saved, its just a empty inventory thats being saved..
lobby:
normalinventory:
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
buildinventory:
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
- null
buildmode: false```
Remember the good old days when databases existed 
I think you might find your solution if you clean up the code first. The first step would be extract commonality. This includes the key you're using to save as it looks fairly static between sections.
Make a string call it key and then replace all instances of the uuid+. Stuff.
don't save empty inventories 🙂
due to it's non-deterministic behaviour: theoretically Bukkit.getPlayer() could return different instances on different invocations, thus it could theoretically return null on the second call, even if it didn't on the first. Fix: create a local variable and check on that
grtPlayerExact 😭
even better: only save the indices of items that are not null
easy fix, easy go
yeah that was way back in the day though
whats the max characters for chest inventory name?
wanted to spread, {Inventory name} {Page} for example
Ok, will try fudge it
its whatever mojang allows in the packet size
I've exceeded it once, but you need to be excessive
Hence the word practical smh
Its goofy
You should learn JUnit a bit better
Like for instance to use @BeforeEach and @BeforeAll
And then the test also is… well… lets say I wouldve written it differently
lmao
too much
blud goes through all that and still can't give variables more than 1 letter
@ivory sleet what do you think
and ofc all perks that were available before and more are still accessible, also the layer system and stuff all works with ease
I like the idea
But I hate the execution, the nested callback intention just asks for trouble almost lol
it's just one way of doing it
Callback hell is generally an anti pattern u wna avoid
Because of… well… I’m sure I dont need to even explain the reasons lol
yeah I know (from react lol), but I don't think it's that awful in the example above, and as said you can totally go a different way of building the inventory, you don't have to use callbacks if you don't want them
the only reason i implemented them was to make it "easier" to create inventories yk
like in one go with chained method calls on the builder
Yeah, I mean I’d advocate to have some more framework stuff around the population
Like InventoryPopulator.create().material(…).drawOutline(…);
Or sth yk
So I don’t have to reference storage 3 times in a single callback
I mean the way you do it is good on a base level because it allows expressiveness
But when you want to do basic things, it looks like your framework lacks the simplicity and straightforwardness regarding that
As the aforementioned example
mhn yeah I agree
it's quite complex since there's a lot to it
so it's great for complex inventories, but for really basic ones it's still a lot of effort
I'll have a look into this!
thanks for feedback, as always :3
yeah what I tried to say in essence
No worries, im happy u keep me updated, it looks very promising still
Yesterday (a few hours ago) I was working on my plugin, everything looked perfect, no errors. The command I made did indeed exist. But when I did it, it wouldn’t load the inventory up like it was meant to
No error message
Looked fine, just wouldn’t do it
Do any of u know what might of happend?
?nocode
It’s hard to answer a programming question without code
Oh no! You ran into a problem. But no worries, people are willing to help, but first they need to see your code. This is because otherwise, they would be providing help based on guesses instead of concrete knowledge. Whether it be a compile error, runtime error, or an unexpected output, I'm sure that if you were to provide code, you'd receive a quick solution.
Ahh I don’t currently have the code so I shall update you in the morning if that’s alright. Sorry for this!
Well, I have some of it but not all of it
( This is the bit I do have )
package me.tom.test.Listeners;
import org.bukkit.ChatColor;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
public class MenuListener implements Listener {
@EventHandler
public void onMenuClick(InventoryClickEvent e) {
if (e.getView().getTitle().equalsIgnoreCase(ChatColor.GRAY + "Land Shop")) {
// Check if the clicked slot is empty
if (e.getCurrentItem() == null || e.getCurrentItem().getType().isAir()) {
return;
}
// Cancel the event to prevent item movement
e.setCancelled(true);
}
}
}
basically similar to this huh
It probably comes down to your first statement, where you check for the inventory name from the view
yeah well most of it comes from failures
I got the right name and color
I’ve failed so many times… god knows how many just
you might wanna debug that exactly, to find out exactly where your code breaks
yeah fairs
thing is sometimes, especially when you build like bigger libraries, you have such a focus on providing the ability to create something with ease on a large scale (the final solution to the problem), but you completely forget about other applications
It did work untill the // cannsle event to prevent item movement was unreachable. So I fixed it and it broke
in this instance it was smaller inventories haha
yea lol
Failure? What do you mean, all my code works first time
haha
Bonk
So what do u thinks wrong with it?
U think I’ve just forgot to do somthing?
Maybe, I’ll check tmrw again
I overengineer stuff so much that writing a simple feature from scratch is faster than copying all the libs, initializing managers and hooking into it
It’s not my code that’s wrong
Tmrw I will be able to send all the code and hopefully somone can look over it and possibly point out a silly mistake
It’s the jvm that’s wrong
I'm trying to code a simple plugin for my 1.20.2 factions server but it's giving me this error
The package org.bukkit is not accessible
these are all the lines which have org.bukkit
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.entity.FallingBlock;
import org.bukkit.plugin.java.JavaPlugin;
not really sure if this is the right place to ask but figured I might aswell
You're not importing the jar correctly
I'm using eclipse*
Bootstrap Jar
The main spigot-1.18.jar is now a bootstrap jar which contains all libraries. You cannot directly depend on this jar. You should depend on Spigot/Spigot-API/target/spigot-api-1.18-R0.1-SNAPSHOT-shaded.jar, or the entire contents of the bundler directory from your server, or use a dependency manager such as Maven or Gradle to handle this automatically.
Please read the release notes for further information: https://www.spigotmc.org/threads/9-years-of-spigotmc-spigot-bungeecord-1-18-1-18-1-release.534760/#post-4305163
I'll check that, ty
what should I do instead?
Use maven or gradle
you can use the java system, but its just harder imho. Just go with maven
its in my opinion, by far easier than gradle and gets the job done especially if you're not doing anything crazy
is it best to just look up a yt tutorial for maven and such?
im new to this and dont have much of an idea what im supposed to do so I think that would be the best option
Am I right in understanding maven is better?
Alr 👍
I just looked back and I wanted to say the code that I did send was perfect in the sense of no errors at all.
And the rest of the code (I’ll send later today when I’m on me pc) has 0 errors but a few orange warning
Guys is it OK to throw exception
like fetchStatistics(UUID) throws Exception;
something like that
maven is easier to work with and on top of being easy to work with its very versatile. Gradle can be versatile too but it requires more work and can be more difficult to work with. Gradle's biggest advantage is faster compiling and this is because it is by default designed to use all resources available but you will only see this with super huge projects which 99% of all plugins will not come anywhere close to be considering a super large project. Maven by default is designed to be conservative with resources and is the primary reason most see it being slow, however you can just give it more resources to help speed it up.
so in all, its really down to preference for most things
How do other servers develop scoreboard sidebar with player information?
by using the scoreboard api? https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/scoreboard/Scoreboard.html
declaration: package: org.bukkit.scoreboard, interface: Scoreboard
ex) player's money , Online Player..
I've tried to make it, but I keep getting errors
-- test scoredboard --
Money:0 2
Money:1000 2
Online Player:2 1
Online Player:1 1
like this
would be helpful to send them
Do yk why luckperms designed it to throw exception
I can only see them throwing Exceptions in internal stuff
I'd always declare what it really throws though, fetchStatistic e.g. might throw IOException and NoSuchElementException for example
Yeah well
I currently do both rn lol
NoSuch... and IOExc
I'm just p sure gson has a unique exception for everything
should I just wrap it with an IOException
like
try {
...
} catch (Exception e) {throw new IOEx(e)}
does BukkitRunnable#runTaskLater blocks the thread?
No
ok ty
wait if it doesn't block the thread
why do we have Bukkit#runTaskLaterAsynchronously then
and wat i mean by thread is the plugin thread
cuz i wanna know if my code will make different tasks or will it wait for the task to run before creating one
public class EntitySpawnerUtils {
public void startSpawnerLogic() {
for (CustomEntity mob : getLoadedMobs().values()) {
if (mob.getSpawnLocation().getProperty().isEnabled()) {
long interval1 = mob.getSpawnLocation().getProperty().getMinInterval();
long interval2 = mob.getSpawnLocation().getProperty().getMaxInterval();
long higherInterval = Math.max(interval1, interval2);
long lowerInterval = Math.min(interval1, interval2);
long randomInterval = randomizer(higherInterval, lowerInterval);
EntitySpawnerTask mobSpawnerTask = new EntitySpawnerTask(mob);
// Not sure if this will block the thread and prevent the for loop from running correctly
mobSpawnerTask.runTaskLater(getPlugin(), randomInterval);
}
}
}
}
What plugin thread
my plugin thread
What
each plugin has its own thread provided right?
No
Whole server dies
declaration: package: org.bukkit.scheduler, class: BukkitRunnable
Normal runnables work with ticks, so that no thread is used
ah so this code wont be blocked by runtasklater?
cuz i wanna spawn multiple bukkit runnables
would this be a good approach to spawn a magma cube instead of an arrow with same velocity?
did you test it?
no, scheduling a task doesn't block, but tasks run synchronously once the scheduler gets to them
it might not be a good idea to schedule that many tasks, you might be better off sorting it into buckets for each random amount and then schedule one task for each bucket, processing all items at once in each tick
but probably not a major performance concern at small scale
it despawns instantly :/
one task for all wouldn't work
as each mob has its own spawner
are you blocking any entity spawn events?
no
does it die bc of damage? or just despawns?
xD
Did it fix
Breh
im so confused
i just spent like a entire hour trying to get maven done
no worky
what am i supposed to do
whats not working ? any error message. maybe send us your .pom
i just dont know whats going on
i think I might want to just uninstall it and try again
is there any some sort of entity collide event?
alright I deleted it and I'll just try again
nah I think you have to use a schedueler which checks if two entities are too close to each other
is there a good guide on how to properly install maven?
what ide do you use
Eclipse
💀
indeed
why you do mc plugins if you dont know java
yeah thats fine, trust me no one, NO ONE, have I every seen anyone use eclipse at work for java ^^
im just trying to setup a server with friends and me so
trying to figure out what the hell im doing
mhm
I want one that can add sand stacking for factions
i dont wanna pay like 20 bucks for a cannon jar
when does LivingEntity#getAttribute return null
I think when a given attribute does not exists for the entity
e.g. animal and attack damage attribute
is there a list of it
what do you mean
of mobs that doesn't have those
I guess not
had a ss to go with it but ill just explain
does anyone know what exactly EntityChangeBlockEvent do
I'm installing intellji and it has "update path variable" and "create associations"
should i do a .java association and add a bin folder to the path
@faint aspen
You can ig
any reason to?
Not realyl important tho
ah alright
do either
I'm installing it, what do I do to install maven now
perfect
For beginners, I would recommend the "Minecraft Development" plugin in intellij
what's the best way to send an action bar to the player every tick?
create one scheduler for everyone and execute code for everyone? or does everyone have their own?
Or maybe it’s possible without them?
I have a (probably very simple) question.
I'm learning how to use inheritance properly, and I'm trying to make some repeatable code for a custom YAML file.
I have to have 4 default methods that need to be implemented when I extend this class with the super class. How would I go about doing that?
every tick?
well it turns out like this
I can't see how there is anything you would need to update in the action bar every tick
unless it's some colour animation of text or something
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
public class Menu extends CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
Player player = (Player) sender;
Inventory inventory = Bukkit.createInventory(player, 9, ChatColor.GRAY + "Land Shop");
ItemStack item = new ItemStack(Material.GRAY_STAINED_GLASS_PANE, 1);
inventory.addItem(item);
ItemStack Nothing = new ItemStack(Material.GRAY_STAINED_GLASS_PANE, 1);
ItemMeta NothingMeta = Nothing.getItemMeta();
NothingMeta.setDisplayName(" ");
NothingMeta.addEnchant(Enchantment.DURABILITY, 1, true);
Nothing.setItemMeta(NothingMeta);
// rest of the slots
inventory.setItem(1, Nothing);
inventory.setItem(2, Nothing);
inventory.setItem(3, Nothing);
inventory.setItem(4, Nothing);
inventory.setItem(5, Nothing);
inventory.setItem(6, Nothing);
inventory.setItem(7, Nothing);
inventory.setItem(8, Nothing);
return false;
}
} ```
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
public class MenuListener implements Listener {
@EventHandler
public void onMenuClick(InventoryClickEvent e) {
if (e.getView().getTitle().equalsIgnoreCase(ChatColor.GRAY + "Land Shop")) {
// Check if the clicked slot is empty
if (e.getCurrentItem() == null || e.getCurrentItem().getType().isAir()) {
return;
}
// Cancel the event to prevent item movement
e.setCancelled(true);
}
}
} ```
this is my plugin i made, there is no error message in IntelliJ or for the Minecraft server console and the rest of the plugins runs fine but it doesn't work.
( the 2 spaces before the first imput on both of those peaces of code doeant atualy have a space infront of it, idk y it did that when i copy and pasted it
What does not work ?
The menu
I registered the command
return true instead of false in the end of the command
I’ll try again with this change
If it does not work provide the code which shows how you registered your cmd and maybe your plugin.yml
Am I blind or you never actually open the inventory
is this good antiafk detection?
Player player = Bukkit.getPlayer(profile.getUuid());
boolean moving = player.getVelocity().lengthSquared() > 0.0001; // Adjust the threshold as needed
if (!moving) {
Location currentLocation = player.getLocation();
Location lastLocation = playerLocations.get(player.getUniqueId());
return lastLocation != null && !hasSignificantlyMoved(lastLocation, currentLocation);
}
return false;
}
private boolean hasSignificantlyMoved(Location loc1, Location loc2) {
return !loc1.getWorld().equals(loc2.getWorld()) || loc1.distanceSquared(loc2) > 0.25;
}```
ik it's probably flawed, it's basic integration
you could just use the move event
because tbh idk how to exactly make it work so it detects if player moves without moving his mouse (cursor)
also it doesn't account for someone using an inventory
without using packets or something
probably best that you do it based on time
It didn’t work.
move event is unoptimized as sh1t
explain?
i mean it's very bad to be used often, it can cause high cpu usage in my experience
@sterile sapphire
the event is thrown regardless if you decide to do something with it or not
yeah true, I'll add that, but then people can fool the system by opening inventories
yk afk bots
you could do it based on time, and not sure why an afk bot is an issue
if the main issue is because of monster spawning then you should just detect someone near a spawner for long period of time and just stop spawning mobs
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
public class Menu extends CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
Player player = (Player) sender;
Inventory inventory = Bukkit.createInventory(player, 9, ChatColor.GRAY + "Land Shop");
ItemStack item = new ItemStack(Material.GRAY_STAINED_GLASS_PANE, 1);
inventory.addItem(item);
ItemStack Nothing = new ItemStack(Material.GRAY_STAINED_GLASS_PANE, 1);
ItemMeta NothingMeta = Nothing.getItemMeta();
NothingMeta.setDisplayName(" ");
NothingMeta.addEnchant(Enchantment.DURABILITY, 1, true);
Nothing.setItemMeta(NothingMeta);
// rest of the slots
inventory.setItem(1, Nothing);
inventory.setItem(2, Nothing);
inventory.setItem(3, Nothing);
inventory.setItem(4, Nothing);
inventory.setItem(5, Nothing);
inventory.setItem(6, Nothing);
inventory.setItem(7, Nothing);
inventory.setItem(8, Nothing);
player.openInventory(inventory);
return true;
}
}```
the more people connected to your server the more likely people are to join it, but if you are just going to combat them seems you don't want players
there we go
I never had an issue with afk'ing players though, even with mob farms if they were allowed to begin with
because it doesn't matter if they are there or not since anyone can leave their client open and connected, don't even need a bot for it
Should I use .equals or just == to compare strings? (player usernames)
also, not all bots are used for the purpose of afking at a farm, some of them are for just so they could chat
which I see harmless unless they are spamming, which is easy to deal with itself
.equals() for strings. One compares object equality the other compares content equality. == is for object equality while .equal is for content equality
ok epic thx
how do u put someones head in a inv, so no matter who opens it, it will always show your head
Get the item meta from the item, then get the skull meta from the itemmeta, and set the owner
LIke this
SkullMeta skullMeta = (SkullMeta) bum.getItemMeta();
skullMeta.setOwningPlayer(**insert offline player object here, probably of the command executor**);
bum.setItemMeta(skullMeta);```
online player object might work too, just I dont use it
OfflinePlayer extends Player soo
Or opposite
Way
Yeah I think it was P extends OP
I’m confused
If there offline I don’t need it
Because the inventory is gonna be diffrent for everyone
well replace with online player then
other way around
player extends offlineplayer
from offlineplayer they can check if they are online
Makes sense
if they are not online they can stop
tempProfile
It is the asynchronously fetched profile.
profile at that point will still always be null
what's tempProfile?
?paste
Ok, do that then
Hey ! Idk why but i have this error in my console, and its not while doing smth special. Any idea?
https://paste.md-5.net/zisunisale.bash
but like is this the best way to go on about it
def not
ok thanks
Non [a-z0-9/._-] character in path of location: minecraft:Slime
Your 'S' is capital and not within the defined character set (look left)
https://paste.md-5.net/katejotabu.xml what is this error?
wdym? in my code? i dont have anything slime related in my code...
Multiverse-Core wasnt found. Make sure to add their repository to your pom in addition to their dependency
We use a custom map tho, can it be related to this?
Yeah this could very well be a problem with the custom map.
The server tries to load an entity with an invalid resource key.
how could we fix it?
the map is just a big plain biome with a few volcanos for the moment
Oh
Was it built with mods?
made using World Painter tho
Each of your cases should have its own method.
That shouldnt be a problem as long as you use the latest version.
we are using it normally
k
hey
why is inventoryclickevent cancelled even though I dont cancel it anywhere
i tried setting it to false but regardless its still cancelled
i only have 1 plugin installed
Another listener can still cancel the event after yours.
Did you debug your code and made sure your if condition is going through?
yea and its not going after 3. it finishes at line 51
another listener?
Well then your if condition isnt true and you dont uncancel the event 🤷
yeah i dont want it to be cancelled and yet it is
I do return; if item material names arent the same
which they're not
event shouldnt be cancelled
I dont cancel it
I just return
return should exit out of function right?
Yes
Well, then another listener method cancels it
Add a monitor listener to make sure
I see it now yeah I'll change it
I basically have a blocks gui and homes gui, for each i have a separate click listener
why do you bother setting it uncancelled if you never bother to check if it was cancelled to begin with?
attempting to debug by the looks of it
also you could just set in the annotation to ignore cancelled as well
frostalf you're a little late to the party i've just fixed it 😂
You should 100% change that as soon as you have more experience.
I can't, each gui has different configuration preset and different amount of slots
as well as items, contents blaaablabla
that's bad practice and could result in unreadable and unclear code
lol
Yep. You can have one listener with a single line and support hundreds of inventories.
Just change it when you have a bit more experience.
where inventories are somewhat the same, I do one listener, but in this case I do a separate listener just for the sake of understanding
this is where abstraction helps
I've never used abstraction, will need to learn it someday
Here is the Listener for the GUI guide i wrote.
Its one listener that works with an infinite amount of inventories.
that's basically a wrapper for gui listener
i'm talking about an actual InventoryClickEvent I needed for each gui
No its a proxy, not a wrapper
You can propagate this event to as many GUIs as you want, without registering all of them as a listener.
If you want to learn how:
https://www.spigotmc.org/threads/a-modern-approach-to-inventory-guis.594005/#post-4553427
the correct?
I've seen that
thanks for the help though
Dont use Pair. Its messy. Use a private record if you must not create a proper class.
I'll consider using abstraction in the future
I don't understand, are you telling me that I have to create it myself?
Im saying that you should create a proper class like PendingDuelInvitation instead.
ok
i try
so can i just check if an inventory is null and if its null i can save null and not null x36 itemstacks
yeah ik, but couldnt i just put null in the file like this:
inventory: null
Instead of
Inventory:
- null
- null
...
Myeah, and make sure that you save a single null value to erase the previous inventory.
doing that removes inventory from the file
^ Which is nice 🙂
so im doing everything rihgt?
if(player.getInventory().isEmpty()) {
storage.set(uuid + "." + world + "." + "buildinventory", null);
} else {
storage.set(uuid + "." + world + "." + "buildinventory", player.getInventory().getContents());
}```
So every time when i check wheater there is an entry or when i change an entry im putting this
Entity damager = (Entity) p.getLastDamageCause().getEntity();
why it gave null?
Because the last damage cause can be null
then how can i check the damager?
A bit more information would be nice 🙂
if its null then there is no damager, cant there be other damage like fall damage etc..
but he get hitted by a player
i want to check when a player get hitted by another player do something
public boolean ruba(EntityDamageEvent e) {
Entity p = e.getEntity();
Entity damager = (Entity) p.().getEntity();
if (damager instanceof Player) {
Player whod = (Player) damager;
if (whod.getItemInHand().getType() == Material.DIAMOND_SWORD) {
if (p instanceof Player) {
Player player = (Player) p;
Inventory inventory = player.getInventory();
Material material = Material.BOOK;
if (inventory.contains(material)) {
p.sendMessage("TI hanno fottuto il portafoglio!");
damager.sendMessage("Ti sei Fottuto un portafoglio!");
}
}
}
}
return false;
}
}```
Then listen to the EntityDamageByEntityEvent and get the damager.
When triggering this
if(player.getInventory().isEmpty()) {
storage.set(uuid + "." + world + "." + "normalinventory", null);
Bukkit.broadcastMessage("bool true, set norm inv to null");
} else {
storage.set(uuid + "." + world + "." + "normalinventory", player.getInventory().getContents());
Bukkit.broadcastMessage("bool true, set norm inv to playerinv");
}```
It says set buildinv to playerinv so it should save it, when looking into the file i can confirm: It saved the items. But this:
```java
List<?> normalList = storage.getList(uuid + "." + world + "." + "normalinventory");```
doesnt get these items it says the normalList is null. Why the frick is that
you print the Map to check what are currently saved?
should i print the normalinventory after saving it?
i mean for debug and check if is saved or any if you say that return null
well i tried this:
storage.set(uuid + "." + world + "." + "buildinventory", player.getInventory().getContents());
Bukkit.getServer().getLogger().info(storage.getList(uuid + "." + world + "." + "buildinventory").toString());
Bukkit.broadcastMessage("bool true, set build inv to playerinv");```
But now its getting an error when executing the command
```java
Caused by: java.lang.NullPointerException: Cannot invoke "java.util.List.toString()" because the return value of "org.bukkit.configuration.file.YamlConfiguration.getList(String)" is null
at mondlw.laserserver.laserservermanager.utils.BuildUtils.setBuildMode(Bu```
So i see its not being saved correctly
because its returning null
Yeah because its not saved at all. Meaning the inventory was empty, resulting in the config entry being removed and the config returning null when asked for that value.
but i have something in my inventory when executing the command
Debug your conditional statements then
and its actually being saved right here
- ==: org.bukkit.inventory.ItemStack
v: 3105
type: BIRCH_STAIRS
amount: 64
well there isnt much to debug
its this
if(!storage.contains(uuid + "." + world)) {
Checking wheather there is an entry
if(player.getInventory().isEmpty()) {
Checking if the inventory is null and deciding wheather to put inventory or null in file
if(buildList != null && !buildList.isEmpty()) {
checking weather its null or empty in file
?mappings
Compare different mappings with this website: https://mappings.cephx.dev
how to add effects to everyone in certain radius from a player
ok i found getNearbyEntitiesByType
anyone here use mainly a sql or mongo db but have a failsafe that goes flatfile if connections fail?
You can use SQLite as failsafe
True
then periodically check if the main connections back up and import sqlite data?
or do you just close the pl down and save to sqlite?
You can prob save the data async as its being mutated and changed
That way u dont need to buffer a synchronization of the data
Ok thank you, will take a look
I made a damagetag by boarding TextDisplay on the entity, but when I tested it on mythic mob,TextDisplay was dismounted.
Cancelling EntityDismountEvent set to EventPriority=MONITOR does not work as desired.
how can i resolve this?
Is there any way I can get the default suspicious stews that are already in minecraft or do I have to create them myself using SuspiciousStewMeta?
what is the spigot alternative for the forge Start/Stop Tracking event?
declaration: package: org.bukkit.event.entity, class: EntityTargetEvent
nah
what is the forge start stop tracking event?
paper events iirc
I mean, what does it do?
Actually no i lied
no events under that name
there is track and untrack events
called when the server starts the player on tracking an entity in the world (e.g. initial packet sync and then updates via packets)
ah
how can i use / check a public string in a Listener?
String dir = "";
float y = playerSelf.getLocation().getYaw();
if( y < 0 ){y += 360;}
y %= 360;
int i = (int)((y+8) / 22.5);
if(i == 0){dir = "west";}
else if(i == 1){dir = "north";}
else if(i == 2){dir = "east";}
else if(i == 3){dir = "south";}
else {dir = "west";}
return dir;
}```
i make that Public String for get the direction of where the player is looking and i want apply it on a `BlockPlaceEvent` Event how can i do that?
?learnjava
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.
Just a question, how do i return the item in the offhand of a player?
player.getInventory().getOffHand or something like that
player.getInventory().getItemInOffHand()
ooog thx
i tried doing e.getPlayer().getInventory().getItemInOffHand().setType(Material.BUCKET); but it doesnt seem to work
it probably returns a mutable copy
set the slot
player.getInventory().setItem(45, new ItemStack(Material.BUCKET))
or simply e.getPlayer().getInventory().setItemInOffHand(new ItemStack(Material.BUCKET));?
can it work?
Would this change slot 45 to a bucket from what it was before?
So it would?
Yes, it would set the ItemStack in that slot to a bucket
Probaby better to use the fixed setItemInOffhand
Def
In case the slot number changes one day :p
Ye magic values evil
can i cancel chorus fruit teleport if it has specified pdc tag?
PlayerItemConsumeEvent should do the trick
or incase minecraft randomly decides to add more inventory spaces
But if the player is in another world, does it leave them in the "world" or does it leave them in the world the player is in?
??
Why dont you get the world from the player?
Getting a world by name is very risky.
is an example
i dont use it
i only want understand if it drop them in the "world" or does it drop them in the world the player is in?
I bet it will throw an exception if the location world doesnt match the invoking world.
At the very least the item would appear in the "world" but at the x, y, z position of the players location.
ok, so you will need to do player.getloacation.getworld()...
It will drop the item in the "world" at the x, y, z of the location.
player.getWorld() directly
ok
who wanna make a server framework in rust
Isnt there already one with a Bevy backbone?
is it okay to catch (Exception) ?
Only in very few cases.
im working with a database that's abstracted
and I want every exception to be informed for the api users
I was thinking abt just making a bunch of custom exceptions
like
DatabaseException
DatabaseArgumentException stuff like that
or IO
Exceptions will be passed through the call stack. Idk why you would want to catch them early.
well i dont want to catch them later as of now
Hm?
like
this forexample
@Override
public void update(@NotNull Class<? extends T> configClass) throws IOException {
Preconditions.checkState(this.configMap.containsKey(configClass), "configClass is not registered.");
Path pathToConfig = this.configFolderPath.resolve(this.getConfigClassName(configClass) + ".json");
T updatedConfig = this.gson.fromJson(Files.readString(pathToConfig), configClass);
this.configMap.put(configClass, updatedConfig);
}
there's a ton of exceptions that can be thrown and they dont all fall under IOException\
InvalidPathException
JsonParseException
wtf
what's an Error lol
never seen that before
an Error is usually an unrecoverable error that shouldn't be caught
I mean you basically pass through every exception that you want the caller to handle.
But letting him handle a very generalized exception is very discouraged.
That is so far outside of the scope of an application... Catching this error sounds very questionable.
uh
so what if
hm
what if I make my custom exceptions
instead
then in the docs for the interface, I just justify what exceptions the method can only throw
Would it make sense to catch it, clean up the app (and stop the main loop if it exists) and show some screen/print some statement about it

did you know that the Minecraft client has a 10 MB (I think?) buffer that it frees when an OOME is thrown so it can show you the "your system ran out of memory" screen?
Funnily enough, last time I ran out of mem it just crashed
not all OOMEs are the same tho
Hmm, true
no more metaspace
Isnt that just because the user doesnt have an interface for the application?
It wouldnt make much sense for a headless application.
so should I make my own exceptions that wrap all the impl exceptions in my case
Why not simply propagate the exceptions?
well it could also just return the oom exit code and let the launcher show it
is it possible to achieve custom ender dragon movement via EnderDragon#setPassanger (to avoid NMS)
what does that mean
like log it?
Every exception that needs to be handled on compile time is simply appended to the method
public void someMethod() throws ExceptionA, ExceptionB {
}
Exceptions that dont need to be handled are just left alone.
Wouldn’t you have to be holding it for that to happen. But what if you was not holding anything
Or am I just confused
You don't need to be holding it
How would it know what slot to put it in tho if u didn’t give a slot number?
But isn’t off hand your in game hand? And where talking about in an inventory?
not sure what the confusion is
i am confused because of the confusion
main hand and off hand refer to inventory slots since they don't disappear when equipped
the api just makes it easier to refer to common slots that are used
What I’m confused about it if you use of hand to change the bucket won’t it change what in the hand not the inv and if it did change the inv you don’t tell it what slot to use
items in offhand don't disappear out of the inventory when equipped
same goes with main hand
since they are in the inventory, that means if you change it in the inventory, which off hand and main hand refer to, it will change
PlayerInventory and Inventory is different
Chest Inventory does not have the function "setItemInOffhand" etc
Alr, thanks
these are the function that are added in PlayerInventory
the methods not included in the list are from "Inventory"
Alr 👍
Also this would still work right? Coz I removed a bit but not at my pc to see
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
public class Menu extends CommandExecutor {
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
Player player = (Player) sender;
Inventory inventory = Bukkit.createInventory(player, 9, ChatColor.GRAY + "Land Shop");
ItemStack Nothing = new ItemStack(Material.GRAY_STAINED_GLASS_PANE, 1);
ItemMeta NothingMeta = Nothing.getItemMeta();
NothingMeta.setDisplayName(" ");
NothingMeta.addEnchant(Enchantment.DURABILITY, 1, true);
Nothing.setItemMeta(NothingMeta);
// rest of the slots
inventory.setItem(1, Nothing);
inventory.setItem(2, Nothing);
inventory.setItem(3, Nothing);
inventory.setItem(4, Nothing);
inventory.setItem(5, Nothing);
inventory.setItem(6, Nothing);
inventory.setItem(7, Nothing);
inventory.setItem(8, Nothing);
player.openInventory(inventory);
return true;
}
}```
why are you filling only 8 slots and not all 9
also you didnt check if the sender is a playedr
it could be console
Ig
I would add slot 0 but the only reason it wasn’t there was coz I removed it
ItemStack item = new ItemStack(Material.GRAY_STAINED_GLASS_PANE, 1);
inventory.addItem(item);
```
How about you create a method which fills all empty slots in an inventory with a single item?
public void fillEmpty(Inventory inventory, ItemStack filler) {
}
I’m new to this all and am not sure on how to do this
Still learning and getting my head around some things
you are spoonfeeding too much tbh
This is an empty method body... there is no actual logic being fed.
its still spoonfeeding
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.
Ik I am learning
how will you learn if you dont take on a challenge?
I am trying to challenge myself
But trying to also not over do myself, I’m only just learning
When I get used to it I’ll do harder stuff
Showing a concept without implementation is not spoon feeding.
If i explain someone what strong encapsulation is, im introducing abstract information.
Same goes for extracting functionality from a codeblock into a method body. Its an abstract concept.
There is no actual logic being fed.
Or in shot: I disagree
i respect your disagreement
I respect the help 😅
people are free to help how they see fit
Hi,
I want to write two independent plugins.
The first plugin will handle player login and registration, while the
second plugin will record player statistics.
Both plugins will use JDBC to save data to a MySQL database.
Should each plugin contain its own JDBC dependency and database logic, or should I create a separate database plugin to be used by both plugins?
Can someone explain the best practice and how to do it?
why not make it just one plugin?
You could create a monorepo where you have multiple projects that all depend on one common library (your database logic) that you simply shade into both of your plugins, eliminating the need for a third
Or you just put everything into one plugin
Could be a microservice architecture
this makes no sense
given the context anyways
That would eliminate the need to ask for this, so it probably isn't
This is just an example, the point is that I would like to use the database connection, query methods in other plugins without repeating the same code over and over again
well you're right I just wanted to point out a case where it would make sense
It is common practice for public plugins to have a core library which needs to be installed alongside the actual plugins.
This librarie handles common functionality like GUIs, Holograms and Database gateways. This way you dont have to
shade the dependencies into each plugin but only your library.
Spigots runtime dependency loading system made loading shared dependencies a bit more viable.
If you want to use the same connection throughout different plugins you have to opt for using another plugin as a centralized hub for your database
If you are okay with multiple connections, use a monorepo type style (basically what @lost matrix described)
if they are running their own network this is highly advisable
Should I create a plugin that contains methods such as query, update, and connect, etc and then use it as a dependency in another plugin?
(or just use an ORM lol)
ideally you would make both implementation and api for the database plugin
you would make the api in such a way you can just fetch what you are wanting, the db plugin then takes that and creates the necessary query
you can make some methods where its some default queries, but if you intend to query multiple DB's, then it could get a bit more complex
hey, countdown() still gets called even if its not 0 right? if statement is ran regardless of the result?
If your target audience for your Plugins is a large server network, I'd recommend using an ORM instead of raw SQL queries
because you have to switch between DB's and in the context of existing connections the DB switch persists until you switch it again
we need more context to determine that
we need to know the conditions of the countdown call
Before using ORM, I want to understand how it works in its raw form. Thank you for your help. I will try to implement your advices 😄
No worries, good luck 🤞
Is this function still working? Bukkit.getUnsafe().loadAdvancement();
?paste
code: https://paste.md-5.net/rarujuleku.java
exception: https://paste.md-5.net/vehefafobe.pl
how can I fix that?
Hi , how to close permission for /plugins on my plugin ? i just need a name of this permission
in my code i cast org.apache.logging.log4j.core.Logger to org.apache.logging.log4j.core.Logger
at least my IDE says that
its kotlin
and it does pretty much the same thing that i do
i saw that
even this doesn't help:
org.apache.logging.log4j.core.Logger log = (org.apache.logging.log4j.core.Logger) LogManager.getRootLogger();
same exception
you have shaded Log4J or something and relocated it
yes
in that case you also have to cast it to the shaded version
cast it to shaded.org.apache.logging.log4j.core.Logger
Why when ever I package my plugin it makes a shadow . Jar file?
it doesn't see the shaded package
i cant
compilation error
why do you shade log4j in the first place?
cause otherwise my plugin conflicts with other plugins that are using log4j
ClassNotFoundException
because you're relocating it
just set the scope to provided and use the logger provided by spigot
if do like so, my plugin will fail to start
it will not find a class
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.19.0</version> <!-- This is the version Spigot 1.20.1 uses -->
<scope>provided</scope>
</dependency>
just add this to the top of your dependencies and do not relocate any log4j stuff
I asked here before but I forgot to check and lost it now, is there some alternative to the StartTrackingEvent from forge in spigot?
probably not
yeah, it works with that, but how can I manage the conflict then?
which conflict? there shouldn't be any if you just use the version provided by spigot
one sec, maybe i will manage to find the exception
and send it
Hmm, I wonder if there is some packet that would indicate the start or end of tracking
Well yes, the add entity packet
Hmm
well, i cant find it, will stick to this solution until someone lets me know about any conflicts, it is anyway better than to keep compatibility and have bugs
ty
There shouldnt be any conflict, spigot should be the only one which shades log4j
Is it possible to cancel the sign editing when pressing on a sign so that it will not open?
can someone explain what this does when is type code in a class? I dont know what to google, i dont know what it is.
//code
}```
cancel PlayerInteractEvent
itll run the code in there when the class gets loaded iirc
Java allows you to use the so called “init blocks”. You can declare static and instance init blocks. The static init blocks will run exactly once, when the ClassLoader loads the class that declares it, and the instance init blocks run everytime you construct a new object, after the actual constructor ran. The general order...
so on plugin start?
no
best off reading this yea
import com.sumeru.party.SumeruParty;
import com.sumeru.party.economy.Vault;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Color;
import org.bukkit.Statistic;
import org.bukkit.entity.Player;
import org.bukkit.scoreboard.*;
public class PartyScoreboard {
static Scoreboard board;
public static void setupScoreboard() {
ScoreboardManager manager = Bukkit.getScoreboardManager();
for (String pl : SumeruParty.players) {
Player p = Bukkit.getPlayerExact(pl);
board = manager.getNewScoreboard();
Objective objective = board.registerNewObjective("Party", "dummy");
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
updateScoreboard();
p.setScoreboard(board);
}
}
public static void updateScoreboard() {
for (String pl : SumeruParty.players) {
Player p = Bukkit.getPlayerExact(pl);
String kills = "§bKills§8: §7" + p.getStatistic(Statistic.PLAYER_KILLS);
String deaths = "§bDeaths§8: §7" + p.getStatistic(Statistic.DEATHS);
String spacer = "§7§m-------------------";
Objective objective = board.getObjective("Party");
............
}
}
}
please help it throws a nullpointeexception in this line Objective objective = board.getObjective("Party"); and new BukkitRunnable() { public void run() { PartyScoreboard.updateScoreboard(); } }.runTaskTimer(plugin, 0L, 20L);
board is null
please help me identify the problem
he already identified your problem
but why board == null
you probably call updateScoreboard() before you call setupScoreboard
other than that this is an interesting piece of work
you set the global value for every player
then when updating you use that global variable?
this makes very little sense
no i have SumeruParty.gameStarted = true; PartyScoreboard.setupScoreboard(); and condition if(gameStarted) {PartyScoreboard.updateScoreboard();}
really Objective objective = p.getScoreboard().getObjective("Party");?
This is, as already said, an initiation block, the code within that block is executed when the class is loaded. It is primarily used to initialize static variables, you too can do custom initialization and stuff in there
and? so what's the problem with replacing with
Objective objective = p.getScoreboard().getObjective("Party");
thanks
but
right now for every player u setup scorebord u also update for all players
since thats in the for loop
Yes thanks for pointing this out
and once its loaded its loaded forever?
until plugin is disabled?
now objective.getScore(spacer).setScore(15); throws NPE
no disabling the plugin wont necessarily unload the class
how long is it loaded
yes
when the jvm e.g. ur server shuts down or when its defining class loader is reclaimed by the garbage collector
so this can basically be used as an enum, just different?
more or less, yeah
spigot even does so
declaration: package: org.bukkit.enchantments, class: Enchantment
here
here's another example for when a static init block makes sense https://github.com/mfnalex/CustomBlockData/blob/master/src/main/java/com/jeff_media/customblockdata/CustomBlockData.java#L115
yo my boyfriend joined the chat
Is there a better way of adding textures onto player heads instead of using skullmeta?
no
Oh
NMS ig
how's that better though
but whats with the API hate though
just use SkullMeta
I get ItemMeta needs a rewrite but thats internal not API :P
all the cool kids love cloning /s
this is the proper way on 1.18.1+ to use base64 / url skins https://blog.jeff-media.com/creating-custom-heads-in-spigot-1-18-1/
Spigot 1.18.1 added the new PlayerProfiles class, which finally allows us to use custom heads without needing any reflection! You can obtain them as normal items, or actually place them down into the world. I’ll show you how both works: Creating a new PlayerProfile First, we gotta create a new PlayerProfile object. To do so,...
I'm going to clone you if you don't shut your trap
lynx is a trap confirmed
Is that a promise 
uwu

😨
I presume that's not using reflection?
correct
Great, thanks
well any exception breaks the entire method so all exceptions need to be handled
No exception needs to be handled unless the compiler demands it.
You logic would result in every method having to handle all exceptions because they break the method.
How should I recover from a json parse exception
Cause it sounds like an input exception
Not all exceptions are fully recoverable
But you can consider to fallback to some default values/ try to load it again, or just report that the data failed to load
Should that be my service's job or the api user's job to report
As a service you should try to tell the api consumer when the service cannot deliver as expected
You are writing a library so you have two options:
- Let the lib user recover
- Catch the exception, and return null
is there a way to return the player that clicked in the inventory?
getWhoClicked() then if it's instanceof Player, cast it to Player
?jd-s
declaration: package: org.bukkit.event.inventory, class: InventoryInteractEvent
HumanEntity can be cast to player without worries
unless you want to enable the ability for NPC's to interact with your inventory
Ok thx !
I'd rather check instanceof, another plugin might create a HumanEntity that isn't a Player
ok i will
Oh and btw, is there a listener for when a player put on/off a piece of armor?
Has this ever happened in the history of spigot? 😅
i don't know but blindly casting is still not very smart
Thx !
No doubt
Ok I'll just return null lol
I would 100% pass the exception through. 🙂
public static ChatColor of(Color color)
{
return of( "#" + String.format( "%08x", color.getRGB() ).substring( 2 ) );
}
Why MD 🥲
Yeah propagate it is usually quite reasonable
Why would i handle an exception for data i have no business with
PR time
well it can at times be nice to propagate it and wrap it around with a more meaningfully named one but i agree
I ran a JMH test on it just to see invoking the constructor directly instead of doing useless string fuckery turns out to be around 7.5x faster give or take for inconsistencies
this is using MethodHandles ofc
well remember it also runs it through this method too
public static ChatColor of(String string)
{
Preconditions.checkArgument( string != null, "string cannot be null" );
if ( string.startsWith( "#" ) && string.length() == 7 )
{
int rgb;
try
{
rgb = Integer.parseInt( string.substring( 1 ), 16 );
} catch ( NumberFormatException ex )
{
throw new IllegalArgumentException( "Illegal hex string " + string );
}
StringBuilder magic = new StringBuilder( COLOR_CHAR + "x" );
for ( char c : string.substring( 1 ).toCharArray() )
{
magic.append( COLOR_CHAR ).append( c );
}
return new ChatColor( string, magic.toString(), rgb );
}
ChatColor defined = BY_NAME.get( string.toUpperCase( Locale.ROOT ) );
if ( defined != null )
{
return defined;
}
throw new IllegalArgumentException( "Could not parse ChatColor " + string );
}

my guess this is for legacy chat but its not needed when dealing with components
completely uneeded in my component parser so I just am doing invokeExact 💪
Yeah method handles can be so nicee
I don't like that you need to try catch them every time, but 🤷♂️
static {
CHAT_COLOR_CONSTRUCTOR = ReflectionUtils.getConstructor(ChatColor.class, new Class<?>[]{String.class, String.class, int.class});
}
public static ChatColor create(@NotNull final Color color) {
String string = color.toString();
try {
return (ChatColor) CHAT_COLOR_CONSTRUCTOR.invokeExact(string, string, color.getRGB());
} catch (Throwable e) {
throw new IllegalArgumentException(e);
}
}```
Oof catching throwable
🤷♂️ idk what else to do since invoke throws Throwable
yeah well
the other option is to literally just propogate it into my parser
moment
which is equally as well you have to catch Throwable
Its a bit stupid because its just if the underlying method propagates an exception @river oracle
you end up going full circle
but yeah, I just think its oof on javas end altho it’s understandable but still
yup
believe me catching Throwable hurts the soul
my ideal world 🥲
public static ChatColor create(@NotNull final Color color) {
String string = color.toString();
return (ChatColor) CHAT_COLOR_CONSTRUCTOR.invokeExact(string, string, color.getRGB());
}```
create your own ChatColor

not realistic I'd have to create my own component system
that'd be redundant
.... paper ... xD
yea
my platform of choice is spigot not paper
yea
If I send particle packets to a player, I assume only that player can see those particles right?
Adventure support all platforms
Yeah.
Is there an event that is called when the dragon blows up?
I thought it would be EntityDeathEvent, but the blow up effect plays after the dragon is killed
PacketContainer packet = HeeseTroll.protocolManager.createPacket(PacketType.Play.Server.WORLD_PARTICLES);
packet.getIntegers().write(0, particleId);
packet.getFloat().write(0, (float) location.getX());
packet.getFloat().write(1, (float) location.getY());
packet.getFloat().write(2, (float) location.getZ());
packet.getFloat().write(3, 0.3f); // offsetX
packet.getFloat().write(4, 0.3f); // offsetY
packet.getFloat().write(5, 0.3f); // offsetZ
packet.getFloat().write(6, 0.1f); // speed
packet.getIntegers().write(1, 50); // count
try {
HeeseTroll.protocolManager.sendServerPacket(player, packet);
} catch (Exception e) {
e.printStackTrace();
}
}``` Ok I keep getting nullpointerexceptions here, anyone know where I messed up? (specifically at the protocolManager.sendServerPacket)
```sendCustomParticlePacket(target, 101, target.getLocation());```
Use the API
You don't need packets and protocol lib to send particles
why protocollib o0
A particle that only the player can see
You can use the API for that
there's literalls 10 methods for that
declaration: package: org.bukkit.entity, interface: Player
I dont see a player selection though anywhere
How could I send a particle to a specific player?
because it's an instance method on the Player class?
click the javadoc link
oh so player.spawnParticle and only the player can see that particle?
yes
epic thx
np
ScoreboardManager manager = Bukkit.getScoreboardManager();
for (String pl : SumeruParty.players) {
Player p = Bukkit.getPlayerExact(pl);
Scoreboard board = manager.getNewScoreboard();
Objective objective = board.registerNewObjective("Party", "dummy");
objective.setDisplaySlot(DisplaySlot.SIDEBAR);
p.setScoreboard(board);
}
}
public static void updateScoreboard() {
for (String pl : SumeruParty.players) {
Player p = Bukkit.getPlayerExact(pl);
String kills = "§bKills§8: §7" + p.getStatistic(Statistic.PLAYER_KILLS);
String deaths = "§bDeaths§8: §7" + p.getStatistic(Statistic.DEATHS);
String spacer = "§7§m-------------------";
Objective objective = p.getScoreboard().getObjective("Party");
objective.getScore(spacer).setScore(15);
objective.getScore(kills).setScore(14);
objective.getScore(deaths).setScore(13);
objective.getScore(spacer).setScore(12);```please help ``` objective.getScore(spacer).setScore(15);``` throws NPE
did you run setup scoreboard
yes
always
no
and where do you run setup scoreboard
before
i have condition SumeruParty.gameStarted = true; PartyScoreboard.setupScoreboard(); and ```new BukkitRunnable() {
public void run() {
if (gameStarted) {
PartyScoreboard.updateScoreboard();
}
}
}.runTaskTimer(plugin, 0L, 20L);```
i see the problem
i have SumeruParty.players.add(player.getName()); after setupScoreboard
sorry
Hey guys. I'm working on a plugin that uses mysql databases (2 actually). Plugin works & was tested on multiple servers with no issues but just seems to crash after a while for this one specific server I'm working with. Tried the plugin on another server running on the same machine with little amount of plugins, & everything worked fine, so it wasn't the machine stopping the plugin from connecting to the databases or anything. Plugin also runs in a big server with different plugins with no issues whatsoever.
Plugin works fine anywhere from 20 minutes to 3 hours before this one specific server completely crashes: https://pastebin.com/gHiLEpTB
Code for the methods that are mentioned in the crash log: https://pastebin.com/QP1K8AiQ & here's what I use to connect to the database:
public void connect(String databaseUrl, String username, String password) throws Exception {
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection(databaseUrl, username, password);
}
I'm most likely going to use Hikari in the future but I doubt that's what's crashing the server, since it runs on other servers fine?
It's 100% a plugin incompatibility with some other plugin but I can't seem to figure out what it is, & the server I'm working with has 141 plugins, so removing plugin by plugin seems impossible. Any ideas? Thanks 💙
beyond the pooint that there is 0 sense in wrapping all of this fun in a CF
when you just #get directly after
Don't run database queries on the main thread 💀