开发笔记:游戏中的好友系统

挺久没更新文章了,这一年以来个人经历了许多事情,去年下半年开始稳定下来了,但今年初始又赶上疫情,公司的项目进度也推迟了,现在好不容易复工,登录了许久不上的博客,发现自己收到了很多新的关注和私信,也有很多网友表达了对自己文章的支持,在这里先表达自己的感谢。其次对于一些网友询问的问题,在这里统一回复下:之前那一系列对于英雄远征源码分析的文章质量其实不高,各位随便看看就行了...至于交流,本人工作经验尚浅,不是什么大神,就不打扰浪费大家时间了...至于上一篇英雄远征的Erlang源码,有时间会重新整理一遍,附加一些运行说明,确保都能跑起来。

闲话不多说了,最近在参与公司的新项目,对涉及到好友系统的部分有一些自己的理解和疑惑,在此随手记录一下

确认几个前提:
    游戏中每个玩家是一个语言级别的轻量级的进程,A进程要给B进程发送消息需要使用语言层面的RPC调用。
    玩家的好友数据保存在数据库和内存缓存中。
    离线事件:有专门的离线事件管理进程,当给离线玩家派发一个事件(比如有人给其发送了好友申请),进程会将事件先进行保存(数据库,缓存),玩家上线时通过离线事件管理进程取出,并执行其中的操作(收到该好友申请)。

保存的好友结构:
    好友列表
    临时好友列表
    申请列表
    黑名单列表
    
先抽出一个最简单的过程:
    添加好友:A向B申请好友,B收到A的申请,弹出“XXX请求添加你为好友 确认 拒绝”,B点了确认,则A出现在了B的好友列表中,B自己也被添加到了A的好友列表
    删除好友:A把B从好友列表删除,则A自己也从B的好友列表消失了
    黑名单:不再赘述
    这些操作在对方离线的时候也是可执行的。
    
加好友过程:
    A申请B:A向B发送申请请求,B收到请求后将A放入申请列表
    B同意A:B向A发送同意信息,将A从申请列表中删除,放入临时好友列表
    B拒绝A:B向A发送拒绝信息,将A从申请列表中删除
    A收到B的同意:A自动向B发送确认同意信息,将B放入好友正式列表
    B收到A的确认:B将A放入好友正式列表
    
    有点像TCP三次握手
    (1)A -> B:请求好友(请求建立连接)
    (2)A <- B:同意好友(同意建立连接)
    (3)A -> B:确认好友(确认建立连接)
    
    中间任一个阶段条件检查未通过都不能成功加好友
    条件检查涉及几个地方:目标玩家是否存在,自己的好友列表是否已满,对方的好友列表是否已满,是否已经建立关系,是否被拉黑
    
    需要进行条件检查的地方:A给B发申请前;B收到申请时;B给A回复同意时;A给B发送确认时;B收到A的确认时。
    
    其中每个阶段,任一方都有可能离线,需要进行离线事件的处理
    
    在线的情况:
    A向B发出申请时,B将A放入申请列表。
    B选择同意好友,将A从申请列表中删除,同时加入自己的临时好友列表(因为A那边没确认),给A发出同意信息
    A给B发出确认添加好友的信息,B收到A的确认信息后不用再回复,只要把A从临时列表删除,加入到好友列表中即可。
    
    离线的情况:
    一个原则:任一玩家无法修改其他离线玩家的数据。
    A向B发出申请,B离线,给B发离线事件,A下线。
    B上线,取出离线事件,把A加入申请列表;同意A的申请,把A从申请列表删除,加入自己的临时列表。此时A离线,但又不能让B等待A返回的确认结果(玩游戏的时候确实没等),于是决定让离线进程代替A进行确认的判断,把加好友的数据写入离线进程,给B返回确认的结果。等A上线后从离线进程取出离线期间加好友的数据,再写回给A。
    离线进程/A在线,返回了确认的结果但B离线(刚同意完以很快的速度下线了,或者网比较卡),给B发同意的离线事件。
    B上线,取出离线事件,把A从临时列表删除,加入正式的好友列表。
    
也有直接使用公共缓存保存好友数据的方式,每次好友关系的变动无论对方是否在线都只需要修改公共缓存,缓存定期同步到数据库中。离线转换为在线状态时,只需要从公共缓存中加载自己的好友数据。
    
删除好友步骤(双向):
    A想删掉B,此时先把B从好友列表删除。
    如果B在线,则把B列表中的A删除;如果B离线,则给B派发离线事件,等B上线把A从B的好友列表中删除
    
黑名单步骤(单向):
    A拉黑B,直接把B加入黑名单列表中。
    
推荐好友列表:
    随便随机几个
    
极端情况考虑:
    现在我们有三个人:A,B和C,
    情况1:A和B同时向C发出申请,但C只有一个好友位置
        此时C首先同意了A的申请,将A加入自己的好友列表,同时C的好友列表已满,则C无法再同意B的申请。需要在C同意B时对C的好友列表进行检查。是需要在同意阶段(2)检查被申请方的好友列表长度。
        
    情况2:A向B发出申请,B向C发出申请,但B只有一个好友位置
        若B先同意了A发出的申请,则C无法再同意B的申请。是需要在确认阶段(3)对申请方好友列表长度进行检查。
        若C先同意了B的申请,则B无法同意A的申请。是需要在同意阶段(2)检查被申请方的好友列表长度。
        
    情况3:A申请B,B申请C,C申请A,此时每个人都是只有一个好友列表
        其实也没那么复杂:若B同意了A,则C无法同意B,A无法同意C。需要在好友确认阶段(3)检查申请方好友列表长度,在同意阶段(2)检查被申请方好友列表长度。
        
    情况4:A向B申请了,B也向A申请了
        此时A和B都在相互的申请列表中,申请过程中只要做好是否已经是好友的检查问题应该不大。
        
    要防止超出好友列表长度,只需要在同意阶段(2)检查被申请方好友列表长度,确认阶段(3)检查申请方好友列表长度即可。不过考虑实际需求变化和保险起见,最好能想到的地方都加上相关检查。
    
几个疑问:
    参考了一些网络上的文章,好友系统的设计只有两个步骤:请求好友(1)和同意好友(2),那么本文中的第三个步骤确认好友(3)是否是多余的,正如TCP的三次握手,如果涉及到“确认”这一步,可能会掉入A给B发送消息,B给A发送确认消息,A给B发送确认消息的确认...一种循环中,而如果将TCP三次握手中的第三次去掉的话,影响会和好友系统中去掉确认好友(3)步骤一样吗。说到底,拿添加好友的过程类比TCP三次握手是否恰当...
    
    ...

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值