µ±Ç°Î»Öà : 145zÓÎÏ·Õ¾¡¡|¡¡Ä§Á¦±¦±´¡¡|¡¡¼¼Êõ½Ì³Ì¡¡|¡¡

¡¶Ä§Á¦±¦±´¡·¿É³ÖÐø¿ª·¢Êֲ᣺ģ¿é»¯Éè¼Æ + ÎÞ·ì¸üР+ Íæ¼ÒÊý¾ÝÇ¨ÒÆÊµÕ½

Èȶȣº
´Ó“ÄÜÔËÐДµ½“ºÃά»¤”µÄ¼¼ÊõԾǨ

µ±¶É¹ý´î½¨½×¶Î£¬¹¦Äܵü´ú³åÍ»¡¢Éý¼¶µ¼Ö»صµ¡¢Íæ¼ÒÊý¾Ý¶ªÊ§³ÉΪÐÂµÄØ¬ÃΡ£±¾ÎĽ«½â¾öÈý´óºËÐÄÍ´µã£º
1️⃣ Ä£¿é»¯¼Ü¹¹Éè¼Æ£¨±ÜÃâ“Ç£Ò»·¢±ÀÈ«·þ”£©
2️⃣ ÈȸüÐÂÓë°æ±¾Æ½»¬Éý¼¶£¨¸æ±ðÍ£·þά»¤£©
3️⃣ Íæ¼ÒÊý¾ÝÎÞ·ìÇ¨ÒÆ£¨Ó²ºË±¸·ÝÓë¼æÈÝÐÔ·½°¸£©
ºËÐÄÔ­Ôò£ºÓù¤³Ì»¯Ë¼Î¬¹ÜÀí£¬Èû³¾É·þÎñ³ÖÐøÎȶ¨ÔËÐÐ

Ò»¡¢Ä£¿é»¯¸ÄÔ죺½¨Á¢Áé»î¿ÉÀ©Õ¹µÄ¼Ü¹¹
½âñîºËÐÄϵͳ£¨²Î¿¼Ä£ÐÍ£©

graph TB
A[ÓÎÏ·ºËÐÄÒýÇæ] --> B(Õ½¶·ÏµÍ³Ä£¿é)
--> C(¾­¼Ãϵͳģ¿é)

--> D(ÈÎÎñϵͳģ¿é)

--> E[½ÚÈջ²å¼þ]

--> F[½»Ò×Êг¡²å¼þ]

style A fill:#f9f,stroke:#333
style E fill:#cfc,stroke:#090

¹Ø¼ü²Ù×÷²½Ö裺

²½Öè1£º·ÖÀëÅäÖÃÎļþ

´´½¨ /modules/ Ŀ¼£¬°´¹¦Äܲð·Ö£º
config/
©À©¤©¤ core.conf # ºËÐIJÎÊý
©À©¤©¤ battle/ # Õ½¶·Ä£¿é
©À©¤©¤ pvp.conf

©¸©¤©¤ skill.conf

©À©¤©¤ economy/ # ¾­¼ÃÄ£¿é
©À©¤©¤ currency.conf

©¸©¤©¤ shop.conf


²½Öè2£º¶¯Ì¬¼ÓÔØÄ£¿é

ÔÚ·þÎñ¶ËÆô¶¯½Å±¾Ìí¼Ó£º
# α´úÂëʾÀý£¨¾ßÌåÓïÑÔÒÀ·þÎñ¶Ë£©
load_module("battle") if battle_enabled else skip()
load_module("auction_house") if economy_enabled else skip()


¶þ¡¢Èȸüм¼Êõ£ºÊµÏÖ7x24Сʱ²»å´»ú
ÅäÖÃÎļþÈÈÖØÔØ·½°¸

Linux ÐźÅÍ¨ÖªÖØÔØ£¨ÎÞÐèÖØÆô½ø³Ì£©

kill -SIGHUP $(pidof map-server) # ÖØÔØµØÍ¼·þÎñÆ÷ÅäÖÃ
kill -SIGUSR1 $(pidof login-server) # ÖØÔØµÇ¼¹æÔò

Lua½Å±¾ÈȸüÐÂÁ÷³Ì

-- ¾É°æ½Å±¾ÔÝÍ£·þÎñ
UnregisterNPC(10001)

-- Ìæ»»½Å±¾Îļþ
os.execute("cp new_quest.lua /scripts/")

-- ÖØÐÂ×¢²áNPC
ReloadLuaCache()
RegisterNPC(10001, "new_quest.lua")

Èý¡¢Íæ¼ÒÊý¾ÝÇ¨ÒÆ£º¿ç°æ±¾Éý¼¶ÁãËðʧ
Êý¾Ý¿âÇ¨ÒÆ¼æÈÝÐÔ¾ØÕó

¾É°æ±¾ а汾 Ç¨ÒÆ¹¤¾ß ·çÏյȼ¶

v1.2 v1.3 ÄÚÖÃÇ¨ÒÆ½Å±¾ ⭐
v1.3 v2.0 db_converter¹¤¾ß ⭐⭐
v2.0 v3.0 È˹¤Ð£Ñé + ²¹¶¡½Å±¾ ⭐⭐⭐

°²È«Ç¨ÒÆËIJ½·¨£º

È«Á¿±¸·Ý

mysqldump -uroot -p cgdb > backup_v1.2.sql

×ֶμæÈÝÐÔɨÃè

¼ì²â¼´½«É¾³ýµÄ×Ö¶Î /

SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'tbl_char'
AND TABLE_SCHEMA = 'cgdb'
AND COLUMN_NAME NOT IN (а汾×Ö¶ÎÁбí);

Ö´ÐÐ×Ô¶¯»¯Ç¨ÒÆ

./db_upgrade --from 1.2 --to 1.3 --user root --db cgdb

Êý¾ÝÍêÕûÐÔУÑé

# ¶Ô±È¹Ø¼ü±í¼Ç¼Êý
SELECT 'tbl_item', COUNT(*) FROM tbl_item UNION ALL
SELECT 'tbl_guild', COUNT(*) FROM tbl_guild;


ËÄ¡¢³¤ÆÚά»¤¹¤¾ßÏä
°æ±¾¿ØÖÆÊµÕ½£¨Git²ßÂÔ£©

·ÖÖ§Ä£ÐÍʾÀý

master -> Îȶ¨Éú²ú»·¾³°æ±¾
develop -> ¹¦Äܼ¯³É·ÖÖ§
feat/monster_ai # ¹ÖÎïAIÖØ¹¹·ÖÖ§
hotfix/login_crash # ½ô¼±²¹¶¡·ÖÖ§

×Ô¶¯»¯²âÊÔ·½°¸£¨Ä£ÄâÍæ¼ÒÐÐΪ£©

ʹÓÃPython+seleniumÄ£ÄâµÇ¼ս¶·

def test_player_login():
driver.get("http://127.0.0.1:9040/")
driver.find_element(By.ID, "username").send_keys("test")
driver.find_element(By.ID, "password").send_keys("test123")
driver.find_element(By.CLASS_NAME, "login-btn").click()
assert "½ÇɫѡÔñ" in driver.page_source

Íæ¼ÒÊý¾ÝÀä´æ´¢²ßÂÔ

¹éµµ³¬¹ý180ÌìµÄÀëÏßÍæ¼ÒÊý¾Ý

mysqldump -uroot -p cgdb tbl_char --where="last_login<DATE_SUB(NOW(),INTERVAL 180 DAY)" > inactive_player.sql
ѹËõ¼ÓÃܹ鵵

gpg -c inactive_player.sql && rm inactive_player.sql

½áÓÈü¼ÊõÇ黳Àú¾ÃÃÖÐÂ

ͨ¹ýÄ£¿é»¯Éè¼Æ¡¢×Ô¶¯»¯ÔËάÓëÑϽ÷µÄÊý¾Ý¹ÜÀí£¬ÄãµÄ¿ÉʵÏÖ£º
✅ ¹¦ÄܸüÐÂÌáËÙ£¨Ä£¿é¶ÀÁ¢¿ª·¢»¥²»Ó°Ï죩
✅ Íæ¼ÒÌåÑéÎÞË𣨰汾Éý¼¶ÎÞÐèɾµµ£©
✅ ÀúÊ·Êý¾Ý´«³Ð£¨Ê®Äê½ÇÉ«Êý¾ÝÍêÕû±£Áô£©
⚠️ ÖÕ¼«¾¯Ê¾£º

- ËùÓпª·¢ÐÐΪӦͣÁôÔÚ ¼¼ÊõÑéÖ¤²ãÃæ

- ´æµµÊý¾Ý½¨Òé ¶¨ÆÚÇå³ýÃô¸ÐÐÅÏ¢£¨ÈçÊÖ»úºÅ¡¢Éí·ÝÖ¤£©

- ¹¦ÄÜÉè¼Æ±ÜÃâ ½üËÆ¹Ù·½ÉÌÒµ»¯Ä£ÐÍ£¨Èç³é½±×ªÅÌ£©

¼¼ÊõÊÇ»ØÒäµÄÔØÌ壬·¨ÂÉÊÇÔØÌåµÄ¹ìµÀ¡£ µ±Ã¿Ò»ÐдúÂ붼Ϊ´¿´âµÄÈȰ®¶øÉú£¬·½ÄÜÔÚÇà´º¼ÇÒäÓë·¨ÂɺìÏ߼䣬ÕÒµ½×î°²ÐĵĹéËÞ¡£
¸½¿ª·¢Ð­×÷ÍÆ¼ö£º

- ÏîÄ¿¹ÜÀí£ºJira (¹¦Äܵü´ú×·×Ù)

- ÎĵµÐ­×÷£ºNotion (Ä£¿é½Ó¿ÚÎĵµ)

- ´úÂëÍйܣº×Ô½¨Gitea (±ÜÃâ±ÕÔ´´úÂëÍâй)