• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            Fork me on GitHub
            隨筆 - 215  文章 - 13  trackbacks - 0
            <2018年10月>
            30123456
            78910111213
            14151617181920
            21222324252627
            28293031123
            45678910


            專注即時通訊及網游服務端編程
            ------------------------------------
            Openresty 官方模塊
            Openresty 標準模塊(Opm)
            Openresty 三方模塊
            ------------------------------------
            本博收藏大部分文章為轉載,并在文章開頭給出了原文出處,如有再轉,敬請保留相關信息,這是大家對原創作者勞動成果的自覺尊重!!如為您帶來不便,請于本博下留言,謝謝配合。

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            相冊

            Awesome

            Blog

            Book

            GitHub

            Link

            搜索

            •  

            積分與排名

            • 積分 - 215351
            • 排名 - 118

            最新評論

            閱讀排行榜

            轉載請自覺標明原創出處
            原文鏈接:http://gameislife.info/archives/category/游戲開發
             
            游戲服務器開發技術小結
            1 概述
            本文從開發者的視角,淺析游戲服務器開發涉及到的幾個技術層面,并說明這幾個層面我們可以選擇的解決方案。

            一般地,會把游戲服務器的架構劃分如下三層:網絡接入層、游戲邏輯層、數據存儲層,這樣劃分的主要目的是:

            將底層通信與業務邏輯處理解耦合;
            將業務邏輯處理與數據存儲解耦合;
            有利于運營部署與擴展;
            游戲服務器開發框架整體視圖,如下所示:

            2 網絡接入層
            網絡接入層主要任務是解決來自客戶端大量并發請求和負載均衡的處理,考量該層的主要性能指標是:高吞吐、低延遲、均負載,即既能同一時刻處理大批量的客戶端請求(每秒至少1萬個請求以上),又能快速響應,并且均負載的分布處理這些請求。

            本層的基本技術要點如下圖所示:

            2.1 高并發處理
            2.1.1 http接入
            (1)優點

            低成本:有成熟的開源webserver;
            快速開發的效率:一請求一應答的協議通訊,使用游戲邏輯處理相當簡單;
            低門檻:基于web的應用,玩家無需下載客戶端,也不用擔心防火墻等問題;
            (2)不足

            難以處理服務器廣播事件;
            文本協議會占用較大流量;
            2.1.2 socket接入
            (1)優點

            功能強大:能靈活處理服務器廣播事件;
            高效通信:二進制協議較文本協議能大幅度節省帶寬,并且通信包可做組播等處理,以有效降低流量;
            (2)不足

            實現成本較高,開發難度較大;
            可能會遭遇部分辦公室玩家的機器通訊端口被屏蔽,無法穿透防火墻等問題;
            2.2 IP路由與負載均衡
            這塊跟服務器集群和IDC部署密切相關,主要是為了讓整個服務器集群能最大化其處理能力,尤其是在業務高峰時期,整個服務器集群能均衡平滑的應對客戶端請求,不至于出現某個單點服務器出現很高負載時,其它同層服務器較空閑的情況。

            目前,這塊公司和開源界都有很成熟的解決方案,故在此不多贅述。

            2.3 應用場景
            目前市面上絕大多數的Social Game和SLG類的WebGame均采用http通訊;
            RPG類的WebGame和有源客戶端網游均采用socket通訊;
            3游戲邏輯層
            游戲邏輯層主要是處理游戲的具體業務邏輯,根據游戲類型和部署的不同,它會由一個或多個進程組成。其主要組成可由下圖說明

            3.1 基礎系統
            基礎系統包含的內容基本上為各個游戲業務邏輯所公有的東西。

            游戲對象內存管理:這是業務系統中最基本也是最重要的系統之一,目前,我們采用基于共享內存的預分配機制,來管理游戲中各個對象所需內存的分配與回收。這樣的好處是,當游戲服務器進程Crash時,配合運營的實時監測機制,系統自動拉取Crash進程后,在線玩家的狀態數據可以無損恢復,并且在線玩家不會感覺到服務器宕機;
            消息分發管理:集中處理CS消息和SS消息,設計時重點考慮程序的可擴展性;
            系統與運營日志管理:分別用來監控服務器狀態和玩家的各種行為;
            游戲商城管理:對付費物品的上架、扣除、計費等處理;
            玩家登錄管理:玩家登錄游戲時的流程統一處理;
            3.2 業務系統
            業務系統主要是說明游戲的主體內容是由哪些子模塊組成,這跟具體的游戲類型關系較大,這里抽取出大部分游戲應用的業務模塊。

            地圖與副本管理:游戲各公共場景和玩家獨自的副本地圖的處理,包括Npc與怪物分布、傳送點分布、地圖阻擋數據等的解析,以及地圖實例和副本實例的抽象等;
            移動管理:主要是實現游戲對象(玩家角色、怪物等)的地圖尋路、障礙物檢測,以及動態碰撞處理等功能。
            裝備與道具管理:主要包括裝備的合成、拆分、打造、鑲嵌、升星等,以及道具的獲取、交易、使用等功能;
            任務與事件管理:主要包括任務的領取、任務節點的更新、任務的完成和失敗處理等,以及系統隨機事件的產生等內容;
            游戲世界狀態管理:可將整個游戲世界各游戲對象的狀態分成幾大類與幾小類,如:玩家角色的狀態、技能Buff的狀態等,然后對各狀態之間關系進行統一管理;
            戰斗與技能管理:處理PVE、PVE戰斗流程、傷害計算,以及各個技能、Buff、Debuff的業務規則處理;
            Npc與怪物AI管理:包括Npc在場景中的分布規則和本身的功能處理,以及怪物的分布、刷新、各類AI行為的處理;
            視野管理:包括玩家的視野、Npc和怪物的視野等,設計時需要特別注意考慮各個不同場景中玩家的視野大小和視野搜索網格大小這兩個重要參數,因為,它們對服務器的性能(CPU和流量)影響很大;
            寵物與坐騎管理:包括寵物和坐騎的養成、交易、附帶技能和裝備等功能;
            社會關系管理:包括玩家組隊、玩家好友、玩家交易、家族、公會、陣營、國家等社會關系功能的處理;
            郵件管理:通過郵件可實現發送系統消息、發放系統道具,玩家道具交易等功能;
            聊天管理:包括玩家點對點聊天、群聊等功能;
             

            4 數據存儲層
            數據存儲層是整個服務器的關鍵基礎系統之一,因為游戲服務器的核心功能之一就是存取玩家數據。游戲類型不同,對數據的存取需求也不一樣,對于傳統客戶端MMORPG而言,一般采用Mysql作數據持久化,然后在Mysql與GameSvr中間實現一個ORM的服務提供數據的代理或緩存即可。而新興的Social Game和強交互的WebGame,則選擇用NoSql來替代Mysql,以滿足其超大規模IO并發的需求。如下圖所示:

            4.1 ORM
            ORM即為對象關系映射,可以這樣來簡單的理解:我們平時操作關系型數據庫,需要業務自己編寫許多數據訪問的代碼,這樣會把許多SQL語句直接暴露在業務代碼里,十分不利于維護。利用ORM技術,可以避免這個問題,即業務邏輯不會直接對DB進行操作,而改由ORM來完成,業務邏輯與ORM服務之間約定相關協議和API接口,來完成對數據的增、刪、改、查等功能。

            4.2 NoSql
            NoSql,指的是非關系型的數據庫,它可以滿足對數據庫的高并發讀寫、對海量數據的高效率存儲和訪問,以及對數據庫的高可擴展性和高可用性等需求,它是隨著SNS和Web2.0的興起而產生的新興存儲技術。對于游戲而言,目前它主要應用于Social Game和強交互的WebGame中。

            5 通用組件庫
            通用組件庫是指那些與具體業務無關的,能應用于所有服務器開發的組件庫。目前,我們所積累的可歸納如下圖所示:

            5.1 后臺服務應用框架
            后臺服務應用框架規范了進程的起停方式、信號處理、命令行參數等操作,框架本身實現了一個daemon服務所必備的消息主循環、reload機制,以及定時器處理等功能。

            5.2 日志組件
            日志是服務器調試和定位Bug的主要手段之一,日志組件一般需要實現日志分級、異步寫磁盤、以及按日期時間分類等功能。

            5.3 進程間通訊組件
            進程間的通訊也是服務器的核心基礎功能之一,高效的進程間通訊是服務器性能的基本保障,進程間通訊組件需要實現同機器與跨機器的進程高效通訊。

            5.4 消息打包組件
            在許多通信程序中,需要定義一套網絡協議,并需要根據網絡協議對協議數據單元(PDU)進行Pack/Unpack,以實現可移植性和網絡傳輸的可靠性及效率。但是對協議數據單元進行Pack/Unpack是一個重復性很強的操作,繁瑣而且容易出錯(Pack和Unpack容易不匹配)。而消息打包組件則簡化了網絡協議的制定,使得業務應用不用關心協議的Pack/Unpack操作,并且支持良好的數據擴展和協議版本兼容。

             

            發布于
            手游游戲服務器邏輯框架
            1 背景
            首先,要回答一個問題:

            我們為什么要專門為手機游戲專門定制設計一個游戲服務器邏輯框架?

            坦白地說,公司自研游戲做了這么多年,事實上互娛已經沉淀了一批相當成熟的組件,如:解決底層網絡通信的Tconnd、解決進程間通信Tbus、解決協議加解包的Tdr等等,但我們發現,這些組件絕大多數都是與業務無關的基礎組件、服務和庫。而與游戲業務緊密相關的邏輯框架,可能每個項目組都有自己的一套,這一方面源于,不同游戲業務,的確需求本身有較大的差別,很難用一套可復用性很強的邏輯框架包打天下;另一方面,也可能受限于項目本身的開發進度壓力,端游有相對充裕的開發時間,但由于游戲系統繁多,平攤下來,每個系統的開發時間也不多,而頁游和手游的開發進度就更緊一些,邏輯框架這塊也沒太多時間來作整理了。

            2 現狀
            以stan經歷過的工作室里三款游戲為例:微連、微胖和微塔。

            三款游戲在業務邏輯處理上,均各自使用不同的一套框架,風格迥異。如果要說相同點,則是均使用C/C++來作業務邏輯的實現。微連和微胖均以tapp作基礎來搭建框架,而微塔則是完全自行做的一套后臺框架。

            考慮到手游開發周期短,迭代速度快,發布頻率高等特點,如果延用目前的邏輯框架,無論是上述三款游戲的哪一種,均難以解決如下幾個問題:

            (1)開發復雜度較高

            這里的復雜度包括語言本身的復雜度、開發效率、代碼可讀/可維護性等。

            (2)運維部署代價較高

            從代碼編譯到上線部署,整個周期都比較長,雖然目前的邏輯框架基本上都采用了共享內存保存玩家核心數據,以便于進程重啟后數據即時恢復的機制,用來實現“熱更新”的效果,但這實際上是以犧牲開發復雜度來作代價的。

            (3)系統可靠性

            實事求是地說,要寫出可靠性的代碼,根本上還是取決于寫代碼的“人”。但由于C/C++本身是屬于偏底層的語言,對開發者的要求客觀上要更高一些。但即使經驗豐富的開發者,也難免不犯內存越界、內存泄漏、堆棧溢出等諸多令人抓狂的錯誤。

            有鑒于此,結合業內同行朋友成熟項目的經驗,我們選擇用Lua與C/C++混合編程的方式來實現游戲業務邏輯。

            3 新的解決方案
            新改進的邏輯框架基本可以解決上述提到的三個問題,至于為什么選擇用Lua,這個業內基本上已有了一些共識,可以看這里,互娛魔方工作室也有項目已經在應用 ,看這里。故這個問題在此不再贅述。

            接下來,我們探討一下解決方案的具體實現方法。

            3.1 邊界
            混合編程面臨的一個問題是:如何界定不同語言之間的處理邊界。對于我們來說就是,Lua能干什么,該干什么?C/C++需要做什么?

            為此,我們在實現需要遵行的一些原則有:

            網絡消息的收發、加解包、DB讀寫、日志讀寫、玩家對象池管理等涉及到有一定CPU開銷或底層處理的操作均由C/C++來承擔;
            有復雜交互流程的邏輯,由Lua來實現,如:一個業務協議流程涉及到多個SS交互;
            有單一重復邏輯的需求,由Lua來實現,如:任務、關卡、副本等;
            系統配置文件由Lua來實現;
            其它比較模糊的業務系統,我們會根據如下幾個因素來綜合權衡:開發效率、性能、兩種語言的交互調用頻率等;
            3.2 框架外貌
            (1)GAMESVR加載Lua配置文件進行進程參數以及業務邏輯參數配置;

            (2)GAMESVR加載Lua邏輯腳本,根據CS請求,運行不同的邏輯腳本;

            (3)GAMESVR可以通過修改Lua邏輯腳本進行熱更新;

            3.3 框架處理流程


            3.4 Lua配置文件處理思路
            Lua的一種重要用途是作為配置語言

            XML層次分明,寫起來太復雜;ini配置不夠靈活;其他配置需要自己開發

            Lua作為配置文件編寫起來簡單,解析也方便,更重要的是在Lua協程框架中,很多情況是Lua協程讀取配置文件,而不需要其他接口便可直接讀取,天然的結合,使用起來非常方便。

            遇到的問題:

            (1)一份配置文件,C++中需要調用并且Lua業務邏輯腳本中也需要調用如何處理?

            在GAMESVR中,建立一個ConfModule,ConfModule加載Lua配置文件到本模塊中的Lua虛擬機,并把配置文件需要的字段解析到本模塊的成員變量中,對外提供GET接口進行訪問,對于LuaTaskMgrModule也同樣加載該lua配置文件,方便Lua業務邏輯腳本中的調用。

             

            (2)lua配置文件便捷的解析方式

            采用lua_dostring方式,將需要的參數按lua語句方式復制給一個變量,然后通過lua_tostring、lua_tointeger、lua_tonumber將其解析出來,lua_dostring方式速度較慢,但該模塊只是在GAMESVR初始化時候解析一次,并將解析出來的數據存入模塊的成員變量中,后續數據訪問通過提供的GET接口,解析完后關閉lua虛擬機,我們認為該方式在解析速度上可接收。

             

            3.5 C++網絡收發包處理思路
            目前GAMESVR中存在三個異步回調點:

            TBUS
            TCAPLUS
            LIBCURL
            lua協程框架需要將task_id存入異步交互數據中,并且需要在響應包中能夠原封不動的帶回該task_id;
            TBUS可以將task_id放入包頭的seq_id字段;
            TCAPLUS可以通過TcaplusService::TcaplusServiceRequest中的SetAsyncID將task_id存入,并在響應包時,通過TcaplusService::TcaplusServiceResponse的GetAsynID獲取task_id
            LIBCURL需要封裝,使得CurlClient支持緩存task_id的機制;

            4 寫在后面的話
            目前用新的邏輯框架,重寫了好友關系鏈Server和GameSvr賬號登錄驗證模塊,可以用微塔老客戶端完成賬號登錄全流程。

            雖然新設計的邏輯框架還有諸多可完善的地方,但初次嘗試應用,我們已感受到它帶來的變化,比如:重寫的好友關系鏈Server代碼量比原來縮減了近三分之一,代碼量減少的很明顯的好處就是:代碼更簡潔,可讀性更高(客觀說,微塔原來的代碼也寫得不錯,可讀性也比較好)。

            在后續項目的開發實踐過程中,我們還需不斷優化、完善新設計的邏輯框架,讓其可用性更高、可復用性更強,相信經歷咱們新項目的洗禮,新的邏輯框架能成為咱們產品中心游戲服務器開發的一把利器。

            發布于
            手游對戰設計方案
            1       術語
            1.1    術語和定義
            術語 解釋
            硬直時間 客戶端連續作移動消除時的累積時間
               

            2       需求說明
            2.1    實時對戰
            下面論述以《女巫之戰》為例進行。

            系統從當前在線玩家中,匹配出合適對手來。當進入挑戰場景時,對戰兩方玩家在同一屏顯示,雙方的每一次游戲操作帶來的變化,如:消除效果,都能實時同步到屏幕上。

            如下圖:來自《女巫之戰》截圖,即游戲對戰界面會顯示兩個棋盤,左邊為玩家自己的,右上角為對手的,游戲過程中,會同步顯示血條和棋盤的變化。

            2.2    離線對戰
            離線對戰模式,在SNS游戲中是比較常見的一種PVP玩法。玩家可以隨時對自己的關系鏈好友發起挑戰,即玩家A可以對好友玩家B發起的挑戰,不關心其玩家B是否在線。挑戰完成后,若玩家B在線,則即時通知其被挑戰的信息,若玩家B離線,則待其上線時,再通知被挑戰詳細信息。

            2.3    半實時對戰
            同實時對戰類似,系統也是先從當前在線玩家中,匹配出合適對手來。但是當進入挑戰場景時,屏幕只顯示玩家自己,不顯示對手游戲界面。待這局游戲結束后,在結算界面一起顯示對戰結果。

            還有另一個版本是,對戰雙方都是帶角色的,游戲過程中可以顯示對手玩家的角色Icon,對戰過程中發生的變化,如:分數等,是實時廣播給雙方的。

             

            3       設計實現
            3.1    實時對戰
            實時對戰的設計實現,總的來說,可分為兩類,一類是服務器強同步,一類是服務器弱同步,下面詳細描述之。

            3.1.1     服務器強同步方案
            在這個方案中,游戲邏輯的判定均放在服務端進行,無論是棋盤的初始化操作,還是游戲過程中的消除、新棋子生成等邏輯均由服務器運算,即將消除的算法放在服務器端,客戶端主要作相應消除效果的表現。

            進一步分析,該方案分為兩種情況:

            阻塞同步
            阻塞同步的特征是:玩家每次移動棋子作消除操作時,需要等本次操作產生的效果全部完成后(如:播放消除特效、已有棋子下落,新棋子填充等),才能作下一次移動棋子的操作。基本流程如下圖所示:

             

            圖1  阻塞同步序列圖

             

            (0)客戶端發起PVP匹配,服務器根據相關規則,在同一臺gamesvr上匹配出對手玩家,并向兩者廣播一致的初始化棋盤信息;

            客戶端A和B分別發起棋子移動請求,在收到服務器的響應包之前,客戶端阻塞不允許移動;
            服務器分別判定兩者的移動是否合法,若非法,客戶端收到移動失敗響應包后,讓棋子置位;若合法,先響應客戶端移動成功消息。然后,服務器進一步計算本次移動影響的待下落棋子和新生成待填充的棋子,以及新生成棋子中可能引發的combo棋子,計算完畢后,則一起打包分別向客戶端A與B廣播棋子下落消息,同時處理業務對應的邏輯,如:扣對手玩家的HP、累加自己的分數等;
            客戶端收到服務器的響應移動結果包后,若檢查通過,則處理棋子移動,并播放棋子消除特效等,若不通過,則重置棋子歸位;
            客戶端收到服務器的棋子下落和新棋子填充廣播包后,分別處理A和B兩個棋盤的棋子下落效果;
            進入下一輪棋子請求處理;
             

            幀同步
            幀同步允許玩家在一定時間內(硬直時間),即時移動消除,即時反饋移動消除結果。當硬直時間到達時,客戶端A和客戶端B分別提交其在硬直時間內累積的所有移動請求,同時鎖定棋盤,并等待服務器的處理結果。這種情況下,客戶端和服務器都需要作消除邏輯的計算,并且兩者的算法要保持一致。基本流程圖如下所示:

            圖2  幀同步序列圖

             

            (0)客戶端發起PVP匹配,服務器根據相關規則,在同一臺gamesvr上匹配出對手玩家,并向兩者廣播一致的初始化棋盤信息;

            在硬直時間內,客戶端A和B各自處理玩家的移動消除操作,此時只處理移動效果和消除爆炸效果,而棋子下落和新棋子填充不處理。硬直時間到達時,分別向服務器提前期間所有的請求移動信息;
            服務器分別判定兩者的移動是否合法,若非法,客戶端收到移動失敗響應包后,讓棋子置位;若合法,先響應客戶端移動成功消息。然后,服務器進一步計算本次移動影響的待下落棋子和新生成待填充的棋子,以及新生成棋子中可能引發的combo棋子,計算完畢后,則一起打包分別向客戶端A與B廣播棋子下落消息,同時處理業務對應的邏輯,如:扣對手玩家的HP、累加自己的分數等;
            客戶端收到服務器的棋子下落和新棋子填充廣播包后,分別處理A和B兩個棋盤的棋子下落效果;
            進入下一輪處理;
             

            3.1.2     服務器弱同步方案
            在該方案中,游戲消除邏輯主要放在客戶端進行,即棋盤初始生成算法、消除檢查算法、棋子下落與新棋子生成算法等均由客戶端來控制,而服務器主要作消息轉發與一些簡單的判定,如:對局結束的條件等,基本流程圖如下所示:

            圖3  弱同步序列圖

             

            (0)客戶端發起PVP匹配,服務器根據相關規則,在同一臺gamesvr上匹配出對手玩家,并向兩者廣播約定的對局開始時間,如:播放開場動畫(3s)后開始;

            客戶端各自判定玩家的移動棋子操作,判定能過,則表現相應的消除效果、棋子下落與新棋子填充過程,同時將本次消除信息打包發至服務器;
            服務器收到客戶端的消除信息后,分別轉發至其對應的玩家,同時處理業務對應的邏輯,如:扣對手玩家的HP、累加自己的分數等;
            客戶端收到對手玩家轉發來的消除信息后,在其對手棋盤上表現相應的消除過程與效果;
            如此循環往復,直至對局條件達到,如:某一方玩家HP<=0,或游戲對局時間到等;
            3.1.3     小結
            對比以上兩類實時對戰的實現方案,可以得出如下結論:

            強同步方案一般適用于需要服務器作嚴格檢查判定的場合,即游戲業務上,需要嚴防玩家作弊的情形。其中,阻塞同步方案在MMORPG中應用較多,如:戰斗技能系統等;幀同步方案在ACT中經常使用,如:雙人格斗游戲中的動作同步等;
            與強同步方案有所不同,弱同步方案所應用的游戲,往往更關心玩家的單機體驗手感,而不是數值本身,因此,對于數據校驗的要求也會低一些,如:Puzzle類休閑游戲;
            強同步方案的實現成本一般要高于弱同步方案,并且,由于強同步方案往往需要服務器實現比較復雜的邏輯運算,因此,其服務器的性能開銷要較弱同步方案的大一些,相應地,服務器的承載能力就會較弱同步方案的低;
            3.2    離線對戰
            離線對戰在實現層面需要關注點是多點數據的修改問題。即同一時刻,某個玩家可能會被他的多個好友同時發起挑戰,而在挑戰過程中,可能會同時修改對戰雙方的玩家數據。

            多點數據的修改問題,目前都有比較成熟的解決方案,具體方案需要根據業務需求實際來選擇:

            全局邏輯鎖方案
            實現要點是用一個單獨的locksvr來保持數據修改時的同步。即玩家A發起對玩家B挑戰,gamesvr在get玩家A和玩家B數據的同時,會lock這兩者的數據。此時,若還有其他玩家需要get這兩個玩家數據時,就會get失敗,即鎖沖突。這樣就保證了,每次修改只會有一個玩家在操作。

            該方案的優點:

            好處在于單獨的locksvr可以設計得比較通用,多個項目可以復用,一定程度上可以提高開發效率;
            locksvr邏輯上比較清晰,部署也比較方便。目前微連等項目就是采用的架構組提供的locksvr組件;
            不足的地方:

            當交互比較頻繁時,locksvr的機制可能會導致比較多的沖突,從而會影響玩家的游戲體驗。這個問題在webgame中,玩家可能不會太敏感,這跟玩家的操作習慣有關,當沖突發生時,玩家一般刷新一下頁面操作即可恢復正常。而在手機游戲中,需要根據具體游戲業務來評估;
             

            增量修改方案
            實現要點是gamesvr修改玩家數據時,只提交修改的相對值,各個gamesvr的修改數據請求匯總至一臺中心服務器(熱點服務器)進行,因為只有一個地方修改,故修改數據自然會保持隊列同步。

            該方案的優點:

            最大的好處是不會產生修改引發的沖突問題;
            Gamesvr為無狀態服務器,邏輯會比較簡單;
            不足的地方:

            要求修改的數據結構比較簡單且單一,否則會導致中心服務器的邏輯處理復雜度成倍增加;
            由于所有數據的修改均在中心服務器進行,故其有單點風險;
             

            (三)Compare And Swap

            實現要點保證每次提交的操作,只有一個是成功的。即gamesvr修改玩家數據前,先獲取該玩家的cas值,并在修改數據時把cas值帶上。數據到達DBSvr時,會檢查cas值的合法性,檢查通過,則允許修改數據,同時將當前cas值加1。此時,若有其它gamesvr提交同一玩家的修改請求時,會發現cas值與當前的不匹配,則拒絕此次修改,同時,返回一個錯誤給這個gamesvr的請求。

            該方案的優點:

            它其實是前兩種方案的一個折衷方案,相對于全局鎖的強鎖定(get數據就會鎖定),它只會在set數據時判定數據是否沖突,即有玩家A修改玩家B數據時,玩家C依然可以get玩家B或玩家A的數據,不會引發沖突問題;
            該方案同樣可以做到通用;
            不足的地方:

            依然有強交互時,可能有比較多的沖突問題;
            需要有DBsvr支持該CAS機制;
            注:目前公司的CMem組件支持CAS機制;

             

            3.3    半實時對戰
            半實時對戰本質上還是在線玩家之間的PK,只是客戶端在表現手法上,與實時對戰有所區別。以《女巫之戰》為例,若換成半實時對戰,則對戰開始后,對戰界面只顯示玩家自己一個人的棋盤,對手玩家只顯示一個Avatar Icon和血條。

            半實時對戰的實現方案可參考實時對戰中的弱同步方案。

            4       我們的選擇
            上面討論了三類對戰需求,在實現層面上,可供選擇的設計方案。并且分析了每種設計方案的優缺點和適用場合。咱們微項目具體選擇哪種實現方案,需要根據特定的業務需求來決定。選擇原則是:方案滿足需求,實現代價最小。

            發布于
            WebGame游戲開發現狀淺析
            (一)產品設計

                1)新手設計無腦化、傻瓜化
                    1. UI操作簡單、直觀、便捷;
                    2. 短時間使玩家角色獲得快速成長;
                2)針對付費的設計
                    1. 第一時間讓玩家產生付費的沖動;
                    2. 付費點遍及游戲各個系統;
                3)內掛設計,減少外掛影響
                    1. 自動尋路、自動拾取物品、自動戰斗、自動補充HP/MP等;
                    2. 自動換裝(或者提示玩家換更強的裝備);
                4)提供玩家最大的滿足感和爽快感
                    1. 更好的游戲代入:游戲題材的選擇,游戲世界觀的設計等
                    2. 深挖數值,但又不能使游戲系統過于復雜,即玩家能快速理解游戲玩法內容;
            (二)技術研發

                1)提供跨服PK的功能,即不同大區的玩家能夠同場競技;
                    技術關注點:不同大區的服務器是否部署在同一IDC?存儲服務器數據分區部署 or 全Cluster共享?
                2)支持一機多服部署
                    即同一臺物理機器部署多個游戲世界
                3)形成一套核心研發機制和穩定的開發框架、基礎庫,保障核心功能快速復制
            (三)運營推廣

                1)快速開服,滿足玩家“滾服”需求:《龍將》和《神仙道》做到了1天1服或1天2服,所謂“滾服”,即玩家會在不同服務器體驗,目的是爭取在新的服務器更高的排名和更大的滿足感;
                2)開服第一周的收入是該服最主要的收入,也決定了運營商是否加大推廣的力度;
                3)流量就是金錢,一般運營商的成本是每個人1-2元每人的流量成本;
                4)運營商可以提供機器,也可能讓開發者自己租用機器和帶寬,它只提供一個域名;
            (四)其它

                1)核心玩家群特征:低粘性、高ARP值,即純粹互聯網用戶,游戲只是其網絡生活的一種典型應用;
                2)3–6個月完成一款RPG類webgame的全部開發,即正式付款公測;
            發布于
            WebGame游戲服務器技術要點
            (一)服務器技術實現方案選擇的問題?
            (1)選擇標準WebServer+CGI開發(偏輕)
            【優點】
                1)快速開發:WebServer都是現成的,如:Nginx和Apache;CGI程序能也快速編程;
                2)靈活開發:整個后臺服務可由多個CGI程序組成,一個CGI程序可以對應一項或多項業務功能,增加新功能時則增加新的CGI程序即可;
                3)不停機更新:部署新的CGI程序,不影響已運行的CGI程序;
                4)可適合處理SNS類玩家異步(離線)交互數據的情形;
            【不足】
                1)CGI程序如果過多,可能會加大維護的難度;
                2)業務需求如果要涉及到多個CGI程序之間的通信,即有狀態的關聯依賴,可能會有較復雜的邏輯和可能的性能瓶;
            (2)選擇自定義通信服務器+GameSvr開發(偏重)
            【優點】
                1)可應對復雜業務邏輯的處理,如:業務需求之間的關聯依賴較深等;
                2)可輕松處理玩家之間同步數據的需求;
            【不足】
                1)開發復雜度較大,需要較多的開發資源;
            (二)游戲服務器Cache設計方案
            【背景】
                1)游戲服務器cache數據可大大緩解數據存取時壓力;
                2)多臺分布式游戲服務器作Cache,可有效利用硬件資源;
            【實現方案】
                1)基于共享內存的對象池設計;
            【注意事項】
                1)數據一致性:對于SNS強交互類游戲,需要作多玩家修改同一數據的設計;
                2)數據同步的時機:根據業務數據的重要程度,分級設計同步時間,越重要的數據,同步時間越短;
            (三)游戲服務器數據分類設計方案
            【基本思想】
                把業務數據按重要程度進行分類,每類數據采用不同的存儲和邏輯處理策略;
             
            【應用說明】
                SNS類游戲需要重點考慮
            (四)游戲服務器全局鎖的設計
            【背景】
                1)同一玩家數據會被多玩家修改;
                2)某一Cache數據會被多個應用修改;
            【方案一】:熱點數據分布在各個游戲服務器的Cache中
                1)數據被修改點(熱點數據)設置一個全局Seq,如:玩家數據修改,則在玩家身上設置一個Seq;
                2)當Client讀熱點數據時,則直接返回數據給Client,并將Seq一齊帶上;
                3)當Client寫熱點數據時,會在寫數據請求里帶上上次請求獲得的該熱點數據的Seq,熱點數據的處理邏輯先比較寫數據請求的Seq,是否與當前熱點數據的Seq一致,若不一致(該請求來之前已被其它Client修改過),則有如下兩種異步處理方案:
                    1. 直接報錯給請求Client,此時Client可能需要提示玩家重新刷新瀏覽器;
                    2. 返回當前最新熱點數據給請求Client,Client需要重新處理一遍之前的業務邏輯,再提交寫數據請求;
                4)每次寫熱點數據成功后,熱點數據本身的Seq加1;
                5)數據修改的邏輯統一在熱點數據所在的游戲服務器處理;
            【方案二】:熱點數據集中在一個全局公共服務器的Cache中
                實現方法與【方案一】類似
            【兩個方案的比較】
                1)【方案一】:Cache分布在每臺游戲服務器中,可以有效利用硬件資源,但SS交互邏輯復雜一些;
                2)【方案二】:可以減少一些SS協議的交互,但需要單獨的全局Cache服務器;
            【注意事項】
                1)需要分別考慮玩家在線和離線數據的修改;
             (五)如何有效利用機器的多核CPU
            1)多個通信服務器+1個游戲服務器;

                2)多個通信服務器+多個游戲服務器;
             
            (六)如何評估網絡I/O的瓶頸
                1)網卡(1000M bit/100M bit)本身的極限處理能力:理論處理包的數量:網卡帶寬[1000M bit]/(最小包大小[64Byte] * 8);
                2)游戲業務對包的數量較包的大小更敏感,因為每個網絡包在CPU處理時,會產生IO中斷,因此,常用的策略是,合并多個請求包為一個包,提高帶個包的信息量;
             
            (七)深入了解MySQL的存儲性能
                1)Mysql5.5+InnoDB1.1;
                2)Mysql的Cache解決方案;
            【聲明:若有摘錄,請注明來自http://gameislife.info/archives/109
            發布于
            動作類網游技術難點分析
            1 背景
            動作類游戲(ACT)在百度百科上的定義是:由玩家所控制的人物根據周圍環境的變化,利用鍵盤或者手柄、鼠標的按鍵做出一定的動作,如移動、跳躍、攻擊、躲避、防守等,來達到游戲要求的相應目標。單機代表作有:《波斯王子》、《鬼泣》、《真三國無雙》、《戰神》等,而網游代表作有:《DNF》、《龍之谷》、《怪物獵人OL》等。

            從技術層面來說,與傳統MMORPG不同的是,動作類網游對于操作響應的網絡時延要求極高,要保證較好的體驗效果的話,一般要求時延小于150ms。如果網絡時延較大的話,會帶來對戰雙方(或多方)數據不一致的問題,即所謂的數據同步問題。因此,數據同步問題是動作類網游的首要問題,也是最大的問題。

            下面將先描述數據同步問題的具體表現,再嘗試分析目前業界常用的解決辦法,最后簡要講述公司兩個自研項目的實施方案。

            2 問題聚焦
            下面列舉的這些同步問題,也是大部分網絡游戲共有的一些典型問題,如果處理不好,又會在動作類網游中進一步放大,從而極大的影響玩家體驗。

            2.1 位置不同步
            比如在T1時間,第三世界的玩家B看第一世界的玩家A在射程內并發起攻擊,但此時玩家A正在跑出射程,當服務器收到玩家B的攻擊請求,會判斷玩家A已經在射程外了,如果服務器拒絕B的攻擊,則會讓B覺得很困惑,為什么明明在攻擊范圍內,卻攻擊不到呢?

             

            2.2 動態阻擋
            所謂動態阻擋是指角色、怪物和建筑這些實體不可重疊。動態阻擋讓玩家感覺更具有真實性,并且在多人PK中,可以利用動態阻擋進行卡位,制造人墻,豐富游戲的玩法。

            動態阻擋本身就會有很多碰撞問題,再加上網絡延遲,會有各種各樣的問題產生。

            碰撞情形1:玩家A在P1點請求要去P2點時,玩家B也有可能在P3點請求要到P2點,但最終只能有一個人到P2的位置,如何避免拉扯呢。

             

            碰撞情形2:玩家A在P1點請求要去P2點,玩家B在P3點請求要去P4點,路徑有交叉,要讓他們碰還是不碰呢?

             

             

             

            碰撞情形3:玩家A在P1點請求要去P2點,玩家B在P3點要去P4點,這種情形也會有碰撞發生。

             

             

            碰撞情形4:玩家A要通過一個只能容納一個人的關隘,玩家B要阻止玩家A通過,但是由于網絡延遲,當A通過時,并沒有發現B已經在卡住關隘,服務器是相信A,允許通過呢,還是相信服務器自己,要拖拽A呢?

             

             

            碰撞情形5:玩家A要通過城門,但是由于網絡延遲,當A通過時,并沒有發現城門已經關閉了,服務器是相信A,允許通過呢,還是要拖拽A呢?

            2.3 技能事件
            考慮冰凍情形,在T1時間,玩家A對玩家B施放冰凍,在T2時間,服務器收到報文,并下發冰凍確認,玩家B在T3時刻才收到自己被冰凍的消息,

            如果在T3時間前,B沒有收到被冰凍消息,進行移動,而移動報文又在T2時刻到達服務器,如果按照邏輯,服務器拒絕處理B的移動請求,那么就會產生B在第一視角的位置和服務器的位置不一致的現象,就會產生拖拽,如何避免拖拽呢?

             

            其他諸如擊暈,減速,恐懼,死亡等等,都類似冰凍情形,不再贅述

            3解決方案
            3.1 幀同步
            原理
            玩家在發起戰斗后,每隔一定時間在玩家的戰斗動作序列中設置一個邏輯關鍵幀,在關鍵幀這個點,本機必須收到來自所有參與者反饋后才可繼續執行其余的動作序列,否則,就進行鎖幀、等待。這樣就通過頻繁對時(即在每一個關鍵幀節點上對齊),便可以像編寫串行單機指令一樣來進行多個客戶端的事件指令同步了。

            如下圖所示:

             

            優點
            簡單易實現,不會出現任何的不一致性。在延遲小(< 100ms)且穩定的環境下非常合適。此外,在實時性要求不高的玩法(比如回合制玩法)中也非常合適。

            缺點
            游戲節奏受最慢的那個玩家客戶端影響巨大。一人卡機,所有人受影響。惡意玩家可以用偽造大延遲的方式來獲得好處,從而破壞游戲公平性。

             

            3.2 客戶端承擔消耗運算
            原理
            游戲比較消耗CPU的運算均放在玩家本地客戶端執行,如:角色移動物理判定、戰斗物理判定、AI邏輯判定等等。服務器只對影響玩家利益的關鍵信息作驗證。

            優點
            保證了游戲操作手感,避免了本機操作延時。

            缺點
            運算邏輯存放在客戶端,會帶來較大的外掛風險。

             

            3.3 游戲策劃上的優化
            原理
            在游戲設計層面,來隱藏玩家的延遲感。比如:延長出招/收招動作時間、降低動作判定精度、給技能加公共CD、避免戰斗受擊時發生位移等等。

            優點
            無任何技術風險,綠色、環保、安全,代價最小。

            缺點
            可能會影響戰斗的爽快感。

             

            4 公司內項目的一些做法
            《QQ堂》和《炫斗之王》都是公司自研的動作休閑類游戲,在與其相關負責同事作了一些簡要交流后,將他們的做法小結如下:

            客戶端之間采用P2P通信
            這對于在同一局域網內(如:網吧)的玩家,網絡延遲很小。只有當兩個Peer連結不同時,消息包才通過服務器中轉;

            客戶端先表現,服務器后檢驗
            玩家角色在移動、戰斗出招等操作時,客戶端在發出請求包的同時,先自行在本機表現,繼續后面的游戲邏輯,而無需等到服務器驗證通過后才開始。

            客戶端的校驗邏輯同時在服務器再運行一遍
            這也是慣用做法,即所謂的服務器強校驗。

            做好客戶端反外掛
            由于采用P2P通信,有些邏輯難免會放在客戶端,這與上述的一些解決方案的做法也是類似的。附上QQ堂對于反外掛處理的一個分享文檔

            5 小結
            綜上所述,動作類網游在技術實施層面上,較傳統MMORPG主要是在數據同步(多個Peer間、C/S間)上要求更加苛刻,當然,這目前在客戶端平臺上,也已經有了較為成熟的技術解決方案。但具體到頁游平臺,雖然從Flash10和Adobe AIR1.5開始,已經支持P2P通信,Adobe也在官方提供相應 的P2P服務,即代號為Cirrus,但目前尚未看到其在商業運營的頁游項目里有成熟的應用。因此,在頁游平臺的P2P應用,還需要更進一步的探索和挖掘。

            發布于
            Social Game與MMORPG在服務器架構上的差異
            最近在作公司的一個Social Game的項目服務器架構設計,與之前做過的MMORPG(簡稱RPG)相比,差別還是較為明顯的,現總結一二,以供分享!

            (一)協議通信

            1)Socail Game為了快速開發,在通信協議的選擇上均會選擇http作為底層通信協議,這樣選擇的好處大致有:

            1、方便客戶端編程:http為一應一答的同步模型;

            2、可以選擇成熟的開源http服務器,如:apache、nginx;

            2)RPG選擇的是基于socket的TCP通信,這是由游戲本身的特點所決定的,如:聊天、多人視野、服務器主動通知事件等需求

            (二)游戲邏輯服務器的承受能力

            1)RPG的游戲邏輯服務器(地圖服務器)所能承載的最高在線(PCU)是在3000-5000不等;

            2)Social Game由于沒有RPG復雜的移動、戰斗、視野管理等需求,邏輯服務器承受的在線一般都是比較高的,如:10000-30000不等

            (三)游戲邏輯服務器的Cache和回寫機制

            1)RPG的游戲邏輯服務器一般都需要Cache玩家數據,并且采取定時回寫的策略,如根據數據重要程度分別作5min-15min不等的定時回寫;

            2)Social Game的游戲邏輯服務器一般都無需Cache玩家數據,玩家的每次請求都是即時讀即時寫(這樣會涉及到另外一個問題,即DB讀寫的性能問題,見下一條);

            (四)DB存儲模型的選擇

            1)RPG存儲服務器常用的還是MySQL+innodb,中間還由業務自己寫一個Cache代理服務器,以Cache熱點數據;

            2)Social Game則會選用TC、MemCached等所謂Key-Value全內存數據存儲,有實力的公司會自己實現一個類似這種機制的存儲系統,它可以無源,也可以是有源,并且還可以選擇用MySQL作數據落地,畢竟MySQL作為互聯網業務DB的成熟解決方案,已毋庸置疑;

            (注:我們公司是選擇自己開發基于key-value機制的全內存DB,現網測試的數據是平均1KB的數據可以分別達到5w左右的讀/寫,還是很牛X的了)

            (五)交互數據的一致性

            1)在SNS Game中,會經常出現同一個玩家在某一個時刻同時被多個好友訪問和修改數據的情況,這時就需要保證,每次數據的更新都是正常有序進行的,而不能被寫臟數據。一般地,都會使用一個類似全局鎖服務的設計來解決這個問題;

            2)RPG不會存在這樣的問題,類似的需求是:玩家可能會跨地圖服務器,即所謂的跳線或跨服,這個問題的通常解決方案是服務器重新作一次下線、重登錄的處理,當然,玩家是感覺不到的;

            (六)IDC部署

            1)RPG一般是分區分服部署;

            2)Social Game則是全區全服部署;

            呵,先寫這些多,后面再慢慢補充,也歡迎同行朋友拍磚!:)

            發布于
            關于游戲服務器性能問題的幾點思考(2)
            工作中對項目壓力測試的一些心得,先自我作一個小結吧!

            (一)宏觀與微觀相結合
              (1)宏觀層面
                   即系統的一些關鍵性能指標,如:各進程所占CPU的百分比、內存消耗、網絡包量、磁盤IO等等,詳細指標列舉如下:
            名稱 描述 參考值
            CPU useage CPU 的使用時間百分比。 平均值小于70%
            Process virtual memery size 進程使用的內存空間總量,包括物理內存和swap內存 進程長時間運行后該值不能大幅度的改變,否則是內存泄露
            Disk rate 磁盤傳輸速率 一般少于2M/s, 日志級別太低時硬盤io會是瓶頸。
            Bytes trans rate 網絡發送速率 少于200Mbps
            Bytes receive rate 網絡接收速率 少于200Mbps
            Pages swap in 每秒鐘讀入到物理內存中的頁數 長期大于0表示物理內存不足
            Pages swap out 每秒鐘寫入頁面文件頁數 參考上面
            Context switches rate 每秒鐘在進程或線程之間的切換率。 少于5000*cpu個數
            Interrupt rate 每秒內的設備中斷數。該指標代表了本地向CPU引起的本地中斷,例如IO端口引起中斷,系統時鐘引起中斷。 一個巨大的中斷值,同時伴隨著緩慢的系統性能表現,指示存在硬件問題。
              

                測試工具:nmon
              (2)微觀層面
                   這里是指具體到Server程序的邏輯功能模塊,包括函數消耗CPU周期、函數調用次數等資源占用情況,以及系統內核哪一部分最忙等。
                   測試工具:oprofile、gprof
             
            (二)黑盒與白盒相結合
              (1)黑盒測試
                   我們目前的壓力測試程序,其實是歸于黑盒測試范疇的,它模擬玩家的一些行為,應用具體項目的實際協議與被測游戲Server通訊,通過同時產生大規模機器人,來模擬與實際運營中相似的場景。這里編寫的測試用例,其功能就是要盡可能真實地模擬client的功能,并能方便的配置化和部署client行為;
              (2)白盒測試
                   我理解的白盒測試包括兩部分,一是單元測試,它能有效地解決BUG回歸測試的問題,二是代碼覆蓋率檢查,它能有效檢查到每個函數分支的執行情況。前者可借助業界成熟的自動化測試框架,如:cppunit、gtest;后者也有許多第三方工具,比較方便的有GNU自帶的gcov,只要在編譯程序時,加入-fprofile-arcs -ftest-coverage編譯選項即可。
               如果要用一句話來概括兩者的話,那就是:
              白盒測試能極大的保障程序邏輯功能層面的正確性(正常與異常流程均能檢測到),而黑盒測試則能有效保障程序運行的穩定性。
            發布于
            MMORPG游戲在技能戰斗中的位置同步問題
            這里列舉在技能戰斗系統開發中,碰到的兩個與位置同步相關的問題

            (一)

            在MMORPG游戲中,對于那些同時擁有近攻和遠程系等多種職業的游戲,策劃一般都會對近攻類的職業,加上沖鋒類的技能,以便平衡遠程類職業在攻擊距離上的優勢。在client看到的效果,是玩家邊播放沖鋒動作,然后快速接近目標,并對目標一個傷害,而對server而言,該技能與其它技能在處理的不同之處在于,施法玩家在施法的同時,也作一個位置的變更。一般server的處理流程是,先檢查沖鋒直線路徑是否合法(有無阻擋)和其它施法條件,若通過,則告訴client可以施法,并同時設置當前玩家坐標為沖鋒后的坐標(該坐標由client帶上來)。

            由于server移動系統在對client發過來的移動數據作檢驗時,需要檢查本次移動的起步點,是否為上次移動的結束點,即作線段端點合法檢查,而沖鋒到達的目標點并未在上次移動的路徑棧信息中,所以,server技能系統在設置沖鋒位置時,需要先清除原路徑棧信息(如調用MoveStop接口),以便確認本次沖鋒為一次全新的移動。

            (二)

            兩個玩家同時使用沖鋒技能時(目前client在做技能時,采用先表現的方式),出現一個玩家(沖鋒目標client)停在沖鋒途中的現象,原因為server廣播技能施法時,沒有帶目標主動位移的信息(client在處理沖鋒位置時,對于使用沖鋒技能的client,因為它知道沖鋒到達的位置,所以它的處理沒有問題,而另一個沖鋒目標client,由于它不知道對方要沖到哪里,則client處理時就是選擇沖鋒路徑上的一點,這樣就會看到停在沖鋒途中了)所致。解決辦法是,要么在協議中下發目標位移信息,要么在策劃規則上,只允許同一時刻一個玩家沖鋒,如:沖鋒加暈眩debug等;

            發布于
            MMORPG中技能戰斗系統的技術分享
            今天下午參加了公司兄弟項目組的一個技術分享會,主題是關于MMORPG游戲中的技能系統設計的,有幾點體會和思考,先記錄下來了!

            (1)技能施法時,client只有一個上行的請求施法包,后續施法的過程全由server來驅動下發施法各階段的結果信息,如吟唱、效果傷害、命中信息等等;

            (2)彈道類技能是由server計算飛行時間,并不考慮飛行后的軌跡,若此時目標有移動,則client會做目標跟隨的處理;

            (3)技能學習:由秘籍來獲得技能,一本秘籍包含多個技能,被動技能不影響主動技能的屬性;

            (4)Buff系統與技能系統是相互獨立的,相互之間有接口各自的進行訪問;

            (5)玩家施法作群攻目標選定時,也是由server來完成,這時是從玩家自己的視野里搜索,而無需再搜一次動態區域(格子32*32);

            (6)技能效果由一個主效果+N個Buff效果組成;

            (7)Buff對象區分玩家和怪物,其存儲結構獨立出來放在內存池中,在施法者需要時再根據目標類型來添加;

            (8)特別小心:在作技能效果計算時,盡量避免有輪循的處理,因為,這個這個很耗CPU;

            思考題:關于技能引發的位置同步問題

            (1)對于改變目標(玩家)移動速度的技能,可能會帶來位置不同步的問題,即server下發速度改變的包時,目標玩家可能正在移動,從而導致server和client的位置不一致?

            答:對于這個問題,一般是通過移動系統自身的位置同步策略來解決的,即移動系統發現client和server位置不一致時,通過一定的策略來補償速度慢的一方,從而在目標玩家在接來的一定時間內達到位置平衡。

            (2)類似性質的問題還有給目標加冰凍、定身等Buff,也可能帶來位置不同步的問題?

            答:這個問題暫也還沒有好的解決方案,目前的做法是當目標中定身Buff時,client立即表現定身,即定在原地,并將此時的位置信息帶給server,server檢驗合法后設置這個位置,解凍后client為繼續玩家移動(若玩家是移動中被定身住的話)。

             

            posted on 2017-02-25 11:43 思月行云 閱讀(7658) 評論(0)  編輯 收藏 引用 所屬分類: MMO
            亚洲人成网站999久久久综合| 97久久超碰国产精品2021| 国产激情久久久久影院老熟女| 久久人人妻人人爽人人爽| 国产精品99久久久久久人| 久久久青草久久久青草| 久久久久一级精品亚洲国产成人综合AV区 | 国产毛片久久久久久国产毛片 | 国产激情久久久久影院小草| 精品国产热久久久福利| 久久精品国产99国产精品亚洲| 97久久久精品综合88久久| 国产成人无码精品久久久久免费| 久久丫忘忧草产品| 777久久精品一区二区三区无码 | 精品一二三区久久aaa片| 精品久久久久久| 久久精品桃花综合| 国产午夜精品理论片久久| 亚洲AV无一区二区三区久久| 国产日韩久久久精品影院首页| 少妇精品久久久一区二区三区| 久久精品国产亚洲AV不卡| 国产午夜精品理论片久久影视| 狠狠色婷婷久久一区二区 | 久久综合久久综合久久综合| 亚洲中文字幕无码久久精品1| 欧美精品丝袜久久久中文字幕| 草草久久久无码国产专区| 久久久一本精品99久久精品66| 久久国语露脸国产精品电影| 四虎久久影院| 午夜精品久久久久久影视777| 久久99久久成人免费播放| 久久成人精品视频| 久久99中文字幕久久| 精品一区二区久久| 品成人欧美大片久久国产欧美...| 99久久99这里只有免费的精品| 久久久久无码精品国产| 精品午夜久久福利大片|