Working with players
Find online players, message them, move them, and read or change their state.
A Player is the API handle for someone connected to the server. From it you send messages and titles, play sounds, teleport, change game mode, and read stats like health and experience. Player extends Mob -> Actor -> OfflinePlayer, so everything an entity can do - location, health, teleport - a player can do too. This page covers the player-specific surface; for locations and the level the player lives in, see worlds and blocks.
#include <endstone/endstone.hpp>
namespace es = endstone;The es:: alias is assumed in the fragments below.
Get a player
The server hands you the players that are online right now, and looks one up by name or by UUID:
std::vector<es::Player *> players = getServer().getOnlinePlayers(); // everyone connected now
es::Player *by_name = getServer().getPlayer("Steve"); // case-insensitive exact name
es::Player *by_uuid = getServer().getPlayer(some_uuid); // es::UUIDgetPlayer returns nullptr when nobody matches - the player may have logged off, or the name may be misspelled. Always check before dereferencing:
auto *player = getServer().getPlayer(name);
if (player == nullptr) {
sender.sendErrorMessage("{} is not online.", name);
return true;
}Most of the time you don't look players up at all - you receive them. A command handler is passed the sender (often a player), and events carry the player on event.getPlayer().
Message and notify
sendMessage and sendErrorMessage are inherited from every command sender; the rest are player-only surfaces, each landing in a different spot on screen:
player.sendMessage("Goes to the chat log.");
player.sendErrorMessage("Red error text in chat.");
player.sendPopup("Popup above the hotbar.");
player.sendTip("Tip text, also above the hotbar.");
player.sendToast("Achievement!", "A toast in the top-right corner.");A title is the large text that fills the centre of the screen, with an optional subtitle under it. The two-argument form uses default timings; the five-argument form takes fade-in, stay, and fade-out in ticks (20 per second):
player.sendTitle("Welcome", "to the server");
player.sendTitle("Welcome", "to the server", 10, 70, 20);
player.resetTitle(); // clear it and restore default timingsMessages accept colour and format codes, so you can colour any of the strings above.
Play sounds
Sounds play at a location - usually the player's own - with a volume and pitch:
player.playSound(player.getLocation(), "random.levelup", 1.0f, 1.0f);
player.stopSound("random.levelup");
player.stopAllSounds();Move and connect
teleport is inherited from Actor and takes a Location or another actor to teleport to. Build a Location from a dimension reference plus coordinates:
es::Location spawn{player.getDimension(), 0.0, 64.0, 0.0};
player.teleport(spawn); // to a location
player.teleport(other_player); // straight to another actorThe connection-level controls are player-only:
player.transfer("play.example.com", 19132); // hand the player to another server
player.kick("Banned for griefing."); // disconnect with a reason
player.performCommand("time set day"); // run a command as this playerGame mode
A player's game mode is read with getGameMode and set with setGameMode, using the GameMode enum:
if (player.getGameMode() == es::GameMode::Survival) {
player.setGameMode(es::GameMode::Creative);
}es::GameMode has Survival, Creative, Adventure, and Spectator.
Flight, sneaking, sprinting
Flight is two separate ideas: whether the player is allowed to fly, and whether they currently are. setFlySpeed and setWalkSpeed tune the movement speeds.
player.setAllowFlight(true); // enables the double-tap-jump to fly
player.setFlying(true); // put them in the air right now
player.setFlySpeed(0.1f); // default is 0.05
player.setWalkSpeed(0.2f); // default is 0.1
if (player.isSneaking()) {
// ...
}
player.setSprinting(true);Health and experience
getHealth / setHealth and getMaxHealth / setMaxHealth are inherited from Mob, measured in half-hearts (a full heart is 2):
player.setHealth(player.getMaxHealth()); // full heal
player.setMaxHealth(40); // 20 heartsExperience splits into a level and the fractional progress toward the next level:
player.giveExp(100); // raw experience points
player.giveExpLevels(5); // whole levels
player.setExpLevel(30); // set the level outright
player.setExpProgress(0.5f); // half-way to the next level (0.0 - 1.0)
int total = player.getTotalExp(); // read-only running totalA combined example
A /spawn command that teleports the player home, plays a sound, and drops a title - the everyday shape of player work. asPlayer() returns nullptr when the sender is the console, so guard it:
#include <endstone/endstone.hpp>
namespace es = endstone;
class MyPlugin : public es::Plugin {
public:
bool onCommand(es::CommandSender &sender, const es::Command &command,
const std::vector<std::string> &args) override
{
if (command.getName() == "spawn") {
auto *player = sender.asPlayer();
if (player == nullptr) {
sender.sendErrorMessage("Only players can use this command.");
return true;
}
es::Location spawn{player->getDimension(), 0.0, 64.0, 0.0};
player->teleport(spawn);
player->playSound(spawn, "mob.endermen.portal", 1.0f, 1.0f);
player->sendTitle("Spawn", "Welcome back!");
}
return true;
}
};Because Player is also an Actor, the same handler could just as well read player->getHealth(), check player->getGameMode(), or call player->setAllowFlight(true) - the entity API and the player API are one object. See worlds and blocks for Location and the level the player moves through, and forms for richer in-game UI.