创建新工程

This commit is contained in:
moyin
2025-12-05 19:00:14 +08:00
commit ff4fa5fffd
227 changed files with 32804 additions and 0 deletions

View File

@@ -0,0 +1,470 @@
extends Control
class_name EnhancedDialogueBox
## 增强对话框 UI
## 支持表情符号、群组对话、历史记录等功能
# UI 元素
var message_display: RichTextLabel
var message_input: LineEdit
var send_button: Button
var emoji_button: Button
var history_button: Button
var group_button: Button
var close_button: Button
var target_label: Label
var container: VBoxContainer
var scroll_container: ScrollContainer
# 表情符号选择器
var emoji_picker: Control
var emoji_picker_visible: bool = false
# 历史记录面板
var history_panel: Control
var history_list: ItemList
var history_visible: bool = false
# 群组面板
var group_panel: Control
var group_list: ItemList
var create_group_button: Button
var join_group_button: Button
var group_visible: bool = false
# 管理器引用
var emoji_manager: EmojiManager
var dialogue_filter: DialogueFilter
var group_manager: GroupDialogueManager
var history_manager: DialogueHistoryManager
# 当前对话目标
var current_target_id: String = ""
var current_target_name: String = ""
var is_group_chat: bool = false
# 信号
signal message_sent(target_id: String, message: String, is_group: bool)
signal dialogue_closed()
signal emoji_selected(emoji: String)
func _ready():
"""初始化增强对话框"""
setup_ui()
setup_managers()
connect_signals()
print("EnhancedDialogueBox initialized")
## 设置UI元素
func setup_ui() -> void:
"""设置UI元素和布局"""
# 主容器
container = VBoxContainer.new()
add_child(container)
container.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
# 目标标签
target_label = Label.new()
target_label.text = "对话"
target_label.add_theme_font_size_override("font_size", 16)
container.add_child(target_label)
# 消息显示区域
scroll_container = ScrollContainer.new()
scroll_container.custom_minimum_size = Vector2(400, 300)
container.add_child(scroll_container)
message_display = RichTextLabel.new()
message_display.bbcode_enabled = true
message_display.fit_content = true
scroll_container.add_child(message_display)
# 按钮行
var button_row = HBoxContainer.new()
container.add_child(button_row)
emoji_button = Button.new()
emoji_button.text = "😊"
emoji_button.custom_minimum_size = Vector2(40, 30)
button_row.add_child(emoji_button)
history_button = Button.new()
history_button.text = "历史"
history_button.custom_minimum_size = Vector2(60, 30)
button_row.add_child(history_button)
group_button = Button.new()
group_button.text = "群组"
group_button.custom_minimum_size = Vector2(60, 30)
button_row.add_child(group_button)
close_button = Button.new()
close_button.text = "关闭"
close_button.custom_minimum_size = Vector2(60, 30)
button_row.add_child(close_button)
# 输入行
var input_row = HBoxContainer.new()
container.add_child(input_row)
message_input = LineEdit.new()
message_input.placeholder_text = "输入消息..."
message_input.custom_minimum_size = Vector2(300, 30)
input_row.add_child(message_input)
send_button = Button.new()
send_button.text = "发送"
send_button.custom_minimum_size = Vector2(60, 30)
input_row.add_child(send_button)
# 创建弹出面板
create_emoji_picker()
create_history_panel()
create_group_panel()
## 创建表情符号选择器
func create_emoji_picker() -> void:
"""创建表情符号选择器面板"""
emoji_picker = Control.new()
emoji_picker.visible = false
add_child(emoji_picker)
var picker_bg = NinePatchRect.new()
picker_bg.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
emoji_picker.add_child(picker_bg)
var picker_container = VBoxContainer.new()
picker_container.position = Vector2(10, 10)
picker_container.custom_minimum_size = Vector2(300, 200)
emoji_picker.add_child(picker_container)
# 表情符号网格
var emoji_grid = GridContainer.new()
emoji_grid.columns = 8
picker_container.add_child(emoji_grid)
# 添加常用表情符号
var common_emojis = ["😊", "😢", "😃", "😉", "😛", "😮", "😲", "😐", "😕", "😭", "😂", "😍", "😠", "😡", "😎", "👍", "👎", "👏", "❤️", "🔥"]
for emoji in common_emojis:
var emoji_btn = Button.new()
emoji_btn.text = emoji
emoji_btn.custom_minimum_size = Vector2(30, 30)
emoji_btn.pressed.connect(_on_emoji_button_pressed.bind(emoji))
emoji_grid.add_child(emoji_btn)
## 创建历史记录面板
func create_history_panel() -> void:
"""创建历史记录面板"""
history_panel = Control.new()
history_panel.visible = false
add_child(history_panel)
var history_bg = NinePatchRect.new()
history_bg.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
history_panel.add_child(history_bg)
var history_container = VBoxContainer.new()
history_container.position = Vector2(10, 10)
history_container.custom_minimum_size = Vector2(350, 250)
history_panel.add_child(history_container)
var history_title = Label.new()
history_title.text = "对话历史"
history_title.add_theme_font_size_override("font_size", 14)
history_container.add_child(history_title)
history_list = ItemList.new()
history_list.custom_minimum_size = Vector2(330, 200)
history_container.add_child(history_list)
## 创建群组面板
func create_group_panel() -> void:
"""创建群组管理面板"""
group_panel = Control.new()
group_panel.visible = false
add_child(group_panel)
var group_bg = NinePatchRect.new()
group_bg.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
group_panel.add_child(group_bg)
var group_container = VBoxContainer.new()
group_container.position = Vector2(10, 10)
group_container.custom_minimum_size = Vector2(300, 250)
group_panel.add_child(group_container)
var group_title = Label.new()
group_title.text = "群组管理"
group_title.add_theme_font_size_override("font_size", 14)
group_container.add_child(group_title)
var group_buttons = HBoxContainer.new()
group_container.add_child(group_buttons)
create_group_button = Button.new()
create_group_button.text = "创建群组"
group_buttons.add_child(create_group_button)
join_group_button = Button.new()
join_group_button.text = "加入群组"
group_buttons.add_child(join_group_button)
group_list = ItemList.new()
group_list.custom_minimum_size = Vector2(280, 180)
group_container.add_child(group_list)
## 设置管理器
func setup_managers() -> void:
"""设置各种管理器"""
# 延迟初始化管理器以避免性能问题
call_deferred("_initialize_managers")
func _initialize_managers() -> void:
"""延迟初始化管理器"""
emoji_manager = EmojiManager.new()
add_child(emoji_manager)
dialogue_filter = DialogueFilter.new()
add_child(dialogue_filter)
group_manager = GroupDialogueManager.new()
add_child(group_manager)
history_manager = DialogueHistoryManager.new()
add_child(history_manager)
## 连接信号
func connect_signals() -> void:
"""连接UI信号"""
send_button.pressed.connect(_on_send_button_pressed)
message_input.text_submitted.connect(_on_message_submitted)
emoji_button.pressed.connect(_on_emoji_button_pressed_toggle)
history_button.pressed.connect(_on_history_button_pressed)
group_button.pressed.connect(_on_group_button_pressed)
close_button.pressed.connect(_on_close_button_pressed)
# 管理器信号
dialogue_filter.message_blocked.connect(_on_message_blocked)
group_manager.group_message_received.connect(_on_group_message_received)
## 开始对话
func start_dialogue(target_id: String, target_name: String, is_group: bool = false) -> void:
"""
开始与指定目标的对话
@param target_id: 目标ID
@param target_name: 目标名称
@param is_group: 是否为群组对话
"""
current_target_id = target_id
current_target_name = target_name
is_group_chat = is_group
# 更新UI
if is_group:
target_label.text = "群组: " + target_name
else:
target_label.text = "对话: " + target_name
# 加载历史记录
load_dialogue_history()
# 显示对话框
visible = true
message_input.grab_focus()
## 发送消息
func send_message(message: String) -> void:
"""
发送消息
@param message: 消息内容
"""
if message.strip_edges().is_empty():
return
var sender_id = "player"
# 过滤消息(添加安全检查)
if not dialogue_filter:
show_error_message("对话过滤器未初始化")
return
var filter_result = dialogue_filter.filter_message(sender_id, message)
if not filter_result.allowed:
show_error_message(filter_result.reason)
return
var filtered_message = filter_result.filtered_message
# 转换表情符号
var final_message = EmojiManager.convert_text_to_emoji(filtered_message)
# 发送消息
if is_group_chat:
group_manager.send_group_message(current_target_id, sender_id, final_message)
else:
# 通过NetworkManager发送消息如果连接到服务器
var network_manager = get_node("/root/Main/NetworkManager")
if network_manager and network_manager.is_server_connected():
var dialogue_message = MessageProtocol.create_dialogue_send(sender_id, current_target_id, final_message)
network_manager.send_message(dialogue_message)
message_sent.emit(current_target_id, final_message, false)
# 添加到历史记录
history_manager.add_message_to_history(current_target_id, sender_id, final_message)
# 显示在对话框中
display_message(sender_id, final_message)
# 清空输入框
message_input.text = ""
## 接收消息
func receive_message(sender_id: String, message: String) -> void:
"""
接收消息
@param sender_id: 发送者ID
@param message: 消息内容
"""
# 添加到历史记录
history_manager.add_message_to_history(current_target_id, sender_id, message)
# 显示在对话框中
display_message(sender_id, message)
## 显示消息
func display_message(sender_id: String, message: String) -> void:
"""
在对话框中显示消息
@param sender_id: 发送者ID
@param message: 消息内容
"""
var timestamp = Time.get_datetime_string_from_system()
var sender_name = sender_id if sender_id != "player" else ""
var formatted_message = "[color=gray][%s][/color] [color=blue]%s[/color]: %s\n" % [timestamp, sender_name, message]
message_display.append_text(formatted_message)
# 滚动到底部
await get_tree().process_frame
scroll_container.scroll_vertical = scroll_container.get_v_scroll_bar().max_value
## 加载对话历史
func load_dialogue_history() -> void:
"""加载当前目标的对话历史"""
message_display.clear()
var history = history_manager.get_character_history(current_target_id, 20)
for message_record in history:
var sender_name = message_record.sender if message_record.sender != "player" else ""
var timestamp = Time.get_datetime_string_from_unix_time(message_record.timestamp)
var formatted_message = "[color=gray][%s][/color] [color=blue]%s[/color]: %s\n" % [timestamp, sender_name, message_record.message]
message_display.append_text(formatted_message)
## 显示错误消息
func show_error_message(error_text: String) -> void:
"""
显示错误消息
@param error_text: 错误文本
"""
var error_message = "[color=red]系统: %s[/color]\n" % error_text
message_display.append_text(error_message)
## 信号处理函数
func _on_send_button_pressed() -> void:
"""发送按钮点击处理"""
send_message(message_input.text)
func _on_message_submitted(text: String) -> void:
"""消息输入提交处理"""
send_message(text)
func _on_emoji_button_pressed_toggle() -> void:
"""表情符号按钮点击处理"""
emoji_picker_visible = not emoji_picker_visible
emoji_picker.visible = emoji_picker_visible
# 隐藏其他面板
if emoji_picker_visible:
history_panel.visible = false
group_panel.visible = false
history_visible = false
group_visible = false
func _on_emoji_button_pressed(emoji: String) -> void:
"""表情符号选择处理"""
message_input.text += emoji
emoji_manager.add_to_recent(emoji)
emoji_selected.emit(emoji)
# 隐藏选择器
emoji_picker.visible = false
emoji_picker_visible = false
# 聚焦输入框
message_input.grab_focus()
func _on_history_button_pressed() -> void:
"""历史记录按钮点击处理"""
history_visible = not history_visible
history_panel.visible = history_visible
# 隐藏其他面板
if history_visible:
emoji_picker.visible = false
group_panel.visible = false
emoji_picker_visible = false
group_visible = false
# 更新历史记录列表
update_history_list()
func _on_group_button_pressed() -> void:
"""群组按钮点击处理"""
group_visible = not group_visible
group_panel.visible = group_visible
# 隐藏其他面板
if group_visible:
emoji_picker.visible = false
history_panel.visible = false
emoji_picker_visible = false
history_visible = false
# 更新群组列表
update_group_list()
func _on_close_button_pressed() -> void:
"""关闭按钮点击处理"""
visible = false
dialogue_closed.emit()
func _on_message_blocked(user_id: String, message: String, reason: String) -> void:
"""消息被阻止处理"""
show_error_message("消息被阻止: " + reason)
func _on_group_message_received(group_id: String, sender_id: String, message: String) -> void:
"""群组消息接收处理"""
if group_id == current_target_id and is_group_chat:
receive_message(sender_id, message)
## 更新历史记录列表
func update_history_list() -> void:
"""更新历史记录列表"""
history_list.clear()
var recent_conversations = history_manager.get_recent_conversations(10)
for conversation in recent_conversations:
var item_text = "%s: %s" % [conversation.character_id, conversation.last_message]
if item_text.length() > 50:
item_text = item_text.substr(0, 47) + "..."
history_list.add_item(item_text)
## 更新群组列表
func update_group_list() -> void:
"""更新群组列表"""
group_list.clear()
var player_groups = group_manager.get_player_groups()
for group_info in player_groups:
var item_text = "%s (%d人)" % [group_info.name, group_info.participant_count]
group_list.add_item(item_text)