英雄遠征Erlang源碼分析(3)-遊戲服務器的啓動

上一篇文件介紹了網關服務器的啓動,其功能主要用於給客戶端返回可選的遊戲服務器列表,讓客戶端去連接。其實有些遊戲的網關部分使用的是PHP搭建,代碼的維護和Erlang是分開的。現在讓我們來看遊戲服務器的部分。

同樣,找到script文件夾,運行run.sh,即可啓動遊戲服務器(先確認遊戲的數據庫和相關的表已建立,通過運行sdzmmo.sql文件)。

腳本里的啓動參數和一些解釋:
    +P 102400 erlang節點系統最大併發進程數
    +K true 開啓kernel poll
    -smp disable 禁用smp
    -name [email protected] 節點名稱
    -setcookie sd2 設置cookie
    -boot start_sasl 使用sasl
    -config log 指定配置文件
    -s sd server_start 函數入口

進入sd:server_start(),通過start_application(server)啓動名爲server的app。查看server.app,參數{mod, {sd_server_app, []}},找到回調模塊sd_server_app

找到sd_server_app:start/0函數,如下:

start(normal, []) ->
    [Ip, Port, Sid] = init:get_plain_arguments(),
    {ok, SupPid} =sd_sup:start_link(),
    sd_networking:start([Ip, list_to_integer(Port), list_to_integer(Sid)]),
    {ok, SupPid}.

裏面主要進行了兩個操作:
    1.{ok, SupPid} = sd_sup:start_link()用於啓動sd_sup監控樹,返回sd_sup監控樹的Pid。sd_sup是整個遊戲服務器最頂端的監控樹,接下來啓動的進程/監控樹都要掛在這下面。
    2.sd_networking:start([Ip, Port, Sid])傳入IP,端口和sd監控樹的Pid,開啓遊戲內的網絡服務和初始化遊戲內容。

進入sd_networking:start/1,可以看到下面開啓了多個服務,每個服務的開啓形式如下:

start_kernel() ->
    {ok,_} = supervisor:start_child(
               sd_sup,
               {mod_kernel,
                {mod_kernel, start_link,[]},
                permanent, 10000, supervisor, [mod_kernel]}),
    ok.

服務的開啓指定了將進程掛到sd_sup下。下面是具體開啓的服務:
    start_kernel/0:開啓核心服務,啓動名爲mod_kernel的gen_server,並掛到sd_sup下。在mod_kernel:init/0中初始化三項:init_ets/0進行ets表的初始化(創建),init_mysql/0進行數據庫連接的初始化(建立連接),goods_util:init_goods/0初始物品,物品屬性,強化,寶石鑲嵌,掉落規則(從數據庫取出,插入到對應的ets表中)。
    start_disperse/0:開啓多節點服務,啓動名爲mod_disperse的gen_server,並掛到sd_sup下,在mod_disperse:init/0中從數據庫獲取其他線路(節點),使用rpc:cast通知它們自己的加入,並維護一張保存其他節點信息的ets表,當有新節點加入或者舊節點退出時進行更新。
    start_rand/0:開啓隨機種子服務,掛到sd_sup下,用於返回隨機種子,避免直接使用erlang隨機函數“假隨機”的影響。
    start_client/0:開啓名爲sd_tcp_client_sup的客戶端監控樹,掛到sd_sup下,等待收到來自客戶端的Socket連接後,在監控樹下啓動名爲sd_reader的進程,在sd_reader:init/0中開始等待客戶端的登錄連接,是客戶端與遊戲服務器開始交互的入口,這裏暫不展開講。
    start:tcp/0:開啓名爲sd_tcp_listener_sup的監控樹,掛到sd_sup下,往下新建sd_tcp_acceptor_sup和sd_tcp_listener(用於監聽端口),在sd_tcp_acceptor_sup下新建sd_tcp_acceptor,用於接收tcp連接,這裏也不展開講,後面文章會講到。
    start_mon/0和start_npc/0:調用mod_mon_create:start_link/0和mod_npc_create:start_link/0啓動生成怪物和NPC的gen_server,用於管理怪物和NPC(當前還沒有怪物和NPC生成,要加載場景的時候纔會去根據配置生成)。
    start_map/0:啓動場景管理進程,進入mod_scene:init/0中,加載所有場景id,並根據配置,在load_scene/1中使用mod_mon_create:create_mon/0和mod_npc_create:create_npc/0創建怪物和npc。遊戲地圖使用mask配置可移動區域與阻塞區域,使用load_mask/4,根據地圖的mask尋找可移動的座標,將座標保存到ets表中。
    start_task/0:啓動任務管理進程,用於管理任務。
    start_timer/0:啓動定時服務管理gen_fsm,調用timer_framer:init/1函數,加載需要進行定時任務的模塊列表,保存到state中,每隔十分鐘檢查一次。定時任務模塊都在timer文件夾下。
    start_guild/0:啓動幫派管理gen_server,調用lib_gulid:load_all_guild/0,從數據庫加載所有幫派信息,存入ets中,並進行檢查幫派建設,加載幫派成員,加載幫派申請等操作。
    start_pet/0:啓動寵物管理gen_server,調用lib_pet:load_base_pet/0,從數據庫加載所有寵物信息,並存入ets。
    start_mail/0:啓動郵件管理gen_server
    start_rank/0:啓動排行榜管理gen_fsm,在lib_rank:init_rank()中創建空排行榜(新建排行榜ets表),排行榜的初始化在timer_rank:init/1中調用mod_rank:first_update_rank/0實現。

將遊戲數據從數據庫加載到內存中,等待玩家客戶端的連接,這樣遊戲服務器的初始化就完成了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章