638 lines
22 KiB
Python
638 lines
22 KiB
Python
"""
|
||
编辑器接口模块
|
||
提供可视化配置和监控界面
|
||
"""
|
||
|
||
import time
|
||
import threading
|
||
import json
|
||
from typing import Dict, Any, List, Optional
|
||
|
||
class EditorInterface:
|
||
"""
|
||
编辑器接口
|
||
提供可视化配置和监控界面
|
||
"""
|
||
|
||
def __init__(self, plugin):
|
||
"""
|
||
初始化编辑器接口
|
||
|
||
Args:
|
||
plugin: 服务器架构插件实例
|
||
"""
|
||
self.plugin = plugin
|
||
self.enabled = False
|
||
self.initialized = False
|
||
|
||
# 编辑器配置
|
||
self.editor_config = {
|
||
"enable_editor": True,
|
||
"editor_port": 8082,
|
||
"enable_realtime_updates": True,
|
||
"update_interval": 1.0,
|
||
"enable_data_export": True,
|
||
"enable_data_import": True,
|
||
"max_history_points": 1000,
|
||
"enable_theme_customization": True,
|
||
"default_theme": "dark"
|
||
}
|
||
|
||
# 编辑器状态
|
||
self.editor_state = {
|
||
"is_running": False,
|
||
"last_update": 0.0,
|
||
"connected_clients": 0,
|
||
"total_updates": 0,
|
||
"ui_elements": {},
|
||
"selected_tab": "overview"
|
||
}
|
||
|
||
# 编辑器数据
|
||
self.editor_data = {
|
||
"system_stats": {},
|
||
"performance_metrics": {},
|
||
"active_alerts": [],
|
||
"client_list": [],
|
||
"room_list": [],
|
||
"server_config": {}
|
||
}
|
||
|
||
# 编辑器统计
|
||
self.editor_stats = {
|
||
"updates_sent": 0,
|
||
"data_points_collected": 0,
|
||
"ui_interactions": 0,
|
||
"export_operations": 0,
|
||
"import_operations": 0,
|
||
"errors": 0
|
||
}
|
||
|
||
# 实时更新线程
|
||
self.update_thread = None
|
||
self.update_thread_running = False
|
||
|
||
# 回调函数
|
||
self.editor_callbacks = {
|
||
"editor_started": [],
|
||
"editor_stopped": [],
|
||
"data_updated": [],
|
||
"ui_interaction": [],
|
||
"editor_error": []
|
||
}
|
||
|
||
# 时间戳记录
|
||
self.last_data_update = 0.0
|
||
self.last_ui_interaction = 0.0
|
||
|
||
print("✓ 编辑器接口已创建")
|
||
|
||
def initialize(self) -> bool:
|
||
"""
|
||
初始化编辑器接口
|
||
|
||
Returns:
|
||
是否初始化成功
|
||
"""
|
||
try:
|
||
print("正在初始化编辑器接口...")
|
||
|
||
# 初始化UI元素
|
||
self._initialize_ui_elements()
|
||
|
||
self.initialized = True
|
||
print("✓ 编辑器接口初始化完成")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 编辑器接口初始化失败: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def _initialize_ui_elements(self):
|
||
"""初始化UI元素"""
|
||
try:
|
||
self.editor_state["ui_elements"] = {
|
||
"overview_tab": {
|
||
"name": "系统概览",
|
||
"icon": "dashboard",
|
||
"visible": True
|
||
},
|
||
"clients_tab": {
|
||
"name": "客户端管理",
|
||
"icon": "people",
|
||
"visible": True
|
||
},
|
||
"rooms_tab": {
|
||
"name": "房间管理",
|
||
"icon": "meeting_room",
|
||
"visible": True
|
||
},
|
||
"monitoring_tab": {
|
||
"name": "监控面板",
|
||
"icon": "monitor",
|
||
"visible": True
|
||
},
|
||
"config_tab": {
|
||
"name": "配置管理",
|
||
"icon": "settings",
|
||
"visible": True
|
||
},
|
||
"logs_tab": {
|
||
"name": "日志查看",
|
||
"icon": "description",
|
||
"visible": True
|
||
},
|
||
"alerts_tab": {
|
||
"name": "警报管理",
|
||
"icon": "warning",
|
||
"visible": True
|
||
}
|
||
}
|
||
|
||
print("✓ UI元素已初始化")
|
||
|
||
except Exception as e:
|
||
print(f"✗ UI元素初始化失败: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
|
||
def enable(self) -> bool:
|
||
"""
|
||
启用编辑器接口
|
||
|
||
Returns:
|
||
是否启用成功
|
||
"""
|
||
try:
|
||
if not self.initialized:
|
||
print("✗ 编辑器接口未初始化")
|
||
return False
|
||
|
||
# 启动实时更新线程
|
||
self._start_update_thread()
|
||
|
||
self.enabled = True
|
||
print("✓ 编辑器接口已启用")
|
||
return True
|
||
|
||
except Exception as e:
|
||
print(f"✗ 编辑器接口启用失败: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
import traceback
|
||
traceback.print_exc()
|
||
return False
|
||
|
||
def disable(self):
|
||
"""禁用编辑器接口"""
|
||
try:
|
||
self.enabled = False
|
||
|
||
# 停止实时更新线程
|
||
self._stop_update_thread()
|
||
|
||
print("✓ 编辑器接口已禁用")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 编辑器接口禁用失败: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def finalize(self):
|
||
"""清理编辑器接口资源"""
|
||
try:
|
||
# 禁用编辑器接口
|
||
if self.enabled:
|
||
self.disable()
|
||
|
||
# 清理回调
|
||
self.editor_callbacks.clear()
|
||
|
||
self.initialized = False
|
||
print("✓ 编辑器接口资源已清理")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 编辑器接口资源清理失败: {e}")
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def update(self, dt: float):
|
||
"""
|
||
更新编辑器接口状态
|
||
|
||
Args:
|
||
dt: 时间增量(秒)
|
||
"""
|
||
try:
|
||
if not self.enabled:
|
||
return
|
||
|
||
current_time = time.time()
|
||
self.editor_state["last_update"] = current_time
|
||
|
||
except Exception as e:
|
||
print(f"✗ 编辑器接口更新失败: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
import traceback
|
||
traceback.print_exc()
|
||
|
||
def _start_update_thread(self):
|
||
"""启动实时更新线程"""
|
||
try:
|
||
self.update_thread_running = True
|
||
self.update_thread = threading.Thread(target=self._update_loop, daemon=True)
|
||
self.update_thread.start()
|
||
print("✓ 实时更新线程已启动")
|
||
except Exception as e:
|
||
print(f"✗ 实时更新线程启动失败: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
|
||
def _stop_update_thread(self):
|
||
"""停止实时更新线程"""
|
||
try:
|
||
self.update_thread_running = False
|
||
if self.update_thread and self.update_thread.is_alive():
|
||
self.update_thread.join(timeout=5.0)
|
||
self.update_thread = None
|
||
print("✓ 实时更新线程已停止")
|
||
except Exception as e:
|
||
print(f"✗ 实时更新线程停止失败: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
|
||
def _update_loop(self):
|
||
"""实时更新循环"""
|
||
try:
|
||
while self.update_thread_running:
|
||
try:
|
||
if self.enabled and self.editor_config["enable_realtime_updates"]:
|
||
# 收集数据
|
||
self._collect_editor_data()
|
||
|
||
# 发送更新
|
||
self._send_editor_updates()
|
||
|
||
self.editor_state["total_updates"] += 1
|
||
|
||
# 等待下一个更新间隔
|
||
time.sleep(self.editor_config["update_interval"])
|
||
|
||
except Exception as e:
|
||
print(f"✗ 实时更新循环错误: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
time.sleep(1.0) # 出错时短暂休眠
|
||
|
||
except Exception as e:
|
||
print(f"✗ 实时更新线程失败: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
|
||
def _collect_editor_data(self):
|
||
"""收集编辑器数据"""
|
||
try:
|
||
current_time = time.time()
|
||
|
||
# 收集系统统计数据
|
||
self.editor_data["system_stats"] = {
|
||
"server": self.plugin.server_manager.get_server_stats() if self.plugin.server_manager else {},
|
||
"clients": self.plugin.client_manager.get_client_stats() if self.plugin.client_manager else {},
|
||
"rooms": self.plugin.room_manager.get_room_stats() if self.plugin.room_manager else {},
|
||
"messages": self.plugin.message_router.get_message_stats() if self.plugin.message_router else {},
|
||
"storage": self.plugin.storage_manager.get_storage_stats() if self.plugin.storage_manager else {},
|
||
"loadbalancer": self.plugin.load_balancer.get_loadbalancer_stats() if self.plugin.load_balancer else {},
|
||
"monitoring": self.plugin.monitoring_system.get_monitoring_stats() if self.plugin.monitoring_system else {},
|
||
"security": self.plugin.security_manager.get_security_stats() if self.plugin.security_manager else {},
|
||
"api": self.plugin.api_interface.get_api_stats() if self.plugin.api_interface else {}
|
||
}
|
||
|
||
# 收集性能指标
|
||
if self.plugin.monitoring_system:
|
||
self.editor_data["performance_metrics"] = self.plugin.monitoring_system.get_performance_metrics()
|
||
|
||
# 收集活动警报
|
||
if self.plugin.monitoring_system:
|
||
self.editor_data["active_alerts"] = list(self.plugin.monitoring_system.get_active_alerts().values())
|
||
|
||
# 收集客户端列表
|
||
if self.plugin.client_manager:
|
||
self.editor_data["client_list"] = list(self.plugin.client_manager.get_all_clients().values())
|
||
|
||
# 收集房间列表
|
||
if self.plugin.room_manager:
|
||
self.editor_data["room_list"] = self.plugin.room_manager.get_all_rooms()
|
||
|
||
# 收集服务器配置
|
||
if self.plugin.config_manager:
|
||
self.editor_data["server_config"] = self.plugin.config_manager.get_config()
|
||
|
||
self.editor_stats["data_points_collected"] += 1
|
||
self.last_data_update = current_time
|
||
|
||
except Exception as e:
|
||
print(f"✗ 编辑器数据收集失败: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
|
||
def _send_editor_updates(self):
|
||
"""发送编辑器更新"""
|
||
try:
|
||
# 在实际实现中,这里会通过WebSocket或其他方式发送数据到编辑器前端
|
||
# 此处简化处理,仅触发回调
|
||
|
||
self._trigger_editor_callback("data_updated", {
|
||
"data": self.editor_data,
|
||
"timestamp": time.time()
|
||
})
|
||
|
||
self.editor_stats["updates_sent"] += 1
|
||
|
||
except Exception as e:
|
||
print(f"✗ 编辑器更新发送失败: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
|
||
def handle_ui_interaction(self, interaction_data: Dict[str, Any]):
|
||
"""
|
||
处理UI交互
|
||
|
||
Args:
|
||
interaction_data: 交互数据
|
||
"""
|
||
try:
|
||
self.editor_stats["ui_interactions"] += 1
|
||
self.last_ui_interaction = time.time()
|
||
|
||
# 触发UI交互回调
|
||
self._trigger_editor_callback("ui_interaction", {
|
||
"interaction": interaction_data,
|
||
"timestamp": self.last_ui_interaction
|
||
})
|
||
|
||
# 处理特定交互类型
|
||
interaction_type = interaction_data.get("type")
|
||
if interaction_type == "tab_change":
|
||
self.editor_state["selected_tab"] = interaction_data.get("tab_name", "overview")
|
||
elif interaction_type == "config_update":
|
||
self._handle_config_update(interaction_data.get("config_data", {}))
|
||
elif interaction_type == "client_action":
|
||
self._handle_client_action(interaction_data.get("action_data", {}))
|
||
elif interaction_type == "room_action":
|
||
self._handle_room_action(interaction_data.get("action_data", {}))
|
||
|
||
except Exception as e:
|
||
print(f"✗ UI交互处理失败: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
|
||
def _handle_config_update(self, config_data: Dict[str, Any]):
|
||
"""
|
||
处理配置更新
|
||
|
||
Args:
|
||
config_data: 配置数据
|
||
"""
|
||
try:
|
||
if not self.plugin.config_manager:
|
||
return
|
||
|
||
# 应用配置更新
|
||
for section, section_data in config_data.items():
|
||
if isinstance(section_data, dict):
|
||
self.plugin.config_manager.update_config_section(section, section_data)
|
||
|
||
print("✓ 配置已更新")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 配置更新处理失败: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
|
||
def _handle_client_action(self, action_data: Dict[str, Any]):
|
||
"""
|
||
处理客户端操作
|
||
|
||
Args:
|
||
action_data: 操作数据
|
||
"""
|
||
try:
|
||
if not self.plugin.client_manager:
|
||
return
|
||
|
||
action = action_data.get("action")
|
||
client_id = action_data.get("client_id")
|
||
|
||
if action == "kick":
|
||
self.plugin.client_manager.disconnect_client(client_id, "kicked_by_admin")
|
||
print(f"✓ 客户端已踢出: {client_id}")
|
||
elif action == "ban":
|
||
client_data = self.plugin.client_manager.get_client(client_id)
|
||
if client_data:
|
||
client_address = client_data.get("address")
|
||
if client_address:
|
||
self.plugin.security_manager._block_ip(client_address[0], 3600) # 阻止1小时
|
||
print(f"✓ 客户端IP已阻止: {client_address[0]}")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 客户端操作处理失败: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
|
||
def _handle_room_action(self, action_data: Dict[str, Any]):
|
||
"""
|
||
处理房间操作
|
||
|
||
Args:
|
||
action_data: 操作数据
|
||
"""
|
||
try:
|
||
if not self.plugin.room_manager:
|
||
return
|
||
|
||
action = action_data.get("action")
|
||
room_id = action_data.get("room_id")
|
||
|
||
if action == "destroy":
|
||
self.plugin.room_manager.destroy_room(room_id)
|
||
print(f"✓ 房间已销毁: {room_id}")
|
||
|
||
except Exception as e:
|
||
print(f"✗ 房间操作处理失败: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
|
||
def export_data(self, export_type: str = "json") -> Optional[str]:
|
||
"""
|
||
导出数据
|
||
|
||
Args:
|
||
export_type: 导出类型 (json, csv等)
|
||
|
||
Returns:
|
||
导出的数据字符串或None
|
||
"""
|
||
try:
|
||
self.editor_stats["export_operations"] += 1
|
||
|
||
if export_type == "json":
|
||
export_data = {
|
||
"export_time": time.time(),
|
||
"data": self.editor_data,
|
||
"stats": self.editor_stats
|
||
}
|
||
return json.dumps(export_data, ensure_ascii=False, indent=2)
|
||
else:
|
||
print(f"✗ 不支持的导出类型: {export_type}")
|
||
return None
|
||
|
||
except Exception as e:
|
||
print(f"✗ 数据导出失败: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
return None
|
||
|
||
def import_data(self, import_data: str, import_type: str = "json") -> bool:
|
||
"""
|
||
导入数据
|
||
|
||
Args:
|
||
import_data: 导入的数据
|
||
import_type: 导入类型 (json, csv等)
|
||
|
||
Returns:
|
||
是否导入成功
|
||
"""
|
||
try:
|
||
self.editor_stats["import_operations"] += 1
|
||
|
||
if import_type == "json":
|
||
data = json.loads(import_data)
|
||
# 在实际实现中,这里会处理导入的数据
|
||
print("✓ 数据导入完成")
|
||
return True
|
||
else:
|
||
print(f"✗ 不支持的导入类型: {import_type}")
|
||
return False
|
||
|
||
except Exception as e:
|
||
print(f"✗ 数据导入失败: {e}")
|
||
self.editor_stats["errors"] += 1
|
||
return False
|
||
|
||
def get_editor_state(self) -> Dict[str, Any]:
|
||
"""
|
||
获取编辑器状态
|
||
|
||
Returns:
|
||
编辑器状态字典
|
||
"""
|
||
return self.editor_state.copy()
|
||
|
||
def get_editor_data(self) -> Dict[str, Any]:
|
||
"""
|
||
获取编辑器数据
|
||
|
||
Returns:
|
||
编辑器数据字典
|
||
"""
|
||
return self.editor_data.copy()
|
||
|
||
def get_editor_stats(self) -> Dict[str, Any]:
|
||
"""
|
||
获取编辑器统计信息
|
||
|
||
Returns:
|
||
编辑器统计字典
|
||
"""
|
||
return {
|
||
"state": self.editor_state.copy(),
|
||
"stats": self.editor_stats.copy(),
|
||
"config": self.editor_config.copy()
|
||
}
|
||
|
||
def reset_stats(self):
|
||
"""重置编辑器统计信息"""
|
||
try:
|
||
self.editor_stats = {
|
||
"updates_sent": 0,
|
||
"data_points_collected": 0,
|
||
"ui_interactions": 0,
|
||
"export_operations": 0,
|
||
"import_operations": 0,
|
||
"errors": 0
|
||
}
|
||
print("✓ 编辑器统计信息已重置")
|
||
except Exception as e:
|
||
print(f"✗ 编辑器统计信息重置失败: {e}")
|
||
|
||
def set_editor_config(self, config: Dict[str, Any]) -> bool:
|
||
"""
|
||
设置编辑器配置
|
||
|
||
Args:
|
||
config: 编辑器配置字典
|
||
|
||
Returns:
|
||
是否设置成功
|
||
"""
|
||
try:
|
||
self.editor_config.update(config)
|
||
print(f"✓ 编辑器配置已更新: {self.editor_config}")
|
||
return True
|
||
except Exception as e:
|
||
print(f"✗ 编辑器配置设置失败: {e}")
|
||
return False
|
||
|
||
def get_editor_config(self) -> Dict[str, Any]:
|
||
"""
|
||
获取编辑器配置
|
||
|
||
Returns:
|
||
编辑器配置字典
|
||
"""
|
||
return self.editor_config.copy()
|
||
|
||
def _trigger_editor_callback(self, callback_type: str, data: Dict[str, Any]):
|
||
"""
|
||
触发编辑器回调
|
||
|
||
Args:
|
||
callback_type: 回调类型
|
||
data: 回调数据
|
||
"""
|
||
try:
|
||
if callback_type in self.editor_callbacks:
|
||
for callback in self.editor_callbacks[callback_type]:
|
||
try:
|
||
callback(data)
|
||
except Exception as e:
|
||
print(f"✗ 编辑器回调执行失败: {callback_type} - {e}")
|
||
except Exception as e:
|
||
print(f"✗ 编辑器回调触发失败: {e}")
|
||
|
||
def register_editor_callback(self, callback_type: str, callback: callable):
|
||
"""
|
||
注册编辑器回调
|
||
|
||
Args:
|
||
callback_type: 回调类型
|
||
callback: 回调函数
|
||
"""
|
||
try:
|
||
if callback_type in self.editor_callbacks:
|
||
self.editor_callbacks[callback_type].append(callback)
|
||
print(f"✓ 编辑器回调已注册: {callback_type}")
|
||
else:
|
||
print(f"✗ 无效的回调类型: {callback_type}")
|
||
except Exception as e:
|
||
print(f"✗ 编辑器回调注册失败: {e}")
|
||
|
||
def unregister_editor_callback(self, callback_type: str, callback: callable):
|
||
"""
|
||
注销编辑器回调
|
||
|
||
Args:
|
||
callback_type: 回调类型
|
||
callback: 回调函数
|
||
"""
|
||
try:
|
||
if callback_type in self.editor_callbacks:
|
||
if callback in self.editor_callbacks[callback_type]:
|
||
self.editor_callbacks[callback_type].remove(callback)
|
||
print(f"✓ 编辑器回调已注销: {callback_type}")
|
||
else:
|
||
print(f"✗ 无效的回调类型: {callback_type}")
|
||
except Exception as e:
|
||
print(f"✗ 编辑器回调注销失败: {e}") |