#development
1 messages · Page 118 of 1
How would I make a blank ItemMeta object for a certain item? For some reason ItemStack.getItemMeta() is returning null (on ItemStack{Stone x 1}).
that 10000% shouldn't be the case
the only case ever getItemMeta returns null is when it's AIR
I assumed that to and it says its suppose to return a blank ItemMeta but thats not the case for some reason
Wait... read the wrong line I think. 🤦
Oh it was my config. I have 1.18 material names 🤦
What's a good way to go from &6 (string) to for example NamedTextColor.GOLD
namedtextcolor?
is that a paper color?
NamedTextColor.NAMES.value("6") iirc
Yes in paper
Thank you
nah that is for passing in the name as string, NAMES.value("gold") etc
LegacyComponentSerializer
¯_(ツ)_/¯
idk if it'd work as a replacement tho
idk how components workk
Do you have to work with components in paper or are there other solutions aswell?
I wouldnt want to work with something else
what r u trying to do?
that requires converting 6 to gold
if it's just to get the color, used NamedTextColor
if it's to convert an entire legacy string, use LegacyComponentSerializer
I have a database where I have ranks, so I want the prefix of for example a specific role to be &6&l (gold and bold)
However if this is the case I now need to make two columns with one having color and the other a boolean for bold
Oooor just have the Style json-serialized 
Oh :o
u can also store it with the NamedTextColor enum name
it's not an enum
I mean that's a good solution on my end
oh wait
for that you'll have to use decoration
exactly, that's why you'd store the serialized Style
in the db u can have gold,true :))))))))))))))))))))))
..
Nahh xD
lol
storing it as json costs you nothing
Yea true
Currently looking at the docs of kyori (for the NamedTextColor part) however I dont see how you could only put the style in a json
Ahh wait nvm I think I already understand
Ah yeah
https://paste.helpch.at/ufiwuhofex.java
any time i break a block which is what this database is for the server lags for about around 0.25-0.5s
any ideas on what i could do to make it so the server doesnt lag?
ok turns out i shouldve been doing this async not sync...
running the delete and insert queries async worked
turns out it didnt work, just stopped stalling the server while it processed the query
didnt stop the lag that nuked the server after a couple breaks
load world in server start
do the queries when server starts
then uodate blocks locally in some list or smth
and make a repeating async task to update the database
so it runs once in 5 or 10 mins
ezpz
Wouldn't it lag with even more data?
Since he said logging couple of blocks async still lags
Hello! Can anyone help me to get TPS?
This doesn't work: double tps = Bukkit.getServer().spigot().getTPS()
that doesn't look like a real method
I don't see it on the javadocs
declaration: package: org.bukkit, interface: Server, class: Spigot
maybe 1.8?
@NotNull
@org.jetbrains.annotations.NotNull double[] getTPS()```
Gets the current server TPS
current server TPS (1m, 5m, 15m in Paper-Server)
@tall anchor ^ don't call .spigot()
Huh aight, I made a mistake there, developed "Bukkit" plugin... I'll do Paper then :)
Bukkit is just the API
not sure bukkit has a method for getting the tps
Spigot and Paper are implementations
iirc people used to use nms
ye
Understood, I just chose "Bukkit Plugin" from IntelliJ "Choose plugin or mod platform".
Should've done Paper Plugin.
In spigot, how can I disable default commands like /help and so on? That players won't be able to do for example either /help or /minecraft:help
I've tried to remove their permission minecraft.command.gamemode however that doesn't work
try to negate it instead
Wdym?
if that command requires a permission, negate it
So -minecraft.command.help should do it? Because that does not work for me
Are you using Luckperms?
If so, you need to set the normal permission and set it to False instead of True
Weird it didnt do that before but now it does xD
Ty
In Luckperms, it has always been like that
PermissionsEx and GroupManager used the dash for negation though
Can you create Placeholder with BungeeCord Plugins? The wiki shows that I need org.bukkit.OfflinePlayer..?

PAPI doesnt work on bungee, so no
Alright
Lmao just askin
Is there a packet for hiding attributes? Like ItemFlag#HIDE_DYE - it's for bedrock edition so itemflag is not a possibility
I want to add a delay to one of my events. For example: When player joins it will wait for 2 secs and then it will send message but I don't know how to add that delay
you can schedule a delayed task
with a BukkitRunnable or with the bukkit scheduler, i believe bukkitrunnable is recommended
tx
if its a bungeecord plugin, commands are handled in bungeecord
connect your plugin to mysql on all your instances.
not much point having a punishment system on bungee only even if it would be convienient
?paste
Paste Services
When asking for help with a config/menu/code issue please use our paste bin:
(we prefer it over pastebin.com)
• HelpChat Paste - How To Use
wrong channel, whoops
SOO PEOPLE, how would you do a world cycler? like for minigames that switches the world every 10 minutes or so
ive thought of a class implementing Runnable and having an iterator with all worlds
would that technically work?
minigames that switches the world?
if you mean that your ffa rotates map every X minutes, then yes
a runnable and that stuff
you don't necessarily need a runnable for that
every time you're about to start a minigame, you can get the current time and use that as an offset to your list of possible maps
like if your time is for example 12:01-12:10 am you'll use map 1, if it's 12:11 - 12:20 am you'll use map 2, etc.
from there i'm sure you already have logic to load the players into the correct world and all that
you can probably do this with the modulus operator; I think the logic will be:
take current system time modulus (10 minutes in ms * # of maps)
then integer divide by 10 minutes in ms to get the int value corresponding to the map number you want to use at that time
That sounds harder than just running a runnable with an iterator
And the time measuring will still be done thru a runnable or something similar
What is the Best way to compare two guis?
I mean what is the Best way to learn is gui1 equals gui2
its not so harder..just a simple mathematics...also really performant than running a scheduler
I use InventoryHolders but it might break api sometimes
Hey, So im getting the enchants on an item with ItemStack#getEnchantments which is a map of <Enchantment, Integer> and i want to get a random enchant form that. How can i get the key?
Hello, I seem to be having trouble using this: https://paste.md-5.net/jesaxayije.nginx
Error: https://paste.md-5.net/rizohuduku.apache
My plugin has both 1.9.2 and 1.16.5 Spigot versions
I am definitely confused why it is like this, I believe 1.9.2 is interfering with it, since I've used this same method for hex colors before..
But from what I know.. it shouldn't?
"Could not parse ChatColor 0§F§FX" means that you're trying to get an invalid color code
line 85 of TipsPro
I was using #FF0000 but it didn't work with that either
Are you using bungee?
The chat color import for it?
Yeah
Yes
make sure your importing the right one
As far as I know there's only bukkit's chatcolor and bungee's chatcolor, and bungee is the right one
try bukkit
If I use bukkit's then ChatColor.of doesn't exist lol
Also ChatColor.translateAlternateColorCodes won't exist
why wouldn't it?
Fine, well for one, ChatColor.get(color) doesn't really work, color is a string, soooo I guess I'll try ChatColor.getByChar(color) ?
Hmm, nope..
Using &c&lTipsPro &8&l| #FF0000H#00FF00E#0000FFX #D49E9Bcode support! just made it look like this:
wdym time measuring?
if you're actually just measuring the time it takes to do (something), you can just subtract the final time from the initial time; you dont need to manually increment anything
Hey there, sorry if this is a noobish comment but I was using cpulimit just to host a test server locally since 1.18 was really taking a toll on the machine I use for a test server. Unfortunately after using this command
cpulimit -l 400 -- java -jar -Xmx2048M -Xms2048M server.jar nogui
I cannot type anything into the console, which is very annoying. Is there a solution to this?
dont use cpulimit?
I'm sharing it with family members and I don't want it using all the resources
is the speed of the processor (Ghz) really useful for a server or do the cores compensate?
uhh
imo at least 2-3 cores are needed
it really depends on what u do
iirc you need cpu with good single core performance
also #off-topic
or #minecraft
imo the simplest way to get access to the console in your case is simply to make use of RCON, make sure it's enabled in yout server config and you can then access the console remotely even if cpulimit doesn't let you access it locally
single threaded performance is always the bottleneck for MC servers. (so yes)
Having more than 1 core allows for some improvements to performance, especially if you're using a performance fork like Paper, but every additional core yields significantly less benefit - with 4 being the most your server can reasonably make use of
additionally, the clock speed of the processor is only one factor in determining how performant it is. CPUs made in 2011 that can run at 3.5ghz are SIGNIFICANTLY WORSE than modern cpus that run at 3.5ghz
You want modern CPUs, which usually have a higher IPC and useful features like various SIMD instructions - only pay attention to clock speed if you're comparing two cpus from the same generation
Anyone got an idea to fix this? https://paste.helpch.at/oyocuviciz.cs
I found this thread but not sure how I could add java arguments to a server
https://github.com/google/gson/issues/1875
guice?
ah lol, I'm just a little bit confused
guess that's resolved in up to date gson versions too tho
PaperMC comes with a gson version, I guess I need to remove that dependency somehow then
Or will it automatically override it if I add a new dependency?
Getting this error now, using jdk17 everywhere though
General error during conversion: Unsupported class file major version 61
java.lang.IllegalArgumentException: Unsupported class file major version 61
Could not compile settings file 'C:\Users\45512\Desktop\JAVA\NetherPortals\settings.gradle'.
Okay this doesn't make sense, my gradle version is 7.3.3 and JDK 17 which should work according to this (from gradle website) But I get the unsupported class file major version error
file > settings > build/execution/deployment -> build tools -> gradle
make sure gradle is using jdk 17
It is
Exact same JDK as the one in project structure
I have tried to invalidate caches also
So I'm trying to use this tutorial or whatever https://www.spigotmc.org/threads/packet-discovery-spectator-mode-modifications-noclip.319125/ but I got compilation error.
Error: https://paste.md-5.net/elevilovod.cpp
Code: https://paste.md-5.net/qimimipece.cpp
Same error
paste bui.d.greadle
I tried removing the gson dependency since I think it happened after adding it (not sure) but didn't work.
replace L10-L14 with sourceCompatibility = JavaVersion.VERSION_17
how about target compatibility?
useless
what is it for?
literally no clue
get rid of your "gson" repo
gradlew.bat clean build
pro tip you can run that same task from the top right of ij
don't need the gradle tab open
Oh ye, but do you know why it only works there?
This is my dir btw
C:\Users\45512\Desktop\JAVA\NetherPortals>dir
Volume in drive C has no label.
Volume Serial Number is 2CF3-1DB5
Directory of C:\Users\45512\Desktop\JAVA\NetherPortals
26/01/2022 14.39 <DIR> .
25/01/2022 23.20 <DIR> ..
25/01/2022 23.21 1.637 .gitignore
26/01/2022 14.40 <DIR> .gradle
26/01/2022 14.15 <DIR> .idea
25/01/2022 23.42 <DIR> build
26/01/2022 14.39 547 build.gradle
25/01/2022 23.20 <DIR> gradle
25/01/2022 23.20 0 gradle.properties
25/01/2022 23.20 35 settings.gradle
25/01/2022 23.20 <DIR> src
4 File(s) 2.219 bytes
7 Dir(s) 115.692.630.016 bytes free
How can I add java args to gradle?
java --add-opens java.base/java.lang=ALL-UNNAMED
Hello guys! Who know how to get an array of configuration sections like this: https://paste.helpch.at/xuxosamebo.bash
(Via bukkit configuration api)
compileJava {
options.compilerArgs.addAll(["--add-opens", "java.base/java.lang=ALL-UNNAMED"])
}```
Try this
A problem occurred evaluating root project 'NetherPortals'.
> Could not get unknown property 'compileArgs' for task ':compileJava' property 'options' of type org.gradle.api.tasks.compile.CompileOptions.
Hmm
try now
gradle loaded correctly, building now
Well
warning: [options] --add-opens has no effect at compile time
1 warning
ohhh
It has to be there at runtime also I assume
only at runtime afaik
or did you try that already
I mean there's no such thing as runtimeArgs so not sure how I would add it
you add it when you run the jar
java --add-opens java.base/java.lang=ALL-UNNAMED -jar your.jar
On in the start.bat?
Ahhh I see
Might've worked not sure, still getting this error though
[15:08:51 ERROR]: Error occurred while enabling NetherPortals v1.0 (Is it up to date?)
java.lang.reflect.InaccessibleObjectException: Unable to make field private java.lang.Object java.lang.ref.Reference.referent accessible: module java.base does not "opens java.lang.ref" to unnamed module @7568852c
I'm not, java is
what
for (JsonElement element : parser) {
dataList.add(GSON.fromJson(element, Data.class));
}
Since java 9 they use reflections for this or smth
for json
Just cant find a solution that works
you need to add the flags to the start script of your server
I did ```
java --add-opens java.base/java.lang=ALL-UNNAMED -Xms2G -Xmx4G -jar purpur-1.18.1-1531.jar --nogui
@pause
java.lang.ref isn't java.lang
Should still be included no?
New error after adding the .ref https://paste.helpch.at/cejowahili.cs
no, packages don't have any hierarchy
It has no args though
yes, and it fails to invoke that constructor
because worldName is null
at the time of invocatio of the getWorld method
That's weird
The world has been generated
and the string is indeed "world" in the plugin
Ohhh wait I might see what you mean
Not sure how else I could set it up though
Answer: I don't believe that surgical castrastion is something that is a viable method for aquaculture. Typically the method used is an induced triploidy. You are probably familiar with triploidy from eating bananas or seedless watermelons. The idea is that the triploid fish mature faster and don...
thank you
anytime
Ma'am this is #development
yes
you dont know for how long I was looking after this
purpur 🤡
not in the moment the constructor is fired
just put it in after world name
in your constructor of the data class
Will do, thanks
Yeah…
is there a way to make the code continue only after a bukkitrunnable ended?
confusion
isn't this the right repo?
https://papermc.io/repo/repository/maven-public/
im not where to ask for help, but i am trying to install buildtools on debian WSL while following this link: https://www.spigotmc.org/wiki/buildtools/#running-buildtools but I got a bunch of errors having to do with import org.bukkit.material cannot be resolved. the last one before the process ended looks like this Exception in thread "main" java.lang.RuntimeException: Error running command, return status !=0: [sh, /mnt/d/plugin-dev/apache-maven-3.6.0/bin/mvn, -Dbt.name=582a, clean, install]
trying to create my own plugins for a 1.8.8 paper server
for 1.17+ it's io.papermc.paper:paper-api:{version}
oh, same repo?
ya
k ty
uh if I were you I'd ask in the spigotmc discord about that one
there is one?
mhm
private void saveChunk(int chunkX,int chunkY,HashSet<Location> set) {
Bukkit.getScheduler().runTaskAsynchronously(FernCore.getInstance(), () -> {
try {
PreparedStatement ps = connection.prepareStatement("INSERT INTO fc_block VALUES (?,?,?,?)");
for (Location loc : set) {
ps.clearParameters();
ps.setInt(1,getWorldID(loc.getWorld().getName()));
ps.setInt(2, (int) loc.getX());
ps.setInt(3, (int) loc.getY());
ps.setInt(4, (int) loc.getZ());
ps.addBatch();
}
ps.executeBatch();
} catch (SQLException e) {
Bukkit.getLogger().log(Level.SEVERE, "FAILED TO SAVE CHUNK AT "+chunkX+", "+chunkY);
e.printStackTrace();
}
});
}
is this a decent method for inserting the chunk into the db?
or should i split it up so that it handles lets say every 256 requests or smth
is there a way to make a delayed task inside of a for loop?
how do I write a BitSet into a ProtocolLib PacketContainer?
do you depend on vault?
he's probably making it wrong
Vault is the first plugin loading
so even if he didnt add the depend or soft-depend
yes, it's in plugin.yml
it would still return true
followed literally https://github.com/MilkBowl/VaultAPI
Yeah
it says:
if (getServer().getPluginManager().getPlugin("Vault") == null) {
make sure you have that
yup
1s
d;spigot PluginManager#ispluginenabled
boolean isPluginEnabled(@NotNull String name)```
Checks if the given plugin is enabled or not
Please note that the name of the plugin is case-sensitive.
name - Name of the plugin to check
true if the plugin is enabled, otherwise false
this is better
the thing is... vault is enabled xD
but yes will use that
^^ my main
just noticed, forgot to remove Strings.format lol
that doesnt mean vault is not loading
that means there is no economy plugin loaded
which added the economy class
to the provider
...
vault is an API
"requirement": {
"trigger": "minecraft:entity_hurt_player",
"conditions": {
"damage": {
"dealt": {
"min": 12,
"max": 30
},
"blocked": true,
"source_entity": {
"type": "earth:rubro",
--> "nbt": "{Deepslate:0}" <--
}
}
}
}``` Does the NBT section check that the source entity matches the given nbt?
That's what I understood from this
But it doesn't really seem to be working
is there a good way of translating https://wiki.vg/Protocol to protocolLib calls?
Hey so I'm serializing an object to json but I need to create a custom constructor to also create a Location variable, but my initialize method isn't running, does someone know why?
Constructor and method: https://paste.helpch.at/cabokiloha.java
GSON serialization: https://paste.helpch.at/tuxiyumufu.cs
Issue is really just that my getter for the location returns null.
you need a custom TypeAddapter in that case
try this, so {damage:{type:{source_entity:{ }}}}
Where
3rd arrow should point to source_entity mb
Hmm, I think I'll just do this
public Location bukkitLocation() {
return new Location(Bukkit.getWorld(worldName), x, y, z);
}
public void setLocation(Location location) {
worldName = location.getWorld().toString();
x = location.getBlockX();
y = location.getBlockY();
z = location.getBlockZ();
}
Not sure if it's bad for performance or not tbh
I just need to null check ofc
"requirement": {
"trigger": "minecraft:entity_hurt_player",
"conditions": {
"damage": {
"dealt": {
"min": 12,
"max": 30
},
"blocked": true,
"type": {
"source_entity": {
"type": "earth:rubro",
"nbt": "{Deepslate:0}"
}
}
}
}
}```
i'll try that, if it doesnt work Ill try figuring it out tomorrow I was about to go to sleep 😅 thank you tho
and make sure the entity has that exact nbt
That's impossible
Cause it will have other NBT like age noAi
Age especially is impossible to replicate
I thought that it wasnt working because I need the same exact NBT
I don't think it checks 1:1
but rather "contains"
what I meant is, check if the entity has Deepslate:0 using your code or whatever
is that tag inside a compound?
So now it works no matter the NBT
Wait wht
I'm confused, hold on
Nah it doesn't work I think
what if you remove the NBT?
and, can you send the NBT of the entity?
im about to go to sleep as well, maybe we can figure this out really quick
I have no clue how to check an entity's NBT
The debug stick doesnt do anything
Removing the NBT also doesnt work
there should be a selector or whatever, /data get, could also use an EntityDamageEven
Keep in mind I am using Fabric now 😂 but I asked help here since jsons work the same everywhere
Should I send the NBt of the entity that should work?
Don't mind the italian bit, was testing out my translation file
If it doesn't work it's alright, I can make the advancent work through other means
I'm going to sleep now tho, goodnight!
Anyone know any useful API's?
chunks that are positive work fine when loading data from sqlite, chunks that are in negatives do not.
weird
they work, but they are offset by 1 chunk
currently using "SELECT wid,x,y,z FROM fc_block WHERE wid = ? AND x / 16 = ? AND z / 16 = ?" to figure out the data that wouldve been in the chunk
flooring didnt work, just broke more things, i found a solution, just storing the chunk X and Z with the location entry.
I mean flooring 100% works
that's how the game calculates the chunk coord from the absolute block coord lmao
well i tried using floor and it was the same as without it
maybe its cause i specified 16 instead of 16.0
¯_(ツ)_/¯
ive had autocommit on all this time...
no wonder it was so sluggish
that change made my plugins's disable finish in ms instead of a few seconds
the limiting factor now is the chunk amount, which i can do the same thing with and just leave world size cause at most its 3 or 4 worlds
Does anyone know how to unregister a village so that whenever someone comes there with bad omen there won't be a raid?
WorldGuard doesn't seem to have a flag for that. What I'm trying to do is deny getting raids on spawn village, pillagers can't spawn there anyway (denied spawning), but people still lose their bad omen effect.
Is any way to disable that village from triggering raid therefore losing bad omen?
iirc there is an event for structure spawn
There's raid start event I could cancel
But thought maybe I could use some built-in solution, wouldn't want to create yet another plugin for cancelling one event...
whats the place holder to put someone's xp on a scoreboard?
I use animated scoreboard if that makes a dif
Can someone familiar with kotlin let me know what these lines are doing? I'm trying to do something similar in Java.
https://github.com/akkinoc/yaml-resource-bundle/blob/main/src/main/kotlin/dev/akkinoc/util/YamlResourceBundle.kt#L163-L166
my intuition, is that the value strings will contain a sequence of key, string[] if ALL entries in the list are strings?
That’s why most make “Cores” a plugin that does a bunch of small things
Likely your best option
Trying to "read" my custom flag, but can't do it... My JAVA is pretty basic so please help me out.
I register custom flag with this: https://worldguard.enginehub.org/en/latest/developer/regions/custom-flags/
And how can I read it in events class?
For example:
Player player = event.getPlayer();
Location loc = BukkitAdapter.adapt(player.getLocation());
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = container.createQuery();
ApplicableRegionSet set = query.getApplicableRegions(loc);
for (ProtectedRegion region : set) {
// Check if region has RAID flag true/false (allow/deny)
}
I'll try, maybe this works:
if (region.getFlag(plugin.RAID) == StateFlag.State.DENY) {
Hey so I'm serializing an object to json using this serializer https://paste.helpch.at/culabucuha.cs
But the values in the object (https://paste.helpch.at/xebumugefi.java) are for some reason not being set since the world debug prints, and I am 100% the world name is correct and there is indeed a world loaded with that name, it shows in console when server starts.
Okay so first can you show me this data within the file itself
Secondary can you show me a debug of all of those lines printed out when requesting them
Including worldName
Here
Like this I assume?
for (JsonElement element : parser) {
Data data = GSON.fromJson(element, Data.class);
LOGGER.error(data.toString());
dataList.add(data);
}
Prints this
If you wouldn’t mind putting it in a paste for me I’m on a phone rn
Thx
worldName = location.getWorld().toString();
Isn’t it meant to be getName()
Ohh wait nevermind maybe not
Probably... testing now
Btw it also creates this for some reason
That json file shouldn't be there
The correct one is in the NetherPortals directory in plugins folder
Check around there will be a reference somewhere
Perfect
Just confused why that file is there
Only file in my plugin is this File file = new File(netherPortals.getDataFolder(), "portals.json");
toString isn't a method of WOrld
Lol yeah
Me realised
It is, caused no error at least
It’s inherited
Ah yeah probably
He is correct
it's inherited from object but it won't show on docdex because docdex sees world as an interface, which doesn't directly inherit object
the implementation of world does
Makes sense
Ahhh yeah ty
But anyway sounds like your issues have been resolved now
Idk there will be a call somewhere but it might be really indirect
Ohhh it's from here
public void updateDataFolder() throws IOException {
for (Data data : dataList) {
GSON.toJson(data, new FileWriter(netherPortals.getDataFolder() + "portals.json"));
}
}
I thought it would make a path to the NetherPortals folder though?
Oh yeah true
Or listen to big daddy supposing he is here
File.SEPARATOR is when you need to show a path to a user with their operating system's separator character
java's file system uses forward slashes
Interesting
Well I guess some of my stuff has potentially hidden bugs in it
Fun fun
Lmao, alright well adding a / would be a bit simpler lol
it should still work with File.SEPARATOR, or even if you use backslashes like when on windows
it's just you don't need to
forward slashes work perfectly fine on all operating systems in java
not sure how the separator works so yeah
perfect
I use it more for my own sake when reading back I clearly see I’m trying to separate
But honestly the way you suggested is easier
is data empty?
I guess I need more to deserialize
for (Data data : dataList) {
GSON.toJson(data, new FileWriter(netherPortals.getDataFolder() + "/portals.json"));
}
???
now**
Now that’s a double negative if I’ve ever seen one 😂
mb haha
This just doesn't write anything, kinda confused why
first debug by checking if data is being properly converted to json
so just sout gson#toJson(element)
get rid of the file stuff
Alright, testing now
It's printing this
From this LOGGER.error(GSON.toJson(data));
Looks like correct json format
I'll try that now
valdemarF
that might make sense since 0b tells minecraft it's a boolean
idk why it's doing that
but it doesn't matter because this system won't work anyway as is
instead of looping through data and writing each individual datum, simply write the whole list at once
GSON.toJson(dataList, blah)
expanding on this if it appended each datum, it wouldn't be valid json
Oh didn't know that was a thing... ty
Because it would need a new line every time?
To append properly?
no, json doesn't care for new lines
it's just not valid json
it'd look something like this
{"blah": "yes"}
{"blah": "yes"}
{"blah": "yes"}
it needs to look like
[
{"blah": "yes"},
{"blah": "yes"},
{"blah": "yes"}
]```
^ serializing the list will do that
Yeah... That's what I'm trying to do, I thought this would serialize it though
your loop does this in theory, which gson wouldn't be able to deserialize
This would be proper json format right?
[{"worldName":"world","x":-209,"y":70,"z":34},{"worldName":"world","x":-201,"y":66,"z":35},{"worldName":"world","x":-205,"y":68,"z":37},{"worldName":"world","x":-297,"y":65,"z":29}]
Yup that's what I just did, I'll test with filewriter now
if the file writer thing doesn't work then I'd try an alternative approach to writing the file, e.g. Files.write
Files.write works I believe
[{"worldName":"world","x":-209,"y":70,"z":34},{"worldName":"world","x":-201,"y":66,"z":35},{"worldName":"world","x":-297,"y":65,"z":29},{"worldName":"world","x":-205,"y":68,"z":37}]
I'll just make new lines to make it more readable
But thx a lot for helping! :))
new GsonBuilder().setPrettyPrinting().create();
This is the json file
show me how you load it
Ohhh yeah I load it as a named array
JsonArray parser = JsonParser.parseReader(reader).getAsJsonObject().get("portalsData").getAsJsonArray();
This is the initial json file which is loaded correctly https://paste.helpch.at/murotumagu.json
JsonParser.parseReader(reader).getAsJsonArray()
Thanks
@dense drift It worked! Deepslate:0b, needed to specify that 0 is a boolean and not an int! thank you!
nice
It makes sense it works this way
otherwise what would be the point 😂
But I guess that if I want to see if the entity's age is above a value
that's impossible
I have a question I use PufferPannel for my server and I want to define 3-4 CPU cores / servers do you know how I can do that ?
How can I specify a json object name when writing to a json file?
show me an example of the json you want to generate
This
"linkedPortals": [
{
1:3,
2:4
}
]
I think I can read it like this
Type typeOfHashMap = new TypeToken<Map<Integer, Integer>>() { }.getType();
linkedPortals = GSON.fromJson(JsonParser.parseReader(reader).getAsJsonObject().get("linkedPortals").getAsString(),
typeOfHashMap);
So I just need to write it somehow
any chance you're using guice
dependency injection framework
just asked because it has a util that makes typeOfHashMap a bit cleaner
Types.mapOf(Integer.class, Integer.class)
Ahhh yeah a lot cleaner tbf
Ummm?
.
It's not stored in the data instance anymore
show me how you're saving it
It's just in my manager class
And then this runs when I start the server
Type typeOfHashMap = new TypeToken<Map<Integer, Integer>>() { }.getType();
linkedPortals = GSON.fromJson(
JsonParser.parseReader(reader).getAsJsonObject().get("linkedPortals").getAsString(),
typeOfHashMap);
you know there is one easy way to do this
Would be great lol
instead of deserializing all these parts of your config individually
just create one object that represents your entire config
Yeah I was wondering if that would be better for performance, but kinda wanna know how I save a named object to a json file
you pass in an object or a map that has the same structure as the json you want it to generate
or you can build the json manually with jsonobject or whatever gson provides
performance wise, it doesn't make any difference, it's a quality thing
Wait does it automatically compare the names from the json file with the java object name then?
yes
That explains a lot, but how would you store it all in one instance? I only have one linkedPortals map and a lot of locations from data?
Just wondering
show me your config
This is the idea https://paste.helpch.at/eduyamaras.cs
wait no
paste is missing smth
Basically every data instance also contains an id
which is how I'm linking them in the linkedPortals
can you paste the correct config
Idk why it's indented like that but yeah
Idk why it's indented like that but yeah
Idk why it's indented like that but yeah
mix of tabs and spaces likely
Probably yeah
Would preferably have it like this also
"portalLocations": [
{
"worldName": "world",
...
To name the list
But doesnt matter much for now
aight
public final class Config {
private List<PortalLocation> portalLocations;
private List<Map<Integer, Integer> linkedPortals;
public List<PortalLocation> portalLocations() {
return portalLocations;
}
public List<Map<Integer, Integer>> linkedPortals() {
return linkedPortals;
}
}
public final class PortalLocation {
private String worldName;
private int x;
private int y;
private int z;
private int id;
// getters
}```
public final class Config {
private List<PortalLocation> portalLocations;
private List<Map<Integer, Integer> linkedPortals;
public List<PortalLocation> portalLocations() {
return portalLocations;
}
public List<Map<Integer, Integer>> linkedPortals() {
return linkedPortals;
}
}
public final class PortalLocation {
private String worldName;
private int x;
private int y;
private int z;
private int id;
// getters
}```
public final class Config {
private List<PortalLocation> portalLocations;
private List<Map<Integer, Integer> linkedPortals;
public List<PortalLocation> portalLocations() {
return portalLocations;
}
public List<Map<Integer, Integer>> linkedPortals() {
return linkedPortals;
}
}
public final class PortalLocation {
private String worldName;
private int x;
private int y;
private int z;
private int id;
// getters
}```
think discord is dying
took 3 tries to send that code block
Yeah I couldnt send before either
but anyway gson can fully handle those objects
you'd just go gson.fromJson(str, Config.class)
gson.toJson(config)
And then the same with PortalLocation I assume, and then add them all to the portalLocations list in Config class?
Ohhh yeah I see
Smart!
I'll try
Wouldn't I need this?
Reader reader = new FileReader(file);
JsonArray parser = JsonParser.parseReader(reader).getAsJsonArray();
for (JsonElement element : parser) {
config = GSON.fromJson(element, Config.class);
}
Not sure how you would retrieve that String or Element otherwise
config = GSON.fromJson(Files.newInputStream(file), Config.class)
or smh like this
config = GSON.fromJson(Files.newInputStream(file), Config.class)
or smh like this
discord dying
doesnt want to send my messages
config = GSON.fromJson(Files.newInputStream(file), Config.class)
or smh like this
discord dying
config = GSON.fromJson(Files.newInputStream(file), Config.class)
no
Kinda worked but this? config = GSON.fromJson(String.valueOf(Files.newInputStream(file.toPath())), Config.class);
String.valueOf won't work for that
idk it should take an InputStream
Oh
just pass in file reader
also make sure to put a name on the portal location array
in the json
and a comma after the array ends
(the json you pasted earlier is invalid)
Not the parser?
Oh nice
- gson.fromJson(str, Config.class)
- gson.toJson(config)
these are like the only two gson interactions u need
This should be valid right? https://paste.helpch.at/ufimiqunah.bash
missing a comma l31
Ohhh yeah since it's all in one object now
And it's not possible to just make this into a map?
public Set<Map<Integer, Integer>> linkedPortals() {
return linkedPortals;
}
aight nice
and alter the json accordingly
Says it expects a name here but there's already one?
"portalLocations": [
paste json
what's the exact error
Might be wrong indentation?
I probably used space or smth
Is it required to use tab?
no
Ummm that's weird, I used tab instead, idk why, and got this error instead of the other one https://paste.helpch.at/ifomulovit.bash
the config doesn't accurately represent the json
you updated the config to use a map, but not the json
How can I change the compiler on gradle project? Basically I have a same problem like on this spigot thread (https://www.spigotmc.org/threads/cannot-access-net-minecraft-server-v1_16_r3-packetplayoutplayerinfo-playerinfodata.497496/) and I don't know how to change the compiler in gradle.
And this is the compiler https://mvnrepository.com/artifact/org.codehaus.plexus/plexus-compiler-eclipse/2.9.0
eclipse 🥶
jdt 
I have to 😮💨
IntelliJ literally exists
I'm using IntelliJ but I need to use eclipse compiler to fix the problem that I have right now.
oh no
where can I get help pls?
Ask your question in the requisite channel
requisite?
The channel that suits your needs
If it's a development problem, this channel
General plugins, #general-plugins
okay thx
If someone know how to do this, please help me out
Hello guys! Who know how to build gradle sub modules with different java versions? (Like, module1 will use java 8, module2 java 16 and etc.)
in each build script set the language version the compiler will use and emit
tasks.compileJava {
options.release.set(11)
}
or 8, or 9, or 17, you get the idea
Good, in which section of the config, can I disable the special characters? Since I can't find it, thanks.
Uh, what is "the config" you're talking about? Also what special characters?
got it, ty
THE CONFIG
This "chat_illegal_characters"
what
Again, which config?
I'm with the DeluxeChat plugin and I want to disable the "chat_illegal_characters" option, but I can't find the option in config.yml
Spigot Account Linking
To get support for a premium plugin owned by Clip or Glare you will need to verify your spigot account using =spigot in the #bot-commands channel. After you have successfully linked your spigot account you should ask your question in the coresponding channel for that plugin. If you have already linked your account and want to update your roles, run this command =spigot check.
Can someone help?
Could not compile settings file 'C:\Users\45512\Desktop\JAVA\Infection\settings.gradle'.
> startup failed:
General error during conversion: Unsupported class file major version 61
java.lang.IllegalArgumentException: Unsupported class file major version 61
Project SDK is 17
Gradle JVM is 17
Gradle version is 7.3.3
It works when using the gradle task in the menu of right side, but not when ran through console in IntelliJ
Does anyone know what packet(s) enable the spectator shader for creepers, spiders, etc?
i'd expect it's client side
well how does it know when to enable it?
although i have no evidence whatsoever
client knows when you've clicked an entity
https://www.youtube.com/watch?v=1fcCgzr2gfY
via a bunch of packets in quick succession could I abuse this server-side?
probably
but yeah there is no packet for "apply shader", it's handled by the client depending on the entity you're spectating
.
I'm running gradle buildJar but it happens in all my plugins
Even with the simplest build task
Also happens in this https://paste.helpch.at/sedobudojo.coffeescript
Could it be openjdk 17 that doesn't work properly or something? It's downloaded from Oracle
run and share the output of gradle -v
C:\Users\45512\Desktop\JAVA\Infection>gradle -v
------------------------------------------------------------
Gradle 7.0.2
------------------------------------------------------------
Build time: 2021-05-14 12:02:31 UTC
Revision: 1ef1b260d39daacbf9357f9d8594a8a743e2152e
Kotlin: 1.4.31
Groovy: 3.0.7
Ant: Apache Ant(TM) version 1.10.9 compiled on September 27 2020
JVM: 17 (Oracle Corporation 17+35-2724)
OS: Windows 10 10.0 amd64
Oh yeah gradle 7.0.2 in this but it should still work with any version above 7
eh yesn't
Wait doesn't it need 7.3?...
7.3.3 is the latest but yeah
Yeah...
It is 7.3.3 in the gradle-wrapper properties file though
Figured it out ^^^
right, and IJ is using that one
but you're trying to use the one installed in your system which is this one
use relative file locs
¯_(ツ)_/¯
../ to exit a dir
so I think ../Paper18/plugins
(it's ../. in this case because the folder name is .TestServers in case u got confused from that)
hey! I have a plugin that does loads of stuff when a player joins the game, I have done my best to optimize it, but I am still getting some weird issues. If I restart the server, and a player joins, they sit with the world unloaded for multiple seconds, before everything loads in. Every other time they connect, it is perfectly fine. And the funny this, I am not caching anything, so idk why this is happening.
show code
and do they sit with the world unloaded for some time without the plugin?
it can also be caused by a low-end server
no
it definitely is the plugin,
the code is all over the place
@EventHandler
public void onPlayerJoin(PlayerJoinEvent e) {
Player p = e.getPlayer();
LobbyPlayer newP = new LobbyPlayer(p);
PlayerUtils.addPlayer(newP);
Bukkit.getScheduler().scheduleSyncDelayedTask(LobbySystem.getInstance(), () -> {
DatabaseUtils.initialJoin(e.getPlayer());
}, 40);
p.setHealth(10);
newP.sendLoginMessage();
e.setJoinMessage("");
}
that is my on player join
Bukkit.getScheduler().scheduleSyncDelayedTask(LobbySystem.getInstance(), () -> {
DatabaseUtils.initialJoin(e.getPlayer());
}, 40);
```does this run database code sync or async?
as far as I know async
scheduleSyncDelayedTask runs sync
in initialJoin do u have anything that redirects it to async?
no
then it's running sync rn
yeah
you'll have to do Bukkit.getScheduler().runTaskLaterAsynchronously
forget about the db thing
assuming that LobbyPlayer and PlayerUtils.addPlayer doesn't run any heavy/database calls either
the lobbyplayer runs a ton of db calls
it gathers a bunch of information in one call
public static ArrayList<Object> getPlayerValues(Player p) {
MongoDatabase database = mongoClient.getDatabase("player-data");
MongoCollection<Document> col = database.getCollection("main");
Document filter = new Document("id", p.getUniqueId());
ArrayList<Object> values = new ArrayList<>();
for (Document doc : col.find(filter)) {
values.add(doc.get("exp"));
values.add(((Date) doc.get("first-join")).toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime());
values.add(doc.get("shark-scales"));
values.add(doc.get("gold"));
values.add(doc.get("chat-color"));
values.add(doc.get("welcome-message"));
return values;
}
return values;
}
that's probably why - the server is halted until all of the database data is retrieved
yeah do that bad boy async
in here none of this is running async
or do a spark profiler with only long tick times if you want to be sure
I ran some System.out.println() and the print appeared in console almost immediately yet the player was still stuck in mid air.
where did you put the print?
do this to find out then
And I also dont understand why this only happens on the first join when a server restarts
and can you try removing the listener and seeing if it's still happening?
Why is a display name null if i didnt rename the original item?
if it isn't, then run spark report
oh right its only first join
hmm
because getDisplayName only returns a custom name
right before return values;
not the vanilla name
can i get the vanilla name?
(since it doesn't use a hardcoded string, it changes based off of the language and resource pack)
lemme see, gimme a min
try doing it after e.setJoinMessage
this part is a bit odd tho
ye
but the other thing is
is that the db calls change the items in the player inventory and the stuff that appears on screen, If for like 3 seconds they dont see that, it would look very janky
if I used async ^^
and Hypixel has to do a bunch of that stuff and they dont have a problem
so idk what is different
caching 😌
wdym?
that too
their cache must be terrabytes
if you need speed, use Redis or something and keep that shit loaded into memory
You'd be surprised how little they need to cache
I have never had this issue on any other network
99% of their stuff doesn't have persistence
never suspended in air
I mean just run a damn spark report
We can sit here all day speculating
Or we can find out immediately
yeah, it produces the print right as the players world loads
hmm
can you try removing the listener and see if it still happens?
and just to make sure: if you remove the plugin entirely this does not happen?
it does not happen if I remove the plugin entirely
I can try again if you would like
^^^^^^^^^^^^
🥲
it runs perfectly fine without the listener
huhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
very odd
I think it has to do with creating a new LobbyPlayer
ye but u said the print printed out instantly
public LobbyPlayer(Player player) {
p = player;
RegisteredServiceProvider<LuckPerms> provider = Bukkit.getServicesManager().getRegistration(LuckPerms.class);
LuckPerms lp = provider.getProvider();
user = lp.getUserManager().getUser(player.getUniqueId());
rank = user.getPrimaryGroup();
ArrayList<Object> values = DatabaseUtils.getPlayerValues(p);
chatColor = ChatColor.valueOf((String) values.get(4));
scales = (int) values.get(2);
playerVis = VisibilityUtils.generateItem();
joinMessage = (int) values.get(5);
gold = (int) values.get(3);
updateSocials();
createProfile();
updateInv();
updateDisplayName();
currentInv = p.getInventory();
Bukkit.getScheduler().scheduleSyncRepeatingTask(LobbySystem.getInstance(), () -> p.spigot().sendMessage(ChatMessageType.ACTION_BAR, new TextComponent("\uDB86\uDDFA" + Translator.numToUni(Translator.formatInt(gold)))), 0, 40);
}```
oh wait
that was just the db call
Bukkit.getScheduler().scheduleSyncDelayedTask(LobbySystem.getInstance(), () -> {
DatabaseUtils.initialJoin(e.getPlayer());
}, 40);
```it might be this part, since it runs 2 secs after which might not be enough for the player to load it? 🤷
I removed that
or did u try that already
hmmmmmmmmmm
I did that to
it printed right as the clients screen loaded
loaded into the server or loaded into the world?
so it has to do with something inside the listener
into world
alright i need to ignore this conversation
y'all are trying to sink a nail with your hand while a hammer sits right next to you
is it a plugin?
yes
yes
sort of
and you can set it so that it only profiles during ticks that are extra long
in console (before player joins): spark profilerthen once the player joins and the world loads, do /spark profiler --stopas a player cmd or ```
spark profiler --stop
then send the link that it generates here
wait
so like
I have a custom skull thing
and I guess that is literally causing all the issues
ooof
I'm guessing it takes about 4 seconds slower for the player to load in?
ye
seems like something in SkullUtils.getCustomSkull
yeah
public static ItemStack getCustomSkull(String id) {
String url = "http://textures.minecraft.net/texture/" + id;
GameProfile profile = new GameProfile(UUID.randomUUID(), null);
PropertyMap propertyMap = profile.getProperties();
if (propertyMap == null) {
throw new IllegalStateException("Profile doesn't contain a property map");
}
byte[] encodedData = base64.encode(String.format("{textures:{SKIN:{url:\"%s\"}}}", url).getBytes());
propertyMap.put("textures", new Property("textures", new String(encodedData)));
ItemStack head = new ItemStack(Material.LEGACY_SKULL_ITEM, 1, (short) 3);
ItemMeta headMeta = head.getItemMeta();
Class<?> headMetaClass = headMeta.getClass();
ReflectionUtils.getField(headMetaClass, "profile", GameProfile.class).set(headMeta, profile);
head.setItemMeta(headMeta);
return head;
}```
I think what's happening is that spigot is connecting to that URL synchronously which is where the 3.5 seconds come from
this is getting a custom skull for the socials
so I think I can handle this on startup
and create a new instance and then just edit the lore when the player joins
since it says that the lag is caused when the ItemMeta is made
but the player head wouldn't be changed
does this require being sync? or could you run this async?
ah
it doesnt need to be different per player
I think a player head updating 4 seconds later is better than a player floating in midair for 4 seconds 🙃
🥲
ye
although note that interacting with the world async is unsafe (I think spigot throws an error) so you'll have to run the code async using runTaskAsynchronously/etc then when you get the ItemStack, you go back to sync: runTask and set the block
k
LobbyPlayer.sendLoginMessage and PlayerUtils.getPLayerLevel are also each taking up 44ms (so 2 ticks in total), so you'll want to run those async also
btw in the future, for reading spark reports you just go to the top right and click this: https://i.imgur.com/7ibnPB2.png until it says sources, then where you see your plugin you click Server thread then that's where you can see where it's lagging the server
yeah ik
alr
pog
I made it call the textures.minecraft.net when the plugin loads
and then just grab that item whenever the player needs it
also
for Redis
I have it setup, and I use it for a few things, but how would I store a bunch of player stuff? cause as far as I know I can only store strings, kinda like a hashmap
with a key and a value
would I do like "<player_uuid>.gold", "2837"?
Oh yeah good idea, testing now
Considering a someCompletableFuture which is doing some heavy task, is there difference between those 2? Is thenApply going to block thread waiting for someCompletableFuture to finish?```java
someCompletableFuture.thenApplyAsync{
//some code
}
someCompletableFuture.thenApply{
//some code
}
Hey! Does Bukkit/Spigot/Paper have "village entry" event?
I know there's "RaidTriggerEvent" that gets triggered when player enters a village and has bad omen.
But I'd still have to use some event for triggering.
Why? You can just run this in a runnable and checking within a specific radius
True, maybe 10sec timer or something
Yeah
Would you happen to know if its possible to cancel "removing bad omen" effect, when triggering RaidTriggerEvent?
At the moment I'm using "EntityPotionEffectEvent" to see if Bad Omen gets removed from player when it shouldn't, but it's very spammy...
Not even sure why Bad Omen gets removed even with RaidTriggerEvent is cancelled - maybe it's a bug.
is there a way to get the names of all different types of entities?
d;fields spigot entitytype
org.bukkit.entity.EntityType%HOGLIN
org.bukkit.entity.EntityType%FISHING_HOOK
org.bukkit.entity.EntityType%SHEEP
org.bukkit.entity.EntityType%SNOWMAN
org.bukkit.entity.EntityType%SPECTRAL_ARROW
org.bukkit.entity.EntityType%TURTLE
org.bukkit.entity.EntityType%IRON_GOLEM
org.bukkit.entity.EntityType%VEX
org.bukkit.entity.EntityType%EXPERIENCE_ORB
org.bukkit.entity.EntityType%SILVERFISH
org.bukkit.entity.EntityType%CAVE_SPIDER
org.bukkit.entity.EntityType%MAGMA_CUBE
org.bukkit.entity.EntityType%ELDER_GUARDIAN
org.bukkit.entity.EntityType%MINECART_TNT
org.bukkit.entity.EntityType%MINECART```
that enum has all the entities
can call Enum#values then #getName on all the values
turns out getName is deprecated actually you're meant to call getKey I think
if i have a plugin that requires pemission.1 permission.2 etc etc
but i want to allow also permission.2-5 for ranges, what would be the best way to make it?
Filter their permissions and then get the numbers?
you mean get (effective) permissions and that stuff?
check if format is similar, get the min-max part, separate by dash
Yeah or using vault (if it has such function)
If you are looking for a certain value, could be worth to see if they have that permission first
yeah, already doing that
just wondering if there was another option
maybe something i was missing

Well, since permissions are just some strings and don't have a set format, i don't think there's many options
Could also keep a cache of permission -> range in case you are checking for this frequently
A Cache<String, Pair<Integer, Integer>> maybe
If you have such function, they will xd
it's disabled by default, its hidde in config
otherwise they need to use
heads.1 heads.2 heads.3 heads.4
and so on until heads.42000

Then why do you add it if is hidden lol
hi, im looking up for a way to place blocks randomdly using worldedit/fawe. I have been searching but there's not more results than 5 or 6 and all of these are above 1.8 spigot, which is in the version where im developing ;/
1.8
I'm sorry to hear that 😟
im not
🥸
im knot

What is [20:47:57 WARN]: Enabled plugin with unregistered PluginClassLoader? When I use my plugin's reload command it says this.
what the hell are you doing in your reload command
send message to sender and
Bukkit.getPluginManager().disablePlugin(plugin);
Bukkit.getPluginManager().enablePlugin(plugin);
No
oh god
Dont
Bukkit#shutdown
What should I do instead?
I'm adding placeholders to PAPI, Should I register placeholders again at reload?
no
Yo, how can I turn a List<String> into a List<Component>? (I want to set the lore of an item, but newer versions need component lol)
d;adventure Component#text
@@Contract(pure=true) @@NotNull
static TextComponent.Builder text()```
Creates a text component builder.
4.0.0
a builder
if they're legacy strings you'll want to use the LegacyComponentSerializer tho
wdym with legacy strings
&cHey
or § but that's the "idea"
oh ye then yes, I am using those
but the thing is, doesn't Component.text only accept a string as input
not a list of strings
Component.text doesn't convert legacy colors
for loop 
_ _
ik, but that's not the issue rn.
well you can use this
or this
k ty
Hi, I have a problem registering custom placeholders using PlaceholderAPI.
This is my code:
getConfig().getStringList("connected-servers").forEach(server -> {
sqlModules.addServer(server);
PlaceholderAPI.registerPlaceholderHook("adminutils_" + server, new EZPlaceholderHook(this, "adminutils_" + server) {
@Override
public String onPlaceholderRequest(Player p, String s) {
return String.valueOf(getSqlModules().getOnlinePlayers(server));
}
});
});```
The list is this:
```YML
connected-servers:
- "lobby-1"
- "event"```
But when I try `/papi parse me %adminutils_event%` it returns %adminutils_event%. Could someone help me out?
use the PlaceholderExpansion instead of EZPlaceholderHook
And how whould I do that?
i am also very confused about what is happening there
wait what is EZPlaceholderHook
im pretty sure its the very very very old way of registering expansions
oh 🥲
i think it was even taken out in newer versions
@hushed badge When I try to use this, it says that the #registerPlaceholderHook() is gonna be removed. Do you know what I can use for something like this?
getConfig().getStringList("connected-servers").forEach(server -> {
sqlModules.addServer(server);
PlaceholderAPI.registerPlaceholderHook("adminutils_" + server, new PlaceholderHook() {
@Override
public String onRequest(OfflinePlayer player, @NotNull String params) {
return String.valueOf(getSqlModules().getOnlinePlayers(server));
}
});
});```
"'registerPlaceholderHook(java.lang.String, me.clip.placeholderapi.PlaceholderHook)' is scheduled for removal in version 2.13.0"
follow the guide, u should be creating a new class that extends PlaceholderExpansion, and to register that expansion u would use new YourClassThatExtendsPlaceholderExpansion().register(), and only register this once, so preferably in onEnable()
PlaceholderHook and EZPlaceholderHook are both the old ways of creating expansions 🥲

So I'm using the Paper API currently for a plugin, but I also want it to support Spigot.
I'm mostly only using it for components, and also I used the armor change event.
What would be the best way to support Spigot too?
Should I separate them into modules?
Separate modules or don't use Paper API and use just the Bukkit platform of adventure
This can be static since it's just a config util right?
doesnt look like a util to me
Ye
I guess I'll switch to bukkit then
i'm working on something where i need to modify or cancel the player's chat message, but having venturechat on the server breaks it. i found their VentureChatEvent, but it can't be modified or cancelled. so far i've tried listening to AsyncChatEvent with priority = highest. i also considered copying how they send messages to players in their chat listener, but i don't think that'll work. any ideas?
anyone know why this code isnt working? im not getting any errors, and i use this EXACT same code all over my plugin
public class OnRespawnEvent implements Listener {
private Classes main;
public OnRespawnEvent(Classes classes){
this.main = classes;
}
@EventHandler
public void onRespawn(PlayerRespawnEvent e) {
Player ply = e.getPlayer();
UUID plyID = ply.getUniqueId();
String calledClass = main.getConfig().getString(String.valueOf(plyID));
// String realClass = CustomConfig.get().getString(calledClass);
if (calledClass != null) {
for (String section : CustomConfig.get().getConfigurationSection(calledClass + ".effects.").getKeys(false)) {
PotionEffectType type = PotionEffectType.getByName(CustomConfig.get().getString(calledClass + ".effects." + section + ".type"));
int potency = CustomConfig.get().getInt(calledClass + ".effects." + section + ".potency");
ply.addPotionEffect(new PotionEffect(type, Integer.MAX_VALUE, potency));
}
}
}
}```
Does the order which advancements are shown in the advancement tab depend on anything
or is it semi random
Yeah but
Why is the line of advancements following the iron pickaxe above the deepslate one
And not the other way around
If I had to guess it's alphabetical order tbh
It's not
What other order could it be then
Online it says it's based on file name but doesnt seem like it to me
Does
Bukkit.broadcast("message", "permission")
sends message to Operator's who don't have specified permission?
d;spigot Bukkit#broadcast
public static int broadcast(@NotNull String message, @NotNull String permission)```
Broadcasts the specified message to every user with the given permission name.
message - message to broadcast
permission - the required permission permissibles must have to receive the broadcast
number of message recipients
Broadcasts the specified message to every user with the given permission name.
tx
Paste Services
When asking for help with a config/menu/code issue please use our paste bin:
(we prefer it over pastebin.com)
• HelpChat Paste - How To Use



