在引入 uv 依赖管理、ruff 静态检查与格式化、pyright 类型检查之前, 先把当前可正常运行的状态固定下来,作为后续大规模自动改动的回滚点。 此时状态:97 项测试全绿,HTTP + WebSocket 多牧场服务器可用。
61 lines
2.4 KiB
Python
61 lines
2.4 KiB
Python
"""SimpleFarm 服务器包。
|
||
|
||
把原本"一个进程一局游戏"的单机引擎,改造成一个可以多人同时在线、
|
||
可以后台常驻、既能被人玩也能被 AI 调用的小型游戏服务器。
|
||
|
||
模块划分
|
||
--------
|
||
* :mod:`farm.server.app` —— FastAPI 应用(REST + WebSocket)
|
||
* :mod:`farm.server.actions` —— 动作表:所有入口共用的唯一执行通道
|
||
* :mod:`farm.server.session` —— 多牧场会话与统一时钟
|
||
* :mod:`farm.server.hub` —— WebSocket 连接池与状态推送
|
||
* :mod:`farm.server.daemon` —— 守护进程(start/stop/status)
|
||
* :mod:`farm.server.webui` —— 内嵌网页客户端
|
||
|
||
``app`` 依赖 FastAPI,而 ``daemon`` 只依赖标准库。为了让
|
||
``python main.py stop`` 在没有装 FastAPI 的机器上也能用,这里采用**惰性导出**:
|
||
真正 import 到用例时才加载对应子模块。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
from typing import Any
|
||
|
||
_LAZY = {
|
||
"API_VERSION", "SERVER_NAME", "ServerConfig", "ServerHandle",
|
||
"build_app", "create_app", "rules_text", "brief",
|
||
"Action", "Param", "ACTIONS", "run_action", "describe_actions", "action_names",
|
||
"FarmSession", "SessionManager", "FarmClock", "validate_farm_id", "DEFAULT_FARM",
|
||
"Client", "ConnectionHub", "Publisher",
|
||
"DaemonManager", "pid_alive",
|
||
"DASHBOARD_HTML", "dashboard_text",
|
||
}
|
||
|
||
__all__ = sorted(_LAZY)
|
||
|
||
|
||
def __getattr__(name: str) -> Any: # PEP 562:模块级惰性属性
|
||
if name not in _LAZY:
|
||
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
||
from importlib import import_module
|
||
|
||
if name in ("DaemonManager", "pid_alive"):
|
||
module = import_module("farm.server.daemon")
|
||
elif name in ("DASHBOARD_HTML", "dashboard_text"):
|
||
module = import_module("farm.server.webui")
|
||
elif name in ("Action", "Param", "ACTIONS", "run_action", "describe_actions",
|
||
"action_names"):
|
||
module = import_module("farm.server.actions")
|
||
elif name in ("FarmSession", "SessionManager", "FarmClock", "validate_farm_id",
|
||
"DEFAULT_FARM"):
|
||
module = import_module("farm.server.session")
|
||
elif name in ("Client", "ConnectionHub", "Publisher"):
|
||
module = import_module("farm.server.hub")
|
||
else:
|
||
module = import_module("farm.server.app")
|
||
return getattr(module, name)
|
||
|
||
|
||
def __dir__() -> list:
|
||
return sorted(set(list(globals()) + __all__))
|