EG/plugins/user/network_sync/config/sync_config.py
2025-12-12 16:16:15 +08:00

867 lines
30 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
配置管理模块
负责管理网络同步插件的配置
"""
import time
import json
import os
from typing import Dict, Any, List, Optional
import threading
class SyncConfig:
"""
同步配置管理器
负责管理网络同步插件的配置
"""
def __init__(self, plugin):
"""
初始化同步配置管理器
Args:
plugin: 网络同步插件实例
"""
self.plugin = plugin
self.enabled = False
self.initialized = False
# 配置文件路径
self.config_path = "/home/hello/EG/plugins/user/network_sync/config/network_sync_config.json"
# 默认配置
self.default_config = {
"general": {
"plugin_version": "1.0.0",
"enable_network_sync": True,
"log_level": "INFO",
"max_log_size": 10485760, # 10MB
"enable_debug_logging": False
},
"network": {
"server_host": "localhost",
"server_port": 7777,
"max_connections": 32,
"connection_timeout": 30.0,
"heartbeat_interval": 5.0,
"buffer_size": 4096,
"enable_compression": True,
"enable_encryption": False,
"protocol_version": "1.0"
},
"sync": {
"sync_rate": 20,
"interpolation_rate": 60,
"extrapolation_limit": 0.1,
"sync_distance_threshold": 0.01,
"sync_rotation_threshold": 0.1,
"sync_scale_threshold": 0.01,
"enable_delta_compression": True,
"enable_state_filtering": True,
"max_sync_objects": 1000,
"sync_area_radius": 100.0
},
"prediction": {
"enable_prediction": True,
"enable_interpolation": True,
"enable_extrapolation": True,
"max_prediction_time": 0.5,
"prediction_smoothing": 0.1,
"correction_speed": 5.0,
"velocity_damping": 0.95,
"position_threshold": 0.01,
"rotation_threshold": 0.1,
"enable_snap_correction": True,
"snap_threshold": 1.0
},
"clock": {
"sync_interval": 5.0,
"samples_per_sync": 10,
"max_offset_samples": 100,
"enable_interpolation": True,
"interpolation_rate": 60.0,
"max_drift_correction": 0.1,
"min_sync_quality": 0.8,
"timeout": 10.0
},
"security": {
"enable_authentication": False,
"auth_timeout": 30.0,
"max_auth_attempts": 3,
"enable_rate_limiting": True,
"max_requests_per_second": 100,
"enable_blacklist": True
},
"performance": {
"max_packet_size": 65536,
"enable_fragmentation": True,
"fragment_size": 1024,
"enable_caching": True,
"cache_size": 1000,
"thread_pool_size": 4
}
}
# 当前配置
self.current_config = {}
# 配置变更监听器
self.config_listeners = {}
# 配置备份
self.config_backup = {}
# 配置统计
self.config_stats = {
"loads": 0,
"saves": 0,
"changes": 0,
"errors": 0,
"backups": 0
}
# 线程锁
self.config_lock = threading.RLock()
# 回调函数
self.config_callbacks = {
"config_loaded": [],
"config_saved": [],
"config_changed": [],
"config_error": []
}
# 时间戳记录
self.last_load_time = 0.0
self.last_save_time = 0.0
self.last_change_time = 0.0
print("✓ 同步配置管理器已创建")
def initialize(self) -> bool:
"""
初始化同步配置管理器
Returns:
是否初始化成功
"""
try:
# 创建配置目录
config_dir = os.path.dirname(self.config_path)
if not os.path.exists(config_dir):
os.makedirs(config_dir)
# 加载配置
self.load_config()
# 如果配置为空,使用默认配置
if not self.current_config:
self.current_config = self.default_config.copy()
self.save_config()
self.initialized = True
print("✓ 同步配置管理器初始化完成")
return True
except Exception as e:
print(f"✗ 同步配置管理器初始化失败: {e}")
import traceback
traceback.print_exc()
return False
def enable(self) -> bool:
"""
启用同步配置管理器
Returns:
是否启用成功
"""
try:
if not self.initialized:
print("✗ 配置管理器未初始化")
return False
self.enabled = True
print("✓ 同步配置管理器已启用")
return True
except Exception as e:
print(f"✗ 同步配置管理器启用失败: {e}")
import traceback
traceback.print_exc()
return False
def disable(self):
"""禁用同步配置管理器"""
try:
self.enabled = False
print("✓ 同步配置管理器已禁用")
except Exception as e:
print(f"✗ 同步配置管理器禁用失败: {e}")
import traceback
traceback.print_exc()
def finalize(self):
"""清理同步配置管理器资源"""
try:
self.disable()
self.config_listeners.clear()
self.config_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
# 配置管理器不需要频繁更新
pass
except Exception as e:
print(f"✗ 同步配置管理器更新失败: {e}")
import traceback
traceback.print_exc()
def load_config(self) -> bool:
"""
加载配置
Returns:
是否加载成功
"""
try:
with self.config_lock:
if os.path.exists(self.config_path):
with open(self.config_path, 'r', encoding='utf-8') as f:
self.current_config = json.load(f)
else:
# 使用默认配置
self.current_config = self.default_config.copy()
self.config_stats["loads"] += 1
self.last_load_time = time.time()
# 触发配置加载回调
self._trigger_config_callback("config_loaded", {
"config": self.current_config,
"timestamp": self.last_load_time
})
print("✓ 配置加载完成")
return True
except Exception as e:
print(f"✗ 配置加载失败: {e}")
self.config_stats["errors"] += 1
# 触发配置错误回调
self._trigger_config_callback("config_error", {
"error": str(e),
"operation": "load"
})
return False
def save_config(self) -> bool:
"""
保存配置
Returns:
是否保存成功
"""
try:
with self.config_lock:
# 创建配置目录
config_dir = os.path.dirname(self.config_path)
if not os.path.exists(config_dir):
os.makedirs(config_dir)
# 保存配置
with open(self.config_path, 'w', encoding='utf-8') as f:
json.dump(self.current_config, f, ensure_ascii=False, indent=2)
self.config_stats["saves"] += 1
self.last_save_time = time.time()
# 触发配置保存回调
self._trigger_config_callback("config_saved", {
"config": self.current_config,
"timestamp": self.last_save_time
})
print("✓ 配置保存完成")
return True
except Exception as e:
print(f"✗ 配置保存失败: {e}")
self.config_stats["errors"] += 1
# 触发配置错误回调
self._trigger_config_callback("config_error", {
"error": str(e),
"operation": "save"
})
return False
def get_config(self, section: str = None, key: str = None, default: Any = None) -> Any:
"""
获取配置值
Args:
section: 配置节名称
key: 配置键名称
default: 默认值
Returns:
配置值
"""
try:
with self.config_lock:
if section is None:
return self.current_config.copy()
elif key is None:
return self.current_config.get(section, {}).copy()
else:
return self.current_config.get(section, {}).get(key, default)
except Exception as e:
print(f"✗ 配置获取失败: {e}")
return default
def set_config(self, section: str, key: str = None, value: Any = None, save: bool = True) -> bool:
"""
设置配置值
Args:
section: 配置节名称
key: 配置键名称
value: 配置值
save: 是否保存到文件
Returns:
是否设置成功
"""
try:
with self.config_lock:
# 备份当前配置
self._backup_config()
if key is None:
# 设置整个节
if isinstance(value, dict):
self.current_config[section] = value
else:
print(f"✗ 配置值必须是字典类型: {section}")
return False
else:
# 设置特定键值
if section not in self.current_config:
self.current_config[section] = {}
old_value = self.current_config[section].get(key)
self.current_config[section][key] = value
# 触发配置变更回调
self._trigger_config_callback("config_changed", {
"section": section,
"key": key,
"old_value": old_value,
"new_value": value,
"timestamp": time.time()
})
self.config_stats["changes"] += 1
self.last_change_time = time.time()
# 保存配置
if save:
return self.save_config()
else:
return True
except Exception as e:
print(f"✗ 配置设置失败: {e}")
self.config_stats["errors"] += 1
# 触发配置错误回调
self._trigger_config_callback("config_error", {
"error": str(e),
"operation": "set"
})
return False
def update_config(self, updates: Dict[str, Any], save: bool = True) -> bool:
"""
批量更新配置
Args:
updates: 更新字典
save: 是否保存到文件
Returns:
是否更新成功
"""
try:
with self.config_lock:
# 备份当前配置
self._backup_config()
old_values = {}
# 应用更新
for section, section_data in updates.items():
if isinstance(section_data, dict):
if section not in self.current_config:
self.current_config[section] = {}
for key, value in section_data.items():
old_values[f"{section}.{key}"] = self.current_config[section].get(key)
self.current_config[section][key] = value
else:
old_values[section] = self.current_config.get(section)
self.current_config[section] = section_data
self.config_stats["changes"] += 1
self.last_change_time = time.time()
# 触发配置变更回调
self._trigger_config_callback("config_changed", {
"updates": updates,
"old_values": old_values,
"timestamp": self.last_change_time
})
# 保存配置
if save:
return self.save_config()
else:
return True
except Exception as e:
print(f"✗ 配置批量更新失败: {e}")
self.config_stats["errors"] += 1
# 触发配置错误回调
self._trigger_config_callback("config_error", {
"error": str(e),
"operation": "update"
})
return False
def reset_config(self, section: str = None) -> bool:
"""
重置配置
Args:
section: 要重置的配置节None表示重置所有配置
Returns:
是否重置成功
"""
try:
with self.config_lock:
# 备份当前配置
self._backup_config()
if section is None:
# 重置所有配置
self.current_config = self.default_config.copy()
elif section in self.default_config:
# 重置特定节
self.current_config[section] = self.default_config[section].copy()
else:
print(f"✗ 无效的配置节: {section}")
return False
self.config_stats["changes"] += 1
self.last_change_time = time.time()
# 触发配置变更回调
self._trigger_config_callback("config_changed", {
"operation": "reset",
"section": section,
"timestamp": self.last_change_time
})
# 保存配置
return self.save_config()
except Exception as e:
print(f"✗ 配置重置失败: {e}")
self.config_stats["errors"] += 1
# 触发配置错误回调
self._trigger_config_callback("config_error", {
"error": str(e),
"operation": "reset"
})
return False
def _backup_config(self):
"""备份当前配置"""
try:
self.config_backup = json.loads(json.dumps(self.current_config))
self.config_stats["backups"] += 1
print("✓ 配置已备份")
except Exception as e:
print(f"✗ 配置备份失败: {e}")
def restore_config(self) -> bool:
"""
恢复配置备份
Returns:
是否恢复成功
"""
try:
with self.config_lock:
if self.config_backup:
self.current_config = json.loads(json.dumps(self.config_backup))
self.config_stats["changes"] += 1
self.last_change_time = time.time()
# 触发配置变更回调
self._trigger_config_callback("config_changed", {
"operation": "restore",
"timestamp": self.last_change_time
})
# 保存配置
return self.save_config()
else:
print("✗ 没有可用的配置备份")
return False
except Exception as e:
print(f"✗ 配置恢复失败: {e}")
self.config_stats["errors"] += 1
# 触发配置错误回调
self._trigger_config_callback("config_error", {
"error": str(e),
"operation": "restore"
})
return False
def validate_config(self) -> bool:
"""
验证配置
Returns:
配置是否有效
"""
try:
# 这里可以添加配置验证逻辑
# 例如:检查必需的配置项是否存在,值是否在有效范围内等
# 检查基本结构
required_sections = ["general", "network", "sync", "prediction", "clock"]
for section in required_sections:
if section not in self.current_config:
print(f"✗ 缺少必需的配置节: {section}")
return False
# 检查关键配置值范围
network = self.current_config.get("network", {})
if "server_port" in network and not (1 <= network["server_port"] <= 65535):
print("✗ 无效的服务器端口")
return False
sync = self.current_config.get("sync", {})
if "sync_rate" in sync and sync["sync_rate"] <= 0:
print("✗ 同步频率必须大于0")
return False
print("✓ 配置验证通过")
return True
except Exception as e:
print(f"✗ 配置验证失败: {e}")
return False
def export_config(self, file_path: str) -> bool:
"""
导出配置到文件
Args:
file_path: 导出文件路径
Returns:
是否导出成功
"""
try:
with self.config_lock:
with open(file_path, 'w', encoding='utf-8') as f:
json.dump(self.current_config, f, ensure_ascii=False, indent=2)
print(f"✓ 配置已导出到: {file_path}")
return True
except Exception as e:
print(f"✗ 配置导出失败: {e}")
return False
def import_config(self, file_path: str) -> bool:
"""
从文件导入配置
Args:
file_path: 导入文件路径
Returns:
是否导入成功
"""
try:
with self.config_lock:
# 备份当前配置
self._backup_config()
with open(file_path, 'r', encoding='utf-8') as f:
imported_config = json.load(f)
# 验证导入的配置
temp_manager = SyncConfig(self.plugin)
temp_manager.current_config = imported_config
if not temp_manager.validate_config():
print("✗ 导入的配置无效")
return False
# 应用导入的配置
self.current_config = imported_config
self.config_stats["changes"] += 1
self.last_change_time = time.time()
# 触发配置变更回调
self._trigger_config_callback("config_changed", {
"operation": "import",
"source": file_path,
"timestamp": self.last_change_time
})
# 保存配置
return self.save_config()
except Exception as e:
print(f"✗ 配置导入失败: {e}")
self.config_stats["errors"] += 1
# 触发配置错误回调
self._trigger_config_callback("config_error", {
"error": str(e),
"operation": "import"
})
return False
def get_default_config(self) -> Dict[str, Any]:
"""
获取默认配置
Returns:
默认配置字典
"""
return self.default_config.copy()
def get_config_stats(self) -> Dict[str, int]:
"""
获取配置统计信息
Returns:
统计信息字典
"""
return self.config_stats.copy()
def reset_config_stats(self):
"""重置配置统计信息"""
try:
self.config_stats = {
"loads": 0,
"saves": 0,
"changes": 0,
"errors": 0,
"backups": 0
}
print("✓ 配置统计信息已重置")
except Exception as e:
print(f"✗ 配置统计信息重置失败: {e}")
def register_config_listener(self, section: str, key: str, listener: callable) -> bool:
"""
注册配置监听器
Args:
section: 配置节名称
key: 配置键名称
listener: 监听器函数
Returns:
是否注册成功
"""
try:
listener_key = f"{section}.{key}"
if listener_key not in self.config_listeners:
self.config_listeners[listener_key] = []
self.config_listeners[listener_key].append(listener)
print(f"✓ 配置监听器已注册: {listener_key}")
return True
except Exception as e:
print(f"✗ 配置监听器注册失败: {e}")
return False
def unregister_config_listener(self, section: str, key: str, listener: callable) -> bool:
"""
注销配置监听器
Args:
section: 配置节名称
key: 配置键名称
listener: 监听器函数
Returns:
是否注销成功
"""
try:
listener_key = f"{section}.{key}"
if listener_key in self.config_listeners:
if listener in self.config_listeners[listener_key]:
self.config_listeners[listener_key].remove(listener)
print(f"✓ 配置监听器已注销: {listener_key}")
return True
print(f"✗ 配置监听器不存在: {listener_key}")
return False
except Exception as e:
print(f"✗ 配置监听器注销失败: {e}")
return False
def _trigger_config_callback(self, callback_type: str, data: Dict[str, Any]):
"""
触发配置回调
Args:
callback_type: 回调类型
data: 回调数据
"""
try:
if callback_type in self.config_callbacks:
for callback in self.config_callbacks[callback_type]:
try:
callback(data)
except Exception as e:
print(f"✗ 配置回调执行失败: {e}")
except Exception as e:
print(f"✗ 配置回调触发失败: {e}")
def register_config_callback(self, callback_type: str, callback: callable):
"""
注册配置回调
Args:
callback_type: 回调类型
callback: 回调函数
"""
try:
if callback_type in self.config_callbacks:
self.config_callbacks[callback_type].append(callback)
print(f"✓ 配置回调已注册: {callback_type}")
else:
print(f"✗ 无效的回调类型: {callback_type}")
except Exception as e:
print(f"✗ 配置回调注册失败: {e}")
def unregister_config_callback(self, callback_type: str, callback: callable):
"""
注销配置回调
Args:
callback_type: 回调类型
callback: 回调函数
"""
try:
if callback_type in self.config_callbacks:
if callback in self.config_callbacks[callback_type]:
self.config_callbacks[callback_type].remove(callback)
print(f"✓ 配置回调已注销: {callback_type}")
except Exception as e:
print(f"✗ 配置回调注销失败: {e}")
def apply_config_to_modules(self):
"""
将配置应用到各个模块
"""
try:
if not self.enabled:
return
# 应用配置到同步管理器
if self.plugin.sync_manager:
sync_config = self.get_config("sync")
self.plugin.sync_manager.set_sync_config(sync_config)
# 应用配置到网络管理器
if self.plugin.network_manager:
network_config = self.get_config("network")
self.plugin.network_manager.set_network_config(network_config)
# 应用配置到协议处理器
if self.plugin.protocol_handler:
# 协议配置可能需要从多个节获取
protocol_config = {}
protocol_config.update(self.get_config("network", {}))
protocol_config.update(self.get_config("performance", {}))
self.plugin.protocol_handler.set_protocol_config(protocol_config)
# 应用配置到对象同步器
if self.plugin.object_sync:
sync_config = self.get_config("sync")
self.plugin.object_sync.set_sync_config(sync_config)
# 应用配置到连接管理器
if self.plugin.connection_manager:
connection_config = self.get_config("network")
security_config = self.get_config("security")
combined_config = {**connection_config, **security_config}
self.plugin.connection_manager.set_connection_config(combined_config)
# 应用配置到数据序列化器
if self.plugin.data_serializer:
serialization_config = self.get_config("performance")
self.plugin.data_serializer.set_serialization_config(serialization_config)
# 应用配置到时钟同步器
if self.plugin.clock_sync:
clock_config = self.get_config("clock")
self.plugin.clock_sync.set_clock_config(clock_config)
# 应用配置到预测管理器
if self.plugin.prediction_manager:
prediction_config = self.get_config("prediction")
self.plugin.prediction_manager.set_prediction_config(prediction_config)
print("✓ 配置已应用到所有模块")
except Exception as e:
print(f"✗ 配置应用失败: {e}")
import traceback
traceback.print_exc()