###一、问题核心与设计思路
用户反馈的"沙城主换人可重复领取"问题,本质在于传统脚本仅检测**角色名或行会名**,未绑定**行会唯一标识**与**时间戳验证**。根据中攻沙奖励逻辑,需实现以下核心功能:
1.**行会唯一性锁**:通过`GUILDUNIQUEID`绑定行会唯一标识,即使沙城易主,原行会已领取仍无法重复。
2.**全局时间戳检测**:利用`G变量`记录领取日期,实现每日仅一次领取限制。
3.**双重验证机制**:先校验是否为当前沙城主,再检测行会是否已领取。
---
###二、完整防重复领取脚本
```lua
;-----------------------------------------
;沙城领奖NPC脚本(Merchant.txt配置)
;文件路径:Mir200\Envir\Market_Def\沙城奖励-3
;-----------------------------------------
[@main]
#IF
ISCASTLEMASTER;检测是否为沙城主
#ACT
MOVS0<$GUILDUNIQUEID>;获取行会唯一ID
GetGlobalVarG99S1;读取全局变量G99(记录上次领取日期)
GetGlobalVarG100S2;读取全局变量G100(记录领取行会ID)
#IF
EQUALS0<$STR(S2)>;当前行会是否已领取
CHECKTEXTLIST..\QuestDiary\沙城日志\已领奖日期.txt<$STR(S1)>;日期验证
#SAY
您所在行会今日已领取过攻沙奖励!\
<离开/@exit>
#ELSESAY
尊敬的沙城主【<$USERNAME>】,今日可领取攻沙奖励:\
<领取元宝奖励/@getreward>\
<查看领取记录/@checklog>\
<离开/@exit>
[@getreward]
#IF
HOUR2222;限时22:00-23:00(根据时间规则)
ISCASTLEMASTER
SMALL<$STR(G99)><$DATENUM>;日期是否更新
#ACT
CALCVARG99=<$DATENUM>;更新全局日期变量
SAVEVARG99..\QuestDiary\沙城日志\全局变量.txt
CALCVARG100=<$GUILDUNIQUEID>;绑定行会唯一ID
SAVEVARG100..\QuestDiary\沙城日志\全局变量.txt
AddTextListEx..\QuestDiary\沙城日志\已领奖日期.txt<$STR(G99)>;记录日期
GAMEGOLD+200000;发放20万元宝(数值可调)
SENDMSG6【系统】沙城奖励已发放至行会【<$GUILDNAME>】金库!
#ELSESAY
领取失败!请检查:\
1.当前时间非22:00-23:00\
2.今日奖励已领取\
3.非沙城主无法操作
```
---
###三、关键技术解析
####1.**行会唯一ID绑定**
-**`<$GUILDUNIQUEID>`**:引擎生成的行会唯一标识码,即使行会更名或城主更换,ID不变。
-**全局变量G100**:记录最后一次领取奖励的行会ID,防止跨行会重复领取。
####2.**时间戳防跨天漏洞**
-**`<$DATENUM>`**:获取系统日期数字(如20240331),比传统`CHECKTIME`更精准。
-**双验证机制**:
-`CALCVARG99=<$DATENUM>`更新领取日期
-`CHECKTEXTLIST`检测日期文件,避免变量被篡改。
####3.**日志追踪与防篡改**
-**文本记录**:在`QuestDiary\沙城日志`目录下生成:
-`已领奖日期.txt`:记录所有领取日期
-`全局变量.txt`:存储G99/G100变量值
-**SAVEVAR命令**:持久化存储变量,重启服务器不丢失。
---
###四、进阶优化方案
####1.**行会金库替代个人领取**
```lua
#ACT
GUILDGAMEGOLD+200000;奖励发放至行会金库
SENDMSG0【全服公告】行会【<$GUILDNAME>】成功领取今日攻沙奖励20万元宝!
```
通过`GUILDGAMEGOLD`实现奖励归属行会,避免个人城主独占(需M2支持行会资金功能)。
####2.**多维度安全校验**
```lua
#IF
CHECKVARLIST..\QuestDiary\沙城日志\封禁行会.txt<$GUILDUNIQUEID>
#SAY
您的行会因违规已被禁止领取奖励!
```
加入封禁名单检测,增强反作弊能力。
####3.**自动清理过期记录**
```lua
#CALL[\系统任务\定时清理.txt]@clearlog
;定时清理脚本(每日0点执行)
[@clearlog]
#IF
EQUAL<$SERVERDAY>1
#ACT
CLEARVARG99G100
DELTEXTLIST..\QuestDiary\沙城日志\已领奖日期.txt*
```
避免日志文件无限膨胀。
---
###五、常见问题排查
####1.**换城主仍能领取**
-**原因**:未使用`<$GUILDUNIQUEID>`,误用`<$GUILDNAME>`检测。
-**解决**:确保脚本中所有行会标识均采用唯一ID。
####2.**变量不保存**
-**检查**:`SAVEVAR`路径是否正确,`全局变量.txt`需有写入权限。
-**命令修正**:
```lua
SAVEVARG99..\QuestDiary\沙城日志\全局变量.txt
```
####3.**时间检测失效**
-**校准**:在M2控制台输入`@DATE`查看服务器时间,时区需与脚本匹配。
-**备用方案**:
```lua
#IF
CHECKTIME22:00-23:00
```
用户反馈的"沙城主换人可重复领取"问题,本质在于传统脚本仅检测**角色名或行会名**,未绑定**行会唯一标识**与**时间戳验证**。根据中攻沙奖励逻辑,需实现以下核心功能:
1.**行会唯一性锁**:通过`GUILDUNIQUEID`绑定行会唯一标识,即使沙城易主,原行会已领取仍无法重复。
2.**全局时间戳检测**:利用`G变量`记录领取日期,实现每日仅一次领取限制。
3.**双重验证机制**:先校验是否为当前沙城主,再检测行会是否已领取。
---
###二、完整防重复领取脚本
```lua
;-----------------------------------------
;沙城领奖NPC脚本(Merchant.txt配置)
;文件路径:Mir200\Envir\Market_Def\沙城奖励-3
;-----------------------------------------
[@main]
#IF
ISCASTLEMASTER;检测是否为沙城主
#ACT
MOVS0<$GUILDUNIQUEID>;获取行会唯一ID
GetGlobalVarG99S1;读取全局变量G99(记录上次领取日期)
GetGlobalVarG100S2;读取全局变量G100(记录领取行会ID)
#IF
EQUALS0<$STR(S2)>;当前行会是否已领取
CHECKTEXTLIST..\QuestDiary\沙城日志\已领奖日期.txt<$STR(S1)>;日期验证
#SAY
您所在行会今日已领取过攻沙奖励!\
<离开/@exit>
#ELSESAY
尊敬的沙城主【<$USERNAME>】,今日可领取攻沙奖励:\
<领取元宝奖励/@getreward>\
<查看领取记录/@checklog>\
<离开/@exit>
[@getreward]
#IF
HOUR2222;限时22:00-23:00(根据时间规则)
ISCASTLEMASTER
SMALL<$STR(G99)><$DATENUM>;日期是否更新
#ACT
CALCVARG99=<$DATENUM>;更新全局日期变量
SAVEVARG99..\QuestDiary\沙城日志\全局变量.txt
CALCVARG100=<$GUILDUNIQUEID>;绑定行会唯一ID
SAVEVARG100..\QuestDiary\沙城日志\全局变量.txt
AddTextListEx..\QuestDiary\沙城日志\已领奖日期.txt<$STR(G99)>;记录日期
GAMEGOLD+200000;发放20万元宝(数值可调)
SENDMSG6【系统】沙城奖励已发放至行会【<$GUILDNAME>】金库!
#ELSESAY
领取失败!请检查:\
1.当前时间非22:00-23:00\
2.今日奖励已领取\
3.非沙城主无法操作
```
---
###三、关键技术解析
####1.**行会唯一ID绑定**
-**`<$GUILDUNIQUEID>`**:引擎生成的行会唯一标识码,即使行会更名或城主更换,ID不变。
-**全局变量G100**:记录最后一次领取奖励的行会ID,防止跨行会重复领取。
####2.**时间戳防跨天漏洞**
-**`<$DATENUM>`**:获取系统日期数字(如20240331),比传统`CHECKTIME`更精准。
-**双验证机制**:
-`CALCVARG99=<$DATENUM>`更新领取日期
-`CHECKTEXTLIST`检测日期文件,避免变量被篡改。
####3.**日志追踪与防篡改**
-**文本记录**:在`QuestDiary\沙城日志`目录下生成:
-`已领奖日期.txt`:记录所有领取日期
-`全局变量.txt`:存储G99/G100变量值
-**SAVEVAR命令**:持久化存储变量,重启服务器不丢失。
---
###四、进阶优化方案
####1.**行会金库替代个人领取**
```lua
#ACT
GUILDGAMEGOLD+200000;奖励发放至行会金库
SENDMSG0【全服公告】行会【<$GUILDNAME>】成功领取今日攻沙奖励20万元宝!
```
通过`GUILDGAMEGOLD`实现奖励归属行会,避免个人城主独占(需M2支持行会资金功能)。
####2.**多维度安全校验**
```lua
#IF
CHECKVARLIST..\QuestDiary\沙城日志\封禁行会.txt<$GUILDUNIQUEID>
#SAY
您的行会因违规已被禁止领取奖励!
```
加入封禁名单检测,增强反作弊能力。
####3.**自动清理过期记录**
```lua
#CALL[\系统任务\定时清理.txt]@clearlog
;定时清理脚本(每日0点执行)
[@clearlog]
#IF
EQUAL<$SERVERDAY>1
#ACT
CLEARVARG99G100
DELTEXTLIST..\QuestDiary\沙城日志\已领奖日期.txt*
```
避免日志文件无限膨胀。
---
###五、常见问题排查
####1.**换城主仍能领取**
-**原因**:未使用`<$GUILDUNIQUEID>`,误用`<$GUILDNAME>`检测。
-**解决**:确保脚本中所有行会标识均采用唯一ID。
####2.**变量不保存**
-**检查**:`SAVEVAR`路径是否正确,`全局变量.txt`需有写入权限。
-**命令修正**:
```lua
SAVEVARG99..\QuestDiary\沙城日志\全局变量.txt
```
####3.**时间检测失效**
-**校准**:在M2控制台输入`@DATE`查看服务器时间,时区需与脚本匹配。
-**备用方案**:
```lua
#IF
CHECKTIME22:00-23:00
```

