Skip to content

Developer API

Niall7459 edited this page Aug 22, 2020 · 3 revisions

This page is for developers who wish to integrate KiteBoard functionality into their plugins or extend KiteBoard's built in features.

The examples on this page are only available on KiteBoard versions 3.1 and above.

Contents:

Getting started

Download and install the API

You must first get a copy of the KiteBoard API from the releases page.

Install the jar file as a dependency in your local maven repository:

mvn install:install-file 
-Dfile=kiteboard-api-1.0-SNAPSHOT.jar 
-DgroupId=net.kitesoftware
-DartifactId=kiteboard-api 
-Dversion=3.2.2
-Dpackaging=jar 
-DgeneratePom=true

Importing with Maven

<dependency>
  <groupId>net.kitesoftware</groupId>
  <artifactId>kiteboard-api</artifactId>
  <version>3.2.2</version>
</dependency>

Importing with Gradle

repositories {
    mavenLocal()
}

dependencies {
    compileOnly "net.kitesoftware:kiteboard-api:3.2.2"
}

Preparing your Plugin

If you intend to use the KiteBoard interface, you must ensure that it is loaded before for your plugin to access. You can enforce this by adding it as either a depend or a softdepend in your plugin YAML file.

If your plugin cannot run without KiteBoard

depend:
 - "KiteBoard"

If your plugin can run without KiteBoard, but some features depend on it

softdepend:
 - "KiteBoard"

Accessing the API

The KiteBoard Interface is provided to third-party applications using the ServicesManager. It is recommend that you check the Service Registration exists before attempting to access methods from the KiteBoard Interface.

package org.example;

import net.kitesoftware.board.KiteBoard;
import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin;

public class ExamplePlugin extends JavaPlugin {
    @Override
    public void onEnable() {
        RegisteredServiceProvider<KiteBoard> serviceProvider =
                getServer().getServicesManager().getRegistration(KiteBoard.class);

        if (serviceProvider == null) {
            return;
        }

        KiteBoard kiteBoard = serviceProvider.getProvider();
    }
}

KiteBoard Interface

The KiteBoard Interface serves as the entry point for third-party applications to interact with the main KiteBoard components.

Managing groups

Group Types

Table 1: Available values on enumeration GroupType

Name Description Since
GroupType.SCOREBOARD Refers to the on-screen sidebar displayed to users 1.0
GroupType.TABLIST Refers to the player list section displayed when pressing tab. 2.0

Get an instance of the Group Manager

GroupManager groupManager = kiteBoard.getGroupManager();

Retrieving a group

Since group's of different types may share the same name, the GroupType value is required to rule out any ambiguity.

Optional<Group> result = groupManager.getGroup("main_board", GroupType.SCOREBOARD);

Group information

Table 2: Public methods on class Group

Method Description Return type
getName Get the group name String
getCriteria Get the group's criteria Criteria
getType Get the group's type GroupType
getShowDelay Get the group's show delay in ticks Int
getPriority Get the group's priority Int

Group criteria

The getCriteria method returns an object of type Criteria. If the group is configured with a nested criteria or multiple criteria, it's likely the return type is a CriteriaContainer, see Traversing criteria

Managing Criteria

Criteria Registry

CriteriaRegistry criteriaRegistry = kiteBoard.getCriteriaRegistry();

Registering a criteria with an identifier and factory:

criteriaRegsitry.registerCriteria(id, factory);

Unregistering a criteria by it's identifier:

criteriaRegistry.unregister(id);

Internal criteria

Table 3: Default criteria provided by KiteBoard

Identifier Description
PERMISSION Permission based criteria, see Assignment Criteria
WORLD World based criteria, see Assignment Criteria
EVENT Event based criteria, see Assignment Criteria
CONTAINER Group criteria, see Assignment Criteria#Advanced-criteria

Criteria Factories

To register a custom criteria class, you need to build a factory that will provide a new instance of your class from a specified configuration file

Creating a criteria factory:

Criteria factories can be expressed as a Java 8 lambda.

// Style 1, Method reference 
Criteria.Factory<MyCriteria> factory = MyCriteria::new;

// Style 2, Lambda
Criteria.Factory<MyCriteria> factory = (config) -> new MyCriteria(config);

Creating a custom criteria

KiteBoard provides the AbstractCriteria class you can use to build your own criteria. It provides access to the configuration section of the criteria. Separate criteria instances exist for separate configurations and no Criteria instance will be used over different configurations.

This means you can do processing within the constructor instead of in the isMet method to reduce overhead at runtime.

Custom criteria example

This example creates a custom criteria which will return true when the player's name is equal to the one in the configuration:

public class PlayerCriteria extends AbstractCriteria {
    public PlayerCriteria(ConfigurationSection config) {
        super("PLAYER", config);
    }

    @Override
    public boolean isMet(KiteUser kiteUser) {
        return kiteUser.getPlayer().getName()
                .equals(getConfiguration().getString("player"));
    }

    @Override
    public String toString() {
       return "Player (name = " + config.getString("player") + ")";
    }
}

This criteria needs registering with the CriteriaRegistry before it can be used in a KiteBoard configuration:

Notes:

  • Criteria should make sure they have a defined toString method that describes the criteria.
  • Criteria identifier's should always be in upper case, and prefer underscores over spaces

Table 4 Identifier naming rules.

Identifier Allowed
PLAYER YES
PLAYER_NAME YES
PLAYER NAME NO
Player_Name NO
Player NO
kiteBoard.getCriteriaRegistry().registerCriteria("PLAYER", PlayerCriteria::new);

Using the criteria within a group configuration:

Our new criteria can be used within any group configuration file using the standard criteria format as such:

criteria:
  1:
    type: IDENTIFIER
    option1: ..
    option2: ..

For our custom criteria the configuration will look like this:

criteria:
  1:
    type: PLAYER
    player: "Notch"

Checking the criteria has been registered at runtime.

KiteBoard will log all registered criteria in the console as they are being registered.

[KiteBoard] Registered criteria 'PLAYER'

Supplying dependencies to a criteria via constructor using a factory.

Logger logger = ...
MyPlugin plugin = ...

Criteria.Factory<MyCriteria> factory = (config) -> {
    return new MyCriteria(config, logger, plugin);
}

Traversing criteria

Since criteria may contain sub-criteria, it's important to check this when traversing all the criteria in a group.

Criteria criteria = group.getCriteria();
traverse(criteria)

private void traverse(Criteria criteria) {
  if (criteria instanceof CriteriaContainer) {
    CriteriaContainer container = (CriteriaContainer) criteria;
    for (Criteria subCriteria : container.getCriteria()) {
      traverse(criteria);
    }
  } else {
    System.out.println(criteria);
  }
}

Managing Users

The KiteUser class is used to represent players in a KiteBoard context. Methods involved with setting, getting groups for players are within this class.

Retrieve a user

KiteUser user = userManager.getUser(player.getUniqueId());

User's represent a Player

// get the native player
Player bukkitPlayer = user.getPlayer();

Supported user operations

Some methods are currently only supported with certain GroupType values in mind. Attempting to invoke a method with an unsupported group type will throw an UnsupportedOperationException.

Table 5 supported GroupType operations on class KiteUser

Name GroupType.SCOREBOARD GroupType.TABLIST
updateGroup Supported Supported
setGroupOverride Supported Supported
isGroupOverridden Supported Supported
isGroupEnabled Supported Unsupported
setGroupEnabled Supported Unsupported
getCurrentGroup Supported Unsupported

Refreshing a user's groups

Refresh a specific group type:

user.updateGroup(GroupType.SCOREBOARD);

See Table 1: Group Types for available group types.

Refreshing all a user's groups:

user.updateGroups();

Get the current assigned group

This methods get's the users current group from the specified GroupType. This method will return the group of an overridden GroupType as well, to check if a group is overridden, see Checking if a group is overridden

user.getCurrentGroup(groupType);

See Table 1: Group Types for available group types.

Code example:

Optional<Group> group = user.getCurrentGroup(GroupType.SCOREBOARD);

if (group.isPresent()) {
  // user has a scoreboard.
  if (user.isGroupOverridden(GroupType.SCOREBOARD)) {
    user.getPlayer().sendMessage("Override scoreboard: " + group.getName());
  } else {
    user.getPlayer().sendMessage("Assigned scoreboard: " + group.getName());
  }
} else {
  // no scoreboard assigned.
  user.getPlayer().sendMessage("You do not have a scoreboard");
}

Overriding a group

Overriding a group disables the automatic group updating provided by KiteBoard. Whilst a group is overridden user's will not receive any different groups for the overridden group type. This means that features such as event triggers will also not execute.

Note: There is no need to first check the result of isGroupEnabled, KiteBoard will do this internally on all methods before attempting to make changes.

user.setGroupOverride(groupType, group);

See Retrieving a group

Example

Optional<Group> result = kiteBoard.getGroupManager().getGroup("main_board", GroupType.SCOREBOARD);

if (result.isPresent()) {
    user.setGroupOverride(GroupType.SCOREBOARD, result.get());
}

Checking if a group is overridden

user.isGroupOverridden(groupType);

See Table 1: Group Types for available group types.

Code Example

if (user.isGroupOverridden(GroupType.SCOREBOARD)) {
  //scoreboard is overridden
}

Removing an overridden group

user.setGroupOverride(groupType, null);

See Table 1: Group Types for available group types.

Code example:

//reset the tablist group
user.setGroupOverride(GroupType.TABLIST, null);

Enabling or disabling a group Note: this refers to user-level toggling system, not the configuration options in config.yml

user.setGroupEnabled(groupType, boolean);

See Table 1: Group Types for available group types.

Code example:

// Enable the scoreboard
user.setGroupEnabled(GroupType.SCOREBOARD, true);

Checking if a group is enabled

Note: this refers to user-level toggling system, not the configuration options in config.yml

user.isGroupEnabled(groupType);

See Table 1: Group Types for available group types.

Code example:

// check if the scoreboard is enabled
if (user.isGroupEnabled(GroupType.SCOREBOARD)) {
    //scoreboard is visible
}