mangos0 9原始碼分析學習筆記(二)

2021-06-09 15:03:29 字數 4576 閱讀 3200

當mangos開始執行到  smaster.run()時,開始執行master物件 ,至此,mangos開始所構建的遊戲伺服器才算真正開始執行。

smaster其實是master類的乙個例項,smaster mangos::singleton::instance(),應該是使用了單例模式來實現的,設計模式這塊不是很清楚。

master類的主要作用是啟動server伺服器,run()函式為該類的執行入口。

該函式主要處理如下工作:

1,輸出一些版本等資訊;

2,開始啟動資料庫的連線,連線三個資料庫,這三個資料庫就是在main函式中所宣告的三個全域性databasemysq,包括worlddatabase遊戲世界資料庫,characterdatabase遊戲角色資料庫,logindatabase登入資訊資料庫.

3,進行遊戲世界的初始化,即sworld  (#define sworld mangos::singleton::instance())的初始化。

4,從配置中獲取通訊埠,生成乙個socket控制代碼,並將監聽socket與該埠進行繫結, 這一步是做通訊的初始化處理 。

5,對程式的中止訊號進行捕捉 ,捕捉中斷訊號,其實主要是設定world::m_stopevent,該引數非常重要,主要用於世界更新中判斷是否需要更新伺服器。

6,啟動worldrunnable執行緒,並設定server的登入狀態,該執行緒會呼叫worldrunnable::run(),該函式用於世界資訊的更新,伺服器檢查從客戶端傳送來的資訊,並且根據資訊進行遊戲世界的更新,應該是是核心中的核心。

7,啟動clirunnable執行緒  // 如果配置中啟動了命令列模式,則使用該執行緒,用於在伺服器執行過程中處理命令列資訊

8,啟動ralistensocket    // 作用暫時未知

9 ,主伺服器的主迴圈,判斷當world::m_stopevent不為真時,即伺服器未收到中止訊號時,進行如下幾個處理

10,當伺服器world::m_stopevent為真時,開始結束服務做各種斷開服務連線的準備工作等等,並且清空各種scriptingmodule。

**較長,貼出部分**如下:

/// master 開始執行入口

void master::run()

h.add(&worldlistensocket); // 將繫結好的套接字增加到之前宣告的socket控制代碼上

//捕捉程式中止訊號,判斷是否中止服務

_hooksignals();

//啟動worldrunnable執行緒 該執行緒會呼叫worldrunnable::run(),該函式用於世界資訊的更新,伺服器檢查從客戶端傳送來的資訊,

//並且根據資訊進行遊戲世界的更新,應該是是核心中的核心。

zthread::thread t(new worldrunnable);

t.setpriority ((zthread::priority )2);

// 然後設定server的登入狀態,設定分割槽號碼realmid

logindatabase.pexecute("update `realmlist` set `color` = 0, `population` = 0 where `id` = '%d'",realmid);

#ifdef win32

if (sconfig.getbooldefault("console.enable", 1) && (m_servicestatus == -1)/* need disable console in service mode*/)

#else

if (sconfig.getbooldefault("console.enable", 1))

#endif

///啟動ralisten 這部分沒有想明白是做什麼,以後在細看

listensocketralistensocket(h);

if (sconfig.getbooldefault("ra.enable", 0))

}uint32 realcurrtime, realprevtime;

realcurrtime = realprevtime = getmstime();

uint32 socketselecttime = sworld.getconfig(config_socket_selecttime);

uint32 numloops = (sconfig.getintdefault( "maxpingtime", 30 ) * (minute * 1000000 / socketselecttime));

uint32 loopcounter = 0;

///- 主迴圈,當世界資訊中m_stopevent不為真,即未接到中止訊號時,執行更新迴圈,判斷當前時序,根據監聽埠獲得到的客戶端資訊,對遊戲世界進行更新,並且通過心跳機制保證與資料庫的連線。

while (!world::m_stopevent)

}// 當接收到中止訊號之後,即m_stopevent為真以後,處理伺服器關閉相關事宜。

logindatabase.pexecute("update `realmlist` set `color` = 2 where `id` = '%d'",realmid);

_unhooksignals();

// when the main thread closes the singletons get unloaded

// since worldrunnable uses them, it will crash if unloaded after master

t.wait();

characterdatabase.haltdelaythread(); // 角色資料庫延遲處理

worlddatabase.haltdelaythread(); // 世界資料庫

logindatabase.haltdelaythread(); // 登入資料庫

slog.outstring( "halting process..." );

unloadscriptingmodule();

return;

}

主線就是這樣的,以後會根據主線慢慢的讀進去,自己也是剛剛開始接觸這**,感覺挺有意思的。

在run()中,輸出相關資訊後,要做的第一件事情就是連線資料庫,使用_startdb()方法對資料庫進行連線,資料庫的位址和使用者名稱密碼資訊均從配置檔案中讀取,可能這也是單機版的問題,實際中的不清楚應該怎麼做。

bool master::_startdb()函式**如下:

// 進行資料庫連線的初始化

bool master::_startdb()

slog.outstring("world database: %s", dbstring.c_str());

///- 連線worlddata資料庫,其中全域性變數worlddatabase為之前在main函式中定義的databasemysql類

if(!worlddatabase.initialize(dbstring.c_str()))

// 獲取角色資料庫 預設配置為"127.0.0.1;3306;mangos;mangos;characters"

if(!sconfig.getstring("characterdatabaseinfo", &dbstring))

slog.outstring("character database: %s", dbstring.c_str());

//連線到角色資料庫,可以獲取到角色的資訊 使用的是之前main中定義的characterdatabase全域性變數

if(!characterdatabase.initialize(dbstring.c_str()))

///從配置檔案中獲取登入資訊資料庫的資訊

if(!sconfig.getstring("logindatabaseinfo", &dbstring))

//連線到登入資訊資料庫,這裡應該是記錄使用者的賬戶資訊,具體資料庫的內容以後會詳細分析的

slog.outstring("login database: %s", dbstring.c_str() );

if(!logindatabase.initialize(dbstring.c_str()))

//從配置檔案中獲取到遊戲分割槽的資訊

realmid = sconfig.getintdefault("realmid", 0);

if(!realmid)

slog.outstring("realm running as realm id %d", realmid); //輸出一些分割槽資訊 ?

clearonlineaccounts();

// 從世界資料庫中獲取到版本資訊 並且檢測版本是否正確

queryresult* result = worlddatabase.query("select `version` from `db_version` limit 1");

if(result)

else

slog.outstring("using unknown world database."); // 若版本錯誤則只輸出提示資訊

return true;

}

連線資料庫之後是遊戲世界的初始化。以後會順著這個思路一點一點分析其實現的。

Mangos原始碼分析 一)

mangos 原始碼分析 realmd 登陸伺服器 realmd 主程式 launch the realm server int main int argc,char argv h.add authlistensocket 進行一些引數設定 while stopevent 伺服器主迴圈 return...

mangos原始碼分析 計畫

最近無意中看到了mangos這麼個東東,它很好的反應了目前遊戲伺服器的設計,所以決定在打醬油的時候對其研究一下。現在給出參考位址 參考 1 mangos原始碼分析系列 2 mangos 原始碼閱讀筆記,十分詳細,框架流程分析的很清晰 3 綠色格線內表示物理上為一台伺服器。1 方案一 低成本 低效能 ...

Mangos原始碼分析(一) DBC檔案分析

2008 01 24 22 57 57 標籤 mangos 一 dbc檔案結構 檔案頭 檔案頭 4位元組 wdbc 記錄數 4位元組 記錄字段數 4位元組 每條記錄位元組數 4位元組 字串表總位元組數 4位元組 記錄1 欄位1 欄位2 欄位n 記錄2 欄位1 欄位2 欄位n 字串表 字串1 字串2 ...