#help-development

1 messages · Page 1387 of 1

woeful moon
#

Do I have to import the API or something?

worldly ingot
#

No, you're just making a web request

woeful moon
#

Ok, sounds good

quaint mantle
#

I start the server, when I join it will time me out then say ./start.sh does not exist, stopping the server!

novel lodge
#

How can I wait without halting the entire server?

mortal hare
#
java -Xms[STARTUP-MEMORY-IN-GB]G -Xmx[IDLE-MEMORY-IN-GB]G -XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:+AlwaysPreTouch -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1 -Dusing.aikars.flags=https://mcflags.emc.gs -Daikars.new.flags=true -jar [SPIGOT-LAUNCHER-NAME].jar nogui

paste this inside the shell file (.sh)

#

these are optimized flags of garbage collection for minecraft

#

made by aikar's love to community

quaint mantle
#

I don't have an sh file do i create one and put this in it?

mortal hare
#

just create it

quaint mantle
#

okay

woeful moon
#

Question, does this apply to plugin creation?
https://www.youtube.com/watch?v=YYP_dNSYOG4

In this video I show you how you can easily interface with discord webhooks using Minn Development's Discord-Webhooks library.

Discord's intro to webhooks: https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks
Discord-Webhooks Github: https://github.com/MinnDevelopment/discord-webhooks

0:00 - Intro
0:30 - Creating the Webho...

▶ Play video
mortal hare
#

if you're on windows create .bat file

#

yes it does

#

its in java

woeful moon
#

Ok :D

mortal hare
#

you just need to make it work via bukkit plugin API

#

handle the plugin itself

quaint mantle
#

I created the file and pasted the stuff in it now do i run the server by opening the new .bat file or the old one @mortal hare

mortal hare
#

have you changed those?

quaint mantle
#

ye

mortal hare
#

if you're on linux terminal:
chmod +x [filename].sh
./[filename].sh
if you're on windows:
just double click it, or from cmd.exe inside directory - [filename].bat

quaint mantle
#

"This app can't run on your pc
To find a version for you pc, check the software publisher"

#

Windows

hushed crescent
#

Is there a simple database/method to store Usernames and their points?

mortal hare
#

have you created .sh file on windows

#

or .bat file one?

quaint mantle
#

.bat

quaint mantle
#

exactly

mortal hare
#

are you running on some kind of ARM based windows pc ?

#

is it like surface shit

quaint mantle
#

nope

mortal hare
#

maybe its windows defender

quaint mantle
#

ill disable it and let you know

mortal hare
#

can you do a screenshot?

quaint mantle
#

can't upload images here

mortal hare
#

on the edited file

quaint mantle
#

okay

mortal hare
#

login to your spigotmc account

#

and verify the discord account

#

and you'll be able to do that here

quaint mantle
#
@EventHandler
    public void onMushroomBlockUpdate(BlockPhysicsEvent event) {
        if (event.getBlock().getType() == Material.BROWN_MUSHROOM_BLOCK ||
                event.getBlock().getType() == Material.RED_MUSHROOM_BLOCK ||
                event.getBlock().getType() == Material.MUSHROOM_STEM) {
            event.setCancelled(true);
            //Update the blocks with their current face values to force the client to update
            resendMushroomStates(event.getSourceBlock());
        }
    }

    private void resendMushroomStates(Block block) {
        Location loc = block.getLocation();
        for (int x = loc.getBlockX() - 10; x < loc.getBlockX() + 10; x++) {
            for (int y = loc.getBlockY() - 10; y < loc.getBlockY() + 10; y++) {
                if (y < 1) continue;
                for (int z = loc.getBlockZ() - 10; z < loc.getBlockZ() + 10; z++) {
                    if (block.getType() == Material.BROWN_MUSHROOM_BLOCK || block.getType() == Material.RED_MUSHROOM_BLOCK
                            || block.getType() == Material.MUSHROOM_STEM) {
                        BlockData blockData = block.getBlockData();
                        MultipleFacing multiFacing = (MultipleFacing) blockData;
                        multiFacing.setFace(BlockFace.UP, multiFacing.hasFace(BlockFace.UP));
                        multiFacing.setFace(BlockFace.DOWN, multiFacing.hasFace(BlockFace.DOWN));
                        multiFacing.setFace(BlockFace.NORTH, multiFacing.hasFace(BlockFace.NORTH));
                        multiFacing.setFace(BlockFace.SOUTH, multiFacing.hasFace(BlockFace.SOUTH));
                        multiFacing.setFace(BlockFace.EAST, multiFacing.hasFace(BlockFace.EAST));
                        multiFacing.setFace(BlockFace.WEST, multiFacing.hasFace(BlockFace.WEST));
                        block.setBlockData(multiFacing);
                    }
                }
            }
        }
    }
#

I am trying to cancel the mushroom block state update but for some reason it still changes

mortal hare
#

have you tried debugging it if it does happen for mushrooms on that event?

quaint mantle
#

it is fired yes

main dew
#

How the best metod to set all chunk to max bright? (max light and max skylight)

mortal hare
#

not sure mate, i've rarely used that event

quaint mantle
#

Now it's giving me this infinite error and won't let me join, timed out @mortal hare

quaint mantle
#

it's really weird, the event cancel should work by itself

mortal hare
#

what java version have you got on your computer

#

some software just vomits errors when it seems older or newer java version

quaint mantle
mortal hare
#

minecraft version?

quaint mantle
#

1.16.5

mortal hare
#

try installing java 11

#

its now industry standard

#

java 8 is deprecated

quaint mantle
#

this error wasn't happening but as soon as i installed essentials everything is ruined

quaint mantle
mortal hare
quaint mantle
#

?

#

custom blocks

mortal hare
#

yes

#

but you can listen to onBlockBreak or onBlockPlace events and check if block is mushroom type

#

if its is restore the blockstate

#

??

quaint mantle
#

still it changes the blocks around it

#

because that is how the mushroom block works

mortal hare
#

what's stopping you to check 3x3 block area around the broken block

quaint mantle
#

that is why I need to listen to the BlockPhysicsEvent

#

then it will change the ones around the ones that are placed and again and again

mortal hare
#

you only need to change 6 block's blockstates

#

since it only changes the blocks around the broken or placed block

#

if that's not an option for you and spigot doesn't work

#

try to listen to the packet which changes the block type

#

and create your own custom bukkit event

#

or handle it from there synchronised to the main server thread (BukkitRunnables)

main dew
#

What the best metod to set all chunk to max bright? (max light and max skylight)

mortal hare
#

Never done it so i don't know if spigot api supplies light api

#

but you can do it manually via NMS i think

quaint mantle
opal sluice
#

Hey, can someone help me to find out how could I change the crafting slots of the player inventory ?

mortal hare
#

check if it is the mushroom block

#

then change the block state

opal sluice
#

Cause it seems that it is a sort of view and can't get the actual slot

quaint mantle
#

if its for example a 100x100 and you place one in the center

#

you will have to change for each one of those blocks the block state because when you update one it will update the others again and again

mortal hare
#

idk what you're talking but it only changes the blockstates around the broken block

#

unless this is different in older versions of minecraft

#

if it would work like that, i would be lagging p2w creative server straight away

#

heck no need for creative servers, you can do it in survival with silk touch enchantment and a big ass area

cinder thistle
#

p2w? creative?

mortal hare
#

there are some

#

ngl

quaint mantle
#

the others around it will change

cinder thistle
#

you can "win" on a creative server??

#

ig competitions

mortal hare
#

i dunno

quaint mantle
#

it confirms that it will change stuff on this pc, I click yes and it won't open

#

even in task manager there is nothing

cinder thistle
#

try restarting your pc?

#

never heard that one before

quaint mantle
#

alright

mortal hare
#

i've never heard about this too

#

are you sure you haven't downloaded some kind of trojan virus?

cinder thistle
#

bruh

mortal hare
#

i use amazon coretto

cinder thistle
#

why does everybody assume that when something doesn't work it's immediately a virus

#

why not just use adoptopenjdk smh

mortal hare
#

because first signs of RAT or trojan is to hide itself

#

because the download speeds of adoptjdk were slow

#

when i downloaded it

cinder thistle
#

bruh

#

download from a mirror

left swift
#

How can i make nametag prefix? I tried with scoreboard teams, but when i make prefix type "&cPREFIX " so the player's name is still white

mortal hare
#

it was like 3kbps

#

for 100-200 mb package

cinder thistle
#

y'all aren't that patient?

#

I had to put up with that for years

novel lodge
#

How could I make something run every few seconds?

cinder thistle
#

BukkitRunnable

left swift
mortal hare
# novel lodge How could I make something run every few seconds?
BukkitWiki

This tutorial will guide you in using the scheduler provided by bukkit. It will allow you to defer the execution of code to a later time. This is not the same as registering a Listener, a block of code which is executed in response to an event in the game. Blocks of code may also be scheduled to be executed repeatedly at a fixed interval, with o...

tribal holly
#

is there any way to set only 1 heart of absorption ? (the potion effect is minimum 4 hearts) ?

quiet ice
#

well, damage the player

tribal holly
mortal hare
#

or send the packet

quiet ice
#

good point

tribal holly
mortal hare
#

#player.setHealthScale​(double scale)

tribal holly
#

hoooo

mortal hare
#

this will scale your health bar

tribal holly
#

well okay but i wanna have the visual effect of the absorption

mortal hare
#

more hearts or less hearts

cinder thistle
#

4 = 2 hearts

#

2 = 1 heart

tribal holly
mortal hare
tribal holly
mortal hare
#

in ealier days of minecraft you could've glitched the minecraft client in to removing the health bar

#

miss that glitch so much

#

i think you couldn't set it normal hearts to the absorption ones if you're talking about it

#

you can set it to wither ones or hardcore ones tho

#

if you're talking one absportion heart above the normal hearts then yes you can

#

but im not sure if spigot api allows it

#

or you need to handle it yourself

#

im not an expert in spigot api

tribal holly
mortal hare
#

yes but im not sure, there could be a better way to do that

tribal holly
#

hmmm

mortal hare
#

and im pretty sure there is

quaint mantle
#

I have my antivirus run 24/7

mortal hare
#

found it

tribal holly
#

well

quaint mantle
#

and btw, restarting doesn't fix it

tribal holly
#

what an ass hole i am

mortal hare
#

#DamageableEntity.setAbsorptionAmount(double amount)

vague mason
#

What Absorption means?

mortal hare
#

that yellow hearts

#

above the normal ones

vague mason
#

Thanks

mortal hare
#

its a potion effect

tribal holly
mortal hare
#

np

quaint mantle
#

yo I fixed it

#

one of powerranks's ymls was corrupted

#

thanks dovidas for the help : )

novel lodge
#

How can I send an actionbar to somebody

mortal hare
mortal hare
lost matrix
mortal hare
#

oh

#

how strange it looks

#

but at the same time correct

#

Message can be sent via action bar, title, subtitle, chat

lost matrix
#

So for example

    Player player = ...;
    BaseComponent[] components = new ComponentBuilder().append("Some text").create();
    player.spigot().sendMessage(ChatMessageType.ACTION_BAR, components);
mortal hare
#

so its better to group them i guess

novel lodge
#

Ty

mortal hare
#

Whoever thought of that component api integration, hands down

#

But enum name shouldn't be ChatMessageType

#

Chat is the type of message

#

in this case

#

name makes no sense

#

but i guess this was left out because of bungeecord component api

#

before it was integrated with other types of messages

rugged topaz
#
    public String getTexture(final UUID u) {
        URL urlUUID = null;

        try {
            urlUUID = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + u + "?unsigned=false");
        } catch (MalformedURLException ignored) {
        }

        try {
            InputStreamReader reader = new InputStreamReader(urlUUID.openStream());
            JsonObject json = new JsonParser().parse(reader).getAsJsonObject().get("properties").getAsJsonArray().get(0).getAsJsonObject();
            return json.get("value").getAsString();
        } catch (IOException e) {
            return null;
        }
    }

need a method that doesn't kill tps 😬

earnest junco
earnest junco
quaint mantle
#

Hi, I have this code:

List<ItemStack> drops = event.getDrops();
        
String items = drops.stream()
           .map(it -> String.format("%d %s",it.getAmount(),it.getType()))
           .collect(Collectors.joining(", "));
``` that prints me this: `1 IRON_SHOVEL`

And I want to print me this: `:iron_shovel: x1`

How can I do that?
rugged topaz
eternal night
#

just change your format and lowercase the get type ?

rugged topaz
#

such as passing the result string type as the texture of an item

#

i'm not sure how to incorporate .thenAccept in there

earnest junco
#

Be careful though, you're not on the main thread in #thenAccept, so you might need to call some API through BukkitScheduler#runTask.

eternal night
gritty mist
#

can i turn a string into an integer

#

?

rugged topaz
# earnest junco ```java CompletableFuture.supplyAsync(() -> { // ... web request return ...
    gui.setItem(13, getTexture(visiting.getUniqueId()).thenAccept(texture -> {
        createSkull(texture, 1, "&avisit", "&7Player: " + inst.getRankedName(visiting));
    }));

    public CompletableFuture<String> getTexture(final UUID u) {
        CompletableFuture<String> result = new CompletableFuture<>();
        try {
            InputStreamReader reader = new InputStreamReader(new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + u + "?unsigned=false").openStream());
            JsonObject json = new JsonParser().parse(reader).getAsJsonObject().get("properties").getAsJsonArray().get(0).getAsJsonObject();
            result.complete(json.get("value").getAsString());
        } catch (IOException e) {
            result.completeExceptionally(e);
        }
        return result;
    }

look right?

#

cause apparently i'm doing something wrong with the first line (:

eternal night
#

but your getTexture method is still on the main thread

#

why use a completable future then

rugged topaz
#

i'll async

#

mb

#

needa fix this error tho

eternal night
#

Well gui is an Inventory I am guessing ?

rugged topaz
#

yes

eternal night
#

it expects an ItemStack not a CompletableFuture<ItemStack>

#

so you will have to either CompletableFuture#join

#

which holds the thread you call this on until the future resolves

rugged topaz
#

sounds like we're not doing that

eternal night
#

Yeah xD

#

tho joining would kinda defeat the purpose

#

because then you could just run all of this on the same thread anyway

#

so I guess you would more do a

#
getTexture(...).thenApply(texture -> createSkull(...)).thenAccept(skullStack -> gui.setItem(13, skullStack))
winged mica
#

try calling that with somehting like this

earnest junco
winged mica
#

this.runTaskTimer(getTexture, 0, 20L);

#

it lauches a new thread

eternal night
winged mica
#

and doesn't block the main one

eternal night
#

but yeah you could just do a single thenAccept

#

¯_(ツ)_/¯

novel lodge
#

Is there a way I could stop a projectile from damaging a specific plaer

mortal hare
#

paperspigot

#

onProjectileCollide event on paper

opal sluice
#

Hi, is there an event triggered by the usage of the crafting recipe ?

gritty mist
#
        if(!(sender instanceof Player)){
            return false;
        }
        Player player = (Player) sender;
        if(args.length == 1){
            try{
                String argsValue = args[0];
                float FlySpeed = Float.parseFloat(argsValue);
                player.setFlySpeed(FlySpeed);
            }catch (Exception e){
                player.sendMessage(ChatColor.RED + "Please use a float value !");
            }
        }

        return true;
    }```
this is supposed to change the flyspeed to the input value but somehow it throws an error each time
mortal hare
#

Don't catch exception in abstract Exception form

gritty mist
mortal hare
#

it can lead to bad both in bad code reading quality and some problems, like when threads fails

#

etc

gritty mist
#

ok is there a way i can verify if the input value is a float ?

mortal hare
#

you're already doing it .

#

try using #String.trim()

#

wait

#

nvm

#

yes

prime nimbus
#
public class main extends JavaPlugin {
    private World world;

    @Override
    public void onEnable() {
        World delete = Bukkit.getWorld("world_the_end");
        File deleteFolder = delete.getWorldFolder();
        World unload = Bukkit.getWorld("world_the_end");
        unloadWorld(unload);
        deleteWorld(deleteFolder);

    }

    @Override
    public void onDisable() {

    }

    public void unloadWorld(World world) {
        this.world = Bukkit.getWorld("");
        if(!world.equals(null)) {
            Bukkit.getServer().unloadWorld(world, true);
        }
    }

    public boolean deleteWorld(File path) {
        if(path.exists()) {
            File files[] = path.listFiles();
            for(int i=0; i<files.length; i++) {
                if(files[i].isDirectory()) {
                    deleteWorld(files[i]);
                } else {
                    files[i].delete();
                }
            }
        }
        return(path.delete());
    }
}

it deletes the end every time the server starts up, but it dosent create it again so i tried setting the plugin to run before the world was loaded but since the location of the world is received only after the world it loaded, it dosnet work, so it there any way to hardcode the location of then end dimension or recreate the world after it has been deleted

mortal hare
#

try using #String.trim()

#

for an argument

#

and see if it works

#

wdym by location of world

#

folder path location? @prime nimbus

prime nimbus
#

yes

gritty mist
#
            try{
                String argsValue = args[0].trim();
                float FlySpeed = Float.parseFloat(argsValue);
                player.setFlySpeed(FlySpeed);
            }catch (Exception e){
                player.sendMessage(ChatColor.RED + "Please use a float value !");
            }
        }```
like that ?
mortal hare
#

yes

mortal hare
# prime nimbus yes

well you can use plugin's data folder path location and traverse it back two folders to get root location of your minecraft server folder

prime nimbus
#

im not sure on how to do that

gritty mist
#

it stills throws an error

prime nimbus
#

sorry im pretty new to java

mortal hare
#

File endFolderLoc = new File(#Plugin.getDataFolder().getParentFile().getParentFile(), "world_the_end")

wet breach
#

if you are that new that you don't know basic Java API stuff, then you probably should be learning more about said API that is part of the language you want to learn.

mortal hare
prime nimbus
#

oh okay, ill try it

gritty mist
mortal hare
#

try adding f to the back

torn oyster
#

why is this happening (bungeecord)

#

this is a tabexecutor thingy

#

but when i try typing "un"

mortal hare
#

or try using Float.valueOf() instead

torn oyster
#

it doesnt recommend unsponsored

mortal hare
#

@gritty mist

gritty mist
#

still doesnt work

mortal hare
torn oyster
#

wdym

mortal hare
#

or maybe you send the tab completion every letter?

torn oyster
#

how do i do that

#

i have this in my command class

#
    @Override
    public Iterable<String> onTabComplete(CommandSender commandSender, String[] args) {
        List<String> names = new ArrayList<>();

        for (String s : BanManager.getBanManager().config.getKeys()) {
            String name = BanManager.getBanManager().config.getString(s + ".name");
            names.add(name);
        }
        return names;
    }```
mortal hare
#

ik why

#

i think

torn oyster
#

this is my first time using tabexecutor/tabcomplete

mortal hare
#

Try saving the names in lowercase

torn oyster
#

so idk how to use it

mortal hare
#

i think its casesensitive

torn oyster
#

nope

#

i tried that

#

i typed "Un"

#

instead

#

but it still doesnt work

mortal hare
#

that's strange

#

i've never had these kind of issues before

gritty mist
#

it doesnt work with the valueof to

#

unless I wrote it wrong

#

float FlySpeed = Float.valueOf(Float.parseFloat(argsValue));

mortal hare
#

you wrote it wrong

#

float flySpeed = Float.valueOf(argsValue);

gritty mist
#

lets try it

mortal hare
#

you don't need trim() in this case

gritty mist
#

ok

#

oh yeah it works im as fast as Flash McQueen

mortal hare
#

ParseFloat is raw type of valueOf(), it has more strict rules

#

that's why probs it didn't worked

gritty mist
#

so if i want to slow down a bit can I write ?
float flySpeed = Float.valueOf(argsValue)/10;

mortal hare
#

yes

#

since returned number from static method is float

gritty mist
#

bcz 10 is real fast

#

ok perfect

torn oyster
#

this is a tabexecutor thingy
but when i try typing "un"

#

it doesn't suggest "Unsponsored"
i have this in my command class

    @Override
    public Iterable<String> onTabComplete(CommandSender commandSender, String[] args) {
        List<String> names = new ArrayList<>();

        for (String s : BanManager.getBanManager().config.getKeys()) {
            String name = BanManager.getBanManager().config.getString(s + ".name");
            names.add(name);
        }
        return names;
    }```
mortal hare
#

Have you tried add random tab completion to it?

#

maybe bungeecord lacks this feature

#

and you would need to implement it yourself

#

with contains

#

idk

waxen plinth
#

That's also a pretty slow way of doing it - if you have a lot of bans, that will definitely cause lag on tab complete

#

What you want to do is keep a cached set/list of bans somewhere

#

And then when they're tab completed, you filter out ones that do not start with the partial string in the last argument passed

torn oyster
#

if (name.startsWith(args[0])) {
names.add(name);
}

#

would that work

waxen plinth
#

No

#

It would error if they haven't entered any args yet

mortal hare
lost matrix
mortal hare
#

Its a wrapper of SnakeYaml

#

still

#

the configuration is cached

#

there's no need to create new references to it

waxen plinth
#

Yeah he is literally fetching potentially hundreds/thousands of values from a hash map every time someone types a character

#

That's a bad idea

mortal hare
#

why? map's contains() method time complexity is O(1)

#

how is that different from hashset

#

which uses hashmap internally

waxen plinth
#

Because if you cache them in a set the elements are just in there and you can iterate them

#

Instead of fetching them all from a hash map

#

Like, yes, hash maps are efficient

#

But hashing is still an operation that takes much more time than native array access

#

Iterating a hash set is only marginally slower than iterating an array

mortal hare
#

well for putting this into list or primitive array your statement correct, but putting it in set is as not efficient as the hashmap

waxen plinth
#

More than just the runtime complexity of an algorithm matters

#

???

#

In a set it's already in there

#

What he's doing is literally going through and fetching each value from a hashmap, essentially

lost matrix
waxen plinth
#

Calling get on a hashmap to generate each element

#

That is significantly slower than just using an already-generated hashset

lost matrix
#

That for sure

waxen plinth
#

And an array/list can't provide that

#

This guy is getting a set of keys, presumably UUID keys, iterating it, and then for each key, fetching a value from a hashmap

mortal hare
#

so you're saying that everytime hashmap get an instruction to check if it contains the object it calculates all the hashcodes of the objects

#

that sound inefficient

waxen plinth
#

???

#

No what the fuck

#

He is getting the set of UUIDs as keys

#

(Strings, mind you)

#

Then generating a list of the banned players by iterating that list and getting each player's name from a hashmap

#

To generate a hash of each string it needs to iterate all the characters

opal sluice
#

Is there a way to cancel the autocraft of the crafting recipe book ?

waxen plinth
#

UUIDs are like 48 characters in length, right?

mortal hare
#

no im talking about hashset vs hashmap performance on contains()

waxen plinth
#

Bro

#

Oh my god

#

That's not what we're talking about

#

HashSet is backed by a HashMap

lost matrix
waxen plinth
#

That's not what I'm talking about

#

What I'm talking about is that his way of doing it requires hashing potentially hundreds to thousands of elements every time someone types a character

mortal hare
#

that's what i was talking about but i got confused because he started talking about runtime complexity

waxen plinth
#

Which is going to create a hell of a lot more issues than just iterating a cached HashSet of those same values already fetched

#

I'm not talking about the runtime complexity

#

They have the same runtime complexity but his way is still a lot slower because the O(1) operations are much more expensive

#

Just because it doesn't take more time with more elements doesn't mean it can't still be slow

mortal hare
#

i got it, i just got confused by your explanation, no worries

lost matrix
#

One could use a tree approach to calculate all the possible inputs beforehand 😄

waxen plinth
#

This is true

#

A prefix tree would be a very elegant solution

lost matrix
#

So
u
un
und
unde
...
all point to
undermined and undetermined

#

With depth first traversing and early escaping this would be quite efficient. O(log n)

waxen plinth
#

Yeah you could just get the node for the current partial string

#

And then iterate the subtree to get the completions

#

You could technically have an O(1) solution but it would be pretty memory intensive

#

Storing a list of possible completions at each node

lost matrix
#

Yeah XD

waxen plinth
#

O(log n) is perfectly acceptable here

#

Hm..

#

It's O(n) for the base case

#

When they haven't typed any characters yet

#

Then again it's O(n) no matter what you do

#

Because it has to serialize and send the completions

mortal hare
#

well i have command node system which acts like it, by iterating the nodes

#

eh its not the best one

#

but fits well for me

#

brigadier is still better

tough zephyr
#

Is it possible to transition the worldborder by position rather then size? Like on warzone how the border moves

quaint mantle
#

Call of Duty in Minecraft!

tough zephyr
#

Pretty much the goal, yes

quaint mantle
#

Hunger Games Battle Royale

#

shit

#

is it survival or hunger games

tough zephyr
#

Hungergames sort of

#

Setting the center wont transition though. Damn shame

#

Only the size allows for a transition

quaint mantle
#

why not use a task

tough zephyr
#

Not SMOOTH enough

quaint mantle
#

too damn picky

tough zephyr
#

The transition effect looks really nice

lost matrix
safe granite
#

Hello,

quaint mantle
safe granite
#

im currently making a plugin to change skin texture of a player

tough zephyr
#

@lost matrix Are you MOVING the border's center?

#

I mean like MIGRATE the border to another center

#

Not the size

lost matrix
lost matrix
tough zephyr
#

Very cool, I'll give it a go

safe granite
#

@lost matrix yes that im doing

#

and its works well

#

but idk what the best way to reload skin view for other player

#

simply hide and show ?

#

and for a self view

quaint mantle
#

teleport to other world and come back if you want it to be simple

lost matrix
safe granite
#

respawning looks a better way

lost matrix
#

I dont think there is a better way.

  1. Change the GameProfile using nms or reflections
  2. Respawn the player using spigot API
safe granite
#

is nms better than reflections

#

or just different way

#

im doing it with nms right now

lost matrix
#

nms makes your plugin only viable for one exact version.
Using reflections might make it compatible with multiple ones.
You can also use a multi module setup to write the same code for each version and implement an interface that is used in your plugin.

#

But reflections are risky and will be slower if you dont cache them

safe granite
#

okok ty for your explanation

#

I will look more details on the internet

#

ive tried with player.spigot().respawn();

#

but it looks to doing nothing

sullen marlin
#

that method respawns a dead player

#

not whatever youre doing

safe granite
#

so how cand i o pls ?

#

its works pretty well when im teleporting a player to another dimension then tp him back to his original position

#

but it dont looks like clean to do it like that

quaint mantle
#

What’s the difference between a hash set and arraylist? In terms of the data it stores?

tough zephyr
#

@quaint mantle HashSet = wrapper for HashMap. So O(1) gets/puts/removes

#

Arraylist is a wrapper for an array. So just a generic list

quaint mantle
#

Alright cheers

tough zephyr
#

If you're just iterating the data, use an arraylist. Otherwise, a hashset

quaint mantle
#

Cheers

ashen flicker
#

Is there a way to have a chat click that runs code rather than just a command?

dusty herald
#

🤷 why not have a command that runs code

ashen flicker
#

I'd just prefer not to register a command if I can avoid it

lost matrix
ashen flicker
#

So like, I could make an api for it that does it or something maybe? I'd need an interface I think

lost matrix
#

Using one of the functional interfaces should suffice

ashen flicker
#

Like?

#

Are you saying making my own interface for it would be pointless

lost matrix
#

Map<String, Consumer<Player>>

ashen flicker
#

Ah okay, I've not actually used Consumer before but let me look at it, probably is what I need

stone sinew
ashen flicker
#

Well I'm gonna probably do that anyways, but I need to register the command. Which is fine. Why would I need to use Consumer actually @lost matrix? I just need to run code, couldn't I use like Runnable or something?

drowsy helm
#

consumables run code

#

Consumeable<int> myConsumable = i -> { //do stuff};

stone sinew
lost matrix
ashen flicker
#

Okay awesome thx

dusty herald
#

I haven't put must testing into PlayerPreProcessCommandEvent but is it possible to have tab completions?

tawdry rampart
#

Hey, how would I access for example the playerList string from the Bungee plugin message in other places around my plugin?
I have the actual thing done that gets the player list and then the subchannel listener, but just unsure on how to get that string..

lost matrix
lost matrix
dusty herald
#

what is your username

#

that's an amazing username lmao

ashen flicker
#

Yea I mean as long as that's per user and not just 1 click over all that's probably fine

eternal night
#

iconic username

woeful moon
#

Hello. Doing webhook programming right now. Everything works well, one question though: For setting the image/thumbnail, you need a String (a url to the image). Which image hosting website do you guys suggest?

lost matrix
tawdry rampart
lost matrix
ashen flicker
#

Ah I see how it works

tawdry rampart
tawdry rampart
#

Alright

unreal finch
#

Would anyone know why setSitting() wouldnt be working for me? I’ve confirmed that the code works entirely and there are no errors whatsoever. The wolf in question just wont stand up

lost matrix
tawdry rampart
lost matrix
#

But at second glance this looks quite complicated... Non linear programs can get confusing quite fast.

lost matrix
tawdry rampart
glossy dirge
#

hello

#

whats going on with spigot api

#

i got this error

#

Could not find spigot-api-1.16.5-R0.1-SNAPSHOT.jar (org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT:20210411.223231-46). Searched in the following locations: https://hub.spigotmc.org/nexus/content/repositories/snapshots/org/spigotmc/spigot-api/1.16.5-R0.1-SNAPSHOT/spigot-api-1.16.5-R0.1-20210411.223231-46.jar

lost matrix
#

Are you using maven?

glossy dirge
#

im using gradle

lost matrix
#

First of all the scope should be compileOnly instead of implementation

glossy dirge
#

still the same

lost matrix
#

Then you need to include the sonatype repositories

  maven { url = 'https://oss.sonatype.org/content/repositories/snapshots' }
  maven { url = 'https://oss.sonatype.org/content/repositories/central' }
glossy dirge
#

still the same

lost matrix
#

No idea then... run BuildTools once on your machine

glossy dirge
#

its working now

#

when i try to change the spigot api version

lost matrix
#

Ok nice

glossy dirge
#

but

#

how do i use the latest spigot api

#

1.16.5

lost matrix
#

No idea then... run BuildTools once on your machine

glossy dirge
#

where is BuildTools ?

lost matrix
#

?bt

queen dragonBOT
hushed crescent
#

'registerEvents(org.bukkit.event.Listener, org.bukkit.plugin.Plugin)' in 'org.bukkit.plugin.PluginManager' cannot be applied to '(com.synth.tns.PlantSapling.EventsClass)'

#

Whata does this mean?

lost matrix
#

Does EventsClass implement Listener?

hushed crescent
#
public class PlantSapling implements Listener {

    public void createBoard(Player player) {
        ScoreboardManager manager = Bukkit.getScoreboardManager();
        Scoreboard board = manager.getNewScoreboard();
        Objective obj = board.registerNewObjective("Saplings", "", "Saplings Placed");
        obj.setDisplaySlot(DisplaySlot.SIDEBAR);
    }

    public static class EventsClass implements Listener {
        private final Map<UUID, Integer> saplingMap;

        public EventsClass() {
            this.saplingMap = new HashMap<>();
        }

        @EventHandler
        public void onPlayerPlantSapling(BlockPlaceEvent e) {
            if (e.getBlockPlaced().getType().toString().endsWith("SAPLING")) {
                if (this.saplingMap.containsKey(e.getPlayer().getUniqueId())) {
                    int placed = this.saplingMap.get(e.getPlayer().getUniqueId()) + 1;
                    this.saplingMap.remove(e.getPlayer().getUniqueId());
                    this.saplingMap.put(e.getPlayer().getUniqueId(), placed);
                    System.out.println(this.saplingMap);
                    System.out.println(e.getPlayer() + " placed a sapling");
                } else {
                    this.saplingMap.put(e.getPlayer().getUniqueId(), 1);
                }
            }
        }
    }

}```
lost matrix
#

What spigot version?

#

And why the heck do you need an inner class for this?

hushed crescent
#

.

#

Maybe I am overly object oriented

#

😆

hushed crescent
glossy dirge
hushed crescent
#

I created a spigot project with a plugin in intellij

#

"Minecraft Integration"

lost matrix
hushed crescent
#

Yeah I removed the inner class.

lost matrix
#

Pls show how you register the event

quaint mantle
#

@lost matrix are you in germany

hushed crescent
#
public final class TNS extends JavaPlugin {

    @Override
    public void onEnable() {
        System.out.println("Wassup");
        getServer().getPluginManager().registerEvents(new PlantSapling);
    }

    @Override
    public void onDisable() {
        // Plugin shutdown logic
    }
}```
quaint mantle
#

well thats not java

#

well thats not spigot

hushed crescent
#

...

lost matrix
#

so new PlantSapling() in your case

hushed crescent
#

Yeah, I fixed it.

#

Still getting the same error though.

eternal night
#

Also you'll need to provide the plugin instance

hushed crescent
eternal night
#

So new PlantSaplling(), this

hushed crescent
#

Oh

eternal night
#

This being the reference to the current instance of your TNS class

hushed crescent
#

That fixed everything

#

Well, thank you haha

eternal night
#

Hope you understood why that fixed it 😅

hushed crescent
#

Why did I need to reference my TNS Class?

#

May I ask what those do?

eternal night
#

Spigot basically wants to know what plugin is registering the listener here. So besides providing your listener instance (new PlantSappling()) you also need to provide your instance of the Plugin interface which is, when executing from onEnable just this

lost matrix
# glossy dirge where is BuildTools ?

Just tested a clean gradle project. Works fine.
Make sure to add at least those repos:

repositories {
    mavenCentral()
    maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
    maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
    maven { url 'https://hub.spigotmc.org/nexus/content/repositories/snapshots/' }
}

And this dependency

dependencies {
    ...
    compileOnly 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT'
}
hushed crescent
#

They are already added btw

#

inside a pom.xml

#

Not sure what that is

#

Is that like a package.json but for java?

eternal night
#

I think this is for someone else

#

XD

hushed crescent
#

Oh

quaint mantle
#

hello how would i add the string? getConfig().addDefault("message"); I have to do something... i just am not sure what

lost matrix
quaint mantle
#

im trying to have a onjoin message taht u can change

#

and i tried manually making the config with creating a file but it didn't work

lost matrix
#

Ok so there are two approaches for default configurations.

  1. You just write and put a config.yml in your plugin and then save it when the server starts
  2. You generate a config.yml from code when the server starts

Which one do you prefer?

quaint mantle
#

I tried the first one but that doesn't work for me and now im trying to do the second one

glossy dirge
#

but when i created a clean project its working

lost matrix
lost matrix
quaint mantle
#

I have tried that but it doesn't work

lost matrix
quaint mantle
#

I'll again thought thanks!

#

tysm :)

lost matrix
quaint mantle
#

spigot api

lost matrix
#

Ok so you manually add the spigot api i suppose.
Then go to your src folder and create a new file.
Name it however you want. So messages.yml should suffice.

#

Content should look similar to this:

messages:
  on-join-message: "This is a default message."
quaint mantle
#

ok

glossy dirge
quaint mantle
#

player.sendMessage(getConfig().getString("on-join-message"));would it be that?

lost matrix
#

Then (just to be sure) compile your plugin and open the jar with a compession program like 7zip or winrar to see if the yml is actually in your final jar file.

quaint mantle
#

ok

lost matrix
#

Next you should export the file when your plugin starts.

  @Override
  public void onEnable() {
    setupFiles();
  }

  private void setupFiles() {
    this.getDataFolder().mkdirs(); // Creates plugin folder
    this.saveResource("messages.yml", false); // Saves the messages.yml if it doesnt exist
  }
#

create a method named setupFiles() where you handle all your io setup stuff.
Normally you would create a FileManager class that handles all that so your JavaPlugin class doesnt get messy

quaint mantle
#

ok

lost matrix
#

If this is done. Compile your plugin and run it once with your server. You should then see a messages.yml file in your plugin folder

quaint mantle
#

ok thx

lost matrix
# quaint mantle ok thx
  private void setupFiles() {
    this.getDataFolder().mkdirs();
    this.saveResource("messages.yml", false);

    // Create a file variable. This is not the actual file on your hard drive but only a representation for Java to work with
    File messagesFile = new File(this.getDataFolder(), "messages.yml");

    // Load the content from that file into a FileConfiguration. This reads the whole file at once.
    FileConfiguration messagesConfig = YamlConfiguration.loadConfiguration(messagesFile);

    // Now you can access all the content using the methods from FileConfiguration
    String message = messagesConfig.getString("messages.on-join-message");
    
    // Print out the message we just got from our FileConfiguration
    this.getLogger().info(message);
  }
hushed crescent
#

Thank you @eternal night and @lost matrix! My first ever plugin works

#

I am so happy

#

Now I just need to find a way to parse the stuff onto a scoreboard

tawdry rampart
lost matrix
tawdry rampart
#

Yeah sure let me upload it to github or smtn

quaint mantle
quaint mantle
#

whatt

#

I see that it would print out the message but would I just put that in the event method?

lost matrix
# quaint mantle so what would I put in the onjoin event?

You first need to somehow gain access to the FileConfiguration you just created. For this you could create a field in your JavaPlugin class.
Then you need to pass the FileConfiguration in the construcor of your listener class like this:

public class SpigotCore extends JavaPlugin {

  private FileConfiguration messagesConfiguration;

  @Override
  public void onEnable() {
    this.setupFiles();
    
    JoinListener listener = new JoinListener(messagesConfiguration);
    Bukkit.getPluginManager().registerEvents(listener, this);
  }

  private void setupFiles() {
    this.getDataFolder().mkdirs();
    this.saveResource("messages.yml", false);
    File messagesFile = new File(this.getDataFolder(), "messages.yml");
    this.messagesConfiguration = YamlConfiguration.loadConfiguration(messagesFile);
  }

}

Or you create a getter method in your JavaPlugin class so you can get the FileConfiguration from other classes like this:

public class SpigotCore extends JavaPlugin implements Listener {

  private FileConfiguration messagesConfiguration;

  @Override
  public void onEnable() {
    this.setupFiles();

    JoinListener listener = new JoinListener(this);
    Bukkit.getPluginManager().registerEvents(listener, this);
  }

  private void setupFiles() {
    this.getDataFolder().mkdirs();
    this.saveResource("messages.yml", false);
    File messagesFile = new File(this.getDataFolder(), "messages.yml");
    this.messagesConfiguration = YamlConfiguration.loadConfiguration(messagesFile);
  }

  public FileConfiguration getMessages() {
    return this.messagesConfiguration;
  }

}
quaint mantle
#

ok thanks

lost matrix
tawdry rampart
lost matrix
lost matrix
tawdry rampart
tawdry rampart
#

Oh I'm a dumbass

#

Still had .toString() in the consumer thing, now that I've changed String[] to just String

lost matrix
lost matrix
tawdry rampart
lost matrix
#

All good

tawdry rampart
#

Alright! Sends the message with all players, also removed it making a new one, thanks for putting up with me lmao

south onyx
#

i have a question, its not about spigot, but its about plain java

#

is an initilized string with nothing in it null?

stone sinew
#

No

south onyx
#

ok

#

thx

stone sinew
#

String string = null; is null...
String string = ""; is not null.

south onyx
#

ok

#

thx

stone sinew
#

np

drowsy helm
#

String string; is null

south onyx
#

will this work?

lost matrix
#

yes

south onyx
lost matrix
#

da fk is this

south onyx
#

basically what i want to do is remove a uuid from a list called stalkers

drowsy helm
#

what bit am i looking at

south onyx
#

wait one sec

#

i will explain everything

#

do u see the string builder?

drowsy helm
#

Bukkit.getOnlinePlayers().toString().contains(args[i])

#

yes

south onyx
#

no wait

#

this part

#
if (invalidPlayers.toString() != null && alreadyStalker != null) {
                            player.sendMessage(ChatColor.GREEN + "Removed players that were listed, except " + alreadyStalker.toString() + ",because these players are already not stalkers, and also except " + invalidPlayers.toString() + "because these players are invalid!");
                        } else if (invalidPlayers.toString() != null && alreadyStalker == null) {
                            player.sendMessage(ChatColor.GREEN + "Removed players that were listed, except" + invalidPlayers.toString() + ",because these players are invalid!");
                        } else if (alreadyStalker.toString() != null && invalidPlayers.toString() == null) {
                            player.sendMessage(ChatColor.GREEN + "Removed players that were listed, except" + alreadyStalker.toString() + ",because these players are already not stalkers!");
                        } else {
                            player.sendMessage(ChatColor.GREEN + "Removed all players successfully!");
                        }
#

idk why it pasted like that

drowsy helm
#

right

south onyx
#

lemme try again

lost matrix
#

Because you dont respect the character limit

south onyx
#
if (invalidPlayers.toString() != null && alreadyStalker != null) {
                            player.sendMessage(ChatColor.GREEN + "Removed players that were listed, except " + alreadyStalker.toString() + ",because these players are already not stalkers, and also except " + invalidPlayers.toString() + "because these players are invalid!");
                        } else if (invalidPlayers.toString() != null && alreadyStalker == null) {
                            player.sendMessage(ChatColor.GREEN + "Removed players that were listed, except" + invalidPlayers.toString() + ",because these players are invalid!");
                        } else if (alreadyStalker.toString() != null && invalidPlayers.toString() == null) {
                            player.sendMessage(ChatColor.GREEN + "Removed players that were listed, except" + alreadyStalker.toString() + ",because these players are already not stalkers!");
                        } else {
                            player.sendMessage(ChatColor.GREEN + "Removed all players successfully!");
                        }
#

o

#

ok anyways

lost matrix
#

If this happens then you need to overthink your design.

south onyx
#

ok

drowsy helm
#

also please change that if statement with getOnlinePlayers()

south onyx
#

ok

rugged topaz
#
    @EventHandler
    public void onTryShoot(EntityShootBowEvent e) {
        if (e.getEntity() instanceof Player) {
            Player p = (Player) e.getEntity();
            e.setCancelled(true);
        }
    }

this takes arrows out of the player's inventory, now instead of just adding an arrow back into it, how do i fix this efficiently?

rugged topaz
#

thanks

lost matrix
rugged topaz
#

i'll search and find for my entire project (:

lost matrix
#

Also p -> player

rugged topaz
#
    private void doBlockEater(final Player player, final Block startingBlock, final int amount) {
        if (startingBlock.getType() == Material.AIR) return;

        final Material targetMaterial = startingBlock.getType();
        final ItemStack item = new ItemStack(targetMaterial, 1);
        final ArrayList<Block> blocksToCheck = new ArrayList<>();

        blocksToCheck.add(startingBlock);

        Bukkit.getScheduler().runTaskAsynchronously(getInstance(), () -> {
            while (!blocksToCheck.isEmpty()) {
                int blocksToRemove = 0;
                final Block block = blocksToCheck.get(0);
                blocksToCheck.remove(block);
                if (block.getType() == targetMaterial) {
                    for (final BlockFace blockFace : faces) {
                        blocksToCheck.add(block.getRelative(blockFace));
                    }

                    if (block.getType().name().contains("LOG")) {
                        player.getInventory().addItem(item);
                        block.getWorld().playSound(block.getLocation(), Sound.DIG_WOOD, 0.3F, 2.0F);
                        Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(getInstance(), () -> block.setType(Material.AIR), 3);
                    }
                    blocksToRemove++;
                }
                if (blocksToRemove >= amount) blocksToCheck.clear();
            }
        });
    }

what is effectively wrong with this method of cutting down an entire tree but with an interval of 3 ticks per second of producing an animation of breaking the log block

#

considering, it used to work better on my old slower system then i upgraded, and it's worse. but even before, it would give me way too many logs filling up my entire inventory after around 20 blocks broken

sudden raft
#

You're scheduling the removal of all the blocks 3 seconds later

#

I think u want to schedule the removal 3 seconds after the previous removal

rugged topaz
#

yeah

#

but that wouldn't even answer for the reason why my inventory fills up completely and my ears are bloated with emotion

#

only from 10 blocks worth of logs

sudden raft
#

Also, you should use a Queue

#

instead of a list

rugged topaz
#

for the blocksToCheck?

cerulean harbor
#

hi y'all, im completely new to plugin making so excuse the basic question.

so far i have a working command '/power [target]', but right now it's empty and just sends a message to the player. what I want the command to do is store the target player's UUID in an arraylist somewhere that persists through server resets. how would you guys go about this?

rugged topaz
#

through server resets?

cerulean harbor
#

restarts

rugged topaz
#

yes ik

#

but

sudden raft
#
Queue<Block> blocks = new LinkedList<>();
blocks.add(startingBlock);

int count = 0;
while (!blocks.isEmpty() && count++ < maxRemovedBlocks) {
  Block block = blocks.remove();
   if (block is target) {
         // ... same code you have
   }
    if (is log) {
     
        runLater(plugin, () -> {
              // add item and remove block
        }, count * 60);
    }
}```
sudden raft
rugged topaz
#

arraylists are tied to memory, and memory is reset after /rl, /restart, /stop, the process ceasing to exist blah

#

you can write it to a file

sudden raft
#

Lemme see the javadocs because i dont remember the method names

rugged topaz
#

and parse that onEnable()

#

this'll help you

cerulean harbor
#

ah

#

thank you

#

seems like exactly what I need

rugged topaz
#

yessuh

cerulean harbor
#

@rugged topaz would i just be putting this in my main class? does it matter where?

sudden raft
#

what is lyk

rugged topaz
#

let you know

sudden raft
#

ah

rugged topaz
#

and if your main class is called Main, Plugin, consider changing it (:

cerulean harbor
#

i was told that naming it main was standard? is there a specific reason

rugged topaz
#

ambiguity

#

and that's not true

#

just call it the name of your plugin

#
    private void doBlockEater(final Player player, final Block startingBlock, final int amount) {
        if (startingBlock.getType() == Material.AIR) return;

        final Material targetMaterial = startingBlock.getType();
        final ItemStack item = new ItemStack(targetMaterial, 1);
        final Queue<Block> blocks = new LinkedList<>();
        blocks.add(startingBlock);

        Bukkit.getScheduler().runTaskAsynchronously(getInstance(), () -> {
            int count = 0;
            while (!blocks.isEmpty() && count++ < amount) {
                Block block = blocks.remove();
                if (block.getType() == targetMaterial) {
                    for (final BlockFace blockFace : faces) {
                        blocks.add(block.getRelative(blockFace));
                    }
                    count++;
                }

                if (block.getType().name().contains("LOG")) {
                    Bukkit.getScheduler().runTaskLaterAsynchronously(getInstance(), () -> {
                        player.getInventory().addItem(item);
                        block.getWorld().playSound(block.getLocation(), Sound.DIG_WOOD, 0.3F, 2.0F);
                        player.playSound(player.getLocation(), Sound.SUCCESSFUL_HIT, 1.0F, 1.8F);
                        givePlayerForagingXP(player);
                        block.setType(Material.AIR);
                    }, 1 * 60);
                }
            }
        });
    }

@sudden raft

#

how's this

dusty herald
cerulean harbor
#

i see

#

thank you

sudden raft
#

It's already done in the while(...)

rugged topaz
#

whoops

sudden raft
#

Also it's not necessary to run everything asynchronosuly

dusty herald
#

it's not possible to run everything async ;)

#
Bukkit.getScheduler().runTaskLaterAsynchronously(getInstance(), () -> {
                        player.getInventory().addItem(item);
                        block.getWorld().playSound(block.getLocation(), Sound.DIG_WOOD, 0.3F, 2.0F);
                        player.playSound(player.getLocation(), Sound.SUCCESSFUL_HIT, 1.0F, 1.8F);
                        givePlayerForagingXP(player);
                        block.setType(Material.AIR);``` *psst* You shouldn't be messing with the Bukkit API async, this code won't even work
rugged topaz
#

so just

dusty herald
#

you're trying to modify the world async

rugged topaz
#

oo oohoohh

dusty herald
#

pretty sure you can't even play sounds async either

rugged topaz
#

i mean

#

it works

#

it's just terrible

dusty herald
#

it shouldn't work

rugged topaz
#

if you read above, it literally spams my inventory and ears

#

nah it worked

sudden raft
#

i dont remember the class name hahaha

dusty herald
#

🤷 never tried it

#

I don't like using async that much, I run everything on the main thread, even Thread.sleep /s

sudden raft
#

🤨

rugged topaz
#

welp

#

what to do

dusty herald
#

try running it sync

rugged topaz
sudden raft
#

use runTaskLater instead of runTaskLaterAsynchronously

#

It shouldnt cause lag

rugged topaz
#

or the first

sudden raft
#

the nested

rugged topaz
#
    private void doBlockEater(final Player player, final Block startingBlock, final int amount) {
        if (startingBlock.getType() == Material.AIR) return;

        final Material targetMaterial = startingBlock.getType();
        final ItemStack item = new ItemStack(targetMaterial, 1);
        final Queue<Block> blocks = new LinkedList<>();
        blocks.add(startingBlock);

        Bukkit.getScheduler().runTaskAsynchronously(getInstance(), () -> {
            int count = 0;
            while (!blocks.isEmpty() && count++ < amount) {
                Block block = blocks.remove();
                if (block.getType() == targetMaterial) {
                    for (final BlockFace blockFace : faces) {
                        blocks.add(block.getRelative(blockFace));
                    }
                }

                if (block.getType().name().contains("LOG")) {
                    Bukkit.getScheduler().runTaskLater(getInstance(), () -> {
                        player.getInventory().addItem(item);
                        block.getWorld().playSound(block.getLocation(), Sound.DIG_WOOD, 0.3F, 2.0F);
                        player.playSound(player.getLocation(), Sound.SUCCESSFUL_HIT, 1.0F, 1.8F);
                        givePlayerForagingXP(player);
                        block.setType(Material.AIR);
                    }, amount * 40L); // count * 2 seconds interval
                }
            }
        });
    }

current code

#

still async huh

summer scroll
#

it's not

rugged topaz
#

haha

#

for some reason, it only breaks 1 block tho

#

oh and now

#

almost a minute later

#

it's working in pairs of 2 blocks every 2 seconds

#

almost what it's meant to? but completely broken nonetheless

sudden raft
#

hmm

#

Oh

#

Youre using the amount variable

#

You should use the count

#

For the delay

rugged topaz
#

oh frick

#

the timing's heavily inaccurate

#

idk why we're multiplying count by 2 seconds

#

if it's meant to be at a 2 second interval per block

#

or even, 4 ticks

drowsy helm
#

there any methods for getting ping without using nms?

sudden raft
#

i dont think so

sudden raft
#

so, first block waits 2 seconds to be removed, the next waits 4, and so on

rugged topaz
#
Bukkit.getScheduler().runTaskLater(getInstance(), () -> {
     block.setType(Material.AIR);
     player.getInventory().addItem(item);
     block.getWorld().playSound(block.getLocation(), Sound.DIG_WOOD, 0.3F, 2.0F);
     player.playSound(player.getLocation(), Sound.SUCCESSFUL_HIT, 1.0F, 1.8F);
     givePlayerForagingXP(player);
}, count * 1L); // count * 1 tick per block

fr some reason

#

this is just too slow

#

and i'm not sure if that's to do with the fact that it's sync

#

but probably

#

@sudden raft

sudden raft
#

slow?

rugged topaz
#

mhm

#

ikr idk

#

it shouldn't be count

#

but i'ma test it with just

#

1 tick

lost matrix
# rugged topaz ```java private void doBlockEater(final Player player, final Block startingB...

Try this thing

public class BlockEaterTask extends BukkitRunnable {

  private static final EnumSet<BlockFace> DETECTION_FACES = EnumSet.of(
      BlockFace.NORTH,
      BlockFace.SOUTH,
      BlockFace.EAST,
      BlockFace.WEST,
      BlockFace.UP,
      BlockFace.DOWN
  );

  private final int hardCheckLimit;
  private final Set<Block> checkedBlocks;
  private final Queue<Block> blockQueue;
  private final Predicate<Block> filter;
  private final Consumer<Block> action;

  public BlockEaterTask(final Block startBlock, final int hardLimit, final Consumer<Block> action, final Predicate<Block> blockFilter) {
    this.hardCheckLimit = hardLimit;
    this.checkedBlocks = new HashSet<>();
    this.checkedBlocks.add(startBlock);
    this.blockQueue = new ArrayDeque<>();
    this.filter = blockFilter;
    this.action = action;
  }

  @Override
  public void run() {
    if (this.blockQueue.isEmpty() || this.checkedBlocks.size() == this.hardCheckLimit) {
      this.cancel();
      return;
    }
    this.next();
  }

  private void next() {
    final Block nextBlock = this.blockQueue.poll();
    for (final BlockFace face : BlockEaterTask.DETECTION_FACES) {
      final Block surrounding = nextBlock.getRelative(face);
      if (this.checkedBlocks.contains(surrounding)) {
        continue;
      }
      this.checkedBlocks.add(surrounding);
      if (this.filter.test(surrounding)) {
        this.action.accept(surrounding);
        this.blockQueue.add(surrounding);
      }
    }
  }

}
quaint mantle
#

um does EntityDamageByEntityEvent give the kb that the player has recieved ?

rugged topaz
rugged topaz
# sudden raft slow?
while (!blocks.isEmpty() && count++ < amount) {
     Bukkit.broadcastMessage(count + "");

printing count immediately sends 35 messages (in my instance) from 0-35, so i'm pretty sure at that point count = 35, which is equal to the amount i pass in

sudden raft
#

Yes it's correct

rugged topaz
#

forsure?

rugged topaz
#

mhm ik

#

but idk why it'd immediately find its way to count = 35 whilst it hasn't broken a single block yet

#

ahh understand why now

#

but still undesired result :/

sudden raft
#

how are u calling the method?

rugged topaz
#

blockbreakevent, if the block is equal to type of log, if the player has the intended item in their hand, and if they're in the intended spot, doBlockEater(e.getPlayer(), e.getBlock(), 35)

#

should be nothing wrong

#

w that

sudden raft
#

Hmm

lost matrix
# rugged topaz i dunno how i'd use that tbh

Example:

  public void destroyStone(final Block startBlock, final JavaPlugin plugin) {
    final BlockEaterTask task = new BlockEaterTask(startBlock, 100, Block::breakNaturally, bl -> bl.getType().equals(Material.STONE));
    task.runTaskTimer(plugin, 1, 1);
  }
rugged topaz
#

i'll try it

sage swift
#

the block iterator

lost matrix
#

Dont remember ^^ but you are welcome 😄

sage swift
lost matrix
#

A i see ^^

onyx shale
#

wut is that a custom break animation?

#

nvm

#

its a block remover

rugged topaz
#

isn't blockQueue gonna be empty if it's initalized empty regardless?

lost matrix
#

Uhm. The first block should be inserted in the queue in the beginning.

rugged topaz
#

the starting block is added to checkedBlocks

lost matrix
#

Oh nvm. You need to add that in the constructor

rugged topaz
#

not blockQueue

#

add wha

#

starting block to the queue?

lost matrix
#
    this.blockQueue = new ArrayDeque<>();
    this.blockQueue.add(startBlock);
rugged topaz
#

yah

#

seems like it works fine

#

just the starting block isn't broken 😝

lost matrix
#

just

    if (blockFilter.test(startBlock)) {
      action.accept(startBlock);
    }

At the end of the constructor. idk

rugged topaz
#

that fixed it

#

but i needa perform multiple things at once,
is it possible to pass that in as a parameter instead of this final Consumer<Block> action?

#

rather not just cheat it into the actual class

#

like a lambda of code

lost matrix
#

Sure. This here would grow all the connected wheat to max age:

  public void growWheat(final Block startBlock, final JavaPlugin plugin) {
    final BlockEaterTask task = new BlockEaterTask(startBlock, 100, this::growBlock, this::isViableBlock);
    task.runTaskTimer(plugin, 1, 1);
  }

  private boolean isViableBlock(final Block block) {
    return block.getType() == Material.WHEAT;
  }

  private void growBlock(final Block block) {
    final BlockData data = block.getBlockData();
    if (data instanceof Ageable) {
      final Ageable ageable = (Ageable) data;
      ageable.setAge(ageable.getMaximumAge());
    }
    block.setBlockData(data);
  }
kind coral
#

how would i round up a number to a multiple of 9? i am making a InventoryLib

lost matrix
#

Wait...

lost matrix
#

Now it works...

#

Just not for 0

silk mirage
#

..

whole elbow
#

how to create custom achievement popups?

severe zenith
#

i dont understand exactly how to spcify the reciever player

quaint mantle
#

what are u trying to do?

severe zenith
#

understand plugin messaging

quaint mantle
#

yea i got it but i mean like are u trying to do (Connect, IP, IPother etc.)

severe zenith
#

nothing yet. i just want to know how it works

quaint mantle
#

u just send messages between spigot and proxy

severe zenith
#

yeah: for example Connect

quaint mantle
#

like connect u send player to server

#

lemme send u example

severe zenith
#

ok, the channel is "BungeeCord", the subchannel is "Connect", the argument is "", and the reciever is player???

#

@quaint mantle is this correct?

quaint mantle
#

yes

severe zenith
#

ok, thanks

quaint mantle
#

like you write into the argument something like i said for ex. Lobby, Auth

#

like name of server when u use Connect

wary harness
#

so it doesen't go back to 0 age

#

when it grows block above

median plank
#

Hello

#

Am newbie

#

Please I need a sample of spigot game

quaint mantle
#

sample of spigot game?

median plank
#

Yes sir

quaint mantle
#

wdym by that

median plank
#

Or anything on spigot

quaint mantle
#

you mean plugins?

median plank
#

Yes

quaint mantle
median plank
#

Did you made it

quaint mantle
#

no

#

this is all plugins that everybody made

quiet ice
median plank
#

Hey! I saw you were interested in our Java Project of working with the SpigotAPI.

This is a long-term project. We have a current open project of about one year of work. Here is the plugin we are currently working on:
https://docs.google.com/document/d/1wKi4Cr7dHou1JZFjqPwi2GBE-WLGEhF5XYXtWguYlXA/edit

This is also a well-paying and loyal position.
I have a few question, it is okay to be honest, as we are hiring several developers who are interested in this position long-term.

Do you have any experience with SpigotAPI?

Have you played Minecraft?

Could you learn the SpigotAPI?

Do you have experience working in gradle?

What interests you about this job and why do you want this project?

This is just to get an understanding so we can work better together! :D

#

That's is what am looking for

quiet ice
#

what

eternal oxide
#

?services

queen dragonBOT
quaint mantle
#

xd

quiet ice
#

There are multiple issues with your messages my man

quaint mantle
#

yeah like

#

Do you have any experience with SpigotAPI?

Could you learn the SpigotAPI?

#

?

quiet ice
quaint mantle
#

why would you apply for spigot developing when you dont know spigotapi

median plank
#

Am newbie

quiet ice
median plank
#

I want to start

quiet ice
#
  1. This is not how you hire people
quaint mantle
eternal oxide
quiet ice
#

Meh, that is a bad one

quaint mantle
#

well first of all if you dont know java u should learn it first before working with apis and stuff

quiet ice
#

Granted, it is outdated but it does a lot more right

eternal oxide
#

It looks decent

#

I link the other as it covers more IDEs and should be all anyone needs.

toxic mesa
#

Hi hi, i'm trying to get a config.yml file for bungeecord and I used this example https://www.spigotmc.org/threads/bungeecords-configuration-api.11214/
I get a null pointer error in this line: Files.copy(in, file.toPath());
full method:

    private void saveDefaultConfig() {
        if (!getDataFolder().exists())
            getDataFolder().mkdir();
        File file = new File(getDataFolder(), "config.yml");
        if (!file.exists()) {
            try (InputStream in = getResourceAsStream("config.yml")) {
                Files.copy(in, file.toPath());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

Full class (and yes, I know bungeecord already sends a startup message for the plugin)
https://pastebin.com/nwewHt4P

#

Can anyone explain what i'n doing wrong?

#

oh and the error

11:47:04 [WARNING] Exception encountered when loading plugin: UltimateStats
java.lang.NullPointerException
    at java.util.Objects.requireNonNull(Objects.java:203)
    at java.nio.file.Files.copy(Files.java:2984)
    at me.Michielo.UltimateStats.BungeeMain.saveDefaultConfig(BungeeMain.java:51)
    at me.Michielo.UltimateStats.BungeeMain.onEnable(BungeeMain.java:19)
    at net.md_5.bungee.api.plugin.PluginManager.enablePlugins(PluginManager.java:250)
    at net.md_5.bungee.BungeeCord.start(BungeeCord.java:285)
    at net.md_5.bungee.BungeeCordLauncher.main(BungeeCordLauncher.java:62)
    at net.md_5.bungee.Bootstrap.main(Bootstrap.java:15)
eternal oxide
#

BungeeMain.java:51

toxic mesa
eternal oxide
#

either in or file is null

toxic mesa
#

Alrighty ill mess around with it

eternal oxide
#

Why not just use the provided saveResource method?

#

ah Bungee

toxic mesa
#

yep

#

And #getResourceAsStream was indeed null, and i found this fourm post https://www.spigotmc.org/threads/getting-file-as-inputstream-within-the-jar.405681/
And tried what they said:

        this.getClass().getClassLoader();
    try (InputStream in = ClassLoader.getSystemResourceAsStream("config.yml")) {

however this still returns null

quiet ice
#

Use Java 15+ and you wouldn't be in here anyways

toxic mesa
#

o

quiet ice
#

The more descriptive Null Pointer Exception messages are really worth to get Java 15+

ivory sleet
#

Objects#requireNonNull(obj,str) 🤡

quiet ice
#

Why not use Plugin#getResourceAsStream?

#

Or whatever it is called

toxic mesa
#

I had that before, but it was null

#

So i googled and got that forum

eternal oxide
toxic mesa
#

yup

eternal oxide
#

thats not how you do it..sec

#

followed that?

toxic mesa
#

Jup

eternal oxide
#

If you have then you are missing the config.yml in your plugin jar

toxic mesa
#

thats

#

o

#

yeah

#

shit

#

m b

#

god dammit

eternal oxide
#

happens to everyone at some point 🙂

severe zenith
#

Ok, I now understood how to send messages from a spigot plugin to the bungeecord system and how to recieve responses. But how to send messages from Bungeecord to Spigot and how to recieve messages on Bungeecord?

ivory sleet
#

Check the plugin message channel API in bungee javadoc but presumably you’d do smtng very similar to what is done in spigot API

slim magnet
#

What's the difference between InventoryInteractEvent and InventoryClickEvent? (In terms of making GUI menus)

eternal oxide
#

Interact is an abstact event thats used as a base for other Inventory events. It will not be fired itself.

slim magnet
#

Can I still listen to it tho?

#

Should I handle interact or click?

eternal oxide
#

As I just said, interact will never fire. Its an abstract class

#

look at its subclasses for those that you can listen for

tame iron
#

hi! there is a task to get chunks in a certain radius from the player, how can this be implemented?

eternal oxide
#

Explain what you mean by "get chunks"

tame iron
#

the player specifies the value in chunks with the command and I need to get all chunks in this radius getChunk()

ivory sleet
rapid vigil
#

Hey, is there anyway to do so everytime someone dies it comes up with different death message?

Like different death message everytime

ivory sleet
#

yeah

rapid vigil
#

I tried multiple ways but none worked

#

I made 6 classes, and each one has a different death message

#

But It's 1 same message from them and it never changes

eternal oxide
stone sinew
rapid vigil
#

First class :

    public void onDeath(PlayerDeathEvent e) {
        if (e.getEntity().getKiller() instanceof Player) {
            Player k = e.getEntity().getKiller();
            Player v = e.getEntity();
            e.setDeathMessage("§6§l" + v.getName() + "§6 was slain by §l" + k.getName);
        }
    }
}```
ivory sleet
#
class PogConclure implements Listener {
  String[] messages = new String[]{"first", "second"};

  @EventHandler public void onDeath(EntityDeathEvent event) {
    if(event.getEntity().getType() != EntityType.PLAYER) return;

    Bukkit.broadcastMessage(messages[ThreadLocalRandom.current().nextInt(messages.length)]);
  }
}``` @rapid vigil
rapid vigil
#

And same thing with other classes, but different death message

tame iron
stone sinew
ivory sleet
#

oh yeha you might wanna set it instead

rapid vigil
#

Thanks Conclure. Appreciate it

eternal oxide
#

its just two loops then to grab all chunks

eternal oxide
rapid vigil
#

What's wrong with Conclure's code though?

eternal oxide
#

Nothing. I didn't see it. Both are just as valid

rapid vigil
#

Thanks a lot appreciate it anyways ;)

minor garnet
#
    public Location getLocationAim(Player p) {
        Vector direction = p.getLocation().getDirection();
        Location l = new Location(p.getWorld(), direction.getX(), direction.getY(), direction.getZ());
        return l;
    }

    @EventHandler
    public void PlayerInteractEvent(PlayerInteractEvent e) {
        if (e.getAction() == Action.RIGHT_CLICK_AIR || e.getAction() == Action.RIGHT_CLICK_BLOCK) {
            Player p = e.getPlayer(); Location point = getLocationAim(p);
            Bukkit.broadcastMessage("Funcionando ponto: " + point);
            particle(EnumParticle.NOTE, point);
        }
    } 
}```
eternal oxide
minor garnet
#

translator bad

eternal oxide
#

You want the block the player is looking at?

minor garnet
#

no

#

location of cross hair

eternal oxide
#

the cross hair is only on the client. It represents nothing on the server

minor garnet
#

no i mean

#

when you right-click on the block, you have the location of the block, I wanted the location of the crosshairs on the block

eternal oxide
#

There is a method but I forget what it called. sec

minor garnet
#

i forgot, i'm on 1.8

eternal oxide
#

ok, not helping with that

minor garnet
languid geode
#

Lads what in the hell did you guys do the the project structure of craftbukkit all my branches are no longer compilable

eternal oxide
#

Nothing

languid geode
#

@eternal oxide Well Something happened to all my NMS patches none of them are able to apply anymore

#

Also for some reason my project is unable to import any of the classes in the same package

willow fossil
#

Can i set more then one Item in an Inventory in one Code Line?

eternal oxide
minor garnet
#

and get a location by this vector

languid geode
#

Still wont fix all my patch files tho but still

#

ill redo the changes on those because merging patch files is a pain in the first place

languid geode
cold field
#

Hi guys, can some explain me what dataWatcher is used for?

languid geode
#

To watch data changes

#

data-watcher

cold field
#

Lol, ok

#

More in-depth?

willow fossil
#

Can i set more then one Item in an Inventory in one Code Line?

languid geode
#

Think events for variables

cold field
#

so, when a variable changes it executes code, right?

languid geode
#

correct

languid geode
#

@eternal oxide Could you help with my patch files ever since we decided to change all of the paths for them none of them work for me anymore and i cant get my root fixed due to that fact

drowsy helm
languid geode
#

Well darn guess i just nuke my changes and rebuilt them from the ground up

drowsy helm
#

Probs have to move em manually

cold field
#

Does anyone know what it is the variable "a" inside the DataWatcherObject class?

eternal night
#

I believe that would be the data value id

#

basically an integer identifier of the data that is stored in the object