#development
1 messages · Page 73 of 1
just save when they close it? lol
Well I can't really
why wouldn't you
I don't know when they close it, or I can find out but it's goofy asf
there is legit an event for that?!
Well obv I made my own
I mean you can do some pretty complex stuff. It is up to you to decide how it should work but you could do a few things:
- Save all changes they make in memory
- If they close the menu, ask for confirmation (using another menu in which they can go back to the previous one with their changes or exit without saving)
- If they exit the server without confirming or denying, save the changes in a new table and ask for confirmation the next time they join and try to edit. Also, don't let them edit again until they confirm.
My GUI system is built on conversations, which is used cross all my plugins. It consists of a deque of Conversations which are both chat and GUI based. These conversation does not necessarily have to mean that a user is editing something. And if they are, they can be editing in the chat. Also there are multiple different types of structures
Oh. I though they just didn't know what the best flow would be.
If it's conversations, then I would assume it's a step by step thing, just save it in memory like said before.
The confirmation one is the best ig. I still have to make some goofy way of telling what they are editing based on the conversations?
if it's per message and they exit, you will have the previous edits
if it's in GUI, just listen to the close event
What do you mean step by step?
What's your name?
Afonso
What's your favorite food?
Pizza
ETC.
just save at which position they are
and their answers to the previous ones.
There is no good way of doing it though. Ig I can flag them if they start editing and unflag them when they exit. If they exit mid convo I'll ask for confirmation. Ig that's the best way?
Oh well it does not really work like that. It's more of a GUI -> Select value -> enter value in chat -> open GUI again over and over ish
So not q1 -> q2 -> q2 -> ... -> GUI
why not stay in GUI?
use anvils
What about lists?
?
Say lore
You can't really edit lore in an anvil.
you can't edit all lines, but you can edit one by one
which is what you would do in chat eitherway
since you can't have multiple lines in chat
Yeah but that's kinda wonky no? I mean this is what I have now, it's hard to do this outside of chat. I think I'll go with the flag/confirmation thingy.
Like how would you display this in a GUI
lmao
yeah the line editing part is fine ig. But how would you show the list if not in chat?
You have 3 item slots in an anvil + text input
use them lol
you can literally showcase the item itself with the lore (like in the image)
inside the anvil gui
even better than chat, since you see the actual item and it's lore
instead of some mimic in chat
I mean in theory you can show the item in a slot. But moving lines, selecting one to edit and removing lines is hard. Or at least idk how that would be done in a good way.
on a side note, these types of "ingame builders" are quite overrated and most of the time, are barely used lmao, just saying.
its more than an item builder
why would it? have in one slot, the lore with all lines, with the line currently being edited highlighted
right click to go up
left click to go down
and voila
ingame builders overall tend to not be used at all, or very rarely, since config is simply WAY faster. So, I wouldn't lose too much time on it imo
"I want to edit line 15, click,click,click,click. Now I want to swap the places of line 1 and 2, click,click,click,click"
Again its much more than an item builder. The lore is just an example.
I am not speaking about item builders though
I am speaking about overall builders xD
I find it way better than chat imo, chat stays there and polutes the chat + incoming messages from players will disturb it unless you do some funky stuff
Well the entire selling point is GUIs, and there is a good market for it. I promise you the GUI will be used :)
I am not speaking about guis not being used lol
I am speaking about builders not being used. Several "ingame building gui" plugins, which advertise it as one of their main selling points, according to their own developers, are barely used lmao
ok xd.
it's very junky to use overall because of the limitations of minecraft itself
and even if you ignore that, from an User Experience stand point, going back and forth from gui to chat and vice versa is simply unpleasent
either stay with one or the other
depends how good you design them. my users would tell you otherwise
This is much more but sure. cant be bothered with this anymore lmao. bai, the initial help was good so thanks for that at least
This is just my POV on this, (and several other developers), solutions were given, you choose whatever you wanna do
Like try telling UltraPlugin users that GUIs suck xd
.
Yeah sure, some people dislike GUIs, you for example. But on the other hand a lot of people like GUIs. Why not have both? That way to can provide a good product for everyone.
bro. I legit don't care, I already said what I had to say, leave it. And you are missing the whole point but I won't even try to explain it. As said, you do you, solutions were given, now leave it.
I got a 2 stars review because my plugin is "not up to standards" and doesnt have a way to edit configs in-game 
lmao
as said, from what I spoke with several devs which their plugins do have it, they say those systems are barely used.
Anyways, in-game editors are shit, since you have to hover over each item to see what it represents
Which is funny cause they are widely asked, but once users get it, they are used once or twice and never use it again lmao
yeah
its kinda a thing that is a nice to have, well, for people that dont have access to the file system
but the things that need to be configured are more often than not meant for the server owner or dev, not staff
professional server plugin configurator yml developer
im a professional server custom item name color picker
my take is that if someone doesn't have access to file systems, they shouldnt be touching configs for a reason
plus the system of implementing ingame editors is the jankiest shit in the world and the people who use them are morons anyway
does anyone here can introduce me just a lil bit to publishing spigotmc plugins?
i created my first plugin that i want to publish but i dont know what i can and cannot do
any ideas for things that you "can or cannot do"?
Just a little confused, there are tons of random plugins out there
idk im just a little bit stressing about my acc getting banned or some shit
hopefully you aren't trying to upload anything malicious 😂
I feel that might say more about what you're making than spigot's rules 😂 😬
Why would you be worried about getting banned for posting a resource. Unless you intentionally adding malicious code or posting something that isn't yours, you're fine.
yeah that was my second point
that was not what I meant lol
Adding to the above, I would also think twice, "do I really need to publish this?" cause there are simply too many repeated plugins, with (no offense) bad code in spigot. I would only consider posting anything if your plugin actually brings something new or different imo. (or if a plugin already exists but doesn't have X thing that you added, that's okay)
On a side note, if you end up posting something, I would 100% ditch spigotmc and use Hangar and Modrinth. And I would also use Paper API.
what
me
you're gunna have to give a bit more context then that if your actually wanting support
since that method doesnt seem to exist in the spigotapi
This is called multiple times per event, any idea what would be the cause of it?
private static final EventListener EVENT_EXECUTOR = new EventListener();
private static final Set<Class<? extends Event>> REGISTERED_LISTENERS = new HashSet<>();
public void registerListener() {
Class<E> event = getEventClass();
if (REGISTERED_LISTENERS.contains(event))
return;
REGISTERED_LISTENERS.add(event);
Bukkit.getPluginManager().registerEvent(event, EVENT_EXECUTOR, EventPriority.NORMAL, EVENT_EXECUTOR, PLUGIN);
}
private static class EventListener implements Listener, EventExecutor {
private EventListener() {}
@Override
public void execute(Listener listener, Event event) throws EventException {
System.out.println("event " + event);
Driver.dispatch(event);
}
}
it depends on the event type
some events subclass other events, event A extends listenable event B, if you register the listener for both events but only A is fired, the executor will get called for "both" registrations
although that is also not guaranteed, if A has its own handler list then that won't happen
bukkit event bus is hot garbage
(also Set#add returns a boolean)
That is not the case for some events that are called multiple times, meaning it is not the cause.
Yeah I know, but it checks just before. And I've souted each registration, no event is registered twice.
yeah but you can skip the check
Ahh ok I see! Didn't think of that.
it is entirely possible for no event to be registered twice and what i described above to still happen
But that requires them to be subclasses no?
yeah, but the event class itself will not be registered twice
you can probably check if event.getClass() == the class you expect before calling into your code
CraftItemEvent extends InventoryClickEvent
CraftItemEvent shares the same handler list with InventoryClickEvent
you can register a listener for both InventoryClickEvent and CraftItemEvent
the listener for InventoryClickEvent will be called twice whenever CraftItemEvent is fired, because you have two separate registrations for the same handler list
ffs
I tried to use papi 2.11.x from repo.extendedclip.com in gradle, but i get > Could not download placeholderapi-2.11.5.jar (me.clip:placeholderapi:2.11.5) > Could not get resource 'https://repo.extendedclip.com/content/repositories/placeholderapi/me/clip/placeholderapi/2.11.5/placeholderapi-2.11.5.jar'. > Could not HEAD 'https://repo.extendedclip.com/content/repositories/placeholderapi/me/clip/placeholderapi/2.11.5/placeholderapi-2.11.5.jar'. it works fine with 2.10.9. Is there anything special I need to use 2.11.5?
Quick question, using configurate object mapper, how would I achieve something like this in yaml:
list:
1: "something"
2: "something_else"
# etc
I know that you can use Sets to achieve a StringList, like
list:
- A
- B
# etc
but that's not really what I want
I don't use configurate, but in other libs that'd be like a Map<Integer, String>
¯_(ツ)_/¯
hmmm
yeah that's just a map
Method does not override method from its superclass
private void registerPlaceholder() {
if (getProxy().getPluginManager().getPlugin("PlaceholderAPI") != null) {
// Registering a PlaceholderHook with PlaceholderAPI
PlaceholderAPI.registerPlaceholderHook(this, "mythiccredits_ertek", new PlaceholderHook() {
@Override
public String onPlaceholderRequest(ProxiedPlayer player, String params) {
if (player != null && params.equals("mythiccredits_ertek")) {
int creditAmount = DatabaseManager.getCredits(player.getName());
return String.valueOf(creditAmount);
}
return null;
}
});
} else {
getLogger().warning("PlaceholderAPI not found! Placeholder registration failed.");
}
}
Can someone help me with this?
idk, but that doesn't look like what's displayed in the wiki
on the phone rn
so...
ProxiedPlayer, registerPlaceholderHook??
i know it's there and I don't have any issue with 2.10.x just any of 2.11.x, gradle cannot locate them.
tf, PlaceholderAPI in proxy?
🤯
Probably a different plugin
what is the !learnjava command thing again? I need the links to send to a friend
?learn-java
can i just add the placeholderAPI repo to my forge mod and use it normally? or do i HAVE to use it in a plugin
also
its :/
Due to the PlaceholderExpansion being internal, does PlaceholderAPI not load it automatically, requiring us to do it manually.
should be PlaceholderAPI does not load it...
Papi is a plugin, not a mod.
ik, but cant i just use it in my mod ?
i can use luckperms
so i thought maybe i can use this too
Try and see 🙂
is 300 ms considered slow for setting a value for data or whatever
cause im experimenting with SQL and my method for setting a value takes around 300 ms (as it also creates table + column beforehand)
public void setValue(@NotNull String table, @NotNull String target, @NotNull String column, @NotNull String value) {
createTable(table);
createColumn(table, column);
setValue(table, target, column, value); // not recursive, i just replaced statement execution with this to make this more understandable
}
300ms isn't awful depending on how you're handling that time (running it async, caching it so it can be used immediately) but this function seems pretty not ideal
Why do you have to create and add a column every time?
if the column doesnt exist then the value wont be set
Why wouldnt the column exist?
if its the first time setting a value, user for some reason deletes it, etc...
why would the user delete a column just like that
idk but mainly the first reason ¯_(ツ)_/¯
you can run a few queries to initialize all your tables when your plugin first loads
then you wont have to worry about tables or columns not existing
I would definitely recommend getting some more exposure to how people effectively use SQL for minecraft and really any applications, it's very strong but also is different to work with in some respects compared to handling data in just java
so if you charge in head first you might make lots of silly mistakes that make SQL very difficult to use
hmmm yeah, i had that for tables, but since im putting this into my framework, i thought it'd be too annoying to have to declare all the names of the tables/columns id be using
but ig its better than having slow times
this shouldn't be too bad, but were you planning on having dynamic tables / columns based on the person using your framework? or just the same static schema for everyone
because the way you made your function makes it seem like you'll let people make their own tables and columns on the fly
the framework has its own table that stores data for entities using a class that already exists in the framework which has 3 methods: get, set, remove
the method i posted above is really only useful for that, so i might just get rid of the separate method and combine with the existing class
@NotNull private final DataManager dataManager;
@NotNull private final String table;
public StringData(@NotNull AnnoyingPlugin plugin, @NotNull String table, @NotNull String string) {
super(plugin, string, string);
if (plugin.dataManager == null) throw new IllegalStateException("Data manager is not enabled/initialized. Make sure options.dataOptions.enabled is true!");
this.dataManager = plugin.dataManager;
this.table = dataManager.getTableName(table);
}
@Override @Nullable
public String get(@NotNull String key) {
return dataManager.getValue(table, target, key);
}
@Override @NotNull
protected Data<String> set(@NotNull String key, @NotNull String value) {
dataManager.setValue(table, target, key, value);
return this;
}
@Override @NotNull
public Data<String> remove(@NotNull String key) {
dataManager.removeValue(table, target, key);
return this;
}
see, literally just calls the other methods, kinda useless to have them separate, and probably confusing
i think if other ppl or i were to wanna create new tables/columns in their plugin, it'd have to be done manually, but idk, i havent gotten that far yet
i see
well in any case i think a good rule of thumb is to limit what your public methods can do as much as possible to their own scope
this code seems to be doing that moderately well so all good there
my end goal with this was to have the 3 simple methods, get/set/remove, that can be used for entities to store values, similar to PDC (as thats what i was using before)
this reminded me of dialects, so i have no idea what to do about that
for (ProxiedPlayer p : getProxy().getPlayers()) {
p.playSound(p.getLocation(), "entity.experience_orb.pickup", 1.0f, 1.0f);
}
Can someone help me out with the correct syntax?
Issue:
Cannot resolve method 'playSound' in 'ProxiedPlayer'
Cannot resolve method 'getLocation' in 'ProxiedPlayer'
Can you even play a sound via ProxiedPlayer?
@lilac portal Bungeecord or Velocity?
As well what version
Bungeecord and 1.18.2
Yeah I don’t think you can play a sound through bungeecord
Same with getting a players location via getProxy().getPlayers()
And what about hex color gradients?
Well i have this atm:
§x§C§B§2§D§3§E§lM§x§C§F§3§0§3§E§ly§x§D§2§3§2§3§D§lt§x§D§6§3§5§3§D§lh§x§D§9§3§7§3§C§li§x§D§D§3§A§3§C§lc§x§E§1§3§D§3§C§lM§x§E§4§3§F§3§B§lé§x§E§8§4§2§3§B§ld§x§E§B§4§4§3§A§li§x§E§F§4§7§3§A§la
I use legacy on MCHub as well, but there’s a way todo formats like #FFFFFF
what about this?
<gradient#CB2D3E:#EF473A>MythicMedia</gradient>
You’d need to add MiniMessage support if you don’t have it already.
Ty i'll try this
Kk :D
Sorry, another thing
Is there a way with this so i can just say "Click here" and there would be a link embeded, and when the user clicks on it, it would request to open the link as default by minecraft?
ty :D
That should be it.
Yeah i am watching it but can't seem to find a solution as i want it to work or i might just be blind
i want to say "Click here" and embeded there should be a variable "link" which would obviously be a link provided by the player
Yeah you should be able to do that
But how
<click:_action_:_argument_>text</click>
Action will be open_url and the argument will be the url
Yeah
Lemme try
Are you coding using chatgpt?
No
just for some stuff i can't seem to find inside the docs
if it has some better ideas
Ok, take a closer look at the docs because they are very well structured, you have a list with all the actions
I messed up something i think xd
Okay
You don’t have it parsing through MiniMessage
You’re just sending it via a normal chat message.
How can i make this work then:
getProxy().broadcast(new TextComponent("§8[<gradient#CB2D3E:#EF473A>MythicMedia</gradient>§8] » §c" + sender.getName() + " §félőben közvetít hálózatunkon!\n§8• §fMegtekintés: §4§n<click:open_url:" + link +">Kattints ide.</click>§r §7§o(Platform: " + platform + ")."));
Despite both having the name "component", what you are using is from the bungeecord chat api
from bungeecord i use these:
import net.md_5.bungee.api.CommandSender;
import net.md_5.bungee.api.chat.TextComponent;
import net.md_5.bungee.api.connection.ProxiedPlayer;
import net.md_5.bungee.api.plugin.Command;
import net.md_5.bungee.api.plugin.Plugin;
Yeah gotta use MiniMessages API, not Bungeecords
Yea
I need to tho
i was stupid
alr i have this in my pom
<dependency>
<groupId>net.kyori</groupId>
<artifactId>adventure-text-minimessage</artifactId>
<version>4.15.0</version>
</dependency>
Now do i need to make it look something like this?
getProxy().broadcast(MiniMessage.miniMessage().deserialize(new TextComponent("§8[<gradient#CB2D3E:#EF473A>MythicMedia</gradient>§8] » §c" + sender.getName() + " §félőben közvetít hálózatunkon!\n§8• §fMegtekintés: §4§n<click:open_url:" + link +">Kattints ide.</click>§r §7§o(Platform: " + platform + ").")));
Give it a shot
it was underlined
A lot of development is trial and era.
so maybe this could work?
Object mm = MiniMessage.miniMessage();
getProxy().broadcast(mm.deserialize(new TextComponent("§8[<gradient#CB2D3E:#EF473A>MythicMedia</gradient>§8] » §c" + sender.getName() + " §félőben közvetít hálózatunkon!\n§8• §fMegtekintés: §4§n<click:open_url:" + link +">Kattints ide.</click>§r §7§o(Platform: " + platform + ").")));
What are you doing mate...
Trying to make this work
I am a beginer in this
Read the docs
In the docs there is var, but as soon as i put var inside my code it becomes red :/
You need to use this https://docs.advntr.dev/platform/bungeecord.html
And after you get an Audience you can send Components to it
var test = "Hi"; is the same as String test = "Hi"; in java 11 >
You only specify the type once
Im not sure how to send broadcasts, but I'd say you simply send the message to each player one by one
I can't figure this out..
It would be easier with a simple text but i have a paragraph, which should include 2 words that should be clickable..
with ofc the link
hi back with sql questions
i want to support 5 types; h2, sqlite, mysql, mariadb, postgresql
but when i end up adding all of the drivers, my framework's size is around 28 MB
ok
ok
i was under the impression that mysql and mariadb could use the same drivers, that could save you some space
if true
java.lang.NoClassDefFoundError: me/clip/placeholderapi/expansion/PlaceholderExpansion
ig i cant :/
I don't think so - you'll probably need something like https://www.curseforge.com/minecraft/mc-mods/forge-placeholderapi (https://github.com/EnvyWare/ForgePlaceholderAPI/wiki/)
although it doesn't seem to be as big as PAPI
I don't run forge/fabric servers so I don't really know what the equivalent would be, if any
Does anyone have experience with ProtocolLib on 1.20.4? I'm trying to create a fake sign. Everything works perfectly, only the predefined text is not transferred to the sign.
This is my Code for the fake sign. Maybe someone here knows a solution
https://pastebin.com/cKhAAExa
i dont have loom :O
i just did implementation() 🔥
i have never used anything other than that before, how do u think i should add it?
compileOnly dependencies are required to compile your code but are not included in the runtime classpath.
implementation: dependencies are required to compile **and **run your code.
Ex. if you're making a plugin that uses PlaceholderAPI, the classes are loaded by the plugin itself, meaning you can use compileOnly. If you don't have a jar that loads those classes for you, you need to include them in your jar yourself via implementation.
I need help with my plugin. When i enter the placeholder into anything it doesnt display the correct way. i have created 2 placeholder the first being %evadedeco_top_balance_player_x% where x is the number of that player e.g. the 10th player in the baltop list and the second placeholder being %evadedeco_top_balance_1% where x is the number of that players balance e.g. the 10th players balance
EvadedCore.java (main class)
https://hastebin.com/share/ozagozacix.typescript
TopBalancePlaceholder.java (creation of the placeholders)
https://hastebin.com/share/umafugafis.typescript
plugin.yml
https://hastebin.com/share/uxaxejomeh.yaml
what doesnt work specifically
When i type in the placeholder into something such as an item in a deluxemenus gui the name of the item doesnt update to what it should be
im not exactly sure whats causing this
does it work in /papi parse?
i can check rn
when i do papi parse it replies with the placeholder not updated to what it should say
/papi parse --null %evadedeco_top_balance_1%
just shows %evadedeco_top_balance_1%
rather than the actual top balance
what do you mean
so if (identifier.startsWith("evadedeco_top_balance_player_")) { should be if (identifier.startsWith("top_balance_player_")) {
o
so is that the entire issue
so if i typed evadedeco_evadedeco_top_balance_1 it would work ?
public String onRequest(Player player, String identifier) {
if (identifier.startsWith("top_balance_player_")) {
int rank;
try {
rank = Integer.parseInt(identifier.replace("evadedeco_top_balance_player_", ""));
} catch (NumberFormatException e) {
return "InvalidRank";
}
return getTopPlayer(rank);
} else if (identifier.startsWith("top_balance_")) {
int rank;
try {
rank = Integer.parseInt(identifier.replace("evadedeco_top_balance_", ""));
} catch (NumberFormatException e) {
return "InvalidRank";
}
return getTopBalance(rank);
}
return null;
}
i have updated it like so
Even with this update to the code it still just doesnt work
your identifier does not contain the prefix
in identifier top_balance_player_ you're replacing evadedeco_top_balance_player_ to empty string
it does not contain evadedeco_, hence, it doesnt get replaced
the placeholder you want to parse is %evadedeco_top_balance_player_1%, the identifier will be top_balance_player_1.
yes but the reason i have it as evadedeco_top_balance_player is because i need this to work for top balance 1 - 10
public String onRequest(Player player, String identifier) {
if (identifier.startsWith("top_balance_player_")) {
int rank;
try {
rank = Integer.parseInt(identifier.replace("top_balance_player_", ""));
} catch (NumberFormatException e) {
return "InvalidRank";
}
return getTopPlayer(rank);
} else if (identifier.startsWith("top_balance_")) {
int rank;
try {
rank = Integer.parseInt(identifier.replace("top_balance_", ""));
} catch (NumberFormatException e) {
return "InvalidRank";
}
return getTopBalance(rank);
}
return null;
}
there you go
spoon fed
They’d ban you on spigotmc if you did this
Im sorry that im new to implementing placeholders lol
but on a real not tysm
its a me not understanding how to implement it ik
you're checking if it starts with top_balance_player_ and then for some reason replacing evadedeco_top_balance_player_, where ``evadedeco` is your prefix, when I told you that your identifier will not have it.
so should it work like this in my plugin.yml?
# Add PlaceholderAPI placeholders
placeholders:
top_balance_player_x:
author: LmaoLoq
version: 20.0
identifier: top_balance_player_
expansion: me.lmaoloq.eco.TopBalancePlaceholder
top_balance_x:
author: LmaoLoq
version: 20.0
identifier: top_balance_
expansion: me.lmaoloq.eco.TopBalancePlaceholder
honestly I havent seen this config so I can't tell
...
Anyone know how to manage through the refferal_code in discord oauth, I have tried sending it as a param or in state to the discord login api of my website. I want that the refferal code i send from here, after the successfull login i can receive the same id in my callback function.
You mean you want to pass some data to OAUTH, then on successful authorization return it back?
For some reason my balance placeholder isnt working. The placeholder should be %evadedeco_balance% I honestly dont know where i fucked up
This is how i register the placeholder
// Register placeholder with PlaceholderAPI
if (getServer().getPluginManager().isPluginEnabled("PlaceholderAPI")) {
new BalancePlaceholder(economy, this).register();
new TopBalancePlaceholder(economy, config).register();
getLogger().info("Registered custom placeholders with PlaceholderAPI.");
} else {
getLogger().warning("PlaceholderAPI not found. Custom placeholders will not work.");
}
This is How i create the placeholder
package me.lmaoloq.eco;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import net.milkbowl.vault.economy.Economy;
import org.bukkit.entity.Player;
import me.lmaoloq.evadedcore.EvadedCore;
public class BalancePlaceholder extends PlaceholderExpansion {
private final Economy economy;
private final EvadedCore plugin;
public BalancePlaceholder(Economy economy, EvadedCore plugin) {
this.economy = economy;
this.plugin = plugin;
}
public String onRequest(Player player, String identifier) {
if (player == null) {
return "";
}
if (identifier.equals("balance")) {
return formatBalance(economy.getBalance(player));
}
return null;
}
private String formatBalance(double amount) {
return plugin.formatMoney(amount);
}
@Override
public String getIdentifier() {
return "evadedeco";
}
@Override
public String getAuthor() {
return "LmaoLoq";
}
@Override
public String getVersion() {
return "8.0";
}
}
aren't there placeholders for vault already?
.... i didnt realise that one xD
getIdentifier is "evadedeco" but onRequest checks for "balance"... Haven't made placeholders with papi but maybe check that?
The reason i want to make my own placeholder is because i have a config that changes the currencySymbol. e.g. if set to $ everywhere money is show it will be $
GetIdentifier and the String parameter from onRequest are two different things
The value returned by getIdentifier is the first part of the placeholder e.g., %vault_eco_balance% here vault is what you return on getIdentifier and eco_balance is what you get on onRequest
Could it be because i did onRequest and not onPlaceholderRequest
no, both methods get called and you should use onRequest
its becuase i didnt have the @Override
No
@Override is just for reading purpose from my experience, though it is recommended to have it 
Welp i didnt have it in the code i sent earlier and once i added it the code started working perfectly
Thats why you use a proper ide and let it handle these things for you
😦 im using Eclipse ide its old but works
It is just old 
It helps prevent the case when you write a function that you think overrides another one but you misspelled something and you get completely unexpected behavior.
Sincerely,
StackOverflow
but yeah, its not necessary, just makes sure you are really overriding something
Hey, Im new to this and wanted to learn how to make plugins and whatnot, so I was wondering what the best way to start/learn is ?
Still need to learn Java but like what in Java should I focus on and then what can I do after that?
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!
I would advise learning java and knowing how the language functions before trying to tackle plugin creating.
Hypocritical advise slightly because I mainly started with plugins, but I have taken a comp sci java class and my knowledge has only improved since
Oh
But wdym how it functions, i took a AP comp sci class in hs which was java based but i forgot most of it
but relearning should be easier than learning for the first time no?
Teach what?
💀💀💀
I can’t really speak for your experience with it. But if you forgot all of it, then yes; you would need to learn how the language works and operates. What rules it follows, conventions, what OOP is if you forgot, etc.
I wouldn’t entirely say so, it’s about the same as getting to learn any other API
Oh
I see
Ive never had experience with API's and stuff
dont think I learned OOP either
java is an OOP language, object-oriented programming
package fr.xenore87.waterchecker;
import org.bukkit.Material;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
public class Main extends JavaPlugin {
@Override
public void onEnable() {
getLogger().info("WaterCheckerPlugin has been enabled!");
}
@Override
public void onDisable() {
getLogger().info("WaterCheckerPlugin has been disabled!");
}
public static boolean isInWater(Player player) {
return player.getLocation().getBlock().getType() == Material.WATER;
}
}
package fr.xenore87.waterchecker;
import org.bukkit.entity.Player;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
/**
- This class will automatically register as a placeholder expansion
- when a jar including this class is added to the /plugins/placeholderapi/expansions/ folder
*/
public class WaterPlaceholderExpansion extends PlaceholderExpansion {
/**
* This method should always return true unless we
* have a dependency we need to make sure is on the server
* for our placeholders to work!
* This expansion does not require a dependency so we will always return true
*/
@Override
public boolean canRegister() {
return true;
}
/**
* The name of the person who created this expansion should go here
*/
@Override
public String getAuthor() {
return "clip";
}
/**
* The placeholder identifier should go here
* This is what tells PlaceholderAPI to call our onPlaceholderRequest method to obtain
* a value if a placeholder starts with our identifier.
* This must be unique and can not contain % or _
*/
@Override
public String getIdentifier() {
return "example";
}
/**
* if an expansion requires another plugin as a dependency, the proper name of the dependency should
* go here. Set this to null if your placeholders do not require another plugin be installed on the server
* for them to work
*/
@Override
public String getPlugin() {
return null;
}
/**
* This is the version of this expansion
*/
@Override
public String getVersion() {
return "1.0.0";
}
/**
* This is the method called when a placeholder with our identifier is found and needs a value
* We specify the value identifier in this method
*/
@Override
public String onPlaceholderRequest(Player p, String identifier) {
// %example_placeholder1%
if (identifier.equals("inwater")) {
if (Main.isInWater(p)) {
return "true";
} else {
return "false";
}
}
return null;
}
}
no error
but the placeholder is alltime on "false"
I use 1.8 and java 8
have you ever heard of using ```
primarily
secondly, only give us the code thats like actually relevant to the issue
dont include all the comments
third
Check what block the player is actually standing in
System.out.println(player.getLocation().getBlock().getType())
if(Main.isInWater(p))
return "true"
else return "false"; 💀
blud
how can there be so many mistakes in such few lines of code
that code looks like it was written by chatgpt or smth
lmao
How bad is the idea of making a placeholder that reads from a file in every single request
that saved about 5 MB, still at around 23 MB tho :(
ever thought about spigots lib system?
never heard of it
whaaat
send link
it's the thing that breaks maven central's ToS

yep
also SQLite and MySQL drivers are included in Spigot
no way
if u want to use them
although those are intended for internal use
why does spigot need mysql/sqlite?
does 1.8.8 have it
https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/browse/pom.xml?at=refs%2Fheads%2Fversion%2F1.8.8#58-71
it uses a diff mysql connector though, idk what the difference is
this is for my framework tho, dont rly wanna have to declare the libraries in all of my plugins
then deal with the file size
so can i just remove mysql/sqlite from my jar then and it should work?
you wanna use the same dependencies and its versions too
wdym?
it wouldnt even be in my build.gradle.kts at all
i just specify the classpath of the driver class and jdbc does funky stuff idk
// Load driver
try {
Class.forName(method.driver);
} catch (final ClassNotFoundException e) {
AnnoyingPlugin.LOGGER.log(Level.SEVERE, "Failed to load the database driver: " + method.driver, e);
return null;
}
so the dependencies r runtimeOnly actually
they're compile only :(
<scope>compile</scope>
gradle used to have compile but its now implementation
fun history fact of the day 🙃
1.8.8 doesnt generate a libraries folder, but 1.20.4 does (with mysql/sqlite), where is mysql/sqlite for 1.8.8?
i think its just in the server jar
nope
.............
in cache folder or smth
[17:43:28 INFO]: [AnnoyingAPI] Loaded the database driver: xyz.srnyx.annoyingapi.libs.h2.Driver
[17:43:28 INFO]: [AnnoyingAPI] Loaded the database driver: org.sqlite.JDBC
[17:43:28 INFO]: [AnnoyingAPI] Loaded the database driver: com.mysql.jdbc.Driver
[17:43:28 INFO]: [AnnoyingAPI] Loaded the database driver: xyz.srnyx.annoyingapi.libs.postgresql.Driver
```it work :)
How does one register enchantments in 1.20.4?
Did you figure it out perhaps?
gay reflections
✨ internal registry ✨
Nope. Just went back to hiding them with flags.
Anybody with NMS NPC experience can you explain something to me. I’m trying to apply a skin to my NPC but it doesn’t seem to take. Am I supposed to spawn the NPC first then update its skin or should I set the textures property on spawn?
I’ve tried both ways, each time the NPC spawns but with its default skin producing no errors both times.
is the textures property signed?
Ya signature and… the other one. I’m not at pc right now so I forget what it’s called but both are gotten from mineskin using json
What version?
I’m caching both values to a file and from what I can tell from debug they’re being retrieved properly
Latest 1.20.4
Are you setting the PlayerProfile and PlayerTextures?
Umm no I don’t think I am. Just player profile. PlayerTextures?
Thats how you set the skin now is update the skin URL in PlayerTextures.
Is this new? Like recent versions?
1.18+
i personally dont register them, i just use nms to apply the nbt data to the itemstack and then just check for it in the specific events it would be used
since enchantments wont show on the itemstack tooltip without modifying the lore
i have to manually change the lore and deal with all the bs
In my case... it was for the enchantment glow.
i just used protection 0, then replaced it if a higher version of protection was wanted on the itemstack
Am I able to get/set PlayerTextures of a ServerPlayer?
you might beable to get, but i dont think you can set since from like 1.7.x player textures have been signed or smth and prevent you from doing so
afaik player's texture is stored under gameprofile
Ya in my case the NPC the GameProfile textures are not set and when I try to set them it doesn’t update the skin
You have to set the PlayerProfile now.
Even through NMS?
Yeap
when was playerprofile added?
1.18+
im trying to find it but only find gameprofile
I’ve gone through Citizens2 and another plugin and I haven’t seen any mention of PlayerProfile… plus doesn’t the URL have to be from the mojang servers? Mine are saved locally
playerprofile seems to be a paper specific thing
Yes it has to come from the textures.minecraft.net API
thats deprecated
unless its only deprecated for paper and forks
It could be, I’m on mobile so I’m struggling over here lol
seems like it is
when you set them did you delete and remake the entity in world?
since afaik youd have to do that to update its texture
Here is how I set the PlayerProfile on skullmeta but essentially you do it the same way on EntityHuman
PlayerProfile profile = Bukkit.createPlayerProfile(UUID.randomUUID(), "Minion");
PlayerTextures profileTextures = profile.getTextures();
profileTextures.setSkin(textureURL);
skullMeta.setOwnerProfile(profile.update().getNow(profile));
skull.setItemMeta(skullMeta);
PlayerProfile.update() returns a completable future so I recommend doing this Async if you just want to use getNow()
yeah i was about to mention the getNow
Thank you, didn’t even know PlayerProfile existed, I’ll look into it more when I get back to my PC
👍
was about to say, unless you're returning skull couldn't you just do profile.update().thenAccept(setSkin, setowningplayer, setmeta)
i know spigot can be pretty weird so
In my method above I return the skull.

idk if the profile api takes care of that
i've always (since 1.20.2) used setSkin new URL the texture
never signed it
but i'm adding it to an inventory, so maybe that is related 
what exactly makes the screen freeze when you open an inventory with many custom skulls?
would it worth trying this
skullMeta.setOwnerProfile(profile.update().getNow(profile));


Maybe I'm thinking of "signed" wrong. What do you mean?
Yeah the lore manipulation is what I want to avoid lol
Got it working using just NMS. The issue being I was tired last night and was setting textures to an older instance of the NPC's GameProfile 
How else would you display them?
well my mistake fsr I thought the lore is applied automatically if the enchantment was registered and applied to the item
That is correct, with the older versions of the API registering the enchant would take care of lore for you
My server uses custom enchants heavily (Prison) and when the API removed custom enchant "support" I switched to PDC but the other's suggestions work just as well, as well.
yeh as people keep saying it was never really a feature to register them
oddly enough
though it makes sense ig
I guess I will have to fiddle around with PDC, been already using it, since some of the plugins we are using in 1.20.2 keep stripping them away when restarting the server, I suppose due to them being registered after those plugins initialize
how to check block at location is exist with javascript expansion ?
It never did that, the client doesnt know how to display the enchantments
Then I must of been working with witch-craft. Because I was able to do it using the API 
:/ ?
at spectific world ?
I might be mistaken, thinking back I might of been messing with lores back then
yes, you need to get the world somehow and then use that
To get player's world you use BukkitPlayer.getWorld()
then ?
.getBlockAt(x, y, z).getType().name().indexOf("AIR") == -1
getType() - the Material
name() - the name of the Material
indexOf("AIR") == -1 - it doesnt contain the word "AIR" (there's AIR, CAVE_AIR and a couple more iirc)
where can i read doc ?
If you click on the type returned by getBlockAt, which is Block, you will see all methods it has
Ah, you meant the docs for the js expansion.
Well, there's a few variables injected in each script
BukkitPlayer - org.bukkit.entity.Player - the player for whom the placeholder is parsed
BukkitServer - org.bukkit.Server - the server object
args - String[] - the arguments provided in the placeholder
And there's probably 1 more but I can't remember it
:/ error
Yeah because x y z are strings, you need to use parseInt(location[n])
ah yea
why it return trueValue ? type = AIR
Cause you are doing && which says if all are true which it never would be.
👍🏼
Pro gaming tip use material.isAir
hi, currently have issues with a custom inventory updating itself. I have a runnable every tick which runs a method, and the method uses an ItemStack list to fill out slots in that inventory. Whenever items in the List are replaced using set() however, nothing is updated in the inventory, anyone know why?
Is the list in the runnable the same list you created the runnable with or is it the list you are setting?
Also show code so we get a clearer picture. Even minimal code helps.
the list is created in another class
public List<ItemStack> playerHeads;
public CrashGame(CrashItPlugin plugin) {
this.playerHeads = new ArrayList<>();
well based on this code, the inventory isn't being updated anywhere
where do you use the playerHeads list?
i use it in a method in another class called renderPlayerBets() in a loop
when testing i had no way to check if the index of the itemstack list is null, so i just decided to ignore it with IndexOutOfBoundsException instead
can you show the code?
private int itemstackArray;
for (int b = 9; b < guislots; b++) {
if (!borderInts.contains(b)) {
if (inventory.getItem(b) != null) {
continue;
}
if (inventory.getItem(b) == null) {
try {
ItemStack renderBetItem = bets.get(itemstackArray);
inventory.setItem(b, renderBetItem);
itemstackArray++;
} catch (IndexOutOfBoundsException ex) {
// ignore
break;
}
}
}
}
this is in a different class
So based on this code, it will only ever set the slot once.
You basically say if slot "b" is not null continue through loop. Is this the current outcome?
Also the second if, checking is null, is useless since you just checked if it's not null.
You can check if "b" is less than the length of the list "bets".
if(bets.size() < b) {}
are you updating the original inventory or the one that the player is currently viewing?
He's not updating. Only setting the item once.
h2.jdbc.JdbcSQLSyntaxErrorException: (Message 42S03 not found); SQL statement:
MERGE INTO entities (target, testTime) KEY(target) VALUES (test, '?') [42103-220]
```i dont understand whats wrong with it *ping if reply*
code
final PreparedStatement statement = dataManager.connection.prepareStatement("MERGE INTO " + table + " (target, " + column + ") KEY(target) VALUES (" + target + ", '?')");
statement.setString(1, value);
statement.executeUpdate();
yeah i mean test itself is not a valid value
and also to set a parameterised value you need to leave the ? unquoted, otherwise you're just putting the literal string "?"
wdym?
String values need quotes, and if you want statement.setX() to work, the question mark should not be surrounded by quotes
is that really always the case
yes
this is what i had before and it didnt work either:
"MERGE INTO `" + table + "` (`target`, `" + column + "`) KEY(`target`) VALUES ('" + target + "', ?)"
? is basically the placeholder marker
Im almost sure Ive seen it work even with single quotes
why do you use string concatenation and placeholders?
or must be dreaming
oh maybe it was the other thingamajig
the table + column + target arent user inputs so they dont need to be placeholders
those are used for like column or table names i think
yeah thats what im using in my statement above
but target doesnt need to be a placeholder
ig i could make it one
entity uuid
blud stop bluddin
either one or the other (both placeholders or string concat)
not both lol
there's no harm in doing it the good way
I was hopping this would be a good moment to talk ab sql injection, but oh well 
ik about it
ig it could be a user input cause it might not always be an entity uuid
so ill keep it a placeholder
h2.jdbc.JdbcSQLSyntaxErrorException: (Message 42S03 not found); SQL statement:
MERGE INTO `entities` (`target`, `testTime`) KEY(`target`) VALUES (?, ?) [42103-220]
any recommended software to view an H2 database?
If you have a jetbrains student license, you can get intelIij idea ultimate which has a very great database tool
oh yeah it has H2, didnt know
To play the health regeneration animation, is it player.sendHealthUpdate()?
the table + columns exist
im not sure what TARGET is, though
I suppose it shouldn't be case-sensitive, but try TARGET instead of target?
nope 
h2.jdbc.JdbcSQLSyntaxErrorException: (Message 42S03 not found); SQL statement:
MERGE INTO `entities` (`TARGET`, `testTime`) KEY(`TARGET`) VALUES (?, ?) [42103-220]
do not use enums?
Open for ideas that allow you to match a string to multiple variables.
I would prefer not generating a map of all the items needed.
i mean you can do reflections
Can you give an example? I don't think I'm thinking of the same thing.
is your intention for the extra methods to not be visible?
Yes. I don't want the methods, variables and constructors to be duplicated in all 12 enums.
well then I don't really see how you could do it using enums
that's not exactly their purpose
Open for ideas.
Exactly whats posted is pasted in all 12 enums.
can u give like an example? 🤔
That is the example xD
public record StatisticType(String id) {
public static final StatisticType KILLS = new StatisticType("kills");
private static final Map<String, StatisticType> values;
public static Optional<StatisticType> type(String id) {
return Optional.ofNullable(values.get(id));
}
static {
Map<String, StatisticType> types = new HashMap<>();
for(Field field : StatisticType.class.getFields()) {
if(!Modifier.isStatic(field.getModifiers()) || field.getType() != StatisticType.class) continue;
try {
StatisticType type = (StatisticType) field.get(null);
types.put(type.id, type);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
values = types;
}
}
Enums are not suitable for that as they don't support inheritance, generics or anything at all tbh
if you have various types with different paramaters you should rethink design to avoid use of enums. Or you can re-invent them like i did in this example, as it wil support basically any abstraction
Ok so it was what I was thinking lol.
At that point I have to loop through every value in each enum which defeats the purpose.
you do it only once at class init though?
I do but the issue is I already have to write each name individually which is the point of the methods/constructors in the first place. If I do similar to your code above I still have to check the enum, the value and apply a value to the variable based on its name.
Meh. I'm just gonna scrap it. Its still to close to writing down all material names anyways.
Anyone? it looks like when using that method a damage animation is played too
where it does a little wave effect?
ah well that's a different effect tho
Yeah it might be something else that I messed up
regeneration basically jumps each heart individually one per tick
but, for that the player has to have regeneration, or, well, the client has to be told it has regeneration
Yeah i got it thank you
Is there not a method to kill the player? Do I just have to set their health to 0?
pretty sure that's what you do to "actually" kill them yeah
Another question haha
How can I change the state of a campfire to be turned off or turned on?
Do you have a different Enum class for each material?
I am so confused on how you check that what the
BlockState?
There isn't any method in the Campfire blockstate relating to that
Or whether it is a signal fire or not too
Is there no API for that?
I see that RedstoneWallTorch has a setLit() method
It doesn't seem to
Cast block data to campfire
Campfire campfire = (Campfire) block.getBlockData();
campfire.setLit(false)
I swear
There is no setLit() method
https://paste.helpch.at/uboyopuwec.java This is the whole class I am seeing
Yeah even if I try casting to Lightable, it gives an error saying it cannot be cast
if I get a block's state through clickedBlock.getState(), do I need to setState() or similar once I have changed it?
BlockState#update should work
Nothing seems to happen :/
so if I do campfireState.setItem(1, item) campfire.update(), that should work?
yeah, try update(true)
Not each material but like sub material. Log, wood, stone, door, fence etc...
is there devs in here that can build a plug in for you? sorry if am asking in the wrong channel thank you
you can ask in #1202497508203561020 #1202497504655188028 @dark canopy
thank you for your help sorry i was in the wrong channel
all good
Yeah that did it thank you
the naming is sometimes a bit confusing ngl
when the block and the state/data has the same class name
does anyone know how I can disable only a specific check in the gradle ktlint plugin (org.jlleitschuh.gradle.ktlint)?
(I want to disable the package and class name check for my NMS modules)
You used to be able to do something like this using spotless for ktlint
ktlint("0.46.1").editorConfigOverride(
mapOf("disabled_rules" to "filename"),
)
But it has updated recently and I don't know how it's done now, but the best way to deal with it is using it with spotless
sorry but what is spotless? 😄
ah thx
I'm stupid, it was possible to just create an .editorconfig on the root project and disable the rules there
Oh yeah I forgot about that lmao
Noob
hi can someone help me i need to convert my 1.8.8 menus to 1.20.4 menus
not #development question
but try #1202497508203561020 or #1202497504655188028
dont expect anything though
okay so im not the best with gradle and i'd like to ask so i have NMS modules for plugin and i run the paper dev thingy in them to remmap the jar, and if i add that module into main plugin module its not remapped? am i doing something wrong or is this not possible?
you can add the module using ```kt
project(":paperweight-module:", "reobf")
i think
in your base build.gradle(.kts)
okay i'll give it a try
you should also have like an interface/compatibility module as well instead of using the nms modules directly (and access via reflection afaik)
yeah but like NMS has to remap the thingies cuz i didnt want to use full reflection and do java magic
ye but I mean like you shouldn't have this in your plugin module build.gradle(.kts)
oh
yeah
ignore what i said :)))
i think adding the reobf here should work
yup it works, thanks!
im still getting an error when trying to execute my SQL: https://paste.srnyx.com/vavezepevo.apache ping if reply
try running that same query directly from your sql console
@dark garnet
generally those errors should be a lot less cryptic
[42S03][42103] (Message 42S03 not found); SQL statement: MERGE INTO `entities` (`target`, `testTime`) KEY(`target`) VALUES ('test', '123456') [42103-220]
whar
thats all it says
DATA> MERGE INTO `entities` (`target`, `testTime`) KEY(`target`) VALUES ('test', '123456')
[2024-02-16 18:50:34] [42S03][42103] (Message 42S03 not found); SQL statement:
[2024-02-16 18:50:34] MERGE INTO `entities` (`target`, `testTime`) KEY(`target`) VALUES ('test', '123456') [42103-220]
ping again if anyone knows how to fix 
but the table does exist whats going on 😭
A common cause is that the names are written in different case.
make sure all the cases are right
they are, the screenshot i posted is the actual database
entities is lower-case, which is how i type it in the cmd
i mean at what point do you just use SQLite lmao
im planning on supporting sqlite too
h2 is just the first one im testing 🙃
well try getting it working on SQLite and it'll probably give you better error messages
it was working with postgresql when i was doing my preliminary tests but ye ill try sqlite
hmm then yeah might be an H2 thing
maybe it doesn't support whatever is going on there
sqlite fails with something else;
[19:54:47 ERROR]: [AnnoyingAPI] Failed to create column testTime in table entities
org.sqlite.SQLiteException: [SQLITE_ERROR] SQL error or missing database (near "EXISTS": syntax error)
``````sql
"ALTER TABLE \"" + table + "\" ADD COLUMN IF NOT EXISTS \"" + column + "\" TEXT"
weird, it worked when creating table
"CREATE TABLE IF NOT EXISTS \"" + table + "\" (target TEXT PRIMARY KEY)"
oh yeah just not in ALTER
ah
sqlite works, either just an h2 thing or my statements r wrong for it
classic
What
Anyone would be interested Hooking 2 plugins togeter ? id not mind paying or whatever..
how to make first image (currently default) to second image ? placeholderAPI
public Map<String, Object> getDefaults() {
final Map<String, Object> defaults = new HashMap<>();
defaults.put("safe","&aAn toàn");
defaults.put("dangerous","&cNguy hiểm");
defaults.put("world.world","Thế giới");
defaults.put("world.build","Xây dựng");
defaults.put("world.mountain","Đồi núi");
defaults.put("material.1","oak_log");
defaults.put("material.2","stone");
defaults.put("material.3","grass_block");
defaults.put("material.4","sand");
defaults.put("material.5","gravel");
defaults.put("material.6","coal_ore");
defaults.put("material.7","sea_lantern");
defaults.put("material.8","target");
defaults.put("material.9","redstone");
defaults.put("material.10","torch");
defaults.put("material.11","bell");
defaults.put("material.12","iron_sword");
defaults.put("material.13","iron_axe");
defaults.put("material.14","iron_pickaxe");
defaults.put("material.15","iron_shovel");
return defaults;
}
probably try a LinkedHashMap instead
HashMap doesn't keep insertion order
Was he asking about the key-value being unordered or the key being string… I am confused in the question 😄
ah good to know
both? lmao
no idea either
on a very different note, any ideas why I get this error when listening to the system chat message packet with packetevents? https://paste.helpch.at/esobebejat.rb I only get this whenever I use the vanilla /give command...
which is weird? What's different about that exact command response
why it dont work ? %name_position_10%
@Override
public @Nullable String onPlaceholderRequest(Player player, @NotNull String params) {
String[] args = params.split("_");
Map<Integer, Integer> slotToPosition = new HashMap<>();
slotToPosition.put(10, 1); slotToPosition.put(11, 2); slotToPosition.put(12, 3); slotToPosition.put(13, 4);
if (params.equalsIgnoreCase("position")) { return slotToPosition.get(String.valueOf(args[2])).toString(); }
if (params.equalsIgnoreCase("material")) {
int num = slotToPosition.get(Integer.parseInt(args[2])) + (Integer.parseInt(args[3]) * 28);
String material = getString("material." + num, "");
return material;
}
return null;
}
the equalsIgnoreCase doesn't make sense this way
what the code must to be ?
depends on what you want it to do, but if any of the equalsIgnoreCase calls is true, there can't be a _ in the string
now i just to make it return something
you need to check if it starts with position lol
not if its equals to position
your code would only "work" for %homeprogress_position%
so you either check if args[0] is position
or if params starts with position
one of the two
i need input something
what?
I already told you the answer....
want me to give the code or what
lol
but im not get it :/
no idea how else I would explain it, maybe someone else can
so i need to check it startwith
otherwise, there is an issue with basic java here
if you want to use params
yes
since you already splited the params
you can also check if args[0] is position
wait, param is position_10 ?
yes
helloo
yep :D
How you doing?
good :))
not working on a lot of mc stuff though
ahh yea, same. What platform you working on now?
trying out some other things
the most I've done outside of mc is probably android though
jetpack compose ftw
sure
that was sarcastic.
I sure as hell hope you are 13+ cause I assume you don't need to be spoonfed xD
Do you have basic java knowledge?
well since you used maps and what not I would assume yes.
All answers were given already
dkim already answered your question
already provided 2 ways of doing it, if you expect someone to just code it all for you, #1202497504655188028 exists lmao
Ayy, I actually do android for work rn
😌
check if args[0] is equal to "position"
solved
is placeholder has look slike math.min, max?
huh
%math_0_min(%math_0_(%var_NeutralDamage_int% - %mythic_var_%entity_uuid%_Defense%)%, 1)%
cause
[22:31:46 WARN]: [PlaceholderAPI] [math] Placeholder: %math_0_min(%
[22:31:46 WARN]: [PlaceholderAPI] [math] Cause: 'min(' is not a valid Math expression.
from here
tho for future reference thats not a development question, its either #placeholder-api (i think dont crucify me if its not), #general-plugins or #minecraft
thanks!
can someone help me with sorting with getLocalDateTime its not sorting correctly https://paste.helpch.at/loqififova.rust
public LocalDateTime getLocalDateTime() {
if (dtf == null) {
dtf = DateTimeFormatter.ofPattern("M/d/yyyy h:mm a");
}
String newTime = getDate();
newTime = newTime.replace("[", "");
newTime = newTime.replace("]", "");
return LocalDateTime.parse(newTime, dtf);
}```
You are always sorting twice, that doesn’t make sense
Also what the heck is that
he is lazy loading the datetimeformatter
That’s the smaller issue here lol
Lol
i can give you a bigger issue if you keep looking at me funny
I… I’m sssorry…
I forgive you
thanks
dom sub shit right there

Hey, is there anyone interested in making a plugin for me? Its basically a plugin that checks if someone is gliding with a custom model data elytra and add a trail of particles to it. I want it to work with different elytras and different trails to them. deleted it by mistake
#1202497504655188028 / #1202497508203561020 is where you should ask 
I couldnt see those haha, thanks
Emily's ready to throw hands lol
can i use IF on placeholder?
Does anyone knows about the new papermc nbt exploit ?
I do
my plugin patches it
What kind of exploit is this ?
A crash exploit
it's also patched on recent versions of paper 1.20.4
Yep I know. But how was the exploit working ? 🤔
can't share much but it has to do with tab complete suggestions
I thought it was something about nbt data
why do you need to know how it works?
because I'm interested in what something like that looks like and how we can prevent something like that, also in the future, if this happened again
staying up to date is how you can prevent it
Yeah with the paper jar 😂
If a "patch" is already out for it I don't see why you can't just answer his question.
@digital temple I would read through the patch code to see how to replicate as I don't know myself.
because its only for 1.20.4 paper (forks)
They don't support earlier versions anyways.
many many servers arent on 1.20.4 yet
sure, not my problem tho, i'd rather not let someone have the exploit even if easily findable
in general, an exploit should only be shared one major version after I would say
so when 1.21 comes out.
ngl, a "big" free public client does have a opensource crash using it
if people stay in 1.20 then that is surely their fault
sure, still dont want to be the one who got them crashed on
but 1.20.3 to 1.20.4 is not that realistic
especially since i make plugins that patch it on older versions
since several builds get released every month
and keeping it updated is a hassle
I don't personally care about older versions
for me only latest and previous major versions should be supported
so rn, 1.20 and 1.19
anything before that, idc
they can have exploits, they can be on fire, idc
their fault for using outdated systems.
well if you run a server, that's your job, basically
Are there any libraries to handle Schematics?
WorldEdit
Is there a simple way to convert a project from using maven to using gradle?
Check your IDE, eclipse has converters.
I'm on IntelliJ, I'll see what I can find
gradle init
although it's not the best
What is the common consensus on the maven vs gradle debate?
I find maven easier to use/understand
Hell no
I am totally the opposite
and imo it is the opposite
gradle is faster and imo more understandable
fuck xml files lol
(fuck groovy too though, kotlin dsl)
although it was written years ago
so idk if things have changed or not
Hi! Is anyone having the same issue that couldn't play sound asynchronously after 1.20.4?
is there any error or anything?
But if not, you can just create a scheduler for a task to run on the main thread
I know, but why it just can't after 1.20.4, it works fine before.
wait isn't 1.20.4 latest?
yes, so i'm wondering.
Listen bro, we’ve been trying to update from 1.20.1 to 1.20.4, but ProtocolLib doesn’t have a stable release, and the whole MMOItems/MythicLib/MMOCore squad just barely released a dev build supporting it a week ago 😫
💀
that's what happens when the whole mc community relies in a single plugin... I really hope one day we have more alternatives to protocollib... packetevents is going there but apparently its dev is a immature and it has some bugs.
probably better chances asking in the spigot/paper discord
(although who uses spigot api nowadays)
viaversion wont have a non dev build for 1.20 till 1.21 comes out
How to turn rebalanced villager trades if the world was created without this feature? Ive changed trade_rebalance option in level.dat by using nbt editor. but the server said Pack trade_rebalance requires features minecraft:trade_rebalance that are not enabled for this world, disabling pack. Purpur 1.20.4
I also cant turn it on with /datapack enable trade_rebalance Pack 'trade_rebalance' cannot be enabled, since required flags are not enabled in this world: minecraft:trade_rebalance!
I keep getting a expected <document start>, but found <block mapping start> error when trying to load this:
db:
host: 127.0.0.1
port: <port>
db_name: <db_name>
user: <user>
password: <password>
auto_save_interval: 6000
debug_level: 2
What's actually wrong with my yml file?
No
u forgot >
I mean
I replaced the password with that
I replaced most of the info on there with <> as I don't want to share it with everyone haha
how are you trying to load it?
ohhh
It's just my config.yml
is there any more information in the exception?
https://paste.helpch.at/cogaqucika.php This is the whole exceptiojn
There seems to be some invalid syntax in your config! You can paste it into https://yaml.helpch.at/ in order to find out where your issue is!
I tried that already
is your password properly escaped?
What do you mean with that?
No, is it meant to be
there might be special characters in it that have some meaning in yaml
remove the characters until theres no more error ig
yea
I mean, the password to my database has that symbol though 🥲
I don't think @ is a special symbol in yaml
You can escape characters in YAML if they're special
It's always pointing at my auto_save_interval part
I tried wrapping the password in "" and the issue persists
did you try this
or putting password: ""
yaml parsers tend to show errors ahead of where the actual error is
you can also use '' instead
I would suggest you use an online yaml parser with the entirety of its contents
the one I find best is yamlchecker.com
oh. you have passwords in it
idk how trustworthy that website is
maybe you can find an os library with positive reviews to use locally
You can also try this if you have dobule quotes in your passwords
Also, always remember, TABs are not supported in YAML
Huh uhh
I update my config.yml, but it does not seem to really update
It still thinks that it is auto_save_interval: 6000, though when I look at the file it is auto_save_interval: 4000
I know, I know... but have you tried turning it off and on again?
yeah, several times
Yeah no matter what I write in my config.yml, it keeps finding the old one?
I deleted the jar and put it back in there again and it started working
What could have gone wrong
Many things, none that I am aware of :))
Is triumph cmd a continuation of matt's framework?
is there a guide on tab completions for Triumph, like there was for matts framework?
Or simply use a text editor
isn't triumph cmd part of matt's framework?
ah
hmm if the current docs are outdated, then he also has a discord server
I think you just had the old link to the documentation. new one: https://triumphteam.dev/
Even that one is outdated 
I want to load data from a database only once the server is done starting up and all plugins have loaded, as the plugin's GET query will get updated by other plugins which depend on it, how would I go about that?
maybe WorldInitEvent or WorldLoadEvent? (i think these may fire multiple times so you should account for that if thats what you end up using)
ServerLoadEvent?
Though is it guaranteed to fire when the server has finished loading
(And not when some plugins may still be disabled)
yeah I think ServerLoadEvent fires earlier which might give you trouble, idk the exact order of operations so thats maybe something you want to play around with and figure out
I am lowkey losing my mind here trying to figure out how to do the following:
I have a plugin which works as a "core" of my other plugins. This plugin works as an API for those with plenty of utility methods, as well as being what hooks into my server's database and what saves/loads player data to and from it.
This core plugin, has a class called PlayerData which has four simple variables which stores the information found on the database upon a player's join, and then saves it into the database once they quit.
However, as my other plugins will also need to add their own data to the database, I am trying to create some form of generic data container in my PlayerData class.
My original idea was to make a Map<String, Object> and simply add the values to that, however it could easily break when saving and loading to the database.
After realizing that, I had a thought: Can I somehow create a system where in order for my plugins to add data to the Map<String, Object>, they first gotta call some form of register() method which would:
- Add a default key-value pair to the map for the data type to be stored
- Modify the queries used by the
load()andsave()methods of my database implementation, and those used to create the tables.
And lastly, to actually set this data inside of the PlayerData class, they would have to call a method like updateAdditionalData(String key, Object value), which would check if the key is present in the map before adding it (And if that fails, an exception is thrown).
I KNOW This is a wall of text I'm sorry, I just have been trying to figure out how to make this work for hours but I can't
you dont really want to keep changing the table contents, use a seperate table for each plugin
and refer to the main row id's
Why not?
I thought that this way of doing it would be the most efficient with the least amount of code repetition
Within my AsyncChatEvent, in 1.20.1 this worked fine:
gsonComponentSerializer.serialize(originalMessage
But now in 1.20.4, it doesn't serialize into json at all. It just returns the raw message -> "test"
Any clue?
look into primary and foreign keys in sql
Yeah but that way I will need to write load and save logic in each of my plugins
as for code repetition, what you want is a basic orm
The reason for this was to keep all of the saving/loading in one plugin
arent you planning on doing this anyways? from what you sent
And also the PlayerData class would store all the data for all plugins as well
I would only need to do playerData.updateData(Key, value) though
Instead of writing sql queries etc.
modular works way better imho, all you are doing with the fat core is spagettifying when you dont need to
orm is your solution, hibernate might work fine if you dont care about jar sizes
you wont write queries, you just make the data classes and let the orm take care of the rest
I have no clue what orm is
I'm reading on it but I don't really know what to do with it
ORM = object relational mapping
Idk I was really hoping that what I had in mind would work since it seemed like the least amount of code repetition and the highest level of compartmentalization I could achieve
Even if it wasn't efficient it would still be cool if I could somehow let my core plugin do ALL the database and data stuff while the others take care of other stuff