#development

1 messages · Page 73 of 1

queen plank
#

Ping when responding pls :)

worn jasper
#

just save when they close it? lol

queen plank
#

Well I can't really

worn jasper
#

why wouldn't you

queen plank
#

I don't know when they close it, or I can find out but it's goofy asf

worn jasper
#

there is legit an event for that?!

queen plank
#

Well obv I made my own

worn jasper
#

wdym made your own?

#

It's still an inventory, InventoryCloseEvent will be triggered

broken elbow
#

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.
queen plank
# worn jasper It's still an inventory, InventoryCloseEvent will be triggered

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

broken elbow
worn jasper
queen plank
worn jasper
#

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

worn jasper
#

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.

queen plank
queen plank
#

So not q1 -> q2 -> q2 -> ... -> GUI

worn jasper
#

use anvils

queen plank
#

What about lists?

worn jasper
#

?

queen plank
#

Say lore

worn jasper
#

what's with that

#

you can't use them as input lol

queen plank
#

You can't really edit lore in an anvil.

worn jasper
#

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

queen plank
worn jasper
#

why would it be wonky though

#

you can easily do the same exact functions in an anvil

queen plank
#

Like how would you display this in a GUI

worn jasper
#

lmao

queen plank
#

yeah the line editing part is fine ig. But how would you show the list if not in chat?

worn jasper
#

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

queen plank
#

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.

worn jasper
#

on a side note, these types of "ingame builders" are quite overrated and most of the time, are barely used lmao, just saying.

queen plank
#

its more than an item builder

worn jasper
#

right click to go up

#

left click to go down

#

and voila

worn jasper
queen plank
queen plank
worn jasper
#

I am not speaking about item builders though

#

I am speaking about overall builders xD

worn jasper
queen plank
worn jasper
#

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

queen plank
#

ok xd.

worn jasper
#

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

queen plank
queen plank
worn jasper
#

This is just my POV on this, (and several other developers), solutions were given, you choose whatever you wanna do

queen plank
#

Like try telling UltraPlugin users that GUIs suck xd

worn jasper
#

that's funny that you mentioned those

#

but welp

queen plank
#

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.

worn jasper
dense drift
worn jasper
#

as said, from what I spoke with several devs which their plugins do have it, they say those systems are barely used.

dense drift
#

Anyways, in-game editors are shit, since you have to hover over each item to see what it represents

worn jasper
#

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

river solstice
#

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

minor summit
#

professional server plugin configurator yml developer

torpid raft
#

im a professional server custom item name color picker

tight junco
#

plus the system of implementing ingame editors is the jankiest shit in the world and the people who use them are morons anyway

fleet barn
#

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

grim oasis
#

any ideas for things that you "can or cannot do"?
Just a little confused, there are tons of random plugins out there

fleet barn
#

idk im just a little bit stressing about my acc getting banned or some shit

grim oasis
#

O.o

grim oasis
hoary scarab
#

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.

river solstice
river solstice
worn jasper
# fleet barn idk im just a little bit stressing about my acc getting banned or some shit

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.

worn jackal
#

who can i use getRankupName

#

?

minor summit
#

what

torpid raft
#

me

proud pebble
#

since that method doesnt seem to exist in the spigotapi

queen plank
#

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);
  }
}
minor summit
#

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

sterile hinge
#

(also Set#add returns a boolean)

queen plank
queen plank
sterile hinge
#

yeah but you can skip the check

queen plank
minor summit
#

it is entirely possible for no event to be registered twice and what i described above to still happen

queen plank
#

But that requires them to be subclasses no?

minor summit
#

yeah, but the event class itself will not be registered twice

sterile hinge
#

you can probably check if event.getClass() == the class you expect before calling into your code

minor summit
#

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

final cosmos
#

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?

worn jasper
#

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

dusky harness
#

¯_(ツ)_/¯

worn jasper
#

hmmm

minor summit
#

yeah that's just a map

lilac portal
#

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?

worn jasper
#

idk, but that doesn't look like what's displayed in the wiki

#

on the phone rn

#

so...

dense drift
#

ProxiedPlayer, registerPlaceholderHook??

final cosmos
shell moon
#

🤯

dense drift
#

Probably a different plugin

robust flower
#

what is the !learnjava command thing again? I need the links to send to a friend

waxen vector
#

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...

dense drift
#

Papi is a plugin, not a mod.

waxen vector
#

i can use luckperms

#

so i thought maybe i can use this too

dense drift
#

Try and see 🙂

dark garnet
#

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
}
torpid raft
dense drift
#

Why do you have to create and add a column every time?

dark garnet
dense drift
#

Why wouldnt the column exist?

dark garnet
torpid raft
#

why would the user delete a column just like that

dark garnet
torpid raft
#

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

dark garnet
#

but ig its better than having slow times

torpid raft
#

because the way you made your function makes it seem like you'll let people make their own tables and columns on the fly

dark garnet
#
@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

torpid raft
#

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

dark garnet
#

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)

dark garnet
lilac portal
#
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'
ocean crow
#

Can you even play a sound via ProxiedPlayer?

#

@lilac portal Bungeecord or Velocity?

#

As well what version

lilac portal
ocean crow
#

Yeah I don’t think you can play a sound through bungeecord

#

Same with getting a players location via getProxy().getPlayers()

lilac portal
ocean crow
#

Probably could do that as it’s above 1.16.

#

Just depends on how you’re doing it.

lilac portal
#

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
ocean crow
#

I use legacy on MCHub as well, but there’s a way todo formats like #FFFFFF

lilac portal
ocean crow
ocean crow
#

Kk :D

lilac portal
#

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?

ocean crow
#

Uh

#

I believe so. Lemme look at the docs rq.

lilac portal
#

ty :D

ocean crow
#

That should be it.

lilac portal
#

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

ocean crow
#

Yeah you should be able to do that

lilac portal
#

But how

dense drift
#

<click:_action_:_argument_>text</click>

#

Action will be open_url and the argument will be the url

ocean crow
#

Yeah

lilac portal
#

Lemme try

dense drift
#

Are you coding using chatgpt?

lilac portal
#

No

#

just for some stuff i can't seem to find inside the docs

#

if it has some better ideas

dense drift
#

Ok, take a closer look at the docs because they are very well structured, you have a list with all the actions

lilac portal
ocean crow
#

What’s up?

#

Whatcha getting?

lilac portal
#

I mean

#

lemme upload it to imgur

ocean crow
#

Okay

lilac portal
ocean crow
#

You don’t have it parsing through MiniMessage

#

You’re just sending it via a normal chat message.

lilac portal
#

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 + ")."));
dense drift
#

Despite both having the name "component", what you are using is from the bungeecord chat api

lilac portal
#

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;
ocean crow
#

Yeah gotta use MiniMessages API, not Bungeecords

lilac portal
ocean crow
#

Yea

lilac portal
#

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 + ").")));
ocean crow
#

Give it a shot

lilac portal
#

it was underlined

ocean crow
#

A lot of development is trial and era.

lilac portal
#

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 + ").")));
dense drift
#

What are you doing mate...

lilac portal
#

I am a beginer in this

dense drift
#

Read the docs

lilac portal
#

In the docs there is var, but as soon as i put var inside my code it becomes red :/

dense drift
#

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

lilac portal
#

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

dark garnet
#

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

minor summit
#

ok

torpid raft
#

ok

#

i was under the impression that mysql and mariadb could use the same drivers, that could save you some space

#

if true

waxen vector
tight junco
#

how did you implement it in

#

cause if you used compileOnly thats your first fault

dusky harness
#

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

digital temple
#

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

waxen vector
#

i just did implementation() 🔥

river solstice
#

yes bro

#

thats fire

#

ong

waxen vector
#

i have never used anything other than that before, how do u think i should add it?

river solstice
#

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.

analog skiff
#

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

river solstice
#

what doesnt work specifically

analog skiff
#

im not exactly sure whats causing this

river solstice
#

does it work in /papi parse?

analog skiff
#

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

river solstice
#

uh

#

your identifier will not contain the prefix

analog skiff
river solstice
#

so if (identifier.startsWith("evadedeco_top_balance_player_")) { should be if (identifier.startsWith("top_balance_player_")) {

analog skiff
#

o

#

so is that the entire issue

#

so if i typed evadedeco_evadedeco_top_balance_1 it would work ?

river solstice
#

no

#

change the if statement

#

well

#

nvm

#

yes, it shouldd

analog skiff
#
    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

river solstice
#

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.

analog skiff
#

yes but the reason i have it as evadedeco_top_balance_player is because i need this to work for top balance 1 - 10

river solstice
#
    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

terse osprey
analog skiff
#

but on a real not tysm

river solstice
#

well that's not really a placeholder issue

#

it told you what's wrong

analog skiff
#

its a me not understanding how to implement it ik

river solstice
#

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.

analog skiff
#

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
river solstice
#

honestly I havent seen this config so I can't tell

analog skiff
#

...

twin dawn
#

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.

river solstice
#

You mean you want to pass some data to OAUTH, then on successful authorization return it back?

analog skiff
#

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";
    }
}
sterile hinge
#

aren't there placeholders for vault already?

analog skiff
hoary scarab
#

getIdentifier is "evadedeco" but onRequest checks for "balance"... Haven't made placeholders with papi but maybe check that?

analog skiff
#

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 $

dense drift
#

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

hoary scarab
#

👍

#

On that note. Send a screenshot and check for errors.

analog skiff
dense drift
#

no, both methods get called and you should use onRequest

analog skiff
dense drift
#

No

analog skiff
#

yep

#

second i added it it worked perfectly

dense drift
#

@Override is just for reading purpose from my experience, though it is recommended to have it shrug

analog skiff
dense drift
#

Thats why you use a proper ide and let it handle these things for you

analog skiff
#

😦 im using Eclipse ide its old but works

dense drift
#

It is just old pepe_kek

river solstice
#

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

orchid acorn
#

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?

neat pierBOT
#
FAQ Answer:

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!

grim oasis
#

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

orchid acorn
#

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?

terse osprey
#

💀💀💀

grim oasis
orchid acorn
#

Ah I see

#

And are minecraft plugins generally hard to make?

grim oasis
#

I wouldn’t entirely say so, it’s about the same as getting to learn any other API

orchid acorn
#

Oh

#

I see

#

Ive never had experience with API's and stuff

#

dont think I learned OOP either

grim oasis
#

java is an OOP language, object-oriented programming

remote pawn
#

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

tight junco
#

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())

river solstice
#

if(Main.isInWater(p))
return "true"
else return "false"; 💀

#

blud

#

how can there be so many mistakes in such few lines of code

proud pebble
#

that code looks like it was written by chatgpt or smth

worn jasper
#

lmao

waxen vector
#

How bad is the idea of making a placeholder that reads from a file in every single request

dark garnet
spiral prairie
#

ever thought about spigots lib system?

dark garnet
spiral prairie
#

whaaat

dark garnet
#

send link

minor summit
#

it's the thing that breaks maven central's ToS

dark garnet
spiral prairie
#

also SQLite and MySQL drivers are included in Spigot

dark garnet
#

no way

spiral prairie
#

scroll down to libraries

dusky harness
#

if u want to use them

#

although those are intended for internal use

dark garnet
#

why does spigot need mysql/sqlite?

dusky harness
#

¯_(ツ)_/¯

#

true

dark garnet
#

does 1.8.8 have it

dusky harness
dark garnet
spiral prairie
#

then deal with the file size

dark garnet
dusky harness
#

you wanna use the same dependencies and its versions too

dusky harness
#

like if you use a newer version in ur build.gradle then it might break

#

¯_(ツ)_/¯

dark garnet
dusky harness
#

oh

#

ok i dont know how sql works

dark garnet
#

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

dusky harness
#

oh 💀

#

no it isn't

dark garnet
#

<scope>compile</scope>

dusky harness
#

gradle used to have compile but its now implementation

#

fun history fact of the day 🙃

dark garnet
#

omg

#

its only 5 MB now!

dark garnet
dusky harness
dark garnet
dusky harness
#

not the one from papermc

#

but like the one generated from that

dark garnet
#

.............

dusky harness
#

in cache folder or smth

dark garnet
#

oh yeah

#

cache/patched_1.8.8.jar

#

😠

dark garnet
# dusky harness i think its just in the server jar
[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 :)
river solstice
#

How does one register enchantments in 1.20.4?

river solstice
#

Did you figure it out perhaps?

tight junco
minor summit
#

✨ internal registry ✨

hoary scarab
terse osprey
#

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.

minor summit
#

is the textures property signed?

terse osprey
#

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

hoary scarab
#

What version?

terse osprey
#

I’m caching both values to a file and from what I can tell from debug they’re being retrieved properly

terse osprey
hoary scarab
#

Are you setting the PlayerProfile and PlayerTextures?

terse osprey
#

Umm no I don’t think I am. Just player profile. PlayerTextures?

hoary scarab
#

Thats how you set the skin now is update the skin URL in PlayerTextures.

terse osprey
#

Is this new? Like recent versions?

hoary scarab
#

1.18+

proud pebble
#

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

hoary scarab
#

In my case... it was for the enchantment glow.

proud pebble
#

i just used protection 0, then replaced it if a higher version of protection was wanted on the itemstack

terse osprey
#

Am I able to get/set PlayerTextures of a ServerPlayer?

proud pebble
#

afaik player's texture is stored under gameprofile

terse osprey
#

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

hoary scarab
terse osprey
#

Even through NMS?

hoary scarab
#

Yeap

proud pebble
#

when was playerprofile added?

hoary scarab
#

1.18+

proud pebble
#

im trying to find it but only find gameprofile

terse osprey
#

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

proud pebble
#

playerprofile seems to be a paper specific thing

hoary scarab
#

Yes it has to come from the textures.minecraft.net API

proud pebble
#

unless its only deprecated for paper and forks

terse osprey
#

It could be, I’m on mobile so I’m struggling over here lol

proud pebble
#

seems like it is

proud pebble
#

since afaik youd have to do that to update its texture

hoary scarab
#

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()

tight junco
#

yeah i was about to mention the getNow

terse osprey
hoary scarab
#

👍

tight junco
#

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

hoary scarab
#

In my method above I return the skull.

minor summit
#

thing is skull textures need not be signed

#

whereas player profile skins do

shell moon
minor summit
#

idk if the profile api takes care of that

shell moon
#

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 Thonk

#

what exactly makes the screen freeze when you open an inventory with many custom skulls?

minor summit
#

the client probably downloading all the textures

#

that's my guess

shell moon
#

would it worth trying this

#

skullMeta.setOwnerProfile(profile.update().getNow(profile));

minor summit
#

well no

#

the client has to download the actual png

shell moon
hoary scarab
river solstice
terse osprey
#

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 facepalm

dense drift
river solstice
#

well my mistake fsr I thought the lore is applied automatically if the enchantment was registered and applied to the item

terse osprey
#

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.

river solstice
#

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

wet pier
#

how to check block at location is exist with javascript expansion ?

dense drift
terse osprey
wet pier
#

at spectific world ?

terse osprey
#

I might be mistaken, thinking back I might of been messing with lores back then

dense drift
#

yes, you need to get the world somehow and then use that

#

To get player's world you use BukkitPlayer.getWorld()

dense drift
#

.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)

wet pier
dense drift
#

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

wet pier
#

:/ error

dense drift
#

Yeah because x y z are strings, you need to use parseInt(location[n])

wet pier
#

ah yea

dense drift
#

And so is the world

#

BukkitServer.getWorld(args[1])

wet pier
#

why it return trueValue ? type = AIR

hoary scarab
#

Cause you are doing && which says if all are true which it never would be.

grand island
unborn ivy
#

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?

hoary scarab
unborn ivy
#
    public List<ItemStack> playerHeads;

    public CrashGame(CrashItPlugin plugin) {
        this.playerHeads = new ArrayList<>();
dusky harness
#

where do you use the playerHeads list?

unborn ivy
#

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

dusky harness
unborn ivy
#
    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

hoary scarab
#

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) {}

proud pebble
#

are you updating the original inventory or the one that the player is currently viewing?

hoary scarab
dark garnet
#
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*
minor summit
#

code

dark garnet
# minor summit code
final PreparedStatement statement = dataManager.connection.prepareStatement("MERGE INTO " + table + " (target, " + column + ") KEY(target) VALUES (" + target + ", '?')");
statement.setString(1, value);
statement.executeUpdate();
minor summit
#

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 "?"

dense drift
#

String values need quotes, and if you want statement.setX() to work, the question mark should not be surrounded by quotes

river solstice
minor summit
#

yes

dark garnet
#

this is what i had before and it didnt work either:

"MERGE INTO `" + table + "` (`target`, `" + column + "`) KEY(`target`) VALUES ('" + target + "', ?)"
minor summit
#

? is basically the placeholder marker

river solstice
#

Im almost sure Ive seen it work even with single quotes

dense drift
#

why do you use string concatenation and placeholders?

river solstice
#

or must be dreaming

minor summit
#

'tis a dream

#

wake up

river solstice
#

oh maybe it was the other thingamajig

dark garnet
river solstice
#

the other symbol on tilde key

#

backtick? idk

minor summit
#

those are used for like column or table names i think

river solstice
#

could be

#

idrm tbh

dark garnet
#

yeah thats what im using in my statement above

dense drift
#

I mean on the VALUE

#

VALUE('" + target + "', ?) should be VALUE(?, ?)

dark garnet
#

ig i could make it one

dense drift
#

Why is that?

#

where does target come from?

dark garnet
#

entity uuid

river solstice
#

either one or the other (both placeholders or string concat)

#

not both lol

minor summit
#

there's no harm in doing it the good way

dark garnet
#

alr i made it a placeholder

#

still getting the same error tho

dense drift
dark garnet
#

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]
dark garnet
#

any recommended software to view an H2 database?

dense drift
#

If you have a jetbrains student license, you can get intelIij idea ultimate which has a very great database tool

dark garnet
#

oh yeah it has H2, didnt know

dense galleon
#

To play the health regeneration animation, is it player.sendHealthUpdate()?

dark garnet
#

im not sure what TARGET is, though

river solstice
river solstice
#

well

#

pass them as null

#

?

#

though that'd require int -> Integer

dark garnet
grand island
#

do not use enums?

hoary scarab
# grand island 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.

grand island
#

i mean you can do reflections

hoary scarab
#

Can you give an example? I don't think I'm thinking of the same thing.

river solstice
#

is your intention for the extra methods to not be visible?

hoary scarab
#

Yes. I don't want the methods, variables and constructors to be duplicated in all 12 enums.

river solstice
#

well then I don't really see how you could do it using enums

#

that's not exactly their purpose

hoary scarab
#

Open for ideas.

dusky harness
#

wdym?

#

like what would be copied and pasted?

hoary scarab
dusky harness
#

can u give like an example? 🤔

hoary scarab
#

That is the example xD

grand island
#
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;
    }
}
dusky harness
#

ohhh wait i see

#

oh lol

grand island
#

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

hoary scarab
grand island
#

you do it only once at class init though?

hoary scarab
#

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.

dense galleon
minor summit
#

where it does a little wave effect?

dense galleon
#

Yeah the camera just tilts a bit

#

And the player glows in red

minor summit
#

ah well that's a different effect tho

dense galleon
#

Yeah it might be something else that I messed up

minor summit
#

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

dense galleon
#

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?

minor summit
#

pretty sure that's what you do to "actually" kill them yeah

dense galleon
#

Another question haha

#

How can I change the state of a campfire to be turned off or turned on?

river solstice
dense galleon
river solstice
#

BlockState?

dense galleon
#

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

minor summit
#

Campfire extends Lightable or smth

#

it has setLit as well

dense galleon
#

It doesn't seem to

river solstice
#

Cast block data to campfire

#

Campfire campfire = (Campfire) block.getBlockData();
campfire.setLit(false)

dense galleon
#

I swear

#

There is no setLit() method

#

Yeah even if I try casting to Lightable, it gives an error saying it cannot be cast

minor summit
#

no no there is another Campfire interface

#

org.bukkit.block.data.type or something

dense galleon
#

AH

#

My bad haha

dense galleon
#

if I get a block's state through clickedBlock.getState(), do I need to setState() or similar once I have changed it?

dusky harness
dense galleon
#

Nothing seems to happen :/

#

so if I do campfireState.setItem(1, item) campfire.update(), that should work?

hoary scarab
dark canopy
#

is there devs in here that can build a plug in for you? sorry if am asking in the wrong channel thank you

torpid raft
dark canopy
#

thank you for your help sorry i was in the wrong channel

torpid raft
#

all good

dense galleon
river solstice
#

when the block and the state/data has the same class name

light pendant
#

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)

pulsar ferry
light pendant
#

sorry but what is spotless? 😄

pulsar ferry
light pendant
#

ah thx

light pendant
#

I'm stupid, it was possible to just create an .editorconfig on the root project and disable the rules there

pulsar ferry
#

Oh yeah I forgot about that lmao

dense drift
#

Noob

vast gazelle
#

hi can someone help me i need to convert my 1.8.8 menus to 1.20.4 menus

river solstice
#

dont expect anything though

mental haven
#

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?

dusky harness
#

i think

#

in your base build.gradle(.kts)

mental haven
#

okay i'll give it a try

dusky harness
#

you should also have like an interface/compatibility module as well instead of using the nms modules directly (and access via reflection afaik)

mental haven
#

yeah but like NMS has to remap the thingies cuz i didnt want to use full reflection and do java magic

dusky harness
mental haven
#

oh

dusky harness
#

actually

#

nevermind

mental haven
#

oke XD

#

i mean i do have interface that is then used by every version of NMS

dusky harness
#

yeah
ignore what i said :)))

dusky harness
mental haven
#

yup it works, thanks!

dark garnet
torpid raft
#

@dark garnet

#

generally those errors should be a lot less cryptic

dark garnet
torpid raft
#

whar

dark garnet
#

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]
dark garnet
#

ping again if anyone knows how to fix Sadge

dark garnet
dusty frost
#

make sure all the cases are right

dark garnet
#

they are, the screenshot i posted is the actual database

#

entities is lower-case, which is how i type it in the cmd

dusty frost
#

i mean at what point do you just use SQLite lmao

dark garnet
#

h2 is just the first one im testing 🙃

dusty frost
#

well try getting it working on SQLite and it'll probably give you better error messages

dark garnet
#

it was working with postgresql when i was doing my preliminary tests but ye ill try sqlite

dusty frost
#

hmm then yeah might be an H2 thing

#

maybe it doesn't support whatever is going on there

dark garnet
#

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"
dusty frost
#

I don't think SQLite supports IF NOT EXISTS

#

or MySQL

dark garnet
#
"CREATE TABLE IF NOT EXISTS \"" + table + "\" (target TEXT PRIMARY KEY)"
dusty frost
#

oh yeah just not in ALTER

dark garnet
#

ah

dark garnet
#

sqlite works, either just an h2 thing or my statements r wrong for it

dusty frost
#

classic

zinc pebble
#

How do you reset the values in the ecloud?

#

Or where-ever its stored.

dense drift
#

What

slate cargo
#

Anyone would be interested Hooking 2 plugins togeter ? id not mind paying or whatever..

wet pier
#

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;
    }
sterile hinge
#

probably try a LinkedHashMap instead

worn jasper
#

isn't this cause you have a String key? no idea

#

lol

pulsar ferry
night ice
#

Was he asking about the key-value being unordered or the key being string… I am confused in the question 😄

worn jasper
worn jasper
#

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

wet pier
#

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;
    }
sterile hinge
#

the equalsIgnoreCase doesn't make sense this way

wet pier
sterile hinge
#

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

wet pier
worn jasper
#

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

wet pier
worn jasper
#

I already told you the answer....

#

want me to give the code or what

#

lol

wet pier
worn jasper
#

no idea how else I would explain it, maybe someone else can

wet pier
#

so i need to check it startwith

worn jasper
#

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

wet pier
#

wait, param is position_10 ?

dusky harness
brittle thunder
#

yooo dkim

#

tier 8

#

damn

dusky harness
#

helloo
yep :D

brittle thunder
#

How you doing?

dusky harness
#

good :))
not working on a lot of mc stuff though

brittle thunder
#

ahh yea, same. What platform you working on now?

dusky harness
#

jetpack compose ftw

wet pier
worn jasper
#

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

brittle thunder
brittle thunder
proud pebble
wet pier
odd rock
#

is placeholder has look slike math.min, max?

river solstice
#

huh

odd rock
#

%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.

proud pebble
#

from here

odd rock
#

thanks!

craggy zealot
#
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);
    }```
sterile hinge
sterile hinge
merry knoll
#

he is lazy loading the datetimeformatter

sterile hinge
#

That’s the smaller issue here lol

dense drift
#

Lol

minor summit
sterile hinge
minor summit
#

I forgive you

sterile hinge
#

thanks

bitter basin
#

dom sub shit right there

minor summit
unique hawk
#

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

minor summit
unique hawk
#

I couldnt see those haha, thanks

hoary scarab
#

Emily's ready to throw hands lol

odd rock
#

can i use IF on placeholder?

digital temple
#

Does anyone knows about the new papermc nbt exploit ?

mellow pond
#

my plugin patches it

digital temple
#

What kind of exploit is this ?

mellow pond
mellow pond
digital temple
mellow pond
digital temple
#

I thought it was something about nbt data

sterile hinge
#

why do you need to know how it works?

digital temple
sterile hinge
#

staying up to date is how you can prevent it

digital temple
#

Yeah with the paper jar 😂

hoary scarab
#

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.

mellow pond
hoary scarab
mellow pond
#

many many servers arent on 1.20.4 yet

mellow pond
worn jasper
#

in general, an exploit should only be shared one major version after I would say

#

so when 1.21 comes out.

mellow pond
#

ngl, a "big" free public client does have a opensource crash using it

worn jasper
#

if people stay in 1.20 then that is surely their fault

mellow pond
#

sure, still dont want to be the one who got them crashed on

worn jasper
#

but 1.20.3 to 1.20.4 is not that realistic

mellow pond
#

especially since i make plugins that patch it on older versions

worn jasper
#

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.

sterile hinge
stuck canopy
#

Are there any libraries to handle Schematics?

sterile hinge
#

WorldEdit

dense galleon
#

Is there a simple way to convert a project from using maven to using gradle?

hoary scarab
dense galleon
#

I'm on IntelliJ, I'll see what I can find

dusky harness
#

although it's not the best

dense galleon
#

What is the common consensus on the maven vs gradle debate?

#

I find maven easier to use/understand

worn jasper
#

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)

dense galleon
#

I mean is there more 'objective' reasons

#

like maven being too slow or something

dusky harness
#

although it was written years ago

#

so idk if things have changed or not

tender fossil
#

Hi! Is anyone having the same issue that couldn't play sound asynchronously after 1.20.4?

dusky harness
tender fossil
#

I know, but why it just can't after 1.20.4, it works fine before.

dusky harness
#

wait isn't 1.20.4 latest?

tender fossil
#

yes

#

yeah so it's on 1.20.4

dusky harness
#

ohh ok

#

idk that's odd, if it works before 1.20.4

#

🤔

tender fossil
#

yes, so i'm wondering.

dusty frost
river solstice
#

💀

worn jasper
worn jasper
#

(although who uses spigot api nowadays)

proud pebble
glass terrace
#

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!

dense galleon
#

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?

glass terrace
#

u need > in the password

#

i guess

#

it caught my eye

#

password: <password>

dense galleon
#

No

glass terrace
#

u forgot >

dense galleon
#

I mean

glass terrace
#

why no

#

oh ok

dense galleon
#

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

sterile hinge
#

how are you trying to load it?

dense galleon
#

It's just my config.yml

sterile hinge
#

is there any more information in the exception?

dense galleon
neat pierBOT
dense galleon
#

I tried that already

sterile hinge
#

is your password properly escaped?

dense galleon
#

What do you mean with that?

dusky harness
#

is your password in ""?

#

i think quotes also escape special chars but im not sure

dense galleon
#

No, is it meant to be

sterile hinge
#

there might be special characters in it that have some meaning in yaml

dense galleon
#

@

#

I mean can I wrap text in "" in yaml anyway? Just for clarity sake

dusky harness
#

remove the characters until theres no more error ig

dense galleon
#

I mean, the password to my database has that symbol though 🥲

dusky harness
#

I don't think @ is a special symbol in yaml

broken elbow
#

You can escape characters in YAML if they're special

dense galleon
#

It's always pointing at my auto_save_interval part

#

I tried wrapping the password in "" and the issue persists

dusky harness
#

or putting password: ""

broken elbow
sterile hinge
#

you can also use '' instead

broken elbow
#

I would suggest you use an online yaml parser with the entirety of its contents

#

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

broken elbow
#

Also, always remember, TABs are not supported in YAML

dense galleon
#

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

broken elbow
#

I know, I know... but have you tried turning it off and on again?

dense galleon
#

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

broken elbow
#

Many things, none that I am aware of :))

dense galleon
#

Is triumph cmd a continuation of matt's framework?

broken elbow
#

yes

#

a rewrite*

dense galleon
#

is there a guide on tab completions for Triumph, like there was for matts framework?

dusky harness
#

ah

#

hmm if the current docs are outdated, then he also has a discord server

broken elbow
dusky harness
#

oooh right

#

i forgot that existed

pulsar ferry
#

Even that one is outdated omega_lul

dense galleon
#

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?

torpid raft
#

maybe WorldInitEvent or WorldLoadEvent? (i think these may fire multiple times so you should account for that if thats what you end up using)

dense galleon
#

ServerLoadEvent?

#

Though is it guaranteed to fire when the server has finished loading

#

(And not when some plugins may still be disabled)

torpid raft
#

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

dense galleon
#

It looks like it gets called after the plugins are loaded

#

So it might work

dense galleon
#

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:

  1. Add a default key-value pair to the map for the data type to be stored
  2. Modify the queries used by the load() and save() 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

merry knoll
#

and refer to the main row id's

dense galleon
#

Why not?

#

I thought that this way of doing it would be the most efficient with the least amount of code repetition

turbid jewel
#

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?

merry knoll
dense galleon
merry knoll
#

as for code repetition, what you want is a basic orm

dense galleon
#

The reason for this was to keep all of the saving/loading in one plugin

torpid raft
dense galleon
#

And also the PlayerData class would store all the data for all plugins as well

dense galleon
#

Instead of writing sql queries etc.

merry knoll
#

modular works way better imho, all you are doing with the fat core is spagettifying when you dont need to

merry knoll
#

you wont write queries, you just make the data classes and let the orm take care of the rest

dense galleon
#

I have no clue what orm is

#

I'm reading on it but I don't really know what to do with it

torpid raft
#

lets you avoid writing SQL queries

#

for basic stuff

merry knoll
#

ORM = object relational mapping

dense galleon
#

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

merry knoll
#

so your data class turns into a sql table automatically, you lose fine control over the sql queries for less repetition

#

what i would do in your case would be to have a sql module

#

that provides connections (just use hikari honestly)

#

and depend on that with your other plugins