GameDevMind 游戏社交系统实战:基于 Python 的好友、聊天频道与在线状态设计

GameDevMind 游戏社交系统实战:基于 Python 的好友、聊天频道与在线状态设计 GameDevMind 游戏社交系统实战基于 Python 的好友、聊天频道与在线状态设计【免费下载链接】GameDevMind最全面的游戏开发技术图谱(Game Development Map)。帮助游戏开发者们在已知问题上节省时间省出更多的精力投入到更有创造性的工作中去。项目地址: https://gitcode.com/GitHub_Trending/ga/GameDevMind导读本文以 GameDevMind 仓库中 社交系统配套代码 为主线系统讲解游戏社交系统中好友关系、聊天频道、在线状态、未读计数与屏蔽机制的设计与实现。阅读完本文你将掌握一套纯标准库、可直接运行的游戏社交系统最小实现理解双向好友关系Pending/Friend/Blocked的状态机、多频道消息的存储与未读计数、五种在线状态的语义以及屏蔽即隔离的社交安全策略并能把同一套思路迁移到 C#/C 游戏服务端的真实项目中。该示例属于 GameDevMind 六大能力中研发能力 → 业务层功能的社交系统模块与其配套的知识图谱文档 3.3.3.综合业务层功能.md 中好友系统聊天系统章节一一对应是图谱理论 → 可运行代码的落地示范。一、系统概览四个 Manager 与一个关系模型1.1 文章章节与代码的对应关系配套代码 README.md 明确说明对应文章为三-06 游戏社交系统正文只保留 4 个 Manager 骨架约 50 行 C#完整实现由 Python 版本 social_system.py 承载。章节覆盖如下系统代码载体核心能力好友系统SocialManager好友相关方法请求/接受/删除好友FriendRelation双向关系聊天系统ChatManager多频道缓存敏感词过滤ChatFilter公会系统文章章节创建/申请/审批/捐献GuildRole职位权限组队系统文章章节邀请/准备/开副本队长权限校验社交关系SocialManager.block_user等黑名单、好友的好友推荐其中好友 聊天 在线状态是当前 Python 示例实际落地的部分可运行演示公会/组队在文章正文中以 Manager 骨架形式覆盖本文第 5 节会结合知识图谱与实战经验给出设计要点。1.2 顶层结构从 social_system.py 源码结构看系统由三层组成枚举与数据模型层OnlineStatus在线状态、FriendStatus好友关系状态、ChannelType频道类型、FriendRelation好友关系、ChatMessage聊天消息管理器层ChatManager聊天管理、SocialManager统一社交入口演示层main()串联注册→好友→状态→聊天→屏蔽→删除的完整流程。SocialManager是所有社交功能的统一门面内部聚合了用户表、好友关系表和聊天管理器这种一个 Facade 管理多个子系统的结构与服务端社交服务模块的设计思路一致。二、好友系统双向关系状态机2.1 三种状态的设计好友关系用 FriendStatus 枚举表达class FriendStatus(Enum): NONE 无关系 PENDING 待确认 # A→B 发出申请 FRIEND 好友 BLOCKED 已屏蔽好友关系不是单向的我加了你而是双向关系FriendRelation 同时记录user_a与user_b并用initiator记录申请发起方、since记录关系建立时间。other(name)方法用于从任意一方视角取回另一方dataclass class FriendRelation: user_a: str user_b: str status: FriendStatus FriendStatus.NONE initiator: str # 谁发出的申请 since: float 0.0 def other(self, name: str) - str: return self.user_b if name self.user_a else self.user_a2.2 状态流转与防重入校验申请、接受、删除、屏蔽四步操作构成了完整的状态机关键实现细节如下发送申请add_friend_requestdef add_friend_request(self, from_user: str, to_user: str) - bool: if from_user not in self.users or to_user not in self.users: print(f❌ 用户不存在); return False if from_user to_user: print(f❌ 不能添加自己); return False key self._relation_key(from_user, to_user) if key in self.relations: rel self.relations[key] if rel.status FriendStatus.FRIEND: # 已经是好友 return False if rel.status FriendStatus.BLOCKED: # 已被屏蔽 return False if rel.status FriendStatus.PENDING: # 已有待确认申请 return False ...这里沉淀了四个实战校验点用户存在性校验、禁止添加自己、屏蔽隔离BLOCKED 状态下申请直接被拒、重复申请防抖。特别是屏蔽后无法发送好友申请这一条是社交安全的核心——被拉黑方永远无法通过好友申请通道骚扰对方。关系索引技巧_relation_key(a, b)返回(a, b) if a b else (b, a)即按字典序归一化后作为字典键。这样无论从 A 视角还是 B 视角访问同一条关系都能命中同一个键天然规避了关系方向不一致的问题——这是双向关系存储的关键实现细节。接受申请accept_friend除了状态校验还要求rel.initiator requester防止接受一个根本不存在于申请方向上的关系接受成功后自动向双方发送系统通知消息self.chat.send(ChannelType.SYSTEM, requester, 系统, f{accepter} 已接受你的好友申请) self.chat.send(ChannelType.SYSTEM, accepter, 系统, f你和 {requester} 成为了好友)这是好友系统与聊天系统联动的示范社交动作产生系统消息通过 SYSTEM 频道投递不需要单独的推送通道。删除好友remove_friend要求关系处于FRIEND状态直接del从关系表移除屏蔽block_user则会先删除已有关系再写入BLOCKED状态实现屏蔽优先于一切旧关系。2.3 好友列表与待处理申请查询get_friends 遍历关系表命中FRIEND状态且包含当前用户的关系通过rel.other(user)取回对方并排序get_pending_requests 则额外用rel.initiator ! user排除自己发起的申请只返回别人申请我的待确认列表。打印好友列表时还会带上对方的实时在线状态print_friend_list这是好友列表 在线状态组合展示的典型实现。知识图谱佐证综合业务层功能.md 对好友系统的要求是好友关系好友添加、删除、列表、状态匹配好友好友推荐、搜索、匹配算法好友数据库好友同步好友权限管理好友分组、好友备注、好友黑名单、好友推荐。当前示例落地了其中的关系管理主线分组/备注/推荐可作为扩展方向。三、聊天系统多频道缓存与未读计数3.1 五种频道类型ChannelType 定义了五种频道class ChannelType(Enum): WORLD 世界 TEAM 队伍 GUILD 公会 WHISPER 私聊 SYSTEM 系统与知识图谱 3.3.3.综合业务层功能.md 中频道点对点私聊通道、消息加密、离线消息广播世界频道、公会频道、队伍频道的划分完全对应WORLD/GUILD/TEAM是广播类频道WHISPER是点对点频道SYSTEM用于系统通知投递。3.2 频道缓存的数据结构ChatManager 用两层字典管理消息class ChatManager: MAX_HISTORY 100 # 每频道最多保留 def __init__(self): self.channels: dict[tuple[ChannelType, str], list[ChatMessage]] defaultdict(list) self.unread: dict[str, dict[tuple[ChannelType, str], int]] defaultdict( lambda: defaultdict(int))channels以(频道类型, 频道ID)为键channel_id是世界频道的global、私聊频道的对方用户名等实现世界只有一个频道、私聊每人一个频道的统一寻址unread以用户名 → (频道, 频道ID) → 未读数的三级结构为每个用户每个频道维护独立的未读计数。3.3 消息发送与历史裁剪send 生成带uuid短 ID 和时间戳的ChatMessage追加到频道并通过MAX_HISTORY 100做环形裁剪超出 100 条丢弃最旧的msg ChatMessage( idstr(uuid.uuid4())[:8], channelchannel, channel_idchannel_id, sendersender, contentcontent, ) key (channel, channel_id) self.channels[key].append(msg) if len(self.channels[key]) self.MAX_HISTORY: self.channels[key] self.channels[key][-self.MAX_HISTORY:]这正好对应知识图谱中历史聊天数据通常游戏不会长期保存实现消息缓存、清理、查询的要求——get_history 按limit取最近 N 条默认 20 条模拟了客户端拉取最近消息的场景。未读计数设计发送时注释明确频道以 channel_id 标识私聊 channel_id 是对方名即私聊消息写入接收者名下的频道后接收方即可通过get_unread_count感知新消息mark_read 将对应频道未读数清零。这是红点提示/未读角标的最小实现。3.4 私聊与世界频道的封装SocialManager 对外只暴露两个简洁接口def send_whisper(self, sender: str, receiver: str, content: str): if sender receiver: print(❌ 不能给自己发私聊); return self.chat.send(ChannelType.WHISPER, receiver, sender, content) def send_world(self, sender: str, content: str): self.chat.send(ChannelType.WORLD, global, sender, content)注意私聊时channel_id填的是接收者名字receiver这样接收方用show_channel(ChannelType.WHISPER, 自己的名字)就能读到别人发给自己的消息——频道寻址即收件箱寻址省去了额外的路由表。四、在线状态与屏蔽机制4.1 五种在线状态OnlineStatus 定义了五种状态覆盖了主流游戏的在线语义class OnlineStatus(Enum): ONLINE 在线 BUSY 忙碌 AWAY 离开 INVISIBLE ⚫ 隐身 OFFLINE ⭕ 离线set_status 支持运行时切换状态并打印变更日志get_status 对未注册用户返回OFFLINE兜底。状态与好友列表联动好友列表展示的正是对方的当前状态见print_friend_list。INVISIBLE隐身在真实产品中通常还伴随对非好友隐藏在线的可见性控制示例中保留了状态位可见性策略可按产品需求扩展。4.2 屏蔽社交隔离的强制手段屏蔽的实现block_user有两个关键动作先清旧关系如果两人此前有好友/待确认关系先删除再写入 BLOCKED建立一条单向语义的屏蔽关系。随后在add_friend_request中只要检测到BLOCKED状态就直接拒绝已被屏蔽从而形成完整的闭环屏蔽 → 无法发送好友申请 → 无法通过好友通道骚扰。main()演示中Dave尝试添加已被其屏蔽的Alice为好友结果即为被拒绝。实战延伸SLG 样例文档 游戏研运资产样例-SLG手游2D.md 指出社交系统中除好友/黑名单外还应考虑仇敌标记、坐标书签、战报分享等与玩法绑定的社交动作以及邮件系统系统邮件、战报邮件、资源领取邮件附件有效期通常 7–30 天。黑名单是其中防御性的一环与聊天频率风控、敏感词过滤共同构成社交安全三件套。五、可扩展设计公会、组队与推荐文章骨架解读关联文档 README.md 的文章章节覆盖列出了正文中另两个 Manager 骨架这里结合知识图谱给出其设计要点便于读者在现有代码上继续扩展5.1 公会系统GuildManagerGuildRole创建/申请/审批创建公会校验名称唯一与人数上限玩家申请入会后由会长/官员审批与好友申请的PENDING → FRIEND状态机同构捐献公会捐献产出公会资金与个人贡献值属于资源流转型社交需要独立的贡献值账本职位权限GuildRole会长/官员/成员等用权限位表达审批入会、发布公告、开除成员、开启公会战等操作的允许集合实现上是角色 → 权限掩码 → 操作校验三层。5.2 组队系统TeamManager邀请/准备/开副本队长发起邀请成员进入队伍后准备就绪全员就绪才能开启副本队长权限校验踢人、解散、更换队长等操作前必须校验is_leader与公会职位校验共用同一套权限思路队伍频道组队场景天然与ChannelType.TEAM频道打通队员间的战术沟通走队伍频道即可复用ChatManager。5.3 社交关系扩展好友的好友推荐以现有关系图做一跳邻居推荐公式为共同好友数 你的好友 ∩ 对方的好友可基于当前get_friends结果两两求交集实现未读计数的产品化unread三级结构与客户端红点直接对应可进一步增加按频道汇总总数接口用于主界面角标。5.4 从原型到生产性能与安全考量知识图谱 3.3.3.综合业务层功能.md 对聊天系统的生产要求还包括敏感词过滤DFA确定性有限自动机或 Trie 树构建敏感词库实时过滤并输出替换文本与过滤日志当前示例中的ChatFilter骨架即对应此模块防刷屏发言频率限制、冷却时间、刷屏检测、自动禁言消息同步广播频道世界/公会/队伍需要消息队列 实时推送点对点私聊需考虑离线消息与消息加密容量策略历史聊天数据通常不长期保存用缓存 定期清理 按需查询示例中MAX_HISTORY 100正是该策略的代码化表达。六、运行与验证6.1 运行演示示例使用 Python 3 纯标准库dataclasses、enum、collections、time、uuid无任何第三方依赖直接运行python3 social_system.pymain()social_system.py#L289-L353按六个步骤串联全部功能输出示例节选 Alice 注册成功 (Lv.50) Alice → Bob 好友申请已发送 ✅ Bob 和 Alice 成为好友 Alice 的好友列表 (2): 忙碌 Bob 离开 Cathy [世界频道] ── [世界] 最近 3 条消息 ── [07:xx:xx] [世界] Alice: 有人组队下副本吗 Alice 屏蔽了 Dave Dave 尝试添加 Alice 好友: 被拒绝 Alice 删除了好友 Bob ✅ 社交系统演示完成6.2 验证清单功能点预期行为重复申请第二次add_friend_request返回 False已有待确认申请添加自己返回 False不能添加自己屏蔽后申请被屏蔽方申请返回 False已被屏蔽未读计数私聊后接收方get_unread_count 0mark_read后归零频道裁剪频道消息超过 100 条时仅保留最近 100 条在线状态切换set_status后好友列表展示新状态6.3 迁移到 C# / C 服务端关联文档 README.md 说明正文为 C# 骨架仓库中还提供了 C# 与 C 的同类示例可对照学习C# 对象池示例gamedevmind/1.基础能力/1.1.3.C#语言/object_poolC 设计模式示例gamedevmind/1.基础能力/1.2.1.设计模式/。迁移时的核心等价映射为PythonEnum→ C#enum/ Cenum classdataclass→ C#class/recorddefaultdict→Dictionary初始化默认值时间戳time.time()→DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()。七、总结本文通过 GameDevMind 的 社交系统配套代码 完整走通了游戏社交系统的核心链路好友关系双向关系模型 NONE/PENDING/FRIEND/BLOCKED状态机用字典序键归一化解决双视角同一条关系问题聊天频道(频道类型, 频道ID)统一寻址 环形历史裁剪 三级未读计数覆盖世界/队伍/公会/私聊/系统五类频道在线状态五种状态枚举与好友列表联动展示屏蔽机制删旧关系 写入 BLOCKED 申请拦截形成完整的社交隔离闭环。该示例与仓库知识图谱 3.3.3.综合业务层功能.md 中的好友/聊天章节、以及 SLG 实战样例 游戏研运资产样例-SLG手游2D.md 中的社交系统设计相互印证原型代码解决怎么实现图谱解决要考虑什么两者结合即可快速产出一个结构清晰、可平滑迁移到服务端语言C#/C的社交系统雏形。【免费下载链接】GameDevMind最全面的游戏开发技术图谱(Game Development Map)。帮助游戏开发者们在已知问题上节省时间省出更多的精力投入到更有创造性的工作中去。项目地址: https://gitcode.com/GitHub_Trending/ga/GameDevMind创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考