#development

1 messages ยท Page 58 of 1

sterile hinge
#

For large enums, heavily depends whether you have sparse sets or not

dusky harness
#

does it still use hashmap in the end? or completely different implementation

sterile hinge
#

Different impl

#

EnumSets are basically bit vectors

light pendant
#

a "JumboEnumSet" uses a long[] array internally

#

no clue what a regular enum set uses

#

yeah anyway I'm not an md_5 simp, just to clarify that, lol

#

yeah anyway I got an actual dev question related to gson, one sec I'll find the github link

dusk crypt
#

Hello, I need some help with Permission. I have a command called /ghost . And I want to hide that from player if they don't ahve a permission. But I want to freely access it via console. How can I do that?

commands:
  ghost:
    description: test
    permission: ghost.command.help

With this, I was able to hide the command to player but this command isn't working in console as it says that I don't have permission.

light pendant
#

unless you delcared that permission to be "default: false"

#

by default, permissions have "default: op" and console is OP

dusk crypt
light pendant
#

np

dusky harness
# light pendant I'm using this shitty hack to avoid integers (and longs) being parsed as doubles...

Assuming the map is being used in the spigot ConfigurationSerializable with spigot's own classes, I don't think there is a better way (in your own custom classes you could cast to Number and go from there ig
I don't think gson would have an option to store it as an int because that goes against the json specs
You could also store it as a String though, and maybe put a unique identifier so that you don't get "false positives" with real strings such as like "this is a real integer: 123" ๐Ÿฅฒ (This would be the most reliable method, because if there's a double 10.0, that would break because it's a whole number)

light pendant
#

yeah it's meant to be used for ANY given ConfigurationSerializable

#

e.g. CraftItemMeta uses "instanceof Integer" when parsing the map so I need stuff to be an int

dusky harness
#

tbh I would do the string method - you don't have to add a prefix thing since that might look weird to the user, but if you do, that would be 100% reliable

#

and even if you don't, idk how often users name their item like "123"

#

ยฏ_(ใƒ„)_/ยฏ

#

since I feel like doubles would be a whole number pretty often

light pendant
#

I cannot add arbitrary strings to anything as I rely solely on gson's output - I simply throw the output of ConfigurationSerializable#serialize() (which is a Map<String,Object>) into gson's toJson(...) method

dusky harness
light pendant
#

I know that I could use a custom ToNumberStrategy for a certain gson instance, but my serializer class only implements JsonSerializer and that one doesn't have access to the gson instance

light pendant
dusky harness
#

like for ex ```json
{
"cool-int": "int: 123",
"cool-double": 123.45,
"cool-whole-number-double": 123.0
}

#

also hopefully theres no floats, shorts (are enchantments still in shorts?), and longs.......

#

if there are, you can just continue with float: 123.45, etc

#

orrrrrrrrrr
make a json parser ๐Ÿ‘

dense drift
#

dkin, the man with the ideas

dusky harness
#

I am dkin ๐Ÿ˜Œ

light pendant
dusky harness
#

I made one relatively quickly with half the performance of gson

light pendant
#

I need to provide a TypeAdapter or what's it called to be used with gson

#

and unfortunately Gson's JsonDeserializer method does not allow me to specify a custom ToNumberStrategy

#

it only gives me a JsonElement

#

by current code is also working fine, but I still think it's nasty

dusky harness
#

Oh wait this is a library

#

How come you're not just making your own gson instance?

#

(also add .idea to your gitignore)

light pendant
dusky harness
#

ig you could add a Gson parameter then

#

unless it goes on the builder

#

then ig you could add a GsonBuilder parameter then ๐Ÿฅฒ

light pendant
#

that sounds like a horrible solution lol

#

this woul dhave saved me so much trouble

dusky harness
# light pendant that sounds like a horrible solution lol

why?
Assuming ToNumberStrategy works (i have no idea what that is), it wouldn't affect the user (configuration is the same) and it wouldn't really affect the developer (it is reliable - 10.0 or any whole number won't break everything)

light pendant
#

a ToNumberStrategy takes in a JsonElement and returns a Number. IMHO it should return double for 10.0 and integer for 10 and long for 91571515781571515615

#

but the default used ToNumberStrategy always returns a double

dusky harness
#

so if you used ToNumberStrategy

#

it would work like how you'd want

#

wait

#

no

light pendant
#

this leads to issues

MyItemStack:
  # ...
  enchants:
    UNBREAKING: 1

this would return a Map<String,Double> for enchants. Unfortunately CraftItemMeta does an instanceof Integer in the buildEnchants() method, so it will not apply the enchantments if the value of the enchant is not an integer

dusky harness
#

JsonElement still converts everything to double

#

because that's how it's parsed

light pendant
#

I cannot add a custom ToNumberStrategy because I only get passed a JsonElement

dusky harness
#

yes

#

so there really isn't a good solution to this

#

especially since it's a library, and not a private plugin

light pendant
#

yeah probably my current solution is the best that exists

dusky harness
#

OR

#

OR

dusky harness
light pendant
#

or I just get drunk and call it a day?

dusky harness
#

you can make a CUSTOM map implementation

#

when you do get

light pendant
#

now I suspect that you are already drunk lol

dusky harness
#

wait

#

nevermind

#

my idea wouldn't work at all ๐Ÿ’€

#

WAIT

#

NO

#

wait

light pendant
#

anyway I can't decide which Map gets used as json returns the map in fromJson(..., MAP_DATA_TYPE)

dusky harness
#

yeah its an Object value nevermind

dusky harness
light pendant
#

no offense lol

#

anyway you remind me, I must update my dkim txt records

light pendant
#

does anybody know if it's possible to use "variables" in javadocs, i.e. so that I don't have to write the same docs twice and be able to say "pls reuse the same javadocs as from the following method: ..."?

#

e.g. I got a public static final field of an instance of class XY, and I want the field to have the same javadocs as the XY class itself

#

is that possible without custom doclets ๐Ÿฅฒ

dense drift
#

proabably not, but you can have a @see Class

light pendant
#

yeah unfortunately that's not what I want

#

I want it to copy the exact same content instead

molten wagon
light pendant
#

the setTitle method was merged in may and works fine from what I remember

#

it was merged within a few days IIRC, just by accident I saw it in the spigot changelogs like an hour ago lol

#

the InventoryMoveItemEvent is indeed messed up

#

I fully agree with that

#

somehow neither the original nor the new inventory contain that item at the time when that event is called

#

but what's wrong with the setTitle method? Works fine from what I know

#

although the javadocs are shit, idk why y2k didn't mention which exception it throws

dense drift
molten wagon
light pendant
#

I mean paper is still paper
true lol. I also haven't checked how it's implemented, all I know is that it seems to work fine

molten wagon
light pendant
#

mojang's motto, I guess

#

I'm still angry that they obfuscate their .jar - what's the point if the distribute the mappings file >.<

molten wagon
light pendant
#

what are they doing?

#

Yeah anyway I have a very weird maven issue, maybe someone can help me with that.

I have one .jar that's using whatever-SNAPSHOT as version name. maven then appends a "build number" and "timestamp" to the actual name, and somehow maven always says the build number is 2 instead of 1 whe nI deploy this to my repo. I have already opened an issue on reposilite about that but it seems like the problem is actually my own project, but I cannot figure out why this happens, it's strange. Here's the reposilite issue I opened https://github.com/dzikoysk/reposilite/issues/1905

molten wagon
# molten wagon Yeah how they implement the barrel in the code compere to other containers for e...

This seams to be the way to get the barrel from this fieldDataWatcherObject<NBTTagCompound> bR. So you get it from nbt tag and that can also contain other data? what is wrong with mojang staff, why not add it in containers class?

     protected boolean a(EntityHuman entityhuman) {
                if (entityhuman.bR instanceof ContainerChest) {
                    IInventory iinventory = ((ContainerChest)entityhuman.bR).l();
                    return iinventory == TileEntityBarrel.this;
                } else {
                    return false;
                }
            }
light pendant
#

which class is that from?

#

BarrelBlockEntity?

molten wagon
light pendant
#

ah yeah then it's BarrelBlockEntity in moj maps

#

ah that seems to be RandomizableCOntainerBlockEntity#stillValid(Player)

molten wagon
light pendant
#

lol that makes little sense

#

composters don't even have any inventory or am I stupid

#

what the hell is a NonNullList ๐Ÿ’€

molten wagon
light pendant
#

huuh why does it even store the composted materials

molten wagon
light pendant
#

I wrote a whole plugin about composters

#

from what I know, you can add items to composters and depending on the item, there's a certain chance that the level is raised

#

but I don't remember that a composter actually stores "what items" it got

#

sometimes I think that macgyver works at mojang, otherwise it's hard to explain why their code looks like they wrote it using a chewing gum and a paperclip

molten wagon
light pendant
#

wtf?!

#

it can produce something that's not bone meal?

#

when was this added lol

#

from what I know, it always yields exactly 1 bone meal once the level reaches 7

molten wagon
light pendant
#

might also be 8, i don'

#

t remember

#

I'm pretty sure it's 7 though because it goes from 0 to 7 so 8 possible states

molten wagon
light pendant
#

why do I get Invalid session even though I started the game 30 seconds ago ๐Ÿฅฒ

molten wagon
light pendant
#

I just checked the composter - 7 is full and after a second or so, it automatically goes from 7 to 8

#

where 8 is the harvestable state that also shows the "bone meal" texture

#

so yeah it's full when it's either 7 or 8

molten wagon
#

yeah ๐Ÿ™‚ I pull this from the wiki "comparator outputs a signal strength between 0 and 8"

#

So your observation match this statment from the wiki "7 is for completely full but the bone meal is not ready to collect, and 8 for completely full and the bone meal is ready to collect"

light pendant
#

damn I should play some survival

#

what the hell is a torchflower lol

molten wagon
light pendant
#

but it's fancy ๐Ÿฅฒ

molten wagon
tight junco
#

can i ask

#

is it 10.5/hour or 105/hour

spiral prairie
#

probably 105

serene saddle
#

i'm new to making plugins, ive got a kit system working but realized no modded items are persisting

this is my current implementation (this is day 1 of development so don't judge)

private void handleCreateLoadout(Player player, String[] args) {
        
        if (args.length < 3) {
            player.sendMessage("Specify a name for the loadout.");
            return;
        }

        String name = args[2];
        if (plugin.getLoadouts().containsKey(name.toLowerCase())) {
            player.sendMessage("A loadout with that name already exists.");
            return;
        }

        // Create the loadout from the player's inventory and add to plugin's map
        List<ItemStack> itemsList = Arrays.stream(player.getInventory().getContents()).filter(Objects::nonNull).collect(Collectors.toList());
        Loadout loadout = new Loadout(name, itemsList);
        
        // Add the new loadout to the plugin's loadouts map
        plugin.getLoadouts().put(name.toLowerCase(), loadout);
        player.sendMessage("Loadout " + name + " created successfully!");
    }

private void handleSelectLoadout(Player player, String[] args) {
        if (args.length < 3) {
            player.sendMessage("Specify the name of the loadout to select.");
            return;
        }
    
        String name = args[2].toLowerCase();
        Loadout loadout = plugin.getLoadouts().get(name);
        
        if (loadout == null) {
            player.sendMessage("No loadout with that name exists.");
            return;
        }
    
        player.getInventory().clear();
        for (ItemStack item : loadout.getItems()) {
            player.getInventory().addItem(item);
        }
        player.sendMessage("Loadout " + name + " equipped!");
    }```

vanilla items work fine when I retrieve them, but modded are empty slots
using mohist for spigot/forge integration

is this even possible or not with forge items? do I need to do a different method of handling the inventory items?
river solstice
#

brr

serene saddle
#

looks like i'll be looking into spongeforge instead... thanks for that notice lol

light pendant
#

mohist bad

#

also mohist users are weird and tend to leave 1 star reviews for your plugins because they think it's the dev's fault if sth doesn't work on this weird fork

#

I remember that I once looped over Material.values() and mohist threw a NPE or sth (while doing Iterator#next()) for non-bukkit materials or sth

royal hedge
river solstice
royal hedge
#

yea so howd the non existant iterator throw an exception and how was it an npe

river solstice
#

Real

fading stag
#

What would be the best way to store a placer of a Shulker? iirc there is no way to do it with PDC right?

dense drift
#

How can an enum constant be null?

#

Shulkers are tile entities, It doesnt have PDC?

#

@uneven lantern ping

fading stag
#

I mean shulker box

#

The block similar to chest

dense drift
#

Yes, the Box

fading stag
dense drift
#

Yes

fading stag
#

Thanks

dense drift
#

At the top you can see it implements PersistentDataHolder

fading stag
#

Yes saw that thanks

river solstice
#

but yeah, .values() shouldn't can't contain nulls

dense drift
#

Not what I meant smh M0dii

river solstice
#

yes

pulsar ferry
#

"mohist" that's your answer, god knows how many hacky things they do
I have seen the wackiest problems with it

#

Enum values having null on it doesn't surprise me

hazy nimbus
#

Hey

#

I was just thinking

#

How does mohist handle materials different than those defined in the Material enum?

#

Like, for example the BlockPlaceEvent, what's the Material if the player placed a non-vanilla block?

icy shadow
#

theres been lots of attempts to do things like this and afaik theyre usually shit

#

but i guess they patch the material class, not sure

fading stag
#

I have a plugin which is developed for both 1.8 and 1.16 (customer wanted it) I'm using Material.getMaterial("NETHERITE_SWORD") with null check for checking does the version have NETHERITE_SWORD or not and then I tried Material.values().toList().filter { it.name.contains("SWORD") } (it is a kotlin code but it gets values() as list and filters them) then I got a list of [LEGACY_IRON_SWORD, LEGACY_WOOD_SWORD, LEGACY_STONE_SWORD, LEGACY_DIAMOND_SWORD, LEGACY_GOLD_SWORD], what causes this? How can I make it give me a proper list with NETHERITE_SWORD on 1.16?

dense drift
#

set api-version: 1.13 in plugin.yml

#

and perhaps add another condition in there, !it.name.startsWith("LEGACY_")

fading stag
dense drift
#

no afaik

#

if all plugins have api-version defined, spigot won't do its legacy bullshit

spiral prairie
#

I mean that kills 1.8 compatibility doesn't it?

dense drift
#

no

#

api-version exists since 1.13

spiral prairie
#

A

dense drift
#

but yeah, if you set it to like 1.16, it won't run on 1.13-1.15

light pendant
minor summit
#

mfw Collections.emptyIterator exists BocchiBruh

#

oh i see what that is doing ๐Ÿ’€ that is hideous

#

instead of calculating if there is a value available in hasNext it does it inside next

#

dear god

light pendant
#

yeah catserver is a bad joke

#

but the name is cool

#

catserver lol

#

uwu

dusky harness
#

What if someone made a forge and fabric thing ๐Ÿค”

icy shadow
#

they would explode

#

unfortunately

light pendant
#

i'm still confused why catserver is rethrowing that exception instead of just skipping the non-bukkit materials

#

makes little sense to me lol

minor summit
#

i think they used to have a cute mascot too, but i can't seem to find it anywhere

light pendant
#

not a mineraft question but does anyone have a comprehensive guide to use sourcemod? I haven't used it in 10+ years and now wanted to get back at it - somehow I can only find specific tutorials on their website but nothing about "how to get the project started" in the first place

molten wagon
sterile hinge
#

you can use a debugger to see where it goes wrong

molten wagon
# sterile hinge you can use a debugger to see where it goes wrong

I did already debug it, no values is null. Don't know if the effect SPELL could be the issue.

System.out.println("this.world " + this.world);
System.out.println("location " + location);
System.out.println("this.effect " + this.effect);
System.out.println("this.data " + this.data);
sterile hinge
#

use a proper debugger and step into the internal bukkit code

molten wagon
sterile hinge
#

the IntelliJ debugger

molten wagon
river solstice
#

it wont if you dont know how to use it

molten wagon
urban rock
#

Are there any fake inventory packages people use? I could dump files into DeluxeMenus but seems a bit "hacky" to do that

proud pebble
#

tho from what i can tell its not using the right method which is strange

#

tho thats probs the data is using a type other then int

#

since there are two methods, one that uses int for data and one that use T (Generic Type)

#

tho id suggest casting it to int

molten wagon
proud pebble
#
    @Override
    public <T> void playEffect(Location loc, Effect effect, T data, int radius) {
        if (data != null) {
            Validate.isTrue(data.getClass().isAssignableFrom(effect.getData()), "Wrong kind of data for this effect!");
        } else {
            Validate.isTrue(effect.getData() == null, "Wrong kind of data for this effect!");
        }
        if (data != null && data.getClass().equals(MaterialData.class)) {
            MaterialData materialData = (MaterialData)data;
            Validate.isTrue(materialData.getItemType().isBlock(), "Material must be block");
            this.spigot().playEffect(loc, effect, materialData.getItemType().getId(), materialData.getData(), 0.0f, 0.0f, 0.0f, 1.0f, 1, radius);
        } else {
            int dataValue = data == null ? 0 : CraftEffect.getDataValue(effect, data);
            this.playEffect(loc, effect, dataValue, radius);
        }
    }

    @Override
    public void playEffect(Location location, Effect effect, int data, int radius) {
        this.spigot().playEffect(location, effect, data, 0, 0.0f, 0.0f, 0.0f, 1.0f, 1, radius);
    }
#

this makes sense why you are getting a npe

#

since you are using something other then int, the first method is called, and when it attempts to do data.getClass() it would npe since double isnt an object its a primitive type

#

if you had used Double it wouldve probably worked

#

or should i say wouldve spit out the wrong kind of data error seen there

molten wagon
proud pebble
molten wagon
proud pebble
#

currently diving through packets, im trying to figure out when Use Item (Serverbound 0x32) is called, because its not firing when im expecting it to according to its description on wiki.vg

#

its supposed to fire when you right click with an item in hand, im doing that and its firing as Use Item On (Serverbound 0x31) or atleast it is according to protocollib

#

this is on 1.19.4 with protocollib 5.1.0

#

actually might be when you attempt to eat idk

dusty frost
minor summit
#

Use Item is consumable items like food, potions, milk, etc

#

Use Item On is like placing blocks, or, well, anything that won't trigger a Use Item really

proud pebble
#

turns out im a bit dense and forgot to add BLOCK_PLACE to the list of packets to listen for kekw

#

in protocollib the packets have their name switched around, USE_ITEM does the use item on packet, and BLOCK_PLACE does use item packets, so basically use item == blockplace and blockplace == use item

#

so helpful craftbukkit, so helpful

minor summit
#

using protocollib is pretty meh tbh unless you for whatever reason must support multiple versions out of the box

#

even then not all plib packet types are really transferable between versions, as some packets are replaced or deleted, good luck figuring those out

proud pebble
#

im using it only to listen to packets incoming or outgoing cus i wanna get something to work untill i get around to going the normal route of netty stuff

minor summit
#

it's pretty painless on paper

dusky harness
#

oh?

#

since when did paper add packet api

#

or networking

minor summit
#

not api

dusky harness
#

oh

minor summit
#

it's internals but you can easily register a listener that will get called on channel initialize

dusky harness
#

wdym? (link?)

minor summit
#
ChannelInitializeListenerHolder.addListener(Key.key("cool-plugin:whatever"), channel -> {
  // ... add ChannelHandler etc
});
dusky harness
#

what is ChannelHandler?

#

oh its netty

minor summit
#

yes

dusky harness
#

but protocollib lets u convert it to mc stuff

#

whereas i assume netty just gives you the bytes?

minor summit
#

depends on where you put the channel handler

#

if you put it at the very beginning, yes

#

if you put it before the Connection handler, no, it's deserialized to the Packet pojo by the packet_decoder or w/e

proud pebble
#

oh its like a fresh new feature

#

still stuck on 1.19.4 for the time being, ill look into it later

dusky harness
#

because if so, combined with paperweight, would be pretty nice

minor summit
minor summit
dusky harness
#

wait then how would you access it in the API

#

like if you don't have paperweight

#

wouldn't it show as like an error?

minor summit
#

it is not API ....

dusky harness
#

oh its a server patch

minor summit
#

yes

dusky harness
#

oops

#

๐Ÿค”
mixing two annotation frameworks

tired olive
#

Cf on top

gray tide
#

Hi, Someone know how can I get the Armor Toughness attribute from an ItemMeta and then adding 1 to it ?

#

I've done that to test but I got an error

if(command.getName().equalsIgnoreCase("test")){
            Player player = (Player)sender;
            ItemStack item = player.getItemInHand();
            ItemMeta meta = item.getItemMeta();
            meta.getAttributeModifiers(Attribute.GENERIC_ARMOR_TOUGHNESS).add(new AttributeModifier("test-toughness", 10, AttributeModifier.Operation.ADD_NUMBER));
            item.setItemMeta(meta);
        }
#
Caused by: java.lang.NullPointerException: Cannot invoke "java.util.Collection.add(Object)" because the return value of "org.bukkit.inventory.meta.ItemMeta.getAttributeModifiers(org.bukkit.attribute.Attribute)" is null
        at fr.skylined.evolution.Main.onCommand(Main.java:82) ~[?:?]
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[spigot-api-1.20.1-R0.1-SNAPSHOT.jar:?]
        ... 23 more
dense drift
#

get description

Return an immutable copy of all AttributeModifiers for a given Attribute

gray tide
#

ohh I see ok

#

ty

gray tide
# dense drift Use this <https://hub.spigotmc.org/javadocs/spigot/org/bukkit/inventory/meta/Ite...

I have done this, it work but there is a little problem...

AttributeModifier modifier = new AttributeModifier(UUID.randomUUID(), Attribute.GENERIC_ARMOR.name(), 1, AttributeModifier.Operation.ADD_NUMBER, EquipmentSlot.CHEST);
            meta.addAttributeModifier(Attribute.GENERIC_ARMOR, modifier);

But if I repeat my command to test multiple times it shows up like this on the item :

When on Body:
+1 Armor
+1 Armor
+1 Armor
...

do you know how can I make it so it shows up like this :

When on Body:
+3 Armor
dense drift
#

yeah probably because you add 3 different modifiers

gray tide
#

Then I can do that maybe ?

meta.getAttributeModifiers(Attribute.GENERIC_ARMOR).add(new attribute here)
```?
dense drift
#

no

#

Check if there is any modifier for that attribute, if not add a new one, otherwise increase the value of the existing one

proud pebble
inland walrus
#

Hello! I have a problem with placeholders of the PlaceholderAPI plugin in my plugin. I found a solution on GitHub, but I don't understand how to modify my code by adding the code from GitHub.

proud pebble
inland walrus
spiral prairie
#

Read the wiki?

inland walrus
#

yes

inland walrus
# spiral prairie Read the wiki?
package at.helpch.placeholderapi;

import me.clip.placeholderapi.PlaceholderAPI;

import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.plugin.java.JavaPlugin;
import me.clip.placeholderapi.PlaceholderAPI;

public class JoinExample extends JavaPlugin implements Listener {

    @Override
    public void onEnable() {
 
        if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
            /*
             * We register the EventListener here, when PlaceholderAPI is installed.
             * Since all events are in the main class (this class), we simply use "this"
             */
            Bukkit.getPluginManager().registerEvents(this, this);
        } else {
            /*
             * We inform about the fact that PlaceholderAPI isn't installed and then
             * disable this plugin to prevent issues.
             */
            getLogger().warn("Could not find PlaceholderAPI! This plugin is required.");
            Bukkit.getPluginManager().disablePlugin(this);
        }
    }

    @EventHandler(priority = EventPriority.HIGHEST)
    public void onJoin(PlayerJoinEvent event) {
        String joinText = "%player_name% &ajoined the server! They are rank &f%vault_rank%";

        /*
         * We parse the placeholders using "setPlaceholders"
         * This would turn %vault_rank% into the name of the Group, that the
         * joining player has.
         */
        joinText = PlaceholderAPI.setPlaceholders(event.getPlayer(), joinText);

        event.setJoinMessage(joinText);
    }
}
spiral prairie
#

yees?

#

wheres your issue?

inland walrus
#

I have an unusual message output system

gray tide
#

Hi I have created a custom recipe in the anvil using the PrepareAnvilEvent (be cause my recipe need to handle nbt and attribute) but when I click on my result item I can get it. I use event.setResult(ItemStack) in my code

#

I mean in game it shows up in the GUI but I can't get it

proud pebble
inland walrus
#

in messages: onMessages and offMessages

proud pebble
inland walrus
#

hm

proud pebble
#

like ig for example on line 127 you can do getServer().dispatchCommand(getServer().getConsoleSender(), PlaceholderAPI.setPlaceholders(player,group.getCommands()));

#

since if you have the player expansion you dont have to replace the %player_name% placeholder yourself anymore

inland walrus
#

String messages = enabledGroups.getString(groupName + ".off_messages");

#

I don't understand...

river solstice
#

I think you need to learn some more

#

Before blindly trying to put pieces together

inland walrus
#

PlaceholderAPI.setPlaceholders(player,message)

#

oh

#

Ee

#

String messages = enabledGroups.getString(groupName + ".getMessages");

proud pebble
#

like i dont really get what your plugin is even trying to do

inland walrus
#

staff work mode

proud pebble
#

thats not really that descriptive

inland walrus
#

/sw on - give player moderator role

#

/sw off - take player moderator role

proud pebble
#

so your trying to make a weird permissions plugin?

inland walrus
#

yes)

proud pebble
#

why not just use luckperms? its like one of the standard permissions plugins

inland walrus
#

everything works for me except the placeholder

proud pebble
#

why reinvent the wheel?

inland walrus
#

in what sense

proud pebble
#

there is very little sense it trying to make another permissions plugin

#

tho it doesnt even look like your doing that

inland walrus
#

this is not a permissions plugin, it is a plugin for granting permissions to players through certain commands, granting privileges to players to work on the server

proud pebble
#

are you doing this convoluted way instead of doing it through a permission plugin?

#

ohhh its a wrapper

inland walrus
#

helper:
off_commands: "lp user %player_name% parent add helper"
off_messages: "&6StaffWork &8ยป %vault_rankprefix%&7%player_name% &aะฝะฐั‡ะฐะป ั€ะฐะฑะพั‚ัƒ."
group_permission: "blackdigo.sw.offhelper"
permission_priority: 1

#

offhelper:
on_commands: "lp user %player_name% parent remove helper"
on_messages: "&6StaffWork &8ยป %vault_rankprefix%&7%player_name% &cะทะฐะบะพะฝั‡ะธะป ั€ะฐะฑะพั‚ัƒ."
group_permission: "blackdigo.sw.helper"
permission_priority: 1

proud pebble
# inland walrus helper: off_commands: "lp user %player_name% parent add helper" off_mess...

it would make more sense to compact them into just one entry cus its unlikely that you would have access to give them permissions but not to take them away

prefix_message: "&6StaffWork &8ยป"
enabled_groups:
  helper:
    on_messages:
      - "%prefix% %vault_prefix%&7%player_name% &cะทะฐะบะพะฝั‡ะธะป ั€ะฐะฑะพั‚ัƒ."
    on_commands:
      - "lp user %player_name% parent add helper"
    off_messages:
      - "%prefix% %vault_prefix%&7%player_name% &aะฝะฐั‡ะฐะป ั€ะฐะฑะพั‚ัƒ."
    off_commands:
      - "lp user %player_name% parent remove helper"
    group_permission: "blackdigo.sw.helper"
    permission_priority: 1
#

also you should probably use StringList rather then String

spiral prairie
#

var newMessage = PlaceholderAPI.setPlaceholders(player, originalMessage)

#

Done

proud pebble
#

also its %vault_prefix%, not %vault_rankprefix%

atomic trail
#

I always forget, if I make a plugin that should work from 1.8.8-1.17 I should make the jar in 1.8.8 right?

leaden sinew
#

Yes

atomic trail
#

Where can I see the list of dependency versions?

#

I think it's this but can't find it compileOnly("io.papermc.paper:paper-api:1.17.1-R0.1-SNAPSHOT")

dense drift
#

It depends what you do. For example, if you have a GUI and want to allow users to use shields with custom banners, you would need to use spigot-api 1.9+

atomic trail
#

Or wait 1.8.9 it might be not sure

dense drift
#

As long you add a check that works in 1.8, it will be alright

#

E.g. material.name().equals("SHIELD")

atomic trail
#

How about methods that have a different name in the API in 1.17 than 1.8, what will then happen?

#

It would still work right?

dense drift
#

There isn't any, spigot maintained backwards compatibility

atomic trail
#

Paper didnt though? Or did they?

dense drift
#

They did.

atomic trail
#

So what happens if I use text components etc?

dense drift
#

Adventure works on 1.8 just fine, but you need to shade it alongside with bukkit platform

#

Spigot compatibility while using paper-api is a different thing. And even if you want to support paper only, you can't depend on its version of adventure, because it is available only on 1.16.5+

hazy nimbus
#

I just said fuck you and only support paper with java 17

#

And I've never been happier

#

Had to code in java 8 today and holy moly

dense drift
#

Yeah I miss var and Records xD

hoary scarab
atomic trail
#

The issue is that it has to work with WineSpigot 1.8.9 and Purpur 1.17.1 though lol

#

And Purpur 1.19 actually

hoary scarab
#

Yeah all you have to do is add api: 1.13 to the plugin.yml

atomic trail
#

1.13?

hoary scarab
#

Yeap.

atomic trail
#

Why exactly that version?

hoary scarab
#

You'd have to ask spigot

#

I think someone wrote an explanation here.

atomic trail
#

Alright, and also that jar version in the jar ig? Or just 1.19?

pulsar ferry
#

The api-version thingy was added in 1.13 so that's the lowest you'd go if you want to support the most amount of versions

atomic trail
#

Ahhh gotcha, thanks! :))

atomic trail
dusky harness
#

if it's not included, then spigot assumes <1.12 (pre-material change)

hoary scarab
#

Depends which methods you want to use.

dusky harness
#

but if you include it, it assumes 1.13

#

he wants to make it 1.8

#

so you shouldn't include it at all

hoary scarab
dusky harness
#

yes it will

#

it shows a "legacy plugin" (since it's for 1.12 and below, it adds legacy compatibility) warning

hoary scarab
#

Really when did that change?

dusky harness
#

it should've always been like that
maybe the warning made it confusing (and some other issue made the plugin not load, resulting in thinking that the warning was the reason?)

#

since it's not just a normal INFO message

#

or maybe its somewhere in 1.13 to like 1.15 since i didn't code from that long ago

hoary scarab
#

It's been awhile now so maybe I'm wrong... but when 1.13 released plugins were disabled if they didn't contain the api version.

dusky harness
#

when 1.13 released
oh then maybe since I didn't even play minecraft when 1.13 released ๐Ÿฅฒ

hoary scarab
#

Well anyone here can test it lol. I'm not on PC right now.

atomic trail
#

Which dependency should be used? Latest version I'll be using or?

hoary scarab
atomic trail
#

Not really I think, but I might lol

hoary scarab
#

If not really, then just use 1.8.8

#

Might need 1.9 for multi hand methods.

dusky harness
#

any code that exists in 1.9 api for ex will end up erroring if you run it on 1.8

atomic trail
#

Alright, thanks :))

dusky harness
hoary scarab
#

As long as you check the version before using the method you won't have issues.

atomic trail
#

Alright, thanks

spiral prairie
#

For whatever reason you want to support a version older than some Minecraft players lol

icy shadow
#

spigot guarantees forward compatibility but not backwards compatibility

icy shadow
dusky harness
#

have I been calling forwards compatibility "backwards compatibility" this whole time

#

๐Ÿฅฒ

icy shadow
#

well it depends on your perspective

#

but i think saying backwards compatibility is misleading people into thinking new plugins work on older versions

#

Backward compatibility is a design that is compatible with previous versions of itself. Forward compatibility is a design that is compatible with future versions of itself

#

so it is a matter of perspective really

west socket
#

It should be in relation to whatever the API version is, no?

icy shadow
#

"it"?

west socket
#

Like if the plugin is running API version 1.8, and it works on the latest version, its forward compatibility

icy shadow
#

yes

dusky harness
#

i feel like 95% of people say backwards compatibility though

icy shadow
#

and they would be wrong

leaden sinew
#

Java is backwards compatible, not Spigot

dusky harness
icy shadow
#

i mean

leaden sinew
#

Just like Skript

dusky harness
#

a java 16 program isn't compatible with previous versions

west socket
#

Skript ๐Ÿ˜

#

My favorite "programming language"

icy shadow
#

again it depends on your perspective but yeah id say theyre the same

dusky harness
#

unless you mean the side from the java -jar

icy shadow
#

older programs can run on newer jvms

#

not vice versa

#

so... it's either the programs being forward compatible, or the jvm being backwards compatible

west socket
#

I mean I'd assume it would work as long as all the classes/methods still exist in the latest version of spigot

icy shadow
#

yes, and spigot basically never removes stuff for this reason

#

almost every deprecated method still works

west socket
#

I'd assume its almost always NMS that breaks plugins on version updates

icy shadow
#

well

#

pre 1.13 yeah, by definition

#

1.13? maybe 1.16

#

whenvever the package changed

leaden sinew
dusky harness
#

if a 1.8 plugin doesn't use any internals then theres a very high chance (afaik) that it would still work on latest

#

๐Ÿ˜Œ

west socket
#

I should look at how multi-versioned anticheats do it

leaden sinew
#

Maybe it would be able to run but it would probably have issues

inland walrus
#

Hello! How to disable PvP mode for a specific player so that they cannot deal damage?

#

player.

warm steppe
#

Check entity damage event

light pendant
atomic trail
#

Is spigot 1.8.8 actually completely outdated and not possible to use anymore?

spiral prairie
#

1.8.9

atomic trail
spiral prairie
#

Dunno

dusky harness
#

if you google "spigot gradle" or that error it should come up

#

(i think theres 2 repos you need - the snapshots repo and the bungee)

atomic trail
#

Oh yeah I need sonatype as well

#

Thanks

dense drift
#

I would've said yes and hope he will use 1.17 api instead D:

atomic trail
#

I made this code to create a "trench" enchant, but the issue is that it keeps getting called again and again as player.breakBlock triggers the event again ofc. any way I can avoid this while other plugin still being able to access the event to check for regions etc on the other blocks?

https://paste.helpch.at/uqigibodib.java

proud pebble
#

its like uhh, Block#breakNaturally(ItemStack)

#

instead of getting the player to do it

#

and ofcourse do your checks for each block before calling that method

dusky harness
#

if the uuid is in the map, ignore the event

atomic trail
#

Yup, that's what I'm doing rn

#

Kinda

proud pebble
#

but theres no reason to do that when Block#breakNaturally exists

#

means you are only doing a player break once and the rest dont trigger the event

dusky harness
#

interesting way of writing a boolean variable...

#

oh

#

uh

#

now that I think about it, you don't even need to store the location or the uuid

#

since it all runs sync, no?

#

orrrrrrrrrrrrr you can do Block#breakNaturally

#

as Lunaiskey suggested

proud pebble
#

only problem with Block#breakNaturally(ItemStack) is that you cant modify the items dropped, which means you will have to go through the craftbukkit classes, figure out exactly what they do and then copy that ofcourse with the blocks dropped missing and just calculate the block drops yourself manually or something

atomic trail
#

Well no, I can't. breakNaturally doesn't run the BlockBreakEvent which I need for other plugins to handle worldguard regions, drops etc.

#

I could manually call the event, but there would be no reason to do that when player.breakBlock exists.

dense drift
#

It is better to handle the breaking on your own afaik, because breakBlock doesnt apply enchantments and stuff as you would expect

dusky harness
#

even tho it inputs an ItemStack instead of like a Material

proud pebble
light pendant
dense drift
#

Hmm, then it might be the case for a method on Block, is been a while ๐Ÿคฃ I think Block#breakNaturally(ItemStack) or Block#getDrops(Entity, ItemStack)

normal obsidian
#

can anyone join a vc and help me with my plugins

dense drift
light pendant
worn jasper
#

Hey there, if I set the amount of an itemstack to something like 300 and remove it from the inventory, will it remove 300 items of that itemstack or does it not work like that?

minor summit
#

depends on which remove method you're using

pulsar ferry
worn jasper
#

bruh

small arrow
#

Current issue: /dupe off
How it's supposed to work: Operators run /dupe off - plugin takes the item in the operators hand - adds it to a set which is saved into the config.yml file - running /dupe off again will take it out of the set (all of that works fine)
When a player now trys to run /dupe to duplicate the item, if the item is in the set, the player can't dupe the item.
The Issue: The player is STILL able to run /dupe on the item which the operator ran /dupe off on. What is causing the issue?

leaden sinew
#

Also you can change

if (undupableItems.contains(itemType)) {
    undupableItems.remove(itemType);
```to 
```java
if (undupableItems.remove(itemType))
small arrow
leaden sinew
#

Do you want it to require the same amount?

small arrow
#

The quantity shouldnโ€™t matter it should only take the material into account

#

Thatโ€™s why I changed it to material before it was itemstack

leaden sinew
#

Oh

#

You're checking if the set contains an ItemStack, not a Material

#

getItemInMainhand returns an ItemStack

#

You're IDE should warn you about that

small arrow
#

Right and then I have a .getType()

leaden sinew
lyric gyro
#

yo if anyone wants to have a multitool message me

minor summit
#

i have all the tools

small arrow
#

if you want me to change my Set<> to an ItemStack, I'll just have the same issue I had before where it's quantity specific

leaden sinew
small arrow
#
               ItemStack itemInHand = player.getInventory().getItemInMainHand();

                if (!itemInHand.getType().isAir()) {
                    Material itemType = itemInHand.getType();
                    if (undupableItems.contains(itemType)) {
                        undupableItems.remove(itemType);
                        saveUndupableItemsConfig(); // Save the updated set
                        player.sendMessage("Item is now dupable.");
                        player.playSound(player.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1f, 1f);
                    } else {
                        undupableItems.add(itemType);
                        saveUndupableItemsConfig(); // Save the updated set
                        player.sendMessage("Item is now undupable.");
                        player.playSound(player.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1f, 1f);
                    }
                    saveUndupableItemsConfig();
                    return true;
                }
            } else {
                sender.sendMessage(ChatColor.RED + "You don't have permission to use this command.");
                player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_LAND, 1f, 1f);
                return true;
            }
leaden sinew
#

Yes, but you have undupableItems.contains(itemInHand)

leaden sinew
# small arrow ```java ItemStack itemInHand = player.getInventory().getItemInMai...
        ItemStack itemInHand = player.getInventory().getItemInMainHand();

        if (itemInHand.getType().isAir()) {
            player.sendMessage("You need to hold an item to use this command.");
            player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_LAND, 1f, 1f);
            return true;
        }

        if (undupableItems.contains(itemInHand)) {
            player.sendMessage("This item cannot be duplicated.");
            player.playSound(player.getLocation(), Sound.BLOCK_ANVIL_LAND, 1f, 1f);
            return true;
        }
small arrow
leaden sinew
#

I'm not telling you to change it to an ItemStack

#

I'm telling you you're checking if the set contains an ItemStack instead of a Material

leaden sinew
#

if (undupableItems.contains(itemInHand))

small arrow
#

ah I see

#

ty

leaden sinew
#

You're welcome

small arrow
#

I am so sorry ๐Ÿ˜…

leaden sinew
#

Lol it's okay

small arrow
#

Issue Resolved ๐Ÿ‘ tysm for the help!

leaden sinew
#

No problem

idle crown
#

Hi,
do les anyone know if there is a better way to do this https://pastebin.com/WaF6NuVz ?
I just want to check wether the player has to turn left or right to look at the target

small arrow
#

Any good tutorials online for how I can make placeholders for my plugin through PAPI?

dusky harness
#

assuming you mean inside an external plugin's internal class

#

which is what I'd recommend for making PAPI placeholders for your plugin

#

placeholder format: %identifier_params%

small arrow
dusky harness
#

or can you give a more specific example?

#

since by that example you can have like a %events_time_remaining% placeholder

dusky harness
#

identifier and params can be found on the link

#

(it should also automatically scroll you to the relevant part of the page)

small arrow
light pendant
#

I got an issue with gradle not being able to find my script from inside buildSrc - can I somehow send a screenshot here? Or am I allowed to link to some screenshot website?

#

it complains about my bukkit module's build.gradle:

Build file 'C:\Users\mfnal\IdeaProjects\lightpermsx\bukkit\build.gradle' line: 2

Plugin [id: 'lightpermsx.java-conventions'] was not found in any of the following sources:

Here's the whole github repo: https://github.com/mfnalex/lightpermsx

light pendant
# light pendant it complains about my bukkit module's build.gradle: ``` Build file 'C:\Users\mfn...

I got it working myself. Additionally to declaring the actual script in buildSrc/src/main/groovy/lightpermsx.java-conventions I also had to declare a build.gradle in buildSrc/ with the following content:

plugins {
    id 'groovy-gradle-plugin'
}

I could then apply my "lightpermsx.java-conventions" script file using plugins { id 'lightpermsx.java-conventions' } in my subproject. However gradle was also angry that i declared the lombok plugin like this in my buildSrc/src/main/groovy/lightpermsx.java-conventions.gradle file:

plugins {
    id "io.freefair.lombok" version "8.2.2"
}

I had to replace this with just id "io.freefair.lombok" (so without the version). Obviously it then complained about this plugin not being specified anywhere, which I fixed by creating a build.gradle file in the root project that consists of nothing but this:

plugins {
    id "io.freefair.lombok" version "8.2.2" apply false
}
fringe spruce
#

Is it possible to side load worlds in from a different directory?

Like, I wanna have โ€œplayer-worlds/<uuid>/โ€œ where the uuid is the name of the world

I donโ€™t really want it to clog the main directory, thatโ€™s why

light pendant
light pendant
minor summit
#

pretty sure you can do new WorldCreator("a/b/c")... and that'll be the dir structure as well PepeLaugh

light pendant
#

oh you're right, that does indeed work

#

i would have thought it'd complain about "illegal char" in the world name or sth

minor summit
light pendant
#

basically, I wanna be able to do gradle export-to-test-server instead of gradle build . it should do exactly the same as build, except that it changes the output directory of one module's shadowJar to another folder

#

I have tried adding this to the one module's build.gradle but when I ran gradle export-to-test-server it still created the .jar at the default location (myModule/build/libs)

tasks.register("export-to-test-server") {
    jar {
        destinationDirectory = file(...)
    }
}
minor summit
#

uh idk groovy dsl but in kotlin dsl is something like this

tasks {
  register<Copy>("exportToTestServer") {
    dependsOn(shadowJar)
    from(shadowJar.flatMap { it.archiveFile })
    into("/...")
  }
}

also unrelated but if you name your tasks camelCase you can run them by their initials like so ./gradlew eTTS ๐Ÿ‘€

light pendant
#

oh right, I didnt worry much about the name, wanted to get it working at first lol. So you're suggesting to just copy it, yeah actually why not.

I already declared build to dependOn shadowJar, so I guess I can make my task depend on build instead of shadowJar, right? Let me quickly try to translate this to groovy, then I'll see if it works. thanks

minor summit
#

i believe on groovy you'd just do from shadowJar.archiveFile instead of the flatmap

light pendant
#

yeah it complained about the flatMap, so I tried this:

tasks.register("exportToTestServer", Copy) {
    dependsOn build
    from shadowJar.archiveFile
    into '/c/mctest/plugins/'
}

that runs without errors and I also see that it ran the task, but nothing happened (except that it built everything normally)

#

oh wow, I'm stupid. I'm running it from IntelliJ and not git bash, so I needed to use C:\ path names. using /c/path/ it just silently failed lol Thanks!

bitter basin
#

hello, having an issue with this

block.blockData = Bukkit.createBlockData(unstrippedBlockMaterial) {
    it as Orientable
    it.axis = (block.blockData as Orientable).axis
}

Works as intended, unless im in creative?? anyone care to advise?

#

weirdly enough, if I print the block.type right after, its correctly set??

#

but the update never actually happens

bitter basin
#

this is being executed in PlayerInteractEvent btw

dusky harness
bitter basin
#

thats the entire event

#

everything gets executed from start to finish as expected

#

works fine in survival

#

but in creative seems to not wanna do anything

dusky harness
#

wait what is in UNSTRIP_MATERIALS

bitter basin
#

UNSTRIP_MATERIALS is just a list of items than can unstrip the logs, for now just all the axe items

#

kind of badly named actually

#

and ye its being called

#

like i said, it works fine in survival mode but when i go creative, the block type doesn't update but the sound is played and the item in hand is swung and print statements show it working from start to finish

#

version is 1.20.1, should also mention that

dusky harness
#

hmmm odd
try

  • removing UNSTRIP_MATERIALS check and just trying with a regular hand (nothing in the hand)
  • cancelling the event afterwards
#

ยฏ_(ใƒ„)_/ยฏ

#

kinda random ideas but worth it if you still have the issue

bitter basin
#

@dusky harness the cancelling event at end works, likely because my code works fine and updates the block but during the same tick, the log is stripped again after all the events are processed

#

so it gives the affect that it isn't unstripped but infact does the unstrip and strip in the same tick

#

:/

dusky harness
#

also note that you can also do if (material !in UNSTRIP_MATERIALS) {}

dusky harness
#

ยฏ_(ใƒ„)_/ยฏ

bitter basin
bitter basin
dusky harness
#

kotlin ftw

bitter basin
#

fr

#

thats some clean ass event handling

dusky harness
#

lol does pastebin require you to put in a category or smth?

#

just noticed that randomly

#

the Gaming

bitter basin
#

i was playing around with it, first time using pastebin

dusky harness
#

ah

#

i haven't used pastebin in ages

spiral prairie
#

hehe

#

:P

dusky harness
#

you should host pastes.dev instead ๐Ÿ‘ ๐Ÿ‘ (haven't checked but i assume you're using hastebin)

spiral prairie
#

im not

dusky harness
#

oh?

pulsar ferry
#

pastes.dev my beloved

dusky harness
#

99% of people host pastes.dev hastebin

spiral prairie
#

yep

#

because its good

dusky harness
#

oops

#

i meant

bitter basin
#

been coding for years but this is the 2nd time ive used a paste thing before

dusky harness
#

hastebin

spiral prairie
#

ah yes

#

because its shit

dusky harness
#

i agree

spiral prairie
#

pastes.dev hogs my shortcuts tho

#

so that sucks

dusky harness
#

wdym?

spiral prairie
dusky harness
#

is this the logo

#

๐Ÿฅฒ

spiral prairie
#

seems like it ahhahaa

dusky harness
#

you should scan this

spiral prairie
#

very cool

dusky harness
#

thank you

limber lagoon
#

Hey

#

oh dkim what's up

pulsar ferry
#

Oh shit, you're alive

dusky harness
minor summit
#

good song!

sharp cove
#

Hey simple question

#
private static final List<String> CMDS = "minecraft", "testje", "blasalala";```
How do I do this correctly?
spiral prairie
#

List.of("minecraft", "testje", "blasalala")

sharp cove
#

Then I'll have to do this

#

Is this smart to do?

spiral prairie
#

Depends on what version you want to be developing for

sharp cove
#

Java version 17

spiral prairie
#

then you can change it to language level 17

sharp cove
#

It is already like that

spiral prairie
#

no it isnt. its 8

sharp cove
#

huh

#

oh wait

sharp cove
spiral prairie
#

set it on the jdk too

sharp cove
#

thank u

spiral prairie
#

np

atomic trail
#

I've got this in my .gitignore

.idea/compiler.xml
.idea/jarRepositories.xml
.idea/modules.xml
.idea/misc.xml
.idea/*.iml
.idea/modules

Then I unstage the changes, but then when I use git add . it adds them back, even though they should be ignored, anyone got an idea why?

dense drift
#

Were they committed already? Also, simply adding .idea/ to .gitignore is enough btw

atomic trail
#

Didnt work

dense drift
#

you need to remove them first, I think it is, uh, git rm --cache -r .idea or smth like that

atomic trail
#

Ohhhh yeah forgot about that

#

Thanks

dense drift
#

Np

icy shadow
#

--cached

#

i think

atomic trail
#

Yeah, does the same it seems

icy shadow
#

ah

worn jasper
#

Hey guys, kinda need assistance here, I have been changing and trying to get this to work for the past hours but it seems like I am either stupid, blind or this actually doesn't work.

I have a compact coin (64 normal coins) and a normal coin, I am making a remove method so that it removes X amount of coins, it works like intended besides in one specific case, when I don't have normal coins, only compact coins, it's supposed to convert the respective amount of compact coins needed to normal coins, to then remove the normal coins that it needs.

Code: https://paste.helpch.at/tusitejeti.java

#

If someone is able to see something or just an idea on what could be going wrong.

#

(for context, it doesn't convert nor remove anything)

warm steppe
#

compare lines 30 and 51

torpid raft
#

doesn't matter if the end result is functions that seem too simple to justify being their own thing, the point is to better organize and not be tricked by nested if's that might otherwise hide stuff from you in plain sight

#

since 90+% of the time the issue for me in cases like this is with something happening when it shouldnt or vice versa, eg. control flow

worn jasper
#

yeah ty

spiral prairie
# worn jasper yeah ty

If you're too lazy you can actually ask ChatGPT, and since it doesn't write code by itself, it usually works

worn jasper
glacial stump
#

Hi, I have a question, I'm making a java program that needs to create a schematic file, but I can't write a single schematic and I don't understand how to create one, so I don't know if anyone here knows how to do it?

pure crater
#

You could probably use a java NBT api and create one with those fields

sterile hinge
#

Note this is a legacy format that doesnโ€™t properly support 1.13+. You should probably look into the Sponge schematic format

heavy wadi
#

How do you name your event listeners?

I have been doing EventNameFeatureName but this results in incredibly long and confusing file names.

AnvilInventoryClickEventDisableTooExpensive.java

river solstice
#

well, since I usually group them in a feature class and usually name them according to what Im trying to achieve with the method, you already have the event name as a parameter, so you already know that part and no need to include it in the method name imo

spiral prairie
#

I just do BlaListener for example

#

Don't call your listeners events, as they aren't events

#

And they don't need to be too long, it's nice having a quick overview of the name of a class and what it could be doing, but people can always look into the class

proud pebble
#

i probs should rename them from Events to Listeners

#

tho i just use a single event listener method for each type and then will transfer to another method somewhere else if it fits a certain criteria

spiral prairie
#

That's fine too imo, just don't call them events

charred ravine
#

I have an issue, I have a for loop that gets nearby entities by 12 blocks from the damager, checks if they are instanceof player then checks if those entities health is below 12D
I then add those players to a list, when I check the size it only returns 1, anyone got any idea why its not returning the amount of players it should have in the list?

light pendant
#

I'm trying out kotlin in my build scripts. What's the difference between these two? Only the former one seems to work

plugins {
    `kotlin-dsl`
}
plugins {
    id("kotlin-dsl")
}
dense drift
#

it needs to be escaped with ` because it contains an illegal character (dash).
id() should also work I think, hmm

dusky harness
light pendant
dusky harness
light pendant
#

the gradle docs say that using subprojects {} or allprojects{} should be avoided so that's why I moved my stuff into buildSrc lol

minor summit
#

it's probably some id("org.jetbrains:idk:idk:whatever:kotlin-dsl")

spiral prairie
#

yeah

minor summit
light pendant
minor summit
#

it's only for some core plugins, obviously it isn't going to know about every single plugin in the plugin repo lol

light pendant
#

that's funny because in groovy I was able to just do id('groovy-gradle-plugin')

#

and I assumed the kotlin-dsl would be a core plugin ๐Ÿ˜„

minor summit
#

mm well it kind of is but, yeah

light pendant
#

I find groovy to be so much easier ๐Ÿฅฒ

river solstice
#

k๐Ÿคกtlin

minor summit
#

๐Ÿค”

#

"meh"

light pendant
#

i still don't really get the technical difference between pluginname and id("f.q.d.n.pluginname") version("version") - apparently using id requires to give the fully qualified name including the version for all non-core plugins while `pluginname` does not require fully qualified name neither version, even for not-core plugins - interesting 3rdeyethink

dusky harness
#

or more specifically, a property

light pendant
#

yeah I just checked and it seems to be a "field" or however it's called in kotlin

#

interesting

dusky harness
#

the get() is why getters and setters don't have to be explicitely defined by default ๐Ÿคฉ

#

(in kotlin)

pulsar ferry
#

It's just a type safe shortcut so you don't have to type ids all the time

light pendant
#

btw is it normal that when I create a new project in IJ -> Gradle -> Kotlin/Kotlin -> JDK 17, that it uses jvmToolchain(8) even though I specifically set it to 17?

#

shouldn't that be set to 17 ๐Ÿ˜„

spiral prairie
#

dunno

#

the kotlin sdk is also called sdk 8 or sum

minor summit
#

i never use the intellij project wizard lol

#

i always run gradle init

spiral prairie
#

but thats ass to set up for kotlin

minor summit
#

?

spiral prairie
#

you have do add the kotlin thingy

#

i dont wanna do that xD

minor summit
#

it asks you what language you want the project to be in

dusky harness
#

I made my own project generator ๐Ÿ˜Œ

#

its a nice project idea

#

if you need a project idea

spiral prairie
minor summit
#

yes?

#

lol

spiral prairie
#

never saw that tbh

minor summit
light pendant
minor summit
#

it did thonk

#

right before the build script dsl

light pendant
#

oh I didnt see it because it didn't show the 1: 2: as separate lines

#

for me it looks different

#
Split functionality across multiple subprojects?:
  1: no - only one application project
  2: yes - application and library projects
Enter selection (default: no - only one application project) [1..2] 2
minor summit
#

huh what gradle version?

light pendant
#

7.5.1

minor summit
#

mm yeah i guess they changed it for gradle 8

light pendant
#

fair enough, it's a yes/no question

#

no need to split that up into 1 and 2 lol

#

I'm still surprised that gradle init doesn't specify any jdk version in the generated project

minor summit
#

it does for application/library

#

idk for gradle plugin

light pendant
#

oh! now I also understand why the kotlin-dsl plugin requires `this-notation` - it's because the "field" has a hyphen in the name, that's why "java" works without backticks but kotlin-dsl doesn't

light pendant
minor summit
#

and it doesn't really do anything for a basic project, it's a very basic layout

#

well it definitely was defined when i ran it

light pendant
#

in which file exactly?

#

just curious

minor summit
#

well it was without subprojects, just ./app/build.gradle.kts

light pendant
#

hm mine only has this

plugins {
    id("kttestgradleinit.kotlin-application-conventions")
}

dependencies {
    implementation("org.apache.commons:commons-text")
    implementation(project(":utilities"))
}

application {
    // Define the main class for the application.
    mainClass.set("kttestgradleinit.app.AppKt")
}
#

yeah well anyway ๐Ÿ˜„ I learnt a lot again today, thanks

#

things slowly start to make sense to me

minor summit
light pendant
#

I'm currently writing a tiny PAPI extension to properly replace %formatter_text_replace% with a properly working replacer lol.

I currently got the following format which works 100% fine:

%replacer_"<search>"_"<replacement>"_text in which to search and replace%

As you see, both <search> and <replacement> must be put into quotes, so that the search and replace string can both contain underscores just fine. It also works with "quotes" being included in the search and replacement string by simply escaping them like usual:

%replace_"\"jeff\""_"\"alex\""_my name is "jeff"%

I'm using this relatively easy regex:

    private static final Pattern PATTERN_BOTH_QUOTED =
            Pattern.compile("^\"(?<search>([^\"]|\\\\\")+)\"_\"(?<replace>([^\"]|\\\\\")+)\"_(?<text>.*)$");

Outside of java it looks like this: ^"(?<search>([^"]|\\")+)"_"(?<replace>([^"]|\\")+)"_(?<text>.*)$

Now I'm thinking of making the " quotes optional if search or replace doesn't contain any underscores, however I'm unsure how I'd do that using just one regex - ofc I could just use 4 different patterns (current one for both search and replace quoted, one for only search quoted, one for only replacement quoted, and none quoted) but that seems a bit unperformant I guess. Anyone got any idea? Maybe I could add another named group (?<searchWithoutQuotes>(...)) and same for replace, and then combine them with the existing quoted named groups using (|) ?

#

Ha! I got the discord formatting working

prisma briar
#

I have a library called MDLib that shade CommandAPI, and I have a plugin that shading the MDLib library, for some reason the CommandAPI got doubled and it cause some issues, as you can see on the image it has dev.jorel.commandapi package and I have com.muhammaddaffa.rpgclass.mdlib.commandapi package, that shouldn't happen right?

Can someone help me solve this issue?
This is my pom.xml for RPGClass https://paste.helpch.at/qotivogapi.xml

light pendant
#

there's different options

  1. commandapi should only be a transitive dependency in MDLib
    or
  2. MDLib should relocate commandAPI into its own package
prisma briar
light pendant
#

hm that looks correct. Run mvn clean install on your mdlib, and then mvn clean package on your RPG thing

prisma briar
#

Maybe I need to invalidate cache or something.

light pendant
#

Something is messed up. I also dont see the configupdater package in your plugin

#

I think the issue is that you set createDependencyReduced to false in MDLib

#

That way maven doesnโ€™t know MDLib got it shaded already

prisma briar
#

Oh yeah, I didn't noticed it.

#

Alright, I'm gonna try to set it to true.

light pendant
#

Dont forget to โ€žmvn cleanโ€œ on both projects again

prisma briar
#

I think that's it.

light pendant
#

Iโ€˜m pretty sure thats it :p this is exactly tjhe purpose of the reduced pom

#

In short, this is quite useful if you intend to use that shaded JAR (instead of the normal JAR) as a dependency for another module. That dependency-reduced-pom.xml will not contain the JARs already present in the shaded one, avoiding useless duplication.

#

I never understood why people always disable the dependency-reduced-pom ยฏ_(ใƒ„)_/ยฏ

prisma briar
#

I use the Minecraft IntelliJ Plugin to create project and that's the default.

#

But thank you for the help!

light pendant
#

Disabling it has no advantage, only downsides

light pendant
prisma briar
heavy wadi
#

I am implementing a player tracking feature. It's 1:1 so every player is at most tracking exactly one player at any given time.
So I need to look up players in a map every couple ticks.
Should I use Map<Player, Player> for this purpose or is it more efficient to use e.g. Map<UUID, UUID>?

torpid raft
#

use UUIDs

icy shadow
#

uuids always*

torpid raft
#

i think saying always is harsh but yeah if you're ever even slightly unsure then just use uuids

icy shadow
#

thats why you put a vague asterisk and then refuse to elaborate

torpid raft
#

๐Ÿ˜ฑ

dense drift
#

Is there a situation where you would use Player as a key?

icy shadow
#

i cant really think of one where it's better

torpid raft
#

maybe for the sake of performance

icy shadow
#

i dont think theres any noticeable difference

torpid raft
#

but only at the point where're you're concerned about converting players to uuids or vice versa

#

so probably never

heavy wadi
#

First few tutorials I clicked on all put the entire player in the map ๐Ÿ˜„
That would mean that I need to do player.getUniqueId() and Bukkit.getPlayer(uuid) whenever I look up a player pair in the map tho.
But that's still faster than using a <Player, Player> map?

icy shadow
icy shadow
#

also spigot tutorials are almost always awful

heavy wadi
#

Safer in what way? Less prone to errors or are we actually talking about security?

dense drift
#

I wonder, do Player objects become null when the players leave? Or does anything happen at all

icy shadow
#

memory leaks

torpid raft
#

UUIDs are forever ๐Ÿซก

icy shadow
#

this isnt c++

dense drift
#

Ah true

heavy wadi
#

But you could always just clear it yourself during PlayerLeave or later, no?

icy shadow
#

you could, but you might forget. it's more maintenance

#

using Player as a key also relies on equals/hashCode behaviour that is effectively undefined. in practice it'll probably be fine, but you never know.
It's like how trying to serialise a Location with gson stack overflows because it contains a reference to World, whose implementation contains a reference to more locations

#

so UUID also makes serialisation easier

#

no need for a custom type adapter

royal hedge
icy shadow
#

hell yeah

#

yeah no, you should still be manually cleaning up when it makes sense. but leaking player objects might lead to some weird states where you have 2 distinct player objects representing the same player

#

i dont actually know

royal hedge
#

even if it is i dont see the issue

icy shadow
#

why wouldnt it be possible?

torpid raft
#

spigot is too robust and battle tested to be subject to silly bugs

#

it's basically the perfect software

#

linus torvalds could learn a thing or two

icy shadow
#

ha

#

players get removed from the internal cache when they disconnect. as far as i can tell theres nothing preventing a new ServerPlayer getting created, which in turn creates a new CraftPlayer

royal hedge
#

so theres an internal cache?

#

meaning they get reused?

#

or?

#

im not talking about when they leave btw

torpid raft
#

i have to imagine that the same Player object is returned after multiple calls to getPlayerById(id)

#

so yeah they are reused in that sense

icy shadow
#

yes

#

PlayerList

#

something.nms.something.PlayerList to be precise

#

so. let's say you keep a hard reference to a Player after they dc. internally it makes a new CraftPlayer so suddenly you have 2 CraftPlayers

#

it might not be an issue but i reckon it'll subtly break something

royal hedge
torpid raft
#

in theory nothing should go wrong as long as the player doesnt leave

#

bm saying that you should still clean up is just a more general advice

#

i think

icy shadow
#

Yes

atomic trail
#

Can someone help me rewrite this to work in kotlin? Lol

processResources {
    def props = [version: version]
    inputs.properties props
    filteringCharset 'UTF-8'
    filesMatching('plugin.yml') {
        expand props
    }
}
#

It was generated by the minecraft plugin in IDEA

spiral prairie
#

I recommend using the minecrell plugin to just generate the plugin.yml

atomic trail
#

Havn't heard of that before, is in a plugin in IntelliJ?

spiral prairie
#

nope, gradle plugin

atomic trail
#

Wow it needs a lot of configuration lol

spiral prairie
#

no, not really

atomic trail
#

What's all this?

#

Configuration of paper but yeah

spiral prairie
#

thats everything you can do

#

id("net.minecrell.plugin-yml.bukkit") version "0.6.0"

bukkit (or paper) {
    main = "com.example.testplugin.TestPlugin"
    apiVersion = "1.13"
    author = "Skyslycer"
}
#

thats all you need

atomic trail
#

or in paper instead of bukkit right?

#

Ah ye

spiral prairie
#

ye

atomic trail
#

Was about to write it lol

light pendant
atomic trail
#

Thank you, can I ask why you recommend using this instead of plain old plugin.yml?

spiral prairie
spiral prairie
atomic trail
icy shadow
#

could also just apply a json schema to plugin.yml

spiral prairie
#

umm akshualle ^

spiral prairie
#

just my opinion tho

#

(also i want yml to die)

icy shadow
#

thats fair

light pendant
pulsar ferry
#

HOCON ftw

spiral prairie
#

^

#

toml was the hype but i didnt feel it as much tbh

light pendant
#

you should rather use the field imho

#

tasks.processResources { ... }

spiral prairie
#

or processResource {}

#

depends on where you declare it

light pendant
#

you mean ```kt
tasks {
processResources {
...

spiral prairie
#

yep

atomic trail
#

Yeah I just have it in tasks usually

spiral prairie
#

as hes already in the tasks thingy

#

^ same

light pendant
#

oh yeah then ofc you can use it like that

#

it's basically the same lol

spiral prairie
#

yep

atomic trail
#

? So I cant use the plugin or?

#

From Minecrell btw

spiral prairie
#

i believe thats for paper

#

if you use paper plugins (instead of bukkit) it has to be 1.19 or higher since paper plugins didnt exist back then

#

for paper plugins you need this too:

    bootstrapper = "com.example.testplugin.bootstrap.TestPluginBootstrap"
    loader = "com.example.testplugin.loader.TestPluginLoader"
    hasOpenClassloader = false```
atomic trail
#

Oh, so this wouldn't work?

#

I'd have to change to bukkit

spiral prairie
#

yes

#

bukkit is your regular plugin.yml

#

paper is paper-plugin.yml

#

also api version 1.12 doesnt exist

#

you have to use 1.13

atomic trail
#

Shouldn't this still work?

icy shadow
spiral prairie
icy shadow
#

thats the preferable option for legacy plugins

#

i mean...

#

if theyre writing a 1.12 plugin

#

you dont have a choice

spiral prairie
#

you can still put 1.13

icy shadow
#

i dont think thats true

#

i dont think it'll do the material conversions if you put 1.13

light pendant
#

if you actually use 1.12 api you shouldn't set any api-version because you'll wanna have the legacy material support enabled

icy shadow
#

^

spiral prairie
#

hm alriight

atomic trail
spiral prairie
#

you forgot the close bracket

light pendant
#

(unless you don't use any materials, e.g. a chat plugin could use 1.13 api version to avoid the huge material enum conversion thingy)

dense drift
atomic trail
sonic nebula
spiral prairie
atomic trail
#

Yes

light pendant
# dense drift eh, isn't like api-version will do anything on pre 1.13

on pre 1.13 it won't do anything. But someone would run the plugin on 1.13+ and then having the api-version set will break your Material references (unless you have NOT specified an API-version, in that case bukkit injects the legacy material names into your classloader's material class)

spiral prairie
#

oh yes i remember

light pendant
#

very dirty black magic

spiral prairie
#

ye

light pendant
#

it'll be fun when all the Keyed enums will be gone

dense drift
#

I don't understand your concern

spiral prairie
#

@atomic trail you probably used the paper plugin

atomic trail
#

This plugin will only be used for a 1.12.2 server btw

dense drift
#

spigot still enables legacy support if a single plugin doesn't have api-version defined

spiral prairie
#

use id("net.minecrell.plugin-yml.bukkit") version "0.6.0"

light pendant
#

not just some other plugin

atomic trail
dense drift
#

why do you want that?

spiral prairie
#

xD

spiral prairie
light pendant
#

so they will expect Material.GRASS to be a grass block and not the "normal grass"

icy shadow
#

Yeah guys this shouldnโ€™t be so confusing lmao

#

Targeting old api = no api version

spiral prairie
#

yes

light pendant
#

and hence they wanna have legacy material support enabled = no api version set

spiral prairie
#

i agree

#

now after my stupidity has been cured

dense drift
#

yeah whatever

light pendant
#

ofc I'd just suggest to stupi using 1.12 API ยฏ_(ใƒ„)_/ยฏ

atomic trail
#

Sooo I set no api version? Lmao

icy shadow
#

yes

#

donโ€™t set it

light pendant
#

if you use 1.12 API, you set no api-version

atomic trail
#

Alright

light pendant
#

I'd like to upload an extension to the papi ecloud but registration is currently locked, and it says to ask on discord to get an account - where exactly shall I ask? here? ๐Ÿ˜„

spiral prairie
#

@robust crow that should sort it

light pendant
#

thx

spiral prairie
#

hell respond once he can :D

atomic trail
#

Shouldn't the .gradle/ directory be in .gitignore?

light pendant
#

yes

#

.gradle/ should be in gitignore but gradle/ shouldnt be

dense drift
#

it doesnt need to be a plugin if you want to publish it to the ecloud

light pendant
#

I know, it's just a plugin right now because I can't upload it to the ecloud without an account

#

and I can't register an account myself because it's closed

atomic trail
light pendant
#

Yes, at least the properties file should be there

#

The .jar doesnt have to but also doesnt hurt

atomic trail
#

Yeye I'll just keep it there

light pendant
#

I always upload the whole gradle dir

dense drift
minor summit
#

(I have made that mistake before)

light pendant
light pendant
#

nice

pulsar ferry
#

They already extend PlaceholderExpansion so it's pretty easy to find the right class without any yml