zoukankan      html  css  js  c++  java
  • 游戏好友系统

    最近实现了游戏好友系统。第一次按照自己的方法实现,觉得代码有些冗余,估计是思路问题。特在此记录,一是为了以后维护,二是向和我一样没有啥经验的程序员提供一个思路,更希望大家不吝赐教提供更好的设计思路。

    需求:

    1. 添加好友

      a)根据当前玩家等级获取10个正负20级其他玩家列表

      b)  获取的其他玩家最近一次登录时间不得大于1天

      c)当其他玩家列表内玩家数量<10,则放松筛选条件

      d)获取其他玩家列表,推送至玩家添加好友UI

      e)玩家点击申请向申请玩家发送添加好友请求

      f) 玩家可以对列表内其他玩家1键全部申请添加

      g)被申请玩家同意后该好友添加成功,若对方拒绝不返回信息

      h)每个玩家应有1个ID

      i)A玩家知道B玩家ID,A玩家可通过ID直接向B玩家发送添加好友请求

    1. 申请列表

      a)当其他玩家申请与当前玩家成为好友时,该玩家信息出现至申请列表

      b)同意与该玩家成为好友,则该玩家移至当前玩家好友列表且申请列表内清除该玩家信息

      c)拒绝与该玩家成为好友,则申请列表内清除该玩家信息

      d)玩家可以对申请列表内玩家1键全部同意添加

      e)玩家可以对申请列表内玩家1键全部拒绝添加

    1. 好友列表

      a)与当前玩家已成为好友的其他玩家刷新在此列表

      b) 好友之间可以送心

      c)玩家A向玩家B送心则玩家B可在好友列表内领取玩家A送的心

      d)当前玩家可以向其拥有的所有好友1键送心

      e)当前玩家可以1键收取其好友送的心

      f)每日可领取的心数量有上限

     

    我的设计思路:

      我是按照"请求-回答"的形式设计,将用户的操作分为请求和对请求的回答。

      请求:添加好友                         回答:接受 , 拒绝

      请求:好友送心                         回答 :领取 , 不领取(过时心自动消失)

      每种请求被设计成一个消息,例如:A 在 某时 向 B 发送了一条 申请好友 的请求,这时,当服务器收到这个协议后,封装一封消息,并插入到数据库,数据库字段如下:

      表项: id , fromid , toid , msgtype , isread , srecvtime.  ( msgtype:我将每个操作分类,如1就是申请好友 , isread:表示申请的对象是否对此作出了回应,无论是同意或是拒绝都会对此作出回应,即将isread 置为1,

                                  srecvtime:服务器收到的时间 )

      例如: id 为  1 的用户向 2发送了申请好友请求 , 则会记录 1 , 1 , 2 , 1 (申请) , 0(还未被确认) , 1446454554(收到消息的时间)

      但要说明的是,若此时B在线则这条消息将由B插入数据库,表示B收到了一条来自A的申请好友的消息,并在自己的 被申请列表 中将A的ID加入 ,若B不在线,则该记录由A插入,表示A向B申请好友,并在自己的    已申请好友列表中将B的ID加入。 当B看到这条消息时,B会对此进行回复 , 接受或者拒绝 , 这两个操作都是对A发出的申请的回复 , 此时若 A 还在线 , 则B会在服务器内部向A发送消息,“我同意或拒绝你的请 求” , 则A会将之前自己的申请记录中的isread 标记为1,表示这条申请已经作废。同时,若是收到同意的消息 , 则A会在数据库中插入记录表明A和B已经是好友; 若此时A不在线了 , 则对A的申请记录作出回应的操  作由B完成,即B将isread置为1,表示B拒绝A的好友请求。 此时u_friendmsg(用于记录消息的表)中有一条记录: 1 , 1 , 2 , 1 (申请) , 1(被确认) , 1446454554(收到消息的时间) ,此时由于isread = 1 表示这条消息已经被确认。若B同意A的请求则u_friend中会有记录,表明两者一是好友关系。那么B是如何判断要对哪条记录作出回应的呢,这里可以根据id字段,和srecvtime字段。

      这种方式下,当我需要好友列表的时候,直接搜索u_friend 中 friendid( id , uid , friendid , ... ) 字段便可,当需要申请列表时,搜索u_friendmsg中"toid"为当前用户id并且"isread"字段为0(未处理)的记录即可。

      由于目前在使用 "skynet"(当前阶段,仅限使用,惭愧) , 简单说一下申请好友,拒绝或同意的过程:

      1.A 在线 , 在搜索好友或在推荐列表中申请某个玩家B后,这是A在服务端的数据变化为 A维护的一个已申请好友列表(申请其他人)中添加上B的ID,并创建一条消息,内容如上所述。

      2.此时B有在线和不在线两种可能。若B在线,则将这条消息发送到B处理,这是B将这条消息插入数据库,并B自己的“被申请”列表中加上A的ID。若B不在线则有A向数据库插入这条消息。当B在上线后搜索u_friendmsg中toid为自己的并且isread = 0的记录,便可得到自己的申请列表(被申请)

      3.B对这条申请有两个选择,拒绝或接受。若A请求时B在线且拒绝了A的请求,此时B向A发送一条消息,告诉A我拒绝你的申请,则A若此时仍在线的话,便会将之前的申请列表中移除B的ID,并且对自己之前的请求操作进行确认,即把 isread 改为1。若A不在线,则由B来完成确认操作,并将A的    ID,从自己的被申请列表中移除;若B接受了好友请求 , B首先在自己的好友列表中加入A的ID,此时若A在线的话,便将消息发给A告诉A我接受你的申请,此时A若在线,便对之前的消息进行确认,并在自己的好友列表中加入B的ID,并向u_friend中插入记录两条记录( 1 , 1 , 2 ...) , ( 2 , 2 ,    1 )表示已经是好友 ,若A此时不在线,插入好友和确认的操作由B进行。剩下送心和接受心的操作过程大体类似

        skynet中判断是否在线的方法很多,我们是在用户登录的时候,在datacenter中注册此用户,在离线的时候删除,这样通过调用 dc.set{ userid = 1 ,...} , dc.get( 1 )操作来判断用户此时是否在线并获取其数据。

      由于操作不一定实时,因此很可能出现A申请好友,B在几天后才看到,所以服务器发送给客户端的数据中有个专门的时间字段(srecvtime)来标示记录,也就是,这个字段由服务器下发,当B接受申请的时候,向服务器发送数据时要把这个时间标识再传回来,我不清楚这样做是否合适。请高手指教。

      思路是这样,代码感觉还需优化,过几天再贴,希望能对像我这样的新手带来帮助。待续。。。。

      

      

  • 相关阅读:
    Linux-exec族函数
    Linux-竟态初步引入
    Linux-waitpid介绍
    Java基础:Java运算符:算术运算符
    Java中的算术运算符
    JAVA冒泡排序
    引用 java的一些基本概念
    Tomcat服务器的下载安装跟基本配置
    Tomcat配置Web站点
    Tomcat+JSP经典配置实例
  • 原文地址:https://www.cnblogs.com/newbeeyu/p/5253178.html
Copyright © 2011-2022 走看看