#help-development

1 messages · Page 1314 of 1

mortal hare
#

this feels so cursed

wet breach
#

right, that means remove the argument from there

#

since its not required lol

waxen hound
#

you should make another static function that constructs the object or use JavaPlugin.getPlugin instead of taking it as an argument

timid hedge
waxen hound
#

the second is a lazy singleton pattern but i’m not sure if u can use it before the plugin is enabled

wet breach
kindred valley
#

man stop static abusing 👺

waxen hound
#

i’ll stop interfering 😅

kindred valley
#

Static is very dangeous and can cause various problems just use it in your main method okey 👍🏿

wet breach
#
import java.io.File;
import java.io.IOException;

public class FileManager {
    
    private static Main plugin = Main.getInstance();

    private static FileManager instance;

    public void createConfigFile(String fileName){
        File file = new File(plugin.getDataFolder(), fileName);

        if (!file.exists()){
            try {
                file.createNewFile();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

    public void loadConfigFile(String fileName){
        File file = new File(plugin.getDataFolder(), fileName);

        if (!file.exists()){
            try {
                file.createNewFile();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }

    public static FileManager getConfigFile(){
        if (instance == null){
            instance = new FileManager();
        }
        return instance;
    }
}
public class Main extends JavaPlugin {

   private static Main instance;

    private FileManager fileManager;

    @Override
    public void onEnable() {
        instance = this;
        fileManager = FileManager.getConfigFile();
        fileManager.createConfigFile("config.yml");
    }

    @Override
    public void onDisable() {
    }
    public static Main getInstance() {
        return instance;
    }
}
#

@timid hedge

#

fixed it for you

wet breach
#

oh right, I see the problem you were having

kindred valley
wet breach
#

give me a second to fix it lmao

waxen hound
hollow falcon
#

#general Is anyone a mod of this discord server?

worthy yarrow
#

Static calls and methods are perfectly fine so long as you know how to use them

timid hedge
# wet breach <@1050113271392370718>

i still have the errror here
instance = new FileManager();

and i need
` public final Main plugin;

public FileManager(Main plugin){
    this.plugin = plugin;
}`

for
File file = new File(plugin.getDataFolder(), fileName);

wet breach
#

yeah give me a second

#

I am fixing it 😛

timid hedge
#

alr mb i didnt see your first message

wet breach
#

maybe you will notice the changes, however I will note that you shouldn't rely too much on static or abuse it, but for these purposes its perfectly fine

timid hedge
wet breach
#

you shouldn't have an error there o.O

#

oh I see

#

nvm yeah you shouldn't have an error there

alpine solar
#

why uhh

timid hedge
wet breach
timid hedge
wet breach
#

so yeah you shouldn't have that

#

If you can't get rid of stuff you can not free up memory so you should be careful in what you decide to be static. There is some objects that are inherently static for example your main plugin class is static because if it that class/object goes away so does the rest of your plugin effectively being unloaded. So main plugin class is fine to reference as static. Second, because static does not change this means it loses on being dynamic and thus will always reference the same stuff and not change.

timid hedge
wet breach
#

but small steps first I suppose, this is just the beginning to making what you are wanting and I will say its hardly from being the best, but just remember it does not always need to be best as long as it works 😉

timid hedge
wet breach
#

FileManager being the class/object. If it has not been initialized before, it will be null and if it is null it creates the object. If it is not null, it skips to the bottom and returns the instance that already exists. This is part of Singleton's and ensures only a single instance of that class exists in memory

#

Also, this allows the class to be GC'ed if it isn't being used and not worry about getting Nullpointer exceptions when referencing the class as that method takes care of loading 😄

timid hedge
#

gc meaning?

wet breach
#

garbage collected. Java's way of removing stuff in memory not being used to free up memory

alpine solar
#

why are you checking if instance is null

wet breach
alpine solar
#

Ah

wet breach
#

I suppose I should clarify how it works and why it is important to have instance at the top in that class

timid hedge
#

Is this completly wrong for getting the value from a config file?
public File getConfig(String fileName, String value){ return new File(plugin.getDataFolder(), fileName); }

File config = FileManager.initConfig().getConfig("config.yml", "a"); player.sendMessage(String.valueOf(config));

wet breach
# alpine solar why are you checking if instance is null

So the purpose of a singleton class is to not have the ability to be initialized by normal means. Hence this class has no constructor. You could also use a private constructor (lazy loading). In this case we just have no constructor so you can't simply call new FileManager() outside of the class since its constructor is effectively private (in java no constructor is kind of the same as private but more protected since its not actually there on the surface with private on it). Anyways, since the class is not supposed to be initialized by normal means we can use an unassigned instance variable at the top, which makes it null and prevents our method at the bottom from throwing a nullpointer exception since the variable exists at the top just empty (null). The method at the bottom then takes care of assigning a value to it so now it is no longer null, until the class goes away and gets re-initialized and the process starts again.

alpine solar
#

lazy loading

#

that's so me

wet breach
#

lol

wet breach
#

import java.io.File;
import java.io.IOException;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;

public class FileManager {
    private File file;
    private YamlConfiguration data;
    private static Main plugin = Main.getInstance();

    private static FileManager instance;

    public void createConfigFile(String fileName){
        file = new File(plugin.getDataFolder(), fileName);

        if (!file.exists()){
            try {
                file.createNewFile();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    
    }

    public void loadConfigFile(String fileName){
        file = new File(plugin.getDataFolder(), fileName);

        if (!file.exists()){
            try {
                file.createNewFile();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    data = YamlConfiguration.loadConfiguration(file);
    }

    public YamlConfiguration getData() {
        return this.data;
    }

    

    public static FileManager getConfigFile(){
        if (instance == null){
            instance = new FileManager();
        }
        return instance;
    }
}
wet breach
#

there we go @timid hedge added more to your filemanager class 🙂

#

placed the getData() method so now you can use it to pull yaml related stuff from a file you load 😉

#

however, this is not an ideal setup because at the moment you need to ensure you call loadConfigFile() first before you call getData()

#

otherwise you end up with nullpointers 😛

alpine solar
ivory sleet
#

Sounds severe

alpine solar
#

very

ivory sleet
#

I use static so much i was scared id be half a man after reading that statement

wet breach
ivory sleet
#

Lol yea

timid hedge
ivory sleet
#

Icl you definitely have shot urself in the foot a couple of times when you need to use powermocks to unit test ur application

wet breach
#

String something = FileManager.getInstance.getData().getString("a");
String something = FileManager.getInstance.getData().getString("path.to.a");

#

but yeah you would need to ensure you load the appropriate yaml file first before using getData()

rotund ravine
#

Ew static

wet breach
#

indeed, I was about to make a comment in how this slowly shows how using static may not always be best but good news is that you can use this singleton class to initialize appropriate objects which I am hoping they progress to learn to do instead 🙂

timid hedge
#

idk how else im going to call loadconfigfile before getdata else than this
public YamlConfiguration getData() { if (data == null){ loadConfigFile(file.getName()); } return this.data; }

#

idk how im going to do it, so that is just my best guess for now...

kindred valley
#

ais

wet breach
wet breach
#

in another class you would do, loadConfigFile() somewhere in the top, then below that in the class you can do getData()

#

it doesn't have to occur in the same class lol

ivory sleet
kindred valley
#

my father in jail for using that word in main method

ivory sleet
#

Good thing static isnt so dangerous then truth be told

rotund ravine
thorn isle
#

tan juck

ivory sleet
#

i thought jan tuck only wrote in kotlin

timid hedge
# wet breach in another class you would do, loadConfigFile() somewhere in the top, then below...

so like this?
` @Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (!(sender instanceof Player)){
return false;
}
FileManager.instance.loadConfigFile("config.yml");

    Player player = (Player) sender;

    player.setHealth(0);


    String my_message = FileManager.instance.getData().getString("test path");
    player.sendMessage(my_message);


    return false;
}

}
`

#

I just want to know where FileManager.instance.loadConfigFile("config.yml"); should be placed

waxen hound
#

can you use three ticks when u wrap

#

```

wet breach
#

they probably didn't know that

thorn isle
#

off with their heads

waxen hound
#

i didnt mean anythig by it mb 😭

#

its just easier to read

wet breach
#

the way you have it above is acceptable and works

thorn isle
#

disk io on main thread is grounds for capital punishment

wet breach
#

now to teach you what was said earlier in regards to discord

#

if you use three back ticks " ` " and then put java you can create a code block that is styled

#

oops t hat didn't work

thorn isle
#

escape it with \ i think

#

```
java
```

wet breach
#

hmm seems I forgotten how to escape with discord

waxen hound
#

```java
test
```

thorn isle
#

myeah

#

\`

wet breach
#

what turtle did, and then place everything below the java part/your code and it will make a single code block and style it in java format

timid hedge
#

alr thx

eternal oxide
#

?codeblock

undone axleBOT
#

You can use the discord code block format to display code or just text in a more pleasing way:
```java
public class MyPlugin extends JavaPlugin {
@Override
public void onEnable() {

}

}```
Becomes:

public class MyPlugin extends JavaPlugin {
    @Override
    public void onEnable() {

    }
}```
waxen hound
#

does anyone have working code to send a entity metadata packet with protocollib

#

mine doesnt work

#
    private void updatePlayerLine(Player ply, Entity entity) {
        if(entity == null) {
            return;
        }

        PacketContainer packet = ProtocolLibrary.getProtocolManager()
                .createPacket(PacketType.Play.Server.ENTITY_METADATA);
        StructureModifier<List<WrappedDataValue>> watchableAccessor = packet.getDataValueCollectionModifier();

        packet.getIntegers().write(0, entity.getEntityId());

        final WrappedDataWatcher.Serializer chatSerializer = WrappedDataWatcher.Registry.getChatComponentSerializer(true);
        Component component = this.generateLine(ply, entity);
        String json = GsonComponentSerializer.gson().serialize(component);

        watchableAccessor.write(0, List.of(new WrappedDataValue(2, chatSerializer, Optional.of(WrappedChatComponent.fromJson(json)))));
        ProtocolLibrary.getProtocolManager().sendServerPacket(ply, packet);
    }
timid hedge
wet breach
#

no it is not

#

I believe I said that earlier

timid hedge
#

oh...

#

because i just want to make something that is good so i can keep using it without having to remake a config every time

wet breach
#

however, it works though and is easy enough to use for someone still learning. There is far better ways to do this, but some of those better ways require more understanding of java

#

as I said I am not fond at just giving someone the answers and would rather they learn and understand what it is they are making and using otherwise when you do encounter those better ways you will better know how it works as well as when you encounter problems understand what that problem is and fix it.

#

you can just easily google around for code and just copy paste it all day long if that is what you truly want but that doesn't guarantee you understanding it or know how it works

timid hedge
#

yea i understand that, but the thing i dont understand is just it dosent create a folder with my config file...

wet breach
#

ah you want to create a directory

#

well just like you can have paths when calling data in yaml when you specify the config file you can make paths with that too

#

and the method should create the directories and file at the same time

timid hedge
#

oh wait i forgot, i havent made anything that can add things to the config.yml

timid hedge
# wet breach and the method should create the directories and file at the same time

do you talk about this one

    public void createConfigFile(String fileName){
        file = new File(plugin.getDataFolder(), fileName);

        if (!file.exists()){
            try {
                file.createNewFile();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }```

or this one
public void loadConfigFile(String fileName){
    file = new File(plugin.getDataFolder(), fileName);

    if (!file.exists()){
        try {
            file.createNewFile();
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    data = YamlConfiguration.loadConfiguration(file);
}```
wet breach
#

well there both essentially the same, but we will stick with the current one which is the second one lol

#

so where it has fileName

thorn isle
#

always remember to print the message along with the exception's stack trace

wet breach
#

your variable in the method constructor would be this "file/path/file"

thorn isle
#

without the exception message, things can be very hard to nail down

timid hedge
#

should i just delete createconfigfile and use laodconfigfile instead? because data = YamlConfiguration.loadConfiguration(file); this line dosent do anything right now?

wet breach
#

well data does do something as it is used for getData();

#

technically could remove it, and just do YamlConfiguration.loadConfiguration(file); elsewhere if you really wanted to

timid hedge
#

but isnt that line only for that method??

wet breach
#

yeah, as I said you could remove it change it to your liking etc

#

you don't have to strictly do things as I say, just what I say are examples

timid hedge
#

yea i just misunderstood what you said beofre

timid hedge
wet breach
#

it would be what you supply into fileName

#

it is a string after all

#

it is very interesting though that no one else is providing input 🤔

#

normally many people end up doing so, kind of a first that has not happened yet

timid hedge
# wet breach it would be what you supply into fileName

i dont really understand, its in onEnable right?

    @Override
    public void onEnable() {
        instance = this;
        fileManager = FileManager.initConfig();
        fileManager.ymlFile("config.yml");
        getCommand("suicide").setExecutor(new SuicideCommand());
    }```
#

sorry if im too bad for this...

wet breach
#

you are not bad, just not understanding that your class is a bit dynamic. But we will go with your example for the time being

wet breach
#

if that happens, I have alternative ways to creating directories 😛

#

cool part is there is many ways to do this XD

timid hedge
#

is it because i havent made a file called config.yml under "resources"?

wet breach
#

well in spigot/bukkit config.yml gets created on its own with using the api methods or if you include config.yml inside of the plugin jar. The methods I have shown so far should be used for yaml files other then config.yml because all you are doing otherwise is just being redundant lol

timid hedge
#

i just found this in the console
java.io.IOException: Den angivne sti blev ikke fundet translated to english it is:
java.io.IOException: The specified path was not found

faint meadow
#

i can´t use "sk89q" imports.
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;

<dependency>
<groupId>com.fastasyncworldedit</groupId>
<artifactId>FastAsyncWorldEdit-Bukkit</artifactId>
<version>2.12.3</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>com.sk89q.worldedit</groupId>
<artifactId>worldedit-bukkit</artifactId>
<version>7.2.13</version>
<scope>provided</scope>
</dependency>
</dependencies>

<dependency>
<groupId>com.fastasyncworldedit</groupId>
<artifactId>FastAsyncWorldEdit-Core</artifactId>
<version>2.12.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fastasyncworldedit</groupId>
<artifactId>FastAsyncWorldEdit-Bukkit</artifactId>
<version>2.12.3</version>
<scope>provided</scope>
</dependency>

    <dependency>
        <groupId>com.fastasyncworldedit</groupId>
        <artifactId>FastAsyncWorldEdit-Libs-Bukkit</artifactId>
        <version>2.12.3</version>
        <scope>provided</scope>
    </dependency>

I'm trying those dependencies but none of them work,
what is the fuc***g problem?

timid hedge
faint meadow
timid hedge
waxen hound
#

does getEntityId return the id you need to feed into a packet with protocollib

faint meadow
#

¿?

wet breach
#
    public void loadConfigFile(String filePath, String fileName, boolean usePath){
        if (usePath) {
            filePath = this.Path
        } else {
            filePath = plugin.getDataFolder().toString;
        }
        file = new File(filePath, fileName);

        if (!file.exists()){
            try {
                file.createNewFile();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
        data = YamlConfiguration.loadConfiguration(file);
    }
#

believe this should work

#

forgot that the first part of our File() method was the path and the second was the file name

wet breach
#

changes I made, makes it so that if you didn't want to use a path, and instead just want the plugin folder it is possible with a boolean option

timid hedge
#

thx, idk last time i made a config file i didnt have to locate the location and all this... but wdym if i dont want to use a path but the plugin folder?

#

at filePath = this.Path im getting an error, should i just make; private String path; and at filePath = plugin.getDataFolder().toString; it dosent give any fixes for that, the error is at .toString;

waxen hound
# thorn isle iirc yes

I have this code as a packet listener:

    @Override
    public void onPacketSending(PacketEvent event) {
        PacketContainer packet = event.getPacket();

        UtilLogger.getLogger().info("Sending EntityMetadata to " + event.getPlayer().getUniqueId() + " (ent id = " + packet.getIntegers().read(0));
        Entity target = packet.getEntityModifier(event.getPlayer().getWorld()).read(0);
        Player ply = event.getPlayer(); 
        if(target == null) {
            return;
        }

        UtilLogger.getLogger().info("Found armorstand");

        LeaderboardHologram holo = this.leaderboardManager.getHologram(target);
        if(holo == null) {
            return;
        }
 
        UtilLogger.getLogger().info("Found holo");
...

whenever the paper server itself sends an entity metadata, the ids are in the 300s - and it succeeds in finding my entity:

[16:07:28 INFO]: [DuelsSat] Sending EntityMetadata to 69e47f42-b428-45fb-8e54-4d298fd86c81 (ent id = 295
[16:07:28 INFO]: [DuelsSat] Found armorstand
[16:07:28 INFO]: [DuelsSat] Sending EntityMetadata to 69e47f42-b428-45fb-8e54-4d298fd86c81 (ent id = 295
[16:07:28 INFO]: [DuelsSat] Found armorstand
[16:07:28 INFO]: [DuelsSat] Sending EntityMetadata to 69e47f42-b428-45fb-8e54-4d298fd86c81 (ent id = 295
[16:07:28 INFO]: [DuelsSat] Found armorstand
[16:07:28 INFO]: [DuelsSat] Sending EntityMetadata to 69e47f42-b428-45fb-8e54-4d298fd86c81 (ent id = 295
[16:07:28 INFO]: [DuelsSat] Found armorstand

whenever i send it myself, it fails:

[16:17:22 INFO]: [DuelsSat] Sending EntityMetadata to 69e47f42-b428-45fb-8e54-4d298fd86c81 (ent id = 3
[16:17:22 INFO]: [DuelsSat] Sending EntityMetadata to 69e47f42-b428-45fb-8e54-4d298fd86c81 (ent id = 4
#

the sending code

    private void updatePlayerLine(Player ply, Entity entity) {
        if(entity == null) {
            return;
        }

        PacketContainer packet = ProtocolLibrary.getProtocolManager()
                .createPacket(PacketType.Play.Server.ENTITY_METADATA);
        StructureModifier<List<WrappedDataValue>> watchableAccessor = packet.getDataValueCollectionModifier();

        packet.getIntegers().write(0, entity.getEntityId());

        final WrappedDataWatcher.Serializer chatSerializer = WrappedDataWatcher.Registry.getChatComponentSerializer(true);
        Component component = this.generateLine(ply, entity);
        String json = GsonComponentSerializer.gson().serialize(component);

        watchableAccessor.write(0, List.of(new WrappedDataValue(2, chatSerializer, Optional.of(WrappedChatComponent.fromJson(json).getHandle()))));
        ProtocolLibrary.getProtocolManager().sendServerPacket(ply, packet);
    }
thorn isle
#

honestly if you're targeting paper, just use the userdev gradle plugin and build against nms

#

everything is much easier and you can see the nms sources to investigate problems like these

#

and ever since the runtime remapping and mojmapped servers, it's fairly stable across versions as well

#

in this case, looking at nms, yes, that should return the network id for the entity

#

it returns nms.Entity#id which is also passed to the packet constructors by the entity, e.g.

    public void refreshEntityData(ServerPlayer to) {
        List<SynchedEntityData.DataValue<?>> list = this.entityData.packAll(); // Paper - Update EVERYTHING not just not default

        if (to.getBukkitEntity().canSee(this.getBukkitEntity())) { // Paper
            to.connection.send(new net.minecraft.network.protocol.game.ClientboundSetEntityDataPacket(this.getId(), list));
        }
    }
waxen hound
#

i can only assume that im writing the packet wrong then?

thorn isle
#

or you have the wrong entity, i suppose

waxen hound
#

maybe its losing reference to the entity somewhere

thorn isle
#

looking at the packet record, the first int is indeed the eid, so that part should be right

waxen hound
#

they should be in spawn chunks

#

yeah i think the problem is the entities being different

#

im spawning them on startup

#

i guess its before spawn chunks are loaded

thorn isle
#

that'd make sense for the very low ids you have vs the much higher ids the server sends

#

best always hold a reference to the entity and check if it's isValid

waxen hound
#

is that spigot provided functionality?

#

i just added a chunk ticket when i create the entities and that fixed it, so our hypothesis is correct

thorn isle
#

i think isValid has existed ever since craftbukkit and the dawn of time

waxen hound
#

ah, is it just Entity#isValid

thorn isle
#

any time you hold a reference to an Entity for longer than a tick you should in principle check that before next using it, as it could have become invalid in the meanwhile

#

or strictly speaking any time flow control leaves your local code, as it could be e.g. killed by other plugin code

timid hedge
# wet breach changes I made, makes it so that if you didn't want to use a path, and instead j...

idk if you can answer this i asked earlier
idk last time i made a config file i didnt have to locate the location and all this... but wdym if i dont want to use a path but the plugin folder?
at filePath = this.Path im getting an error, should i just make; private String path; and at filePath = plugin.getDataFolder().toString; it dosent give any fixes for that, the error is at .toString;

wet breach
#

so far all of my help I been giving I have not been using an IDE 😛

#

I just wasnt sure if plugin.getDataFolder() is already a string or whatever

#

can't remember everything, despite I been doing alright for the most part lmao

timid hedge
#

... yea, thx for your helping me but i guess ill try get this done and then learn how to use java or just do that now

echo basalt
#

getDataFolder returns a File object

#

if you're on paper there's getDataPath which returns the nio Path

#
File configFile = new File(plugin.getDataFolder(), "settings.yml");

...
#
Path configPath = plugin.getDataFolder().toPath().resolve("settings.yml");

if (!Files.exists(configPath)) {
  Files.create(configPath);
}

#

type deal

wet breach
echo basalt
#

That's no excuse to not give a good quality answer

wet breach
#

never said that lol

#

just to keep it in mind

wild mulch
#

I'm trying to develop a plugin with ProtocolLib, How do I get the ItemStack in the SET_CREATIVE_SLOT packet?

chrome beacon
#

You get the item modifier

wild mulch
#

Ok

#

how do i change the NBT or components of a item

chrome beacon
#

Depends on what you're trying to do

wild mulch
#

I just wanna view nbt and run some checks then change it

thorn isle
#

items don't really work with nbt anymore

#

i think paper has a method to serialize it into snbt

#

alternatively you can serialize to bytes and then parse the bytes as a compound tag

chrome beacon
wild mulch
thorn isle
#

it might be too late at that point

wild mulch
#

doubt it

thorn isle
#

but assuming it isn't, you can serialize it to bytes with paper, parse it as a compound tag with nms, and then run your inspections on the compound tag

wild mulch
#

but i dont wanna switch my stuff over to paper

thorn isle
#

you can do the same with nms then but dunno where you want to hook into exactly

#

ItemStack codec something something

chrome beacon
#

If you're going to use nms anyway you might as well use the bukkit helper method to convert the spigot item stack to an nms one

wild mulch
#

Is there any way without using NMS or Paper

thorn isle
#

no

#

nbt has never been an api feature

#

there are libraries that will use nms for you, iirc itemnbt or something, but your mileage may vary

chrome beacon
#

Parsing the data yourself is also an option

wild mulch
#

tr7zw
Item-NBT-API?

thorn isle
#

probably

wild mulch
#

kk ill try

wet breach
#

if that is your goal you are better off looing at vanilla source code to determine that

wild mulch
#

alright i got it working

#

How do i Make a nbt list using ITEM-NBT-API

wraith dragon
#

@echo basalt sorry for the ping, any project idea recommendations for learning the abstraction stuff we discussed yesterday? Like a quests plugin?

echo basalt
#

Rewards are the best example

#

Quests not so much

#

It could work but quests are more about abstraction

wraith dragon
#

Gotcha

#

I think I'll start with quests then implement rewards

#

my knowledge with abstraction currently isn't too good

quaint mantle
#

Same

echo basalt
timid hedge
#

How long should i be learning java for before making plugins? if it makes sense?, like 2 hours a day for over a year or two?

chrome beacon
#

Until you feel ready

#

Everyone learns at a different pace and have their own way of learning

#

I can recommend Y. Daniel Liang - Introduction to Java Programming and Data Structures if you want a book to read with exercises to do

#

but there are ofcourse many online tutorials as well if you prefer

chrome beacon
#

Yeah that looks like a video made by the author

timid hedge
#

Does it teach some things that codeacedemy dosent or teches it more in depth? right now im just using codeacademy idk if its good or not

chrome beacon
#

I've never tried codeacademy so I can't say

#

You can check your local libraries for the book

#

since it's quite common in universities it's likely there are a couple copies you can borrow

#

or find a pdf somewhere online

chrome beacon
#

That looks like quite an old copy

#

but yes that is it

timid hedge
#

alr, do you know where to buy the new version of the book?

#

amazon?

chrome beacon
#

I got mine from Amazon since it was the cheapest option

timid hedge
#

what edition is the new one?

#

the link is i sent is the 8th

chrome beacon
#

13th

#

I believe I have the 12th since that's what I needed for my course

timid hedge
#

thats the one i want right, its not something like i should read from 10th edition up to the newest to understand everything right?

chrome beacon
#

No he just updates them with new content

#

You do not need the older versions

timid hedge
chrome beacon
#

yeah that's the 11th edition

#

The book is quite expensive since it's quite long

#

mine is over 1000 pages

#

but as I said take a look at your local libraries and see if they have a copy

#

if you feel like it's useful you can buy it or keep borrowing it

timid hedge
#

alr thx, but from what i can see the 13th edition is only online

thorn isle
#

You definitely don't need a 200usd 1000 page book to write bukkit plugins

chrome beacon
#

^ this is true

timid hedge
chrome beacon
#

188USD is like twice the amount I spent on my copy

#

and that's (amazon one not mine) an older edition as well

ivory sleet
thorn isle
#

only preparation you really need is maybe a couple of beginner tutorials on codeacademy or whatever so you know the language syntax

#

the language syntax is very simple, there are only really a few symbols and a few rules that govern how you can put them together, far easier than english for example

#

beyond that, it's all about problem solving, which you won't necessarily learn from any number of tutorials or "preparation"

timid hedge
thorn isle
#

you look it up

timid hedge
#

i have tried

thorn isle
#

looking up things is a big part of problem solving

timid hedge
#

yesterday i used like 3 hours trying to figure it out

#

and i ended up with nothing

#

and afterwards i asked in here

thorn isle
#

you're having difficulty with it because you're unfamiliar with the language syntax

timid hedge
#

and where do i learn the language syntax

thorn isle
#

codeacademy or whatever, the basic tutorials will do fine

timid hedge
#

alr thx

thorn isle
#

but again like i said that's only the very first thing and there isn't that much to learn or "prepare" there; you just need to know what certain words mean so you can effectively look things up

pseudo hazel
#

also whats wrong with it being basic

timid hedge
thorn isle
#

there's nothing basic or wrong about having the config as a file in your resources

#

some plugins don't do it that way, but it is by far the most established and common way of doing it

pseudo hazel
#

how else would you even do it

timid hedge
thorn isle
#

generating it from sources, like towny does

#

i kind of prefer it personally because it allows the config keys to be linted and checked at compile time against typo's, but it isn't as flexible and has its own problems

thorn isle
pseudo hazel
#

wdym sources

thorn isle
#

as in you have say a class with public final fields holding objects, each object representing a config key-value

timid hedge
pseudo hazel
#

thats how my configs work, but I have a general config file that I can still edit by hand for the comments etc

thorn isle
#

public final TimeValue TELEPORT_COOLDOWN = new TimeValue().withDefault(10_000L);
pseudo hazel
#

but then it just gets updated with the correct default values for new options that get added in updates

thorn isle
pseudo hazel
#

the way my config works is it loads the version in the plugin folder, then it loads the version in the jar and puts the jar version into the plugin folder with values found in the existing file from the plugin folder

thorn isle
#

my advice here would be to learn to walk before you try to run; don't try to homebrew your own configuration framework with versioning and updates and all those things, that's complicated

timid hedge
thorn isle
#

just stick with having a configuration file that you read things from

#

if something is wrong in the config, print a warning in the console; don't try to "fix" it for the user

#

e.g. if something is missing, print "X is missing in config"

ivory sleet
#

saveDefaultConfig is a convenience method

pseudo hazel
#

you have to save it more manually using saveResource because saveDefaultConfig is specifially for config.yml

thorn isle
#

this is acceptable

ivory sleet
#

mfw bukkit forums

timid hedge
thorn isle
#

first search result

ivory sleet
#

if you don't know what convenience means u might wna google that word :>

timid hedge
#

yea and thats what i meant and thats why i wanted to make a clas that can manage the config files because savedefaultconfig is for 1 file

thorn isle
#

remember how i told you to go learn the basics so you know what words mean

timid hedge
#

thats what i have been trying to say...

thorn isle
#
    public void saveDefaultConfig() {
        if (!this.configFile.exists()) {
            this.saveResource("config.yml", false);
        }
    }
#

this is saveDefaultConfig

timid hedge
#

i havent used it like that before...

pseudo hazel
#

thats the implementation

thorn isle
#

this.configFile is a File representing the config file

#

this.saveResource extracts the file from your jar into the plugin directory

#

passing false to it means it won't overwrite it if it already exists

#

now do this but with a File and a path representing your custom config file

timid hedge
thorn isle
#

no

#

again, updating and versioning configs is complicated

#

do the basics first

#

get into the complicated things later

timid hedge
#

should i do it the same way as the person the the bukkit forum you sent

thorn isle
#

if you want sure but i'd advise against trying to "fix" a broken config

ivory sleet
pseudo hazel
#

you can fix a broken config perfectly fine

thorn isle
#

you can but he can't even figure out how to save it or to load it on his own, so let's leave that for later

pseudo hazel
#

I load in the old file, then create a new file, and then put the old options back into the new file

timid hedge
#

lol

thorn isle
#

clearly not

timid hedge
#

i dont think you know what i want to do...

pseudo hazel
#

then the new file will have the old options + the new ones

thorn isle
#

you spent 3 hours last night with frostalf trying to load a config

timid hedge
#

because i wanted to do it on another way

#

and you clearly dont understand it...

ivory sleet
#

if you want god tier versioning

thorn isle
#

just use configurate

ivory sleet
#

you could throw urself at DataFixerUpper

pseudo hazel
#

thats usually overkill for a general config

#

atlesst in my case

#

options rarely change, they either get removed or added

ivory sleet
#

i mean its more for data

#

not configing but yea

thorn isle
#

i think he meant configurate probably

pseudo hazel
#

yeah ig other config files it could be a different story

thorn isle
#

configurate is definitely overkill for basic things

pseudo hazel
#

no I meant datafixer is overkill for what we are trying to do now

thorn isle
#

but properly updating configs while retaining correct formatting and comments isn't basic

sly topaz
thorn isle
#

oh for sure, DFU is a nightmare

ivory sleet
#

idk about nightmare

sly topaz
#

configure is fine for simple things, it gets annoying when you have anything mildly complex in a config

pseudo hazel
#

configurate is overkill too but that just depends on your workflow

thorn isle
#

yes my convenience class of 1,500 transformation registrations

pseudo hazel
#

I usually dont like to use too many deps but its fine if you do

ivory sleet
#

I mean configurate does one thing good

#

it fixes broken libraries like snakeyaml and represent them with a good node structure

sly topaz
ivory sleet
pseudo hazel
#

oop is overcooked anyways

ivory sleet
#

just look at what they're doing for generics, lambdas, data orientation etc

sly topaz
#

I'd say they took the functional approach a bit too much for what they wanted to do

ivory sleet
#

Well my take on DFU is that its a perfectly engineered library given the goals of it

#

for ur average config maybe not the library ud use

#

but as soon as u wna scale with lets say a dsl language a large set of instances in that dsl, or more so just data formats in general

thorn isle
#

the readme is like 50% by length links to 1000-page phd papers that were used in and written on it

ivory sleet
#

dont get me wrong, u couldve written the data transformation optimizations in an imperative way, but then u lose the ability to pick up on certain traits and properties

thorn isle
#

i don't know if that's good or bad but it's definitely something

ivory sleet
sly topaz
ivory sleet
#

u only ever use like their dynamic operations, codecs and data fixers

#

and their dsl to navigate and rewrite data types

sly topaz
#

I'd want to try and use it outside of Minecraft to have a more clear picture of it, tbh

#

I just haven't had the opportunity to

ivory sleet
#

thats the theory thats backing up what the implementation allows DFU to be as powerful as it is

#

u dont need to touch the impl

#

meaning u dont need to read the 1k pdfs

slender elbow
#

and to think that codecs weren't part of DFU originally

#

it was just data fixing

ivory sleet
#

true

ivory sleet
slender elbow
#

you can totally use it outside of minecraft, it's not as bad as many make it seem, it just has a couple of methods in the Schema that are specific to Minecraft that you need to implement or the whole thing blows up

ivory sleet
#

yea I mean i think it lacks a bit of qol, for example shipping more codecs for std types, and also that, but there's also some undocumented invariants

#

which u just run into and have to deal w on the spot (maybe not that big of an issue)

slender elbow
#

codecs are the easy part i reckon

ivory sleet
#

instead of creating a new major schema maybe?

slender elbow
#

it would be nice if the serialization part was separated from the data fixing into a separate library tbh

sly topaz
#

that kinda defeats the point of it, no? DFU always seemed to try encompass the idea of "serialization with migration in mind"

#

you could separate the two but still use them together ig

slender elbow
#

serialization was added separately, originally it was only data fixing

#

they aren't strictly tied together from what I know, they do share, like, a couple of classes in common but besides that they really aren't

ivory sleet
sly topaz
#

yeah but without serialization it'd mean plugin their data fixing system on an existing serialization library which would probably be kind of awkward in the end

#

I assume that's why they ended up implementing serialization on the library

ivory sleet
#

u still likely need to depend on another serialization lib, like if u wna have anything else than json and java ops

slender elbow
#

all i'm saying is there have been times where i just wanted to write basic codecs usage without caring about data migration, that's all

#

but at that point i would just use jackson

sly topaz
#

can someone please think about the migrations!!

slender elbow
#

but that's not what i'm saying lol

sly topaz
ivory sleet
#

but def could a separate dfu lib that depends on the serialization lib

slender elbow
#

referencing the simpsons in 2025 👴

ivory sleet
#

not a dumb idea

sly topaz
#

I am fully asserting my rights to send gifs in whatsapp with it

slender elbow
#

dw i'm with you

hard socket
#

is BuildTools still the best way to get NMS source code?

chrome beacon
#

yes

#

if you're talking spigot

#

if you just want to dig around and see how things work I recommend a Fabric workspace since it attaches sources better

#

though you'd be missing spigot specific stuff

hard socket
#

hmm good to know thanks a lot!

#

what about paper tho? if I may ask

chrome beacon
#

if you're making a Paper plugin you can use Paperweight

sly topaz
#

paperweight is fine, I usually still just clone the paper repo because IntelliJ isn't as good at searching usage/implementations of a given method/field of compiled classes (the API classes are in source form but the internals ones aren't)

hard socket
#

will work around that thanks guys

chrome beacon
#

guess I'll have to give the main repo a try

thorn isle
#

i do seem to have the sources for nms internals attached from the paperweight dev bundle

sly topaz
#

but since internals don't ship a -sources jar, there's nothing to attach

#

or at least there isn't on my local maven repo lol

thorn isle
#

maybe i've attached them manually at some point, i can't remember

slender elbow
#

unless you have some CI flag/envvar that i can't remember, userdev will automagically attach to the intellij sync task and decompile & apply source patches to make them available

thorn isle
#

i think i probably just attached the userdev cache directory as sources directly

#

yeah i can't remember having to deal with finding sources to attach manually for a long time

sly topaz
#

but I guess this is way out of scope for #help-development, I'll ask in Paper dc later

slender elbow
#

blame the minions in your cpu

sly topaz
#

damn you cpu minions and comsmic rays that flip bits!!!

sly topaz
#

I love how you always got one reaction gif saved up in your pocket lol

wet breach
#

lol

buoyant viper
#

?stash

undone axleBOT
weak wasp
#

Anyone ever deal with the Twitch WebSocket API? It's so exhausting.

chrome beacon
#

I do remember messing with their api a couple years ago

#

But it's been a while

weak wasp
#

I have like a dozen+ events I want to subscribe to. I have to make a data class for the sub itself, the subs condition, a method to send the request, make sure that all works, then test with CLI tool to see what the response JSON looks like then make a data class for that, then finally I can actually process the event

#

I wish there was a better way

steady niche
#

What are some good VPS services?

weak wasp
#

I have so far subscribed to chat, follow, subscribe, unsubscribe, use bits, and I forget events. So many more to go...

#

I just need to vent, sorry guys

buoyant viper
#

Hetzner is another goodie but ive had some weirdness with payments (skill issue)

steady niche
timid hedge
#

Im trying to learn some java but i have a question, why dont you always use double instead of switching between double and int

young knoll
#

double stores floating point values (numbers with decimals) and int stores integers (no decimals)

#

Sometimes you don’t want/need decimals, and math on floating point values isn’t perfect

timid hedge
thorn isle
#

for anything that can't be fractional

#

for example, in minecraft, you can't have 1.5 dirt blocks in your hand

#

you can have 1 or 2 or any whole number up to 64, but you can't have partial items in a stack

#

therefore it is represented with an int, and not a double

timid hedge
thorn isle
#

yes

#

but you can do double amount = 2.5

#

which would be wrong

#

you can't do int amount = 2.5

#

so it forces you to be right

timid hedge
#

yeah i know but what i meant is just why not always use double? when double can be both integer and . numbers

thorn isle
#

because, like i said, sometimes you don't want it to be possible to use .

#

an itemstack can't have .

#

so you use int, which stops you from having .

weak wasp
#

Also int takes up less memory than double so int processes faster.

young knoll
#

Well yeah the equivalent to int would be float

#

Both 32 bits

#

But either way you don’t want decimal values for stack size to even be possible

buoyant viper
#

1.0 + 2.0 = 2.999999999998

#

not rly bc i think its a bit more reliable adding whole numbers with no trailing decimals but

remote swallow
#

i think you mean 0.1 + 0.2 = 0.30000000000000004

remote swallow
buoyant viper
#

just store everything using BigDecimal

#

ezpz

chrome beacon
remote swallow
#

yup

buoyant viper
#

something i had to consider while working on an eco system

#

ended up storing balances as longs LOL

#

decimals will only be visual flair, transactions will act only in whole numbers

worthy yarrow
#

Love when my formatting fucks up and still displays the .12000000000002

young knoll
#

Clearly you gotta used fixed point numbers

#

$2.99 = 299

worthy yarrow
#

Gross

waxen hound
#

its called fixed point arithmetic

#

i believe

buoyant viper
#

just dont ask me how a % of the value works (it just doesnt)

waxen hound
#

wdym

buoyant viper
#

oh i guess i could explode the value

young knoll
#

Some languages have built in types designed for currency

#

Like C#s decimal

slender elbow
#

Java has BigDecimal for that 👵

torn shuttle
#

heyo what is the easiest way to fake a player getting damaged?

#

like

#

honestly I would ideally just like the red tint

#

but I'll take red tint and knockback if I must

#

no real damage

rotund ravine
torn shuttle
#

don't even need to there's a super convenient send hurt animation as it turns out

#

real nice

#

think that's new to me

rotund ravine
#

Cool

torn shuttle
#

is there still no way to remove the numbers from the scoreboard?

rotund ravine
#

There is

torn shuttle
#

does it involve having to use protocollib

rotund ravine
#

Wait idk if it is in spigot yet

#

Paper has itt ehh let me chexk spigot javadoc and see if i can see smth

torn shuttle
#

yeah because I just added the paper mehtod through reflections lmao

#

but it wont' do anything for spigot

rotund ravine
#

Hmmm not sure

#

There’s render type but doesn’t look like it has anything fun

torn shuttle
#

how what was the new cool ui stuff called that was introduced in 1.21

#

1.21.X

#

the one that someone got doom to run in it

#

dialogs I think

worldly ingot
#

Dialogs yes

torn shuttle
#

am I meant to interface with that via spigot api or by injecting json into players?

#

like uh

#

idk

#

seems like it's just a bunch of json if I don't want to use a rsp right

worldly ingot
#

There is a Dialog type provided by Bungee Chat

#

Then Player#openDialog() iirc

torn shuttle
worldly ingot
#

Bungee Chat is base spigot?

torn shuttle
#

is it?

#

the methods I'm trying to use are giving me a class not found thing

#

like

Dialog notice = new NoticeDialog( new DialogBase( new ComponentBuilder( "Hello" ).color( ChatColor.RED ).build() ) );
        player.showDialog( notice );
#

dialog gives class not found

#

am I looking in the wrong place?

torn shuttle
#

I am not which is definitely the problem here

#

I guess I'm maybe confused, is bungee chat a discrete system from base spigot that also needs to be installed? I thought it would be

#

hence me not having the class when running

echo basalt
#

It's a separate module for convenience but it's bundled with spig

torn shuttle
#

ok so should my code not be giving a class not found or what am I missing here

echo basalt
#

it doesn't exist on paper

torn shuttle
#

oh if it doesn't exist on paper I'm kinda fucked, too many of my users use it

echo basalt
#

time to make a spig and paper module thingy

torn shuttle
#

I think this env might be paper, idk I have htem thrown in at random

echo basalt
#

adventure for paper, bungee chat for spig

mortal vortex
#

can’t you just use bungeechat?

echo basalt
#

or you can shade adventure

torn shuttle
#

I'm not going to do that

#

that's way too much effort

mortal vortex
#

if bungeechat is serializing, you could just shade bungeechat-dialogue because it’s WAYYY smaller than adventure.

#

The dialogue package is hardly that many classes.

torn shuttle
#

I don't know if i'd rather just deal with raw json

#

hm shading bungeechat-dialogue isn't a bad idea

#

it is tiny yeah

mortal vortex
#

Say W abb3v rn

torn shuttle
#

checking the size before I comming to a w

mortal vortex
#

thank you sir

sly topaz
worldly ingot
#

If they just straight up removed the module, that would be the first major API break

quaint mantle
#

Hi, help pls. I want to set up a command (for example /spawn) so that it has a 5-second delay before execution and a 30-second cooldown, but the teleport should only cancel if the player takes or deals damage, not if they move. Currently, the command executes instantly. Are there any plugins or solutions that can handle this behavior?

thorn isle
#

schedule a repeating task that checks the position periodically and cancels itself in 5 seconds, teleporting the player if they haven't moved

#

and cancels itself if the player moves

#

a self-cancelling BukkitRunnable is useful for this

#

for the cooldown, keep a UUID -> Long map of timestamps of last usage; check the map when the command is run and insert into the map when the player teleports successfully

#

uuid being the player's unique id

quaint mantle
#

It’s unlikely that such a plugin doesn’t exist; I’ve seen it on several servers, apparently not configured, but completely identical. Also, I need it so that different ranks or permissions can have different times.

thorn isle
#

this is dev-help

#

we make plugins here

#

if you want an existing plugin, go to ^

slender elbow
worldly ingot
#

Oh, well then, there ya go

#

Figured the API break would happen eventually

slender elbow
#

I mean

#

bungee chat is just a subset of the spigot api

#

it isn't the first bit that stopped getting updated.. like, the whole of spigot

worldly ingot
#

There haven't been many large API additions to Bukkit or Spigot for the last little while

#

Dialogs feel like the most significant because people actually want to use them

slender elbow
#

i guess

worldly ingot
#

Yeah. Yeah you should guess aPES2_AngeryDistort

quaint mantle
#

I guess

glass zealot
#

Hey, I wanted to ask, how Plugins detect the Client etc. like "... joined with fabric" or "... joined with feather-fabric" or "... joined with lunarclient- 218293-dev". Someone already told me that this will most likely not be uncertain and not reliable. But I dont really mind about that, I just didnt understand how back when the person told me, so I'd appreciate an example!

chrome beacon
glass zealot
slender elbow
#

didn't you get an answer in the paper discord, like, last week when you asked?

glass zealot
#

I only remember that everyone told me its not reliable and stuff

slender elbow
#

yeah, because it isn't

chrome beacon
#

It's not reliable since it can be changed to anything the user wants

slender elbow
#

and after that you were given the method that tells you what you want

slender elbow
#

Bro

#

Serious Spigot and BungeeCord programming/development help

ivory sleet
violet blade
#

Everything u need is already in cmi

quaint mantle
#

great we are now adding another server loader to the question.

violet blade
#

🧽

quaint mantle
#

mohist wen

left holly
#

Hi so I am trying to create a plugin using spigot 1.8 api but I can't find it

chrome beacon
#

Are you using maven or gradle?

buoyant viper
tawny osprey
#

wowwww

wise portal
#

guys i need help in importing my custom /recipes guim ive tried for 5 hours and im still in the exact same place!

young knoll
#

Importing it from what?

weak wasp
#

I am using API 1.8 for my plugin. When I use .dispatchCommand() it will execute on a 1.8 server, but not the 1.21.10 server.
Anyone know what I can do about this?

amber fox
#

Hi! My IP was banned and I dont know why
Can someone help me?
Appears: SpigotMC - High Performance Minecraft Community - Error
Your IP address has been banned.

weak wasp
#

Are you using a VPN?

slender elbow
#

of course, nordvpn, to make my internet browsing experience safe from hackers

#

runs

amber fox
weak wasp
#

lol

flint quiver
#

@worldly ingot

#

@red mauve

#

Can you help him?

eternal oxide
#

?support

undone axleBOT
wise portal
wraith delta
#

How would i make the warden attack a certain player instead of the one who just hit it? it seems vanilla forces the warden to chase a player no matter how many times they die, it will never follow a new player

#

but i need it to chase a new player for a custom system

wraith dragon
torn shuttle
#

somehow wiht each passing day intellij gets worse

#

how is this happening

#

do they just want to lay down and let cursor walk over them or something

#

this is the second time today it has hard gotten stuck

#

when opening a project

#

like 100% unresponsive

#

and it's the 4th time I have to force quit it

#

it also broke my git again

summer scroll
wraith delta
#

I tried that, but the thing is minecraft has that aggression internally hardcoded which somehow wont budge. the target event works for other mobs, its just not working for warden.

wraith dragon
wraith dragon
potent atlas
#

Hi guys!
I'm trying to set a config section to null to erase it but when I check the file everything is still there. Can someone look at my code to see if I'm doing it right? (Yes I am saving the file after editing)
I set up a loop to tell me every key under the node and it successfully printed them in console but still did not erase them from the file.
There are no errors in console.
Here are the methods involved. Let me know if you need to see more.
https://pastes.dev/cwMTh1ZOki

summer scroll
#

Can't tell much from your code, loading and saving looks okay to me.

potent atlas
summer scroll
fierce valley
#

What are the chances a model engine expert i here... and can help me

undone axleBOT
#

If you have a question, please just ask it. Don't look for staff or topic experts. Don't ask to ask or ask if people are awake or available. Just ask the question to the channel straight out, and wait patiently for a reply. Make sure you use the right channel regarding the topic of your question. Create a thread in case the channel is already in use!

fierce valley
#

Damn my bad

#

I have been trying to make a custom model in block bench and place it into model engine so I can run it on my server and later connect it to mythic mobs, I've tried everything, but everytime I make a model and put it in the folder it dont work. However after playing around I could confirm the bbmodel is working with a different file called herobrine. However I cant figure out why I keep getting this long error talking about naming issues...

#

What am I doing wrong?

smoky anchor
#

well if you have an error do send it

#

?paste

undone axleBOT
fierce valley
#
[05:42:24 WARN]: [A] --Warning: Missing hitbox.
[05:42:24 WARN]: [A] --Error: Cannot invoke "String.toLowerCase(java.util.Locale)" because the return value of "com.ticxo.modelengine.api.generator.parser.blockbench.BlockbenchModel$Group.getName()" is null
[05:42:24 WARN]: [A] --Error: Unknown format.
fierce valley
#

Chatgpt said it was a naming issue, but honestly I named everything so I think Ai just failed me here T_T

smoky anchor
#

ofc it tells you that, it probably has no fucking idea what model engine is, it only sees that java error
don't use AI for this...

fierce valley
#

Oh benevolent plugin master pls give me your wisdom what am I doing wrong T_T

smoky anchor
thorn isle
#

modelengine 🚮

#

use that whatever open source version by that whoever guy here instead

smoky anchor
#

FreeMinecraftModels by MagmaGuy
I agree :D

thorn isle
#

that's the one

#

i don't think it's 100% feature complete vs modelengine, but the features it does have for sure work much better

sly topaz
slender elbow
#

yeah that one's better

#

it's literally in the name, so

thorn isle
#

says so on the tin

#

hey it looks like this one does what i was planning to do, with the animated player models composed of textured skulls

#

neat

sly topaz
pseudo hazel
#

imagine naming something Better<x> and actually being better than <x>

young knoll
#

BetterHypixel

left holly
#

Hi so I am trying to create a plugin using spigot 1.8 api but I can't find it (I am using maven)

chrome beacon
smoky anchor
#

Then don't use over a decade old version, update

chrome beacon
#

replace 1.21.5 with 1.8(.8)

thorn isle
#

wasn't the 1.8 artifact removed from the repo at some point

chrome beacon
#

Should still be there

#

You might be thinking of Bungee chat which was removed from sonatype

thorn isle
#

may be, i can't say i've tried to build anything against 1.8 for years

eternal oxide
#

build a newer version before you try to build 1.8

jagged thicket
thorn isle
#

💀

slender elbow
#

lol

smoky anchor
eternal oxide
#

With a beard

smoky anchor
#

Don't you have a kid too ? :D

eternal oxide
#

grandkids

smoky anchor
#

ah ye

quaint mantle
tame wolf
#

Heya! Does anyone know if there were any changes to bossbars? There's a ghost bossbar that won't go away no matter what I do.. Even trying to remove it using /bossbar just removes the actual bossbar my plugins creates

sly topaz
tame wolf
#

Yep, if I log out and back in it's still there

sly topaz
#

did you register a persistent bossbar perhaps?

tame wolf
#

🤨 A few months ago I had an issue where the bossbar wouldn't work unless I used a persistent bossbar

sly topaz
#

there shouldn't be anything that requires persistent bossbars for them to work

#

that being said, I don't know why it is getting duplicated there

tame wolf
#

Alright, I'll try making it non-persistent 😁

#

Now it won't show at all once I relog

hybrid spoke
#

possibly show us the code so we don't have to search the needle in the hay

sly topaz
#

oh, the pathetic guy

tame wolf
#

The method I use to show the bossbar to the player:

#
    public void showEnergyBar(RunePlayer player) {
        if (!Runecraft.getInstance().getRegistry().getInitiated().containsKey(player.getUUID()) || !Runecraft.getInstance().getConfig().getBoolean("RunecraftEnergyBar.Enabled"))
            return;
        EnergyBar bar = Runecraft.getInstance().getRegistry().getPlayerEnergyBar(player.getUUID());
        BossBar bossBar;
        int energy = Runecraft.getInstance().getRegistry().getEnergyReservoir(player.getUUID()).getEnergy();
        if (playerEnergyBars.containsKey(player.getUUID())) {
            bossBar = playerEnergyBars.get(player.getUUID());
            bossBar.setTitle(GOLD + "Runic Energy: " + String.format("%,d", energy));
        } else {
            bossBar = Bukkit.createBossBar(GOLD + "Runic Energy: " + String.format("%,d", energy), BarColor.valueOf(bar.getColor().name()), BarStyle.valueOf(bar.getStyle().getSpigot()));
            playerEnergyBars.put(player.getUUID(), bossBar);
        }
        bossBar.setProgress((float) energy / Initiation.TierCapMapping[Runecraft.getInstance().getRegistry().getInitiated().getOrDefault(player.getUUID(), 0)]);
        bossBar.setVisible(true);
//        Logger.fine("Bossbar is " + bossBar.isVisible() );
        if (!bossBar.getPlayers().contains(Bukkit.getPlayer(player.getUUID())))
            bossBar.addPlayer(Bukkit.getPlayer(player.getUUID()));
        if (Runecraft.getInstance().getConfig().getInt("RunecraftEnergyBar.Timer") != -1) {
            if (playerEnergyBarsTaskIDs.containsKey(player.getUUID())) {
                Bukkit.getScheduler().cancelTask(playerEnergyBarsTaskIDs.get(player.getUUID()));
            }
            playerEnergyBarsTaskIDs.put(player.getUUID(), scheduleDelayedTask(() -> {
                bossBar.setVisible(false);
                playerEnergyBarsTaskIDs.remove(player.getUUID());
            }, 20 * Runecraft.getInstance().getConfig().getInt("RunecraftEnergyBar.Timer")));
        }
    }
#

Which I also call in the OnPlayerJoin event

hybrid spoke
#

you should really use variables instead of calling the same methods all over again

#

would make it more readable

tame wolf
#

Pretty readable to me, I think it's just the discord formatting making it harder for you...

hybrid spoke
#

no, it's the code duplication by always calling getInstance().method1().method2().method3(), which could be much shorter with

var descriptiveVariable = getInstance().method1().method2();
var energyResult = descriptiveVariable.method3();

but that's not the problem here - it's hard to tell where the duplicate bossbar is coming from. i would guess it's either a failed cleanup or the code is executed twice somewhere

tame wolf
#

Anyways, I uncommented the debug line for whether the bossbar is visible

#

It says the bossbar's visibility is true

#

But that's not the case, as there's no bossbar 🤷

tame wolf
#

There are only five places where I call the method for the bossbar, and neither of them work for making it re-appear

#

Unlikely that it's being executed twice, as this is the only place in my codebase where I create a bossbar

#

I'll try making it persistent again 🤔

#

Alright... So after making it persistent on my dev server, it functions fine, however, the production server, where I originally noticed the double bossbar issue, now has zero bossbars! :D lol

left holly
left holly
smoky anchor
left holly
chrome beacon
left holly
chrome beacon
#

Reload your pom

left holly
#

still on red

thorn isle
chrome beacon
#

incase you had a cached fail

autumn cave
#

In https://hub.spigotmc.org/versions/ is it safe to assume that builds between version X (inclusive) and version X+1 (exclusive) are all builds for version X?

For example: 1.21.1.json is at Build #4344, and 1.21.2.json is at Build #4398, so:
Builds 4344 till 4397 are builds for version 1.21.1.

Is this correct, and is this the only/best way to know the build versions per minecraft versions?

nocturne pollen
#

Hey can anyone help me?

i need to use player.performcommand but this dosnt work with 1.21.8... i need to trigger a proxy (velocity) command

chrome beacon
potent atlas
buoyant viper
#

not spigot related, but how should i keep client side js... clean?

#

i want to break up this god-file (contains All the program logic)

#

(web project btw)

#

do i really just need to have like 5 <script src=file.js> tags?

mortal vortex
#

r u using ES6 Modules?

buoyant viper
#

just a folder with index.html and a js file

mortal vortex
#

so just split the JS into files, export the functions, and then inport them in the main js

buoyant viper
#

guh

#

gotta learn how exporting works :(

mortal vortex
# buoyant viper gotta learn how exporting works :(
// js/somefile.js
export function boykisser(xyz) { /* ... */ }
export function fortnite(fn, delay) { /* ... */ }

// js/otherfile.js
export async function skibidi(id) { /* ... */ }

// js/main.js
import { boykisser, fortnite } from './somefile.js';
import { skibidi } from './otherfile.js';
young knoll
#

I think you literally just do export function Ligma()

buoyant viper
#

does a browser understand the import and export keywords?

mortal vortex
#

just use typescript

#

its acronym is that of our Queen

buoyant viper
#

TS = transsexual?

mortal vortex
#

YASSS

#

Is there a Wiki for the Minecraft Server? I want to know in what series to send packets for auth and connection

rough ibex
#

wiki vg merged with mcwiki a while ago

mortal vortex
#

ohh shit

#

tenks

young knoll
#

?protocol

undone axleBOT
weak wasp
#

Making some good progress on my plugin. Should have it published by the end of the night, if not tomorrow night for sure.
Pretty stoked.

pallid ibex
#

is buildtools down?

Starting clone of https://hub.spigotmc.org/stash/scm/spigot/bukkit.git to Bukkit
Exception in thread "main" org.eclipse.jgit.api.errors.TransportException: https://hub.spigotmc.org/stash/scm/spigot/bukkit.git: 502 Bad Gateway
    at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:227)
    at org.eclipse.jgit.api.CloneCommand.fetch(CloneCommand.java:311)
    at org.eclipse.jgit.api.CloneCommand.call(CloneCommand.java:182)
    at org.spigotmc.builder.Builder.clone(Builder.java:1120)
    at org.spigotmc.builder.Builder.startBuilder(Builder.java:302)
    at org.spigotmc.builder.Bootstrap.main(Bootstrap.java:60)
Caused by: org.eclipse.jgit.errors.TransportException: https://hub.spigotmc.org/stash/scm/spigot/bukkit.git: 502 Bad Gateway
    at org.eclipse.jgit.transport.TransportHttp.connect(TransportHttp.java:719)
    at org.eclipse.jgit.transport.TransportHttp.openFetch(TransportHttp.java:465)
    at org.eclipse.jgit.transport.FetchProcess.executeImp(FetchProcess.java:143)
    at org.eclipse.jgit.transport.FetchProcess.execute(FetchProcess.java:95)
    at org.eclipse.jgit.transport.Transport.fetch(Transport.java:1309)
    at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:216)
    ... 5 more```
pallid ibex
#

😭

pallid ibex
#

@ancient plank should we tag someone for this? seems important to me

torn shuttle
#

what causes a teleport of a player to return false? just cancelling the event?

#

I'm having a weird problem with it

rotund ravine
#

Probably invalid too?

torn shuttle
#

that's kind of the thing, best I can tell it's valid

#

it's very weird

echo basalt
torn shuttle
#

def not

echo basalt
#

riding something and that something not teleporting

torn shuttle
#

it's my player entity

#

also not riding

#

waiiiiiiiiiit

#

wait

echo basalt
#

having a passenger

torn shuttle
#

yeah

#

I have a display passenger

#

that does it?

echo basalt
#

Yup

#

not sure if it's valid on spigot but ik on paper you have teleport flags you can use

#

it once took me like 2 hours to figure out why tps werent working

torn shuttle
#

holy shit

#

let me check but I def have one

#

why on earth why on earth would you do this

echo basalt
#

something something position desync or whatever

torn shuttle
#

yeah that was it

echo basalt
#

not as fun as folia killing itself the moment you schedule something onPlayerQuit

torn shuttle
#

that's crazy stupid

echo basalt
#

legit just hard crashes

torn shuttle
#

seems reasonable

thorn isle
#

huh? is there a proper way around the "player can't teleport with passengers" issue on paper now?

#

can i finally put my hacky clientside passenger on passenger bandaid to rest?

remote swallow
thorn isle
#

hm well that doesn't really help unless i fork essentials and every other plugin on the server to use the flag

mortal hare
#

isnt it crazy that we dont have spec first svg editor in 2025
sure there is inkscape
but it always litters your svg with inkscape extensions
also UI feels awful, im sorry but GTK for such an app works so bad. Want to have two panels seen at once, nope, here's a crash for you. QT would've been much better since it packs so many toggles in GUI, that GTK was not even designed for

thorn isle
#

real men use rasters

#

i don't want no math in my pictures

#

you can take your bezier curves and put them where the sun don't shine

sly topaz
#

well, not yet but soon™

#

they're changing the default to retain passengers

thorn isle
#

yeeeees

wooden relic
#

hey y'all 😌 I was wondering if anybody was knowledgeable on Custom Model Data to get custom textures working in-game? I've got the resourcepack set up, however I'm struggling to get the textures to actually apply in-game. I know that the CustomModelData was deprecated in favour of CustomModelDataComponent, however neither of the two are working for me 😅 I'm not really sure what's wrong with my json files and why it's struggling to be mapped unfortunately :/ I've attached the zip of my pack directory, which in-game says has loaded successfully, however no texture seems to be getting applied. I'm on 1.21.7 (running Paper but my plugin is off of Spigot)

public ItemStack getItem() {
    ItemStack item = new ItemStack(Material.ARROW, 1);
    ItemMeta meta = item.getItemMeta();
    if (Objects.nonNull(meta)) {
        ArrayList<String> lore = new ArrayList<>();
//        CustomModelDataComponent cmdc = meta.getCustomModelDataComponent();
//        cmdc.setFloats(List.of((float) 5));
//        meta.setCustomModelDataComponent(cmdc);
        meta.setCustomModelData(1);

        meta.getPersistentDataContainer().set(ARROW, PersistentDataType.STRING, "diamond");
        meta.setDisplayName(ChatUtils.translateToColor(getName()));
        meta.setLore(lore);
        item.setItemMeta(meta);
    }
    return item;
}
smoky anchor
#

You can look at the vanilla RP for inspiration

#

Also, "which in-game says has loaded successfully" take a look into your client logs instead, I think those might show some error. Maybe, I'm not sure what it would do for nonexisting field.

#

Additinally, I'd like to suggest using setItemName instead. This will replace the base name an item has instead of using the "anvil name".

  • if possible, use translatable (with fallback to your custom name) and create a translation file, en_us is enough to start.
young knoll
#

Smh it's en_us

wooden relic
#

thank you for the info!! Regarding the translatable, it’s in the plans hahaha, I have had all text hardcoded as of now, since my plugin has been just for a little survival server with some friends and I, but I’m planning to open up publicly and I’m stepping it up a notch😎

#

Just a question regarding the itemModel component… How do I get access to it, and how does the json get linked? I’m still veeeeery new to model data and all, so it’s all foreign to me 😅 If you happen to be aware of a tutorial that I could follow and learn from, that would be awesome! All I’ve been able to find as of now has been on CMD 🙁

#

I’m assuming it’s just via the getItemModel() method from the ItemMeta, however I’m not sure how it gets mapped to the json

smoky anchor
#

as test you can simply use a "minecraft:stick" on a stone item

ancient plank
# echo basalt something something position desync or whatever

Olden days of Minecraft there were some nasty bugs with entities and passengers in chunks unloaded to you, where a player would be floating somewhere across the world for you and a horse would be moving around you. Probably something related to that tbh

#

i.e. You teleport both the entity and the passenger and it desyncs because of load orders

#

and now it's broken for someone somewhere

wooden relic
#

@smoky anchor progress!! Thank you so much 🙂 I'll try to figure out how to integrate it to my custom models later on today

smoky anchor
#

Feel free to tag me (with context of our conversation 'cause I might forget)

hybrid spoke
smoky anchor
#

Why does someone remember that lmao

remote swallow
#

it was 10 days ago

smoky anchor
#

This is why I added the note about context hahahaha

smoky anchor
alpine solar
#

@smoky anchor hi

visual zealot
#

Hello,
I try to update my old bukkit plugin to spigot. I had this code that would work previously, but unfortunately ItemMeta does not survive to Inventory#setItem().

The output should be 1true, 2true, but it is 1true, 2false. Could you tell me what is wrong here?

    mystack = new ItemStack(Material.WRITTEN_BOOK);
    final BookMeta mybook = (BookMeta) mystack.getItemMeta();
    mystack.setItemMeta(mybook);
    log.info("1"+mystack.hasItemMeta());
    inventory.setItem(index, mystack);
    log.info("2"+inventory.getItem(index).hasItemMeta());
pseudo hazel
#

yes

#

thats definitely minecraft code

slender elbow
#

I'm not sure

quaint mantle
#

Should be.

full breach
#

need someone whos good at compiling plugins dm me youll be compensated aswell

slender elbow
#

how will i be compensated

#

!!!

quaint mantle
sullen marlin
visual zealot
# sullen marlin You've done nothing to the book meta though

In fact I stripped the part where I set an author before. The full code is here:
if (mystack == null || ! mystack.getType().equals(Material.WRITTEN_BOOK)) { mystack = new ItemStack(Material.WRITTEN_BOOK); } //final BookMeta mybook = (BookMeta) Bukkit.getServer().getItemFactory().getItemMeta(Material.WRITTEN_BOOK); final BookMeta mybook = (BookMeta) mystack.getItemMeta(); if (name != null) { final String myauthor = prefix + "." + name; mybook.setAuthor(myauthor); } else { mybook.setAuthor(prefix); } mystack.setItemMeta(mybook); ByteCart.log.info("1"+mystack.hasItemMeta()); ByteCart.log.info("2"+mystack.getType().isItem()); ByteCart.log.info("3"+index); ByteCart.log.info("4"+mybook.getAsString()); ByteCart.log.info("4"+((BookMeta)mystack.getItemMeta()).getAuthor()); inventory.setItem(index, mystack); ByteCart.log.info("5"+inventory.getItem(index).hasItemMeta()); inventory.getItem(index).setItemMeta(mybook); ByteCart.log.info("6"+inventory.getItem(index).hasItemMeta()); BookMeta meta = (BookMeta) inventory.getItem(index).getItemMeta(); ByteCart.log.info("7"+(meta.getAuthor()));

#

and the output is:
[21:36:02] [Server thread/INFO]: 1true
[21:36:02] [Server thread/INFO]: 2true
[21:36:02] [Server thread/INFO]: 310
[21:36:02] [Server thread/INFO]: 4{}
[21:36:02] [Server thread/INFO]: 4ByteCart.ticket
[21:36:02] [Server thread/INFO]: 5false
[21:36:02] [Server thread/INFO]: 6false
[21:36:02] [Server thread/INFO]: 7null

#

I expect 5 and 6 to be true

chrome beacon
#

(send the output from /version)

visual zealot
#

The last : 1.21.10-R0.1-SNAPSHOT

#

I tried on older 1.20.1 and it works with this version

chrome beacon
#

Send the output

visual zealot
#

[22:36:19] [Server thread/INFO]: This server is running CraftBukkit version 4542-Spigot-6e369ba-59f1b90 (MC: 1.21.10) (Implementing API version 1.21.10-R0.1-SNAPSHOT)
[22:36:19] [Server thread/INFO]: Checking version, please wait...
[22:36:20] [Thread-3/INFO]: You are running the latest version

outer ember
#

how to save a hashmap to world

echo basalt
#

?PDC

#

?pdc

echo basalt
#

discord pls

wild mulch
#

how do i parse a entity selector with the spigot api? (Selectors such as '@e[type=pig,distance=..3]'

#

while being local to the executor

#

or a entity put in

echo basalt
#

Bukkit.selectEntities(sender, selector)

wild mulch
#

ok

#

what happens if its invalid

visual zealot
wild mulch
#

what happens if the selector is invalid

weak wasp
#

Well guys I'm finally done my plugin which I'm happy about, but now I'm super bored that I have nothing to work on.

weak wasp
daring light
#

What would be the best way to share data with two plugins? I'm working on plugin 1 which needs to find out if a player is AFK, and I want to connect plugin 2 which handles that. Ideally I want plugin 1 to not depend on anything, rather plugin 2 having the capability to connect with plugin 1. Is this possible?

gaunt tangle
#

Pinata plugin

#

Do you know the pinata plugin which is free?

mortal vortex
visual zealot
# visual zealot Hello, I try to update my old bukkit plugin to spigot. I had this code that woul...

I made some new tests and it stopped working starting with 1.20.5 since 2024/04/23:
OK: This server is running CraftBukkit version 4090-Spigot-b754dcc-38b1f49 (MC: 1.20.4) (Implementing API version 1.20.4-R0.1-SNAPSHOT)
NOK: This server is running CraftBukkit version dev-Spigot-b698b49-735b2d0 (MC: 1.20.5) (Implementing API version 1.20.5-R0.1-SNAPSHOT)

I suppose this is linked to this change: https://hub.spigotmc.org/stash/projects/SPIGOT/repos/craftbukkit/commits/735b2d0d7f10bc3b3a816e103cc86af8cb1ec645#src%2Fmain%2Fjava%2Forg%2Fbukkit%2Fcraftbukkit%2Finventory%2FCraftItemStack.java?f=709

ripe depot
#

when i cancel an InventoryClickEvent, does it still get passed to PrepareAnvilEvent? or does that happen after?

worldly ingot
# mortal vortex API interface?

Yeah this is the way to go about it. And to be clear, plugin 1 is the one that would be providing the interface and calling its methods. Plugin 2 would be the one implementing and registering it.

#

Think of it like this. You want your plugin 1 to know about AFK players. You don't care who or what tells you whether or not a player is AFK, you just want to know if that is the case. The plugin 2 comes in and provides that data for you.

echo basalt
#

make a module that provides API interfaces

#

make a module that implements them

#

uh

worldly ingot
#

He said he wants no dependencies on plugin 1. But yes ideally you would have some sort of service providing plugin that both plugins depended on

echo basalt
#

hasMetadata("AFK") be like

worldly ingot
#

That is also certainly an option

#

and a valid use case for the metadata API

onyx fjord
thorn isle
#

i use it quite a bit

#

it's very convenient if a bit verbose

#

many cases that would typically be handled through events are better handled through a service provider

quaint mantle
thorn isle
#

can't really do anything better without api between the plugins and cross-dependencies

#

or i suppose you could have it be configurable in both plugins but that doesn't seem that much better

onyx fjord
#

Do you want your metadata keys translatable in config

#

npc is also very common

echo basalt
#

uh

#
public final class MetadataKeys {

  public static final String AFK_KEY = "AFK"; 
  public static final String IS_NPC_KEY = "NPC";

  private MetadataKeys() {
    throw new IllegalStateException("buddy are you really initializing this via reflection");
  }
}
smoky anchor
#

damn you're fast

echo basalt
#

I'm used to typing in discord

#

no need for an IDE

slender elbow
#

yeah but that requires adding a dependency just for a stupid simple "NPC" string

outer ember
#

can somone explain me to how to save a hashmap to my world?

thorn isle
#

depends on what's in the hashmap

#

not all data types are trivially serializable

outer ember
#

uh

outer ember
thorn isle
#

are you sure you want to save it directly on the world? instead of, say, a file on disk associated with that world?

#

if you want to save it directly on the world, you'll need to use the world's PDC; for a flatfile, things can be easier

outer ember
#

Oh my wifi just broke

onyx fjord
#

For what purpose

outer ember
#

it not visible by owners

#

u know what i mean

#

feels better

thorn isle
#

better access to the data by admins is generally better

worldly ingot
#

I assure you it's still visible to server owners if they have an NBT editor program :p

#

All data is readable

thorn isle
#

"it just works" style shoving of things under the hood is usually not the best way to go

outer ember
#

it's not that important

thorn isle
#

either way, i'd probably serialize it into a json string with maybe gson and shove it in the world PDC

outer ember
#

but i dont like it being visible easily
i don't know why

thorn isle
#

or if you want flatfile, in a <world-uid>.json

outer ember
#

it just feels better

thorn isle
#

someone linked you the pdc docs last time you asked

outer ember
#

can somone just tell me how to

thorn isle
#

for gson you can find tutorials online i'm sure

#

i'm not writing it for you

outer ember
thorn isle
#

world.getPersistentDataContainer()

#

the API is the same

outer ember
#

no explanation for hashmap

thorn isle
#

serialize it with gson

outer ember
#

i did

thorn isle
#

then put the String in the PDC

#

gson turns things into strings

#

you turn your hashmap into a string

#

then put the string in the PDC

outer ember
#

PersistentDataContainer data = world.getPersistantDataContainer

data. -> no tab complete

thorn isle
#

what

#

look at the api docs

outer ember
#

i cant use data.set

slender elbow
#

you don't need tab completion when you have the javadocs and other usage documentation :D

thorn isle
#

what version are you building against?

#

don't tell me 1.8

outer ember
#

1.20.1

thorn isle
#

PDC should be on 1.20

#

let's see your class with full imports

slender elbow
#

should be = is

outer ember
#

Oh my pcccc

thorn isle
#

let's also see your build script

smoky anchor
outer ember
#
HashMap<UUID,Intenger> wanted = new HashMap<>();
NamespacedKey key = new NamespacedKey(NovaPolice.getInstance(),"wanteds_info");
World world = Bukkit.getWorlds.get(0);
PersistantDataContainer data = world.getPersistantDataContiner();
String json = new Gson().toJson(wanted);
data.```
#

if i put .set
after world.getPersistantDataContainer()
it works
but does not works after
data

slender elbow
#

did you just type that out on discord or did you copy/paste from your ide?