Plan/documentation/API.md

297 lines
13 KiB
Markdown
Raw Normal View History

![Player Analytics](https://puu.sh/t8vin.png)
# API
- [API class](/Plan/src/main/java/com/djrapitops/plan/api/API.java)
2017-05-14 14:26:46 +02:00
- [API Javadocs](https://rsl1122.github.io/Plan-PlayerAnalytics/main/java/com/djrapitops/plan/api/API.html)
2017-05-24 12:34:01 +02:00
## Accessing the API Methods:
Install the Plan.jar as a local dependency if you're using Maven.
Add soft-depend or depend in the plugin.yml
```
2017-05-24 12:34:01 +02:00
import main.java.com.djrapitops.plan.api.API;
if (getPluginManager().isPluginEnabled("Plan")) {
try {
// Throws IllegalStateException if onEnable() method for Plan has not yet been called.
// Throws NoClassDefError if Plan is not installed
API planAPI = Plan.getPlanAPI();
} catch (Throwable e) {
// Do something (Plan is not installed)
}
}
```
2017-05-24 12:34:01 +02:00
# Plugins Tab
2017-05-12 12:21:04 +02:00
- [PluginData](/Plan/src/main/java/com/djrapitops/plan/data/additional/PluginData.java)
2017-05-14 14:26:46 +02:00
- [PluginData Javadoc](https://rsl1122.github.io/Plan-PlayerAnalytics/main/java/com/djrapitops/plan/data/additional/PluginData.html)
- [AnalysisType Enum](/Plan/src/main/java/com/djrapitops/plan/data/additional/AnalysisType.java)
2017-05-14 14:26:46 +02:00
- [AnalysisType Javadoc](https://rsl1122.github.io/Plan-PlayerAnalytics/main/java/com/djrapitops/plan/data/additional/AnalysisType.html)
- [Example classes](/Plan/src/main/java/com/djrapitops/plan/data/additional)
2017-05-14 14:26:46 +02:00
## Adding plugin's data to the 'plugins'-tab on Analysis and/or Inspect pages
Plan has a flexible data addition system since 3.1.0. With it you can add Averages, Totals, Percentages, Tables & Other Html elements to the Plugins tab on the Analysis and/or Inspect pages.
2017-05-24 12:34:01 +02:00
To add data **a class that extends PluginData class is needed.**
One PluginData object should only contain data for one user, but tables & other elements are an exception.
### Registering the data point
```
PluginData yourPluginDataObject = new YourClassThatExtendsPluginData();
Plan.getPlanAPI().addPluginDataSource(yourPluginDataObject);
```
**If you register multiple data sources, they will appear in the order they were registered.**
## Building the PluginData object
### Super Constructors
Constructor determines if the datapoint can be analyzed or not & how it should be analyzed.
The Inspect page visibility can be changed with another method call.
Constructor | Parameters | Description
-- | -- | --
super(pluginName, placeholder) | Name of the plugin & the placeholder, eg: "stepsTaken" | This datapoint will be only shown on the Inspect page
super(pluginName, placeholder, AnalysisType.INT_TOTAL) | Type is determined by return value of getValue(UUID)-method | This datapoint will be shown on the Analysis page with total for all Players
super(pluginName, plaheholder, AnalysisType.INT_AVG, AnalysisType.INT_TOTAL) | The constructor takes as many AnalysisTypes as needed. | This datapoint will be shown on the Analysis page with the total and average for all Players
### Method calls in the contructor
There are multiple methods that change the appearance of the PluginData object on the webpage:
Method | Description
-- | --
super.analysisOnly(boolean) | Determine whether or not the datapoint should be only shown on the Analysis page, Set to false to show it on the Inspect page as well.
super.setPrefix(String) | For example: super.setPrefix("Steps taken: "), determines the prefix
super.setSuffix(String) | For example: super.setSuffix(" steps"), determines the suffix.
super.setIcon(String) | Set the font awesome icon name: [Font Awesome Icons](http://fontawesome.io/icons/)
To not show the datapoint on Analysis page, do not give the constructor any AnalysisType variables.
### getHtmlReplaceValue(String modifier, UUID uuid)-method
This method is used by Inspect page & by Analysis Page when AnalysisType.HTML is specified.
**It should use the parseContainer(String modifier, String value) method when returning a value.**
2017-05-24 12:34:01 +02:00
The Prefix, Suffix & Icon are added to the value automatically when using the parseContainer(String modifier, String value)-method.
Example:
```
@Override
public String getHtmlReplaceValue(String modifier, UUID uuid) {
return parseContainer(modifier, stepCounter.getSteps(uuid)+"");
}
```
UUID is the UUID of the player whose Inspect page is displayed OR Random UUID on Analysispage when AnalysisType.HTML is specified
### getValue(UUID uuid)-method
This method is used by Analysis when calculating Totals & Averages for each PluginData object.
The return type is Serializable, so Integer, Double, Long, Boolean & String can be returned.
What type you return determines what AnalýsisType you should use in the super constructor.
**-1** should be returned if the player has no value / Your plugin has no data on the player
If -1 is returned, the value is ignored when calculating Averages & Totals.
**Wrong AnalysisType will cause an exception during calculation** - It is caught per AnalysisType, so test your plugin with /plan analyze.
# Examples:
2017-05-12 12:21:04 +02:00
- Basic Example
- Analysis Example
- Table Example
2017-05-12 12:21:04 +02:00
## Basic Example
2017-05-24 12:34:01 +02:00
This class will show "Steps Taken" on the Inspect page.
```
public class StepCounterSteps extends PluginData {
private StepCounterPlugin stepCounter; // This is the example plugin where the data is taken from.
// Constructor with the plugin as parameter.
public StepCounterSteps(StepCounterPlugin stepCounter) {
// A call to super constructor: PluginName, PlaceholderName
super("StepCounter", "stepsTaken");
2017-05-24 12:34:01 +02:00
super.setPrefix("Steps taken: ")
super.setSuffix(" steps");
super.setIcon("wheelchair");
this.stepCounter = stepCounter; // Setting the plugin
2017-05-24 12:34:01 +02:00
// Registering to the API, this can be done outside the class as well.
API api = Plan.getPlanAPI();
if (api.isEnabled()) {
api.addPluginDataSource(this);
}
}
// Required method.
// This method is used with AnalysisType.HTML and for Inspect page's values.
// All return values should use parseContainer(String modifier, String value)-method, more on that down below.
@Override
2017-05-24 12:34:01 +02:00
public String getHtmlReplaceValue(String modifier, UUID uuid) {
return parseContainer(modifier, stepCounter.getSteps(uuid)+"");
}
// Required method.
// This method is used to calculate values for the Analysis page.
@Override
2017-05-24 12:34:01 +02:00
public Serializable getValue(UUID uuid) {
return stepCounter.getSteps(uuid);
}
}
```
2017-05-12 12:22:42 +02:00
## Analysis Example
Adding data to the Analysis page is straightforward as well. Please note that one class can add a data to both Analysis & Inspect pages.
To add data to the Analysis page, analysisTypes need to be set.
2017-05-24 12:34:01 +02:00
This is done in the super constructor.
Refer to AnalysisType for what types you should add. The type depends on the return of the getValue(UUID uuid)-method you have written.
- [AnalysisType](/Plan/src/main/java/com/djrapitops/plan/data/additional/AnalysisType.java)
2017-05-14 14:26:46 +02:00
- [AnalysisType Javadoc](https://rsl1122.github.io/Plan-PlayerAnalytics/main/java/com/djrapitops/plan/data/additional/AnalysisType.html)
2017-05-24 12:34:01 +02:00
AnalysisType.HTML is for all other elements you might want to add - parseContainer method will be used instead of the getValue method.
**If you want this same datapoint to show data on the inspect page call super.analysisOnly(false);**
Good example is the [FactionsPower](/Plan/src/main/java/com/djrapitops/plan/data/additional/factions/FactionsPower.java)
2017-05-12 12:22:42 +02:00
## Table Example
A good example is the [AdvancedAchievementsTable](/Plan/src/main/java/com/djrapitops/plan/data/additional/advancedachievements/AdvanceAchievementsTable.java).
2017-05-24 12:34:01 +02:00
You can use the [Html Enum](/Plan/src/main/java/com/djrapitops/plan/ui/Html.java) to quickly create table html.
The Html Enum has easy lines for 2, 3 & 4 line columns - More than that will most likely not fit in the box.
the parse(String... p)-method takes as many strings as parameters as needed to replace all the REPLACE# placeholders on the line.
Let's deconstruct the constructor.
```
public AdvancedAchievementsTable(AdvancedAchievementsAPI aaAPI) {
super("AdvancedAchievements", "achievementstable", AnalysisType.HTML);
this.aaAPI = aaAPI;
String player = Html.FONT_AWESOME_ICON.parse("user") + " Player";
String achievements = Html.FONT_AWESOME_ICON.parse("check-circle-o") + " Achievements";
// analysisOnly true by default.
super.setPrefix(Html.TABLE_START_2.parse(player, achievements));
super.setSuffix(Html.TABLE_END.parse());
}
```
- analysisTypes is set as AnalysisType.HTML.
- prefix is set as a sortable table's start with "<icon> Player" and "<icon> Achievements" columns.
- suffix is set as the end tags for the whole table.
Now let's see how the table gets the values:
```
@Override
public String getHtmlReplaceValue(String modifierPrefix, UUID uuid) {
StringBuilder html = new StringBuilder();
List<OfflinePlayer> offlinePlayers = Arrays.stream(getOfflinePlayers()).filter(p -> p.hasPlayedBefore()).collect(Collectors.toList());
if (offlinePlayers.isEmpty()) {
html.append(Html.TABLELINE_2.parse("No Players.",""));
} else {
for (OfflinePlayer p : offlinePlayers) {
String inspectUrl = HtmlUtils.getInspectUrl(p.getName());
String achievements = aaAPI.getPlayerTotalAchievements(p.getUniqueId()) + "";
html.append(Html.TABLELINE_2.parse(Html.LINK.parse(inspectUrl, p.getName()), achievements));
}
}
return parseContainer("", html.toString());
}
```
It simply gets the Players that have played on the server. If the list is empty, a row with "No Players" is added to the value (html, StringBuilder).
Otherwise it get's the Url for the Inspect page of each player, and the amount of achievements a player has.
The link is parsed inside a html a-tag (with the text of the players name).
Then that is parsed into a table line with the a-tag & achievements.
The parseContainer uses an empty string as modifierPrefix, because we don't want any extra text added in-front of the table.
Inspect doesn't use getValue(UUID uuid) &
AnalysisType.HTML disregards it's return values, so that simply returns an empty string.
```
@Override
public Serializable getValue(UUID uuid) {
return "";
}
2017-05-12 12:21:04 +02:00
```
2017-05-24 13:02:46 +02:00
# Accessing the Data & Modification
In addition to the Plugins tab methods the API provides methods for accessing the data of Analysis & Players.
Before using these methods you might want to read about the Caches to understand the difference between DataCache, InspectCache & AnalysisCache
- [Gathering the data & Data Cache](/documentation/DataGathering.md)
## Utility methods
Method | Returns | Description
-- | -- | --
playerNameToUUID(String) | UUID of the player or null | Uses [UUIDFetcher](/Plan/src/main/java/com/djrapitops/plan/utilities/UUIDFetcher.java) to fetch the UUID
getPlayerName(UUID) | Players username | Get's the OfflinePlayer and asks for it's name.
isEnabled() | boolean | Check whether or not Plan enabled successfully
isPlayersDataInspectCached(UUID uuid) | boolean | Check if player's data is in the InspectCache
isAnalysisCached() | boolean | Check if the AnalysisData is cached.
getPlayerInspectPageLink(String name) | Web address | Get the Inspect page link for a player.
## Web methods
Method | Description
-- | --
getAnalysisHtmlAsString() | Returns the full html for Analysis page. If isAnalysisCached() is false, will return html for a 404.
getPlayerHtmlAsString(UUID uuid) | Returns the full html for Inspect page. If isPlayersDataInspectCached(UUID) is false, will return html for a 404.
## Cache methods
Method | Description
2017-05-24 13:03:54 +02:00
-- | --
2017-05-24 13:02:46 +02:00
updateAnalysisCache() | Run's the analysis & places AnalysisData to the cache.
getAnalysisDataFromCache() | Returns the AnalysisData in the cache.
cacheUserDataToInspectCache(UUID uuid) | Caches the UserData of the player to InspectCache from cache or the database. Call from Async thread.
scheduleForGet(UUID uuid, DBCallableProcessor processor) | Schedule a UserData object to be fetched from the database or cache if the player is online.
scheduleEventHandlingInfo(HandlingInfo info) | Cause your own Event to modify the UserData object that is stored in the database.
placeDataToCache(UserData data) | Used to cache a UserData object. If data is already cached it will be overridden. (Use with caution)
saveCachedData() | Saves all UserData in the Cache to the database. Should be only called from an Asyncronous thread.
### DBCallableProcessor
scheduleForGet uses [DBCallableProcessor interface](/Plan/src/main/java/com/djrapitops/plan/data/cache/DBCallableProcessor.java).
The processor's method is called after the fetch is complete.
UUID is the uuid of the player.
Example:
```
DBCallableProcessor p = new DBCallableProcessor() {
@Override
public void process(UserData data) {
// Do something with the data
}
};
Plan.getPlanAPI().scheduleForGet(uuid, p);
```
### HandlingInfo
scheduleEventHandlingInfo uses [HandlingInfo abstract class](/Plan/src/main/java/com/djrapitops/plan/data/handling/info/HandlingInfo.java).
This object can modify the UserData in the cache. If the data is not in the cache prior to processing the data, it will be fetched & placed there.
UUID is the uuid of the player.
Example:
```
long time = new Date().getTime();
HandlingInfo i = new HandlingInfo(uuid, InfoType.OTHER, time) {
@Override
public boolean process(UserData data) {
if (uuid.equals(data.getUuid()) {
// Modify the data in some way
return true;
}
return false;
}
};
Plan.getPlanAPI().scheduleEventHandlingInfo(i);
```