| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |

This page is about API that is available in version 4.8.0 and above.
API can be called on all platforms.
This API requires DATA_EXTENSION_VALUES capability.
See APIv5 for dependency information
๐ญ What is this API for?
DataExtension API is for adding data from your plugin to Plan so that it can be displayed on the Plan website.
DataExtension API is used for providing Plan with data of your plugin, so that the data can be viewed on the web panel.
This makes it easier for users to reason about their server.
You can follow this step-by-step guide for getting started with the API.
try {
DataExtension yourExtension = new YourDataExtensionImplementation();
ExtensionService.getInstance().register(yourExtension);
} catch (NoClassDefFoundError planIsNotInstalled) {
// Plan is not installed, handle exception
} catch (IllegalStateException planIsNotEnabled) {
// Plan is not enabled, handle exception
} catch (IllegalArgumentException dataExtensionImplementationIsInvalid) {
// The DataExtension implementation has an implementation error, handle exception
}Registration should be done in it's own class to avoid NoClassDefFoundError if Plan is not installed.
You might need to catch the error when calling your method that does the registering. Getting started, step 2.1
Every DataExtension implementation requires @PluginInfo annotation.
Usage & Parameters@PluginInfo(
name = "Your Plugin", // ALWAYS REQUIRED
iconName = "cube"
iconFamily = Family.SOLID,
color = Color.NONE
)
public class YourExtension implements DataExtension {}Provider annotations are method annotations that tell Plan what kind of data methods in your DataExtension class provide.
The name of the methods are used for storing information the methods provide.
Methods can have 4 different parameters (But only one):
T method(); // The value is about the server as a whole
T method(UUID playerUUID); // The value is about a player
T method(String playerName); // The value is about a player
T method(Group group); // The value is about a Group a player is in@Override
public CallEvents[] callExtensionMethodsOn() {
return new CallEvents[]{
CallEvents.PLAYER_JOIN,
CallEvents.PLAYER_PERIODICAL,
CallEvents.PLAYER_LEAVE,
CallEvents.SERVER_EXTENSION_REGISTER,
CallEvents.SERVER_PERIODICAL
};
}DataExtension yourExtension;
Optional<Caller> caller = extensionService.register(yourExtension);HOX Do not use Caller inside DataExtension - This might lead to unbound recursion!
Caller caller;
caller.updatePlayerData(playerUUID, playerName);
caller.updateServerData();Speciality: boolean values, Can work with @Conditional-annotation for conditional execution
Usage & Parameters@BooleanProvider(
text = "Has Island", // ALWAYS REQUIRED
description = "Whether or not the player has an island in the island world",
priority = 5,
iconName = "question",
iconFamily = Family.SOLID,
iconColor = Color.NONE,
conditionName = "islandCondition",
hidden = false
)
public boolean hasIsland(UUID playerUUID) {...}@BooleanProvider(
...
conditionName = "hasIsland"
)
public boolean hasIsland(UUID playerUUID) {
return true;
}
@Conditional("hasIsland)
@StringProvider(...) // Another provider is required, can be any Provider.
public String islandName(UUID playerUUID) {...}@BooleanProvider(
...
conditionName = "hasLinkedAccount", // REQUIRED to use hidden
hidden = true
)
public boolean hasLinkedAccount(UUID playerUUID) {...}Speciality: Whole numbers, Time amounts, Timestamps
Usage & Parameters@NumberProvider(
text = "Number of Islands", // ALWAYS REQUIRED
description = "How many islands does the player own",
priority = 4,
iconName = "question",
iconFamily = Family.SOLID,
iconColor = Color.NONE,
format = FormatType.NONE
)
public long islandCount(UUID playerUUID) {...}@NumberProvider(
...
format = FormatType.DATE_YEAR
)
public long banDate(UUID playerUUID) {...}Speciality: Floating point numbers
Usage & Parameters@DoubleProvider(
text = "Balance", // ALWAYS REQUIRED
description = "Amount of money the player has",
priority = 3,
iconName = "question",
iconFamily = Family.SOLID,
iconColor = Color.NONE
)
public double balance(UUID playerUUID) {...}Speciality: Percentages between 0% and 100%. Requires return values between 0.0 and 1.0.
Usage & Parameters@PercentageProvider(
text = "Quest completion", // ALWAYS REQUIRED
description = "Quest completion percentage",
priority = 5,
iconName = "question",
iconFamily = Family.SOLID,
iconColor = Color.NONE
)
public double questCompletion(UUID playerUUID) {...}Speciality: String values, Links to player page when playerName is true
Usage & Parameters@StringProvider(
text = "Town Name", // ALWAYS REQUIRED
description = "What town the player has residency in.",
priority = 5,
iconName = "question",
iconFamily = Family.SOLID,
iconColor = Color.NONE,
playerName = false
)
public String townName(UUID playerUUID) {...}@StringProvider(
...
playerName = true
)
public String townMayor(Group town) {...}Speciality: String values that have chat colors in them (legacy / bungee / minimessage)
Usage & Parameters@ComponentProvider(
text = "Display name", // ALWAYS REQUIRED
description = "What name is the player using",
priority = 5,
iconName = "question",
iconFamily = Family.SOLID,
iconColor = Color.NONE
)
public Component displayName(UUID playerUUID) {
return ComponentService.getInstance().fromAutoDetermine(... /* Put the string in here */);
}These annotations can be used to add information structures. They might have different limitations than other providers.
Speciality: Multiple Groups the player is in. Any providers with Group parameter will be called with the groups that this method provides (Not implemented yet).
Plan will construct following from given group data:
@GroupProvider(
text = "Jobs", // ALWAYS REQUIRED
groupColor = Color.NONE
iconName = "question",
iconFamily = Family.SOLID,
)
public String[] playerJobs(UUID playerUUID) {
return new String[]{"Mason", "Woodcutter"}
}Speciality: Table structures.
Usage & ParametersIf you want to display a table that lists how many players are using something (or data about groups), eg. Players on each version, use @GroupProvider (and Group parameter methods) instead.
@TableProvider(tableColor = Color.NONE)
public Table banHistory(UUID playerUUID) {
Table.Factory banTable = Table.builder()
.columnOne("When", new Icon(Family.SOLID, "gavel")) // Define column names and icons
.columnOneFormat(TableColumnFormat.DATE_SECOND) // All columns support formatting similar to other Providers (numbers, strings)
.columnTwo("...", new Icon(...)) // Icon colors are ignored.
.columnThree("...", new Icon(...))
.columnFour("...", new Icon(...));
for (YourData data : yourData) {
banTable.addRow(System.currentTimeMillis(), true, "Reason", "...");
}
return banTable.build();
}Speciality: Dynamic definition of providers at runtime.
@DataBuilderProvider
public ExtensionDataBuilder lotsOfData(UUID playerUUID) {
ExtensionDataBuilder builder = newExtensionDataBuilder();
...
return builder;
}Speciality: Graphs.
This will be implemented later.
These annotations can be used to further control how the values are displayed.
Specialilty: Control what plugin-tab the provided value appears in.
Usage & Parameters@TabInfo(
tab = "Economy", // REQUIRED
iconName = "circle",
iconFamily = Family.SOLID,
elementOrder = {ElementOrder.VALUES, ElementOrder.TABLE, ElementOrder.GRAPH}
)
@TabInfo(tab = "Second Tab") // REQUIRED
@TabOrder({"Economy", "Second Tab"})
@PluginInfo(...)
public class YourExtension implements DataExtension {
@BooleanProvider(text = "Has Pet")
@Tab("Second Tab")
public boolean hasPet(UUID playerUUID) {...}
}Specialilty: Control execution of another methods. If provided boolean is true the method with @Conditional annotation will be called.
Usage & Parameters@BooleanProvider(..., conditionName="hasPet")
public boolean hasPet(UUID playerUUID) {...}
@Conditional("hasPet")
@StringProvider(text = "Pet Name")
public String petName(UUID playerUUID) {...}@BooleanProvider(..., conditionName="permanentBan")
public boolean isPermanentlyBanned(UUID playerUUID) {...}
@Conditional(value = "permanentBan", negated = true)
@NumberProvider(...)
public long expiryDate(UUID playerUUID) {...}@BooleanProvider(..., conditionName="isBanned")
public boolean isBanned(UUID playerUUID) {...}
@Conditional("isBanned")
@BooleanProvider(..., conditionName="isTemporaryBan")
public boolean isTemporaryBan(UUID playerUUID) {...}
@Conditional("isTemporaryBan")
@NumberProvider(...)
public long expireDate(UUID playerUUID) {...}Speciality: Removes old values from database if you decide to rename a method. The method name is used when storing the values, so this annotation exists to remove the old values.
Usage & Parameters@InvalidateMethod("oldMethodName")
@PluginInfo(...)
public class YourExtension implements DataExtension {
@BooleanProvider(...)
public boolean newMethodName(UUID playerUUID) {...}
}Since annotations do not have any compiler checks, invalid implementation can not be enforced at compile time, and runtime exceptions are used instead.
To make implementation easier it is possible to Unit test against the implementation errors.
How:
@Test
public void noImplementationErrors() {
DataExtension yourExtension = new YourExtensionImplementation();
// Throws IllegalArgumentException if there is an implementation error or warning.
new ExtensionExtractor(yourExtension).validateAnnotations();
}Here is a short list of what throws an exception
Warnings:
If you would like to see how the API is being used in built in plugin support, check out implementations in repositories that start with Extension
ExtensionFactory classes are not important, since they are used by Plan for creating the DataExtension instances when Plan enables. The registration is not automatic.
| Back | FazBrowse Home | New Git URL |