一、核心漏洞成因拆解
1. 背包满拾取判定缺失(核心漏洞)
现有脚本[@MapEventPickUpItem]标签下无任何拾取条件判断,仅执行拾取提示与定时器设置。当玩家背包满时,系统虽触发拾取事件提示、显示红箭头,但实际未完成宝盒交付(背包无存储空间),脚本却默认玩家已持有宝盒,导致后续开奖逻辑失控,背包满玩家均可触发开奖。
2. 开奖条件校验失效
[@开奖]标签仅以“equal N6 0”作为开奖条件,无宝盒持有校验。N6变量无专属绑定逻辑,无法对应“玩家持有宝盒”状态,任意玩家均可通过触发@打开宝盒指令满足条件,造成无限开奖、多人开奖的混乱局面。
3. 定时器与变量逻辑混乱
脚本设置SetOnTimer 7 30(30秒定时器),但未绑定定时器触发的开奖逻辑,且未限定定时器仅对持有宝盒玩家生效。同时SetOffTimer 17关闭的定时器编号与开启的7号不匹配,定时器无法正常终止,进一步加剧开奖紊乱。
4. 冗余代码引发的潜在冲突
[@DropItem]标签下重复5条相同提示信息,虽不直接引发漏洞,但会占用脚本执行资源;[@打开宝盒]标签无任何条件判断,直接跳转开奖,未做权限与状态过滤,放大漏洞影响范围。
二、完整修复脚本(适配主流引擎,可直接替换)
修复核心:补充背包空间校验、宝盒持有判定、变量专属绑定、定时器精准控制,同时清理冗余代码,确保逻辑闭环。
[@DropItem]
#IF
CHECKLEVELEX > 1
#ACT
SendMsg 0 宝盒已掉落在:[%M].坐标:[%x:%y]
sendmsg 5 对不起!你扔掉了宝盒,已被踢下线,请小退重新登录!
KICK
Break
[@MapEventPickUpItem]
#IF
CHECKITEM 宝盒 0 // 校验玩家当前无宝盒,避免重复拾取
CHECKBAGSPACE 1 // 校验背包至少有1格空闲空间
#ACT
GIVE 宝盒 1 // 确认拾取成功,强制交付宝盒
SendMsg 0 宝盒已经在:[%M].坐标:[%x:%y]被玩家〖<$USERNAME>〗捡起
SENDMSG 0 玩家〖<$USERNAME>〗携带宝盒出现在[%M][%x:%y],宝盒藏有稀有道具,仅限持有者开奖!
SendCenterMsg 180 251 宝盒开启倒计时30分钟,仅限持有者操作! 0 60
SetOnTimer 7 1800 // 30分钟=1800秒,修正定时器时长
SET N6 1800 // 绑定倒计时变量,与定时器同步
SET Q1 <$USERNAME> // 记录宝盒持有者名称,绑定专属状态
#CALL [\游戏登陆\顶戴花翎.txt] @顶戴花翎
#ELSEACT
SENDMSG 5 背包空间不足或已持有宝盒,无法拾取!
Break
[@打开宝盒]
#IF
CHECKITEM 宝盒 1 // 校验玩家持有宝盒
EQUAL Q1 <$USERNAME> // 校验为当前宝盒持有者
#ACT
movr N6 0 // 触发开奖,重置倒计时变量
goto @开奖
#ELSEACT
SENDMSG 5 你非宝盒持有者,无法开启!
Break
[@开奖]
#IF
equal N6 0
CHECKITEM 宝盒 1 // 二次校验宝盒持有,防止漏洞绕过
#act
take 宝盒 1 // 回收宝盒,避免重复使用
GIVE 情侣男装 1
SENDMSG 1 恭喜〖<$USERNAME>〗抢宝成功,获得≮情侣男装≯一件!每日限3次,准时参与解锁更多道具技能!
SetOffTimer 7 // 关闭对应7号定时器
SET Q1 "" // 清空持有者记录
SET N6 0 // 重置变量
break
#ELSEACT
SENDMSG 5 开奖条件不满足,无法开奖!
Break
// 新增定时器触发脚本,防止玩家未手动开奖时自动失效
[@OnTimer7]
#IF
equal N6 0
#ACT
SendMsg 0 宝盒倒计时结束,未及时开启,已失效!
SET Q1 ""
SetOffTimer 7
Break
#ELSE
#ACT
DEC N6 1
SendCenterMsg 180 251 宝盒剩余[N6]秒开启,仅限持有者操作! 0 60
Break
三、关键修复点详解
1. 拾取环节双重校验
新增“CHECKITEM 宝盒 0”与“CHECKBAGSPACE 1”两条条件指令:前者确保同一玩家不会重复拾取宝盒,后者强制要求背包有空闲空间才可拾取,从源头杜绝“背包满却判定拾取成功”的漏洞。拾取成功后主动执行“GIVE 宝盒 1”,确保宝盒切实交付至玩家背包。
2. 持有者专属绑定
通过“SET Q1 <$USERNAME>”将宝盒持有者名称存储至Q1变量,在[@打开宝盒]标签中校验当前玩家名称与Q1变量一致,仅允许持有者触发开奖,彻底解决多人均可开奖的问题。开奖后清空Q1变量,释放持有状态。
3. 定时器精准控制
修正定时器时长为1800秒(对应30分钟),新增[@OnTimer7]标签绑定定时器逻辑,实现倒计时实时播报与超时自动失效功能。开奖后关闭对应7号定时器,避免定时器残留引发的重复开奖。
4. 开奖环节二次校验
在[@开奖]标签中补充“CHECKITEM 宝盒 1”,二次确认玩家持有宝盒,防止通过指令绕过拾取环节直接开奖。同时回收宝盒,避免宝盒重复利用导致无限开奖。
5. 冗余代码清理
删除[@DropItem]标签下4条重复提示信息,精简代码结构;优化系统提示文案,明确告知玩家操作结果与限制,提升体验的同时减少脚本执行压力。
四、额外防漏洞强化设置
1. 每日开奖次数限制
在[@开奖]标签#ACT环节添加次数控制逻辑,避免单玩家每日无限参与,示例代码:
CHECKVAR H1 < 3 // H1为每日开奖次数变量
ADD H1 1
SAVEVAR H1 ..\Envir\QuestDiary\TreasureCount.txt // 存储次数数据
SENDMSG 5 今日已参与[%H1]/3次夺宝,剩余次数明日重置!
2. 宝盒唯一性强化
在物品数据库中设置宝盒“不可交易、不可丢弃、不可存入仓库”,字段配置如下:不可交易设为1,不可丢弃设为1,仓库权限设为0,防止玩家通过交易、丢弃宝盒绕过持有校验。
3. 引擎参数辅助防护
启动M2主程序,进入“脚本命令设置”,勾选“物品拾取需校验背包空间”选项,开启引擎层面的拾取防护,与脚本校验形成双重保障,避免脚本逻辑被绕过。
五、脚本部署与测试要点
1. 部署步骤
将修复后脚本替换原文件(路径:Mir200\Envir\market_def\QFunction-0.txt),保存后在M2主程序中执行“重新加载所有脚本”,无需重启服务器即可生效。部署前备份原脚本,便于异常时回滚。
2. 针对性测试方案
(1)背包满场景测试:让玩家背包装满物品,站在宝盒掉落位置,验证是否提示“背包空间不足”,无红箭头显示,无法触发开奖。
(2)多人拾取测试:多名玩家同时抢夺宝盒,验证仅背包有空间且首个拾取者获得宝盒,其余玩家提示“已持有宝盒”,无法重复拾取。
(3)开奖权限测试:非持有宝盒玩家触发@打开宝盒指令,验证提示“非持有者”,无法开奖;持有者开奖后宝盒回收,变量与定时器重置。
(4)超时测试:持有者拾取宝盒后不手动开奖,等待30分钟,验证系统提示宝盒失效,持有者背包宝盒不消失但无法开奖,变量清空。
六、常见问题排查
1. 拾取后无宝盒交付
排查“GIVE 宝盒 1”指令中宝盒名称与物品数据库完全一致,区分大小写;检查引擎是否禁用物品交付命令,进入M2“脚本命令设置”确认“GIVE”命令已启用。
2. 持有者校验失效
核对变量Q1的赋值与校验逻辑,确保“SET Q1 <$USERNAME>”与“EQUAL Q1 <$USERNAME>”格式正确,无符号遗漏;部分引擎变量区分全局与个人,需将Q1改为个人变量(如U1)。
3. 定时器不生效
检查引擎是否开启定时器功能,进入M2“选项-功能设置”勾选“允许脚本定时器”;确认[@OnTimer7]标签名称正确,定时器编号与SetOnTimer一致。
七、总结
本次夺宝脚本漏洞核心源于拾取判定与开奖校验缺失,修复后通过“背包空间+宝盒持有+持有者绑定+定时器精准控制”四重逻辑,彻底解决背包满拾取、无限开奖、多人开奖等问题。脚本适配主流传奇引擎,可直接部署使用,搭配引擎层面防护与针对性测试,能实现稳定的夺宝玩法。后续可根据版本需求,拓展次数限制、道具奖励随机性等功能,进一步完善玩法体验。

