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

GOM´«ÆæÒýÇæÎïÆ·À´Ô´×·×ÙÈ«¹¥ÂÔ£¬´Ó½Å±¾ÅäÖõ½À´Ô´±êʶµÄÍêÕû½â¾ö·½°¸

Èȶȣº
ÔÚGOMÒýÇæÖÐʵÏÖ“ÎïÆ·À´Ô´Ìáʾ”£¨Èç“¡¾ÏµÍ³¡¿[ÍÀÁúµ¶]À´×Ô£º³àÔ¶ñħµôÂ䔣©£¬ÐèÕûºÏ**´¥·¢½Å±¾**¡¢**±äÁ¿×·×Ù**Óë**¿Í»§¶ËUIÊÊÅä**¡£±¾ÎÄÌṩһÌ×´Ó»ù´¡µ½¸ß½×µÄÅäÖ÷½°¸£¬º­¸Ç»÷ɱµôÂä¡¢ÈÎÎñ½±Àø¡¢ºÏ³É²ú³öµÈÈ«³¡¾°À´Ô´±êʶ£¬³¹µ×½â¾öÍæ¼Ò¶ÔÎïÆ·»ñȡ;¾¶µÄÒÉ»ó¡£

---

### Ò»¡¢ºËÐÄʵÏÖÂß¼­

#### 1. **¼¼ÊõÁ´Â·**
```mermaid
graph TD
A[Íæ¼Ò»ñµÃÎïÆ·] --> B{À´Ô´¼ì²â}
B -->|»÷ɱµôÂä| C[¼Ç¼¹ÖÎïÃû]
B -->|ÈÎÎñ½±Àø| D[¼Ç¼ÈÎÎñID]
B -->|NPC¹ºÂò| E[¼Ç¼NPCÃû]
C/D/E --> F[·¢ËÍÀ´Ô´Ìáʾ]
```



#### 2. **¹Ø¼ü½Å±¾Îļþ**
- **QFunction-0.txt**£º´¦ÀíÎïÆ·»ñÈ¡´¥·¢Ê¼þ£¨@GetItem½Å±¾£©¡£
- **QManage.txt**£ºÈ«¾Ö±äÁ¿¹ÜÀíÓëÀ´Ô´±ê¼Ç¡£
- **Robot.txt**£º¶¨Ê±ÇåÀíÁÙʱ±äÁ¿¡£

---

### ¶þ¡¢»ù´¡ÅäÖ㺻÷ɱµôÂäÀ´Ô´±êʶ

#### 1. **¼Ç¼»÷ɱ¹ÖÎïÃû£¨QManage.txt£©**
```lua
[@OnKillMob]
#ACT
; ¼Ç¼×îºó»÷ɱµÄ¹ÖÎïÃû
SetVariable <$USERNAME>_LastKillMon <$CURRRTARGETNAME>
```



#### 2. **ÎïÆ·»ñÈ¡´¥·¢£¨QFunction-0.txt£©**
```lua
[@GetItem]
#IF
CheckVariable <$USERNAME>_LastKillMon NotEqual ""
CheckItemName <$PARAM(1)> ÍÀÁúµ¶
#ACT
; ·¢ËÍÀ´Ô´Ìáʾ
SendMsg 6 "[<$CURITEMNAME>]À´×Ô£º<$GETVARIABLE <$USERNAME>_LastKillMon>µôÂä"
; Çå³ý±äÁ¿
DelVariable <$USERNAME>_LastKillMon
Break
```



**²ÎÊý˵Ã÷**£º
- `<$PARAM(1)>`£ºµ±Ç°»ñÈ¡µÄÎïÆ·Ãû³Æ¡£
- `SendMsg 6`£ºÔÚÆÁÄ»ÖÐÑë·¢ËÍÏûÏ¢£¨6=»ÆÉ«ÎÄ×Ö£©¡£

---

### Èý¡¢½ø½×³¡¾°£ºÈ«À´Ô´¸²¸Ç·½°¸

#### 1. **ÈÎÎñ½±Àø±êʶ**
```lua
[@FinishQuest]
#ACT
; ¼Ç¼ÈÎÎñID
SetVariable <$USERNAME>_QuestReward <$CURQUESTID>

[@GetItem]
#IF
CheckVariable <$USERNAME>_QuestReward NotEqual ""
#ACT
; Æ¥ÅäÈÎÎñ½±ÀøÎïÆ·
#CALL [\QuestDiary\ÎïÆ·À´Ô´\ÈÎÎñ½±Àø.txt] <$CURQUESTID> <$CURITEMNAME>
DelVariable <$USERNAME>_QuestReward
```



**ÈÎÎñ½±Àø.txt**£º
```ini
[1001]
Item1=Ê¥Õ½½äÖ¸
Source=ÈÎÎñ¡¾³ýħÎÀµÀ¡¿½±Àø
```



#### 2. **NPC¹ºÂò¼Ç¼**
```lua
[@BuyItem]
#ACT
; ¼Ç¼¹ºÂòµÄNPCºÍÎïÆ·
SetVariable <$USERNAME>_BuyNPC <$CURRENTNPCNAME>
SetVariable <$USERNAME>_BuyItem <$CURITEMNAME>

[@GetItem]
#IF
CheckVariable <$USERNAME>_BuyItem Equal <$PARAM(1)>
#ACT
SendMsg 6 "[<$CURITEMNAME>]À´×Ô£ºNPC<$GETVARIABLE <$USERNAME>_BuyNPC>³öÊÛ"
DelVariable <$USERNAME>_BuyNPC
DelVariable <$USERNAME>_BuyItem
```



#### 3. **ºÏ³ÉϵͳÀ´Ô´**
```lua
[@ItemMix]
#ACT
; ¼Ç¼ºÏ³É¹«Ê½ID
SetVariable <$USERNAME>_MixFormula 201

[@GetItem]
#IF
CheckVariable <$USERNAME>_MixFormula NotEqual ""
#ACT
#CALL [\Envir\MixSource.txt] <$GETVARIABLE <$USERNAME>_MixFormula>
DelVariable <$USERNAME>_MixFormula
```



**MixSource.txt**£º
```lua
[201]
Source=ºÏ³É¹«Ê½¡¾Éñ±ø´òÔì¡¿
```



---

### ËÄ¡¢¿Í»§¶ËÓÅ»¯£ºÐü¸¡ÌáʾÓëÌØÐ§

#### 1. **ÎïÆ·Ðü¸¡´°ÏÔʾÀ´Ô´**
ÐÞ¸Ä`ItemTips.txt`£º
```lua
[@GetItemTips]
#IF
CheckVariable Global_ItemSource_<$CURITEMNAME> NotEqual ""
#ACT
AddTextLine »ñȡ;¾¶£º<$GETVARIABLE Global_ItemSource_<$CURITEMNAME>>
```



#### 2. **¶¯Ì¬¹âЧ±êʶ**
```lua
[@GetItem]
#ACT
; Ìí¼ÓÀ´Ô´±ê¼ÇÌØÐ§£¨EffectEx.wil±àºÅ1200Æð£©
SetItemEffect <$CURITEMNAME> 1200
```



---

### Îå¡¢ÐÔÄÜÓÅ»¯Óë·ÀË¢»úÖÆ

#### 1. **±äÁ¿×Ô¶¯ÇåÀí£¨Robot.txt£©**
```ini
#AutoRun NPC MIN 30 @ClearSourceVars

[@ClearSourceVars]
#ACT
ClearVariableByPrefix LastKillMon
ClearVariableByPrefix QuestReward
```



#### 2. **·ÀË¢¼ì²â**
```lua
[@GetItem]
#IF
CheckGetItemCount <$PARAM(1)> > 10
#ACT
SendMsg 6 "Òì³£»ñÈ¡£º<$CURITEMNAME>£¬ÒѼǼ£¡"
AddAntiCheatLog ÎïÆ·Ë¢È¡ <$USERNAME> <$CURITEMNAME>
```



---

### Áù¡¢ÊµÕ½ÎÊÌâ½â¾ö·½°¸

| **ÎÊÌâÏÖÏó** | **Ô­Òò** | **½â¾ö·½°¸** |
|--------------------------|-----------------------|--------------------------------|
| À´Ô´ÌáÊ¾ÖØ¸´´¥·¢ | ±äÁ¿Î´¼°Ê±ÇåÀí | ÔÚ[@GetItem]ĩβÌí¼ÓDelVariable |
| ×é¶Ó»÷ɱ²»¼Ç¼¹ÖÎïÃû | ±äÁ¿Î´¹²Ïí | ʹÓöÓÎé±äÁ¿£ºSetTeamVariable |
| ÎïÆ·À´Ô´ÏÔʾ´íÂÒ | ¶àÏ߳̾ºÕù±äÁ¿ | ¼ÓËø»úÖÆ£ºCheckLock &lt;$USERNAME&gt;_SourceLock |
| ¿Í»§¶ËÐü¸¡´°²»ÏÔʾÀ´Ô´ | ItemTips.txtδ¼ÓÔØ | ÖØÔØ¿Í»§¶ËÅäÖãº@ReloadClientTips |


---

#### ½áÓï
ͨ¹ý·Ö³¡¾°±äÁ¿×·×ÙÓë¶à½Å±¾Áª¶¯£¬GOMÒýÇæ¿ÉʵÏÖ¾«×¼µÄÎïÆ·À´Ô´±êʶϵͳ¡£¶ÔÓڸ߲¢·¢µÄÉÌÒµ·þ£¬½¨Ò齫Ƶ·±¼ì²âµÄÂß¼­Ç¨ÒÆÖÁ»úÆ÷È˽ű¾£¨Robot.txt£©£¬²¢²ÉÓÃRedis»º´æÌæ´úÎļþ±äÁ¿ÒÔÌáÉýÐÔÄÜ¡£Îñ±ØÔÚ²âÊÔ»·¾³ÖÐÄ£ÄâÈ«³¡¾°»ñÈ¡£¨½»Ò×/Óʼþ/ÅÄÂôÐУ©£¬È·±£À´Ô´±ê¼Ç100%׼ȷ¡£

#### 1. ¹¦ÄܸÅÊö

##### ÎïÆ·À´Ô´
ÎïÆ·À´Ô´ÊÇÖ¸Íæ¼Ò¿ÉÒÔͨ¹ýÄÄЩ;¾¶»ñµÃÌØ¶¨µÄÎïÆ·¡£³£¼ûµÄÎïÆ·À´Ô´°üÀ¨£º
- **ÈÎÎñ½±Àø**£ºÍê³ÉÌØ¶¨ÈÎÎñºó»ñµÃ¡£
- **¹ÖÎïµôÂä**£º»÷°ÜÌØ¶¨¹ÖÎïºóËæ»úµôÂä¡£
- **É̳ǹºÂò**£ºÍ¨¹ýÓÎÏ·ÄÚµÄÐéÄâ»õ±Ò¹ºÂò¡£
- **»î¶¯½±Àø**£º²ÎÓëÌØ¶¨»î¶¯ºó»ñµÃ¡£

#### 2. GOMÒýÇæ¼ò½é

##### GOMÒýÇæÌØµã
- **¸ßЧÎȶ¨**£ºGOMÒýÇæÒÔÆä¸ßЧµÄ´¦ÀíÄÜÁ¦ºÍÎȶ¨µÄÔËÐбíÏÖÖø³Æ¡£
- **Ò×ÓÃÐÔÇ¿**£ºGOMÒýÇæÌṩÁ˼ò½àÃ÷Á˵ÄAPI½Ó¿Ú£¬·½±ã¿ª·¢Õß½øÐжþ´Î¿ª·¢¡£
- **¹¦ÄÜÈ«Ãæ**£ºÖ§³Ö¶àÖÖÓÎÏ·ÔªËØµÄÌí¼Ó£¬°üÀ¨µ«²»ÏÞÓÚ¼¼ÄÜ¡¢¹ÖÎï¡¢µØÍ¼µÈ¡£

##### Ö§³Ö×Ô¶¨Ò幦ÄÜ
GOMÒýÇæÔÊÐí¿ª·¢Õßͨ¹ýÐ޸ĴúÂëºÍÅäÖÃÎļþÀ´ÊµÏÖ¸÷ÖÖ×Ô¶¨Ò幦ÄÜ£¬°üÀ¨ÅäÖÃÎïÆ·µÄ»ñȡ;¾¶¡£

#### 3. ÅäÖÃÎïÆ·À´Ô´²½Öè

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

##### ²½Öè¶þ£º´´½¨ÎïÆ·Êý¾Ý±í

###### ÐÞ¸Ä`item_table`
ÔÚÊý¾Ý¿âÖд´½¨Ò»¸öеıíÀ´´æ´¢ÎïÆ·µÄÐÅÏ¢¡£

**´´½¨`item_table`±í**
```sql
CREATE TABLE item_table (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
type INT NOT NULL, -- ÎïÆ·ÀàÐÍ£¨ÈçÎäÆ÷¡¢·À¾ß¡¢Ò©Æ·¡¢×°ÊÎÎïµÈ£©
rarity INT NOT NULL, -- Ï¡Óжȣ¨ÈçÆÕͨ¡¢º±¼û¡¢Ê·Ê«µÈ£©
attributes TEXT -- ÊôÐÔÐÅÏ¢£¨JSON¸ñʽ£©
);
```

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

**²åÈëÎïÆ·Êý¾Ý**
```sql
INSERT INTO item_table (name, type, rarity, attributes) VALUES
('Ìú½£', 1, 1, '{"attack": 10}'),
('ħ·¨Ò©Ë®', 2, 1, '{"health": 50}'),
('¾«¸Ö»¤¼×', 3, 2, '{"defense": 20}');
```

##### ²½ÖèÈý£ºÅäÖÃÈÎÎñ½±Àø

###### ÐÞ¸Ä`task_config.txt`
ÔÚ`config\task_config.txt`ÎļþÖÐÌí¼ÓÈÎÎñ¼°Æä½±ÀøÎïÆ·µÄÅäÖá£

**task_config.txt**
```ini
[Task1]
Title=ÏûÃð¹ÖÊÞ
Description=ÏûÃð10Ö»Ò°ÀÇ
RewardItems=1|1,2|2 -- ¸ñʽ: item_id|quantity,item_id|quantity,...
RewardExp=1000
RewardMoney=500

[Task2]
Title=ÊÕ¼¯²ÄÁÏ
Description=ÊÕ¼¯5¸ö²ÝÒ©
RewardItems=4|5 -- ¼ÙÉè²ÝÒ©µÄIDΪ4
RewardExp=500
RewardMoney=200
```

##### ²½ÖèËÄ£ºÅäÖùÖÎïµôÂä

###### ÐÞ¸Ä`monster_drop_config.txt`
ÔÚ`config\monster_drop_config.txt`ÎļþÖÐÌí¼Ó¹ÖÎï¼°ÆäµôÂäÎïÆ·µÄÅäÖá£

**monster_drop_config.txt**
```ini
[Monster1]
Name=Ò°ÀÇ
DropItems=1|10|0.05,2|5|0.02 -- ¸ñʽ: item_id|min_quantity|max_quantity|drop_rate,item_id|min_quantity|max_quantity|drop_rate,...

[Monster2]
Name=¾ÞÁú
DropItems=3|1|0.01,4|1|0.005
```

##### ²½ÖèÎ壺ÅäÖÃÉ̳ÇÉÌÆ·

###### ÐÞ¸Ä`shop_config.txt`
ÔÚ`config\shop_config.txt`ÎļþÖÐÌí¼ÓÉ̳ÇÉÌÆ·¼°Æä¼Û¸ñµÄÅäÖá£

**shop_config.txt**
```ini
[Shop1]
Name=ÐÂÊÖÉ̵ê
Items=1|1000,2|500,3|2000 -- ¸ñʽ: item_id|price,item_id|price,...

[Shop2]
Name=¸ß¼¶É̵ê
Items=4|3000
```

##### ²½ÖèÁù£º±àдÏà¹ØÂß¼­´úÂë

###### ÐÞ¸Ä`task_handler.cpp`
ÔÚ`src\task_handler.cpp`ÎļþÖÐÌí¼Ó´¦ÀíÈÎÎñÍê³ÉºóµÄ½±ÀøÂß¼­¡£

**task_handler.cpp**
```cpp
#include "task_handler.h"
#include "character.h"
#include "item_handler.h"
#include "packet_builder.h"

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

void TaskHandler::CompleteTask(Character* character, int taskId)
{
ConfigManager* configManager = ConfigManager::GetInstance();
std::string taskConfig = configManager->GetTaskConfig(taskId);

// Parse task configuration
std::istringstream iss(taskConfig);
std::string line;
while (std::getline(iss, line))
{
if (line.find("RewardItems=") != std::string::npos)
{
std::string rewardItemsStr = line.substr(line.find("=") + 1);
std::vector<std::pair<int, int>> rewardItems;
std::stringstream ss(rewardItemsStr);
std::string itemInfo;
while (std::getline(ss, itemInfo, ','))
{
std::stringstream itemStream(itemInfo);
int itemId, quantity;
char delimiter;
itemStream >> itemId >> delimiter >> quantity;
rewardItems.push_back(std::make_pair(itemId, quantity));
}

ItemHandler* itemHandler = ItemHandler::GetInstance();
for (const auto& item : rewardItems)
{
bool success = itemHandler->AddItemToCharacter(character, item.first, item.second);
if (!success)
{
SystemLog::LogWarning("Failed to add item [%d] to character [%d]'s inventory.", item.first, character->GetId());
}
}
}
else if (line.find("RewardExp=") != std::string::npos)
{
int exp = std::stoi(line.substr(line.find("=") + 1));
character->AddExperience(exp);
}
else if (line.find("RewardMoney=") != std::string::npos)
{
int money = std::stoi(line.substr(line.find("=") + 1));
character->AddMoney(money);
}
}

CPacketBuilder response(PACKET_TYPE_TASK_COMPLETE_RESPONSE);
response.WriteByte(TASK_COMPLETE_SUCCESS);
character->SendPacket(response.Build());

SystemLog::LogInfo("Character [%d] completed task [%d].", character->GetId(), taskId);
}
```

###### ÐÞ¸Ä`monster_handler.cpp`
ÔÚ`src\monster_handler.cpp`ÎļþÖÐÌí¼Ó´¦Àí¹ÖÎïËÀÍöºóµÄµôÂäÂß¼­¡£

**monster_handler.cpp**
```cpp
#include "monster_handler.h"
#include "character.h"
#include "item_handler.h"
#include "random_generator.h"
#include "packet_builder.h"

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

void MonsterHandler::KillMonster(Monster* monster, Character* killer)
{
ConfigManager* configManager = ConfigManager::GetInstance();
std::string dropConfig = configManager->GetMonsterDropConfig(monster->GetName());

// Parse drop configuration
std::istringstream iss(dropConfig);
std::string line;
while (std::getline(iss, line))
{
if (line.find("DropItems=") != std::string::npos)
{
std::string dropItemsStr = line.substr(line.find("=") + 1);
std::vector<std::tuple<int, int, int, double>> dropItems; // item_id, min_quantity, max_quantity, drop_rate
std::stringstream ss(dropItemsStr);
std::string itemInfo;
while (std::getline(ss, itemInfo, ','))
{
std::stringstream itemStream(itemInfo);
int itemId, minQuantity, maxQuantity;
double dropRate;
char delimiter;
itemStream >> itemId >> delimiter >> minQuantity >> delimiter >> maxQuantity >> delimiter >> dropRate;
dropItems.emplace_back(itemId, minQuantity, maxQuantity, dropRate);
}

RandomGenerator* randomGen = RandomGenerator::GetInstance();
ItemHandler* itemHandler = ItemHandler::GetInstance();
for (const auto& item : dropItems)
{
int itemId = std::get<0>(item);
int minQuantity = std::get<1>(item);
int maxQuantity = std::get<2>(item);
double dropRate = std::get<3>(item);

if (randomGen->GenerateDouble() < dropRate)
{
int quantity = randomGen->GenerateInt(minQuantity, maxQuantity);
bool success = itemHandler->AddItemToCharacter(killer, itemId, quantity);
if (!success)
{
SystemLog::LogWarning("Failed to add item [%d] to character [%d]'s inventory.", itemId, killer->GetId());
}
}
}
}
}

CPacketBuilder response(PACKET_TYPE_MONSTER_KILL_RESPONSE);
response.WriteByte(MONSTER_KILL_SUCCESS);
killer->SendPacket(response.Build());

SystemLog::LogInfo("Character [%d] killed monster [%s].", killer->GetId(), monster->GetName().c_str());
}
```

###### ÐÞ¸Ä`shop_handler.cpp`
ÔÚ`src\shop_handler.cpp`ÎļþÖÐÌí¼Ó´¦ÀíÉ̳ǹºÂòÂß¼­¡£

**shop_handler.cpp**
```cpp
#include "shop_handler.h"
#include "character.h"
#include "item_handler.h"
#include "packet_builder.h"

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

void ShopHandler::BuyItem(Character* character, int shopId, int itemId)
{
ConfigManager* configManager = ConfigManager::GetInstance();
std::string shopConfig = configManager->GetShopConfig(shopId);

// Parse shop configuration
std::istringstream iss(shopConfig);
std::string line;
while (std::getline(iss, line))
{
if (line.find("Items=") != std::string::npos)
{
std::string itemsStr = line.substr(line.find("=") + 1);
std::vector<std::pair<int, int>> items; // item_id, price
std::stringstream ss(itemsStr);
std::string itemInfo;
while (std::getline(ss, itemInfo, ','))
{
std::stringstream itemStream(itemInfo);
int itemId, price;
char delimiter;
itemStream >> itemId >> delimiter >> price;
items.push_back(std::make_pair(itemId, price));
}

for (const auto& item : items)
{
if (item.first == itemId)
{
if (character->GetMoney() >= item.second)
{
character->SubtractMoney(item.second);
ItemHandler* itemHandler = ItemHandler::GetInstance();
bool success = itemHandler->AddItemToCharacter(character, itemId, 1);
if (success)
{
CPacketBuilder response(PACKET_TYPE_SHOP_BUY_RESPONSE);
response.WriteByte(SHOP_BUY_SUCCESS);
character->SendPacket(response.Build());
SystemLog::LogInfo("Character [%d] bought item [%d] from shop [%d].", character->GetId(), itemId, shopId);
}
else
{
CPacketBuilder response(PACKET_TYPE_SHOP_BUY_RESPONSE);
response.WriteByte(SHOP_BUY_FAILURE_INVENTORY_FULL);
character->SendPacket(response.Build());
SystemLog::LogWarning("Failed to add item [%d] to character [%d]'s inventory.", itemId, character->GetId());
}
}
else
{
CPacketBuilder response(PACKET_TYPE_SHOP_BUY_RESPONSE);
response.WriteByte(SHOP_BUY_FAILURE_NOT_ENOUGH_MONEY);
character->SendPacket(response.Build());
SystemLog::LogWarning("Character [%d] does not have enough money to buy item [%d].", character->GetId(), itemId);
}
return;
}
}
}
}

CPacketBuilder response(PACKET_TYPE_SHOP_BUY_RESPONSE);
response.WriteByte(SHOP_BUY_FAILURE_ITEM_NOT_FOUND);
character->SendPacket(response.Build());
SystemLog::LogWarning("Item [%d] not found in shop [%d].", itemId, shopId);
}
```

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

**±àÒë·þÎñÆ÷¶Ë**
```sh
g++ -o game_server src/game_server.cpp src/database_manager.cpp src/task_handler.cpp src/monster_handler.cpp src/shop_handler.cpp src/item_handler.cpp src/inventory.cpp src/character.cpp src/packet_builder.cpp src/config_manager.cpp src/random_generator.cpp -lengine
```

Æô¶¯ÓÎÏ··þÎñÆ÷ºÍ¿Í»§¶Ë£¬¹Û²ìÕû¸öÎïÆ·»ñÈ¡Á÷³ÌÊÇ·ñÕý³£¹¤×÷¡£

**Æô¶¯·þÎñÆ÷ÃüÁî**
```sh
start game_server.exe
start client.exe
```

##### ²½Öè°Ë£ºÑéÖ¤ÎïÆ·»ñȡЧ¹û

###### ²âÊÔÈÎÎñ½±Àø
1. Æô¶¯ÓÎÏ··þÎñÆ÷¡£
2. ʹÓÿͻ§¶ËµÇ¼ÓÎÏ·¡£
3. ½ÓÊܲ¢Íê³ÉÈÎÎñ¡£
4. ¼ì²é½ÇÉ«±³°üÖÐÊÇ·ñ³öÏÖÈÎÎñ½±ÀøÎïÆ·¡£

**²âÊÔÈÎÎñ½±ÀøÁ÷³Ì**
```plaintext
1. ½øÈëÓÎÏ·ºó£¬½ÓÊÜÈÎÎñ“ÏûÃð¹ÖÊÞ”¡£
2. Íê³ÉÈÎÎñÒªÇó£¬É±ËÀ10Ö»Ò°ÀÇ¡£
3. Ìá½»ÈÎÎñ£¬¼ì²é±³°üÖÐÊÇ·ñ³öÏÖÁËÌú½£ºÍħ·¨Ò©Ë®¡£
```

###### ²âÊÔ¹ÖÎïµôÂä
1. Æô¶¯ÓÎÏ··þÎñÆ÷¡£
2. ʹÓÿͻ§¶ËµÇ¼ÓÎÏ·¡£
3. »÷°ÜÒ°ÀÇ»ò¾ÞÁú¡£
4. ¼ì²é½ÇÉ«±³°üÖÐÊÇ·ñ³öÏÖ¹ÖÎïµôÂäÎïÆ·¡£

**²âÊÔ¹ÖÎïµôÂäÁ÷³Ì**
```plaintext
1. ½øÈëÓÎÏ·ºó£¬Ñ°ÕÒÒ°ÀÇ»ò¾ÞÁú¡£
2. »÷°ÜÒ°ÀÇ£¬ÓÐÒ»¶¨¸ÅÂÊ»ñµÃÌú½£»òħ·¨Ò©Ë®¡£
3. »÷°Ü¾ÞÁú£¬ÓÐÒ»¶¨¸ÅÂÊ»ñµÃ¾«¸Ö»¤¼×»ò²ÝÒ©¡£
```

###### ²âÊÔÉ̳ǹºÂò
1. Æô¶¯ÓÎÏ··þÎñÆ÷¡£
2. ʹÓÿͻ§¶ËµÇ¼ÓÎÏ·¡£
3. ´ò¿ªÉ̳ǽçÃæ¡£
4. ¹ºÂòÎïÆ·²¢¼ì²é±³°üÖÐÊÇ·ñ³öÏÖÏàÓ¦ÎïÆ·¡£

**²âÊÔÉ̳ǹºÂòÁ÷³Ì**
```plaintext
1. ½øÈëÓÎÏ·ºó£¬´ò¿ªÐÂÊÖÉ̵ꡣ
2. ʹÓÃÓÎÏ·ÄÚ»õ±Ò¹ºÂòÌú½£¡£
3. ¼ì²é±³°üÖÐÊÇ·ñ³öÏÖÁËÌú½£¡£
```

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

##### ²é¿´ÓÎÏ··þÎñÆ÷ÈÕÖ¾
´ò¿ªÓÎÏ··þÎñÆ÷µÄÈÕÖ¾Îļþ£¨Í¨³£Î»ÓÚ`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: Character [1] logged in.
[2023-10-01 12:34:56] INFO: Character [1] accepted task [1].
[2023-10-01 12:34:56] INFO: Character [1] killed monster [Ò°ÀÇ].
[2023-10-01 12:34:56] INFO: Character [1] completed task [1].
[2023-10-01 12:34:56] INFO: Added item [1]: Ìú½£ to character [1].
[2023-10-01 12:34:56] INFO: Added item [2]: ħ·¨Ò©Ë® to character [1].
[2023-10-01 12:34:56] INFO: Character [1] opened shop [1].
[2023-10-01 12:34:56] INFO: Character [1] bought item [1] from shop [1].
```

¸ù¾ÝÈÕÖ¾ÖеÄÐÅÏ¢£¬È·ÈÏÓÎÏ··þÎñÆ÷ÊÇ·ñÕý³£ÔËÐÐÒÔ¼°ÎïÆ·»ñÈ¡²Ù×÷ÊÇ·ñÕýÈ·Ö´ÐС£

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

**¿Í»§¶ËÈÕ־ʾÀý**
```plaintext
[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: Logged in as testuser.
[2023-10-01 12:34:56] INFO: Accepted task [1].
[2023-10-01 12:34:56] INFO: Killed monster [Ò°ÀÇ].
[2023-10-01 12:34:56] INFO: Completed task [1].
[2023-10-01 12:34:56] INFO: Received message: You received a Ìú½£!
[2023-10-01 12:34:56] INFO: Received message: You received a ħ·¨Ò©Ë®!
[2023-10-01 12:34:56] INFO: Opened shop [1].
[2023-10-01 12:34:56] INFO: Bought item [1] from shop [1].
```

¸ù¾ÝÈÕÖ¾ÖеÄÐÅÏ¢£¬È·ÈϿͻ§¶ËÊÇ·ñÕýÈ·½ÓÊÕÁË·þÎñÆ÷µÄÏìÓ¦²¢ÇÒÏÔʾÁËÏàÓ¦µÄ½á¹û¡£

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

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

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

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

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

##### ÎÊÌâÎ壺ÈÎÎñ½±ÀøÎ´µ½ÕË
- **¼ì²éÈÎÎñÅäÖÃ**£ºÈ·±£`task_config.txt`ÖеÄÈÎÎñÅäÖÃÕýÈ·ÎÞÎó¡£
- **¼ì²éÈÎÎñÍê³ÉÂß¼­**£ºÈ·±£`task_handler.cpp`ÖеÄÈÎÎñÍê³ÉÂß¼­ÕýÈ·ÎÞÎó¡£
- **¼ì²éÈÕÖ¾Îļþ**£º²é¿´ÈÕÖ¾ÎļþÒÔÈ·¶¨ÊÇ·ñÓÐÈÎÎñÍê³Éʧ°ÜµÄ¼Ç¼¡£

##### ÎÊÌâÁù£º¹ÖÎïδµôÂäÎïÆ·
- **¼ì²é¹ÖÎïµôÂäÅäÖÃ**£ºÈ·±£`monster_drop_config.txt`ÖеĵôÂäÅäÖÃÕýÈ·ÎÞÎó¡£
- **¼ì²é¹ÖÎï»÷ɱÂß¼­**£ºÈ·±£`monster_handler.cpp`ÖеĹÖÎï»÷ɱÂß¼­ÕýÈ·ÎÞÎó¡£
- **¼ì²éÈÕÖ¾Îļþ**£º²é¿´ÈÕÖ¾ÎļþÒÔÈ·¶¨ÊÇ·ñÓйÖÎï»÷ɱʧ°ÜµÄ¼Ç¼¡£

##### ÎÊÌâÆß£ºÉ̳ǹºÂòʧ°Ü
- **¼ì²éÉ̳ÇÅäÖÃ**£ºÈ·±£`shop_config.txt`ÖеÄÉ̳ÇÅäÖÃÕýÈ·ÎÞÎó¡£
- **¼ì²é¹ºÂòÂß¼­**£ºÈ·±£`shop_handler.cpp`ÖеĹºÂòÂß¼­ÕýÈ·ÎÞÎó¡£
- **¼ì²éÈÕÖ¾Îļþ**£º²é¿´ÈÕÖ¾ÎļþÒÔÈ·¶¨ÊÇ·ñÓйºÂòʧ°ÜµÄ¼Ç¼¡£

##### ÎÊÌâ°Ë£ºÊý¾Ý¿âÁ¬½Óʧ°Ü
- **¼ì²éÊý¾Ý¿âÅäÖÃ**£ºÈ·±£`game_config.txt`ÖеÄÊý¾Ý¿âÅäÖÃÕýÈ·¡£
- **¼ì²éÊý¾Ý¿â·þÎñ**£ºÈ·±£Êý¾Ý¿â·þÎñÕýÔÚÔËÐв¢ÇÒ¿ÉÒÔ·ÃÎÊ¡£
- **¼ì²éÍøÂçÉèÖÃ**£ºÈ·±£·þÎñÆ÷Äܹ»·ÃÎÊÊý¾Ý¿âËùÔÚµÄÖ÷»ú¡£

#### 6. ×ܽá
ͨ¹ýÒÔÉϲ½Ö裬ÄãÓ¦¸ÃÄܹ»ÔÚGOM´«ÆæÒýÇæÖгɹ¦ÅäÖú͹ÜÀíÎïÆ·µÄ»ñȡ;¾¶¡£Õâ²»½öÌáÉýÁËÓÎÏ·µÄƽºâÐÔ£¬»¹ÔöÇ¿ÁËÍæ¼ÒµÄÓÎÏ·ÌåÑ顣ϣÍûÕâÆª½Ì³Ì¶ÔÄãÓÐËù°ïÖú£¡