Files
whale-town/scripts/FriendSystem.gd
2025-12-06 17:33:14 +08:00

584 lines
16 KiB
GDScript

extends Node
class_name FriendSystem
## 好友系统
## 管理玩家之间的好友关系和社交功能
# 好友关系数据结构
class FriendRelationship:
var friend_id: String
var friend_name: String
var status: String # "pending", "accepted", "blocked"
var added_at: float
var last_interaction: float
var relationship_level: int = 1 # 关系等级 1-5
var interaction_count: int = 0
var shared_activities: Array[String] = []
func _init(id: String, name: String, relationship_status: String = "pending"):
friend_id = id
friend_name = name
status = relationship_status
added_at = Time.get_unix_time_from_system()
last_interaction = added_at
# 好友数据存储
var friends: Dictionary = {} # friend_id -> FriendRelationship
var friend_requests: Dictionary = {} # requester_id -> FriendRelationship
var blocked_users: Dictionary = {} # blocked_id -> timestamp
var max_friends: int = 100
var max_pending_requests: int = 20
# 数据持久化
var friends_file_path: String = "user://friends_data.json"
# 信号
signal friend_request_sent(friend_id: String, friend_name: String)
# signal friend_request_received(requester_id: String, requester_name: String) # 暂时未使用
signal friend_request_accepted(friend_id: String, friend_name: String)
signal friend_request_declined(requester_id: String)
signal friend_removed(friend_id: String, friend_name: String)
signal friend_blocked(friend_id: String, friend_name: String)
signal friend_unblocked(friend_id: String, friend_name: String)
signal friend_online(friend_id: String, friend_name: String)
signal friend_offline(friend_id: String, friend_name: String)
signal relationship_level_changed(friend_id: String, old_level: int, new_level: int)
func _ready():
"""初始化好友系统"""
load_friends_data()
print("FriendSystem initialized")
## 发送好友请求
func send_friend_request(target_id: String, target_name: String) -> bool:
"""
向指定玩家发送好友请求
@param target_id: 目标玩家ID
@param target_name: 目标玩家名称
@return: 是否成功发送
"""
# 验证输入
if target_id.is_empty() or target_name.is_empty():
print("Invalid target for friend request")
return false
# 检查是否已经是好友
if friends.has(target_id):
print("Already friends with: ", target_name)
return false
# 检查是否已发送过请求
if friend_requests.has(target_id):
print("Friend request already sent to: ", target_name)
return false
# 检查是否被屏蔽
if blocked_users.has(target_id):
print("Cannot send friend request to blocked user: ", target_name)
return false
# 检查好友数量限制
if friends.size() >= max_friends:
print("Friend list is full")
return false
# 检查待处理请求数量
if friend_requests.size() >= max_pending_requests:
print("Too many pending friend requests")
return false
# 创建好友请求
var relationship = FriendRelationship.new(target_id, target_name, "pending")
friend_requests[target_id] = relationship
# 保存数据
save_friends_data()
# 发射信号
friend_request_sent.emit(target_id, target_name)
print("Friend request sent to: ", target_name)
return true
## 接受好友请求
func accept_friend_request(requester_id: String) -> bool:
"""
接受好友请求
@param requester_id: 请求者ID
@return: 是否成功接受
"""
if not friend_requests.has(requester_id):
print("No friend request from: ", requester_id)
return false
var relationship = friend_requests[requester_id]
# 检查好友数量限制
if friends.size() >= max_friends:
print("Friend list is full, cannot accept request")
return false
# 移动到好友列表
relationship.status = "accepted"
friends[requester_id] = relationship
friend_requests.erase(requester_id)
# 保存数据
save_friends_data()
# 发射信号
friend_request_accepted.emit(requester_id, relationship.friend_name)
print("Friend request accepted from: ", relationship.friend_name)
return true
## 拒绝好友请求
func decline_friend_request(requester_id: String) -> bool:
"""
拒绝好友请求
@param requester_id: 请求者ID
@return: 是否成功拒绝
"""
if not friend_requests.has(requester_id):
print("No friend request from: ", requester_id)
return false
var relationship = friend_requests[requester_id]
friend_requests.erase(requester_id)
# 保存数据
save_friends_data()
# 发射信号
friend_request_declined.emit(requester_id)
print("Friend request declined from: ", relationship.friend_name)
return true
## 移除好友
func remove_friend(friend_id: String) -> bool:
"""
移除好友
@param friend_id: 好友ID
@return: 是否成功移除
"""
if not friends.has(friend_id):
print("Not friends with: ", friend_id)
return false
var relationship = friends[friend_id]
friends.erase(friend_id)
# 保存数据
save_friends_data()
# 发射信号
friend_removed.emit(friend_id, relationship.friend_name)
print("Friend removed: ", relationship.friend_name)
return true
## 屏蔽用户
func block_user(user_id: String, user_name: String) -> bool:
"""
屏蔽用户
@param user_id: 用户ID
@param user_name: 用户名称
@return: 是否成功屏蔽
"""
if blocked_users.has(user_id):
print("User already blocked: ", user_name)
return false
# 添加到屏蔽列表
blocked_users[user_id] = Time.get_unix_time_from_system()
# 如果是好友,移除好友关系
if friends.has(user_id):
remove_friend(user_id)
# 如果有待处理的好友请求,移除
if friend_requests.has(user_id):
friend_requests.erase(user_id)
# 保存数据
save_friends_data()
# 发射信号
friend_blocked.emit(user_id, user_name)
print("User blocked: ", user_name)
return true
## 解除屏蔽
func unblock_user(user_id: String, user_name: String) -> bool:
"""
解除用户屏蔽
@param user_id: 用户ID
@param user_name: 用户名称
@return: 是否成功解除屏蔽
"""
if not blocked_users.has(user_id):
print("User not blocked: ", user_name)
return false
blocked_users.erase(user_id)
# 保存数据
save_friends_data()
# 发射信号
friend_unblocked.emit(user_id, user_name)
print("User unblocked: ", user_name)
return true
## 记录互动
func record_interaction(friend_id: String, activity_type: String = "chat") -> void:
"""
记录与好友的互动
@param friend_id: 好友ID
@param activity_type: 活动类型
"""
if not friends.has(friend_id):
return
var relationship = friends[friend_id]
relationship.last_interaction = Time.get_unix_time_from_system()
relationship.interaction_count += 1
# 添加到共同活动
if not activity_type in relationship.shared_activities:
relationship.shared_activities.append(activity_type)
# 检查关系等级提升
_check_relationship_level_up(friend_id)
# 保存数据
save_friends_data()
## 检查关系等级提升
func _check_relationship_level_up(friend_id: String) -> void:
"""
检查并处理关系等级提升
@param friend_id: 好友ID
"""
if not friends.has(friend_id):
return
var relationship = friends[friend_id]
var old_level = relationship.relationship_level
var new_level = _calculate_relationship_level(relationship)
if new_level > old_level:
relationship.relationship_level = new_level
relationship_level_changed.emit(friend_id, old_level, new_level)
print("Relationship level increased with ", relationship.friend_name, ": ", old_level, " -> ", new_level)
## 计算关系等级
func _calculate_relationship_level(relationship: FriendRelationship) -> int:
"""
根据互动数据计算关系等级
@param relationship: 好友关系数据
@return: 关系等级 (1-5)
"""
var level = 1
# 基于互动次数
if relationship.interaction_count >= 10:
level = 2
if relationship.interaction_count >= 50:
level = 3
if relationship.interaction_count >= 100:
level = 4
if relationship.interaction_count >= 200:
level = 5
# 基于共同活动种类
var activity_bonus = min(relationship.shared_activities.size() / 3.0, 1)
level = min(level + activity_bonus, 5)
# 基于关系持续时间(天数)
var days_since_added = (Time.get_unix_time_from_system() - relationship.added_at) / 86400.0
if days_since_added >= 7: # 一周
level = min(level + 1, 5)
return level
## 获取好友列表
func get_friends_list() -> Array[Dictionary]:
"""
获取好友列表
@return: 好友信息数组
"""
var friends_list = []
for friend_id in friends:
var relationship = friends[friend_id]
friends_list.append({
"id": friend_id,
"name": relationship.friend_name,
"status": relationship.status,
"relationship_level": relationship.relationship_level,
"last_interaction": relationship.last_interaction,
"interaction_count": relationship.interaction_count,
"shared_activities": relationship.shared_activities.duplicate(),
"added_at": relationship.added_at
})
# 按关系等级和最后互动时间排序
friends_list.sort_custom(func(a, b):
if a.relationship_level != b.relationship_level:
return a.relationship_level > b.relationship_level
return a.last_interaction > b.last_interaction
)
return friends_list
## 获取好友请求列表
func get_friend_requests() -> Array[Dictionary]:
"""
获取待处理的好友请求列表
@return: 好友请求信息数组
"""
var requests = []
for requester_id in friend_requests:
var relationship = friend_requests[requester_id]
requests.append({
"id": requester_id,
"name": relationship.friend_name,
"requested_at": relationship.added_at
})
# 按请求时间排序(最新的在前)
requests.sort_custom(func(a, b): return a.requested_at > b.requested_at)
return requests
## 获取屏蔽列表
func get_blocked_users() -> Array[Dictionary]:
"""
获取屏蔽用户列表
@return: 屏蔽用户信息数组
"""
var blocked = []
for user_id in blocked_users:
blocked.append({
"id": user_id,
"blocked_at": blocked_users[user_id]
})
# 按屏蔽时间排序(最新的在前)
blocked.sort_custom(func(a, b): return a.blocked_at > b.blocked_at)
return blocked
## 检查是否为好友
func is_friend(user_id: String) -> bool:
"""
检查是否为好友
@param user_id: 用户ID
@return: 是否为好友
"""
return friends.has(user_id) and friends[user_id].status == "accepted"
## 检查是否被屏蔽
func is_blocked(user_id: String) -> bool:
"""
检查用户是否被屏蔽
@param user_id: 用户ID
@return: 是否被屏蔽
"""
return blocked_users.has(user_id)
## 获取好友信息
func get_friend_info(friend_id: String) -> Dictionary:
"""
获取好友详细信息
@param friend_id: 好友ID
@return: 好友信息字典
"""
if not friends.has(friend_id):
return {}
var relationship = friends[friend_id]
return {
"id": friend_id,
"name": relationship.friend_name,
"status": relationship.status,
"relationship_level": relationship.relationship_level,
"last_interaction": relationship.last_interaction,
"interaction_count": relationship.interaction_count,
"shared_activities": relationship.shared_activities.duplicate(),
"added_at": relationship.added_at,
"days_since_added": (Time.get_unix_time_from_system() - relationship.added_at) / 86400.0
}
## 搜索好友
func search_friends(query: String) -> Array[Dictionary]:
"""
搜索好友
@param query: 搜索关键词
@return: 匹配的好友信息数组
"""
var results = []
var search_query = query.to_lower()
for friend_id in friends:
var relationship = friends[friend_id]
if relationship.friend_name.to_lower().contains(search_query):
results.append(get_friend_info(friend_id))
return results
## 获取在线好友
func get_online_friends(online_characters: Array[String]) -> Array[Dictionary]:
"""
获取当前在线的好友列表
@param online_characters: 在线角色ID数组
@return: 在线好友信息数组
"""
var online_friends = []
for friend_id in friends:
if friend_id in online_characters:
online_friends.append(get_friend_info(friend_id))
return online_friends
## 处理好友上线
func handle_friend_online(friend_id: String) -> void:
"""
处理好友上线事件
@param friend_id: 好友ID
"""
if friends.has(friend_id):
var relationship = friends[friend_id]
friend_online.emit(friend_id, relationship.friend_name)
print("Friend came online: ", relationship.friend_name)
## 处理好友下线
func handle_friend_offline(friend_id: String) -> void:
"""
处理好友下线事件
@param friend_id: 好友ID
"""
if friends.has(friend_id):
var relationship = friends[friend_id]
friend_offline.emit(friend_id, relationship.friend_name)
print("Friend went offline: ", relationship.friend_name)
## 保存好友数据
func save_friends_data() -> void:
"""保存好友数据到本地文件"""
var data = {
"friends": {},
"friend_requests": {},
"blocked_users": blocked_users
}
# 序列化好友数据
for friend_id in friends:
var relationship = friends[friend_id]
data.friends[friend_id] = {
"friend_name": relationship.friend_name,
"status": relationship.status,
"added_at": relationship.added_at,
"last_interaction": relationship.last_interaction,
"relationship_level": relationship.relationship_level,
"interaction_count": relationship.interaction_count,
"shared_activities": relationship.shared_activities
}
# 序列化好友请求数据
for requester_id in friend_requests:
var relationship = friend_requests[requester_id]
data.friend_requests[requester_id] = {
"friend_name": relationship.friend_name,
"status": relationship.status,
"added_at": relationship.added_at
}
var file = FileAccess.open(friends_file_path, FileAccess.WRITE)
if file:
var json_string = JSON.stringify(data)
file.store_string(json_string)
file.close()
print("Friends data saved")
else:
print("Failed to save friends data")
## 加载好友数据
func load_friends_data() -> void:
"""从本地文件加载好友数据"""
if not FileAccess.file_exists(friends_file_path):
print("No friends data file found, starting fresh")
return
var file = FileAccess.open(friends_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:
var data = json.data
# 加载好友数据
if data.has("friends"):
for friend_id in data.friends:
var friend_data = data.friends[friend_id]
var relationship = FriendRelationship.new(friend_id, friend_data.friend_name, friend_data.status)
relationship.added_at = friend_data.get("added_at", Time.get_unix_time_from_system())
relationship.last_interaction = friend_data.get("last_interaction", relationship.added_at)
relationship.relationship_level = friend_data.get("relationship_level", 1)
relationship.interaction_count = friend_data.get("interaction_count", 0)
relationship.shared_activities = friend_data.get("shared_activities", [])
friends[friend_id] = relationship
# 加载好友请求数据
if data.has("friend_requests"):
for requester_id in data.friend_requests:
var request_data = data.friend_requests[requester_id]
var relationship = FriendRelationship.new(requester_id, request_data.friend_name, request_data.status)
relationship.added_at = request_data.get("added_at", Time.get_unix_time_from_system())
friend_requests[requester_id] = relationship
# 加载屏蔽数据
if data.has("blocked_users"):
blocked_users = data.blocked_users
print("Friends data loaded: ", friends.size(), " friends, ", friend_requests.size(), " requests, ", blocked_users.size(), " blocked")
else:
print("Failed to parse friends data JSON")
else:
print("Failed to open friends data file")
## 获取统计信息
func get_statistics() -> Dictionary:
"""
获取好友系统统计信息
@return: 统计信息字典
"""
var level_counts = {}
var total_interactions = 0
for friend_id in friends:
var relationship = friends[friend_id]
var level = relationship.relationship_level
level_counts[level] = level_counts.get(level, 0) + 1
total_interactions += relationship.interaction_count
return {
"total_friends": friends.size(),
"pending_requests": friend_requests.size(),
"blocked_users": blocked_users.size(),
"total_interactions": total_interactions,
"level_distribution": level_counts,
"max_friends": max_friends,
"max_pending_requests": max_pending_requests
}