µ±Ç°Î»Öà : 145zÓÎÏ·Õ¾¡¡|¡¡ÈÈѪ´«Ææ¡¡|¡¡¼¼Êõ½Ì³Ì¡¡|¡¡

GOM´«ÆæÒýÇæµÇ¼Æ÷È«½âÎö£ºÑ¡ÐÍ¡¢ÅäÖÃÓë±Ü¿ÓÖ¸ÄÏ

Èȶȣº
ÔÚGOMÒýÇæµÄÉú̬ÖУ¬**µÇ¼Æ÷**ÊÇÁ¬½ÓÍæ¼ÒÓë·þÎñÆ÷µÄºËÐÄÇÅÁº£¬Æä¹¦ÄÜÖ±½ÓÓ°ÏìÓÎÏ·¼æÈÝÐÔ¡¢°²È«ÐÔºÍÓû§ÌåÑ顣Ȼ¶ø£¬ÊÐÃæµÇ¼Æ÷ÖÖÀà·±¶à£¬´Ó¹Ù·½Ô­°æµ½µÚÈý·½¶þ´Î¿ª·¢°æ±¾£¨ÈçÂÌÃË¡¢ÐÜè¡¢Õ½ÉñµÈ£©£¬¿ª·¢Õß³£ÏÝÈëÑ¡ÔñÓëÅäÖõÄÀ§»ó¡£±¾ÎÄ´Óʵս½Ç¶È³ö·¢£¬ÏµÍ³ÊáÀíµÇ¼Æ÷µÄºËÐŦÄÜ¡¢ÊÊÅäÂß¼­ÓëÅäÖÃϸ½Ú£¬ÖúÄã´òÔìÎȶ¨¸ßЧµÄµÇ¼»·¾³¡£

---

### Ò»¡¢µÇ¼Æ÷µÄºËÐŦÄÜÐèÇó
#### 1. **»ù´¡ÄÜÁ¦**
- **²¹¶¡¼ÓÔØ**£ºÖ§³ÖPAK¼ÓÃÜ¡¢WZL/WIL×ÊÔ´¶ÁÈ¡£¬²¢¼æÈݶ༶Ŀ¼½á¹¹¡£
- **ͨÐŰ²È«**£º·À½Ù³Ö¡¢·À´Û¸Ä£¨ÈçIPαװ¼ì²â¡¢·â°ü¼ÓÃÜ£©¡£
- **¶à¶ËÊÊÅä**£ºPC¿Í»§¶Ë·Ö±æÂÊ×ÔÊÊÓ¦£¨800x600ÖÁ4K£©¡¢Òƶ¯¶ËÄ£ÄâÆ÷¼æÈÝ¡£

#### 2. **½ø½×À©Õ¹**
- **·´Íâ¹Ò¼¯³É**£ºÄÚÖÃWPE·â°ü¹ýÂË¡¢¼ÓËÙ¼ì²â¡¢ÄÚ´æÐÞ¸ÄÀ¹½Ø¡£
- **UI×Ô¶¨Òå**£ºÖ§³ÖƤ·ôÌæ»»¡¢°´Å¥Âß¼­°ó¶¨¡¢¶¯Ì¬¹«¸æÍÆËÍ¡£
- **Êý¾Ýͳ¼Æ**£ºÊµÊ±¼à¿ØÔÚÏßÈËÊý¡¢IP·Ö²¼¡¢·â½û¼Ç¼¡£

#### 3. **°æ±¾Æ¥Åä**
- **ÒýÇæ¼æÈÝÐÔ**£ºÐèÓëGOMÒýÇæ°æ±¾Ñϸñ¶ÔÓ¦£¨Èç1108°æÒýÇæÐèÅäÌ×2015+µÇ¼Æ÷£©¡£

---

### ¶þ¡¢Ö÷Á÷µÇ¼Æ÷ÀàÐÍÓëÑ¡Ðͽ¨Òé

| µÇ¼Æ÷ÀàÐÍ | ´ú±í²úÆ· | ÓÅÊÆ | ÁÓÊÆ | ÊÊÓó¡¾° |
|------------------|-----------------|-----------------------------------------|-----------------------------|----------------------|
| **¹Ù·½Ô­°æ** | GOM¹Ù·½µÇ¼Æ÷ | Îȶ¨ÐԸߣ¬ÎÞºóÃÅ·çÏÕ | ¹¦Äܵ¥Ò»£¬ÎÞ·´Íâ¹ÒÄ£¿é | µ¥»ú²âÊÔ¡¢Ð¡¹æÄ£Áª»ú |
| **µÚÈý·½Ãâ·Ñ°æ** | ÂÌÃË/ÐÜèÃâ·Ñ°æ | Ö§³Ö»ù´¡PAK¼ÓÃÜ¡¢UI×Ô¶¨Òå | ¹ã¸æÖ²Èë¡¢¹¦ÄÜÊÜÏÞ£¨ÈçÈËÊýÉÏÏÞ£© | Ô¤ËãÓÐÏ޵ķÇÉÌÒµ·þ |
| **ÉÌÒµÊÚȨ°æ** | Õ½Éñ/ºè¶Ü/ESP | È«¹¦ÄÜ·´Íâ¹Ò¡¢DDoS·À»¤¡¢×Ô¶¯¸üР| Äê·ÑÖÆ£¨Í¨³£500-2000Ôª/Ä꣩ | ´óÐÍÉÌÒµ·þ¡¢¸ß°²È«ÐèÇó |
| **×ÔÑж¨Öưæ** | »ùÓÚGOMÔ´Âë¶þ´Î¿ª·¢ | ÍêÈ«×ÔÖ÷¿ØÖÆ£¬¿ÉÉî¶È¶¨Öƹ¦ÄÜ | ¿ª·¢³É±¾¸ß£¬Ðèרҵ¼¼ÊõÍÅ¶Ó | ³¬´óÐÍIP»ò¶ÀÌØÍæ·¨ÏîÄ¿ |


---

### Èý¡¢µÇ¼Æ÷ÅäÖÃÈ«Á÷³ÌÏê½â£¨ÒÔÂÌÃ˵ǼÆ÷ΪÀý£©

#### **²½Öè1£ºÉú³ÉµÇ¼Æ÷ºËÐÄÎļþ**
1. ÏÂÔØÂÌÃ˵ǼÆ÷Éú³ÉÆ÷£¨ÐèÓëGOMÒýÇæ°æ±¾Æ¥Å䣩¡£
2. ÅäÖÃ×ÊԴĿ¼£º
```bash
# ×ÊԴ·¾¶Ê¾Àý
Resources/
©À©¤©¤ data/ # WIL/WZLËØ²Ä
©À©¤©¤ map/ # µØÍ¼Îļþ
©¸©¤©¤ ui.pak # ¼ÓÃÜUI°ü£¨ÃÜÂëÐèÔÚÉú³ÉÆ÷ÖÐÌîд£©
```

3. ÉèÖ÷´Íâ¹Ò²ÎÊý£º¹´Ñ¡“¼ÓËÙ¼ì²â”“ÄÚ´æ±£»¤”µÈÑ¡Ïî¡£

#### **²½Öè2£º¼¯³ÉÁбíÎļþÓ빫¸æ**
1. ÐÞ¸Ä`serverlist.txt`£º
```ini
[Server]
Name=²âÊÔÒ»Çø
IP=127.0.0.1
Port=7000
Show=1 # ÊÇ·ñÔÚÁбíÖÐÏÔʾ
```

2. Éè¼Æ¹«¸æÒ³Ã棺±à¼­`notice.html`£¬Ö§³ÖJavaScript¶¯Ì¬½»»¥¡£

#### **²½Öè3£º¿Í»§¶Ë´ò°üÓëÇ©Ãû**
1. ʹÓù¤¾ß£¨ÈçEnigma Virtual Box£©½«µÇ¼Æ÷Óë²¹¶¡´ò°üΪµ¥Ò»EXE¡£
2. ¶ÔEXE½øÐÐÊý×ÖÇ©Ãû£¨±ÜÃⱻɱ¶¾Èí¼þÎ󱨣©£º
```bash
signtool sign /f mycert.pfx /p ÃÜÂë /t http://timestamp.digicert.com Login.exe
```


#### **²½Öè4£º·þÎñ¶ËÅäÌ×ÉèÖÃ**
1. ÔÚM2ServerÖÐÆôÓõǼÆ÷ÑéÖ¤£º
```ini
[LoginGate]
CheckClient=1 # Ç¿ÖÆÐ£ÑéµÇ¼Æ÷°æ±¾
ClientVersion=2023 # ÓëµÇ¼Æ÷Éú³ÉÆ÷Öеİ汾ºÅÒ»ÖÂ
```

2. ÅäÖ÷À»ðǽ¹æÔò£º·ÅÐÐ7000£¨ÓÎÏ·¶Ë¿Ú£©¡¢7100£¨µÇ¼¶Ë¿Ú£©¡£

---

### ËÄ¡¢¸ßƵÎÊÌâÓë½â¾ö·½°¸

#### **ÎÊÌâ1£ºµÇ¼Æ÷Æô¶¯ºóºÚÆÁ/¿¨½ø¶ÈÌõ**
- **Ô­Òò**£ºPAKÃÜÂë´íÎó»ò·¾¶²»Æ¥Åä¡£
- **ÅŲé**£º
1. ¼ì²é`Resources\data\Pak.txt`ÖеÄÃÜÂëÓëÉú³ÉÆ÷ÉèÖÃÊÇ·ñÒ»Ö¡£
2. ʹÓÃWIL±à¼­Æ÷ÑéÖ¤ËØ²ÄÊÇ·ñ³É¹¦´ò°ü¡£

#### **ÎÊÌâ2£ºÍæ¼Ò·´À¡“ÎÞ·¨Á¬½Ó·þÎñÆ÷”**
- **Ô­Òò**£º¶Ë¿Ú³åÍ»»òIP°×Ãûµ¥ÏÞÖÆ¡£
- **½â¾ö**£º
1. ÔÚ·þÎñÆ÷°²È«×éÖзÅÐÐ7000-7500¶Ë¿Ú·¶Î§¡£
2. ¹Ø±ÕM2ServerµÄ“½öÔÊÐíÖ¸¶¨IPÁ¬½Ó”Ñ¡Ïî¡£

#### **ÎÊÌâ3£ºÉ±¶¾Èí¼þÎ󱨵ǼÆ÷Ϊ²¡¶¾**
- **·½°¸**£º
1. ¹ºÂòÕý¹æ´úÂëÇ©ÃûÖ¤Ê飨ÈçDigiCert£©¡£
2. ÔڵǼÆ÷Æô¶¯Ê±Ìí¼ÓÓû§Ð­Ò鵯´°£¬Òýµ¼Íæ¼ÒÌí¼ÓÐÅÈΡ£

#### **ÎÊÌâ4£º×Ô¶¨ÒåUI°´Å¥µã»÷ÎÞЧ**
- **ÅŲé**£º
1. ¼ì²é°´Å¥Ê¼þÊÇ·ñ°ó¶¨µ½ÕýÈ·µÄ½Å±¾±êÇ©£¨Èç`@MainButton`£©¡£
2. È·ÈϽű¾Îļþ£¨QFunction.txt£©ÒÑͬ²½ÖÁ·þÎñÆ÷¶Ë¡£

---

### Îå¡¢°²È«¼Ó¹ÌÓëÐÔÄÜÓÅ»¯½¨Òé
1. **·ÀÆÆ½â**£º
- ʹÓÃVMProtect¶ÔµÇ¼Æ÷ºËÐÄÂß¼­¼ÓÃÜ¡£
- ¶¨ÆÚ¸ü»»Í¨ÐÅÃÜÔ¿£¨Keymaker¹¤¾ßÉú³É£©¡£
2. **¸ºÔؾùºâ**£º
- ¶àÏß·²¿Êðʱ£¬Í¨¹ýDNSÂÖѯ»òCDN·ÖÁ÷Íæ¼ÒÁ¬½Ó¡£
3. **×ÊÔ´Ô¤¼ÓÔØ**£º
- ÔڵǼÆ÷ÖÐÆôÓÓºǫ́¾²Ä¬¸üД£¬¼õÉÙÍæ¼ÒµÈ´ýʱ¼ä¡£

---

#### ½áÓï
GOMÒýÇæµÇ¼Æ÷µÄÅäÖþø·Ç¼òµ¥µÄ“Éú³É-·¢²¼”£¬¶øÊÇÐè¼æ¹Ë°²È«¡¢¼æÈÝÓëÓû§ÌåÑéµÄϵͳ¹¤³Ì¡£¿ª·¢ÕßÓ¦Ã÷È·×ÔÉíÐèÇ󣨲âÊÔ/ÉÌÓã©¡¢ÆÀ¹À³É±¾ºóÑ¡ÔñµÇ¼Æ÷ÀàÐÍ£¬²¢ÔÚÅäÖý׶ÎÑϸñ×ñÑ­×ÊÔ´¹æ·¶Óë°æ±¾Æ¥ÅäÔ­Ôò¡£¶ÔÓÚÉÌÒµ¼¶ÏîÄ¿£¬½¨ÒéÓÅÏȲɹº¾ß±¸³ÖÐø¸üеÄÉÌÒµµÇ¼Æ÷£¬ÒÔ½µµÍ³¤ÆÚά»¤·çÏÕ¡£

#### 1. ×¼±¸¹¤×÷
ÔÚ¿ªÊ¼Ö®Ç°£¬ÇëÈ·±£ÄãÒѾ­°²×°ÁËGOMÒýÇæ£¬²¢ÇÒÓÐÒ»¸ö»ù±¾µÄÓÎÏ·¿ò¼Ü´î½¨Íê³É¡£´ËÍ⣬»¹ÐèҪ׼±¸ºÃËùÓбØÒªµÄ¿Í»§¶ËºÍ·þÎñÆ÷¶ËÎļþ¡£

#### 2. Àí½âµÇ¼Æ÷µÄ×÷ÓÃ

##### µÇ¼Æ÷¹¦ÄÜ
µÇ¼Æ÷µÄÖ÷Òª¹¦ÄÜÊÇ´¦ÀíÓû§µÄµÇ¼ÇëÇó£¬ÑéÖ¤Óû§µÄÉí·ÝÐÅÏ¢£¨ÈçÓû§ÃûºÍÃÜÂ룩£¬²¢½«ÓÐЧµÄµÇ¼ÇëÇóת·¢µ½ÓÎÏ··þÎñÆ÷¡£Ëü»¹¸ºÔð¹ÜÀí»á»°×´Ì¬ºÍ°²È«ÈÏÖ¤¡£

#### 3. ÅäÖÃÎļþÉèÖÃ

##### ²½ÖèÒ»£º±à¼­`auth_config.txt`
Ê×ÏÈ£¬ÔÚ`data\auth_config.txt`ÎļþÖÐÅäÖõǼÆ÷µÄÏà¹Ø²ÎÊý¡£

```plaintext
db_host=localhost
db_user=legendary_db_user
db_password=legendary_db_password
db_name=legendary_db
listen_port=2106
max_connections=1000
```

- `db_host`: Êý¾Ý¿âÖ÷»úµØÖ·¡£
- `db_user`: Êý¾Ý¿âÓû§Ãû¡£
- `db_password`: Êý¾Ý¿âÃÜÂë¡£
- `db_name`: Êý¾Ý¿âÃû³Æ¡£
- `listen_port`: ¼àÌý¶Ë¿Ú£¬Ä¬ÈÏΪ2106¡£
- `max_connections`: ×î´óÁ¬½ÓÊý¡£

##### ²½Öè¶þ£º±à¼­`game_config.txt`
ÔÚ`data\game_config.txt`ÎļþÖÐÅäÖÃÓÎÏ··þÎñÆ÷µÄÏà¹Ø²ÎÊý¡£

```plaintext
db_host=localhost
db_user=legendary_db_user
db_password=legendary_db_password
db_name=legendary_db
listen_port=2107
max_connections=1000
```

- `db_host`: Êý¾Ý¿âÖ÷»úµØÖ·¡£
- `db_user`: Êý¾Ý¿âÓû§Ãû¡£
- `db_password`: Êý¾Ý¿âÃÜÂë¡£
- `db_name`: Êý¾Ý¿âÃû³Æ¡£
- `listen_port`: ¼àÌý¶Ë¿Ú£¬Ä¬ÈÏΪ2107¡£
- `max_connections`: ×î´óÁ¬½ÓÊý¡£

#### 4. Êý¾Ý¿âÅäÖÃ

##### ²½ÖèÒ»£º´´½¨Êý¾Ý¿âºÍ±í
È·±£Êý¾Ý¿âÖаüº¬±ØÒªµÄ±í½á¹¹£¬Èç`account_table`¡¢`char_table`µÈ¡£

**´´½¨Êý¾Ý¿â**
```sql
CREATE DATABASE legendary_db;
USE legendary_db;
```

**´´½¨Õ˺űí**
```sql
CREATE TABLE account_table (
id INT AUTO_INCREMENT PRIMARY KEY,
login VARCHAR(50) NOT NULL UNIQUE,
password CHAR(64) NOT NULL,
last_ip VARCHAR(15),
last_login DATETIME
);
```

**´´½¨½ÇÉ«±í**
```sql
CREATE TABLE char_table (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL UNIQUE,
job INT NOT NULL,
level INT NOT NULL,
exp BIGINT NOT NULL,
str INT NOT NULL,
dex INT NOT NULL,
intel INT NOT NULL,
con INT NOT NULL,
hp INT NOT NULL,
sp INT NOT NULL,
gold BIGINT NOT NULL,
pos_x FLOAT NOT NULL,
pos_y FLOAT NOT NULL,
map_index INT NOT NULL,
account_id INT NOT NULL,
FOREIGN KEY (account_id) REFERENCES account_table(id)
);
```

##### ²½Öè¶þ£º²åÈëʾÀýÊý¾Ý
²åÈëһЩʾÀýÊý¾ÝÒÔ±ã½øÐвâÊÔ¡£

**²åÈëÕ˺ÅÊý¾Ý**
```sql
INSERT INTO account_table (login, password, last_ip, last_login) VALUES ('testuser', 'hashed_password', '127.0.0.1', NOW());
```

**²åÈë½ÇÉ«Êý¾Ý**
```sql
INSERT INTO char_table (name, job, level, exp, str, dex, intel, con, hp, sp, gold, pos_x, pos_y, map_index, account_id)
VALUES ('TestChar', 1, 1, 0, 10, 10, 10, 10, 100, 50, 1000, 100.0, 100.0, 1, 1);
```

#### 5. ±àдµÇ¼Æ÷´úÂë

##### ²½ÖèÒ»£ºÐÞ¸Ä`auth_server.cpp`
ÔÚ`src\auth_server.cpp`ÎļþÖÐʵÏֵǼÂß¼­¡£

**auth_server.cpp**
```cpp
#include "auth_server.h"
#include "database_manager.h"
#include "packet_builder.h"

CAuthServer::CAuthServer()
{
m_listenPort = 2106;
m_maxConnections = 1000;
}

void CAuthServer::Start()
{
if (!InitializeSocket())
{
SystemLog::LogError("Failed to initialize socket.");
return;
}

ListenForConnections();
}

bool CAuthServer::InitializeSocket()
{
m_socket = socket(AF_INET, SOCK_STREAM, 0);
if (m_socket == INVALID_SOCKET)
{
SystemLog::LogError("Failed to create socket: %d", WSAGetLastError());
return false;
}

sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(m_listenPort);

if (bind(m_socket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
{
SystemLog::LogError("Failed to bind socket: %d", WSAGetLastError());
closesocket(m_socket);
return false;
}

if (listen(m_socket, m_maxConnections) == SOCKET_ERROR)
{
SystemLog::LogError("Failed to listen on socket: %d", WSAGetLastError());
closesocket(m_socket);
return false;
}

SystemLog::LogInfo("Authentication server started on port %d.", m_listenPort);
return true;
}

void CAuthServer::ListenForConnections()
{
while (true)
{
sockaddr_in clientAddr;
int addrLen = sizeof(clientAddr);
SOCKET clientSocket = accept(m_socket, (sockaddr*)&clientAddr, &addrLen);
if (clientSocket == INVALID_SOCKET)
{
SystemLog::LogError("Failed to accept connection: %d", WSAGetLastError());
continue;
}

CClientSession* session = new CClientSession(clientSocket);
m_sessions.push_back(session);
std::thread(&CAuthServer::HandleClient, this, session).detach();
}
}

void CAuthServer::HandleClient(CClientSession* session)
{
while (true)
{
Packet packet;
if (!session->ReceivePacket(packet))
{
SystemLog::LogWarning("Connection closed by client.");
break;
}

switch (packet.GetType())
{
case PACKET_TYPE_LOGIN_REQUEST:
HandleLoginRequest(session, packet);
break;
// ÆäËû°üÀàÐÍ...
}
}

delete session;
}

void CAuthServer::HandleLoginRequest(CClientSession* session, const Packet& packet)
{
std::string username = packet.ReadString();
std::string password = packet.ReadString();

DatabaseManager* dbManager = DatabaseManager::GetInstance();
if (!dbManager->AuthenticateUser(username, password))
{
CPacketBuilder response(PACKET_TYPE_LOGIN_RESPONSE);
response.WriteByte(LOGIN_ERROR_INVALID_CREDENTIALS);
session->SendPacket(response.Build());
return;
}

int accountId = dbManager->GetAccountIdByUsername(username);
if (accountId == -1)
{
CPacketBuilder response(PACKET_TYPE_LOGIN_RESPONSE);
response.WriteByte(LOGIN_ERROR_ACCOUNT_NOT_FOUND);
session->SendPacket(response.Build());
return;
}

CPacketBuilder response(PACKET_TYPE_LOGIN_RESPONSE);
response.WriteByte(LOGIN_SUCCESS);
response.WriteInt(accountId);
session->SendPacket(response.Build());

SystemLog::LogInfo("User [%s] logged in successfully.", username.c_str());
}
```

##### ²½Öè¶þ£ºÐÞ¸Ä`database_manager.cpp`
ÔÚ`src\database_manager.cpp`ÎļþÖÐʵÏÖÊý¾Ý¿â²Ù×÷¡£

**database_manager.cpp**
```cpp
#include "database_manager.h"
#include <mysql/mysql.h>

DatabaseManager* DatabaseManager::GetInstance()
{
static DatabaseManager instance;
return &instance;
}

DatabaseManager::DatabaseManager()
{
m_mysql = mysql_init(nullptr);
if (!mysql_real_connect(m_mysql, "localhost", "legendary_db_user", "legendary_db_password", "legendary_db", 0, nullptr, 0))
{
SystemLog::LogError("Failed to connect to database: %s", mysql_error(m_mysql));
}
}

DatabaseManager::~DatabaseManager()
{
mysql_close(m_mysql);
}

bool DatabaseManager::AuthenticateUser(const std::string& username, const std::string& password)
{
char query[256];
snprintf(query, sizeof(query), "SELECT * FROM account_table WHERE login='%s' AND password='%s'", username.c_str(), password.c_str());

if (mysql_query(m_mysql, query))
{
SystemLog::LogError("Failed to execute query: %s", mysql_error(m_mysql));
return false;
}

MYSQL_RES* result = mysql_store_result(m_mysql);
if (!result)
{
SystemLog::LogError("No results returned: %s", mysql_error(m_mysql));
return false;
}

bool isAuthenticated = (mysql_num_rows(result) > 0);
mysql_free_result(result);

return isAuthenticated;
}

int DatabaseManager::GetAccountIdByUsername(const std::string& username)
{
char query[256];
snprintf(query, sizeof(query), "SELECT id FROM account_table WHERE login='%s'", username.c_str());

if (mysql_query(m_mysql, query))
{
SystemLog::LogError("Failed to execute query: %s", mysql_error(m_mysql));
return -1;
}

MYSQL_RES* result = mysql_store_result(m_mysql);
if (!result)
{
SystemLog::LogError("No results returned: %s", mysql_error(m_mysql));
return -1;
}

MYSQL_ROW row = mysql_fetch_row(result);
int accountId = (row && row[0]) ? atoi(row[0]) : -1;
mysql_free_result(result);

return accountId;
}
```

##### ²½ÖèÈý£º±àÒë²¢²âÊÔ
È·±£ËùÓÐÐ޸ĺóµÄ´úÂë¶¼Äܳɹ¦±àÒë¡£

```sh
g++ -o auth_server src/auth_server.cpp src/database_manager.cpp src/packet_builder.cpp -lengine -lmysql
```

Æô¶¯µÇ¼·þÎñÆ÷ºÍ¿Í»§¶Ë£¬¹Û²ìµÇ¼¹ý³ÌÊÇ·ñ˳Àû¡£

```sh
start auth_server.exe
start client.exe
```

#### 6. ¿Í»§¶ËÅäÖÃ

##### ²½ÖèÒ»£º±à¼­`client_config.txt`
ÔÚ¿Í»§¶ËÅäÖÃÎļþ`config\client_config.txt`ÖÐÅäÖõǼ·þÎñÆ÷µÄÐÅÏ¢¡£

```plaintext
auth_server_ip=127.0.0.1
auth_server_port=2106
game_server_ip=127.0.0.1
game_server_port=2107
```

- `auth_server_ip`: µÇ¼·þÎñÆ÷IPµØÖ·¡£
- `auth_server_port`: µÇ¼·þÎñÆ÷¶Ë¿Ú¡£
- `game_server_ip`: ÓÎÏ··þÎñÆ÷IPµØÖ·¡£
- `game_server_port`: ÓÎÏ··þÎñÆ÷¶Ë¿Ú¡£

##### ²½Öè¶þ£ºÐÞ¸Ä`client_network.cpp`
ÔÚ`src\client_network.cpp`ÎļþÖÐʵÏÖ¿Í»§¶ËÓëµÇ¼·þÎñÆ÷ºÍÓÎÏ··þÎñÆ÷µÄͨÐÅ¡£

**client_network.cpp**
```cpp
#include "client_network.h"
#include "packet_builder.h"

CClientNetwork::CClientNetwork()
{
m_authSocket = INVALID_SOCKET;
m_gameSocket = INVALID_SOCKET;
}

bool CClientNetwork::ConnectToAuthServer(const std::string& ip, int port)
{
m_authSocket = socket(AF_INET, SOCK_STREAM, 0);
if (m_authSocket == INVALID_SOCKET)
{
SystemLog::LogError("Failed to create socket: %d", WSAGetLastError());
return false;
}

sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(ip.c_str());
serverAddr.sin_port = htons(port);

if (connect(m_authSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
{
SystemLog::LogError("Failed to connect to auth server: %d", WSAGetLastError());
closesocket(m_authSocket);
return false;
}

SystemLog::LogInfo("Connected to auth server at %s:%d", ip.c_str(), port);
return true;
}

bool CClientNetwork::ConnectToGameServer(const std::string& ip, int port)
{
m_gameSocket = socket(AF_INET, SOCK_STREAM, 0);
if (m_gameSocket == INVALID_SOCKET)
{
SystemLog::LogError("Failed to create socket: %d", WSAGetLastError());
return false;
}

sockaddr_in serverAddr;
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr(ip.c_str());
serverAddr.sin_port = htons(port);

if (connect(m_gameSocket, (sockaddr*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
{
SystemLog::LogError("Failed to connect to game server: %d", WSAGetLastError());
closesocket(m_gameSocket);
return false;
}

SystemLog::LogInfo("Connected to game server at %s:%d", ip.c_str(), port);
return true;
}

void CClientNetwork::SendLoginRequest(const std::string& username, const std::string& password)
{
CPacketBuilder packet(PACKET_TYPE_LOGIN_REQUEST);
packet.WriteString(username);
packet.WriteString(password);
SendPacketToAuthServer(packet.Build());
}

void CClientNetwork::SendPacketToAuthServer(const Packet& packet)
{
send(m_authSocket, reinterpret_cast<const char*>(packet.GetData()), packet.GetSize(), 0);
}

void CClientNetwork::SendPacketToGameServer(const Packet& packet)
{
send(m_gameSocket, reinterpret_cast<const char*>(packet.GetData()), packet.GetSize(), 0);
}

bool CClientNetwork::ReceivePacket(Packet& packet)
{
char buffer[MAX_PACKET_SIZE];
int bytesRead = recv(m_gameSocket, buffer, MAX_PACKET_SIZE, 0);
if (bytesRead <= 0)
{
SystemLog::LogWarning("Connection closed by server.");
return false;
}

packet.SetData(buffer, bytesRead);
return true;
}
```

##### ²½ÖèÈý£º±àÒë²¢²âÊÔ
È·±£ËùÓÐÐ޸ĺóµÄ´úÂë¶¼Äܳɹ¦±àÒë¡£

```sh
g++ -o client src/client_main.cpp src/client_network.cpp src/packet_builder.cpp -lengine
```

Æô¶¯µÇ¼·þÎñÆ÷¡¢ÓÎÏ··þÎñÆ÷ºÍ¿Í»§¶Ë£¬¹Û²ìÕû¸öµÇ¼Á÷³ÌÊÇ·ñ˳³©¡£

```sh
start auth_server.exe
start game_server.exe
start client.exe
```

#### 7. ÈÕÖ¾Îļþ¼ì²é

##### ²é¿´µÇ¼·þÎñÆ÷ÈÕÖ¾
´ò¿ªµÇ¼·þÎñÆ÷µÄÈÕÖ¾Îļþ£¨Í¨³£Î»ÓÚ`log\auth_server.log`£©£¬²éÕÒÏà¹ØµÄ´íÎóÐÅÏ¢¡£

```plaintext
[2023-10-01 12:34:56] INFO: Authentication server started on port 2106.
[2023-10-01 12:34:56] INFO: Connected to database successfully.
[2023-10-01 12:34:56] INFO: User [testuser] logged in successfully.
```

¸ù¾ÝÈÕÖ¾ÖеÄÐÅÏ¢£¬È·ÈϵǼ·þÎñÆ÷ÊÇ·ñÕý³£ÔËÐÐÒÔ¼°Óû§ÊÇ·ñ³É¹¦µÇ¼¡£

##### ²é¿´ÓÎÏ··þÎñÆ÷ÈÕÖ¾
´ò¿ªÓÎÏ··þÎñÆ÷µÄÈÕÖ¾Îļþ£¨Í¨³£Î»ÓÚ`log\game_server.log`£©£¬²éÕÒÏà¹ØµÄ´íÎóÐÅÏ¢¡£

```plaintext
[2023-10-01 12:34:56] INFO: Game server started on port 2107.
[2023-10-01 12:34:56] INFO: Connected to database successfully.
[2023-10-01 12:34:56] INFO: Account [1] selected character [TestChar].
```

¸ù¾ÝÈÕÖ¾ÖеÄÐÅÏ¢£¬È·ÈÏÓÎÏ··þÎñÆ÷ÊÇ·ñÕý³£ÔËÐÐÒÔ¼°½ÇÉ«ÊÇ·ñ³É¹¦¼ÓÔØ¡£

##### ²é¿´¿Í»§¶ËÈÕÖ¾
´ò¿ª¿Í»§¶ËµÄÈÕÖ¾Îļþ£¨Í¨³£Î»ÓÚ`log\client.log`£©£¬²éÕÒÏà¹ØµÄ´íÎóÐÅÏ¢¡£

```plaintext
[2023-10-01 12:34:56] INFO: Connecting to auth server at 127.0.0.1:2106.
[2023-10-01 12:34:56] INFO: Connected to auth server at 127.0.0.1:2106.
[2023-10-01 12:34:56] INFO: Logging in as testuser.
[2023-10-01 12:34:56] INFO: Login successful, account ID: 1.
[2023-10-01 12:34:56] INFO: Connecting to game server at 127.0.0.1:2107.
[2023-10-01 12:34:56] INFO: Connected to game server at 127.0.0.1:2107.
[2023-10-01 12:34:56] INFO: Selecting character TestChar.
[2023-10-01 12:34:56] INFO: Character selection successful.
```

¸ù¾ÝÈÕÖ¾ÖеÄÐÅÏ¢£¬È·ÈϿͻ§¶ËÊÇ·ñÕýÈ··¢ËÍÁ˵ǼÇëÇóÒÔ¼°·þÎñÆ÷µÄÏìÓ¦¡£

#### 8. ³£¼ûÎÊÌâ¼°½â¾ö·½°¸

##### ÎÊÌâÒ»£ºÎÞ·¨Á¬½Óµ½µÇ¼·þÎñÆ÷
- **¼ì²éÍøÂçÉèÖÃ**£ºÈ·±£¿Í»§¶ËºÍ·þÎñÆ÷Ö®¼äµÄÍøÂçÁ¬½ÓÕý³£¡£
- **¼ì²éÅäÖÃÎļþ**£ºÈ·±£`client_config.txt`ÖеĵǼ·þÎñÆ÷IPºÍ¶Ë¿ÚÅäÖÃÕýÈ·¡£
- **¼ì²é·À»ðǽÉèÖÃ**£ºÈ·±£·À»ðǽûÓÐ×èÖ¹µÇ¼·þÎñÆ÷µÄ¶Ë¿Ú¡£

##### ÎÊÌâ¶þ£ºµÇ¼ʧ°Ü
- **¼ì²éÊý¾Ý¿âÅäÖÃ**£ºÈ·±£`auth_config.txt`ÖеÄÊý¾Ý¿âÅäÖÃÕýÈ·¡£
- **¼ì²éÊý¾Ý¿â·þÎñ**£ºÈ·±£Êý¾Ý¿â·þÎñÕýÔÚÔËÐв¢ÇÒ¿ÉÒÔ·ÃÎÊ¡£
- **¼ì²éÓû§Êý¾Ý**£ºÈ·±£`account_table`Öаüº¬ÕýÈ·µÄÓû§ÐÅÏ¢¡£

##### ÎÊÌâÈý£ºÎÞ·¨Á¬½Óµ½ÓÎÏ··þÎñÆ÷
- **¼ì²éÍøÂçÉèÖÃ**£ºÈ·±£¿Í»§¶ËºÍ·þÎñÆ÷Ö®¼äµÄÍøÂçÁ¬½ÓÕý³£¡£
- **¼ì²éÅäÖÃÎļþ**£ºÈ·±£`client_config.txt`ÖеÄÓÎÏ··þÎñÆ÷IPºÍ¶Ë¿ÚÅäÖÃÕýÈ·¡£
- **¼ì²é·À»ðǽÉèÖÃ**£ºÈ·±£·À»ðǽûÓÐ×èÖ¹ÓÎÏ··þÎñÆ÷µÄ¶Ë¿Ú¡£

##### ÎÊÌâËÄ£º½ÇÉ«¼ÓÔØÊ§°Ü
- **¼ì²é½ÇÉ«Êý¾Ý**£ºÈ·±£`char_table`Öаüº¬ÕýÈ·µÄ½ÇÉ«ÐÅÏ¢¡£
- **¼ì²éÎïÆ·Êý¾Ý**£ºÈ·±£`item_table`Öаüº¬ÕýÈ·µÄÎïÆ·ÐÅÏ¢¡£
- **¼ì²é¼¼ÄÜÊý¾Ý**£ºÈ·±£`skill_table`Öаüº¬ÕýÈ·µÄ¼¼ÄÜÐÅÏ¢¡£

##### ÎÊÌâÎ壺¿Í»§¶Ë°æ±¾²»Æ¥Åä
- **¸üпͻ§¶Ë**£ºÈ·±£¿Í»§¶Ë°æ±¾Óë·þÎñÆ÷°æ±¾¼æÈÝ¡£
- **ͬ²½×ÊÔ´Îļþ**£ºÈ·±£¿Í»§¶ËºÍ·þÎñÆ÷Ö®¼äµÄ×ÊÔ´ÎļþÒ»Ö¡£

#### 9. ×ܽá
ͨ¹ýÒÔÉϲ½Ö裬ÄãÓ¦¸ÃÄܹ»ÔÚGOM´«ÆæÒýÇæÖгɹ¦ÅäÖõǼÆ÷£¬²¢È·±£Íæ¼ÒÄܹ»Ë³ÀûµÇ¼ÓÎÏ·¡£Õâ²»½öÌáÉýÁËÓÎÏ·µÄÎȶ¨ÐԺͿɿ¿ÐÔ£¬»¹È·±£ÁËÍæ¼ÒµÄÁ¼ºÃÌåÑ顣ϣÍûÕâÆª½Ì³Ì¶ÔÄãÓÐËù°ïÖú£¡