#help-development

1 messages · Page 1644 of 1

eternal oxide
#

press CTRL+SHIFT+O

ivory sleet
#

I mean I suppose but gradle plugins are kinda pro/con debatable

opal juniper
#

shit i didn’t see that xD

ivory sleet
#

The strongest argument is that gradle is faster and a lot more concise in terms of less boilerplate and verbosity

karmic grove
ivory sleet
#

Maven is fine but like ObiWhy

river spear
#

I want this to be triggered later and want to pass it on

eternal oxide
hasty prawn
quaint mantle
opal juniper
#

although

ivory sleet
#

Hmm yeah it does add a lot of mobility and customizability which can be frustrating for someone who wants it dead simple

hasty prawn
#

Which is what I want pepehands

ivory sleet
#

But given the speed I think it pays up

opal juniper
#

i guess

quaint mantle
#
interface FutureVoid {
    void run();
}

//
void myFunction() {

}

//
otherFunction(this::myFunction);

@river spear

hasty prawn
#

I do enjoy my nap waiting for the Gradle daemon to start

ivory sleet
eternal oxide
#

No clue, I don;t use other IDEs

opal juniper
#

i’m too lazy to learn keybinds

ivory sleet
#

🤨

opal juniper
#

all i need is copy and paste

#

whoops

opal juniper
#

didn’t mean to say that

quaint mantle
#

is it worth it

opal juniper
ivory sleet
eternal oxide
#

Definitely not worth it.

opal juniper
#

xD

quaint mantle
#

lmao

hasty prawn
#

lmao

quaint mantle
#

brutally honest

reef wind
undone axleBOT
ivory sleet
reef wind
#

don't give code to someone that doesn't know how shit works imajin

quaint mantle
#

i told them

#

i sent them the learn links

eternal oxide
#

Grandkids are great, you can hand them back when you've had enough

quaint mantle
#

lol

opal juniper
#

lmao

ivory sleet
reef wind
#

sure you may have fun doing shit with your kids and teaching them shit, but you can't fuck whenever you want and you will eventually get tired of the little demons.

quaint mantle
#

any upside of using bukkit service provider than making your own

opal juniper
#

cause last time i checked you were the child

reef wind
#

it's not

ivory sleet
narrow furnace
#

check the pfp

reef wind
#

just facts

opal juniper
#

lmao

narrow furnace
#

thats not a child

quaint mantle
reef wind
ivory sleet
#

That’s from the ServicesManager

#

But yes

opal juniper
narrow furnace
#

im saying you look great for your age

reef wind
#

you don't know my age

opal juniper
#

80

reef wind
#

are you assming?

ivory sleet
#

It’s in API so it’s a component for all plugins imagine

narrow furnace
reef wind
#

this is harassment

opal juniper
reef wind
narrow furnace
#

boomer music

reef wind
#

anyone can like it

narrow furnace
#

yes anyone can

#

but only boomers do

reef wind
#

I bet you would love it if you tried it

narrow furnace
#

sounds like something a boomer would say

reef wind
narrow furnace
#

sounds like something a boomer just said 🤔

reef wind
narrow furnace
reef wind
#

@daring sierra likes that music and they are a minor

#

I win

opal juniper
#

one other person

#

wow

#

extensive survey

reef wind
opal juniper
narrow furnace
#

@reef wind why is your name prouddesk

reef wind
#

guess 3 times

narrow furnace
#

i only need 1 time

#

exposed

ivory sleet
#

Lol

daring sierra
regal lake
#

Does someone know if it is possible to show the frosty vignette (when a player is within powder snow) with spigot ?
I think it's a client side thing or ?

daring sierra
#

Ans why do you feel the need to ping me everytime you lose an argument

reef wind
reef wind
daring sierra
#

I don't even like jazz that much, it's kinda bad ngl

reef wind
#

but you like the other shit

#

so I win

daring sierra
reef wind
#

no

#

dumbass

daring sierra
#

You've seen my music collection before

reef wind
#

also move to #general

daring sierra
#

No

#

Stop pinging me when you lose an argument

reef wind
#

not if it involves you

daring sierra
#

What involves me?

reef wind
#

smh

daring sierra
#

Hey

#

Stop dragging me into things.

reef wind
#

go to #general

daring sierra
#

I don't like your playlist, I think it's meh

daring sierra
quaint mantle
#

Can agree, his playlist is shit

wild reef
#

Hey guys got a little issue.
I want to change the biome of a whole chunk and I am trying it like this:

World world = chunk.getWorld();
                        for (int x = 0; x < 16; x++) {
                            for (int z = 0; z < 16; z++) {
                                for (int y = 0; y < world.getMaxHeight(); y++) {
                                    int worldX = (chunk.getX() * 16) + x;
                                    int worldZ = (chunk.getZ() * 16) + z;
                                    world.getBlockAt(worldX, y, worldZ).setBiome(biome);
                                }
                            }
                        }

But it doesn't have any effect when I am checking on F3
Can anyone help me?

narrow vessel
#

chunk.getX() * 16 would mean that when youre at 5000,5000 for example you would be getting 80,000, 80,000

wild reef
#

well example for the calculation:

narrow vessel
#

-93 * 16 is -1,488

#

check that block lol

wild reef
#

but it's chunk.getX() that should be -6 in that case

narrow vessel
#

oh right

pastel drift
#

Why not just get the block location from the chunk?

final Block block = chunk.getBlock(x, y, z);
wild reef
#

I tried that before, didn't work for some reason

pastel drift
#

Also I don't think you need to set the biome for every y value.

#

Just at y=0.

narrow vessel
#

no

#

biomes are 3D

pastel drift
#

Right, they changed.

wild reef
#
for (int x = 0; x < 16; x++) {
                            for (int z = 0; z < 16; z++) {
                                for (int y = 0; y < world.getMaxHeight(); y++) {
//                                    int worldX = (chunk.getX() * 16) + x;
//                                    int worldZ = (chunk.getZ() * 16) + z;
                                    chunk.getBlock(x, y, z).setBiome(biome);
                                }
                            }
                        }

I will try it like this, one sec

karmic grove
#

it says this code is unreachable ...

narrow vessel
#

because it probably is

#

you literally gave no context

karmic grove
#
package me.David.HelloWorld;

import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;

public class Main extends JavaPlugin {

    
    public void OnEnable()
    {
        
        
        
    }
    
    
    public void OnDisble()
    {
        
        
        
    }
    
    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if(label.equalsIgnoreCase("hello"))
        {
            if(!(sender instanceof Player))
            {
                sender.sendMessage("You need to be a player to run this command");
                return true;
                
            }
            
            if(!sender.hasPermission("helloworld.use"));
            {
                sender.sendMessage(ChatColor.RED + "You do not have permission to use this command");
                return true;
            }
        
            Player p = (Player) sender;
            p.sendMessage("Hello" + p.getName());
            return true;
            
            
            
            
            
            
            
        }
        
        return false;
    }
    
}


pastel drift
#

if(!sender.hasPermission("helloworld.use"));

#

you have a semicolon there

silver shuttle
#
if(!(sender.hasPermission("helloworld.use"))) {

}
#

should be that

wild reef
# pastel drift Right, they changed.

Doesn't work with the chunk blocks as well. It's very strange. I got a command to check if the blocks are from a certain biome. The commands displays the setted biome but when I check F3 nothing changed

karmic grove
#

oh

karmic grove
#

thanks :)

wild reef
# pastel drift Did you relog in between?

nope I didn't... sooo it takes effect when u relog, but does it also work for the server like this? I mean for example I change the biome to something where special mobs spawn

pastel drift
#

I'm pretty sure it's only client side.

#

Not sure if there's a way to forcefully update it somehow.

wild reef
#

I hope so :D

#

thanks for your help tho

pastel drift
#

Of course.

wild reef
#

Ah found a way to do it without relog

karmic grove
#

!documentation

#

is there a api documentation

lost matrix
#

?jd

regal lake
#

Im not sure if found a bug or what happens here...
I try to get the bedspawn with the getBedSpawnLocation method from a OfflinePlayer.
If the player never had a bed on the server, the method returns null which is correct.
If the player had a bed, the method returns a instance of a location which is also correct.
If the player had a bed and break the bed, the method still returns a instance of a location, which is not correct. The method should return null again.
Any ideas if that is correct and i don't understand that or if that is a bug ?

toxic mesa
#

If I'm using protocollib and a packet has 3 shorts, do I have to use packet#getshorts#readsafely(0), #readsafely(1) and #readsafely(2)?

torn oyster
#
        List<ServerInfo> waitingServers = new ArrayList<>();
        for (ServerInfo info : foundServers) {
            applyStateToConsumer(info.getName(), s -> {
                p.sendMessage(s);
                if (s.equalsIgnoreCase("pre_game")) {
                    p.sendMessage(ChatColor.GREEN + "This server is pre game!");
                    waitingServers.add(info);
                }
            }, p);
        }```
would i be able to immediately iterate through waitingServers, or do i have to do some fancy stuff? atm i don't think i can iterate
regal lake
#

@torn oyster why you dont test it ?
Yes it should work as it is just a list, the problem is that you try to iterate on a empty list. saw you don't try to iterate on waitingServers

torn oyster
#

nothing

#

it doesnt say "This server is pre game!" at all

regal lake
#

So show more code (e.g. what is the variable foundServer and how will it filled with data).

karmic grove
#

theres a BlockBreakEvent but i cant seem to find block place event 🕵️

torn oyster
#
        List<ServerInfo> foundServers = new ArrayList<>(getProxy().getServers().values());
        
        for (ServerInfo info : foundServers) {
            applyTypeToConsumer(info.getName(), s -> {
                if (s.equalsIgnoreCase(minigame)) {
                    p.sendMessage(ChatColor.GREEN + "This server is the minigame, " + minigame);
                } else {
                    foundServers.remove(info);
                }
            }, p);
        }```
#

thats another one

burnt mural
#

Hi everyone. I have a problem with my plugin and I don't understand why it appears. My goal is to make a weather module which manages the weather of a specific world. So there are different types of weather : SUNNY, RAIN and STORM.

However, I have a problem with the RAIN weather. Indeed, when the user wants the rain to be enabled for a specific world, I use the WeatherChangeEvent to detect a weather change and I cancel it in case in which the new weather isn't rain. However, when I use the /weather clear command and the event is cancelled, it is called a lot of times. I don't know of to fix that. Can someone helps me, please ?

Version used : 1.8 (I want my plugin to support 1.8 to 1.17).
Code :

@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onWeatherChange(WeatherChangeEvent event) {

    System.out.println("WeatherChangeEvent");

    event.setCancelled(true);
}

Note : The sysout is displayed like a loop in the console.

tribal holly
#

Hi ! I need to make a "custom ai target" for wither skeleton. I wanna them to target everyone but not some player. The test of "is a pleyr to not target" is working (i debug it) but i got a weird issue : when i summon for the first time the skeletons they don't target the safe player. But when they target an other entity, kill him then they will target back the safe player with any reason. Is there some kind of issue existing with this or just set target very buggy ?

vague oracle
vague oracle
tribal holly
#

this is what i use to manage this

burnt mural
vague oracle
tribal holly
#

after killing the cow the target go on me but actualy in the code i cancel it when they try

burnt mural
torn oyster
#

if i'm doing getServer().sendPluginMessage(), do i need a player online?

#

if so

#

then this sucks

tribal holly
vague oracle
torn oyster
#

there is 1 player on bungee

#

not on the backend tho

tribal holly
torn oyster
vague oracle
#

I never like the bungee plugin message, redis was the biggest update ever

burnt mural
vague oracle
#

Idk what it is, I dont use the event, use whatever you need to get the weather its changing to

#

it was psudo code 🙂

burnt mural
#

Yeah but there is only toWeatherState that returns a boolean. I tried what you said but I have the same result

torn oyster
#

i really need to be able to do it

#

with 0 people online

vague oracle
#

Use MySQL or a messaging service API like redis

#

I made my own messaging service with MySQL when i didn't know about proper ones and it actually worked

torn oyster
#

i've just spent like 10 hours trying to do all this

#

im not spending another 10 trying to change it to some other thing

vague oracle
#

I spent 3 days working on a problem because i got the number 1 and 2 mixed up

#

xD

#

Well, there isn't much you can do apart from learn something else if you need 1 player online

tribal holly
# torn oyster with 0 people online

you can't for my part i was need it to know player number on all server and on the first boot i create a runTaskTimer that check if on player is connected and if yes i send the message ales i wait until player connect

torn oyster
#

a player will never be able to connect

#

without this plugin messaging

tribal holly
#

what do you want to do exactly ?

torn oyster
#

trying to get an int from the backend server

#

well

#

value

#

if that value is what i want

#

it connects the player

torn oyster
#

you don't know what its for

tribal holly
#

be more precise

quaint mantle
#

Pffft, Just use raw Sockets

torn oyster
#

just know this

trying to get an int from the backend server
well
value
if that value is what i want
it connects the player

torn oyster
tribal holly
#

well with this i can't do nothing for u bro

#

what is the backend server ? what is the int for ? why a int ?

torn oyster
#

its a string

#

not int

tribal holly
#

okay replace by string sry

quaint mantle
#

Well, when a Connection is attempted you create a seperate connection and send some Data outside of the Main connection

vague oracle
#

I really recommend you learn something like redis, its so good.

#

It can be used for other purposes as well such as caching data

quaint mantle
#

Redis wont help

#

At all

vague oracle
#

how?

quaint mantle
#

You'd still need to establish a connection

vague oracle
#

?

#

of course

#

His problem is he can't send things to the bungee when there is no one online

quaint mantle
#

Redis wont magically connect the Server and bungee

vague oracle
#

I mean if you set it up they do

#

read some tutorials

quaint mantle
#

So what Java NIO can do that too!

#

Netty also

vague oracle
#

It was a suggestion

quaint mantle
#

Sure, far too overcomplicated, but works (TM)

tacit drift
#

Map<Player, Integer>

#

Increase integer after every run

quaint mantle
#

Overkill solution:
Attach a PDC entry that is increased on every run and nuked on every tick

quaint mantle
tacit drift
#

why

grim ice
#

Is it possible to use a spigot plugin in bungeecord

burnt mural
quaint mantle
#

You will likely forget to remove the Key on disconnect

tacit drift
#

hmm :))

burnt mural
tacit drift
#

👍

haughty plover
quaint mantle
#

UUID, Integer is safer

#

Industry Standard even

ivory sleet
#

a Map<Player,V> is totally fine

#

If you're afraid of forgetting to remove the key on disconnect, a WeakHashMap implementation would do fine

burnt mural
#

In some cases, Player can be used as key. It's not a Industry Standard or whatever you want. If handled correctly, it's perfectly fine. However, I agree that in some cases, UUID are better.

ivory sleet
#

If your only goal is to store some data whilst the player is online, then using UUID is redundant imo.

#

You could take advantage of the fact that there will only be one player instance per player which means we could in principle also use an IdentityHashMap although we would have to remove the entry on disconnect.

quaint mantle
#

I wish we had mixins available so we can assign a field to do it with 0 overhead

ivory sleet
#

😌

quaint mantle
#

Hashmaps have a certain inefficency after all

ivory sleet
#

indeed

#

Tho arguably suffices for most stuff

burnt mural
#

The only bad thing with Player storage is that we need to have a Player all the times and it can add an operation cost to retrieve it.

ivory sleet
#

You mean like the hash computation?

quaint mantle
#

In this case you'd have the Player object available already

burnt mural
#

No, for example, if the uuid of a Player is only manipulated we need to retrieve it has a Player using Bukkit.getPlayer() for example. And we don't know the complexity of this method.

#

It can be n (where n is the number of players of the server)

ivory sleet
#

Oh yeah, tho pretty sure its O(1)

quaint mantle
#

It's anywhere from O(k/n) to O(n)

ivory sleet
#

Bukkit::getPlayer should by default delegate to CraftServer::getPlayer which just queries the player lookup map iirc

quaint mantle
#

Where as k is the capacity of the underlying hashmap

ivory sleet
#

I doubt the underlying lookup map has to rely on buckets or whatever its called

quaint mantle
#

Custom map implementation?

ivory sleet
#

myes maybe

quaint mantle
#

There are few bucket-less map implementations

ivory sleet
#

the craft implementation isn't my field of expertise

quaint mantle
#

And designing one for this is overkill imo

quaint mantle
ivory sleet
#

Tho I trust the capable maintainers of the software that it isn't too unreliable

torn oyster
#

how do i send a plugin message using sockets

#

i dont have a player online

#

and i need to be able to send it

ivory sleet
#

RabbitMQ or Redis pubsub mb?

quaint mantle
#

I have recommend hin the java.net package, but I doubt that He is bound to anything

torn oyster
#

where do i start

#

i have a method

quaint mantle
#

The issue with Sockets IS that it also requires opening the connection, destinguishing the Socket Type and a Bit more

ivory sleet
#

havent messed with java.net myself that much but probably a good start

quaint mantle
#

At Second thought you might be better Off using a lib unless you want to send Just Tony amounts of data

#

Then use it's getInputStream and getOutputStream for magic

#

Since you'd send Strings you'd send byte[] Bytes = string.toBytes(StandardCharsets.UTF_8); out.write(Bytes.length); out.write(Bytes); and read recieve with String Str = new String(input.readNBytes(input.read()), StandardCharsets.UTF_8);

opal juniper
#

is there a good catch all event for block place / destroy

#

not just player

quaint mantle
#

Of course since you connect multiple clients to a Server you'd need identification and whatnot so perhaps you should be using a lib that does that for you

#

(+ you will need to Reserve a Thread on the Serverside to wait for connections which is inefficent)

quaint mantle
somber hull
#

If i check if NBT is == to something but the NBT doesnt exist on that entity will i get null? or will it pass as its not equal?

#

through persistent data container

ivory sleet
#

myes

somber hull
#

null or no?

ivory sleet
#

an absent value for a key is probably going to be represented with null

lavish hemlock
#

null

somber hull
#

sadge

#

ok

lavish hemlock
#

because people don't know what Optional<T> is apparently :)

ivory sleet
#

😌

#

Also got JSpecify which if we're lucky might be natively implemented in the JDK in the future

lavish hemlock
#

oh shit, never heard of that before

#

that's really cool

ivory sleet
#

yeah found out about it recently also

somber hull
#

also does EntityBreedEvent.getEntity() return the child?

ivory sleet
#

let me see

#

?jd-s

undone axleBOT
ivory sleet
#

yeah

#

seems like it

#

tho its ambiguous so maybe try and see

somber hull
#

Any way to optimize this?

#
        if (fatherData.has(new NamespacedKey(plugin, "family"), PersistentDataType.STRING)) {
            if (motherData.has(new NamespacedKey(plugin, "family"), PersistentDataType.STRING)) {
                if (Objects.equals(fatherData.get(new NamespacedKey(plugin, "family"), PersistentDataType.STRING), motherData.get(new NamespacedKey(plugin, "family"), PersistentDataType.STRING))) {
                    event.setCancelled(true);
                    return;
                }
            }
        }
#

It feels like im doing something wrong

ivory sleet
#

make it more readable

lavish hemlock
#

that's already optimized

ivory sleet
#

create the key once

lavish hemlock
#

oh, true

ivory sleet
#

yeah lol apart from that not much to optimize

somber hull
#

alright

#

thank you

#
if (Objects.equals(fatherData.get(fatherKey, PersistentDataType.STRING), motherData.get(fatherKey, PersistentDataType.STRING)) 
|| Objects.equals(fatherData.get(motherKey, PersistentDataType.STRING), motherData.get(motherKey, PersistentDataType.STRING)))
#

if one of these is null it will give NPE?

#

If so, how do i stop that

ivory sleet
#

dont think so

#

Objects::equals takes 2 arguments where both intentionally accept and handle null accordingly

somber hull
#

Alright

#

And i just realized, i want to also check if father key is == to mother key

#

no shorter way to do that other than adding 2 more ||?

ivory sleet
#

I would suggest extracting out some explanatory variables

quaint mantle
#
/*
    Equivallant to Objects.equals()
 */
public boolean equals(Object a, Object b) {
    if (a == b) return true;
    if (a == null) return false;
    return a.equals(b);
}
ivory sleet
#

so like if (fatherIsMother) rather

somber hull
#

omg

#

thank you so much

ivory sleet
#

lol no worries

somber hull
#

just got back from school im not thinking straight

ivory sleet
#

its fine

#

I have been watching 50 anime episodes straight with no pauses btw lol

quaint mantle
#

aPES_Wow school having a negative impact on an innovative mind

somber hull
#

I should take a nap lol

ivory sleet
#

a wise decision

somber hull
#

Ok

#

Intellij keeps saying that i should do this

#

what the fuck does this mean

#

assert fatherMother != null;

ivory sleet
#

it means dont do it

#

if the following condition after the assert is false

#

then it throws an AssertationError

#

however

#

a special jvm flags needs to be set in order for it to even work

somber hull
#

got it

#

so just check if its null beforehand?

ivory sleet
#

So usually we go with a null check

#

yeah

#

or

#

Objects::requireNonNull

#

depending on what you're doing

somber hull
#

ok

#

im checking if two things are ==

#

and if one of them is null

#

i just want it to be false

ivory sleet
#

alright

lavish hemlock
ivory sleet
#

yeah

lavish hemlock
#

Meanwhile, Objects::equals is for null-safe value-comparison.

ivory sleet
#

Some people prefer guavas Preconditions::checkArgument

#

yup

somber hull
#

Basically, i have

        String fatherFather = fatherData.get(fatherKey, PersistentDataType.STRING);
        String fatherMother = fatherData.get(motherKey, PersistentDataType.STRING);
        String motherMother = fatherData.get(motherKey, PersistentDataType.STRING);
        String motherFather = fatherData.get(fatherKey, PersistentDataType.STRING);
#

and i want to check if any of them are equal to each other

#

if its null

ivory sleet
#

wait wat

somber hull
#

then its not equal to it

ivory sleet
#

two of those are redundant

somber hull
#

oh shit

#

those two are supposed ot be motherData

lavish hemlock
#

Did you mean to type motherData?

#

Yeah

somber hull
#
String fatherFather = fatherData.get(fatherKey, PersistentDataType.STRING);
String fatherMother = fatherData.get(motherKey, PersistentDataType.STRING);
String motherMother = motherData.get(motherKey, PersistentDataType.STRING);
String motherFather = motherData.get(fatherKey, PersistentDataType.STRING);
#

thats better

unkempt peak
#

what is the maven dependency for bukkit 1.17.1?

ivory sleet
#

bukkit?

somber hull
unkempt peak
#

yes

ivory sleet
#

believe does not exist

unkempt peak
#

ik but i need bukkit for nms

#

i need 1.17.1 bukkit

somber hull
#

wait

#

spigot has bukkit inside it

#

...

lavish hemlock
#

Do you mean CraftBukkit?

unkempt peak
#

yes

ivory sleet
#

mere bukkit was abandoned long time ago

unkempt peak
#

ik i can import it with jar and have craftbukkit but i want it with maven

#

i have spigot 1.17.1 imported with maven but it does not have craftbukkit

lavish hemlock
#

that might mean it doesn't exist? I don't know.

#

oh wait

#

gimme a sec

sharp mantle
#

You have to add to ur local repos

lavish hemlock
#

yeah

unkempt peak
#

i tried this wich is the same as the spigot version and it does not work
1.17.1-R0.1-SNAPSHOT

lavish hemlock
#

well yeah, the versions are gonna be different

unkempt peak
#
    <repository>
        <id>spigot-repo</id>
        <url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
    </repository>
    <repository>
          <id>bukkit-repo</id>
          <url>http://repo.bukkit.org/content/groups/public/</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
           <groupId>org.spigotmc</groupId>
           <artifactId>spigot-api</artifactId>
           <version>1.17-R0.1-SNAPSHOT</version>
           <scope>provided</scope>
    </dependency>
    <dependency>
        <groupId>org.bukkit</groupId>
           <artifactId>bukkit</artifactId>
        <version>1.17.1-R0.1-SNAPSHOT</version>
        <scope>provided</scope>
    </dependency>
</dependencies>```
#

what is the version name?

unreal quartz
#

spigot

unkempt peak
#

?

unreal quartz
#

why do you need bukkit

unkempt peak
#

nms

somber hull
#
    public Boolean checkParents(PersistentDataContainer fatherData, PersistentDataContainer motherData) {
        NamespacedKey fatherKey = new NamespacedKey(plugin, "father");
        NamespacedKey motherKey = new NamespacedKey(plugin, "mother");
        List<String> fatherStrings = new ArrayList<>();
        List<String> motherStrings = new ArrayList<>();
        fatherStrings.add(fatherData.get(fatherKey, PersistentDataType.STRING));
        fatherStrings.add(fatherData.get(motherKey, PersistentDataType.STRING));
        motherStrings.add(motherData.get(motherKey, PersistentDataType.STRING));
        motherStrings.add(motherData.get(fatherKey, PersistentDataType.STRING));
        for(String i : fatherStrings){
            if(motherStrings.contains(i)) return true;
        }
        return false;
    }
}
#

am i insane?

unreal quartz
#

you run build tools and it will be installed to your local repo

ivory sleet
unreal quartz
#

under the spigot group and the artifact is just spigot

somber hull
ivory sleet
#

Yeah

lavish hemlock
#

you should make fatherKey and motherKey fields of the class checkParents is in

#

also there's probably a more efficient way to do that search but eh, idk

somber hull
#

wait

somber hull
#

will i get an NPE?

unkempt peak
lavish hemlock
#

Maven Local

#

it's where all of the libraries on your computer are located

#

as opposed to Maven Central, which is a remote repo

unreal quartz
lavish hemlock
#

also what I think they mean is that it's org.spigotmc:spigot:1.17-R0.1-SNAPSHOT

somber hull
#

The capital?

#

i changed that

quaint mantle
#

Ok.

unkempt peak
#

So how would i reference the local repo in the dependency?

unreal quartz
#

maven will look there by default

#

same with central

lavish hemlock
unkempt peak
#

ok.. so i don't add a repo?

#

i still need the version

somber hull
#

wait ok

#

can someone help me with the thought process of this

unreal quartz
#

take a look in your .m2 folder but i am very certain the version string is the exact same

unkempt peak
#

ok so i have this right

        <groupId>org.bukkit</groupId>
           <artifactId>bukkit</artifactId>
        <version>1.17.1-R0.1-SNAPSHOT</version>
        <scope>provided</scope>
    </dependency>``` what do i put for the version i am confused
#

and if i dont have a repo what is the group id?

unreal quartz
#

use the spigot group id and just spigot for the artifact

#

your versoin string is correct

ivory sleet
#

hyperlink by returning the type Boolean you implicitly return Boolean.FALSE or Boolean.TRUE or null, assume you store it to a variable whose type is the primitive variant boolean then it would have to invoke Boolean::booleanValue implicitly which is just straight method overhead

unkempt peak
#

ok ive got this ```
<dependency>
<groupId>spigot</groupId>
<artifactId>spigot</artifactId>
<version>1.17.1-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>

but its telling me it doesn't exist
```Missing artifact spigot:spigot:jar:1.17-R0.1-SNAPSHOT```
unreal quartz
#

not literally just spigot for the group id lol

#

org.spigotmc

unkempt peak
#

oh

#

i am dumb

#

sorry i am still kind of new to maven lol

#

it appears to be working now thanks

lavish hemlock
#

nice :)

unkempt peak
#

wait so does this import also include the spigot api?

unreal quartz
#

yes

unkempt peak
#

ok so i can get rid of the other one then right?

unreal quartz
#

if you want

unkempt peak
#

ok

somber hull
lavish hemlock
#

yes

somber hull
#

fuck

quaint mantle
#

no

somber hull
#

🧄

lavish hemlock
#

only if fatherData or motherData is null tho

somber hull
#

oh

quaint mantle
#

hi! What is the best minecraft server startup flag/parameters ?

somber hull
#

those cant be null

lavish hemlock
#

otherwise, get would just return null

lavish hemlock
quaint mantle
#

nah i been toold to go here

unreal quartz
#

no you haven't

quaint mantle
#

go away troller kid

#

ignore and blocked dude

unreal quartz
#

go to the correct channel and you won't get sarcastic responses

unreal quartz
ivory sleet
#

Aikar got some nice jvm flags

#

Even a documentation

quaint mantle
#

i know but do they work i mean do they make the overall performance better?

#

Yes

#

?flags

undone axleBOT
ivory sleet
#

That’s the entire intention behind them

quaint mantle
#

memory consumption

granite beacon
#

I'm having a bit of a weird issue. When using player.setCollidable(false) it disables arrows from working properly on players using <1.9. (Using protocolsupport for the version support.)

Any idea on how I can disable collision without causing an issue like that?

somber hull
#

How do i check if an entity is a cow, sheep, pig, horse, etc anything breedable

#

like whats the most efficient way

quaint mantle
#

ever heard of docs

unreal quartz
#

who needs docs when you can get random people on the internet to link you to them for you and get mad you simultaneously

somber hull
#

wait

#

so

#
        if(entity instanceof Breedable){
            
        }
lavish hemlock
somber hull
#

trhat should work right?

quaint mantle
quaint mantle
#

🤸🏌️

somber hull
#

cause im big dum

unreal quartz
#

cuz nothing is in there

quaint mantle
#

?code

lavish hemlock
#

Hi. I have two questions:

  • Does anyone have any recommendations for stuff to make plugin dev a bit easier/cleaner? Just some general utilities.
  • Would you recommend using a GUI framework or just coding GUI by yourself? (GUI in this context means chest GUIs)
quaint mantle
ivory sleet
#
  1. Check out BKCommonLib, helper but also awesome-minecraft gh repo
  2. InventoryFramework, Canvas, triumph-gui, interfaces are just some
lavish hemlock
#

I've seen Canvas

#

IF seems a bit overcomplicated though, since it uses a very... Swing-esque panel system

#

I was mainly asking if I should use one.

ivory sleet
#

Hmm well

#

That depends entirely on you

lavish hemlock
#

BKCommonLib'll probably be useful though, thanks.

quaint mantle
#

I’d make an easy system with a consumer for clicking, @stone sinew does it not throw an error?

#

Probably something to do with chunks

stone sinew
quaint mantle
#

please PM me.

lavish hemlock
#

Btw, another question, what is the minimum version of the game I should (actively) support?

ivory sleet
#

Hmm 1.8 usually

#

Since there’s for some peculiar reason a lot of servers staying on that version

stone sinew
ivory sleet
#

It’s outdated

#

And well iirc spigot uses a lib which doesn’t work with Java 16 or something so it makes it limited to what version you’d use to run the server

stone sinew
#

You can join 1.8 with 1.17 clients

ivory sleet
#

frankly if you dislike the features just disable them

#

That’s hella hacky tho

stone sinew
lavish hemlock
quaint mantle
ivory sleet
#

Actually the Apache commons one

lavish hemlock
#

...Commons is fucking it up?

#

wow

ivory sleet
#

yapperyaps it’s a hell to first and foremost having to support a wide range of versions especially if you involve nms

#

Or Lang

#

Idr exactly but yeah

lavish hemlock
#

oof, NMS

#

what's the reason NMS couldn't be remapped, btw?

ivory sleet
#

idk

#

In 1.17 they swapped to just pure obfuscation and then encouragement of building against mojmaps

stone sinew
lavish hemlock
#

I mean, with modern mapping tools they could easily do consistent jar mapping.

ivory sleet
#

Yes a lot of plugins do

#

But that doesn’t take away the irrefutable fact that it would have been much easier if everyone just stayed on latest

somber hull
#

anything i can imporve here?

#

improve*

#

it feels like there are too many if statements

stone sinew
lavish hemlock
ivory sleet
ivory sleet
quaint mantle
#

then loop through the chances

#

apply the event to them

#

adds for much more expandability

somber hull
#

for this part?

        if (randNum.nextBoolean()) {
            childData.set(fatherKey, PersistentDataType.STRING, fatherData.get(fatherKey, PersistentDataType.STRING));
        } else {
            childData.set(fatherKey, PersistentDataType.STRING, fatherData.get(motherKey, PersistentDataType.STRING));
        }
        if (randNum.nextBoolean()) {
            childData.set(motherKey, PersistentDataType.STRING, motherData.get(fatherKey, PersistentDataType.STRING));
        } else {
            childData.set(motherKey, PersistentDataType.STRING, motherData.get(motherKey, PersistentDataType.STRING));
        }
quaint mantle
#

always look for ways to include things in an api

stone sinew
lavish hemlock
#

y'know

the Spigot NBT system is real ugly :p

somber hull
#

i have a nicer looking one

#

but people kept yelling at me to use the normal one

lavish hemlock
#

I'm curious to see why they might be saying that.

somber hull
#

Bananapunchers NBTEditor

ivory sleet
somber hull
#

its one class

ivory sleet
#

But quite frankly not only features

somber hull
ivory sleet
#

In addition more security and better code architecture and more stuff are multi threaded

lavish hemlock
#

Oh

ivory sleet
#

There’s a lot of pros with newer versions also

lavish hemlock
#

I see why they're telling you not to use it

#

That looks incredibly fucking slow

somber hull
#

alright

#

i gtg

ivory sleet
#

PDC is slow as hell

stone sinew
ivory sleet
#

So what’s your definition of needed then?

stone sinew
ivory sleet
#

No I’m genuinely curious, if you say multi threading wasn’t needed and all the new features?

quaint mantle
# somber hull for this part? ```java if (randNum.nextBoolean()) { childDat...
class BreedApi {
    @Getter
    private static final Set<BreedHandler> HANDLERS = new HashSet<>();

    @Getter
    private static BreedApi inst;

    {
        inst = this;
    }

    public static void addBreedHandler(BreedHandler h) {
        HANDLERS.add(h);
    }
}

interface BreedHandler {
    void apply(SomeEvent e);
}

//Whatever event you in
for (BreedHandler h : BreedApi.getHandlers()) {
    h.apply(event);
}
stone sinew
quaint mantle
lavish hemlock
stone sinew
#

Get their velocity and set it in the opposite direction.

ivory sleet
#

Yes but taking away the multi threading part? What’s your definition of needed? Is it only the merely adequate features 1.8 is providing, then sure stick to 1.8 it makes no sense if you don’t care about any improvements to bump version.

lavish hemlock
#

There's legitimately a difference afaik.

quaint mantle
#

do you even understand it

#

you instantiate it on onEnable

#

you cant access the instance in a static initializer

#

and its a fucking example

#

not everything is perfect

lavish hemlock
#

Wait but hold up

quaint mantle
#

omg

lavish hemlock
#

Why are you even using it like a Singleton when everything is already static?

quaint mantle
#

its an ✨ example ✨

#

please

lavish hemlock
#

It's a bad example tho

lavish hemlock
quaint mantle
#

🙂 I was not teaching them the api part

lavish hemlock
#

And you do know that HyperLink is a beginner, right?

quaint mantle
#

they understand basic spigot concepts

#

I believe that

limber dust
#

Reading this it went from 0-100 real quick

lavish hemlock
#

I'm sorry but it's legit just a horrible example :p

quaint mantle
#

then make one yourself and stop complaining

lavish hemlock
#

Like, of course I don't understand it bc it doesn't make sense.

quaint mantle
#

i hate people like you. its a bad example but the api is not the focus. its the abstractation and expandability of what hes doing. if you were to fucking read the original post then you would know why. im on a phone. i couldnt give two shits about writing out a fully fledged system for a two minute spigot project for someone in a help discord. do it yourself, and stop complaining

lavish hemlock
#

Okay but you do know that that also encourages a beginner to do something like what was shown in the example?

quaint mantle
#

everytime someone new joins they make me wanna bang my head against a wall

lavish hemlock
#

If someone doesn't immediately understand that it's the abstraction part, they'll copy it.

limber dust
#

If they copy it and expects it 3o4ks that's their fault

quaint mantle
#

@somber hull Hey buddy! dont copy everything I said! Learn from it!

limber dust
#

Works*

quaint mantle
#

stop being such a dick and further expand on what i say to make the learning process better for the person requesting it @lavish hemlock

lavish hemlock
#

I'm glad you said that at least :p

native nexus
#

Ya'll need to relax

#

Take a step back and think before you speak please.

quaint mantle
ivory sleet
#

Let’s talk about Kotlin, shall we?

quaint mantle
#

and this is my normal personality

quaint mantle
ivory sleet
#

Is that a thing actually?

#

lol

lavish hemlock
#

Here:

// Users of your API can implement this interface to handle an event.
public interface BreedHandler {
    void update(SomeEvent event);
}

// This encapsulates your handlers and also allows said handlers to be updated when an event happens.
public class BreedApi {
    // Use Set instead of List if you:
    // - Don't have duplicates.
    // - Don't need to get a value at a specific index.
    private final Set<BreedHandler> handlers = new HashSet<>();

    // Call this via your implementation classes, like in one of your events or your plugin class.
    public void update(SomeEvent event) {
        handlers.forEach(handler -> handler.update(event));
    }

    public boolean addHandler(BreedHandler handler) {
        return handlers.add(handler);
    }

    public Set<BreedHandler> getHandlers() {
        return handlers;
    }
}

// BreedApi can then either be a Singleton or field on another publicly accessible class.
// A user would implement the interface, and then add it to the API via addHandler.
quaint mantle
#

art thou pronouncing it Pythohn or Pythin

ivory sleet
#

Hehe

quaint mantle
#

addHandler:3

#

i dont know why you gave me such a bad time over a change that I rushed

ivory sleet
#

addBomp:3

quaint mantle
#

Very pointless helper method haha

quaint mantle
#

object.get().add() is a bad design pattern

#

What?

quaint mantle
#

Having single line helper methods that really do nothing is a bad design pattern

#

When you already have a getter for the map

#

its a set, and i agree to some poimt

#

getHandlers

#

used for iteration

#

Cause then I guarantee your project is full of useless helper methods

ivory sleet
#

Bomp might be nice in case you derive from it and want to extend its behavior

quaint mantle
#

^

lavish hemlock
#

It's generally conventional in Java too.

quaint mantle
#

depending on obtaining an object and adding to it is also insecure

lavish hemlock
#

I don't personally like methods like that but yeah.

quaint mantle
lavish hemlock
#

But man I wasn't trying to give you a hard time, just pointing out a flaw since the full example wasn't posted :/

quaint mantle
#

is that an apology

lavish hemlock
#

No.

quaint mantle
#

😩

lavish hemlock
#

It's just me stating something.

quaint mantle
#

Not a fan

quaint mantle
#

Bonzi

lavish hemlock
quaint mantle
#

Bonzi loves helper methods for noobs

#

its not for noobs

#

its genuinely a better design in most cases

#

First off that add method is not a setter

lavish hemlock
#

It's an adder.

quaint mantle
#

Never heard of that one

lavish hemlock
#

Which is probably not a real thing.

#

But that's my name for it.

quaint mantle
#

But anyways, setters shouldn’t really be a thing if you care about immutability. There are small cases of course. Getters are fine. And what makes it better design sorry?

lavish hemlock
#

But seriously, what happens if the name of handlers is changed in a future update, you don't have any methods for accessing it, and someone uses a later version of the plugin with another plugin that uses handlers but from an older version of the other plugin?

ivory sleet
#

I would say it’s a command method if we’re still on the topic of terminology

lavish hemlock
#

fair

#

These things exist to avoid binary compatibilities because there is no other way to access a field safely.

ivory sleet
#

Btw ever heard of the query and command separation principle

lavish hemlock
#

I haven't.

ivory sleet
#

Yeah well hmm it’s not crucial, Java breaks it already but it’s something notable to say the least ¯_(ツ)_/¯

lavish hemlock
#

And by "delegate," I mean get() = newHandlers, not by.

#

in which case, the compiled code would actually be something like BreedApi.getHandlers().add, which is gross, but not visible to API users, as it looks like BreedApi.handlers.add

ivory sleet
lavish hemlock
#

Kotlin's @Deprecated is so nice btw 🥺

#

You can legit specify the reason why something was deprecated

#

And IntelliJ displays it

#

You can also specify whether or not using the deprecated value is a warning or error.

main mural
#

..

ivory sleet
#

Javas @Deprecated is just well

lavish hemlock
#

Wellll

ivory sleet
#

🥴

lavish hemlock
#

I believe the only thing @Deprecated does is add an attribute to the element (I might be mistaken) and also display compiler warnings, it also has a bit of light support in all IDEs.

#

Oh, interesting, @Deprecated has runtime retention

#

You can reflect @Deprecated :)

ivory sleet
#

I know one thing for sure, Bukkit has a lot of them

lavish hemlock
#

Not surprised :p

#

Minecraft's code changes so goddamn much

vagrant stratus
#

no, it's backwards compatibility reasons lol

#

otherwise they'd be gooooone

ivory sleet
lavish hemlock
#

Well it also has to be Minecraft's fault, right?

ivory sleet
#

Ritee

vagrant stratus
#

to an extent yes

native nexus
#

Minecraft code barely changes…?

vagrant stratus
#

1.13 was the perfect time to drop anything below 1.13

#

but ofc, that didn't happen

ivory sleet
#

It has changed over the years quite significantly

vagrant stratus
lavish hemlock
#

I was in a dev group that was working on a mod loader for an older version of the game, like 1.4 or something.

ivory sleet
#

Not surprising lol

lavish hemlock
#

I was doing jar mapping, so I got to see Minecraft's enchantment code.

#

Gimme a sec I'll fetch it again

tame oxide
#

I'm having difficulties with item lore currently, I can't get lore to update after the item is in the players inventory, works fine before.

I'm working with custom enchants and the information looks fine in the output but it refuses to update the lore

#

I would send pictures but I dont have perms

#
    // Writes the enchantments to the items' lore.
    public static void updateItemStackLore(ItemStack itemStack, ArrayList<CustomEnchantment> customEnchantments) {
        if (itemStack == null || itemStack.getItemMeta() == null || customEnchantments == null) return;

        ItemMeta itemMeta = itemStack.getItemMeta();
        ArrayList<String> itemLore = new ArrayList<>();

        // We need to remake it now.
        for (CustomEnchantment customEnchantment : customEnchantments) {
            itemLore.add(getEnchantmentsItemLore(customEnchantment));
        }

        itemMeta.setLore(itemLore);
        itemStack.setItemMeta(itemMeta);

        System.out.println("The new item lore should be: " + itemLore);
        System.out.println("Should be new item meta: " + itemStack.getItemMeta());
    }

This is my code

#

And the item lore and item meta are correct

#

Its just not updating the item

young knoll
#

Minecraft used to have some cursed internal item names too

#

Diamonds used to be emerald internally

lavish hemlock
#

Block was Tile

#

internally

#

that is

#

(at least, iirc, that might just be MCP trivia)

quaint mantle
#

its not memorized or whatever

#

it has no internal access, its just an object

tame oxide
#

Huh?

lavish hemlock
#

change the return type to ItemStack and return itemStack

quaint mantle
tame oxide
#

But changing my game mode from creative to survival did

young knoll
#

Creative is janky

tame oxide
#

Apparently creative mode is prone to replication issues like that

young knoll
#

Yes

tame oxide
#

Hahaha nice to know

#

It'

#

It's only my second day working with this api

quaint mantle
tame oxide
#

What part of my code?

quaint mantle
#

where you create the inventory. or is that what youre doing?

tame oxide
#

creating the inventory?

#

Its adding one enchantment to an items lore

young knoll
#

You probably need to setItem for creative mode

#

Because it doesn’t bother syncing with the server

lavish hemlock
tame oxide
#

setItem?

young knoll
#

Not the same as it does in survival

lavish hemlock
#

Can't you check if a plugin is loaded by the server?

#

well, you could make a util method for checking

#

Utils.isLibraryPresent() or smthn

#

you could just store the plugin as a LibraryPlugin after checking it

#

so

if (Utils.isLibraryPresent()) {
    LibraryPlugin plugin = ...
}
eternal oxide
#

Put your library access in a utility class. So any access to it auto checks the presence

lavish hemlock
#

ooh, true

#

yw

#

I can see it :p

eternal oxide
#

Nope, can;t see a thing

tall siren
#

excellent

#

Basically, here's my code. The intention is that when a chunk generates, kill all the villagers already inside. This is a small part within a larger plugin, but for some reason, e.getChunk().getEntities() is empty, despite there being entities in newly generated chunks

eternal oxide
#

Not all entities are loaded when the Chunk is. You will have to delay your removal. But its also probably better to use .remove() over setHealth.

tall siren
#

Do you have any ideas on how I can accomplish this other than use ChunkLoadEvent, because I want players to be able to get villagers, just not find them naturally.

#

And ChunkLoadEvent would remove them whenever a player joined, or otherwise reloaded their base chunks

eternal oxide
#

You would have to tag any villagers you spawned in yoruself so they are not deleted. PDC.

tall siren
#

Those entities still exist though, even if they're not loaded...right? So is there any way to load them in to check?

young knoll
#

ChunkLoadEvent has an isNewChunk method

eternal oxide
#

You wait, until they are loaed

tall siren
#

Can I track their SpawnReason and if they weren't spawned by either a command or a spawnegg, remove them?

#

or would that not work because villagers in chunks when they are generated technically aren't spawned

tall siren
#

I did

#

My new code is on my server and not working

#

because I'm figuring that chunks load at a different time than when entities load

eternal oxide
#

So long as you only remove if new then you won't delete any of your own.

tall siren
#

cody no worky

eternal oxide
#

it won;t because you are not delaying it

#

entities will not be loaded yet

tall siren
#

how much should I delay and, and frankly, how do I delay it

young knoll
#

Also you don’t need that cast

eternal oxide
#

?scheduling

undone axleBOT
tall siren
#

Oh yeah, not anymore, because I'm not setting health

#

how much should i delay it

quaint mantle
#

1 tick

#

more if the server is shit

#

but you can count on 1 tick

tall siren
#

code is ugly af, but that's what youre talking abt, right?

eternal oxide
#

e will not exist.

upper vale
#

Anyone know of a runtime dependency management library that is reliable with relocation features and supports Java 9+?

eternal oxide
#

create a final variable to hold a reference to the chunk

tall siren
#

thanks for your help btw

#

im makin amateur mistakes, probably because im an amateur

eternal oxide
#

hover over your error

tall siren
#

don't think its an error

eternal oxide
#

try it and see

quaint mantle
naive brook
#

what is protocolib used to?

cunning ermine
#

live debugging with intelij and gradle?

young knoll
#

Same as we told you before

#

Follow the tutorial

pseudo quiver
#

hi, i'm having a yml file that store like

WhiteWorld:
  "example"

so when i write

 getConfig().getString("WhiteWorld");

it will get the WhiteWorld or the example ?

quaint mantle
#

should work

#

although you should make it inline

pseudo quiver
#

like WhiteWorld: "example" ?

cunning ermine
young knoll
#

Remote debugging doesn’t seem to like hotswapping much

#

Works for some things though

cunning ermine
#

probs theres some sort of issue with gradle then

#

imma try figure out whats going on

quaint mantle
pseudo quiver
cunning ermine
quaint mantle
pseudo quiver
quaint mantle
#

how you gonna know if something works for sure if you never try it

cunning ermine
#

try and see what happens

lavish hemlock
#

it's probably related to slot ID?

young knoll
#

Have you tried comparing the clicked inventory to the top inventory

eternal oxide
#

compare getSlot to getRawSlot. If they are equal its the top inventory. Or the player has no inventory open.

young knoll
#

Probably also works

upper vale
#

@jade perch is hdl still maintained :c_:

jade perch
#

Not really anything that needs to be changed about it

somber hull
#

I have no idea what half of it is...

#

im looking stuff up

#

but still

#

what the fuck

young knoll
#

Looks pretty straightforward

#

Except for the lombok

lavish hemlock
somber hull
#

thank you for adding comments lol

#

Quick question

young knoll
#

And removing Lombok

somber hull
#

Could probably look it up

#

But im gonna ask

#

what exactly is a handler?

lavish hemlock
#

It's just a generic term

#

It's used to describe something that interacts with something else

#

So yeah, very generic

somber hull
#

Got it

#

thank you

#

cause i looked it up

#

and there was a java api thing, that didnt make sense for how it was being used

lavish hemlock
#

An example of how people would use it:

// An implementation of BreedHandler in another plugin that uses your API.
class MyBreedHandler implements BreedHandler {
    void update(SomeEvent event) {
        // Print a value of the event to the log, this is just for example purposes.
        System.out.println(event.value);
    }
}

// ... On Plugin Load ...
YourPlugin
  .getBreedApi() // This is just an example, you can put an instance of BreedApi wherever you want. 
  .addHandler(new MyBreedHandler());

// Or, if you want to use BreedApi as a Singleton:
BreedApi.INSTANCE.addHandler(new MyBreedHandler());
somber hull
#

I think im missing what exactly this does

#

Like

lavish hemlock
#

Wellllll, not really much.

#

You want to call BreedApi.update when you have an instance of SomeEvent

#

Like in an event handler

somber hull
#

Wait... So why was this recomended to me

#

I dont see how it would be useful at all...

lavish hemlock
#

I mean the example doesn't do anything

somber hull
#

Yea

#

But i dont see how i could implement it into something useful at all...

lavish hemlock
#

But the main purpose is that it lets people extend your plugin with new features via their plugins.

#

Or, alternatively, just get values from your plugin.

#

Which is why it's an API.

somber hull
#

Ohhhh

lavish hemlock
#

You can also use it yourself, if the API is designed well enough, then maybe it'll even make things easier for you, lol.

somber hull
#

Ok, so basically it has nothing to do with what im trying to do? The guy that said it origionally just kinda said some random thing?

I still want to understand it so if it would be useful later i know about it

lavish hemlock
#

He was suggesting you make an API for your plugin so that other people can extend it.

#

Since you asked "is there anything I can improve?"

somber hull
#

Ok

lavish hemlock
#

So, technically, he was suggesting a thing you could improve.

somber hull
#

Ig lol

#

Ok wait

#

so

#

would i create a new .java file for the interface part?

#

I still dont fully understand how that works

lavish hemlock
#

Yes

somber hull
#

With multiple classes in a file

#

and stuff

#

I have worked a little with interfaces

lavish hemlock
#

I don't think you can put multiple classes in a file, I just did so to reduce redundancy.

somber hull
#

Got it

young knoll
#

You can

#

But it’s generally not recommended

somber hull
lavish hemlock
#

Ah, yeah

#

I believe it can only be package-private.

somber hull
#

So would this whole thing allow people to make plugins for the plugin? Kinda like Slimefun addons? Or would they have to edit the source code?

lavish hemlock
#

Yeah, it would allow people to make plugins for the plugin.

#

Which is mainly recommended for public plugins.

somber hull
#

ok

#

and possibly last thing

#

handlers.forEach(handler -> handler.update(event));

#

what is going on here

#

forEach thing in handlers idk whats after this

#

i get that its a consumer

#

But i dont get what a consumer is

#

nvm i found a indian guy on youtube to explain it

lavish hemlock
#

yeah, sorry about that

#

it's called a lambda

#

in this situation, it's equivalent to

for (BreedHandler handler : handlers) {
    handler.update(event);
}
#

basically

somber hull
#

so it just creates a loop of itself?

lavish hemlock
#

forEach is a method for lists

somber hull
#
    public void update(EntityBreedEvent event) {
        handlers.forEach(handler -> handler.update(event));
    }
#

does this not create a loop of itself?

lavish hemlock
#

yeah, pretty much

somber hull
#

oh ok

lavish hemlock
#

-> creates a new lambda, an empty lambda looks like () -> {}

#

lambdas can also be single statements, so brackets {} aren't required

#

() just means "no value," basically

somber hull
#

got it

lavish hemlock
#

handler is a single value, but for more than one I believe it's (value1, value2) ->

somber hull
#

wait so the first handler value

#

what is that?

#

A variable like in a for loop?

lavish hemlock
#

yeah

young knoll
#

Pretty much

#

You just don’t declare a type

lavish hemlock
#

a lambda is basically a way of passing a function as a parameter

somber hull
#

Ok

lavish hemlock
#

forEach looks like

somber hull
#

And consumer just means lambda?

lavish hemlock
#

a consumer is a function that takes in a value but returns nothing

#

so it's equivalent to void function(thing)

somber hull
#

ok

#

i understand now

#

alright

#

last thing, cause i gtg take the trash out

#

if i wanted to make this "api" public

#

would i just share the interface, and the api class?

lavish hemlock
#

no, someone would have to import your plugin through Maven or Gradle

#

you don't have to worry about that though

#

Here's what forEach looks like btw:

public void forEach(Consumer<BreedHandler> consumer) {
    for (BreedHandler handler : elements) { // I don't remember the actual name for 'elements'
        consumer.accept(handler);
        // accept -> call the function and give it handler, the 'handler' in this for loop is where the handler in the lambda comes from
    }
}
#

Java instantly recognizes Consumer as an interface that can take a lambda btw

#

the others would be:

#

Producer<T> -> takes in no value, returns a value of type T (T function())
Function<T, R> -> takes in a value of type T, returns a value of type R (R function(T))

somber hull
#

alright

lavish hemlock
#

there's also
BiConsumer and BiFunction
which take in two values instead of one, like BiFunction<T, U, R>, which is R function(T, U)

somber hull
#

ok, thank you so much. Ill be back in a few minutes

lavish hemlock
#

and that is Java functional programming in a nutshell :)

#

now I'll tell you some more stuff while you're gone:

#

You can make your own versions of Consumer and etc. since they're just interfaces

#
// This is a function that takes in 3 values and returns nothing

// This annotation isn't absolutely required iirc, but it's helpful since it tells you if the interface doesn't meet requirements from the compiler
@FunctionalInterface 
public interface TriConsumer<T, U, V> { // I hope you know what type parameters are
    void accept(T first, U second, V third);
}

// e.g. TriConsumer<String, String, Integer> =
// Function equivalent:  void function(String s1, String s2, int i)
// Lambda equivalent:    (s1, s2, i) -> { }
#

you don't need type parameters either

#
@FunctionalInterface
public interface CoolFunction {
    String doThing(String s);
}
somber hull
lavish hemlock
#

That is equivalent to String function(String)

lost matrix
lavish hemlock
#

Oh, sorry, you're right

somber hull
#

// I hope you know what type parameters are

#

no idea

lavish hemlock
#

Alright so

somber hull
#

never heasrd of em

lavish hemlock
#

You know List?

somber hull
#

yea

#

ofc

lavish hemlock
#

well, List is declared like List<T>

#

T is a type parameter

#

when you create a new List

#

you can specify what T is

#

so

#
// Side-note: There are no restrictions to the names of type parameters.
public class WithTypeParameter<T> {
    public T giveMeAValue() {
        // irrelevant
    }
}
#

and so

#

you create a new WithTypeParameter like

#
WithTypeParameter<String> wtp = new WithTypeParameter<>();
#

and so now the class knows that T is a String when you reference wtp

#

so if you call giveMeAValue on wtp, it returns a String

somber hull
#

Oh

#

nvm

lavish hemlock
#

well the classname is WithTypeParameter

#

and then after it you have <, which starts a list of type parameters