Skip to content

How to Start a Plugin

Fulminazzo edited this page Oct 17, 2023 · 2 revisions

Welcome to BearCommands Wiki!
In here you will find any information regarding the plugin features and how to use them. In this page we will see how you can start your enhanced BearCommands plugin. Note that as of version 7.0, BearCommands supports Bukkit (Spigot, Paper), BungeeCord and Velocity as platforms.

Contents
Install BearCommands.jar
Download and import Maven dependency
Create the Main Class of the Plugin
Working with the BearPlugin classes

Install BearCommands.jar

First thing first, you will need to download the latest BearCommands.jar file and put it in your server plugins folder. This passage is required and essential because your project will inherit every class and method from BearCommands.

Download and import Maven dependency

As of writing this Wiki, BearCommands is still in no public repository yet. This means that in order to use it, you will need to clone this repository in your local machine. You can then build it using Maven with the scope install. This will make sure to build the latest BearCommands jar and save its classes in your local Maven repository.
You are now ready to import BearCommands as a dependency in your project:

<dependencies>
    <dependency>
        <groupId>it.angrybear</groupId>
        <artifactId>BearCommands</artifactId>
        <version>7.1</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

It is crucial that you use provided inside the scope tags, otherwise your plugin will be built with the BearCommands classes inside it. While this might sound convenient, since you will not be required anymore to Install BearCommands.jar in your server, it is actually a downside both for your plugin and for others: not only you will make it much heavier than necessary, but if in the future you will create more projects on top of BearCommands, loading the same classes with different Class Loaders might lead to problems and inconveniences.

Create the Main Class of the plugin

You are finally ready to start working on your plugin. By importing the correct BearPlugin class to your Main Class, you will get access to many BearCommands features without having to worry about it. You can check the other How-Tos pages for more, in here we will simply see some examples on how to implement BearCommands in every platform.

Create the Main Class of the plugin (Bukkit)

All you have to do to start working on Bukkit is importing the BearPlugin class.

package it.fulminazzo.testplugin;

import it.angrybear.Bukkit.BearPlugin;
import it.angrybear.Bukkit.Objects.BearPlayer;

public class TestPlugin extends BearPlugin<BearPlayer, BearPlayer> {
}

NOTE: do not forget to specify BearCommands in your depend or soft-depend section! As you can see, this class requires two classes that extend the BearPlayer class. We will look into CustomPlayers later in this Wiki, for now you do not have to worry about it. In fact, you can even skip entirely the BearPlayer part by using the SimpleBearPlugin class:

package it.fulminazzo.testplugin;

import it.angrybear.Bukkit.SimpleBearPlugin;

public class TestPlugin extends SimpleBearPlugin {
}

Create the Main Class of the plugin (BungeeCord)

The BungeeCord part of BearCommands is very similar to the Bukkit part:

package it.fulminazzo.testplugin;

import it.angrybear.Bungeecord.BungeeBearPlugin;
import it.angrybear.Bungeecord.Objects.BungeeBearPlayer;

public class TestPluginBungeeCord extends BungeeBearPlugin<BungeeBearPlayer> {
}

All you have to do in order to start working with the BearCommands library is to extend the BungeeBearPlugin class and pass a class that extends the BungeeBearPlayer class. We will look into CustomPlayers later in this Wiki, for now you do not have to worry about it. There is also a shorter version if you want to neglect the player part:

package it.fulminazzo.testplugin;

import it.angrybear.Bungeecord.BungeeSimpleBearCommandsPlugin;

public class TestPluginBungeeCord extends BungeeSimpleBearCommandsPlugin {
}

Create the Main Class of the plugin (Velocity)

With Velocity, things tend to get a little bit trickier. Since there is no plugin.yml or bungee.yml to specify which is the main class, extending a class from BearCommands will not be enough:

package it.fulminazzo.testplugin;

import com.google.inject.Inject;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.ProxyServer;
import it.angrybear.Velocity.Objects.VelocityBearPlayer;
import it.angrybear.Velocity.VelocityBearPlugin;
import org.slf4j.Logger;

import java.nio.file.Path;

@Plugin(
        id = "testplugin",
        name = "TestPlugin",
        version = "1.0",
        authors = {"Fulminazzo"}
)
public class TestPluginVelocity extends VelocityBearPlugin<VelocityBearPlayer> {

    @Inject
    public TestPluginVelocity(ProxyServer proxyServer, Logger logger, @DataDirectory Path dataDirectory) {
        super(proxyServer, logger, dataDirectory);
    }

    @Override
    public String getName() {
        return "TestPlugin";
    }

    @Override
    public String getVersion() {
        return "1.0";
    }
}

As you might tell, this is not very different from creating a normal Velocity plugin: you are still required to use the Plugin annotation, as long as the Inject and DataDirectory ones. However, in order to make BearCommands "universal" across platforms, you are required to provide a getName and a getVersion methods (which are provided by default in the Bukkit and BungeeCord counterparts). Also, you are required to pass a class that extends the VelocityBearPlayer class. We will look into CustomPlayers later in this Wiki, for now you do not have to worry about it. Here is the implementation with the simpler VelocitySimpleBearPlugin class, which does not require the player part at all:

package it.fulminazzo.testplugin;

import com.google.inject.Inject;
import com.velocitypowered.api.plugin.Plugin;
import com.velocitypowered.api.plugin.annotation.DataDirectory;
import com.velocitypowered.api.proxy.ProxyServer;
import it.angrybear.Velocity.VelocitySimpleBearPlugin;
import org.slf4j.Logger;

import java.nio.file.Path;

@Plugin(
        id = "testplugin",
        name = "TestPlugin",
        version = "1.0",
        authors = {"Fulminazzo"}
)
public class TestPluginVelocity extends VelocitySimpleBearPlugin {

    @Inject
    public TestPluginVelocity(ProxyServer proxyServer, Logger logger, @DataDirectory Path dataDirectory) {
        super(proxyServer, logger, dataDirectory);
    }

    @Override
    public String getName() {
        return "TestPlugin";
    }

    @Override
    public String getVersion() {
        return "1.0";
    }
}

Working with the BearPlugin classes

The BearPlugin classes offer a lot of features such as automatic configurations loading, custom players handling, messaging channels handling and more. Although many of these are automatically handled, you might want to edit or work on some methods, or maybe add functioning on various events. According to what you are looking to achieve, you can simply override some methods. We will use the Bukkit implementation as an example, but note that this will work across all the platforms:

package it.fulminazzo.testplugin;

import it.angrybear.Bukkit.SimpleBearPlugin;
import it.fulminazzo.testplugin.Listeners.PlayerListener;
import it.fulminazzo.testplugin.Managers.MyCustomManager;
import org.bukkit.Bukkit;

public class TestPlugin extends SimpleBearPlugin {
    private MyCustomManager myCustomManager;

    // Overriding the onEnable method to add a custom message.
    @Override
    public void onEnable() {
        super.onEnable();
        logInfo("Plugin successfully enabled!");
    }

    // Overriding the onDisable method to add a custom message.
    @Override
    public void onDisable() {
        super.onDisable();
        logInfo("Plugin successfully disabled... :(");
    }

    // Overriding the loadAll method, responsible for calling every
    // "load" method, in order to add a new load call.
    @Override
    public void loadAll() throws Exception {
        super.loadAll();
        loadMessages();
    }

    public void loadMessages() {
        /*...*/
    }

    // Overriding loading config to disable config checking.
    @Override
    public void loadConfig() throws Exception {
        this.loadGeneral("config.yml", false);
        this.reloadConfig();
    }

    // Overriding loading managers to add a new manager.
    @Override
    public void loadManagers() {
        super.loadManagers();
        myCustomManager = new MyCustomManager();
    }

    // Overriding loading listeners to add a new listener.
    @Override
    public void loadListeners() {
        super.loadListeners();
        Bukkit.getPluginManager().registerEvents(new PlayerListener(), this);
    }

    // Overriding loadPlaceholders to print a message of debugging.
    // NOTE: Only available in Bukkit.
    @Override
    public void loadPlaceholders() throws Exception {
        super.loadPlaceholders();
        logWarning(String.format("Loaded %s placeholders", getPlaceholders().size()));
    }
}

Working with dependencies

If your plugin uses other plugins, you might have come across some ugly UnknownDependencyException stacktraces in your console when the required dependencies are nowhere to be found. While you, the developer, know exactly that plugins to use in order to load your own, your users will not (or simply will be too lazy to read them).
To avoid any useless report both for you (the developer) and the end user, every BearPlugin class offers a requires() method, which allows to specify the requirements for your plugin.
Say your project depends on ProjectA (example plugin). All you have to do is specify it as a soft-depend:

soft-depend: [ProjectA]

and call the requires() method:

@Override
public void onEnable() {
    //NOTE: it is CRUCIAL that you specify the dependencies BEFORE calling the super.onEnable() method.
    requires("ProjectA");
    super.onEnable();
}

This way, when loading the plugin, if ProjectA is not found, the user will receive a console warning notifying them.

Clone this wiki locally