创建新工程
This commit is contained in:
258
scripts/DialogueHistoryManager.gd
Normal file
258
scripts/DialogueHistoryManager.gd
Normal file
@@ -0,0 +1,258 @@
|
||||
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
|
||||
Reference in New Issue
Block a user