diff --git a/python/src/endstone/_internal/endstone_python.pyi b/python/src/endstone/_internal/endstone_python.pyi index 43eb855de..4cd6fa9fa 100644 --- a/python/src/endstone/_internal/endstone_python.pyi +++ b/python/src/endstone/_internal/endstone_python.pyi @@ -38,6 +38,14 @@ class Command: """ Executes the command, returning its success """ + def test_permission(self, target: CommandSender) -> bool: + """ + Tests the given CommandSender to see if they can perform this command. + """ + def test_permission_silently(self, target: CommandSender) -> bool: + """ + Tests the given CommandSender to see if they can perform this command. No error is sent to the sender. + """ @property def aliases(self) -> list[str]: """ @@ -63,6 +71,14 @@ class Command: def name(self, arg1: str) -> bool: ... @property + def permissions(self) -> list[str]: + """ + The permissions required by users to be able to perform this command + """ + @permissions.setter + def permissions(self, arg1: list[str]) -> None: + ... + @property def registered(self) -> bool: """ Returns the current registered state of this command @@ -237,7 +253,7 @@ class Plugin(CommandExecutor): Returns the Server instance currently running this plugin """ class PluginCommand(Command): - def __init__(self, plugin: Plugin, name: str, description: str | None = None, usages: list[str] | None = None, aliases: list[str] | None = None) -> None: + def __init__(self, plugin: Plugin, name: str, description: str | None = None, usages: list[str] | None = None, aliases: list[str] | None = None, permissions: list[str] | None = None) -> None: ... def _get_executor(self) -> CommandExecutor: ... diff --git a/python/src/endstone/plugin.py b/python/src/endstone/plugin.py index 045afa4f8..81236f032 100644 --- a/python/src/endstone/plugin.py +++ b/python/src/endstone/plugin.py @@ -22,8 +22,9 @@ def __init__( description: Optional[str] = None, usages: list[str] = None, aliases: list[str] = None, + permissions: list[str] = None, ) -> None: - _PluginCommand.__init__(self, plugin, name, description, usages, aliases) + _PluginCommand.__init__(self, plugin, name, description, usages, aliases, permissions) self._executor: CommandExecutor | None = None def _get_executor(self): @@ -54,12 +55,17 @@ def __init__(self): self._plugin_commands: list[PluginCommand] = [] # keep them alive def register_command( - self, name: str, description: str = "", usages: list[str] = None, aliases: list[str] = None + self, + name: str, + description: str = "", + usages: list[str] = None, + aliases: list[str] = None, + permissions: list[str] = None, ) -> PluginCommand: """ Registers a new PluginCommand. """ - command = PluginCommand(self, name, description, usages, aliases) + command = PluginCommand(self, name, description, usages, aliases, permissions) self._plugin_commands.append(command) return self.server.register_plugin_command(command) diff --git a/src/endstone_python/command.cpp b/src/endstone_python/command.cpp index 7d3c1e142..cfffcba33 100644 --- a/src/endstone_python/command.cpp +++ b/src/endstone_python/command.cpp @@ -53,6 +53,10 @@ void init_command(py::module &m) py::class_>(m, "Command") .def("execute", &Command::execute, py::arg("sender"), py::arg("args"), "Executes the command, returning its success") + .def("test_permission", &Command::testPermission, py::arg("target"), + "Tests the given CommandSender to see if they can perform this command.") + .def("test_permission_silently", &Command::testPermissionSilently, py::arg("target"), + "Tests the given CommandSender to see if they can perform this command. No error is sent to the sender.") .def_property("name", &Command::getName, &Command::setName, "Name of this command.") .def_property("description", &Command::getDescription, &Command::setDescription, "Brief description of this command") @@ -64,6 +68,10 @@ void init_command(py::module &m) "usages", &Command::getUsages, [](Command &self, const std::vector &usages) { self.setUsages(usages); }, "List of usages of this command") + .def_property( + "permissions", &Command::getPermissions, + [](Command &self, const std::vector &permissions) { self.setPermission(permissions); }, + "The permissions required by users to be able to perform this command") .def_property_readonly("registered", &Command::isRegistered, "Returns the current registered state of this command"); diff --git a/src/endstone_python/plugin.cpp b/src/endstone_python/plugin.cpp index e04a19c19..8a52fbc3a 100644 --- a/src/endstone_python/plugin.cpp +++ b/src/endstone_python/plugin.cpp @@ -127,10 +127,15 @@ class PyPluginCommand : public PluginCommand { namespace { PyPluginCommand createPluginCommand(Plugin &owner, std::string name, const std::optional &description, const std::optional> &usages, - const std::optional> &aliases) + const std::optional> &aliases, + const std::optional> &permissions) { - return {owner, std::move(name), description.value_or(""), usages.value_or(std::vector()), - aliases.value_or(std::vector())}; + return {owner, + std::move(name), + description.value_or(""), + usages.value_or(std::vector()), + aliases.value_or(std::vector()), + permissions.value_or(std::vector())}; } } // namespace @@ -174,7 +179,7 @@ void init_plugin(py::module &m) plugin_command // .def(py::init(&createPluginCommand), py::arg("plugin"), py::arg("name"), py::arg("description") = py::none(), - py::arg("usages") = py::none(), py::arg("aliases") = py::none()) + py::arg("usages") = py::none(), py::arg("aliases") = py::none(), py::arg("permissions") = py::none()) .def("_get_executor", &PluginCommand::getExecutor, py::return_value_policy::reference) .def("_set_executor", &PluginCommand::setExecutor, py::arg("executor")) .def_property_readonly("plugin", &PluginCommand::getPlugin, "Gets the owner of this PluginCommand");