-
Notifications
You must be signed in to change notification settings - Fork 0
How to work with Custom Players
Welcome to BearCommands Wiki!
Many times you might have the need to save certain information for every player.
Let's say you are developing a Home plugin: an idea would be to create a .yml file for each player, and save all the player's homes in it.
We call this mechanic "CustomPlayer". A CustomPlayer is a wrapper class that contains basic information of that player (UUID, name) as well as other data chosen by the developer.
BearCommands allows to implement this kind of system in a very easy and reliable way;
all you need is a CustomPlayer and a Manager!
NOTE: in the following examples we will use the Bukkit API, but this also applies for BungeeCord and Velocity.
| Contents |
|---|
| BearPlayer |
| PlayerWrapper |
| SimpleBearPlayersManager |
| (Bukkit) OfflineBearPlayer |
| AnswerListener |
The BearPlayer class (BungeeCord: BungeeBearPlayer, Velocity: VelocityBearPlayer) is the wrapper class that will be used as CustomPlayer.
package it.fulminazzo.testplugin.Objects;
import it.angrybear.Bukkit.BearPlugin;
import it.angrybear.Bukkit.Objects.BearPlayer;
import it.angrybear.Objects.Wrappers.PlayerWrapper;
import it.fulminazzo.TestPlugin;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import java.io.File;
public class TestPlayer extends BearPlayer<TestPlugin> {
// An example of data: not required.
private String data;
public TestPlayer(TestPlugin plugin, File playersFolder, OfflinePlayer player) throws Exception {
super(plugin, playersFolder, player);
}
@Override
protected void createNew(PlayerWrapper playerWrapper) {
data = ((Player) playerWrapper.getPlayer()).getDisplayName();
}
public String getData() {
return data;
}
}As you can see, creating a custom player is trivial, but there are some things to keep in mind:
- the constructor can NOT be altered. It should always be left as it is, the only modification allowed is the type of plugin, that can be your plugin main class;
- since the constructor has to remain the same, the
createNew(PlayerWrapper playerWrapper)method exists. This method will be only called if the custom player is being created (the corresponding YAML file is not present).
For the sake of uniformity and cross-compatibility, all ABearPlayer classes use PlayerWrapper in their createNew methods.
As the name suggests, a PlayerWrapper is an object containing the real player object, regardless of the platform you are on.
Its primary use is to retrieve the real object in the createNew method, but if offers some simple basic functions on its own:
sendMessage(String message), getName(), getUniqueId() and getPing().
Since ABearPlayer, the parent for every BearPlayer implementation, extends Savable,
the plugin will automatically load and dump fields from the YAML file.
Once you are satisfied with your CustomPlayer, it is time to create a Manager that will be responsible for keeping safe every player and easily get access to them.
package it.fulminazzo.testplugin.Managers;
import it.angrybear.Interfaces.IBearPlugin;
import it.angrybear.Managers.BearPlayersManager;
import it.fulminazzo.testplugin.Objects.TestPlayer;
public class TestPlayersManager extends BearPlayersManager<TestPlayer> {
public TestPlayersManager(IBearPlugin<?> plugin, Class<TestPlayer> customPlayerClass) {
super(plugin, customPlayerClass);
}
}This class is universal among other platforms, so a BungeeBearPlayersManager or a VelocityBearPlayersManager do not exist.
While this might seem a very basic implementation, it is crucial to pass the newly created CustomPlayer class in the diamond brackets.
Also, you should never change the constructor of your manager (because of how BearCommands works).
Finally, to complete the system you will have to go back to your plugin main class and add the new manager:
package it.fulminazzo.testplugin;
import it.angrybear.Bukkit.BearPlugin;
import it.angrybear.Bukkit.Objects.BearPlayer;
import it.fulminazzo.testplugin.Managers.TestPlayersManager;
import it.fulminazzo.testplugin.Objects.TestPlayer;
public class TestPlugin extends BearPlugin<TestPlayer, BearPlayer> {
@Override
public void onEnable() {
setPlayerManagerClass(TestPlayersManager.class, TestPlayer.class);
super.onEnable();
}
}A couple of notes before we finish off:
- extending the SimpleBearPlugin class will not be enough anymore; instead, you will have to specify the type of your new CustomPlayer using the default BearPlugin class;
- it is important to specify before the
super.onEnable()call which manager you are using and what CustomPlayer class.
If you are not interested in saving the custom players, but only keeping them saved in memory, then SimpleBearPlayersManager is the class you are looking for. This class works as BearPlayersManager does, but with the exception that it will not create any YAML file or folders to store the players in.
If you are working with Bukkit, there are some additions that you can work with on your plugin.
First, you might have noticed that while
BungeeBearPlugin
and
VelocityBearPlugin
only require one type of BearPlayer,
BearPlugin
requires two.
This is because, since you are working with Bukkit, you also have access to player data while they are offline.
BearCommands tries to replicate this behaviour by offering another manager: OfflineBearPlayersManager.
Its functioning and creation is the same as BearPlayersManager, with the exception that,
while with the normal version players are added on join and removed on quit, here they will always be saved in and retrievable from memory.
To add your custom OfflineBearPlayer manager you can proceed as you would with BearPlayersManager:
package it.fulminazzo.testplugin;
import it.angrybear.Bukkit.BearPlugin;
import it.fulminazzo.testplugin.Managers.TestPlayersManager;
import it.fulminazzo.testplugin.Managers.TestOfflinePlayersManager;
import it.fulminazzo.testplugin.Objects.TestPlayer;
import it.fulminazzo.testplugin.Objects.TestOfflinePlayer;
public class TestPlugin extends BearPlugin<TestPlayer, TestOfflinePlayer> {
@Override
public void onEnable() {
setPlayerManagerClass(TestPlayersManager.class, TestPlayer.class);
setOfflinePlayersManagerClass(TestOfflinePlayersManager.class, TestOfflinePlayer.class);
super.onEnable();
}
}BearCommands provides an implementation of question-answer system for the players. You can simply ask a question to a player using your previously created BearPlayer:
public void askQuestion(BiConsumer<PlayerWrapper, String> action, Consumer<PlayerWrapper> cancelAction, int seconds);Here are the parameters:
-
BiConsumer<PlayerWrapper, String> action: the action that should be executed upon responding. The first parameter is the player, the second is the answer given; -
Consumer<PlayerWrapper> cancelAction: the action to execute when the player answers with "cancel"; -
int seconds: the seconds after which the question is expired (optional).
So, for example you would do:
/* ... */
// Since this mechanic is cross-platform, the type of BearPlayer is irrelevant.
// We use ABearPlayer to generalize.
ABearPlayer player = getPlayersManager().getPlayer("Test");
player.askQuestion((p, s) -> p.sendMessage("You answered: " + s),
p -> p.sendMessage("You cancelled the question."),
180);
/* ... */Then, you will have to register a Listener in your plugin main class, according to the platform you are in:
/* ... */
@Override
public void loadListeners() throws Exception {
super.loadListeners();
// Bukkit
Bukkit.getPluginManager().registerEvents(new AnswersListener<>(this), this);
// BungeeCord
ProxyServer.getInstance().getPluginManager().registerListener(this, new BungeeAnswersListener<>(this));
// Velocity
proxyServer.getEventManager().register(this, new VelocityAnswersListener<>(this));
}
/* ... */That's it! You now have a fully functioning question-answer system for your project.
- Home
- How to start a plugin
- Work with Configuration Files
- Work with Enums
- Work with Commands
- Work with Custom Players
- Work with Messaging Channels
- Creating custom SavableObjects
- Timers
- General Utils
- Placeholders
- Bukkit Utils
- Velocity Utils