mcdreforged.command.command_source 源代码

from abc import ABC
from contextlib import contextmanager
from typing import TYPE_CHECKING, Optional

from typing_extensions import TypeGuard

from mcdreforged.permission.permission_level import PermissionLevel
from mcdreforged.translation.translation_text import RTextMCDRTranslation
from mcdreforged.utils import misc_util
from mcdreforged.utils.exception import IllegalCallError
from mcdreforged.utils.types import MessageText

if TYPE_CHECKING:
	from mcdreforged.mcdr_server import MCDReforgedServer
	from mcdreforged.info_reactor.info import Info
	from mcdreforged.plugin.server_interface import ServerInterface
	from mcdreforged.plugin.type.plugin import AbstractPlugin
	from mcdreforged.preference.preference_manager import PreferenceItem


[文档] class CommandSource(ABC): """ :class:`CommandSource`: is an abstracted command executor model. It provides several methods for command execution Class inheriting tree:: CommandSource ├── InfoCommandSource │ ├── PlayerCommandSource │ └── ConsoleCommandSource └── PluginCommandSource Plugins can declare a class inherited from :class:`CommandSource` to create their own command source """ @property def is_player(self) -> TypeGuard['PlayerCommandSource']: """ If the command source is a player command source :return: ``True`` if it's a player command source, ``False`` otherwise """ return isinstance(self, PlayerCommandSource) @property def is_console(self) -> TypeGuard['ConsoleCommandSource']: """ If the command source is a console command source :return: ``True`` if it's a console command source, ``False`` otherwise """ return isinstance(self, ConsoleCommandSource)
[文档] def get_server(self) -> 'ServerInterface': """ Return the server interface instance """ raise NotImplementedError()
[文档] def get_permission_level(self) -> int: """ Return the permission level that the command source has The permission level is represented by int """ raise NotImplementedError()
[文档] def get_preference(self) -> 'PreferenceItem': """ Return the preference of the command source By default, the default preference of MCDR from :meth:`ServerInterface.get_default_preference() <mcdreforged.plugin.server_interface.ServerInterface.get_preference>` will be returned Subclasses might override this method to return customized preference. e.g. :class:`PlayerCommandSource` will return the preference of the corresponding player .. seealso:: method :meth:`ServerInterface.get_preference() <mcdreforged.plugin.server_interface.ServerInterface.get_preference>` .. versionadded:: v2.1.0 """ from mcdreforged.plugin.server_interface import ServerInterface server = ServerInterface.get_instance() if server is None: raise IllegalCallError('Cannot get default preference when MCDR is not running') return server.get_default_preference()
[文档] @contextmanager def preferred_language_context(self): """ A quick helper method to use the language value in preference to create a context with :meth:`RTextMCDRTranslation.language_context() <mcdreforged.translation.translation_text.RTextMCDRTranslation.language_context>` .. seealso:: Class :class:`~mcdreforged.translation.translation_text.RTextMCDRTranslation` Example usage:: with source.preferred_language_context(): message = source.get_server().rtr('my_plugin.placeholder').to_plain_text() text.set_click_event(RAction.suggest_command, message) .. versionadded:: v2.1.0 """ with RTextMCDRTranslation.language_context(self.get_preference().language): yield
[文档] def has_permission(self, level: int) -> bool: """ A helper method for testing permission requirement :param level: The permission level to be tested :return: If the command source has not less permission level than the given permission level """ return self.get_permission_level() >= level
[文档] def has_permission_higher_than(self, level: int) -> bool: """ Just like the :meth:`CommandSource.has_permission`, but this time it is a greater than judgment :param level: The permission level to be tested :return: If the command source has greater permission level than the given permission level """ return self.get_permission_level() > level
[文档] def reply(self, message: MessageText, **kwargs) -> None: """ Send a message to the command source. The message can be anything including RTexts :param message: The message you want to send :keyword encoding: The encoding method for the message. It's only used in :class:`PlayerCommandSource` :keyword console_text: Message override when it's a :class:`ConsoleCommandSource` """ raise NotImplementedError()
[文档] def __eq__(self, other) -> bool: """ .. versionadded:: v2.12.2 All MCDR builtin command sources have the implemented the `__eq__` method """ return super().__eq__(other)
[文档] class InfoCommandSource(CommandSource, ABC): """ Command source originated from an info created by MCDR """ def __init__(self, mcdr_server: 'MCDReforgedServer', info: 'Info'): self._mcdr_server = mcdr_server self.__info = info
[文档] def get_info(self) -> 'Info': """ Return the Info instance that this command source is created from """ return self.__info
def get_server(self) -> 'ServerInterface': return self._mcdr_server.basic_server_interface def get_permission_level(self) -> int: return self._mcdr_server.permission_manager.get_permission(self) def __str__(self): raise NotImplementedError() def __repr__(self): raise NotImplementedError()
class PlayerCommandSource(InfoCommandSource): def __init__(self, mcdr_server, info, player: str): if not info.is_from_server: raise TypeError('{} should be built from server info'.format(self.__class__.__name__)) super().__init__(mcdr_server, info) self.player: str = player """The name of the player""" def get_preference(self) -> 'PreferenceItem': return self.get_server().get_preference(self) def reply(self, message: MessageText, *, encoding: Optional[str] = None, **kwargs): """ :keyword encoding: encoding method to be used in :meth:`ServerInterface.tell` """ self._mcdr_server.basic_server_interface.tell(self.player, message, encoding=encoding) def __eq__(self, other) -> bool: return isinstance(other, PlayerCommandSource) and self.player == other.player def __str__(self): return 'Player {}'.format(self.player) def __repr__(self): return '{}[player={},info_id={}]'.format(type(self).__name__, self.player, self.get_info().id) class ConsoleCommandSource(InfoCommandSource): def __init__(self, mcdr_server, info): if not info.is_from_console: raise TypeError('{} should be built from console info'.format(self.__class__.__name__)) super().__init__(mcdr_server, info) def get_preference(self) -> 'PreferenceItem': return self.get_server().get_preference(self) def reply(self, message: MessageText, *, console_text: Optional[MessageText] = None, **kwargs): """ :keyword console_text: If it's specified, overwrite the value of parameter ``message`` with it """ if console_text is not None: message = console_text with self.preferred_language_context(): misc_util.print_text_to_console(self._mcdr_server.logger, message) def __eq__(self, other) -> bool: return isinstance(other, ConsoleCommandSource) def __str__(self): return 'Console' def __repr__(self): return '{}[info_id={}]'.format(type(self).__name__, self.get_info().id) class PluginCommandSource(CommandSource): def __init__(self, server: 'ServerInterface', plugin: Optional['AbstractPlugin'] = None): self.__server = server.as_basic_server_interface() self.__logger = self.__server.logger self.__plugin = plugin def get_server(self) -> 'ServerInterface': return self.__server def get_permission_level(self) -> int: return PermissionLevel.PLUGIN_LEVEL def reply(self, message: MessageText, **kwargs) -> None: misc_util.print_text_to_console(self.__logger, message) def __eq__(self, other) -> bool: return isinstance(other, PluginCommandSource) and self.__plugin.get_id() == other.__plugin.get_id() def __str__(self): return 'Plugin' if self.__plugin is None else 'Plugin {}'.format(self.__plugin) def __repr__(self): return '{}[plugin={}]'.format(type(self).__name__, self.__plugin)