ServerInterface

API package path: mcdreforged.api.types

class mcdreforged.plugin.server_interface.ServerInterface(mcdr_server: MCDReforgedServer)[source]

ServerInterface is the interface with lots of API for plugins to interact with the server. Its subclass PluginServerInterface contains extra APIs for plugins to control the plugin itself

It’s recommend to use server as the variable name of the ServerInterface. This is widely used in this document

Instance Getters

classmethod ServerInterface.get_instance() ServerInterface | None[source]

A class method, for plugins to get a ServerInterface instance anywhere as long as MCDR is running

ServerInterface.as_basic_server_interface() ServerInterface[source]

Return a ServerInterface instance. The type of the return value is exactly the ServerInterface

It’s used for removing the plugin information inside PluginServerInterface when you need to send a ServerInterface as parameter

ServerInterface.as_plugin_server_interface() PluginServerInterface | None[source]

Return a PluginServerInterface instance.

If the object is exactly a PluginServerInterface instance, return itself

If the plugin context is available, return the PluginServerInterface for the related plugin. Currently, plugin context is only available inside the following scenarios:

  1. Plugin entrypoint module loading

  2. Event listener callback invocation

  3. Command callback invocation

classmethod ServerInterface.si() ServerInterface[source]

Alias / Shortform of get_instance(), and never returns None

Raises:

RuntimeError – If MCDR is not running

classmethod ServerInterface.si_opt() ServerInterface | None[source]

Alias / Shortform of get_instance(), get an optional ServerInterface instance

Returns:

The ServerInterface instance, or None if failed

classmethod ServerInterface.psi() PluginServerInterface[source]

Shortform of the combination of get_instance() + as_plugin_server_interface(), and never returns None

Raises:

RuntimeError – Get PluginServerInterface failed. This might occur because MCDR is not running (see si()), or plugin context is unavailable (see as_plugin_server_interface())

classmethod ServerInterface.psi_opt() PluginServerInterface | None[source]

Shortform of the combination of get_instance() + as_plugin_server_interface(), get an optional PluginServerInterface instance

Returns:

The PluginServerInterface instance for the current plugin, or None if failed

Utils

ServerInterface.MCDR = True

An identifier field for MCDR

property ServerInterface.logger: Logger

A nice logger for you to log message to the console

ServerInterface.tr(translation_key: str, *args, _mcdr_tr_language: str | None = None, language: str | None = None, **kwargs) str | RTextBase[source]

Return a translated text corresponded to the translation key and format the text with given args and kwargs

If args or kwargs contains RText element, then the result will be a RText, otherwise the result will be a regular str

If the translation key is not recognized, the return value will be the translation key itself

See here for the ways to register translations for your plugin

Parameters:
  • translation_key – The key of the translation

  • args – The args to be formatted

  • _mcdr_tr_language – Specific language to be used in this translation, or the language that MCDR is using will be used

  • language – Deprecated, to be removed in v2.15. Use kwarg _mcdr_tr_language instead

  • kwargs – The kwargs to be formatted

ServerInterface.rtr(translation_key: str, *args, **kwargs) RTextMCDRTranslation[source]

Return a RTextMCDRTranslation component, that only translates itself right before displaying or serializing

Using this method instead of tr() allows you to display your texts in user’s preferred language automatically

Of course, you can construct RTextMCDRTranslation yourself instead of using this method if you want

Parameters:
  • translation_key – The key of the translation

  • args – The args to be formatted

  • kwargs – The kwargs to be formatted

New in version v2.1.0.

ServerInterface.has_translation(translation_key: str, *, language: str | None = None, no_auto_fallback: bool = False)[source]

Check if the given translation exists

Notes that if the current language fails, MCDR will try to use “en_us” for a second attempt. If you don’t want this auto-fallback behavior, set argument no_auto_fallback to True

Also, you don’t need to pass *args and **kwargs for the translation into this method, because existence check doesn’t need those

Parameters:

translation_key – The key of the translation

Keyword Arguments:
  • language – Optional, the language to check for translation key existence

  • no_auto_fallback – When set to True, MCDR will not fall back to “en_us” and have another translation try, if translation failed

New in version v2.12.0.

Server Control

ServerInterface.start() bool[source]

Start the server. Return if the action succeed.

If the server is running or being starting by other plugin it will return False

Returns:

If the operation succeed. The operation fails if the server is already started, or cannot start due to invalid command or current MCDR state

ServerInterface.stop() bool[source]

Soft shutting down the server by sending the correct stop command to the server

This option will not stop MCDR. MCDR will keep running unless exit() is invoked

Returns:

If the operation succeed. The operation fails if the server is already stopped

ServerInterface.kill() bool[source]

Kill the entire server process group. A hard shutting down

MCDR will keep running unless exit() is invoked

Returns:

If the operation succeed. The operation fails if the server is already stopped

ServerInterface.wait_until_stop() None[source]

Wait until the server is stopped

Note

The current thread will be blocked

ServerInterface.wait_for_start() None[source]

Wait until the server is able to start

Actually it’s an alias of wait_until_stop()

ServerInterface.restart() bool[source]

Restart the server

It will first soft stop the server and then wait until the server is stopped, finally start the server up

Returns:

If the operation succeed. The operation fails if the server is already stopped

ServerInterface.stop_exit() bool[source]

soft stop the server and exit MCDR

Returns:

If the operation succeed. The operation fails if the server is already stopped

ServerInterface.exit() bool[source]

Exit MCDR when the server is stopped

Basically it’s the same to invoking set_exit_after_stop_flag() with parameter True, but with an extra server not running check

Example usage:

server.stop()  # Stop the server
# do something A
server.wait_for_start()  # Make sure the server is fully stopped. It's necessary to run it in your custom thread
# do something B
server.exit()  # Exit MCDR
Returns:

If the operation succeed. The operation fails if the server is still running

ServerInterface.set_exit_after_stop_flag(flag_value: bool) None[source]

Set the flag that indicating if MCDR should exit when the server has stopped

If set to True, after the server stops MCDR will exit, otherwise (set to False) MCDR will just keep running

The flag value will be set to True everytime when the server starts

The flag value is displayed in line 5 in command !!MCDR status

ServerInterface.is_server_running() bool[source]

Return if the server is running

ServerInterface.is_server_startup() bool[source]

Return if the server has started up

ServerInterface.is_rcon_running() bool[source]

Return if MCDR’s rcon is running

ServerInterface.get_server_pid() int | None[source]

Return the pid of the server process

Notes the process with this pid is a bash process, which is the parent process of real server process you might be interested in

Returns:

The pid of the server. None if the server is stopped

ServerInterface.get_server_pid_all() List[int][source]

Return a list of pid of all processes in the server’s process group

Returns:

A list of pid. It will be empty if the server is stopped or the pid query failed

New in version v2.6.0.

ServerInterface.get_server_information() ServerInformation[source]

Return a ServerInformation object indicating the information of the current server, interred from the output of the server

It’s field(s) might be None if the server is offline, or the related information has not been parsed

New in version v2.1.0.

Text Interaction

ServerInterface.execute(text: str, *, encoding: str | None = None) None[source]

Execute a server command by sending the command content to server’s standard input stream

See also

execute_command() if you want to execute command in MCDR’s command system

Parameters:

text – The content of the command you want to send

Keyword Arguments:

encoding – The encoding method for the text. Leave it empty to use the encoding method from the configuration of MCDR

ServerInterface.tell(player: str, text: str | RTextBase, *, encoding: str | None = None) None[source]

Use command like /tellraw to send the message to the specific player

Parameters:
  • player – The name of the player you want to tell

  • text – The message you want to send to the player

Keyword Arguments:

encoding – The encoding method for the text. Leave it empty to use the encoding method from the configuration of MCDR

ServerInterface.say(text: str | RTextBase, *, encoding: str | None = None) None[source]

Use command like /tellraw @a to broadcast the message in game

Parameters:

text – The message you want to send

Keyword Arguments:

encoding – The encoding method for the text. Leave it empty to use the encoding method from the configuration of MCDR

ServerInterface.broadcast(text: str | RTextBase, *, encoding: str | None = None) None[source]

Broadcast the message in game and to the console

If the server is not running, send the message to console only

Parameters:

text – The message you want to send

Keyword Arguments:

encoding – The encoding method for the text. Leave it empty to use the encoding method from the configuration of MCDR

ServerInterface.reply(info: Info, text: str | RTextBase, *, encoding: str | None = None, console_text: str | RTextBase | None = None)[source]

Reply to the source of the Info

If the Info is from a player, then use tell to reply the player; if the Info is from the console, then use server.logger.info to output to the console; In the rest of the situations, the Info is not from a user, a IllegalCallError is raised

Parameters:
  • info – the Info you want to reply to

  • text – The message you want to send

Keyword Arguments:
  • encoding – The encoding method for the text

  • console_text – If it’s specified, console_text will be used instead of text when replying to console

Raises:

IllegalCallError – If the Info is not from a user

Plugin Queries

ServerInterface.get_plugin_metadata(plugin_id: str) Metadata | None[source]

Return the metadata of the specified plugin, or None if the plugin doesn’t exist

Parameters:

plugin_id – The plugin id of the plugin to query metadata

ServerInterface.get_plugin_file_path(plugin_id: str) str | None[source]

Return the file path of the specified plugin, or None if the plugin doesn’t exist

Parameters:

plugin_id – The plugin id of the plugin to query file path

ServerInterface.get_plugin_instance(plugin_id: str) Any | None[source]

Return the entrypoint module instance of the specific plugin, or None if the plugin doesn’t exist

If the target plugin is a solo plugin and it needs to react to events from MCDR, it’s quite important to use this instead of manually import the plugin you want, since it’s the only way to make your plugin be able to access the same plugin instance to MCDR

Example usage:

The entrypoint module of my API plugin with id my_api:

def some_api(item):
    pass

Another plugin that needs my API plugin:

server.get_plugin_instance('my_api').some_api(an_item)
Parameters:

plugin_id – The plugin id of the plugin you want to get entrypoint module instance

Returns:

A entrypoint module instance, or None if the plugin doesn’t exist

ServerInterface.get_plugin_list() List[str][source]

Return a list containing all loaded plugin id like ["my_plugin", "another_plugin"]

ServerInterface.get_unloaded_plugin_list() List[str][source]

Return a list containing all unloaded plugin file path like ["plugins/MyPlugin.mcdr"]

New in version v2.3.0.

ServerInterface.get_disabled_plugin_list() List[str][source]

Return a list containing all disabled plugin file path like [“plugins/MyPlugin.mcdr.disabled”]

New in version v2.3.0.

ServerInterface.get_all_metadata() Dict[str, Metadata][source]

Return a dict containing metadata of all loaded plugin with (plugin_id, metadata) as key-value pair

Plugin Operations

Warning

All plugin manipulation will trigger a dependency check, which might cause unwanted plugin operations

It’s not suggested to trigger plugin operations during on_load or on_unload plugin events. During these events, MCDR is in a process of an ongoing plugin operation, which is not suitable to triggered another plugin operation

If you do trigger a plugin operation during on_load or on_unload plugin events, MCDR will delay the new operations till the first operation finishes. In this delayed operation case, the return value of following APIs will always be false or None

ServerInterface.load_plugin(plugin_file_path: str) bool[source]

Load a plugin from the given file path

Parameters:

plugin_file_path – The file path of the plugin to load. Example: “plugins/my_plugin.py”

Returns:

If the plugin gets loaded successfully

ServerInterface.enable_plugin(plugin_file_path: str) bool[source]

Enable a disabled plugin from the given path

Parameters:

plugin_file_path – The file path of the plugin to enable. Example: “plugins/my_plugin.py.disabled”

Returns:

If the plugin gets enabled successfully

ServerInterface.reload_plugin(plugin_id: str) bool | None[source]

Reload a plugin specified by plugin id

Parameters:

plugin_id – The id of the plugin to reload. Example: "my_plugin"

Returns:

A bool indicating if the plugin gets reloaded successfully, or None if plugin not found

ServerInterface.unload_plugin(plugin_id: str) bool | None[source]

Unload a plugin specified by plugin id

Parameters:

plugin_id – The id of the plugin to unload. Example: "my_plugin"

Returns:

A bool indicating if the plugin gets unloaded successfully, or None if plugin not found

ServerInterface.disable_plugin(plugin_id: str) bool | None[source]

Disable an unloaded plugin specified by plugin id

Parameters:

plugin_id – The id of the plugin to disable. Example: "my_plugin"

Returns:

A bool indicating if the plugin gets disabled successfully, or None if plugin not found

ServerInterface.refresh_all_plugins() None[source]

Reload all plugins, load all new plugins and then unload all removed plugins

ServerInterface.refresh_changed_plugins() None[source]

Reload all changed plugins, load all new plugins and then unload all removed plugins

ServerInterface.dispatch_event(event: PluginEvent, args: Tuple[Any, ...], *, on_executor_thread: bool = True) None[source]

Dispatch an event to all loaded plugins

The event will be immediately dispatch if it’s on the task executor thread, or gets enqueued if it’s on other thread

Note

You cannot dispatch an event with the same event id to any MCDR built-in event

Example

For the event dispatcher plugin:

server.dispatch_event(LiteralEvent('my_plugin.my_event'), (1, 'a'))

For the event listener plugin:

def do_something(server: PluginServerInterface, int_data: int, str_data: str):
    pass

server.register_event_listener('my_plugin.my_event', do_something)
Parameters:
  • event – The event to dispatch. It needs to be a PluginEvent instance. For simple usage, you can create a LiteralEvent instance for this argument

  • args – The argument that will be used to invoke the event listeners. An PluginServerInterface instance will be automatically added to the beginning of the argument list

Keyword Arguments:

on_executor_thread – By default the event will be dispatched in a new task in task executor thread If it’s set to False. The event will be dispatched immediately

Configuration

ServerInterface.get_mcdr_language() str[source]

Return the current language MCDR is using

ServerInterface.get_mcdr_config() dict[source]

Return the current config of MCDR as a dict

ServerInterface.modify_mcdr_config(changes: Dict[Tuple[str] | str, Any])[source]

Modify the configuration of MCDR

The modification will be written to the disk and take effect immediately

Currently, MCDR will not validate the type of the value

Example usages:

server.modify_mcdr_config({'encoding': 'utf8'})
server.modify_mcdr_config({'rcon.address': '127.0.0.1', 'rcon.port': 23000})
server.modify_mcdr_config({('debug', 'command'): True})
Parameters:

changes – A dict storing the changes to the config. For the entries of the dict: The key can be a tuple storing the path to the config value, or a str that concat the path with "."; The value is the config value to be set

New in version v2.7.0.

ServerInterface.reload_config_file(*, log: bool = False)[source]

Reload the configuration of MCDR from config file

It has the same effect as command !!MCDR reload config

Keyword Arguments:

log – If the config changing messages should be logged

New in version v2.7.0.

Permission

ServerInterface.get_permission_level(obj: str | Info | CommandSource) int[source]

Return an int indicating permission level number the given object has

The object could be a str indicating the name of a player, an Info instance or a command source

Parameters:

obj – The object you are querying

Raises:

TypeError – If the type of the given object is not supported for permission querying

ServerInterface.set_permission_level(player: str, value: str | int) None[source]

Set the permission level of the given player

Parameters:
  • player – The name of the player that you want to set his/her permission level

  • value – The target permission level you want to set the player to. It can be an int or a str as long as it’s related to the permission level. Available examples: 1, "1", "user"

Raises:

TypeError – If the value parameter doesn’t properly represent a permission level

ServerInterface.reload_permission_file()[source]

Reload the permission of MCDR from permission file

It has the same effect as command !!MCDR reload permission

New in version v2.7.0.

Command

ServerInterface.get_plugin_command_source() PluginCommandSource[source]

Return a simple plugin command source for e.g. command execution

It’s not player or console, it has maximum permission level, it uses logger for replying

ServerInterface.execute_command(command: str, source: CommandSource = None) None[source]

Execute a single command in MCDR’s command system

See also

execute() if you want to send some text to server’s standard input stream

Parameters:
  • command – The command you want to execute

  • source – The command source that is used to execute the command. If it’s not specified MCDR will use get_plugin_command_source() to get a fallback command source

Preference

ServerInterface.get_preference(obj: str | PlayerCommandSource | ConsoleCommandSource) PreferenceItem[source]

Get the MCDR preference of the given object

The object can be a str indicating the name of a player, or a command source. For command source, only PlayerCommandSource and ConsoleCommandSource are supported

Parameters:

obj – The object to query preference

Raises:

TypeError – If the type of the given object is not supported for preference querying

New in version v2.1.0.

ServerInterface.get_default_preference() PreferenceItem[source]

Get the default MCDR preference

New in version v2.8.0.

ServerInterface.set_preference(obj: str | PlayerCommandSource | ConsoleCommandSource, preference: PreferenceItem)[source]

Set the MCDR preference of the given object

The object can be a str indicating the name of a player, or a command source. For command source, only PlayerCommandSource and ConsoleCommandSource are supported

Parameters:
  • obj – The object to set preference

  • preference – The preference to be set

Raises:

TypeError – If the type of the given object is not supported for preference querying

New in version v2.8.0.

Misc

ServerInterface.is_on_executor_thread() bool[source]

Return if the current thread is the task executor thread

Task executor thread is the main thread to parse messages and trigger listeners where some ServerInterface APIs are required to be invoked on

ServerInterface.rcon_query(command: str) str | None[source]

Send command to the server through rcon connection

Parameters:

command – The command you want to send to the rcon server

Returns:

The result that server returned from rcon. Return None if rcon is not running or rcon query failed

ServerInterface.schedule_task(callable_: Callable[[], Any], *, block: bool = False, timeout: float | None = None) None[source]

Schedule a callback task to be run in task executor thread

Parameters:

callable – The callable object to be run. It should accept 0 parameter

Keyword Arguments:
  • block – If blocks until the callable finished execution

  • timeout – The timeout of the blocking operation if block=True