游戏好友系统与邮件系统实现
游戏好友系统与邮件系统实现
好友系统实现:
每个玩家在内存上都会有⾃⼰的⼀个map记录他的好友信息。
这个结构体⼤致如下:
struct FriendData
{
uint32_t rid;
//⽬前我们之间的状态
uint32_t status;
//记录对⽅的data
uint32_t peerRid;
uint32_t peerName;
uint32_t peerLevel;
uint32_t peerVip;
....
....
};
map<uint32_t, FriendData> m_myFriend;
假设A玩家添加了B玩家位他的好友,那么除了A玩家的内存上要增加B玩家的数据外,B玩家也应该会有A玩家的数据。
⼀个好的设计原则是:彼此不操作对⽅的内存数据。
从内存上的实现会需要以下⼏个静态变量(只需要⼀份即可):
//发送好友申请的玩家数据,这样对⽅同意好友申请的时候才知道发起者的数据
struct RequestSenderInfo
{
//发起好友请求的玩家的数据
uint32_t rid;
string name;
uint32_t level;
...
...
};
//我⽬前收到的好友申请
static map<uint32_t, vector<RequestSenderInfo>> m_applyList;
/
/我发起的好友申请后收到的回应,其中FriendData就是回应者的数据;
static map<uint32_t, vector<FriendData>> m_responseList;
//我⽬前收到的好友删除申请。
static map<uint32_t, vector<uint32_t>> m_deleteList;
假设A玩家给B玩家发起了⼀条好友申请:
1.A玩家会操作m_applyList,将B玩家的Rid作为Key,打包⾃⼰A玩家的数据放⼊m_applyList中;
2.B玩家通过定时器或者前端请求的⽅式去查m_applyList知道B玩家有了好友申请。
  1.B玩家拒绝A玩家的好友申请:B玩家会操作m_responseList以A玩家作为Key,将拒绝的结果打包在FriendData的status中放
⼊m_responseList;
  2.B玩家同意A玩家的好友申请:B玩家会操作m_responseLIst以A玩家作为Key,将⾃⼰B玩家的数据和同意的结果打包进FriendData中放⼊m_responseList
好听的游戏id
3.A玩家通过定时器或者前端请求的⽅式去查m_responseList知道了B玩家的是接受还是拒绝,以此来是否将B玩家放⼊⾃⼰
的m_myFriend中;
当B玩家从好友列表中删除A玩家后:
1.B玩家会操作m_deleteList,以A玩家的Rid为Key,将⾃⼰B玩家的Rid放⼊m_deleteList中;
2.A玩家通过定时器或者前端请求的⽅式去查m_deleteList发现了B玩家删除了⾃⼰,⾃⼰A玩家也从m_myFriend中删除B玩家。
以上就是好友系统的内存操作,简洁明了。A玩家不操作B玩家的内存数据,同理B玩家也不操作A玩家的内存数据,因此⽆需关⼼对⽅的数据是否已经从数据库载⼊内存;
数据库表的结构如下:
当B玩家同意好友的时候往数据库写两条数据。
⼀条是A玩家中B玩家的数据,⼀条是B玩家中A玩家的数据。这个设计感觉不是特别好,但是⽬前没有想出特别好的⽅法;
邮件系统实现:
邮件系统的实现有⼏个问题需要解决:
⼀、邮件Id的唯⼀性
⼆、如果每个玩家的内存单独维护⼀个邮件Id。就会遇到⼀个问题:排⾏榜发奖的时候,如果玩家的数据不在内存上,如何知道这个玩家邮件的Id。就要存在Load这个玩家档的情况。
三、全服邮件如何发给每⼀个玩家
我的实现是:普通邮件采⽤全服唯⼀邮件mailId的形式。系统邮件采⽤另⼀个全服唯⼀邮件sysMailId的形式。
系统邮件在数据库的存储位置是:以rid=服务器id的形式分数据库、指定sysMailId字段的形式存储到数据库表内;
数据结构设计为:
struct DataMail
{
uint32_t rid
uint32_t mailId;
uint32_t sysMailId;
uint32_t readTs;
uint32_t sendTime;
char send[19];
char title[100];
char text[512];
char attachments[512];
};
static uint32_t nextSysMailId;
static vector<DataMail> vSystemMail;
static uint32_t nextMailId;
map<uint32_t, DataMail> m_userMail;
对于问题⼀如何做到全服唯⼀的普通邮件mailId:
进程⼀启动的时候不可能加载本服所有邮件然后对最后⼀封邮件mailId++的形式来拿到最⼤的mailId;因此会在另⼀个表Attr表内rid=本服Id 且type=xx存⼀个nextMailId,每个玩家在新增⼀封邮件的时候都会修改这个值。
如果发的是普通邮件(玩家通关某个关卡),会设置Rid、mailId且sysMailId=0存⼊数据库中;
如果普通邮件的发放玩家不在内存上时,由于普通邮件采⽤的是全服唯⼀的mailId,因此依然能指定Rid和mailId存⼊数据库内;
如果通过后台发的是全服(更新补偿、服务器异常补偿)邮件,会单独将rid设置为本服(例如1服为1),mailId和sysMailId相等存到数据库中;
玩家如何拿到这份全服邮件:
玩家登录Load档完⾃⼰邮件的数据以后会遍历系统邮件,判断⾃⼰是否有sysMailId的邮件,如果没有则⾛普通邮件的流程给⾃⼰的数据库表中添加⼀封邮件;
邮件数据库表的设计结构为:

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。