#help-development
1 messages ¡ Page 1711 of 1
uh sort of?
i just did what they told me to do đ¤ˇââď¸
idc
public record A(String name) {}
public class A {
private final String name;
public A(String name) {
this.name = name;
}
public String name() {
return name;
}
}
?
Use your mind
doesnt seem to be helpful to me đ˘
But getting spoonfed does not help you either
You need to understand what an instance is. Iâll try to explain but you really should learn Java basics before getting into plugins. Because what youâll realize is spigot is just an API, if you already know Java, you only have to figure out spigot, and spigot itself really isnât that hard. It just requires some memorization. Every time a class is called as in ânew classnameâ and instance of that class is made. A class is sort of like a blueprint for an object. If you call to your main class in other classes, but donât reference a specific instance. Each main class youâre calling to will be different. Yea thatâs probably not a great explanation
plugin.yml is invalid
did i ever get asked to get spoonfed? no | are you being helpful? no | do you think i care? no
No using your mind is spoonfeeding
This is overkill imo
public class HuskyEssentials extends JavaPlugin {
@Override
public void onEnable() {
Registries.Register(this,
HomeManager.class,
SpawnManager.class,
WarpManager.class
);
Registries.Deserialize();
Registries.Log(this);
}
@Override
public void onDisable() {
Registries.Serialize();
}
}
``` Clean main class uwu
C# !
ew c#
IIn a nut shell, if you donât learn Java youâre gonna be asking questions in here constantly that donât relate to the spigot api. It will be harder for you to make plugins.
i know how to do all that i just dont know the terminology or anything... idk why this isnt working since with the exact same code it was working yesterday and i havent changed anything except move it to another plugin with the same versions
Itâs not overkill itâs OO programming
i know basic java
wdym C# tf
Though ABK I'd strongly advocate to practice your self teaching skill
I thought I knew basic Java until I actually took a course online. I realized I was wrong.
UpperCamelCase method names
You forgot to invoke the initialzeEconomy method
so does anyone know what the issue is with my code or...??
we've told you like 10 times
Plenty have said the answer already
^
Oh true
Where did you invoke it?
onEnable
just somewhat unorthodox when it comes to the java realm but yaaaa
Ignore IntelliJ's autocorrect then
I changed it back to camelCase dw
this.setupEconomy() is fully valid with what you provided
except his first return statement in setpEconomy() should be false not true
though now I must ask does the software your team working on contain inconsistent naming also, just out of curiosity lol
and he should be checking the return of setupEconomy()
i fixed that
still getting the same errors
He is getting an NPE
do you actually have Vault and an eco plugin on yoru test server?
No it's my mistake I coded in C# my whole university career so its a habit ;-;
?paste your server latest.log (startup)
oh fair
Yea, you need an Eco plugin - vault alone does Not suffice
well Java and C# are almost identical anyways
You need to Register your Economy then
I used to go with C# name conventions also back in the days
So, fully different issue
what? your confusing me now
I found some java source code of a plugin but it contained all sort of weird stuff which I ignorantly picked up
im using the vault api to make the economy plugin?
Yes, but you need to Tell vault that you are the Eco plugin
?*
If you are making an eco plugin you are the provider. You should not be "getting" the provider from vault
This is called registering
im using the vault api to give players money and stuff?
If you look at my HuskySuite source code on github you won't find any weird naming conventions I promise.
Thatâs a confusing way to put it. You just need to create an instance of economy in your main class. Thatâs it. You initialize the instance in a setup function. Vault shows you how to do it if you look it up.
You need to implement all that
i do?
Where?
already did i did that
giving players money and stuff is not an eco plugin
the economySetup() part?
id call it an economy plugin i dont know what you would call it :/
how would i do that?
its just a plugin. An eco plugin stores player balances and provides methods to add and remove money from them
Then you are Not the Eco plugin
RegisteredServiceProvider<Economy> rsp = getServer().getServicesManager().getRegistration(Economy.class);?
If you already did that then youâre done, youâre fine: whatâs your issue?
I'll mark your word for it đ
im still getting errors when i try to use plugin.getEconomy()
This obtains the implementation. But what If there is None?
return false;```
You will get errors until you add an eco plugin to your server
what would be an "Eco plugin"?
iConomy, um, hundreds of others. I forget their names
A Plugin implementing and registering an economy
@ivory sleet fml

and yes I know I could use WordUtils but eh
but im trying to make a plugin that uses vault's api and create commands with it to give players money and stuff using vault, i would still need one?
Yes
Yeah same
More fun to make your own utility api
Vault does not do something like, e.g. storing the data - the Eco plugin does that
Vault is only an abstraction layer
public static BookBuilder newInstance() {
return new BookBuilder();
}
``` I peeked into Guava's CacheBuilder source and I found out you could do this.
Very usefull, 10/10
Yeah
Guava has a lot of static factory methods for their builders
It's nice tbh, I know Mongo Java Drive has this also
For broadcasting messages over bungee cord, I could just use the spit messaging channel, send it to my bungee, and then send it from there to every other server to bukkit.broadcast it from there or is that not possible?
how to detect when someone say a specific word in chat?
AsyncPlayerChatEvent
and to detect a specific word for it like "hello" ?
You can use .contains
example please?
I believe it can also take regex if you wish
Use an if statement and player.sendMessage
like so?
?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.
or like this
how do i know the exact syntax for each library i need to shade into my jar file?
Difference between
Bukkit.getScheduler();
and
plugin.getServer().getScheduler();
?
how to detect when a player says "Hello" and it would say "Hello" back?
warning from bukkit: never use bukkit api in async events
?
Not 100% true
i read that totally wrong my bad, async tasks not events i guess
what is bukkit api there other than getting the player? thats kinda required
have you learned java? if so, check https://hub.spigotmc.org/javadocs/bukkit/ before asking
sometimes the javadocs already have the answers to your question
i just wanna detect a player chat event :/
declaration: package: org.bukkit.event.player, class: AsyncPlayerChatEvent
search box...
!docs
Various things are fine to run async, but it's easier to just tell people not to
it said PlayerChatEvent cant use or something, lemme check
?jd
its deprecated
oh i cant read....
use async
declaration: package: org.bukkit.event.player, class: AsyncPlayerChatEvent
also, i suggest you learn java before using any java libraries, we aren't here to teach you how to use java ;)
what happens if i do use the deprecated btw?
its just a warning
when something is depcreated, it usually means that its gonna get removed soon
so dont use it, it will cause bugs *in the future
aah
its just warning but its depreciated for a good reason
okay dokie
especially the chat event though
please do not use it without async its very unsafe
you should always try to avoid depreciated things unless it is impossible to avoid
none
if you want to learn spigot but are too lazy to read docs and forums, then i suggest ||TechnoVision||'s series on the spigot api, its pretty good ||https://www.youtube.com/playlist?list=PLDhiRTZ_vnoUvdrkTnaWP_hPmbj2JfPAF||
plugin.getServer will return the server
or codedred
Bukkit.getScheduler will get the server.getScheduler()
check this playlist out, its was made in 1.15 but it will work for 1.17
https://www.youtube.com/playlist?list=PL65-DKRLvp3Yn7iglPfxKoc7bl0N80XgG
Anyone know how to get ALL bees that belong to a hive? not just the ones currently inside of it
(although I also need to get the ones currently inside it but dont see how to get the entities, only the count)
dont see it on the docs
i am watching the one that MrPizzaGuy gave me
Has anyone released a patch for the known issues with InventoryCloseEvent?
1.8 would be preferred
what issues
It doesn't always get called when an inventory closes in some cases
Including when a player is teleported, leaves the game, etc. etc.
Well
I mean I was asking about 1.8
I'm pretty sure the issues persist in other versions, but not completely
Alright you know what
Are there any Spigot forks that are actively supporting 1.8?
Because I would really like to be able to smoothly develop with better pvp properties and hitreg (what players usually prefer)
I still maintain that in the opinion of a hardcore pvper (not me, lol) authentic 1.8 is still far superior in terms of minor differences
Also I found one
something that makes hard the 1.8 players migrate to the latest version is that change the weapons damage may be hard
which i want to edit
and if someone know how to edit it
help me đ
i dont care i will need to modify the nms/craftbukkit code
Just modify their attributes
just googled it and a lot of people said that this is hardcoded
?
i dont want attribute
What do you think controls the damage
Do events (PlayerTeleportEvent, PlayerQuitEvent), etc fire before or after they ocurr?
Well, I really mean those events specifically
lol
Is it possible to get a uuid from a players name?
Yep
how can I go about doing that?
2 options
if they are online you can use Bukkit.getPlayerExact
if offline
iterate Bukkit.getOfflinePlayers and be happy đ¤Ą
how do i save a file one 1 time?
like, the plugin enables and save a config file
then i can delete it that it wont be created again
Anyone know how to get the honey level of a beehive..? there's no methods for it.
Like.. there is here https://hub.spigotmc.org/javadocs/spigot/org/bukkit/block/data/type/Beehive.html but it doesn't show up.
declaration: package: org.bukkit.block.data.type, interface: Beehive
???????
wrong beehive import
getState != getData
ahhh ty
import org.bukkit.block.data.type.Beehive;
//
Beehive beehive = (Beehive) block.getBlockData();
// beehive.getHoneyLevel()
Yeah I got it thanks sir
I'm guessing there's not an event for that either, ill just have to keep checking it every tick for changes
declaration: package: org.bukkit.event.entity, class: EntityChangeBlockEvent
Is there a way to see what data changed?
For a FallingBlock?
Scroll up smile
Ah. Hm. Check the current state and compare it one tick later...
or do what i said
how do i know the exact syntax for each library i need to shade into my jar file for my plugin.yml?
Yeah but this does not account for states
for my plugin.yml
there isn't a getBlockData() for getTo()
ah.
so you cant compare what it was to what it is now.
F
Thats fine I guess a scheduler could work.
just not as efficiently
that just shows the new data
No
getBlock().getBlockData() <- Old
getBlockData() <- New
wot
getBlock() returns the Block that is about to be changed.
getBlockData() returns the data that is about to be placed on this Block.
yeah I get that
im just surprised
lemme try..
Could I check a specific value to see if it changed..?
getHoneyLevel?
BlockData oldData = block.getBlockData();
BlockData newData = block.getBlockData();
Beehive beehive = (Beehive) oldData;
like could that work?
I wanna run it ONLY when honey level changes.
Right, so return if honey level is the same
Always make an instanceof check first
Another plugin could have spawned a falling block beehive
if(block.getType().equals(Material.BEEHIVE)) {
BlockData oldData = block.getBlockData();
BlockData newData = block.getBlockData();
Beehive beeHiveOld = (Beehive) oldData;
Beehive beeHiveNew = (Beehive) newData;
if(newData != oldData) {
if(beeHiveNew.getHoneyLevel() != beeHiveOld.getHoneyLevel()) {
}
}
}
đ¤
Ah ok that should suffice
Mixed up how?
Enum == Enum
!newData.equals(oldData)
if(!(newData.equals(oldData))) {
useless parentheses
looks nicer
if (!newData.equals(oldData))
Ok
But it should always be true. The whole point of the event is that the BlockData changes
You never know with the API
^
Although Iâm still guilty of unchecked casts from human entity to player
đ
NPEs give me paranoia
same reason i check if items have itemmeta before checking the itemmeta
Always. Never done this check ever.
HumanEntity should always be player
Not really sure how hasItemMeta works
herobrine
Iâm pretty sure hasItemMeta can return false yet getItemMeta can still be called
If you listen to your IDE then you wont get NPEs. Its the least common exception for me currently.
getItemMeta() is going to create item meta if it doesn't exist. If you're fetching an item, you should always check if hasItemMeta
It's going to be faster
what
I usually just check isAir
No. What if there's just a plain diamond sword with no lore, name, damage, or anything else?
its still not null
I understand that... but why get the meta if you don't need it
isAir calls hasItemMeta?
No
If you want to check if an item has a certain name, if it does not have item meta, DO NOT CALL getItemMeta()
Choco is talking about when you want to check the ItemMeta and dont want to modify it
oh well yeah ofc why do that
Yeah, like checking pdc values
/**
* Get a copy of this ItemStack's {@link ItemMeta}.
*
* @return a copy of the current ItemStack's ItemData
*/
@Nullable
public ItemMeta getItemMeta() {
return this.meta == null ? Bukkit.getItemFactory().getItemMeta(this.type) : this.meta.clone();
}
/**
* Checks to see if any meta data has been defined.
*
* @return Returns true if some meta data has been set for this item
*/
public boolean hasItemMeta() {
return !Bukkit.getItemFactory().equals(meta, null);
}
fr
makes no sense
/**
* Get a copy of this ItemStack's {@link ItemMeta}.
*
* @return a copy of the current ItemStack's ItemData
*/
@Nullable
public ItemMeta getItemMeta() {
return this.meta == null ? null : meta.copy();
}
Does the method do something additional? Check for empty meta maybe?
Maybe if its empty its the same as it being null
Yeah thatâs the only reason I could think of
im gonna rewrite this to make it 10x better
public boolean hasItemMeta() {
return this.meta != null && !this.meta.isEmpty();
}
then a method in meta
isEmpty
how do i know the exact syntax for each library i need to shade into my jar file for my plugin.yml? or at least drop me a link for gradle depedency shading
public boolean isEmpty() {
return !(this.hasDisplayName() || this.hasLore() || this.hasEnchants() || this.hasAttributeModifiers() || this.hasModelData() || this.hasLocalizedName()) && this.getItemFlags().isEmpty();
}
thanks mate
I think the unsafe class in bukkit letâs you add an advancement from a json string
Probably better to just extract a datapack from your jar
?
what?
You can bundle a zip file in your plugin jar and copy it to the world datapack folder
Like I said I believe there is a way in the unsafe class using a raw json string
unsafe class?
Donât think so
Maybe its draft. Maybe its unstable.
hm
ok thanks
ill use it i guess
hope they fix this up and add a more stable solution
yea, but i don't really want to use an api right now
i guess ill use unsafevalues
thanks for the help ;D
I guess it wouldnât be too bad if you load it from a file
I wrote the raw string into my IDE and it was ugly
Every advancement has a unique key
return "Hello there".toString().toString()
hmmmm
Yes you can call toString on a string
You can also repeatedly call getPlayer on a player
w h y
Because Object has a toString method, and every class, including string, extends from object
As for player, offline player has a getPlayer method, and player is an extension of offline player
Because Player extends OfflinePlayer which has a getPlayer() method.
@EventHandler
public void onHoneyLevelChange(EntityChangeBlockEvent event) {
Block block = event.getBlock();
Bukkit.broadcastMessage("Changed 1");
if (block.getType().equals(Material.BEEHIVE)) {
BlockData oldData = block.getBlockData();
BlockData newData = block.getBlockData();
Beehive beeHiveOld = (Beehive) oldData;
Beehive beeHiveNew = (Beehive) newData;
Bukkit.broadcastMessage("Changed 2");
if (beeHiveNew.getHoneyLevel() != beeHiveOld.getHoneyLevel()) {
for(CustomHive customHive : cadiaBees.hiveManager.getCustomHives()) {
if(customHive.getHiveLocation().equals(block.getLocation())) {
customHive.setHoneyLevel(beeHiveNew.getHoneyLevel());
for(Player allPlayers : Bukkit.getOnlinePlayers()) {
cadiaBees.cadiaCore.hologramManager.refreshHolo(allPlayers, cadiaBees.hiveManager.getHiveHolo(customHive));
}
}
}
}
}
}
So, I get Changed 1 but not Changed 2, any idea...?
Have you tried outputting what block.getType returns
BEE_NEST
Bee nest is the wild block
mine are hives
Hive is the player made one
Ah. What does yours return?
..
AIR
đ
its either air or its not being called at all for the honey update
I had it feeling it might not be
whats the difference between netty's write and writeAndFlush?
Writing writes a packet to the channel but does not send it immediately. Flushing sends all packets in the channel.
when i only use write it still sends packet
Maybe the channel is set to auto flushing
is there an option for this? or how to check that?
Check if the ChannelInboundHandler#channelWritabilityChanged() method is overwritten to call flush()
Usually netty doesnt auto flush and doesnt have an option for it unless the underlying implementation is changed.
Alright, sooo..
[20:44:57 WARN]: [CadiaBees] Task #6358 for CadiaBees v1.0 generated an exception
java.lang.ClassCastException: class org.bukkit.craftbukkit.v1_17_R1.block.CraftBeehive cannot be cast to class org.bukkit.block.data.type.Beehive (org.bukkit.craftbukkit.v1_17_R1.block.CraftBeehive and org.bukkit.block.data.type.Beehive are in unnamed module of loader 'app')
at com.squallz.CadiaBees.tasks.HoneyLevelTask$1.run(HoneyLevelTask.java:26) ~[CadiaBees.jar:?]
at org.bukkit.craftbukkit.v1_17_R1.scheduler.CraftTask.run(CraftTask.java:101) ~[patched_1.17.1.jar:git-Paper-19
Getting this because I'm casting..
Beehive beehive = (Beehive) blockAtHiveLoc.getState();
apparently you can't cast import org.bukkit.block.data.type.Beehive; to beehive blocks
yet I need to get the data from said block..
You cant cast a TileState to a BlockData.
so then how do I get the data from the block?
Get the BlockData and cast it to the data Beehive or
get the BlockState and cast it to the state Beehive
i dont see anything like channelWritabilityChanged in the code
Im not 100% sure but i think netty does not have an auto flushing option.
Somewhere in the channel (maybe even in the write method) there must be a flush() being called after
a packet is written. Maybe there is a channel handler registered that does this.
oh yea there is something
so basically calling flush from channel sends all packets right?
Yes
where is the classifier and the extention ? https://mvnrepository.com/artifact/net.dv8tion/JDA/1.2.1_106
Beehive beehive = (Beehive) blockAtHiveLoc.getBlockData();
import org.bukkit.block.data.type.Beehive;
đ¤ not working still
i just assume the way i did it was wrong but i can't figure out how i did it wrong. Thrown exception: ```org.bukkit.plugin.InvalidPluginException: java.lang.IllegalArgumentException: Bad artifact coordinates net.dv8tion.JDA:4.3.0_324, expected format is <groupId>:<artifactId>[:<extension>[:<classifier>]]:<version>
gotcha
Check the Material at that location
i think the mystery is solved, i still have some packets being sent but thank you, i think that was it! đ
nowhere do i have that syntax. that's weird:
anyone really good with protocollib?
Nobody is. But just go ahead and
?ask
If you have a question, please just ask it. Don't look for staff or topic experts. Don't ask to ask or ask if people are awake or available. Just ask the question to the channel straight out, and wait patiently for a reply. Create a thread in case the help channel you are using is already in use!
thats paper
- Dont make it static
- This is not a spigot event
LivingEntity mob = (LivingEntity) nearby;
Bukkit.getServer().getPluginManager().callEvent(new EntityDamageByEntityEvent(player, mob, EntityDamageEvent.DamageCause.ENTITY_ATTACK, 5));
calling the EntityDamageByEntityEvent should be enough to damage a mob right?
No i dont think so.
One moment ill write an example
You can damage it with .damage
And you can supply an entity to simulate that entity doing the damage
public void damageWithEvent(final LivingEntity attacker, final LivingEntity defender, final double amount, final DamageCause cause) {
final EntityDamageByEntityEvent event = new EntityDamageByEntityEvent(attacker, defender, cause, amount);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
final double finalDmg = event.getDamage();
defender.damage(finalDmg , attacker);
defender.setLastDamageCause(event); // Not sure if this needs to be here
}
The annoying part is I never found a way to damage an entity with a non-entity source
There are two methods.
LivingEntity#damage(Double) and LivingEntity#damage(Double, LivingEntity)
Actually not sure if the second one fires an event...
probably not
ah thanks
If I set an entity to be a baby, how do I stop it from aging?
setAgeLock
Oh thatâs nms
yeahh
I think you just set itâs age to Short.MIN_VALUE
How do I check if itâs the first time someone start up server with this plugin in on enable
Is it just checking the data folder exists
This is one approach. You can also check if the config file exists or use a boolean inside your config file.
What if someone deletes the config file
đ¤ˇ
You can also have a file inside your jar and modify it.
Yeah like a properties file would be good!
You could also set a system property for the user i suppose đ¤
so... I want to store item to a database... readable... so base64encoding is not an option, but more like a way to stringify... So far I've manage to extract and make a string with weapons and tools with enchantments, but I need a simple way of checking if item in hand, is a tool or an block or something else? what is the best way? Material#isBlock()? what does Material#isItem() return?
I think there is a vanilla way to serialize ItemStacks into json format.
isBlock() returns true if the ItemStack is a placable Block. isItem() returns the inverse.
i mean if the item in hand is block, it doesn't need to check for enchantment and so on.
How do you plan on storing custom NBT Data?
And PDCs
And some plugins might have extra data in block items.
so far, I simply just store name,amount,lore,enchantment and damage
đ
not needed for my purpose
You can probably make a method to encode it as json
Although I donât know why you would want something to be human readable in a database
maybe because other application would have access to it đ
Then those other applications should be able to convert it to a readable form
This other applications just need Spigot as a dependency and then they can use ItemStacks as they are...
I suppose you could go with NoSQL to be a bit more readable
public static String serialize(final ItemStack itemStack) {
final NBTTagCompound tag = new NBTTagCompound();
CraftItemStack.asNMSCopy(itemStack).save(tag);
return tag.toString();
}
Used like this:
@Override
public void onEnable() {
final ItemStack stack = new ItemStack(Material.IRON_PICKAXE);
final ItemMeta meta = stack.getItemMeta();
meta.setDisplayName("§eSome Cool Name");
meta.setLore(Arrays.asList("", "§7Im a cool pickaxe."));
meta.setUnbreakable(true);
meta.addItemFlags(ItemFlag.HIDE_POTION_EFFECTS, ItemFlag.HIDE_DYE);
final PersistentDataContainer container = meta.getPersistentDataContainer();
container.set(NamespacedKey.fromString("test:key"), PersistentDataType.INTEGER, 256);
stack.setItemMeta(meta);
final String data = serialize(stack);
System.out.println(data);
}
Yields:
{Count:1b,id:"minecraft:iron_pickaxe",tag:{Damage:0,HideFlags:96,PublicBukkitValues:{"test:key":256},Unbreakable:1b,display:{Lore:['{"text":""}','{"extra":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"gray","text":"Im acool pickaxe."}],"text":""}'],Name:'{"extra":[{"bold":false,"italic":false,"underlined":false,"strikethrough":false,"obfuscated":false,"color":"yellow","text":"Some Cool Name"}],"text":""}'}}}
thanks i'll look into it
Can also be deserialized
public static ItemStack deserializeItemStack(final String string) {
if (string == null || string.equals("empty")) {
return null;
}
try {
final NBTTagCompound comp = MojangsonParser.parse(string);
final net.minecraft.world.item.ItemStack cis = net.minecraft.world.item.ItemStack.a(comp);
return CraftItemStack.asBukkitCopy(cis);
} catch (final CommandSyntaxException ex) {
ex.printStackTrace();
}
return null;
}
Turn it into a persistent data type and you can get real meta
You mean like a backpack that stores ItemStacks?
Yeah
I know choco wrote a pdc type for that for someone
No idea what the repo is though
Ive used this approach in my machine plugin as all machines are TileStates and have PDCs. I dont need to manage any files or DBs đ
Technically thatâs not really an issue for blocks either now that we have chunk pdcs
Unless you intend to use said block a lot
Its usually better to load the data into memory when the chunk loads and save it again when it unloads. This way you dont have to
access the PDC often as thats quite slow
I figured it would just be a map in the backend
Accessing the PDC has a bit of overhead. And parsing it is also not cheap. Better to just Use an IntMap<CustomData> or something and then
lazily load the data into memory.
(IntMap because a relative block location inside a chunk can be stored in 32 bits)
Does that apply in 1.17+
Yes i made sure that it also supports heights of up to 4096
I imagine it would actually, 5 bits for x and z + 11 bits for y
Or 12, I donât remember how high you can actually make the world without the render system dying
2^16 so 65.536
In case Mojang wants to add 65k tall worlds
Although at that point you probably want cubic chunks
The theoretical value that is now supported by the chunk format is actually substantially higher than what is actually implemented in vanilla
I was around when the fabric guys messed with it after the snapshots
I donât think they got past 4096
We will see. But imagine running 4k Blocks. It takes quite a bit of time. Having this in the y direction would be insane.
Yeah
The render side isnât too bad because the game can already cull in cubic chunks
But worldgen is the issue
Pretty sure someone will write a generator that generates the Nether right under the overworld so you can dig down to Hell đ
And memory footprint
Pre-generate the world. Memory footprint will be ok-ish.
But loading those chunks from disk... you better have an NVMe on your server.
128 x 16 blocks per section
So 256 x 16 = 4096
128
đ¤
Bytes are always signed in java
Although I would imagine negative section IDs would be fine so ÂŻ_(ă)_/ÂŻ
so from -2032 to 2048 then. Doesnt really make a dif
Noice. Cant wait for an Enderdragon to breach the ceiling and trash the whole server
Note to self
Alter dragon path finding
Canonically the dimensions are meant to be separate, but seeing the end stacked on the overworld stacked on the nether would be cool
Hm the boss fight will be bugged as everyone in the world will constantly see the Health bar
You could alter that too to be proximity based
Mixins fix everything, including Mojangs fuckup on world saving in the new versions :p
bunp
there's already a broadcast channel?
The home of Spigot a high performance, no lag customized CraftBukkit Minecraft server API, and BungeeCord, the cloud server proxy.
the god himself speaks
Hello orange guy
can i not make custom items with spigot? I mean with textures
Isnât that resource packs?
Does any here have experience with JDA (Java Discord API)?
Yeah
Yep
Hey, I need help regarding a particular logic. I created a plugin which tracks a player with a compass. It works fine until I have two or more targets at which the compass has to point. If there are two or more players who want the compass to face two different players, it won't. It would just face the latest target which was given by the player.
Main Class - https://paste.md-5.net/jowesivefi.java
Track the Target Class - https://paste.md-5.net/exocimojoz.java
Right Click to refresh target location Class - https://paste.md-5.net/azigasilim.java
?main
Static variable is the issue
also - that is a RightClickListener not a RightClickEvent
How does Spigot register the functions called on an listener
Where does it get the key from
How does it know what event it is?
?eventapi
how does class name matter if the plugin is working?
and i am not making a public plugin...
Okay Thanks! Now I know that my idea will work
Anyways can anyone help?
so i would use CustomModelData?
cause I dont want to replace a ingame item
.
?
didnt wanna just override your question
How to get item durability?
oh i know how to do that with datapacks or is it a resource pack thing
well you set the data with the spigot api and then you need a resource pack for the actual texture
there is a method under player to set the resource pack
Player#setResourcePack
i am trying to make it detect when someone say "hello" in chat and then reply to that hello with a "hey" but idk if this is the right way or not
Whats the non deprecated way of playerinteractevent#iscancelled ?
the send message bit needs to be in the if statement
if not it will send regardless
yeah but idk how I should then use "useInteractedBlock()" as a boolean as its a Result (havent worked with Results yet)
Hey guys, I am trying to connect my plugin to a discord bot
public Discord() throws LoginException {
String token = "";
try {
assert false;
token = plugin.getConfig().getString("token");
} catch(NullPointerException error) {
Bukkit.getConsoleSender().sendMessage("[DiscordIntegration] Token not available");
}
if (token != null) {
startBot(token);
builder.addEventListener(this);
botEnabled = true;
} else {
Bukkit.getConsoleSender().sendMessage("[DiscordIntegration] Failed to login to bot.");
}
}
public void startBot(String args) throws LoginException {
try {
builder = JDABuilder.createDefault(args).build();
} catch(NullPointerException error) {
Bukkit.getConsoleSender().sendMessage("[DiscordIntegration] No token found. Put token in config and restart server");
}
}
In config I have provided the token but it still says [DiscordIntegration] Token not available on console
i got it already, dont worry đ
its correct now
Why do you use assert false & u sure that the path is right?
yes the path is right
Thanks, after getting values(), which element is the one that would be isCancelled? đ
how to make it say "hey" after i say "hello"
what exactly do you mean? you want to insert the word "hey" inside the same message, or want your plugin to "reply" to your message?
ah okay I got it
runn it in a delayed task
how to?
1 sec
for example:
@EventHandler
public void onChat(AsyncPlayerChatEvent event) {
if(event.getMessage().toLowerCase(Locale.ROOT).contains("hello")) {
Bukkit.getScheduler().runTaskLater(this, () -> { // <- "this" is the instance of your class that extends JavaPlugin
event.getPlayer().sendMessage("hey");
}, 20); // <- 20 means a delay of 20 ticks = 1 second
}
}
why is it when i changed "this" to the name of my class that extends JavaPlugin, it becomes static
what do you mean with "it becomes static"?
you need a reference to your main class
for example by passing "this" to your listener class when you create the listener object
^
I'll show you another example in a minute
this is my class that extends java plugin
yeah I'll show you something in a minute
okeh
imagine this is your listener class, while "Test" is your Main class:
public class MyListener implements Listener {
private final Test plugin;
public MyListener(Test plugin) {
this.plugin = plugin;
}
}
In your onEnable, do this:
Bukkit.getPluginManager().registerEvents(new MyListener(this), this);
as you can see, we simply passed "this" to the Listener object, which then keeps it inside a variable "plugin"
so you can access the main instance of your plugin from your Listener
so i need to add something here?
tbh you should learn basic java if you still have questions
I explained you like every single detail
yeh ik
"Testing" has to be replaced with a variable that points to your main instance, like in the above example, "plugin"
in your "Replier" class, you need to create a constructor that takes an instance of your main class as parameter and then saves it inside this "plugin" variable
(you could also use a static getter in your main class but I wouldn't recommend that until you know what you are actually doing, because otherwise things will get messy soon)
@solar sable Example:
Main class:
Listener:
?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.
show code and learn java
theres a shit ton of red
Test is not the same type as Testing
now?
just copying code wonât help
changed the Test to Testing
understand it
learn java
ur passing the paramter testing but trying to use plugin?!
this.plugin = testing
please for gods love learn java
Yeah I agree, you should probably visit some basic Java syntax tutorial which explains different variable types and such
If you do it properly it shouldn't take that long to get a decent understanding of it as well
Just a max of 30 min should be enough to understand the concept of variables
Depends on what you define as fully
There's no strict line where we can separate basics with more intermediate knowledge I'd argue for
but yeah
Fully understand as in: When is a value allocated on the stack and when on the heap?
hell nahxD
this hurts to look at ngl.
?
i know this isnt the place to ask but most people use it here so imma ask anyways, how to change the .jar file version? i tried to change to 2.0 but didnt work lol so it kinda just stayed at 1.0
sorry, i always speak my my mind
jar version???
plugin.yml
tried that
u fixed the other error.
hi md_5
didnt work
well it probably should change smth
The versioned name you usually see is created by dependency managers.
You should not worry about that for now.
well my plugin .jar kinda just shows testing-1.0.jar everytime i change it so
If you're compiling with Gradle or Maven, it's likely the version set in its config that needs changed
how can i run my plugin from intelliJ itself?
pom.xml
dont think u can do that
not sure tho
It is possible, but you have to set up a server environment inside the project
so for every change, and every value i want to change i need to rebuild the jar and restart the server?
That or create a fake sever to run it on
Any time you change the plugin it'll need recompiled and updated on the server, yes
i just want to be able to press the run button, have it compile my plugin, put it in the correct folder, start the server, and allow me to join
Do you use maven?
i have chosen for gradle
Too bad. I got a script that scrapes the jar name from the pom, compiles the plugin, copies the jar and starts the server.
@echo off
SET serverLocation=C:\Users\flo\Desktop\DESK\1.17Spigot
call mvn clean install
set "artifactId="
for /f "tokens=3 delims=<>" %%a in ('find /i "<artifactId>" ^< "pom.xml"') do (
set "artifactId=%%a"
If not [%artifactId%]==[""] (
goto :end1
)
)
:end1
set "version="
for /f "tokens=3 delims=<>" %%a in ('find /i "<version>" ^< "pom.xml"') do (
set "version=%%a"
If not [%version%]==[""] (
goto :end2
)
)
:end2
SET jarName=%artifactId%-%version%.jar
SET jarPath=target\%jarName%
SET serverPluginLoc=%serverLocation%\plugins
xcopy %jarPath% %serverPluginLoc% /Y
SET serverStartScript=%serverLocation%\start.bat
cd %serverLocation%
%serverStartScript%
You just need to figure out how to scrape artifactId and version from your gradle file and change the serverLocation variable.
bruh
i am just wondering
how is it more difficult to run a plugin from intelliJ
than both server and client side mod launchers
I explained like exactly what you had to do, but you just ignored everything of it it and instead just copy pasted everything? of course that won't work
Because you need a third party setup first.
Running a normal java application is no big deal but your
plugin is not a standalone application. Its a plugin.
Hi
If i code a plugon will people who decompile it be able to see information in the jar and code files
Such as ip
Name
Or name of pc user or any info at all
Or just the code
Only code
Thanks <3
im trying to make a hologram plugin with NMS
any idea of how to update it ? like set a new text
or sending another metadatapacket but i dont have the dataWatcher of the armorstand
and i only got the id
or getting an armorstand from id
if i somehow send the metadata packet again
will it get updated ?
gets the time he clicked / clicks?
i think so
he clicked
record when
gets the last click
calculate the time between them
divide by 2
he clicked again
increase amount of the clicks
now do the same division but by 3
ik you will use variables
i guess just listen for click
add to a hasmap
reset the hashmap every second
I GUESS
will it work ?
that would be extremly resource intensive
ask me later
not really
i will be out for now
Whatâs so resource intensive about it?
nothing imho^^
adding to a hashmap and resetting it every second
how is that resource intensive?
maybe when you are running it on a 0.1MHz calculator
â ď¸
In worst case use a concurrent hashmap and do it async but I doubt you need that
yeah i am doing this for an android app, learning stuff
?paste
Previously using jdk8, I was using maven ant and antcontrib in order to copy my built artifacts into my local test servers.
https://gitlab.com/lasersenigma/lasersenigma/-/blob/master/core/pom.xml#L305
I did all this because I wanted each developer to be able to modify his own local test servers locations inside a gitignored file ("build.xml")
So I only gitted the example file build-example.xml:
https://gitlab.com/lasersenigma/lasersenigma/-/blob/master/core/build-example.xml
After updating to Spigot1.17 and updating accordingly to openjdk16 I couldn't use all this setup anymore because of the lact of tools.jar (com.sun:tools) which is a system dependency (coming from "<jdkpath>/lib" directory and which have been removed from the latest versions of the java jdk. this file is required by ant.). I could still have included it manually but then I would have had issues with my gitlab-ci.yml. So I tried to exclude it :
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.10.11</version>
<scope>provided</scope>
<exclusions>
<exclusion>
<artifactId>tools</artifactId>
<groupId>com.sun</groupId>
</exclusion>
</exclusions>
</dependency>
but then I have another issue when running ('org.apache.tools.ant.util.FileUtils org.apache.tools.ant.util.FileUtils.getFileUtils()')
So I'm looking for a solution to one of those problems :
- specifically continue using ant and antcontrib (so this means fixing the
com.sun:tools:1.8missing issue but without including it from the jdk). - using another way to copy built artifact to my local test servers while keeping the ability to modify those locations in a gitignored file.
Please advice đ
I suppose I could add some vars to maven properties (in a gitignored file) and use it with some maven copy plugin or something alike ?
But it seems it could not be done if I want to put multiple target directories. It would also be unable to delete the previously built jar if the version changes.
Player -> Player message or any message a Player receives
Do you want to change the message a player sends in the chat or do you want an arbitrary message to be modified? (From a plugin for example)
gonna be harder i imagine but probably packet stuff
With ProtocolLib its something like this:
public class MessageListener extends PacketAdapter {
public MessageListener(final Plugin plugin) {
super(plugin, Server.CHAT);
}
@Override
public void onPacketSending(final PacketEvent event) {
final PacketContainer container = event.getPacket();
final StructureModifier<WrappedChatComponent> chatStructMod = container.getChatComponents();
chatStructMod.modify(0, current -> {
String json = current.getJson();
// Change component here
});
}
}
Reference this:
https://wiki.vg/Protocol#Chat_Message_.28clientbound.29
But getting this to work wont be easy.
Nope. I dont know how to handle this packet out of the blue. I would have to take a look at the PacketPlayOutChat and play around a bit.
On this page you can read about the general usage of PacketAdapters
Its maybe an array of components. Not sure.
StructureModifier<WrappedChatComponent[]> componentsStruct = event.getPacket().getChatComponentArrays();
hey the player camera rotation is on euler angle ?
Not really. Euler angles are 3 angles. And the cam doesnt have a roll component. Only pitch and yaw.
player.getDirection()?
Is there a easier way to clone a block from a to b(clone all info & other)
Like chest loottable ,etc
(I donât want write all type of them)
So is possible to do it?
Like use nms or?
can't you simply set the block's blockstate?
Different location.
so?
Hmm.
There is no block.setState
Only state.update
If I can set block state to another location then update,that will work too.
hm yeah you're right
Is there a way to create a Listener from a String?
e.g the string is "BlockItemDrop", it creates an BlockItemDropListener
Hm
Let me think.
You can use reflection to get Listener
And use something like eval to dispatch code.
Google is ur friend:/
i said i already found it .-.
Just tips.-.
is there a better way to do this? what i want to do is everytime a player drops an item, it will say in chat what the player dropped
Can anyone help me with this please? Tag me if replying ty
What do you mean?
Say if Everything drop?
Or just some special item.
Talking to me?
Sorry not:/
oh ok
theres no way its that easy
What?
i dont believe its easy as that
sure?
this is the perfect use case for a switch case
you
ArrayList<Material> anythingYouWantFilter=new ArrayList<>(Arrays.asList(Material.DIAMOND,Material.EMERALD);
//event listener
if(anythingYouWantFilter.contains(/.../.getType())){
e.getPlayer().sendMessage(âyou dropped a â+/.../.getType().name +â!!â);
}
Just do this
leme create a thread for this
is this correct that this is two times the same?
Can someone walk me through custom achievements using Bukkit.getUnsafe()?
Spigot doesn't really have much on it
use a switch statement
wait what originals:
Okay I've got a practical question, I'm making an mysql plugin where i save a few player stats like mob kills player kills time played etc, what would be the right thing to do, query update db after certain event like a kill, or do I store everything in hashmaps to then on quit event query update. I'm not that familiar with the quit event don't want to cause logout lockups so my bet would be updating after any event. Thoughts ?
switch?
You have several options for this.
- You can use a Map<Material, String>
- You can use translatable components
- You can transform the Enum into a String like this:
public static String toReadableString(final Material material) {
return StringUtils.capitalize(material.name().replace("_", " ").toLowerCase());
}
And dont use if-else or a switch statement as that will scale horribly
@EventHandler
public static void onDrop(PlayerDropEvent e) {
Player player = e.getPlayer();
String str;
switch (e.getItemDrop.getItemStack().getType()) {
case Stone:
str = "Stone";
// etc
}
player.sendMessage("You dropped a " + str);
}
something like that?
switch (e.getItem...){
case "something" -> sendMessage;
case "something1" -> sendMessage;
}
Pls no. You guys need to stop with your switch statements...
Switches are better
You should stop
what does that toReadableString do?
i will just use this cause i can read this other than the rest that you guys showed me
public static String toReadableString(final Material material) {
return StringUtils.capitalize(material.name().replace("_", " ").toLowerCase());
}
@EventHandler
public void onDrop(final PlayerDropItemEvent event) {
final Player player = event.getPlayer();
final ItemStack drop = event.getItemDrop().getItemStack();
final String itemStr = toReadableString(drop.getType());
final int amount = drop.getAmount();
player.sendMessage("§9Test > §fYou dropped §9x%d %s".formatted(amount, itemStr));
}
There. No switch case needed.
What if this guy dont want every item?
wow
Just some items, as he posted it
no that is perfect actuallly
i do want everything
Then he should use a Map<Material, String> and not a switch-case statement as HashMap scales O(1) and switch case O(n)
How would I deal a specific kind of damage to an entity? like if I want my plugin to deal 5 points of harming damage
A so called label. You can label to explicitly escape a nested loop.
uh i'll look that up
You need to fire an Event yourself for that.
That seems to do void damage, at least in terms of death messages
public void damageWithEvent(final LivingEntity defender, final double amount, final DamageCause cause) {
final EntityDamageEvent event = new EntityDamageEvent(defender, cause, amount);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
return;
}
final double finalDmg = event.getDamage();
defender.setLastDamageCause(event);
defender.damage(finalDmg);
}
ah ok
if i understand correctly you can continue a loop with the given label
so a labeled break and continue
Interestingly while this seems to work in terms of damaging, it does not create an appropriate death message for me. It just says Player died.
Hmm.
does spigot have something like onReload so I can handle it properly?
onEnable and onDisable
does reloading disable it tho?
iirc then reloading should disable and re-enable all plugins.
Try switching those lines
defender.setLastDamageCause(event);
defender.damage(finalDmg);
defender.damage(finalDmg);
defender.setLastDamageCause(event);
You can detect a reload in your onLoad() method. java if (Bukkit.getWorlds().isEmpty()) // its a fresh start
That doesn't seem to change the outcome. If I set a damager in the .damage method it does say slain by correctly though it still doesn't use the source. Trying to simulate a death by magic.
Oh that's a interesting solution, thanks
I also tried setting the cause before firing the event since that was how a random spigot example did it, but that still didn't set the message
You
I was able to successfully use ((CraftLivingEntity) entity).getHandle().damageEntity(DamageSource.o, (float) event.getAmount()); but obviously I'd rather avoid nms
bump
Player gets killed event
in CommandExecutor#onCommand, is there no better way to get the player than this?
Player player = Bukkit.getPlayer(sender.getName());
oh fuck
Player inherits CommandSender
can I just cast it?
404 not found smh
how to put buldtool in my sever
void setArmorContentsâ(@NotNull ItemStack[] items)
what order is the array?
boots first or helmet first?
who me
no
how to put buldtool in my sever
? what is buld tool
are you talking about worledit
you mean adding it as a dependency?
like where you can type //wand in game?
no
bump
it is showing like this
this channel is for help on scripting plugins. for your question, ask #help-server
scripting plugins 
You can add -DIReallyKnowWhatIAmDoingISwear to JVM arguments to make it not do that
i dont think he knows what a jvm is
Probably not but idk how else to explain it LOL
lol considering this is how he talks, either hes a troll or he has no idea what hes doing
are you sure it would matter? as you can't put a chestplate in a helmet slot
its an ItemStack[] array, so theres an order right?
is it {helmet, chestplate, leggings, boots}
or {boots, leggings, chestplate, helmet}?
The latter
oh ok thx
Even if it does it backwards, just reverse it.
im trying to put armor on a zombie, so i was confused what order the itemstacks go in
why cant i message a player in the join event? i cancelled it with 1 tick
Send your code
just this in the player join event
Bukkit.getScheduler().runTaskLater(plugin, () -> Utils.message(player, "&aWelcome to the server &b " + player.getName()), 1L);
Is your Join event firing
yes
You know is firing or you're just assuming that it is
i know it is
messages a player with translated chatcolors
Chatcolor.translateAlternateChatcolors('&', "message")
well yea that
that makes no sense it always works
Or use Chatcolor.red "" ,... x)
^ are you really sure ?
yes
ill debug it
okay it gets logged
but no message
maybe because i join too late
try sending the message a little later?
probably
that one tick probably isnt enough after joining for your chat to realize its been sent a message
How do I make so that player heads are named and look like the person who died?
yea
for the name you can just set the displayname of the head youre dropping to the event.getPlayer().getName() or whatever it is
as for the looks im not sure
When I use p.getLocation().getWorld() I can't use the getName() method. I'm using the latest version, does anyone know what it is?
how to get the (x) element of an arraylist
i guess .get method
yes
if (uses.merge(uuid, 1, Integer::sum) > 2) { // uses is a hashmap```
this means if the hashmap contains uuid and it has a value it increments that value by 1 and checks if that result is > 2?
so it executes uses.put(uuid, uses.get(uuid) + 1) if the value if present
and then checks
well i'm trying to shorten my code but still need quite alot
Yeah but usually I avoid using those higher order functions
Whilst they sure make the code a little bit cleaner itâs also some overhead in terms of speed
Only reason to use it for me is if the map is supposed to be used in a multi threaded environment
poh
Clean code is more important in my opinion than speed. Computers are so fast today that we are allowed to prioritize clean code, and we should.
^^ To an extent atleast, if the clean code is noticeably slower, then we should probably prioritize performance.
Yea but you really shouldnât have that problem if you do it right. Clean code is really just abstraction and extraction. It really shouldnât slow performance that often.
i'm just trying to clean my spaghetti up
Thing is
You can just extract a method which operates as the merge without being a higher order function and then itâs going to be clean enough.
Code should read like butter, and should he polite to someone reading it that didnât make it.
I can't read butter
hey there i am facing an issue with my server while playing bedwars the error shown is Internal Exception: io.netty.handler.codec.EncoderException: java.lang.NullPointerException: Cannot invoke "org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.IntList.size()" because "intlist" is null can someone help me with this issue
Send the stacktrace
Send everything that it printed when it errored
[21:47:03] [Server thread/INFO]: panda3 lost connection: Internal Exception: io.netty.handler.codec.EncoderException: java.lang.NullPointerException: Cannot invoke "org.bukkit.craftbukkit.libs.it.unimi.dsi.fastutil.ints.IntList.size()" because "intlist" is null
[21:47:03] [Server thread/WARN]: java.lang.NoSuchMethodException: net.minecraft.network.protocol.game.PacketPlayOutEntityDestroy.<init>(int)
is this what u have asked me
it's internal
what can i do to solve it
And what is the error
Is your command in plugin.yml?
What is line 33
use a switch please
the blue line
