258 lines
7.3 KiB
GDScript
258 lines
7.3 KiB
GDScript
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 |