-
Notifications
You must be signed in to change notification settings - Fork 7
Teams
Teams are one of the core features of UltimateAdvancementAPI. Teams are used everywhere, for example, advancement progressions are saved per-team.
Until now teams were not mentioned in the wiki to keep things simple, but to achieve the full potential of the API they are needed.
By default, every player is in their own team, containing only they. When a new player joins, a new team is created and the player gets added to it.
Every player progression, as said before, is saved per-team. Thus, by default, every player has "their own advancement progression". If two players must have the same progression, one can be moved in the other's team, since players in the same team have the same progression.
Also, every team is identified by an integer id.
TeamProgression
objects stores information about a team. Furthermore, TeamProgression
is used by the API to cache team information from the database. Thus, it can be used, for example, to get the components of a team.
TeamProgression
has plenty of useful methods, which this page cannot cover all. Check them out on its Javadoc page.
The method UltimateAdvancementAPI#getTeamProgression(Player player)
is used to get the TeamProgression
of a player team. However, if that player is not online, a UserNotLoadedException
will be thrown.
To avoid this, the player information have to be loaded from the database. This is done through UltimateAdvancementAPI#loadOfflinePlayer(UUID uuid)
. This will load the player from the database and will keep they loaded even if the player logs on and then quits. Therefore, after having done with the TeamProgression
, always remember to unload they using UltimateAdvancementAPI#unloadOfflinePlayer(UUID uuid)
to avoid memory leaks.
Note that, due to how the caching system is implemented, only one
TeamProgression
instance is made per team, so callingUltimateAdvancementAPI#getTeamProgression(...)
on two different players of the same team will return the same object.
There is also a more complex version of the loading method, which makes customizable what to do with the loaded TeamProgression
:
UltimateAdvancementAPI#loadOfflinePlayer(UUID uuid, CacheFreeingOption option, Consumer<ObjectResult<TeamProgression>> action)
.
Let's see it in detail.
CacheFreeingOption
is used to choose what will be done with the loaded team. It can be:
- Loaded but not cached (
CacheFreeingOption#DONT_CACHE()
); - Loaded and automatically unloaded after a certain amount of ticks (
CacheFreeingOption#AUTOMATIC(Plugin requester, long ticks)
); - Loaded and kept in cache until a manual unload happens (
CacheFreeingOption#MANUAL(Plugin requester)
).
Note that the third option is the one used by the simpler version of the method seen before (
UltimateAdvancementAPI#unloadOfflinePlayer(UUID uuid)
).
Note that for the first and second options no manual unload have to be done.
The last parameter to pass is a Consumer<ObjectResult<TeamProgression>>
, which provides the code that will be run when the loading will be completed (it can be put to null
if no particular code is ment to be pass here). This is useful with the CacheFreeingOption#DONT_CACHE()
option to retirve the TeamProgression
object.
To go a bit deeper, the ObjectResult<TeamProgression>
object holds the result of the request to the database, so whether it failed and the TeamProgression
in case of success.
Example usage:
// This prints to console the uuid of every team component
// uuid of a random player (suppose they to be offline)
UUID uuid = UUID.fromString("831e3f14-b54d-47fe-bd4e-06d9e6ce681b");
api.loadOfflinePlayer(uuid, CacheFreeingOption.DONT_CACHE(), result -> {
if (result.isSucceeded()) {
TeamProgression progression = result.getResult();
progression.forEachMember(memberUUID -> {
System.out.println(memberUUID);
});
} else {
// An error occurred
result.getOccurredException().printStackTrace();
}
});
In order to add a player to a team, the player (which is, by default, in their own one) have to be moved in the final team.
This can be done by the method UltimateAdvancementAPI#updatePlayerTeam(Player playerToMove, Player aDestTeamPlayer)
.
The first player is the one to move, whereas the second is a player of the destination team.
If a result about the moving is needed, use UltimateAdvancementAPI#updatePlayerTeam(Player playerToMove, Player aDestTeamPlayer, Consumer<Result> action)
instead.
The code to execute is provided by Consumer<Result>
. Result
is very similar to the ObjectResult
from before, except it doesn't provide an object as result (in the example from the above section, it was the TeamProgression
). It only provides whether the request succeded and an exception if it failed.
Example usage:
// This moves the first player in the second's team
Player playerOne = Bukkit.getPlayer("fren_gor");
Player playerTwo = Bukkit.getPlayer("EscanorTargaryen");
api.updatePlayerTeam(playerOne, playerTwo, result -> {
if (result.isSucceeded()) {
playerOne.sendMessage("You're now part of " + playerTwo.getName() + " team!");
} else {
// An error occurred
playerOne.sendMessage("Something wrong happened while moving to " + playerTwo.getName() + " team");
result.getOccurredException().printStackTrace();
}
});
To remove a player from a team, the player have to be moved in a new team.
This can be done using the method UltimateAdvancementAPI#movePlayerInNewTeam(Player playerToMove)
.
A version with a Consumer<ObjectResult<TeamProgression>>
parameter is also present.
Example usage:
// This removes a player from its current team
Player playerOne = Bukkit.getPlayer("fren_gor");
api.movePlayerInNewTeam(playerOne, result -> {
if (result.isSucceeded()) {
TeamProgression progression = result.getResult();
playerOne.sendMessage("You're now alone! (Team id is " + progression.getTeamId() + ")");
} else {
// An error occurred
playerOne.sendMessage("Sorry, an error occurred. Stay in your team!");
result.getOccurredException().printStackTrace();
}
});
There are some events related to teams, listed here down below:
-
TeamLoadEvent
- Called when a newTeamProgression
is created and stored into the caching system (so when the first player of a team is loaded or joins the server); -
TeamUnloadEvent
- Called when aTeamProgression
is removed from caching system (so when every player of a team is unloaded or logs off); -
TeamUpdateEvent
- Called when a player joins or leaves a team.
Due to the fact TeamProgression
is used by the caching system, there are some limitations on its usage. For example, imagine that a couple of players, which are part of the same team, are online and a plugin takes a reference to the TeamProgression
of that team. Suppose now that they all go offline.
Remember that a
TeamProgression
is present in the cache until every player of that team logs off.
Thus, when one of them comes back online, the API creates a new instance of TeamProgression
and reload team data from the database. Thus, the plugin form before (that kept a reference to the old TeamProgression
) now may have incorrect (and not up-to-date) information about the team!
So, it is always important to follow this set of rules when working with TeamProgression
s:
- It is prefereable to get a fresh reference to the
TeamProgression
of a team usingUltimateAdvancementAPI#getProgression(...)
everytime rather than storing that in a variable. If a variable is needed, it should store the team's id, which remains always valid. However, if storing aTeamProgression
instance is very necessary, it is suggested to listen to theTeamUnloadEvent
and remove the reference when it gets called; - Always make sure a player is loaded in the API before calling any update on an advancement, since that will eventually call the
getProgression(...)
method, which will result in aUserNotLoadedException
; - Always make sure to unload a "manually" loaded player, not doing this may cause a memory leak!
- If a long operation should be done on a team, make sure to load "manually" at least one player of that team. This way, the team will never be unloaded during the operation (and keeping the
TeamProgression
in cache).
UltimateAdvancementAPI Wiki © 2021 fren_gor, EscanorTargaryen is licensed under CC BY-SA 4.0.
Except where otherwise noted, code snippets inside the wiki are licensed under The Unlicense.