#development
1 messages · Page 127 of 1
i dont think you get the idea
x,y,z
cause blocks can have the same coords
a column for each axis
but different worlds
and? save world too lol
ik i tried that but it was a lot more complicated
why are you creating a new GetSql every time u make a call yo
still dont get why you "loop columns"
first time working with mysql i guess
First off
u should use sql pools
not instantiate a new connection everytime
and you know the column names so just use those
So he loads them on post construct of the plugin class?
Then make 1 big query that fetches all of it and u can iterate each row
and call the column by their name
and not looping
Theres no need for a system like that unless you're working with unknown structure
@dark garnet If you want help you'll have to give a bit more context to what you're trying to achieve
few words: lockette
@mint verge did u see this
Show me a table schem
^
I tried using an sql API but it’s better to just either write your own or not use one
looks like he wrote his own tbh
idk I don't use sql with java 🙂 @west socket
I see
The only thing the APIs are decent for is managing the connection
ye
They’re terrible for making queries
Which is why u should sql pools
bare minimum sql pool api
ok
so from my understanding
you want to loop through the content in the WORLD_XYZ_BLOCK column
wth is the table even for
To get the coordinates right? @dark garnet
world + coords + block yea
block has a locker right?
just world, the underscores r to separate them
world name with _ = gg
i do that after
List<String> list = new GetSQL("locked").getValue(new String[]{"WORLD_XYZ_BLOCK"});
if (list != null) for (String key : list) {
String[] split = key.split(",");```
o i forgot to change the , to _...
although you should store that string in 3 different columns
like you should have a column world, x, y, z, material
It's much more efficient than storing varchar
CREATE TABLE Locker ( lockerId INT PRIMARY KEY, world VARCHAR(32), x INT, y INT, z INT, type INT);
use VARCHAR(50) for world name
changing this made the plugin load, but its only returning the first value in WORLD_XYZ_BLOCK
imma explore making each one separate later
but i wanna try to get this working first
so i at least have something
it's more struggle than it's worth bro
I’m confused what he’s trying to do
hes tryna store all this shit in a varchar and split it to get all this data
the issue is with the sql method, so if i dont fix it i could run into more issues that use that method
thats not whats breaking it tho
Trying to store an entire map in an SQL db?
you showed no sql interaction in the method how could we help you with that
if i add another row (3 in total), it gets the first 2 but not the last
not even he would attempt that
You mind showing
The GetSql class
https://ghose.xyz/paste You can use this to paste it
youa re doing it wrong prob
its cause of while (rs.next()) (i assume)
when it gets to the last valid row, the row after it is invalid, so it doesnt add the last valid row
You should make your getValue method have a generic
load all on server start, save on server stop (and interval of time)

but yeah
do that, as normal people would do
i mean, why checking database every time someone breaks a block lol
no
public void createTable(String[] columns) {
You should cache the block
that is quite literally a query
StringBuilder result = new StringBuilder(30); for (String value : columns) { result.append(value).append(" VARCHAR(100), "); }
omg
isnt it easier to write the string directly?
and make it a column per axis?
Im also very confused why one would ever need to create a table programmatically, just make a db and host that bitch
phpmyadmin that shit
or
mysqlbench that shit
much easier to create your infrastructure like that
or is this like sqlite or something
@dark garnet did you write that class?
yea
that explains a lot
oh
dont get me wrong but
it sucks
you get confused when using it
it's 100times easier
to simply write the method you need
instead of making it need an array
you can easily make a table with world, x, y, z, locker and a random uuid
instead of complicating your life making it a string like world_x_y_z_world
"An idiot admires complexity, a genius admires simplicity. (...) An idiot, anything the more complicated it is, the more he will admire it. If you make something so clusterfucked he can't understand it, he's gonna think you're a god 'cause you made it so complicated nobody can understand it." -Terry A. Davis
or similar
i'm stealing that to make a tag for my server

+rep for terry davis quote
so what do i do
remove getsql
Remake the sql infrastructure
make db and interface it with code instead of creating the whole db programmatically
Make your Locker Table have a column for each axis, worldname, id of locker, id of placer
^
Then create yourself a method
With an interface
for example
GetAllLockers()
Which gets all lockers
What you could do is make a Locker class
and translate the data each row into a Locker object
then put Locker in a cache
and when someone breaks a block of type locker check locker cache
easy, don't use that class and write a new one with only the methods you need
@dark garnet you're glowing
just wondering
this.name = Main.config.getString("database.prefix") + table;
why?
if prefix is [MyPlugin]
would table name be [MyPlugin]tablename?
why?
default database.prefix is v_
and why?
cause the plugin's name is vanadium
it starts with a v

what
i usually do
Database:
USer etc
Pass etc
Table: "alonsotags"
etc etc
why making a prefix AND a table name?
dont complicate your life
database:
host: "host"
port: "3306"
database: "database"
username: "username"
password: "password"
useSSL: false
prefix: "v_"```
Programming is about being lazy
thats what the config looks like
wtf
not the other way around
thats set with new GetSQL(table)
ive never seen customizable table names ¯_(ツ)_/¯
literally
just make your table name what you want it to be.
no...
y
i have multiple tables
forcing table name
Locker table should be Locker
ew
all of them would be called v_
thats what i did
v_users
if i ever do that, people would complain about it not being configurable lol
make your Locker table named Locker not v_locker_alonsotags shit because thats not fun.
imagine adding a_wahteveryouwant
no way, i rather making it configurable
going back to the main issue
create your sql class and make only necessary methods
no need to be fun, needs to be practical and customizable

does he have 30,000 other plugins using the same db :V
even if he had, i dont think he'd need another database
unless he gets "max amount of connections" 
hey man he was glowing hard we had to say something
He was glowing in the dark
wdym im glowing??
i dont get the reference
dont feel bad, i dont understand it either
prob bc its not my main language
Hey @mint verge this is a warning for that latest post of yours! Please rest the rules
no fun allowed 😠
sadly not
fun is allowed, if on topic 

the topic is memes now
uh oh seb go bye
yes
#off-topic 🙂 let keep this channel on topic
and show it
so basically just get rid of all unused methods right?
you better create a new class
but wouldnt that be the same as just removing the unused ones?
or should i do more than basically copy/pasting (remake from scratch, change used methods, etc...)?
cause i dont see any benefits from removing the unused ones besides making the class cleaner (or is that the only reason?)
like remake from scratch?
do it as you want
but write the methods you need
in an easy way, without utils to make it array or something
if you already know there are 3 rows
write the code like that
not update(String[] values)
i mean, whyy?
just write the sql queries inline
what should be the new things i consider when remaking?
besides doing the necessary methods
like caching and stuff
make the table structure use columns and cache immediately upon start
ok dyno

so like world, x, y, z, placer, locker (each a different column)?
loadLocations() { //on start
get connection, get rows, while next, add to map
}
saveLocations() { //on stop and interval of time
get connection, loop the map, store world, locker, x, y, z, type
}
public boolean contains(String column, String value) {
try {
// Statement
PreparedStatement ps = Main.SQL.getConnection().prepareStatement("SELECT "
+ column
+ " FROM "
+ name);
// Action
return ps.executeQuery().toString().contains(value);
} catch (SQLException e) {
e.printStackTrace();
}
return false;
}
```what is this doing just use .executeQuery that returns resultset
then while(set.next()) { String world = set.getString("world"); int x = set.getInt("x"); int y = set.getInt("y"); int z = set.getInt("z"); ..etc }
then create the instance of the locker and load it into the hashmap
after this all you will need to do is change the data in the map
then onDisable you can make all of your inserts/updates
imma have 2 tables, so should i just create separate methods for both of them?
sure you could have methods to load the maps
no i mean like this will only work for one of the tables
so should i create another method that does the same thing except for the other table?
just wondering, why 2 tables
trusted players
thats not a method/doesnt have to be a method lowkey but yes
v_trusted with PLAYER and TRUSTER columns
you would just do the same shit
player
its to trust with all of ur blocks
ah ok, then it's ok
while(set.next()) {
UUID uuid = UUID.nameUUIDFromBytes(set.getBytes("uuid"));
}```not rlly sure how to load uuids from resultset but i assume its like this if you want to use the uuid datatype in sql otherwise just store as string
does the uuid datatype support hyphens?
sure
probs what i will do
also i just wanted to know the downsides, if any, of using yml storage
and the benefits, if any, of using sql over yml
sql wins in speed over yml unless structure is bad
plus sql has good querying
able to basically write any code to retrieve specific results in sql
yml can corrupt also, right?
and is slow af when too many data
dont ever use it
seriously
the locking system im using, which i got from a plugin i contribute to, uses yml storage
or static data generally
and ive been trying to transfer it all into mysql
its mostly just interacting with the file system thats slow not rlly about the file type, also every java method to filter results is slower than sql
what would be the best option for first plugin?
cause this is my first time making a plugin
first big plugin or first plugin?
first plugin
ive only fixed bugs / added new features to an already made plugin
idk just use yml if you're not comfortable in java or sql
learn java and spigot's api before worrying about data storage imo
Can’t anything?
ok ill just use yml for now and worry about data later
whats a good way to store unused code?
besides just commenting it out

was gonna make a joke about putin but nevermind 
ill just let u imagine what that joke wouldve been
Delete it, can view in your local history or GitHub
any1 know what the green light is saying for raspberry pi
i got no clue
that sound is my fishtank btw
green = on i think
then red means its connected to power
i think
ive been doing research and diff combos of green flashes mean dif errors
O
well for me green always just flashed when it was on, never really googled it before 🤷
didn't know it could represent errors o.o
The sound definitely adds to the video
Hello there! im trying to develop a plugin to play with my friends, i called the plugin CommonDamage, it consists in if one player is damaged, all players in the server get damaged too, but i want to implement the DamageCause into it too so if a player falls from a high place, and another one has father falling 4 in his boots, dont get the same damage as the one who fell in the first place. Someone know how can i make this posible?
I need an easy-to-use API for making GUIs in Bukkit for 1.17, well documented etc, anyone have recommendations? everything I've looked at so far is either cringy, confusing, or just not it
Looking for useful libraries/frameworks?
Here are some which have been deemed useful by the community and are used daily.
-> Menus: https://mf.mattstudios.me/mf-gui/gui
-> Commands: https://mf.mattstudios.me/mf/mf-1/getting-started
-> Messages: https://mf.mattstudios.me/message/mf-msg
-> Config: COMING SOON™️
@cerulean birch
cheers
Good morning, what does it matter if a commandExecutor's onCommand method returns true or false?
Is the difference only that if I return false, it displays some error message to the sender?
Thank you
What is the difference between storing data to PersistentDataContainer and setting metadata? For e.g. a player
one is persistent
When metadata disappears?
I think it's just held by the player object
but that's likely documented in javadocs of the related methods
thank you!
Do I have to prefix metadata key? In case of PersistentDataContainer I think it is not necessary, but can't find the code to setmetadata in my IDE so can't check.
Also, how can I browse full spigot/paper source code?
(Please use "reply" function to answer to my questions because I have to go afk now)
Ctrl click the interface and then you can browse what classes implement it
You also don't have to prefix the key
red is power
the green is IO indicator iirc
Nah, it will have your plugins name appended, plugin:dataKey: value
How do I create a void world? I found a some information on the wiki but a lot from it is deprecated since MC 1.17 changed so much in the world gen.
Use multiverse and void world plugin
Then its like /mv create name Normal -g VoidGenerator
Or something
Is there no easy way without dependencies? I want to avoid them as much as possible :>
All i know is that way but idk if it works for 1.17
you make a ChunkPopulator or something that just returns an empty ChunkData
Class names are probably wrong
But it's something like that
Yes just do it in single player
Change your layers
To all air or whatever
public class VoidChunkGenerator extends ChunkGenerator {
@SuppressWarnings("deprecation")
public ChunkData generateChunkData(World world, Random random, int x, int z, BiomeGrid biome) {
Environment env = world.getEnvironment();
Biome b = (env == Environment.NORMAL) ? Biome.JUNGLE : (env == Environment.NETHER) ? Biome.NETHER_WASTES : Biome.THE_END;
for(int c1 = 0; c1 <= 15; c1++)
for(int c3 = 0; c3 <= 15; c3++)
biome.setBiome(c1, c3, b);
return createChunkData(world);
}
}
// Creation
ConsoleOutput.info(key + " has started generating.");
WorldCreator wc = new WorldCreator(key);
wc.generateStructures(false);
wc.environment(e);
wc.generator(new VoidChunkGenerator());
w = Bukkit.createWorld(wc);
// JavaPlugin class
@Override
public ChunkGenerator getDefaultWorldGenerator(String worldName, String id) {
String name = ConfiguredSettings.get().worldName;
if(worldName.equals(name) || worldName.equals(name+"_nether") || worldName.equals(name+"_the_end"))
return new VoidChunkGenerator();
else
return super.getDefaultWorldGenerator(worldName, id);
}
People don’t know you can just do it in single player I guess lmao?
Not like I just gave the code to do it or anything lol
Why need code when you can just go make a single player workd
But okay
It’s already coded
If you used a single player world when new chunks are loaded they will be loaded by the default worldgenerator and not the void generator.
I have lol
I’m not arguing with you when you haven’t
Or else you wouldn’t be speaking out of your ass
But you are so what does it matter?
And also this is the development channel. So he asked for code to do it. (With no dependencies.)
Here’s the code for what single player already made
I mean creating a simple void world is sure easier by just doing it in single player, altho there are some benefits in regards to doing it programmatically with a plugin I presume
Like what @graceful hedge ?
Setting biomes for one.
When grass is placed I like jungles vibrant colors
Not really visible all that much, and if you do need it for certain chunks world edit can be used
Skyblock worlds 😉
Idk what the original dude was looking for specifically tbf
You can set biomes still 100%
Yeah
If you make a single player void world
Multiverse will make a void then like 1000 blocks away it’s just terrain
My code isn't from multiverse. Its from my skyblock plugin xD
I assumed it wasn’t from multiverse cause there void worlds suck
ah yes, @SuppressWarnings("deprecation")
xD
Yeap.
it makes me sad
it really does
Well if they didn't deprecate useful methods without adding methods to replace them it wouldn't be necessary. (At least in the plugin that code is from cause thats a latest version plugin.)
so you just will continue using the methods after they were removed?
If they are removed how could they be used?
the only method im using is InventoryClickEvent#setCursor, because there is no equivalent
They are marked for removal
thats what deprecation says afaik
There are methods "marked for removal" for over 6 years.
with the exception that the old worldgen API is confirmed by maintainers to be removed in a near-future update
Md5 likes the @Deprecated method 🤡
...that's the joke
"deprecate useful methods"
"without adding methods to replace them"
chooses to ignore the completely new and fine-tuned worldgen api
he abuses it
Imo, some methods are deprecated to somehow make the people use the other methods more, for example getPlayer(String) and getPlayer(UUID) or getOfflinePlayer
this is md5
no, that's yapperyaps 
HeadMeta.setOwner() is replaced by HeadMeta.setOwningPlayer() like TF just keep the method the same name?
?
'?'?
but what if owner can be something else than just player?
setOwner takes String and setOwningPlayer takes an offline player
github is down yet again 
is it?
works fine for me 
isnt for me
seems fine for me.
You can have methods with the same name but different params
you just have shitty internet
oops
skull

but its easier to differ then?
i get 500s when i try to log in
then don't
Yes but based on the current convo... one was supposed to be removed. So whats the point of making the new method instead of replacing the old one?
in case you weren't aware, there is a new worldgen api the better reflects how minecraft world gen stages work
as very well outlined by the javadoc
When was it added? I started the code of that plugin in 1.16.5 xD (And just updated it as necessary)
how does that help with deprecated methods?
the name tho !!!
!!!!! 
Actually I think it was before that, 1.15 or something
really?
I think so, I remember using it before 1.17 at least
checked, it's 1.17+
Link?
Is it the methods in worldcreator you're talking about?
I see, my brain fails me one more time
Yeah only deprecation I see (from the code I use) is the createChunkData() method. And just says ChunkGenerator.ChunkData are now directly provided
And the biomegrid
yes because
ChunkData are now directly provided
in all the new non-deprecated methods that replaced the old ones you should be using instead
public class VoidChunkGenerator extends ChunkGenerator {
@Override
public BiomeProvider getDefaultBiomeProvider(WorldInfo worldInfo) { return new VoidBiomeProvider(); }
@Override
public boolean shouldGenerateNoise() { return false; }
@Override
public boolean shouldGenerateSurface() { return false; }
@Override
public boolean shouldGenerateBedrock() { return false; }
@Override
public boolean shouldGenerateCaves() { return false; }
@Override
public boolean shouldGenerateStructures() { return false; }
@Override
public Location getFixedSpawnLocation(World world, Random random) { return new Location(world, 0, 70, 0); }
}
public class VoidBiomeProvider extends BiomeProvider {
@Override
public Biome getBiome(WorldInfo worldInfo, int x, int y, int z) {
Environment env = worldInfo.getEnvironment();
return (env == Environment.NORMAL) ? Biome.JUNGLE : (env == Environment.NETHER) ? Biome.NETHER_WASTES : Biome.THE_END;
}
@Override
public List<Biome> getBiomes(WorldInfo worldInfo) {
Environment env = worldInfo.getEnvironment();
return (env == Environment.NORMAL) ? Arrays.asList(Biome.JUNGLE) :
(env == Environment.NETHER) ? Arrays.asList(Biome.NETHER_WASTES) : Arrays.asList(Biome.THE_END);
}
}
java 8
I gotta switch that plugins workspace to java 17
😵💫
switch expressions aren't
yes
Object variable = switch() {}
?
Thats a switch expression
Its not in java 8
He's talking about those though
Put the return inside the case
i knoooow
Is there a simple method you can check if a number is incrementing in order:
Example:
1, 2, 3, 4, 5
(correct)
Using spoilers to demonstrate the numbers that should be there, but aren't:
1, 2, ||3,|| 4, ||5,|| 6, ||7,|| ||8,|| ||9,|| 10
(bad)
for each number
if number != previous + 1
it's bad
Thank you
The issue is the more numbers you have the more it has to loop through
the issue?
Yeah if hes missing number 7367462 thats alot to loop through
i dont think it's possible to do in anything better than O(n)
I use to have ID's based on ints. I got way higher then that
I'm saying that because I know what he's doing, cmon yapp, some common sense
obv int ids can go higher, the limit is 2.7b xD
I switched to UUIDs instead of checking for missing ints every time I needed a new id.
I tried getting this to work, but for some reason I can't join my test server when there is a void world being loaded. I just says "connecting" in my client, and no stack traces in the console. Also, only a Session.LOCK, DIM1 and uid.dat is created, nothing else :/ Any idea why this might be happening?
Do it in single player man
Well the thing is I need a void world to be made for my plugin. If there isn't one on the server, the plugin should make one. And I can't really jump on every server and make one myself
I got curious and looked it up, and the answer is not exactly this.
In case of getting metadata, you get back the list of stored values of that given key, and the list contains values for all plugins.
So, in case of common names, when getting stored metadata, you would have to filter for plugins after getting values.
But if you prefix your key with some unique thing (like plugin name), the chance for key coincidence is minimized.
Same thing for hasMetadata too.
So I would recommend everyone to prefix keys with something unique.
If you are curious for the code, here it is:
https://pastes.dev/fBMM97KTEM
the metadata api sucks ass
partly because it's never actually used for its intended purpose, which was a horrible idea even
well I have a player action which has two stages: player selects something, then something else.
For this (to store some state between the two parts), metadata api is great I think.
What version is your server?
I mean you could achieve the exact same thing with a Map of your own 
yeah but if the framework provides an easy way I'll use that
Bear in mind that metadata api is leaky as fuck because nothing is removed (unload of chunks/worlds/entities) ever unless you do
Server is restarted every day, and I clean it up most of the time, so it's fine for us
The original idea of it was to provide an easy means for plugins to communicate between each other
But like, nobody uses it for that and it was never actually promoted
so it was left there to rot lol
Between each other, interesting
yeah
There are other better ways for that I suppose
but reality is, any self-respectable plugin will provide an API of their own of sorts
(because passing shit between a giant ass Map is a horrible idea and constrained to types already provided by the existing libraries only)
Nvm, I'm to tired for this. I sat here for 2-3 hrs trying to figure out why it did not work. And did not once notice that I exported my plugin to the wrong destination lol. So thank you! The world gen works great!
Oh btw just a random fact that if you want a paste service that is serverless (data is stored inside the URL), check this out. I think it's awesome for smaller pastes.
https://github.com/topaz/paste
I do that more often then I would like to admit. Especially when I use maven to output jars lol.
Glad you got it to work.
topaz cringe 👎
Yeah, I just recently changed the output dir. So I thought it exported correctly, but it just went to the old folder lol. Thanks again :))
paste.helpch.at relieved
I wrote a short article on how metadata works, maybe it helps others too 🙂
https://gitlab.com/Arphox.HobbyProjects/minecraft/mcdevkb/-/blob/master/articles/metadata storage.md
Does anyone know why the second if statement isn't getting called?
for (String currentEntry : OraxenItems.getItemNames()) {
Material material = OraxenItems.getItemById(currentEntry).build().getType();
int currentModelData = OraxenItems.getItemById(currentEntry).getOraxenMeta().getCustomModelData();
int previousModelData = currentModelData - 1;
if (material == null) {
Logs.logWarning("Material is null! Cancelling debug system.");
return;
}
if (currentModelData == previousModelData + 1) {
Logs.logInfo("Model Data Match: " + material.name() + " ModelData: " + currentModelData);
} else {
Logs.logInfo("Model Data Mismatch: " + material.name() + " ModelData: " + currentModelData);
}
}
(new to java, sorry if it's something very simple)
Your previous is -1 from your current and your check is for previous +1 which will always equal your current
int previousModelData = 0;
for (String currentEntry : OraxenItems.getItemNames()) {
Material material = OraxenItems.getItemById(currentEntry).build().getType();
int currentModelData = OraxenItems.getItemById(currentEntry).getOraxenMeta().getCustomModelData();
if (material == null) {
Logs.logWarning("Material is null! Cancelling debug system.");
return;
}
if (currentModelData == previousModelData + 1) {
Logs.logInfo("Model Data Match: " + material.name() + " ModelData: " + currentModelData);
} else {
Logs.logInfo("Model Data Mismatch: " + material.name() + " ModelData: " + currentModelData);
}
previousModelData = currentModelData;
}
```Should work.
👍
Hello i would like to display custom text above players names
I tried theses:
-
Scoreboards (Below_Name) (bukkit api and NMS) problem: one '0' is displayed before text
-
AmorStand moving with the player (event handler or scheduler) problem: bugged and expensive for server calculations
-
ArmorStand on passenger on the player (Player#addPassenger(ArmorStand))
problem: player name will not display anymore + cannot change offset between player and armorstand -
Other entities for Player#addPassenger
problem: same of armorstand + customName of riding entity is not displayed if entity is invisible
Does someone know why this doesn't work / other methods ?
I use both so how can I get them to work like they use too?
Would prefer to not have to use reflection for all future minecraft versions lol
For when using mojang mappings just use them normally but also add the.. whatever special-source-plugin md5 provides, it remaps your jar so it works with the reobfed server used at runtime
Yeah I have that maven config.
If I remove remapped-mojang it compiles fine but causes errors on the server. But if I use remapped I can't use the proper classes.
"proper classes"?
IBlockData, BlockData, WorldServer etc...
For example with WorldServer it wants me to use ServerWorld and that causes errors
causes errors when or where?
in the code. It won't let CraftWorld be casted
CraftWorld is CraftWorld, not ServerLevel ?
can you actually show what you're trying to do? I'm having a hard time understanding the situation
I have code that works with the 1.17 jar. That code no longer works with the 1.18 jar (Any of them) I need it to work.
I have used the maven depends (all of them), used the maven config from the 1.18 release. Nothing will let the code work on a 1.18 server.
Its hard to show because I would have to show the whole project and I am not sending that many pictures lol
How do i open a book for a player (one that is not in the inventory) ?
One sec
alright
Google it I found a thread first result
hoe to open a book fir a player spigot
I’m bad at spelling
On Mobile
i also looked up some but i didnt see a good answer
Well
You would have to use packets
Nvm lol
@formal crane
Lemme get the link
declaration: package: org.bukkit.entity, interface: Player
👍
List<String> payMsg = CityRPPaycheck.plugin.getConfig().getStringList("Message");
if (!payMsg.contains("%a%")) {
EconomyResponse r = econ.depositPlayer(player, amt);
for (int i = 0; i <= payMsg.size(); i++) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', payMsg.get(i)));
}
return;
} else {
List<String> plhPayMsg = new ArrayList<>();
EconomyResponse r = econ.depositPlayer(player, amt);
for (String s : payMsg) {
if (s.contains("%a%")) {
String newStr = s.replaceAll("%a%", amt.toString());
plhPayMsg.add(newStr);
} else {
plhPayMsg.add(s);
}
}
for (int i = 0; i <= plhPayMsg.size(); i++) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', plhPayMsg.get(i)));
}
return;
}
Im trying to figure out why it is not replacing the placeholder %a% with the amount
Are you trying to use PAPI?
No
No, its just a local placeholder so that people can place the amount of their paycheck anywhere in the message
Hmm
if (!payMsg.contains("%a%")) {
player.sendMessage("Debug: Passed contains check");
you are checking if the list contains a string "%a%"
not if a string in the list contains %a%
but it isn't passing the placeholder replace
So should I just do a for (String s : payMsg)?
yeah basically just stick with what's inside the else case
Just just put what's in my else { into the if player#hasPermission, yeah?
oh
I didn't include it in the paste
all of that code I pasted is contained within if (player.hasPermission(perm)) {
from what you showed, just use what's in the else block
if (player.hasPermission(perm)) {
player.sendMessage("Debug: Passed perm check");
List<String> payMsg = CityRPPaycheck.plugin.getConfig().getStringList("Message");
player.sendMessage("Debug: Placeholder replace");
List<String> plhPayMsg = new ArrayList<>();
EconomyResponse r = econ.depositPlayer(player, amt);
for (String s : payMsg) {
if (s.contains("%a%")) {
String newStr = s.replaceAll("%a%", amt.toString());
plhPayMsg.add(newStr);
} else {
plhPayMsg.add(s);
}
}
for (int i = 0; i <= plhPayMsg.size(); i++) {
player.sendMessage(ChatColor.translateAlternateColorCodes('&', plhPayMsg.get(i)));
}
return;
}
what is this tabbing
its just because I didn't copy the spaces before the hasPerm check lol

Isn't this how you get potion effects, PotionEffectType.getByKey(new NamespacedKey(plugin, "slowness"))?
yes except the effect isn't "yours" (the key namespace isn't your plugin), you'd use NamespacedKey.minecraft("slowness")
Ahh, I see. Thank you!
So even after switching all spigots deobf classes to their mojang mapped counter parts I still get the same errors I did with the old code.
Caused by: java.lang.ClassNotFoundException: org.bukkit.craftbukkit.v1_18_R1.CraftWorld
would be possible to create a mariadb table and add default data?
CREATE TABLE IF NOT EXISTS `USER_ROLES`
(
id INT PRIMARY KEY,
name VARCHAR(25) NOT NULL
);```
I have this table and id like to add two roles `(1, 'professor')` and `(2, 'student')`
It would help If I changed the import to 18_R2 🤦
INSERT IGNORE INTO `USER_ROLES` (id, name)
VALUES (1, 'professor'),
(2, 'student');```
I guess this will do it
How would i make clickable text in a book? (example: https://gyazo.com/d5a5cbaac3278c4ed2d3265c27f5344e)
@lyric gyro I got it to work. Thanks for the help.
can anyone help me with an error?
can't really understand on where to look
me when can't send messages
dm me if you can help ig

sends messages
"me when can't send messages"
mfw
lmao
How would i run code when a player clicks on a textcomponent in a book?
I know how to like make it do something but its limited to this (see picture below) and i am trying to open a diffrent book instead of one of those actions
what event is that?>
wdym?
I haven't dealt with books like this before, but I'm pretty sure they work like clickable text. A.K.A. you can't run code from them, you have to force the player to run a command (RUN_COMMAND) and then run the code from there.
is it possible for the command to be ran from console?
Not to my knowledge, you will have to sudo the player.
But the player won't see that the command is ran, only the console
Do you think hypixel does this also this way?
Probably not
oh
They have a heavily modified version of minecraft. It is all custom made
So they have access to different tools than us
exactly what i just asked, what event is that, i cant find an even relating to book gui clicking
ahh ok
It's not an event
TextComponent chatAbuseScam = new TextComponent("○ Chat Abuse/Scam");
chatAbuseScam.setClickEvent(new ClickEvent(ClickEvent.Action.idkaeventyouchose));
i didnt know that.
like this
well given the limited options i would suggest creating a command that opens the new book.
Yeah, that is the only way I think
yea probably but i don't want te player to be able to execute the command without clicking in the book
not much else you could do unless you are able to figure out the packet thats sent when you click the book and use protocol lib or smth
if there is a packet thats sent that is
prob just gonna give the player a perm and remove it after orsm (to execute the cmd from the clicked text)
I have a similar system in my plugin. I use a clickable chat conversation but it works the same. When a player starts a conversation, they are added to a set. And the command listener returns immediately if the player sending the command is not in said set, and then removed from it once the conversation is over. It prevents what you want
yeah that can work
actually the second one would probably work best.
its what i do for when i want a value input
The time changes correctly in the world, but the gamerules do not save. Any idea why this is happening?```java
World world = Bukkit.getWorld(worldName);
if (world == null) {
WorldCreator w = new WorldCreator(worldName);
w.generateStructures(false);
w.environment(Environment.NORMAL);
w.generator(new VoidWorld());
w.type(WorldType.NORMAL);
dataWorld = Bukkit.createWorld(w);
} else
dataWorld = world;
dataWorld.setTime(0);
dataWorld.setDifficulty(Difficulty.EASY);
dataWorld.setGameRule(GameRule.DO_DAYLIGHT_CYCLE, false);
dataWorld.setGameRule(GameRule.DO_WEATHER_CYCLE, false);
dataWorld.setGameRule(GameRule.DO_MOB_SPAWNING, false);
dataWorld.setGameRule(GameRule.MAX_ENTITY_CRAMMING, Integer.MAX_VALUE);
The changes don't occur before the world is created, I also believe that MV stores the world properties you set in a config, and does it on startup, but I may be incorrect.
How does one go by setting the player's hp via attributes? (Using setHealth has its limits and for some reason i cant edit it in the spigot.yml).
I've tried this: this.player.getAttribute(Attribute.GENERIC_MAX_HEALTH).addModifier(new AttributeModifier(UUID.randomUUID(), Attribute.GENERIC_MAX_HEALTH.getKey().getKey(), playerHealth, AttributeModifier.Operation.ADD_NUMBER));
but all that does is add the health as you can tell, but i want to set, there isnt an operation to set and I can't seem to find another way of doing so.
I am using Spigot 1.16.5 for this
d;spigot Damageable#setHealth
void setHealth(double health)
throws IllegalArgumentException```
Sets the entity's health from 0 to getMaxHealth(), where 0 is dead.
health - New health represented from 0 to max
IllegalArgumentException - Thrown if the health is < 0 or > getMaxHealth()
How does one go by setting the player's hp via attributes? (Using setHealth has its limits and for some reason i cant edit it in the spigot.yml).
Are the settings not changed after the world is made? The world is created above? Also, I'm not using MV :).
anyone have experience using atomic variables
it just doesnt work for me
when im trying to update it which is static in the main class
in other async threads
am using the set get method of the atomic variable
no manual increment or anything like tehat
Show, and what does “it doesent work for me” mean lmao
well
usually you want to use updateAndGet or getAndUpdate (if the new value is dependent on the old value)
just the mere volatile/wrapping with AtomicReference does not inherently fix all concurrency update problems
also btw static state to some extent is terrible for multi threading
also btw static state
to some extentis terriblefor multi threading
FTFY
is there a way to get the index of an entry or a key in a map? Specifically an index of an entry from this maphttps://github.com/EssentialsX/Essentials/blob/e12f1b50229037197f9b406ae2af3d172e8fb9dc/Essentials/src/main/java/net/essentialsx/api/v2/services/BalanceTop.java#L38. It's mentioned that they're ordered. Do I just have to use a for loop?
as a Map itself doesn't even expose any concept of indexes, yes, you need to use a for loop if you need one specific position
but to loop, I'd have to use Map#entrySet. Couldn't that mess up the order?
that's not further specified, but I guess order is kept there
and as it is an implementation detail, you should not rely on that :)
EntrySet::toArray() is an available function iirc. Therefore you’d have an indexed EntrySet. I also think it would be ordered because what you had shown above was a LinkedHashMap
Sets don't guarantee ordering either, the ordering of the array will depend on the ordering of the map entries
when am i not funny?
ok apart from those days
:executing 'apply patches to decompiled jar'
Yes, but entries in a LinkedHashMap are guaranteed to be in order (throughout the lifetime of the map) due to them having pointers. But as you’ve mentioned, regular HashMap does not guarantee ordinality
correct, and the fact they're using a LHM is an implementation detail in and of itself (unless they're returning it as a LHM rather than a Map which.. they aren't (in other words it's not part of the public contract))
why does it make me do this:
int random = new Random().nextInt(9);
String code = String.valueOf(random) + random + random + random;``` **^**
instead of this:```java
int random = new Random().nextInt(9);
String code = String.valueOf(random + random + random + random);``` **^**
if i do it the second way, it only returns 2 integers rather than 4
The first code block you sent will convert random to a string, and then add on the other integers as a string
The second code block will add together the integers and then convert the result to a string
for example, the first code block:
random = 7
String.valueOf(7) = "7"
"7" + 7 + 7 + 7 = "7777"
the second code block:
random = 7
String.valueOf(7 + 7 + 7 + 7) = String.valueOf(28) = "28"
👍
What do you call a bee that lives in America? A USB.
(please laugh)
haha
Thank you Kaliber
anytime Emily
Hey! Any ideas on how to detect Fire Extinguish Event?
I am trying a Player Interact with the Clicked Block being fire but it doesn't work.
Please @ me if you have any ideas!
PlayerInteractEvent should work
PlayerInteractEvent should work, show code
java.lang.NullPointerException: Cannot invoke "me.clip.placeholderapi.PlaceholderAPIPlugin.getLocalExpansionManager()" because the return value of "me.clip.placeholderapi.expansion.PlaceholderExpansion.getPlaceholderAPI()" is null
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
new PlaceholderAPI(tokenManager).register();
}
why
i have added papi to depend in plugin.yml
can you show the whole stack trace
yeah
You are shading papi
me.clip.placeholderapi.expansion.PlaceholderExpansion.register(PlaceholderExpansion.java:139) ~[GTokens-1.0-SNAPSHOT-all.jar:?]
yes lol
Adding this to gradle shadowJar task fixed it
dependencies {
exclude(dependency("me.clip:placeholderapi"))
}
anybody know how I can get/print the full raw value of a string without colors, but with the color code?
bro do not tell me you're doing implementation(me.clip:placeholderapi:2.11.0)
no wtf
And you still have that issue?
i did the invalidate cache and restart thing and it fixed it
If ur plugin is bungee plugin…ig you can get all the player on the server instance…you don’t need a hashmap
I mean make a bungee plugin of it, else you'll have to deal with a lot of awkward problems which you'll have to basically duct tape around.
I agree with the above, but if u really want to do it…the logic would be something like this
When someone /msgs add whom he sent that message to, later if you recieve a message from that user u could process it with the data in the map…
but its absolutely better to make it as a bungee plugin
Can I somehow add the resources directory to a git? It's not in gitignore, but it isn't being pushed
You can only add files
Does the scheduler method delay for extra time then set sometimes? Is this a known bug or is it a result of an error or something?
It works 90% of the time but occasionally will skip over for one of the people using my plugin. No errors in console
Is there another way I can have something on a repeating interval
It won’t skip…as star said, it might have some micro sec delays…if its skipping, u need t check out the code
Hmm alright
this.saveConfig();
this.reloadConfig();
ConsoleCommandSender console = getServer().getConsoleSender();
String botToken = getConfig().getString("discord-token");
console.sendMessage(botToken);
Is there anything wrong with the way im getting my config? When I update the value it doesnt change.
Okay, this may be a noob question, but I'm asking it anyways.
I recently asked on another server how to make an easier ChatColor.translateAlternateColorCodes() methot, and I was sent this, but cant figure out how to use it.
I'm a bit new to development, and doesn't undestand methods that well.
How does this work and how do I use it?
public static String replaceColors(String input) {
return ChatColor.translateAlternateColorCodes('&', message);
}
You’re getting it correctly, but are you reloading your config before you try to access the value after changing it?
You can either add in a reload command to your plugin or just restart the server after making changes
Oh wait I see the reload, my bad :P
What’s the full context then?
I added reload to test something, it still doesnt update the value on server restart.
19.03 17:54:14 [Server] ERROR Error occurred while enabling SnowyRPGPlugin v2.0 (Is it up to date?)
19.03 17:54:14 [Server] INFO java.lang.IllegalStateException: Could not acquire lock in a reasonable timeframe! (10 seconds)
It’s basically a shortcut function that just makes things look neater.
String coloredMessage = “&cThis message is red”
// you can either do this:
ChatColor.translateAlternateColorCodes(‘&’, coloredMessage);
// or this
replaceColors(coloredMessage)
I’m sure you could tell which one is cleaner!
Is that the full error?
The "message" gets an error, what does that do?
And you’re trying to use a variable called message
When should i declare that variable?
No no, the variable message is wrong here
It’s supposed to be ‘input’, since that’s the argument in the method
You either make both of them input or both of them message
Glad I could help!
We need more people like you, everyone tells me to "Learn Java", but I can't learn when I don't undestand
Well how are you trying to learn?
I learn Java with CodeCademy, but when I'm doing Spigot Development, I mostly Google/ask other people
Yeah so imo you shouldn’t try to code plugins while learning Java both at the same time. You need to get a good understanding of the basics first before thinking about doing anything with APIs like spigot, paper etc
You’re basically learning a language, writing your own software, learning someone else’s software and trying to use it all at the same time. You will most likely end up frustrated
Yeah, I undestand, but I get bored so fast with just learning and get so exited with Spigot development
bad
Yeah, it's bad
Yep, that’s understandable 😄. Spigot is fun to mess around with, but at the end of the day it’s just Java. If you’re getting bored quickly then it might be an issue with the course you’re taking
Everythings costs money, you know. I don't want to pay for a course
I’d recommend reading Head First Java, very fun book and should give you a great base to work with!
CodeCademy has small projects in the course, but you need a pro membership
never paid anything
and learned to code plugins
learn java first
What did you use to learn?
That’s fine, a lot of people don’t actually learn much from videos, some do but a majority would grasp stuff better by reading
Can't ship to Norway
then you need a paid course
which leads to "i have no money"
= excuse
or you learn in the good way
or you pay someone to code it for you
otherwise you'll be asking over and over how to fix your issues
E-books are available for that book!
Does it cost to rent books in US?
I dunno, you can probably find the book on kindle or something tho
I’m sure it’s somewhere for free if snoop around long enough
Found a pdf lol
Have fun reading! 😄
700 pages
dam
I should probably buy a book instead
Can't read 700 pages on a computer
Well I mean, you can if you really wanted to
if (!(npc.getName().contains(PostBE.instance.getConfig().getString("npc.npcname")))) return;
Any1 knows why that doesn't work?
Make a util?
Package name = utils
class name = Format
class information:
import org.bukkit.ChatColor;
public class Format {
public static String chat(String s) {
return ChatColor.translateAlternateColorCodes('&', s);
}
}
usage:
player.sendMessage(Format.chat("&aHey my friends!"));
If u know the problem, please say it! ;D
I’m guessing it’s a translation color issue
literally superior:
public class ChatUtils {
public static String color(String message) {
return ChatColor.translateAlternateColorCodes('&', message);
}
public static void sendMessage(Player sender, String message) {
sender.sendMessage(color(message));
}
}
As the NPC’s name may contain color you don’t compare the name to the color version
usage:
ChatUtils.sendMessage(player, "u are a &6&lpotato");
And how can i fix it?
Oh i could do this right?
if (!(npc.getName().contains(Format.chat("&5" + PostBE.instance.getConfig().getString("npc.npcname"))))) return;
and then in the config:
npc:
npcname: 'PostBE'
No strip the npc’s name and compare it to the confit
config
I’d also suggest using dependency injection over a static variable for your instance
And possibly a place that your configuration stores the NPC rather than grabbing from config each time
True
Also possibly remove npc from npcname as it is already under npc
@spiral prairie is typing a whole book
i have other options down that line
That’s your preference though on the last one
beneath*
hello, sorry to interrupt but im having some issues with packetevents and sadly there isnt much activity in their server. it has worked before so i dont have any point to start. i am initializing it correctly and running that method, idek
https://upload.skyslycer.de/idea64_ThCYnl4vVc.png
Thanks bud', it worked!
welp
Just do it in code
i dont know code
?learn-java
Online Courses:
Online courses are also great for learning java. Some websites that offer them are:
- Coursera - Free unless you want a certificate
- PluralSight - Great courses from what I've seen. Mostly Paid
- Udemy - Never used them myself but they seem to all or at least most be paid.
My first ever course was one from Coursera. - I can say it was pretty good at introducing me to the programming world as a whole not just java.
Oracle Docs:
Oracle docs can help a lot at learning and understanding java:
- Start with this,
- Breeze through this (skipping stuff that doesn't seem relevant like bitwise operators),
- Hit this.
They're the first three from this larger thing which you should definitely go through overall. But those three should be enough for slightly better understanding of what is happening here without feeling like a huge time sink.
That one is a small part of this larger site wherein "Essential Java Classes" and "Collections" also have good useful stuff
Other services:
Some other cool services that will help you learn java are:
As you can see there are plenty of good ways to learn as long as you're willing to invest the time. Have fun learning!
bruh
i aint gonna go though 3 pages of shit
all i need is 1 simple command
nvm this discord useless
Lol
zamn
I tried to make my own dependency for plugins that i use but the problem is that i don't know how to implement it in to my plugin.
This is the repo: https://github.com/RazerStorm/rsLogger
And this is in my build.gradle: implementation 'com.github.RazerStorm:rsLogger:1.0'
(i can't use the implementation because it can't find the dependency)
Did you publish it?
i created a release
jitpack reported an error - seems like you fixed it, but you have to create a new release
Why does the %supervanish_playercount% placeholder sometimes show vanished players too?
Ask in the super vanish discord
Is there one?
hi, im trying to get the number of keys in a yml file that have a specific value in one of their children, how can i do this?
the yml file looks something like this:
WORLD=Z=Y=Z=BLOCK:
placer: "uuid"
locker: "uuid"```i wanna get all `WORLD=X=Y=Z=BLOCK` that have `locker` = `value` (`value` being whatever i want it to be)
ping if reply
You need to iterate over each keys and check whether the value is what you want
Hey guys I'd like to ask for help with dynamically registering Listener implementations to guice IoC container.
I want to write reflection code which finds all Listener implementations in my code base and registers it.
There's libraries like org.reflections & classgraph which can scan the classpath, they may be of use to you
guava also has a classpath scanning util, if you want to use something already in spigot
an alternative, and my preferred solution, is to scan the actual jar - https://github.com/PiggyPiglet/TemplateForSecretX/blob/main/src/main/java/me/piggypiglet/template/scanning/implementations/ZISScanner.java
thank you I will try to understand these
pig, dont you use that system to read external jars?
can be used for both
ah, nice
although that specific implementation wouldn't work for it
the papi 3 zis scanner works for both
it's just todo with the class loader, the linked impl has it hardcoded, in papi 3 it's given in an argument
If you have the same listener being registered in multiple classes, would it be worthwhile making an abstract class with that listener in and then the 2+ classes extending that class?
Therefore the actual listener only gets fired once idk like does that save anything at all
like if theres 2 PlayerMoveEvents
might be a dumb question but
probably helps with organization
uhm the actual listener would still be called for each instance
I mean yeah I guess you only have to register it once
not sure how you want to accomplish that
well I coded it and then realised it might not actually be doing anything except just making stuff more organised and preventing registering of listeners a bunch of times
you still need to register each listener
nah so
You only need to register the abstract one no?
^^
how would you do that?
I did it with two classes, the abstract and then the actual class which fires the listeners and also implements listener
so the abstract is the one they extend
and the handler is the one that fires them
if you register the subclasses, you will have n listeners
can you show some code? I probably completely misunderstand what you're doing, but from my current understanding, that wouldn't really work
I mean it is working I'm just wondering if its helping with anything except organisation
but sure
and then theres multiple classes extending TwistListener and using spawn event
also ignore the constructor its kinda a workaround for another plugin
okay, but every of these listeners needs to be registered?
not independently
only "TwistListenerHandler" class needs to be registered
idk its probs really pointless
its just cus its a big project using repeated listeners
I mean just use it for organization sake
How are the others registered?
the listener is added to a collection, and then they iterate over that collection calling the specific method for each event
When I call set on PersistentDataContainer, does it serialize and stuff? So I shouldn't call it often?
pretty efficient call I believe
How can i get information from the lore? https://github.com/xNoNameHDx/SpigotPlugin/issues/1
?
how do i get locker in each key?
I am currently on phone….i will get u sample code later…
You would need need to use getKeys() and iterate through each
like this correct? for (String key : Main.locked.getKeys(false))
Yeah
then how would i get locker?
FileConfiguration#getString(key + ".locker")
ohh
Hi, what is the recommended way to send config-based messages? Is there a framework for that?
Basically I want to configure from config file every message I send with my plugin
adventure + resource bundles work quite nicely
I believe for instance LuckPerms uses this, so might wanna check that out :3
thank you
yes very good
Hi, i get this error when registering PlaceholderExpansion, https://pastebin.com/U36S0dpM, im using placeholderapi 2.11.1, minecraft version 1.18. Here is my PAPI class, https://pastebin.com/PTuDitBR. Thanks to everyone who helps
are you shading PAPI?
What do you mean by shading ?
in your build script, Maven or Gradle
In maven
does it have <scope>provided</scope>?
Yes it does
huh
This error only happens on this version
of Minecraft? or of PlaceholderAPI?
and are you depending on PAPI in your plugin.yml?
Show your build script
Yes i am depending PAPI, and i mean minecraft version
Hello, I have also had an error with the PlaceholderAPI
I don't understand why this could be happening https://pastebin.com/4CFh5hiG
And it doesn't happen to me only with one extension, but with 3
Server software?
Your expansion is corrupted. Try downloading it directly from https://api.extendedclip.com/all/
We use Magma to have mods and plugins, I don't know if that can bring an incompatibility error
ah that would probably be it
Weird server mixes like that usually don't work for most stuff
Could ask them I suppose
ah, someone already has
Hybrid servers are a nightmare, stay away if you can
By the build script you mean the output when building the jar file ?
Buildscript is either pom.xml with maven or build.gradle with gradle
So you want the whole pom.xml ?
Yeah
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
I get an error
Caused by: java.lang.NoClassDefFoundError: org/java_websocket/client/WebSocketClient
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>me.jayden</groupId>
<artifactId>voice</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Voice</name>
<description>Cool voice plugin</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.2</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>```
</build>
<repositories>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.12.2-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.5.2</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>


