´Ó“ÄÜÔËÐДµ½“ºÃά»¤”µÄ¼¼ÊõԾǨ
µ±¶É¹ý´î½¨½×¶Î£¬¹¦Äܵü´ú³åÍ»¡¢Éý¼¶µ¼Ö»صµ¡¢Íæ¼ÒÊý¾Ý¶ªÊ§³ÉΪÐÂµÄØ¬ÃΡ£±¾ÎĽ«½â¾öÈý´óºËÐÄÍ´µã£º
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 (±ÜÃâ±ÕÔ´´úÂëÍâй)
µ±¶É¹ý´î½¨½×¶Î£¬¹¦Äܵü´ú³åÍ»¡¢Éý¼¶µ¼Ö»صµ¡¢Íæ¼ÒÊý¾Ý¶ªÊ§³ÉΪÐÂµÄØ¬ÃΡ£±¾ÎĽ«½â¾öÈý´óºËÐÄÍ´µã£º
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 (±ÜÃâ±ÕÔ´´úÂëÍâй)

