Server: hunt set once per character, rebuild.sh for patch build/deploy/rollback

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
shenlei
2026-09-30 11:01:36 +09:00
co-authored by Claude Opus 5.5
parent d163aab949
commit 3fcb27dd4d
5 changed files with 124 additions and 12 deletions
+16
View File
@@ -94,3 +94,19 @@ NPC safebox checkin/checkout/move、mall checkout、Cube open/add/delete/make。
- `service.h` 默认定义 `_IMPROVED_PACKET_ENCRYPTION_`;classic 客户端必须走
DH2 + CTR,不能用“明文配置项”绕过。若专门做明文诊断,必须复制源码、重新
编译 game,并把它视为与 shipped server 不同的测试构建。
## 203 上的补丁构建、部署与回滚(rebuild.sh)
203 的 game/db 在 40250 源码上打了两个补丁(`inventory-5-pages`、`hunt-set`,按此顺序)。把整个
`tools/server` 复制到服务器(如 `/root/mt-tools`)后:
```sh
sh rebuild.sh check # 每个补丁:applied / missing / conflict
sh rebuild.sh build # 补上缺的补丁,编译 game + db 到 /root/rebuild/<时间>(不动线上)
sh rebuild.sh deploy <目录> # 停服、备份 share/bin/{game,db} 到 /root/backup-bin/<时间>、替换、开服
sh rebuild.sh rollback <备份目录> # 停服、放回备份、开服
sh rebuild.sh data # 重跑数据安装(传送戒指、辅助技能、狩猎礼包、商城/坐骑商店),重启
```
换服务器时:先按上文准备 40250 源码与数据库,做一次 `inventory-5-pages/README.md` 的数据库迁移,
再 `build` → `deploy` → `data`。2026-09-30 在 203 实测 check/build/deploy。
+4 -10
View File
@@ -24,7 +24,8 @@
| 耳环 | 移速 20%、掉宝 20%、对兽人/秘教/不死 各 20% |
属性都是 `item_attr` 表里该部位允许的类型、5 级的值。背包空格(`CountEmptyInventory`,按格数算)少于 15
时不打开;确认前可以取消,礼包不消耗。
时不打开;确认前可以取消,礼包不消耗。每个角色只能打开一次(任务标记 `hunt_set.opened`),
再用礼包只提示、不扣除。
## 文件
@@ -41,16 +42,9 @@
## 构建与部署
```sh
cd /usr/metin2/src && patch -p1 < server.patch
cd server/game/src && gmake -j2 GAMEDIR=/root/hunt-out/new # 不覆盖线上 share/bin/game
cd /usr/metin2/server && sh close.sh
cp share/bin/game <备份>; cp /root/hunt-out/new/game share/bin/game
sh install.sh # 本目录
sh ../npc-shops/install.sh ../npc-shops/item-mall
echo 1 | sh start.sh
```
用 `../rebuild.sh`:`build`(打补丁并编译)→ `deploy <目录>` → `data`(含本目录 install.sh 和商城商店)。
2026-09-30 已在 203 部署。备份在 `/root/backup-hunt-set/`:`questlua_item.cpp.orig`、`bin-<时间>/game`
(旧二进制)、`<时间>/`(locale_list、quest_functions、item_names.txt)。用 GM 角色(武士)实测:礼包打开后
8 件装备属性与上表一致,重新登录后仍在,礼包已扣除;从百店老板娘处以 0 两买到礼包,金钱不变。
限次改动(2026-09-30):同一角色第二次使用礼包不弹对话框,礼包保留。
+7 -1
View File
@@ -28,6 +28,11 @@ quest hunt_set begin
local STEAL_HP, REFLECT_MELEE, EXP, GOLD, DROP = 23, 39, 43, 44, 45
local IMMUNE_STUN, IMMUNE_SLOW, ATT_GRADE = 48, 49, 53
-- One set per character (quest flag hunt_set.opened); the box stays in the bag.
if pc.getqf("opened") == 1 then
syschat("每个角色只能打开一次小狩猎套装礼包。")
return
end
if pc.get_empty_inventory_count() < 15 then
syschat("背包空位不足,请至少留出15格再打开礼包。")
return
@@ -60,7 +65,7 @@ quest hunt_set begin
return
end
-- The dialog waited; check again that the box is still there and the bag has room.
if pc.count_item(50307) < 1 or pc.get_empty_inventory_count() < 15 then
if pc.getqf("opened") == 1 or pc.count_item(50307) < 1 or pc.get_empty_inventory_count() < 15 then
syschat("背包空位不足,请至少留出15格再打开礼包。")
return
end
@@ -70,6 +75,7 @@ quest hunt_set begin
local helmets = { 12209, 12349, 12489, 12629 }
local main, armor, helmet = mains[job + 1], armors[job + 1], helmets[job + 1]
pc.setqf("opened", 1)
pc.remove_item(50307, 1)
hunt_set.give(weapon, { { CRITICAL, 10 }, { PENETRATE, 10 }, { main, 12 }, { DEVIL, 20 }, { UNDEAD, 20 } })
hunt_set.give(armor, { { MAX_HP, 2000 }, { STEAL_HP, 10 }, { ATT_GRADE, 50 }, { REFLECT_MELEE, 10 }, { CAST_SPEED, 20 } })
+96
View File
@@ -0,0 +1,96 @@
#!/bin/sh
# Rebuilds the 203 game/db from the 40250 source with our server patches, deploys it, or rolls it back.
# Run on the server from tools/server (all of tools/server copied there):
#
# sh rebuild.sh check which patches the source has
# sh rebuild.sh build apply missing patches, build game + db into /root/rebuild/<time>
# sh rebuild.sh deploy <dir> stop, back up share/bin/{game,db}, install <dir>/{game,db}, start
# sh rebuild.sh rollback <dir> stop, put a backup (/root/backup-bin/<time>) back, start
# sh rebuild.sh data rerun the data installers (quests, names, shops), then restart
#
# Patches, in order (each is a patch -p1 against /usr/metin2/src, saved byte-exact):
# inventory-5-pages 5-page inventory; needs its DB migration once (inventory-5-pages/README.md)
# hunt-set quest item.set_attribute, free items in extended shops
set -eu
SRC=${SRC:-/usr/metin2/src}
SERVER=${SERVER:-/usr/metin2/server}
HERE=$(cd "$(dirname "$0")" && pwd)
PATCHES="inventory-5-pages hunt-set"
TS=$(date +%Y%m%d-%H%M%S)
patch_state() {
if patch -p1 -R -C -s -f -d "$SRC" < "$HERE/$1/server.patch" > /dev/null 2>&1; then
echo applied
elif patch -p1 -C -s -f -d "$SRC" < "$HERE/$1/server.patch" > /dev/null 2>&1; then
echo missing
else
echo conflict
fi
}
stop_server() {
(cd "$SERVER" && sh close.sh) > /dev/null 2>&1 || true
sleep 8
if ps ax -o command | grep -q '^[.]/\(game\|db\|auth\)'; then echo "server still running" >&2; exit 1; fi
}
start_server() {
(cd "$SERVER" && echo 1 | sh start.sh) > /dev/null 2>&1
sleep 15
echo "running: $(ps ax -o command | grep -c '^[.]/game') game, $(ps ax -o command | grep -c '^[.]/db') db"
}
case ${1:-} in
check)
for p in $PATCHES; do echo "$p: $(patch_state $p)"; done
;;
build)
for p in $PATCHES; do
state=$(patch_state $p)
echo "$p: $state"
case $state in
missing) patch -p1 -s -d "$SRC" < "$HERE/$p/server.patch" ;;
conflict) echo "$p/server.patch does not apply" >&2; exit 1 ;;
esac
done
OUT=/root/rebuild/$TS
mkdir -p "$OUT"
# The Makefiles move the binary to GAMEDIR/DBDIR (default: the live share/bin).
(cd "$SRC/server/game/src" && gmake -j2 GAMEDIR="$OUT") > "$OUT/game.log" 2>&1 || { tail "$OUT/game.log" >&2; exit 1; }
(cd "$SRC/server/db/src" && gmake -j2 DBDIR="$OUT") > "$OUT/db.log" 2>&1 || { tail "$OUT/db.log" >&2; exit 1; }
ls -l "$OUT/game" "$OUT/db"
echo "built: $OUT (sh rebuild.sh deploy $OUT)"
;;
deploy)
NEW=${2:?usage: sh rebuild.sh deploy <dir with game and db>}
[ -x "$NEW/game" ] && [ -x "$NEW/db" ] || { echo "$NEW has no game/db" >&2; exit 1; }
stop_server
BACKUP=/root/backup-bin/$TS
mkdir -p "$BACKUP"
cp -p "$SERVER/share/bin/game" "$SERVER/share/bin/db" "$BACKUP/"
echo "backup: $BACKUP (sh rebuild.sh rollback $BACKUP)"
cp "$NEW/game" "$NEW/db" "$SERVER/share/bin/"
start_server
;;
rollback)
OLD=${2:?usage: sh rebuild.sh rollback <backup dir>}
[ -f "$OLD/game" ] && [ -f "$OLD/db" ] || { echo "$OLD has no game/db" >&2; exit 1; }
stop_server
cp "$OLD/game" "$OLD/db" "$SERVER/share/bin/"
start_server
;;
data)
stop_server
sh "$HERE/ring-warp/install.sh"
sh "$HERE/support-skills/install.sh"
sh "$HERE/hunt-set/install.sh"
sh "$HERE/npc-shops/install.sh" "$HERE/npc-shops/item-mall"
sh "$HERE/npc-shops/install.sh" "$HERE/npc-shops/mount"
start_server
;;
*)
sed -n '2,15p' "$0" >&2
exit 2
;;
esac