A Placeholder API plugin for Endstone, inspired by the famous PAPI plugin for Spigot. This project provides both native
C++ support and Python bindings via the endstone_papi
package for seamless integration.
Note
This plugin is still under development and has not been released to PyPI. If you are interested in using this plugin, please check out the latest build from our GitHub Actions page: Build Artifacts.
endstone-essentials/papi/
├── endstone_papi/ # Python package (for Python plugins)
├── examples/
│ ├── cpp/ # C++ example plugin
│ └── python/ # Python example plugin
├── include/ # Header files (for C++ plugins)
├── CMakeLists.txt # CMake build configuration
├── pyproject.toml # Python package configuration
├── LICENSE # License information
└── README.md # This file
Note
you can obtain the papi.h
header file packaged within the .whl
file.
#include <endstone/endstone.hpp>
#include <endstone_papi/papi.h>
class JoinExample : public endstone::Plugin {
public:
void onEnable() override
{
if (getServer().getPluginManager().getPlugin("papi")) {
registerEvent(&JoinExample::onPlayerJoin, *this, endstone::EventPriority::Highest);
papi_ = getServer().getServiceManager().load<papi::PlaceholderAPI>("PlaceholderAPI");
}
else {
getLogger().warning("Could not find PlaceholderAPI! This plugin is required.");
getServer().getPluginManager().disablePlugin(*this);
}
}
void onPlayerJoin(endstone::PlayerJoinEvent &event)
{
std::string join_text = "{player_name} joined the server! Their game mode is {player_gamemode}";
join_text = papi_->setPlaceholder(event.getPlayer(), join_text);
event.setJoinMessage(join_text);
}
private:
std::shared_ptr<papi::PlaceholderAPI> papi_;
};
For the full codes, check our C++ Example Plugin.
from endstone_papi import PlaceholderAPI
from endstone.plugin import Plugin
from endstone.event import event_handler, EventPriority, PlayerJoinEvent
class JoinExample(Plugin):
api_version = "0.6"
soft_depend = ["papi"]
def on_enable(self):
if self.server.plugin_manager.get_plugin("papi"):
self.register_events(self)
self.papi = self.server.service_manager.load("PlaceholderAPI")
else:
self.logger.warning("Could not find PlaceholderAPI! This plugin is required.")
self.server.plugin_manager.disable_plugin(self)
@event_handler(priority=EventPriority.HIGHEST)
def on_player_join(self, event: PlayerJoinEvent):
join_text = "{player_name} joined the server! Their game mode is {player_gamemode}"
join_text = self.papi.set_placeholder(event.player, join_text)
event.join_message = join_text
For the full codes, check our Python Example Plugin.
The structure of a placeholder is {<identifier>|<params>}
. Field params
are optional and can be used to provide additional
information to the placeholder. The format of params
is decided by the processor of the placeholder indicated by identifier
.
When params
is missing, you can simply write the placeholder as {identifier}
.
There are a number of built-in placeholders that can be used once papi is installed:
-
{x}
x coordinate -
{y}
y coordinate -
{z}
z coordinate -
{player_name}
player's name -
{dimension}
dimension name -
{dimension_id}
dimension id -
{ping}
player ping -
{date}
date -
{time}
time -
{datetime}
date and time -
{year}
year -
{month}
month -
{day}
day -
{hour}
hour -
{minute}
minute -
{second}
second -
{mc_version}
minecraft version -
{online}
online player count -
{max_online}
max online player count -
{address}
player's address -
{runtime_id}
player's runtime id -
{exp_level}
player's experience level -
{total_exp}
player's experience in total -
{exp_progress}
player's experience progress -
{game_mode}
player's game mode -
{xuid}
player's xuid -
{uuid}
player's uuid -
{device_os}
os name of player's current device -
{locale}
player's locale
Python: 3.10+
Endstone: 0.6+
Contributions are welcome! Feel free to fork the repository, improve the code, and submit pull requests with your changes.
This project is licensed under the MIT License. See the LICENSE file for details.