游戏好友系统
最近實現了游戲好友系統。第一次按照自己的方法實現,覺得代碼有些冗余,估計是思路問題。特在此記錄,一是為了以后維護,二是向和我一樣沒有啥經驗的程序員提供一個思路,更希望大家不吝賜教提供更好的設計思路。
需求:
a)根據當前玩家等級獲取10個正負20級其他玩家列表
b) ?獲取的其他玩家最近一次登錄時間不得大于1天
c)當其他玩家列表內玩家數量<10,則放松篩選條件
d)獲取其他玩家列表,推送至玩家添加好友UI
e)玩家點擊申請向申請玩家發送添加好友請求
f) 玩家可以對列表內其他玩家1鍵全部申請添加
g)被申請玩家同意后該好友添加成功,若對方拒絕不返回信息
h)每個玩家應有1個ID
i)A玩家知道B玩家ID,A玩家可通過ID直接向B玩家發送添加好友請求
a)當其他玩家申請與當前玩家成為好友時,該玩家信息出現至申請列表
b)同意與該玩家成為好友,則該玩家移至當前玩家好友列表且申請列表內清除該玩家信息
c)拒絕與該玩家成為好友,則申請列表內清除該玩家信息
d)玩家可以對申請列表內玩家1鍵全部同意添加
e)玩家可以對申請列表內玩家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接受申請的時候,向服務器發送數據時要把這個時間標識再傳回來,我不清楚這樣做是否合適。請高手指教。
思路是這樣,代碼感覺還需優化,過幾天再貼,希望能對像我這樣的新手帶來幫助。待續。。。。
轉載于:https://www.cnblogs.com/newbeeyu/p/5253178.html
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
- 上一篇: Delphi第三方组件安装DCU.PAS
- 下一篇: nopcommerce商城系统--源代码