30 APIv4
Aurora Lahtela edited this page 2022-10-30 11:35:19 +02:00

Plan Header

Plan API

⚠️ Deprecation notice ⚠️

This part of the API is deprecated, and some of it's functionality may not be present in a future version. Last non deprecated version with this API is 4.7.2 and above that it is deprecated, and does not function.

The users of PluginData API are encouraged to migrate to DataExtension API as soon as possible. PluginData API has been decommissioned and will no-op if one tries to register one.

This page is about the API that is available in version 4.1.5 and above, mainly how to register data from your plugin to be displayed on the website.

API can be called on Bukkit & Bungee.

Important Classes

Accessing API

Install the Plan.jar as a local dependency if you're using Maven. Add soft-depend or depend in the plugin.yml

Maven dependency information.

<dependency>
    <groupId>com.djrapitops</groupId>
    <artifactId>Plan</artifactId>
    <version>4.2.0-SNAPSHOT</version>
    <scope>provided</scope>
</dependency>

Getting PlanAPI instance

try {
    PlanAPI planAPI = PlanAPI.getInstance();
} catch (IllegalStateException e) {
    // Plan has not enabled properly
} catch (NoClassDefFoundError e) {
    // Plan is not installed
}

You might want to do the API check in a separate class in case Plan is not installed - Otherwise loading the class might throw a NoClassDefFoundError

In that case you should add the method above inside your separate class:

if (getPlugin("Plan") != null) {
    new PlanHook().registerPluginData() // Just an example
}

PluginData

Picture

Registering your PluginData class

// API planAPI Assumed available

planAPI.addPluginDataSource(new YourPluginDataObject(...));

Well now that you know how to register PluginData, how can you make one and what can you do with it?

Basic Example:

public class YourPluginDataObject extends PluginData {

    public YourPluginDataObject() {
        super(ContainerSize.THIRD, "YourPluginName");
        super.setPluginIcon("check");
        super.setIconColor("green");
    }

    @Override
    public InspectContainer getPlayerData(UUID uuid, InspectContainer inspectContainer) throws Exception {
        // Add items to inspectContainer
        return inspectContainer;
    }

    @Override
    public AnalysisContainer getServerData(Collection<UUID> uuids, AnalysisContainer analysisContainer) throws Exception {
        // Add items to analysisContainer
        return analysisContainer;
    }
}

Let's go through the example bit by bit

ContainerSize-value

ContainerSize determines how big of a box appears on the plugin tab.

There are three sizes and a special case available: THIRD, TWO_THIRDS, WHOLE & TAB
Before you go make yourself the biggest baddie on the playground, consider what a big empty box says to your users. It is recommended that THIRD is used, unless you add custom HTML or tables larger than 4 columns

setPluginIcon- & setIconColor-methods

This icon appears on the header of your plugin box.

You can choose any of these available icons: http://fontawesome.io/icons/
The icon color can be one of these colors: https://gurayyarar.github.io/AdminBSBMaterialDesign/pages/ui/colors.html

If no color or icon is provided the default icon is a black cube.

return-value

The container given to the method should be returned. - If nothing is added to the container or null is returned nothing is displayed on the plugins tab. (It will look like the plugin is not installed)

If you want your plugin to show up even without data add a dummy value with "No Data"

InspectContainer (PluginData)

InspectContainer is where you place your data about a single player. The UUID of the player is given in the method, and it is up to you to place your data inside the container.

InspectContainer supports single row values, tables & custom html.

  • Values are parsed as <p>label: value</p>
  • Html is added as it is
  • Tables are made with TableContainer. More on TableContainer later.

Adding values:

@Override
public InspectContainer getPlayerData(UUID uuid, InspectContainer inspectContainer) throws Exception {
    inspectContainer.addValue("Label", YourDataProvider.getData(uuid);
    inspectContainer.addValue(getWithIcon("LabelWithIcon", "iconName", "iconColor"), YourDataProvider.getData(uuid);
    return inspectContainer;
}

getWithIcon-method

getWithIcon is a helper method in PluginData for adding icons to your values.
It supports similar values as setPluginIcon & setIconColor.
If you need an icon without color, use getWithIcon("Label", "iconName")

Adding Custom HTML:

@Override
public InspectContainer getPlayerData(UUID uuid, InspectContainer inspectContainer) throws Exception {
    inspectContainer.addHtml("htmlIdentifier", "<div>YourCustomHtml</div>");
    return inspectContainer;
}

Adding Tables (TableContainer):

@Override
public InspectContainer getPlayerData(UUID uuid, InspectContainer inspectContainer) throws Exception {
    TableContainer tableContainer = new TableContainer("Column 1", "Column 2"); // String... constructor
    tableContainer.setColor("blue");

    tableContainer.addRow(data1, data2); // Serializable... method

    inspectContainer.addTable("tableIdentifier", tableContainer);
    return inspectContainer;
}

TableContainer#setColor supports similar values as setIconColor.

Column names support getWithIcon helper method.

If tableContainer.addRow(Serializable... values) has less values than table header, a dash - is added instead. If too many values are given the overflowing ones are ignored.

AnalysisContainer (PluginData)

AnalysisContainer is for adding data about all of the players. The UUIDs of all known players is given to the method.

AnalysisContainer extends InspectContainer, so all methods that are available for InspectContainer are available for AnalysisContainer. Read the section above for methods of InspectContainer

In addition to values, tables & html AnalysisContainer supports adding values to the PluginData Playerlist.

Adding values to Playerlist

@Override
    public AnalysisContainer getServerData(Collection<UUID> uuids, AnalysisContainer analysisContainer) throws Exception {
        Map<UUID, ? extends Serializable> userMap = new HashMap<>();
        // Add player specific values to userMap
        analysisContainer.addPlayerTableValues(getWithIcon("Column name", "columnIcon"), userMap);
        return analysisContainer;
    }

addPlayerTableValues supports all maps with Map<UUID, ? extends Serializable>, so for example Map<UUID, String>, Map<UUID, Integer>, Map<UUID, Double> are all applicable.

If you're adding boolean values to the table, it is recommended to add String instead with booleanValue ? "Yes" : "No"

If you're adding double values to the table, it is recommended to cut the decimals with FormatUtils.cutDecimals(double)

It doesn't matter if you add values to map with an UUID Plan doesn't know, it will not show up in the playerlist nor cause any issues.

BanData (PluginData)

BanData interface is for Plugins that affect player's ban status. The data is taken into account when placing (Very Active)/(Banned) to the main Playerlist.

Only PluginData objects can be added to Plan so implements BanData should be in some PluginData class.
If you don't want anything other than define Banned status don't add values to the inspect- or analysisContainer.

Define Banned status:

    @Override
    public boolean isBanned(UUID uuid) {
        try {
            return // Is the UUID banned?
        } catch (SQLException e) {
            Log.toLog(this.getClass().getName(), e);
        }
        return false;
    }

    @Override
    public Collection<UUID> filterBanned(Collection<UUID> collection) {
        try {
            return collection.stream().filter(/* Only those that are banned */).collect(Collectors.toSet());
        } catch (SQLException e) {
            Log.toLog(this.getClass().getName(), e);
        }
        return new HashSet<>();
    }