148 lines
5.4 KiB
Python
148 lines
5.4 KiB
Python
|
|
from yuxi.channel.protocols import SetupWizardStep
|
|||
|
|
|
|||
|
|
|
|||
|
|
class MinecraftSetupWizard:
|
|||
|
|
steps = [
|
|||
|
|
SetupWizardStep(
|
|||
|
|
key="host",
|
|||
|
|
label="服务器地址",
|
|||
|
|
description="Minecraft 服务器 IP 或域名(如 localhost 或 mc.example.com)",
|
|||
|
|
input_type="text",
|
|||
|
|
required=True,
|
|||
|
|
default="localhost",
|
|||
|
|
),
|
|||
|
|
SetupWizardStep(
|
|||
|
|
key="port",
|
|||
|
|
label="服务器端口",
|
|||
|
|
description="Minecraft 服务器端口(默认 25565)",
|
|||
|
|
input_type="text",
|
|||
|
|
required=True,
|
|||
|
|
default="25565",
|
|||
|
|
),
|
|||
|
|
SetupWizardStep(
|
|||
|
|
key="username",
|
|||
|
|
label="Bot 用户名",
|
|||
|
|
description="Bot 在游戏中显示的用户名",
|
|||
|
|
input_type="text",
|
|||
|
|
required=True,
|
|||
|
|
default="ForcePilotBot",
|
|||
|
|
),
|
|||
|
|
SetupWizardStep(
|
|||
|
|
key="auth_mode",
|
|||
|
|
label="认证模式",
|
|||
|
|
description="选择认证方式:offline(离线模式)或 microsoft(正版验证)",
|
|||
|
|
input_type="select",
|
|||
|
|
required=True,
|
|||
|
|
default="offline",
|
|||
|
|
options=[
|
|||
|
|
{"label": "离线模式(offline)", "value": "offline"},
|
|||
|
|
{"label": "正版验证(microsoft)", "value": "microsoft"},
|
|||
|
|
],
|
|||
|
|
),
|
|||
|
|
SetupWizardStep(
|
|||
|
|
key="version",
|
|||
|
|
label="游戏版本",
|
|||
|
|
description="选择 Minecraft 版本,auto 表示自动探测",
|
|||
|
|
input_type="select",
|
|||
|
|
required=True,
|
|||
|
|
default="auto",
|
|||
|
|
options=[
|
|||
|
|
{"label": "自动探测(auto)", "value": "auto"},
|
|||
|
|
{"label": "1.20.4", "value": "1.20.4"},
|
|||
|
|
{"label": "1.21-1.21.1", "value": "1.21"},
|
|||
|
|
{"label": "1.21.2-1.21.3", "value": "1.21.2"},
|
|||
|
|
{"label": "1.21.4", "value": "1.21.4"},
|
|||
|
|
{"label": "1.21.5", "value": "1.21.5"},
|
|||
|
|
],
|
|||
|
|
),
|
|||
|
|
SetupWizardStep(
|
|||
|
|
key="rcon_port",
|
|||
|
|
label="RCON 端口",
|
|||
|
|
description="RCON 远程管理端口(默认 25575,不需要可留空)",
|
|||
|
|
input_type="text",
|
|||
|
|
required=False,
|
|||
|
|
default="25575",
|
|||
|
|
),
|
|||
|
|
SetupWizardStep(
|
|||
|
|
key="rcon_password",
|
|||
|
|
label="RCON 密码",
|
|||
|
|
description="RCON 认证密码(不需要远程管理可留空)",
|
|||
|
|
input_type="password",
|
|||
|
|
required=False,
|
|||
|
|
),
|
|||
|
|
]
|
|||
|
|
|
|||
|
|
def setup_wizard_steps(self) -> list[SetupWizardStep]:
|
|||
|
|
return self.steps
|
|||
|
|
|
|||
|
|
def validate_wizard_input(self, step_key: str, value: str) -> str | None:
|
|||
|
|
if step_key == "host":
|
|||
|
|
if not value or not value.strip():
|
|||
|
|
return "服务器地址不能为空"
|
|||
|
|
stripped = value.strip()
|
|||
|
|
if len(stripped) > 253:
|
|||
|
|
return "服务器地址过长(最大 253 字符)"
|
|||
|
|
|
|||
|
|
elif step_key == "port":
|
|||
|
|
try:
|
|||
|
|
port = int(value)
|
|||
|
|
if not (1 <= port <= 65535):
|
|||
|
|
return "端口必须在 1-65535 之间"
|
|||
|
|
except ValueError:
|
|||
|
|
return "端口必须是有效的整数"
|
|||
|
|
|
|||
|
|
elif step_key == "username":
|
|||
|
|
if not value or not value.strip():
|
|||
|
|
return "用户名不能为空"
|
|||
|
|
stripped = value.strip()
|
|||
|
|
if len(stripped) > 16:
|
|||
|
|
return "Minecraft 用户名不能超过 16 个字符"
|
|||
|
|
if not stripped.replace("_", "").isalnum():
|
|||
|
|
return "用户名只能包含字母、数字和下划线"
|
|||
|
|
|
|||
|
|
elif step_key == "auth_mode":
|
|||
|
|
if value not in ("offline", "microsoft"):
|
|||
|
|
return "认证模式必须是 offline 或 microsoft"
|
|||
|
|
|
|||
|
|
elif step_key == "version":
|
|||
|
|
valid_versions = ("auto", "1.20.4", "1.21", "1.21.2", "1.21.4", "1.21.5")
|
|||
|
|
if value not in valid_versions:
|
|||
|
|
return f"版本必须是以下之一: {', '.join(valid_versions)}"
|
|||
|
|
|
|||
|
|
elif step_key == "rcon_port":
|
|||
|
|
if value:
|
|||
|
|
try:
|
|||
|
|
port = int(value)
|
|||
|
|
if not (1 <= port <= 65535):
|
|||
|
|
return "RCON 端口必须在 1-65535 之间"
|
|||
|
|
except ValueError:
|
|||
|
|
return "RCON 端口必须是有效的整数"
|
|||
|
|
|
|||
|
|
return None
|
|||
|
|
|
|||
|
|
async def finalize(self, config: dict) -> dict:
|
|||
|
|
result = dict(config)
|
|||
|
|
|
|||
|
|
result.setdefault("host", "localhost")
|
|||
|
|
result.setdefault("port", 25565)
|
|||
|
|
result.setdefault("username", "ForcePilotBot")
|
|||
|
|
result.setdefault("auth_mode", "offline")
|
|||
|
|
result.setdefault("version", "auto")
|
|||
|
|
result.setdefault("rcon_port", 25575)
|
|||
|
|
|
|||
|
|
if "port" in result and isinstance(result["port"], str):
|
|||
|
|
result["port"] = int(result["port"])
|
|||
|
|
if "rcon_port" in result and isinstance(result["rcon_port"], str):
|
|||
|
|
result["rcon_port"] = int(result["rcon_port"])
|
|||
|
|
|
|||
|
|
result.setdefault("group_policy", "mention")
|
|||
|
|
result.setdefault("require_mention", True)
|
|||
|
|
result.setdefault("dm_policy", "pairing")
|
|||
|
|
result.setdefault("allow_from", [])
|
|||
|
|
result.setdefault("text_chunk_limit", 256)
|
|||
|
|
result.setdefault("rate_limit_window", 5.0)
|
|||
|
|
result.setdefault("rate_limit_max", 10)
|
|||
|
|
result.setdefault("reconnect_max_retries", 10)
|
|||
|
|
|
|||
|
|
return result
|