extends Node class_name DialogueHistoryManager ## 对话历史管理器 ## 负责保存、加载和管理对话历史记录 # 历史记录存储 var dialogue_histories: Dictionary = {} # character_id -> Array[Dictionary] var max_history_per_character: int = 100 var history_file_path: String = "user://dialogue_history.json" # 信号 signal history_loaded() signal history_saved() func _ready(): """初始化对话历史管理器""" load_history() print("DialogueHistoryManager initialized") ## 添加消息到历史记录 func add_message_to_history(character_id: String, sender: String, message: String, timestamp: float = 0.0) -> void: """ 添加消息到指定角色的对话历史 @param character_id: 角色ID @param sender: 发送者("player" 或角色ID) @param message: 消息内容 @param timestamp: 时间戳(0表示使用当前时间) """ if timestamp <= 0: timestamp = Time.get_unix_time_from_system() # 确保角色历史记录存在 if not dialogue_histories.has(character_id): dialogue_histories[character_id] = [] var history = dialogue_histories[character_id] # 创建消息记录 var message_record = { "sender": sender, "message": message, "timestamp": timestamp, "id": generate_message_id() } # 添加到历史记录 history.append(message_record) # 限制历史记录长度 if history.size() > max_history_per_character: history.pop_front() # 自动保存(异步) call_deferred("save_history") ## 获取角色的对话历史 func get_character_history(character_id: String, limit: int = 0) -> Array[Dictionary]: """ 获取指定角色的对话历史 @param character_id: 角色ID @param limit: 限制返回的消息数量(0表示返回全部) @return: 消息历史数组 """ if not dialogue_histories.has(character_id): return [] var history = dialogue_histories[character_id] if limit <= 0 or limit >= history.size(): return history.duplicate() # 返回最近的消息 return history.slice(history.size() - limit, history.size()) ## 获取最近的对话记录 func get_recent_conversations(limit: int = 10) -> Array[Dictionary]: """ 获取最近的对话记录(按时间排序) @param limit: 限制返回的对话数量 @return: 最近对话的摘要数组 """ var recent_conversations = [] for character_id in dialogue_histories: var history = dialogue_histories[character_id] if history.size() > 0: var last_message = history[-1] # 最后一条消息 recent_conversations.append({ "character_id": character_id, "last_message": last_message.message, "last_sender": last_message.sender, "timestamp": last_message.timestamp, "message_count": history.size() }) # 按时间戳排序(最新的在前) recent_conversations.sort_custom(func(a, b): return a.timestamp > b.timestamp) # 限制数量 if limit > 0 and recent_conversations.size() > limit: recent_conversations = recent_conversations.slice(0, limit) return recent_conversations ## 搜索对话历史 func search_messages(query: String, character_id: String = "") -> Array[Dictionary]: """ 在对话历史中搜索消息 @param query: 搜索关键词 @param character_id: 指定角色ID(空字符串表示搜索所有角色) @return: 匹配的消息数组 """ var results = [] var search_query = query.to_lower() var characters_to_search = [] if character_id.is_empty(): characters_to_search = dialogue_histories.keys() else: characters_to_search = [character_id] for char_id in characters_to_search: if not dialogue_histories.has(char_id): continue var history = dialogue_histories[char_id] for message_record in history: if message_record.message.to_lower().contains(search_query): var result = message_record.duplicate() result["character_id"] = char_id results.append(result) # 按时间戳排序(最新的在前) results.sort_custom(func(a, b): return a.timestamp > b.timestamp) return results ## 清除角色的对话历史 func clear_character_history(character_id: String) -> void: """ 清除指定角色的对话历史 @param character_id: 角色ID """ if dialogue_histories.has(character_id): dialogue_histories.erase(character_id) save_history() ## 清除所有对话历史 func clear_all_history() -> void: """清除所有对话历史""" dialogue_histories.clear() save_history() ## 保存历史记录到文件 func save_history() -> void: """保存对话历史到本地文件""" var file = FileAccess.open(history_file_path, FileAccess.WRITE) if file: var json_string = JSON.stringify(dialogue_histories) file.store_string(json_string) file.close() history_saved.emit() print("Dialogue history saved") else: print("Failed to save dialogue history") ## 从文件加载历史记录 func load_history() -> void: """从本地文件加载对话历史""" if not FileAccess.file_exists(history_file_path): print("No dialogue history file found, starting fresh") return var file = FileAccess.open(history_file_path, FileAccess.READ) if file: var json_string = file.get_as_text() file.close() var json = JSON.new() var parse_result = json.parse(json_string) if parse_result == OK: dialogue_histories = json.data history_loaded.emit() print("Dialogue history loaded: ", dialogue_histories.size(), " characters") else: print("Failed to parse dialogue history JSON") else: print("Failed to open dialogue history file") ## 生成消息ID func generate_message_id() -> String: """生成唯一的消息ID""" var timestamp = Time.get_unix_time_from_system() var random = randi() return "msg_%d_%d" % [timestamp, random] ## 获取统计信息 func get_statistics() -> Dictionary: """ 获取对话历史统计信息 @return: 统计信息字典 """ var total_messages = 0 var total_characters = dialogue_histories.size() var oldest_message_time = 0.0 var newest_message_time = 0.0 for character_id in dialogue_histories: var history = dialogue_histories[character_id] total_messages += history.size() if history.size() > 0: var first_msg_time = history[0].timestamp var last_msg_time = history[-1].timestamp if oldest_message_time == 0.0 or first_msg_time < oldest_message_time: oldest_message_time = first_msg_time if newest_message_time == 0.0 or last_msg_time > newest_message_time: newest_message_time = last_msg_time return { "total_messages": total_messages, "total_characters": total_characters, "oldest_message_time": oldest_message_time, "newest_message_time": newest_message_time, "file_path": history_file_path } ## 导出历史记录 func export_history(export_path: String, character_id: String = "") -> bool: """ 导出对话历史到指定文件 @param export_path: 导出文件路径 @param character_id: 指定角色ID(空字符串表示导出所有) @return: 是否成功 """ var export_data = {} if character_id.is_empty(): export_data = dialogue_histories elif dialogue_histories.has(character_id): export_data[character_id] = dialogue_histories[character_id] else: print("Character not found: ", character_id) return false var file = FileAccess.open(export_path, FileAccess.WRITE) if file: var json_string = JSON.stringify(export_data) file.store_string(json_string) file.close() print("History exported to: ", export_path) return true else: print("Failed to export history to: ", export_path) return false