Skip to content

Commit

Permalink
Create: #3 独立模式任需要更多基础命令,包括Plugin,list,info等等 ; Fix: #13 独立版本命令无法执行, #14
Browse files Browse the repository at this point in the history
 独立版本加载插件时会出现冲突
  • Loading branch information
zhongbai2333 committed Feb 4, 2025
1 parent 5bc3dd2 commit dc1aa3e
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 35 deletions.
8 changes: 8 additions & 0 deletions connect_core/cli/cli_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@
from connect_core.interface.control_interface import CoreControlInterface
from connect_core.account.register_system import register_system_main
from connect_core.cli.commands import ServerCommand, ClientCommand
from connect_core.cli.command_core import CommandLineInterface

command_core = None

class Server(object):
def __init__(self) -> None:
global command_core
self._control_interface = CoreControlInterface()
command_core = CommandLineInterface(self._control_interface)
command_core.start()
self._control_interface.info(self._control_interface.tr("cli.starting.welcome"))
register_system_main(self._control_interface)
init_plugin_main(self._control_interface)
Expand Down Expand Up @@ -45,7 +50,10 @@ def start_servers(self) -> None:

class Client(object):
def __init__(self) -> None:
global command_core
self._control_interface = CoreControlInterface()
command_core = CommandLineInterface(self._control_interface)
command_core.start()
_config = self._control_interface.get_config()
self._control_interface.info(
self._control_interface.tr(
Expand Down
45 changes: 28 additions & 17 deletions connect_core/cli/command_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,18 @@
from typing import TYPE_CHECKING

if TYPE_CHECKING:
from connect_core.api.interface import PluginControlInterface
from connect_core.api.interface import CoreControlInterface


# 命令行界面类
class CommandLineInterface:
def __init__(self, interface: "PluginControlInterface", prompt: str = ">>> "):

def __init__(self, interface: "CoreControlInterface", prompt: str = ">>> "):
"""
初始化命令行界面类,设置默认提示符和补全器。
Args:
connect_interface (PluginControlInterface): API接口
connect_interface (CoreControlInterface): API接口
"""
self.prompt = prompt
self.completer = {}
Expand Down Expand Up @@ -56,14 +57,21 @@ def add_command(self, sid, command, action):
action (callable): 执行该命令的函数。
"""
commands = command.split()
self.commands.setdefault(sid, {})
for key in commands[:-1]: # 迭代到倒数第二个元素,创建或找到路径
if key not in self.commands[sid]:
self.commands[sid][key] = {} # 如果没有这个键,创建一个新的空字典
self.commands[sid] = self.commands[sid][key]

# 确保 sid 存在,并初始化为空字典
if sid not in self.commands:
self.commands[sid] = {}

cmd_dict = self.commands[sid] # 先取得命令字典

# 遍历命令路径中的每一部分,逐级进入字典
for key in commands[:-1]: # 遍历到倒数第二个元素,创建或找到路径
if key not in cmd_dict:
cmd_dict[key] = {} # 如果没有这个键,创建一个新的空字典
cmd_dict = cmd_dict[key] # 进入下一层级

# 对于最后一个元素,赋予值
self.commands[sid][commands[-1]] = action
cmd_dict[commands[-1]] = action

def remove_command(self, sid, command):
"""
Expand Down Expand Up @@ -136,7 +144,7 @@ def handle_input(self, text):
if sid not in self.commands:
self.interface.warn(f"未知插件ID: {sid}")
return None

# 如果只输入了sid,没有其他命令,默认执行 sid help
if not params:
params = ["help"]
Expand All @@ -150,13 +158,16 @@ def handle_input(self, text):
# 如果命令存在并且当前路径是字典
if isinstance(command, dict) and key in command:
command = command[key]
# 如果遇到占位符,进行替换
elif (
isinstance(command, dict)
and isinstance(command.get(key), str)
and re.match(r"<.*>", key)
):
final_params.append(key.strip("<>")) # 提取参数
# 如果遇到占位符,进行替换并提取参数
elif isinstance(command, dict):
# 查找命令中带占位符的键
for cmd_key in command.keys():
match = re.match(r"<([^>]+)>", cmd_key) # 匹配占位符
if match:
# 如果占位符匹配,则将用户输入的参数替换占位符
final_params.append(key) # 用实际值替换占位符
command = command[cmd_key] # 进入下一层字典
break
else:
self.interface.warn(f"未知命令: {key}")
return None # 如果路径不存在或某层不是字典,则返回 None
Expand Down
84 changes: 77 additions & 7 deletions connect_core/cli/commands.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import os
from typing import TYPE_CHECKING
from connect_core.tools import auto_trigger
from connect_core.plugin.init_plugin import load_plugin, reload_plugin, unload_plugin, get_plugins

if TYPE_CHECKING:
from connect_core.interface.control_interface import CoreControlInterface


class Command(object):
def __init__(self, control_interface: "CoreControlInterface"):
self._control_interface = control_interface
Expand All @@ -12,12 +16,26 @@ def _reg_commands(self):
# Register commands here
self._control_interface.add_command("help", self._handle_help)
self._control_interface.add_command("list", self._handle_list)
self._control_interface.add_command(
"plugin load <Path>", self._handle_plugin_load
)
self._control_interface.add_command(
"plugin reload <ID>", self._handle_plugin_reload
)
self._control_interface.add_command(
"plugin unload <ID>", self._handle_plugin_unload
)
self._completer_words["help"] = None
self._completer_words["list"] = None
self._control_interface.set_completer_words(self._completer_words)
self._control_interface.flush_cli()
self._completer_words["plugin"] = {
"load": None,
"reload": None,
"unload": None,
}
self._get_file_list()
self._reload_completer()

def _handle_help(self, args: list):
def _handle_help(self, *_):
if self._control_interface.is_server():
self._control_interface.info(
self._control_interface.tr("commands.server_help")
Expand All @@ -27,27 +45,60 @@ def _handle_help(self, args: list):
self._control_interface.tr("commands.client_help")
)

def _handle_list(self, args: list):
def _handle_list(self, *_):
self._control_interface.info("==list==")
for num, key in enumerate(self._control_interface.get_server_list()):
self._control_interface.info(f"{num + 1}. {key}")

def _handle_plugin_load(self, path: str):
# Implement plugin loading logic here
load_plugin(path)

def _handle_plugin_reload(self, id: str):
# Implement plugin reloading logic here
reload_plugin(id)

def _handle_plugin_unload(self, id: str):
# Implement plugin unload logic here
unload_plugin(id)

@auto_trigger(5, "plugin_file_list")
def _get_file_list(self):
file_list = {}
id_list = {}
for i in os.listdir("./plugins/"):
file_list[i] = None
for i in get_plugins():
id_list[i] = None
if self._completer_words["plugin"]["load"] != file_list:
self._completer_words["plugin"]["load"] = file_list
self._reload_completer()
if self._completer_words["plugin"]["reload"] != id_list:
self._completer_words["plugin"]["reload"] = id_list
self._completer_words["plugin"]["unload"] = id_list
self._reload_completer()

def _reload_completer(self):
self._control_interface.set_completer_words(self._completer_words)
self._control_interface.flush_cli()


class ServerCommand(Command):
def __init__(self, control_interface: "CoreControlInterface"):
super().__init__(control_interface)

self._reg_commands()
self._reg_server_commands()

def _reg_server_commands(self):
# Register commands here
self._control_interface.add_command("getkey", self._handle_getkey)
self._completer_words["getkey"] = None
self._control_interface.set_completer_words(self._completer_words)
self._control_interface.flush_cli()
self._reload_completer()

def _handle_getkey(self, args: list):
def _handle_getkey(self, *_):
from connect_core.account.register_system import get_password

self._control_interface.info(
self._control_interface.tr("cli.starting.welcome_password", get_password())
)
Expand All @@ -57,4 +108,23 @@ class ClientCommand(Command):
def __init__(self, control_interface: "CoreControlInterface"):
super().__init__(control_interface)

self._reg_commands()
self._reg_client_commands()

def _reg_client_commands(self):
self._control_interface.add_command("info", self._handle_info)
self._completer_words["info"] = None
self._reload_completer()

def _handle_info(self, *_):
"""
显示主服务器信息。
"""
self._control_interface.info("==info==")
server_id = self._control_interface.get_server_id()
if server_id:
self._control_interface.info(
f"Main Server Connected! Server ID: {server_id}"
)
else:
self._control_interface.info("Main Server Disconnected!")
24 changes: 16 additions & 8 deletions connect_core/interface/control_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@ def __init__(self):
if self.__mcdr_server:
self.config_path = "./config/connect_core/config.json"
self._is_server = self.get_config().get("is_server", False)
self.command_core = None
else:
from connect_core.cli.cli_entry import get_is_server

self._is_server = get_is_server()
self.config_path = "./config.json"
self.language = self.get_config().get("language", "en_us")
self.command_core = CommandLineInterface(self)
self.command_core.start()

self.log_system = LogSystem(self.sid, self.get_config().get("debug", False))

# =============
Expand Down Expand Up @@ -168,7 +166,9 @@ def add_command(self, command: str, func: callable):
command (str): 命令名称。
func (callable): 命令对应的函数。
"""
self.command_core.add_command(self.sid, command, func)
from connect_core.cli.cli_core import command_core

command_core.add_command(self.sid, command, func)

def remove_command(self, command: str):
"""
Expand All @@ -177,7 +177,9 @@ def remove_command(self, command: str):
Args:
command (str): 命令名称。
"""
self.command_core.remove_command(self.sid, command)
from connect_core.cli.cli_core import command_core

command_core.remove_command(self.sid, command)

def set_prompt(self, prompt: str):
"""
Expand All @@ -186,7 +188,9 @@ def set_prompt(self, prompt: str):
Args:
prompt (str): 命令行提示符内容。
"""
self.command_core.set_prompt(prompt)
from connect_core.cli.cli_core import command_core

command_core.set_prompt(prompt)

def set_completer_words(self, words: dict):
"""
Expand All @@ -195,13 +199,17 @@ def set_completer_words(self, words: dict):
Args:
words (dict): 命令行补全词典内容。
"""
self.command_core.set_completer_words(self.sid, words)
from connect_core.cli.cli_core import command_core

command_core.set_completer_words(self.sid, words)

def flush_cli(self):
"""
清空命令行界面。
"""
self.command_core.flush_cli()
from connect_core.cli.cli_core import command_core

command_core.flush_cli()

# =========
# Tools
Expand Down
5 changes: 2 additions & 3 deletions connect_core/plugin/init_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,9 @@ def unload(self, plugin_id: str):

def reload(self, plugin_id: str):
"""重载插件,先卸载再加载"""
if plugin_id in self.plugins:
self.unload(plugin_id)
if "path" in self.plugins[plugin_id].keys():
if plugin_id in self.plugins and "path" in self.plugins[plugin_id].keys():
plugin_file = self.plugins[plugin_id]["path"].split("/")[-1]
self.unload(plugin_id)
self.load_plugin(plugin_file)
else:
from connect_core.mcdr.mcdr_entry import get_mcdr
Expand Down

0 comments on commit dc1aa3e

Please sign in to comment.