Files
whale-town/scripts/GroupDialogueManager.gd
2025-12-05 19:00:14 +08:00

433 lines
11 KiB
GDScript
Raw Permalink 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.
extends Node
class_name GroupDialogueManager
## 群组对话管理器
## 管理多人对话和群组聊天功能
# 群组数据结构
class DialogueGroup:
var id: String
var name: String
var participants: Array[String] = [] # 参与者ID列表
var creator_id: String
var created_at: float
var is_active: bool = true
var max_participants: int = 10
var message_history: Array[Dictionary] = []
func _init(group_id: String, group_name: String, creator: String):
id = group_id
name = group_name
creator_id = creator
created_at = Time.get_unix_time_from_system()
participants.append(creator)
# 群组管理
var active_groups: Dictionary = {} # group_id -> DialogueGroup
var player_groups: Array[String] = [] # 玩家参与的群组ID列表
var current_group_id: String = "" # 当前活跃的群组
# 配置
var max_groups_per_player: int = 5
var max_message_history: int = 100
# 信号
signal group_created(group_id: String, group_name: String)
signal group_joined(group_id: String, participant_id: String)
signal group_left(group_id: String, participant_id: String)
signal group_message_received(group_id: String, sender_id: String, message: String)
signal group_disbanded(group_id: String)
func _ready():
"""初始化群组对话管理器"""
print("GroupDialogueManager initialized")
## 创建新群组
func create_group(group_name: String, creator_id: String) -> String:
"""
创建新的对话群组
@param group_name: 群组名称
@param creator_id: 创建者ID
@return: 群组ID失败返回空字符串
"""
# 检查玩家群组数量限制
if player_groups.size() >= max_groups_per_player:
print("Cannot create group: player has reached maximum groups limit")
return ""
# 验证群组名称
if group_name.strip_edges().is_empty():
print("Cannot create group: invalid group name")
return ""
if group_name.length() > 50:
print("Cannot create group: group name too long")
return ""
# 生成群组ID
var group_id = generate_group_id()
# 创建群组
var group = DialogueGroup.new(group_id, group_name.strip_edges(), creator_id)
active_groups[group_id] = group
# 添加到玩家群组列表
if not group_id in player_groups:
player_groups.append(group_id)
group_created.emit(group_id, group_name)
print("Group created: ", group_name, " (", group_id, ")")
return group_id
## 加入群组
func join_group(group_id: String, participant_id: String) -> bool:
"""
加入指定群组
@param group_id: 群组ID
@param participant_id: 参与者ID
@return: 是否成功加入
"""
if not active_groups.has(group_id):
print("Cannot join group: group not found")
return false
var group = active_groups[group_id]
# 检查群组是否活跃
if not group.is_active:
print("Cannot join group: group is not active")
return false
# 检查是否已经在群组中
if participant_id in group.participants:
print("Already in group: ", group_id)
return true
# 检查群组人数限制
if group.participants.size() >= group.max_participants:
print("Cannot join group: group is full")
return false
# 加入群组
group.participants.append(participant_id)
# 如果是玩家,添加到玩家群组列表
if participant_id == "player" and not group_id in player_groups:
player_groups.append(group_id)
group_joined.emit(group_id, participant_id)
print("Participant ", participant_id, " joined group ", group_id)
return true
## 离开群组
func leave_group(group_id: String, participant_id: String) -> bool:
"""
离开指定群组
@param group_id: 群组ID
@param participant_id: 参与者ID
@return: 是否成功离开
"""
if not active_groups.has(group_id):
print("Cannot leave group: group not found")
return false
var group = active_groups[group_id]
# 检查是否在群组中
if not participant_id in group.participants:
print("Not in group: ", group_id)
return false
# 离开群组
group.participants.erase(participant_id)
# 如果是玩家,从玩家群组列表中移除
if participant_id == "player":
player_groups.erase(group_id)
# 如果当前活跃群组是这个,清除当前群组
if current_group_id == group_id:
current_group_id = ""
group_left.emit(group_id, participant_id)
print("Participant ", participant_id, " left group ", group_id)
# 如果群组为空或创建者离开,解散群组
if group.participants.is_empty() or participant_id == group.creator_id:
disband_group(group_id)
return true
## 发送群组消息
func send_group_message(group_id: String, sender_id: String, message: String) -> bool:
"""
向群组发送消息
@param group_id: 群组ID
@param sender_id: 发送者ID
@param message: 消息内容
@return: 是否成功发送
"""
if not active_groups.has(group_id):
print("Cannot send message: group not found")
return false
var group = active_groups[group_id]
# 检查发送者是否在群组中
if not sender_id in group.participants:
print("Cannot send message: sender not in group")
return false
# 验证消息
if message.strip_edges().is_empty():
print("Cannot send empty message")
return false
if message.length() > 500:
print("Message too long")
return false
# 创建消息记录
var message_record = {
"sender_id": sender_id,
"message": message,
"timestamp": Time.get_unix_time_from_system(),
"id": generate_message_id()
}
# 添加到群组历史
group.message_history.append(message_record)
# 限制历史记录长度
if group.message_history.size() > max_message_history:
group.message_history.pop_front()
# 发射信号
group_message_received.emit(group_id, sender_id, message)
print("Group message sent in ", group_id, " by ", sender_id, ": ", message)
return true
## 解散群组
func disband_group(group_id: String) -> bool:
"""
解散指定群组
@param group_id: 群组ID
@return: 是否成功解散
"""
if not active_groups.has(group_id):
print("Cannot disband group: group not found")
return false
var group = active_groups[group_id]
# 通知所有参与者
for participant_id in group.participants:
group_left.emit(group_id, participant_id)
# 从玩家群组列表中移除
player_groups.erase(group_id)
# 如果是当前活跃群组,清除
if current_group_id == group_id:
current_group_id = ""
# 移除群组
active_groups.erase(group_id)
group_disbanded.emit(group_id)
print("Group disbanded: ", group_id)
return true
## 设置当前活跃群组
func set_current_group(group_id: String) -> bool:
"""
设置当前活跃的群组
@param group_id: 群组ID空字符串表示清除当前群组
@return: 是否成功设置
"""
if group_id.is_empty():
current_group_id = ""
return true
if not active_groups.has(group_id):
print("Cannot set current group: group not found")
return false
var group = active_groups[group_id]
# 检查玩家是否在群组中
if not "player" in group.participants:
print("Cannot set current group: player not in group")
return false
current_group_id = group_id
print("Current group set to: ", group_id)
return true
## 获取群组信息
func get_group_info(group_id: String) -> Dictionary:
"""
获取群组信息
@param group_id: 群组ID
@return: 群组信息字典
"""
if not active_groups.has(group_id):
return {}
var group = active_groups[group_id]
return {
"id": group.id,
"name": group.name,
"participants": group.participants.duplicate(),
"creator_id": group.creator_id,
"created_at": group.created_at,
"is_active": group.is_active,
"participant_count": group.participants.size(),
"message_count": group.message_history.size()
}
## 获取群组消息历史
func get_group_history(group_id: String, limit: int = 0) -> Array[Dictionary]:
"""
获取群组消息历史
@param group_id: 群组ID
@param limit: 限制返回的消息数量0表示返回全部
@return: 消息历史数组
"""
if not active_groups.has(group_id):
return []
var group = active_groups[group_id]
var history = group.message_history
if limit <= 0 or limit >= history.size():
return history.duplicate()
# 返回最近的消息
return history.slice(history.size() - limit, history.size())
## 获取玩家的群组列表
func get_player_groups() -> Array[Dictionary]:
"""
获取玩家参与的群组列表
@return: 群组信息数组
"""
var groups = []
for group_id in player_groups:
if active_groups.has(group_id):
groups.append(get_group_info(group_id))
return groups
## 搜索群组
func search_groups(query: String) -> Array[Dictionary]:
"""
搜索群组(按名称)
@param query: 搜索关键词
@return: 匹配的群组信息数组
"""
var results = []
var search_query = query.to_lower()
for group_id in active_groups:
var group = active_groups[group_id]
if group.is_active and group.name.to_lower().contains(search_query):
results.append(get_group_info(group_id))
return results
## 获取附近的角色(用于邀请加入群组)
func get_nearby_characters_for_invite(_player_position: Vector2, _radius: float = 100.0) -> Array[String]:
"""
获取附近可以邀请的角色列表
@param _player_position: 玩家位置(暂未使用)
@param _radius: 搜索半径(暂未使用)
@return: 角色ID数组
"""
# 这里需要与WorldManager集成来获取附近角色
# 暂时返回空数组实际实现时需要调用WorldManager
return []
## 邀请角色加入群组
func invite_to_group(group_id: String, inviter_id: String, invitee_id: String) -> bool:
"""
邀请角色加入群组
@param group_id: 群组ID
@param inviter_id: 邀请者ID
@param invitee_id: 被邀请者ID
@return: 是否成功发送邀请
"""
if not active_groups.has(group_id):
print("Cannot invite: group not found")
return false
var group = active_groups[group_id]
# 检查邀请者是否在群组中
if not inviter_id in group.participants:
print("Cannot invite: inviter not in group")
return false
# 检查被邀请者是否已在群组中
if invitee_id in group.participants:
print("Cannot invite: invitee already in group")
return false
# 检查群组是否已满
if group.participants.size() >= group.max_participants:
print("Cannot invite: group is full")
return false
# 这里应该发送邀请消息给被邀请者
# 实际实现时需要与网络系统集成
print("Invitation sent to ", invitee_id, " for group ", group_id)
return true
## 生成群组ID
func generate_group_id() -> String:
"""生成唯一的群组ID"""
var timestamp = Time.get_unix_time_from_system()
var random = randi()
return "group_%d_%d" % [timestamp, random]
## 生成消息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_groups = active_groups.size()
var active_group_count = 0
var total_participants = 0
var total_messages = 0
for group_id in active_groups:
var group = active_groups[group_id]
if group.is_active:
active_group_count += 1
total_participants += group.participants.size()
total_messages += group.message_history.size()
return {
"total_groups": total_groups,
"active_groups": active_group_count,
"player_groups": player_groups.size(),
"total_participants": total_participants,
"total_messages": total_messages,
"current_group": current_group_id
}