启动器:移除服务端工具/支援兵/插件页面,支援兵模板独立保存
- 删除服务端工具、支援兵、插件三个页面(侧边栏入口 + HTML section) - server.py: 删除 servertool(9个)、companion/basic-attack 相关接口及常量 - native.py: 删除无人引用的 get_server_features/save_server_features/ companion_state/companion_save(保留 GM 工具依赖的 gameplay 方法) - shell.js: 删除 loadServerTool/loadCompanion 全部逻辑及状态变量 - shell.css: 清理 st-/cp- 相关样式 - templates/支援兵页面模板.md: 支援兵页面完整导出为独立模板 - 侧边栏「更新日志」更名为「游戏更新」
This commit is contained in:
1 parent
56236496a0
commit
977a4a1196
6 files changed
+410
-869
No files matched your search
+1
-203
@@ -111,12 +111,8 @@ LOADOUT_EXE = os.path.join(LOADOUT_DIR, "换装工具.exe")
|
||||
if not os.path.exists(LOADOUT_EXE):
|
||||
LOADOUT_EXE = os.path.join(LOADOUT_DIR, "DNFLoadout.exe")
|
||||
|
||||
# 一键换装 / 服务端工具的持久化配置路径
|
||||
# 一键换装的持久化配置路径
|
||||
LOADOUT_CONFIG = os.path.join(LOADOUT_DIR, "config.json")
|
||||
SERVER_CONFIG_DIR = os.path.join(SERVER_ROOT, "Server", "runtime", "config")
|
||||
SERVER_FEATURES_PATH = os.path.join(SERVER_CONFIG_DIR, "server-features.json")
|
||||
ACTIVITY_CONFIG_PATH = os.path.join(SERVER_CONFIG_DIR, "activity.json")
|
||||
RAW_CONFIG_NAMES = ("instance.json", "dnfbridge.toml", "logic.toml", "plan.json")
|
||||
|
||||
# 赞助二维码图片路径(放启动器目录下 sponsor.png)
|
||||
SPONSOR_IMG = os.path.join(BASE_DIR, "sponsor.png")
|
||||
@@ -547,23 +543,6 @@ class Handler(BaseHTTPRequestHandler):
|
||||
self._api_loadout_characters()
|
||||
elif path == "/api/loadout/equipment":
|
||||
self._api_loadout_equipment(qs)
|
||||
elif path == "/api/servertool/features":
|
||||
self._api_servertool_features()
|
||||
elif path == "/api/servertool/activity":
|
||||
self._api_servertool_activity()
|
||||
elif path == "/api/servertool/info":
|
||||
self._api_servertool_info()
|
||||
elif path == "/api/servertool/raw":
|
||||
self._api_servertool_raw(qs)
|
||||
elif path == "/api/servertool/gameplay":
|
||||
self._api_servertool_gameplay()
|
||||
elif path == "/api/servertool/batch-pickup":
|
||||
self._api_servertool_batch_pickup()
|
||||
elif path == "/api/companion":
|
||||
self._api_companion(qs)
|
||||
elif path == "/api/basic-attack":
|
||||
self._json({"ok": True, "enabled": not os.path.exists(
|
||||
os.path.join(CLIENT_DIR, "90CN_basic_attack.disabled"))})
|
||||
elif path == "/api/logs":
|
||||
self._api_logs()
|
||||
elif path == "/api/gm/health":
|
||||
@@ -629,32 +608,6 @@ class Handler(BaseHTTPRequestHandler):
|
||||
self._api_save_loadout_config(data)
|
||||
elif path == "/api/loadout/apply":
|
||||
self._api_loadout_apply(data)
|
||||
elif path == "/api/servertool/features":
|
||||
self._api_save_servertool_features(data)
|
||||
elif path == "/api/servertool/activity":
|
||||
self._api_save_servertool_activity(data)
|
||||
elif path == "/api/servertool/raw":
|
||||
self._api_save_servertool_raw(data)
|
||||
elif path == "/api/servertool/gameplay":
|
||||
self._api_save_servertool_gameplay(data)
|
||||
elif path == "/api/servertool/batch-pickup":
|
||||
self._api_save_servertool_batch_pickup(data)
|
||||
elif path == "/api/companion":
|
||||
self._api_save_companion(data)
|
||||
elif path == "/api/basic-attack":
|
||||
enabled = bool(data.get("enabled", True))
|
||||
flag = os.path.join(CLIENT_DIR, "90CN_basic_attack.disabled")
|
||||
try:
|
||||
if enabled:
|
||||
if os.path.exists(flag):
|
||||
os.remove(flag)
|
||||
else:
|
||||
os.makedirs(CLIENT_DIR, exist_ok=True)
|
||||
with open(flag, "w", encoding="utf-8") as f:
|
||||
f.write("disabled\n")
|
||||
self._json({"ok": True, "enabled": enabled})
|
||||
except Exception as e:
|
||||
self._json({"ok": False, "error": str(e)}, 500)
|
||||
elif path == "/api/accounts-config":
|
||||
self._api_accounts_config_post(data)
|
||||
elif path == "/api/source":
|
||||
@@ -868,161 +821,6 @@ class Handler(BaseHTTPRequestHandler):
|
||||
except Exception as e:
|
||||
self._json({"ok": False, "error": str(e)}, 502)
|
||||
|
||||
# ==================== 服务端工具 ====================
|
||||
def _api_servertool_features(self):
|
||||
if NATIVE is not None and server_running():
|
||||
try:
|
||||
self._json({"ok": True, "source": "native",
|
||||
"data": NATIVE.get_server_features()})
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
cfg = _read_json_file(SERVER_FEATURES_PATH, {})
|
||||
self._json({"ok": True, "source": "file", "data": cfg})
|
||||
|
||||
def _api_save_servertool_features(self, data):
|
||||
if NATIVE is not None and server_running():
|
||||
try:
|
||||
self._json({"ok": True, "source": "native",
|
||||
"data": NATIVE.save_server_features(data)})
|
||||
return
|
||||
except Exception as e:
|
||||
fallback_error = str(e)
|
||||
else:
|
||||
fallback_error = "Native API 不可用"
|
||||
_write_json_file(SERVER_FEATURES_PATH, data)
|
||||
self._json({"ok": True, "source": "file",
|
||||
"warning": fallback_error, "data": data})
|
||||
|
||||
def _api_servertool_activity(self):
|
||||
self._json({"ok": True,
|
||||
"data": _read_json_file(ACTIVITY_CONFIG_PATH, {})})
|
||||
|
||||
def _api_save_servertool_activity(self, data):
|
||||
_write_json_file(ACTIVITY_CONFIG_PATH, data)
|
||||
self._json({"ok": True, "data": data})
|
||||
|
||||
def _api_servertool_info(self):
|
||||
self._json({
|
||||
"ok": True,
|
||||
"features_path": SERVER_FEATURES_PATH,
|
||||
"activity_path": ACTIVITY_CONFIG_PATH,
|
||||
"config_dir": SERVER_CONFIG_DIR,
|
||||
"raw_names": list(RAW_CONFIG_NAMES),
|
||||
"server_running": server_running(),
|
||||
})
|
||||
|
||||
def _api_servertool_raw(self, qs):
|
||||
name = (qs.get("name") or [""])[0]
|
||||
if name not in RAW_CONFIG_NAMES:
|
||||
self._json({"error": "invalid config name"}, 400)
|
||||
return
|
||||
path = os.path.join(SERVER_CONFIG_DIR, name)
|
||||
try:
|
||||
text = ""
|
||||
if os.path.exists(path):
|
||||
with open(path, "r", encoding="utf-8-sig") as f:
|
||||
text = f.read()
|
||||
self._json({"ok": True, "name": name, "path": path, "text": text})
|
||||
except Exception as e:
|
||||
self._json({"error": str(e)}, 500)
|
||||
|
||||
def _api_save_servertool_raw(self, data):
|
||||
name = str(data.get("name", ""))
|
||||
text = str(data.get("text", ""))
|
||||
if name not in RAW_CONFIG_NAMES:
|
||||
self._json({"error": "invalid config name"}, 400)
|
||||
return
|
||||
path = os.path.join(SERVER_CONFIG_DIR, name)
|
||||
try:
|
||||
os.makedirs(SERVER_CONFIG_DIR, exist_ok=True)
|
||||
if os.path.exists(path):
|
||||
shutil.copy2(path, path + ".bak_tool")
|
||||
with open(path, "w", encoding="utf-8", newline="\n") as f:
|
||||
f.write(text)
|
||||
self._json({"ok": True, "name": name, "path": path})
|
||||
except Exception as e:
|
||||
self._json({"error": str(e)}, 500)
|
||||
|
||||
def _api_servertool_gameplay(self):
|
||||
if NATIVE is not None and server_running():
|
||||
try:
|
||||
self._json({"ok": True, "source": "native",
|
||||
"data": NATIVE.get_gameplay_settings()})
|
||||
return
|
||||
except Exception:
|
||||
pass
|
||||
self._json({"ok": True, "source": "file", "data": {}})
|
||||
|
||||
def _api_save_servertool_gameplay(self, data):
|
||||
if NATIVE is None or not server_running():
|
||||
self._json({"error": "服务端未运行,无法写入玩法参数"}, 400)
|
||||
return
|
||||
try:
|
||||
if data.get("hellEpicDropRatePercent") is not None:
|
||||
NATIVE.set_hell_drop_rate(int(data["hellEpicDropRatePercent"]))
|
||||
if data.get("epicPotionMultiplierPercent") is not None:
|
||||
NATIVE.set_epic_potion_multiplier(int(data["epicPotionMultiplierPercent"]))
|
||||
self._json({"ok": True, "data": data})
|
||||
except Exception as e:
|
||||
self._json({"error": str(e)}, 502)
|
||||
|
||||
def _batch_pickup_path(self):
|
||||
return INSTANCE_PATH if INSTANCE_PATH else os.path.join(
|
||||
SERVER_CONFIG_DIR, "instance.json")
|
||||
|
||||
def _api_servertool_batch_pickup(self):
|
||||
path = self._batch_pickup_path()
|
||||
cfg = _read_json_file(path, {})
|
||||
value = True
|
||||
try:
|
||||
value = bool(cfg.get("game", {}).get("dungeonBatchPickupEnabled", True))
|
||||
except Exception:
|
||||
value = True
|
||||
self._json({"ok": True, "data": {"enabled": value}, "path": path})
|
||||
|
||||
def _api_save_servertool_batch_pickup(self, data):
|
||||
path = self._batch_pickup_path()
|
||||
cfg = _read_json_file(path, None)
|
||||
if not isinstance(cfg, dict):
|
||||
self._json({"error": "instance.json 不存在或格式错误"}, 400)
|
||||
return
|
||||
game = cfg.get("game")
|
||||
if not isinstance(game, dict):
|
||||
game = {}
|
||||
cfg["game"] = game
|
||||
game["dungeonBatchPickupEnabled"] = bool(data.get("enabled", True))
|
||||
try:
|
||||
if os.path.exists(path):
|
||||
shutil.copy2(path, path + ".bak_tool")
|
||||
_write_json_file(path, cfg)
|
||||
self._json({"ok": True, "data": {"enabled": game["dungeonBatchPickupEnabled"]}})
|
||||
except Exception as e:
|
||||
self._json({"error": str(e)}, 500)
|
||||
|
||||
# ==================== 支援兵 ====================
|
||||
def _api_companion(self, qs):
|
||||
if NATIVE is None or not server_running():
|
||||
self._json({"ok": False, "error": "服务端未运行,支援兵配置不可用"}, 400)
|
||||
return
|
||||
character = (qs.get("character") or qs.get("id") or [""])[0].strip()
|
||||
if not character:
|
||||
self._json({"ok": False, "error": "缺少角色 ID"}, 400)
|
||||
return
|
||||
try:
|
||||
self._json({"ok": True, "data": NATIVE.companion_state(character)})
|
||||
except Exception as e:
|
||||
self._json({"ok": False, "error": str(e)}, 502)
|
||||
|
||||
def _api_save_companion(self, data):
|
||||
if NATIVE is None or not server_running():
|
||||
self._json({"ok": False, "error": "服务端未运行,无法保存支援兵配置"}, 400)
|
||||
return
|
||||
try:
|
||||
self._json({"ok": True, "data": NATIVE.companion_save(data)})
|
||||
except Exception as e:
|
||||
self._json({"ok": False, "error": str(e)}, 502)
|
||||
|
||||
# ==================== 自定义账号配置 ====================
|
||||
def _api_accounts_config(self):
|
||||
"""返回账号列表(含默认标记)。"""
|
||||
|
||||
Reference in new issue
Block a user