Created APIv5 (markdown)
parent
4c29b6a616
commit
86977d859e
|
@ -0,0 +1,309 @@
|
|||
![Plan Header](http://puu.sh/AXSg7/5f2f78c06c.jpg)
|
||||
# Plan API version 5
|
||||
|
||||
> This API is still under development and might not be completely available yet.
|
||||
In order to ease workload this documentation is written during development.
|
||||
|
||||
This page is about API that will be available in **version 4.8.0** and above.
|
||||
API can be called on all platforms.
|
||||
|
||||
### Table of contents
|
||||
|
||||
- Dependency information
|
||||
- DataExtension API
|
||||
- How to register a DataExtension
|
||||
- PluginInfo Annotation
|
||||
- Provider Annotations
|
||||
- Extra annotations
|
||||
- Preventing runtime errors
|
||||
- Implementation violations
|
||||
|
||||
## Dependency information
|
||||
|
||||
*Not yet available. API module will be available through a Maven repository.*
|
||||
|
||||
Add `"Plan"` as a softdependency to your plugin information (plugin.yml / Plugin annotation).
|
||||
|
||||
# DataExtension API
|
||||
|
||||
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.
|
||||
|
||||
## 🔔 How to register a DataExtension
|
||||
|
||||
1. Create a new object that implements `DataExtension`.
|
||||
2. Obtain instance of `ExtensionService` and register using `ExtensionService#register(DataExtension)`
|
||||
|
||||
```
|
||||
DataExtension yourExtension = new YourDataExtensionImplementation();
|
||||
try {
|
||||
|
||||
ExtensionService.getInstance().register(dataExtension);
|
||||
|
||||
} 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
|
||||
}
|
||||
```
|
||||
|
||||
## ℹ️ `@PluginInfo` annotation
|
||||
|
||||
Every `DataExtension` implementation **requires** `@PluginInfo` annotation.
|
||||
|
||||
> **Notation:**
|
||||
> `*` means required parameter
|
||||
|
||||
Example usage:
|
||||
```
|
||||
@PluginInfo(
|
||||
name* = "Your Plugin",
|
||||
iconName = "cube"
|
||||
iconFamily = Family.SOLID,
|
||||
color = Color.NONE
|
||||
)
|
||||
public class YourExtension implements DataExtension {}
|
||||
```
|
||||
|
||||
- `name` - Name of your plugin
|
||||
- `iconName` - Icon names can be found from https://fontawesome.com/icons?d=gallery&m=free
|
||||
- `iconFamily` - Icon family should match details on the site above
|
||||
- `color` - Colors are available here *Link to be added*
|
||||
|
||||
## 📏 Provider Annotations
|
||||
|
||||
Provider annotations are method annotations that tell Plan what kind of data methods in your `DataExtension` class provide.
|
||||
|
||||
> **Notation:**
|
||||
> `*` means required parameter
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
### `@BooleanProvider`
|
||||
|
||||
**Speciality:** `boolean` values, Can work with `@Conditional`-annotation for conditional execution
|
||||
|
||||
Example usage:
|
||||
```
|
||||
@BooleanProvider(
|
||||
text* = "Has Island",
|
||||
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"
|
||||
)
|
||||
public boolean hasIsland(UUID playerUUID) {...}
|
||||
```
|
||||
|
||||
- `text` - Text that appears next to the value, for example "Has Island: No"
|
||||
- `description` - Text that appears when hovering over the value
|
||||
- `priority` - Ordering number, highest value is placed top most
|
||||
- `iconName` - Icon names can be found from https://fontawesome.com/icons?d=gallery&m=free
|
||||
- `iconFamily` - Icon family should match details on the site above
|
||||
- `iconColor` - Color of the icon that appears next to the value
|
||||
- `conditionName` - Name of a condition this boolean represents, used with `@Conditional` annotations
|
||||
|
||||
### `@NumberProvider`
|
||||
|
||||
**Speciality:** Whole numbers, Time amounts, Timestamps
|
||||
|
||||
Example usage:
|
||||
```
|
||||
@NumberProvider(
|
||||
text* = "Number of Islands",
|
||||
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) {...}
|
||||
```
|
||||
|
||||
- `text` - Text that appears next to the value, for example "Has Island: No"
|
||||
- `description` - Text that appears when hovering over the value
|
||||
- `priority` - Ordering number, highest value is placed top most
|
||||
- `iconName` - Icon names can be found from https://fontawesome.com/icons?d=gallery&m=free
|
||||
- `iconFamily` - Icon family should match details on the site above
|
||||
- `iconColor` - Color of the icon that appears next to the value
|
||||
- `format` - `FormatType` tells that the value is time amount (milliseconds) or a timestamp
|
||||
|
||||
### `@DoubleProvider`
|
||||
|
||||
**Speciality:** Floating point numbers
|
||||
|
||||
Example usage:
|
||||
```
|
||||
@DoubleProvider(
|
||||
text* = "Balance",
|
||||
description = "Amount of money the player has",
|
||||
priority = 3,
|
||||
iconName = "question",
|
||||
iconFamily = Family.SOLID,
|
||||
iconColor = Color.NONE
|
||||
)
|
||||
public double balance(UUID playerUUID) {...}
|
||||
```
|
||||
|
||||
- `text` - Text that appears next to the value, for example "Has Island: No"
|
||||
- `description` - Text that appears when hovering over the value
|
||||
- `priority` - Ordering number, highest value is placed top most
|
||||
- `iconName` - Icon names can be found from https://fontawesome.com/icons?d=gallery&m=free
|
||||
- `iconFamily` - Icon family should match details on the site above
|
||||
- `iconColor` - Color of the icon that appears next to the value
|
||||
|
||||
### `@PercentageProvider`
|
||||
|
||||
**Speciality:** Percentages between 0% and 100%. Requires return values between 0.0 and 1.0.
|
||||
|
||||
Example usage:
|
||||
```
|
||||
@PercentageProvider(
|
||||
text* = "Quest completion",
|
||||
description = "Quest completion percentage",
|
||||
priority = 5,
|
||||
iconName = "question",
|
||||
iconFamily = Family.SOLID,
|
||||
iconColor = Color.NONE
|
||||
)
|
||||
public double questCompletion(UUID playerUUID) {...}
|
||||
```
|
||||
|
||||
- `text` - Text that appears next to the value, for example "Has Island: No"
|
||||
- `description` - Text that appears when hovering over the value
|
||||
- `priority` - Ordering number, highest value is placed top most
|
||||
- `iconName` - Icon names can be found from https://fontawesome.com/icons?d=gallery&m=free
|
||||
- `iconFamily` - Icon family should match details on the site above
|
||||
- `iconColor` - Color of the icon that appears next to the value
|
||||
|
||||
### `@StringProvider`
|
||||
|
||||
**Speciality:** String values, Links to player page when `playerName` is `true`
|
||||
|
||||
Example usage:
|
||||
```
|
||||
@StringProvider(
|
||||
text* = "Town Name",
|
||||
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) {...}
|
||||
```
|
||||
|
||||
- `text` - Text that appears next to the value, for example "Has Island: No"
|
||||
- `description` - Text that appears when hovering over the value
|
||||
- `priority` - Ordering number, highest value is placed top most
|
||||
- `iconName` - Icon names can be found from https://fontawesome.com/icons?d=gallery&m=free
|
||||
- `iconFamily` - Icon family should match details on the site above
|
||||
- `iconColor` - Color of the icon that appears next to the value
|
||||
- `playerName` - Does this provider return a player name that can be linked to? Links are automatic
|
||||
|
||||
## 📐 Extra annotations
|
||||
|
||||
These annotations can be used to further control how the values are displayed.
|
||||
|
||||
### `@Tab`, `@TabInfo` and `@TabOrder`
|
||||
|
||||
**Specialilty:** Control what plugin-tab the provided value appears in.
|
||||
|
||||
Example usage:
|
||||
```
|
||||
@TabInfo(
|
||||
tab* = "Economy",
|
||||
iconName = "circle",
|
||||
iconFamily = Family.SOLID,
|
||||
elementOrder = {ElementOrder.VALUES, ElementOrder.TABLE, ElementOrder.GRAPH}
|
||||
)
|
||||
@TabInfo(tab* = "Second Tab")
|
||||
@TabOrder({"Economy", "Second Tab"})
|
||||
public class YourExtension implements DataExtension {
|
||||
|
||||
@BooleanProvider(text = "Has Pet")
|
||||
@Tab("Second Tab")
|
||||
public boolean hasPet(UUID playerUUID) {...}
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
- `tab` - Name of the tab
|
||||
- `iconName` - Icon names can be found from https://fontawesome.com/icons?d=gallery&m=free
|
||||
- `iconFamily` - Icon family should match details on the site above
|
||||
- `elementOrder` - Order different elements are placed inside the tab. `VALUES` represents all single values
|
||||
|
||||
### `@Conditional`
|
||||
|
||||
**Specialilty:** Control execution of another method. If the provided `boolean` is `false` the method with `@Conditional` annotation is not called.
|
||||
|
||||
Example usage:
|
||||
```
|
||||
@BooleanProvider(..., conditionName="hasPet")
|
||||
public boolean hasPet(UUID playerUUID) {...}
|
||||
|
||||
@Conditional("hasPet")
|
||||
@StringProvider(text = "Pet Name")
|
||||
public String petName(UUID playerUUID) {...}
|
||||
```
|
||||
|
||||
### `@InvalidateMethod`
|
||||
|
||||
**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.
|
||||
|
||||
Example usage:
|
||||
```
|
||||
@InvalidateMethod("oldMethodName")
|
||||
public class YourExtension implements DataExtension {
|
||||
@BooleanProvider(...)
|
||||
public boolean newMethodName(UUID playerUUID) {...}
|
||||
}
|
||||
```
|
||||
|
||||
## Preventing runtime errors
|
||||
|
||||
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();
|
||||
}
|
||||
```
|
||||
|
||||
### Implementation violations
|
||||
|
||||
Here is a short list of what throws an exception
|
||||
|
||||
- No `@PluginInfo` class annotation
|
||||
- Class contains no public methods with Provider annotations
|
||||
- Class contains private method with Provider annotation
|
||||
- Non-primitive return type when primitive is required (eg. `Boolean` instead of `boolean`)
|
||||
- Method doesn't have correct parameters (none, UUID, String or Group)
|
||||
- `@BooleanProvider` is annotated with a `@Conditional` that requires same condition the provider provides.
|
||||
- `@Conditional` without a `@BooleanProvider` that provides value for the condition
|
||||
|
||||
Warnings:
|
||||
|
||||
- An annotation String `<variable>` is over 50 characters (Or over 150 if `description`)
|
||||
- Method name is over 50 characters (Used as an identifier for storage)
|
Loading…
Reference in New Issue