####一、游戏自动化脚本基础原理
在开发复古传奇自动化脚本之前,我们需要了解一些基础原理。游戏自动化脚本主要通过以下几种方式实现:
1.**键鼠模拟**:通过程序控制鼠标移动和点击,以及键盘按键
2.**图像识别**:识别游戏画面中的元素,如怪物、血条、物品等
3.**内存操作**:直接读取或修改游戏内存数据(此方法容易被检测)
4.**网络拦截**:拦截和分析游戏网络数据包(需要更高级的技术)
对于大多数玩家而言,基于键鼠模拟和图像识别的脚本是最安全和可行的选择。这种脚本通过分析游戏画面来做出决策,并通过模拟人类操作来执行这些决策。
####二、开发环境搭建
首先,我们需要搭建开发环境并安装必要的库:
```bash
#安装Python3.9或更高版本
#安装必要的库
pipinstallpyautoguiopencv-pythonnumpypillowpywin32
```
我们将使用以下库:
-**PyAutoGUI**:用于控制鼠标和键盘
-**OpenCV**:用于图像识别和处理
-**NumPy**:用于数值计算
-**Pillow**:用于图像处理
-**pywin32**:用于Windows窗口管理
####三、核心功能实现
下面是一个完整的复古传奇自动化脚本实现,包含了自动打怪、拾取物品、喝药和回城等核心功能:
```python
importpyautogui
importcv2
importnumpyasnp
importtime
importwin32gui
importwin32con
importrandom
importlogging
fromenumimportEnum
#配置日志
logging.basicConfig(level=logging.INFOformat='%(asctime)s-%(levelname)s-%(message)s')
logger=logging.getLogger(__name__)
#游戏状态枚举
classGameState(Enum):
IDLE=1#空闲状态
FIGHTING=2#战斗状态
PICKING=3#拾取状态
RETURNING=4#回城状态
REPAIRING=5#修理状态
BUYING=6#购买状态
classLegendBot:
def__init__(self):
#游戏窗口信息
self.game_title="复古传奇"
self.game_hwnd=None
self.game_rect=None
#游戏状态
self.current_state=GameState.IDLE
self.hp_percentage=100
self.mp_percentage=100
self.inventory_full=False
#配置参数
self.config={
"hp_threshold":30#血量低于此值时喝药
"mp_threshold":20#魔法值低于此值时喝蓝
"inventory_threshold":80#背包满的阈值(百分比)
"fight_interval":(1.02.0)#攻击间隔(秒)
"pick_interval":3.0#拾取间隔(秒)
"return_delay":10.0#回城延迟(秒)
"templates_path":"templates/"#模板图片路径
}
#模板图片
self.templates={
"monster":None
"item":None
"hp_bar":None
"mp_bar":None
"inventory":None
"town_npc":None
"repair_button":None
"buy_button":None
}
#加载模板图片
self._load_templates()
def_load_templates(self):
"""加载所有模板图片"""
try:
forkeyinself.templates:
template_path=f"{self.config['templates_path']}{key}.png"
self.templates[key]=cv2.imread(template_path0)
ifself.templates[key]isnotNone:
logger.info(f"成功加载模板:{key}")
else:
logger.warning(f"无法加载模板:{key}")
exceptExceptionase:
logger.error(f"加载模板时出错:{str(e)}")
deffind_game_window(self):
"""查找并激活游戏窗口"""
self.game_hwnd=win32gui.FindWindow(Noneself.game_title)
ifnotself.game_hwnd:
logger.error(f"未找到游戏窗口:{self.game_title}")
returnFalse
#获取窗口位置和大小
rect=win32gui.GetWindowRect(self.game_hwnd)
self.game_rect=(rect[0]rect[1]rect[2]-rect[0]rect[3]-rect[1])
logger.info(f"找到游戏窗口:位置{self.game_rect}")
#激活窗口
win32gui.SetForegroundWindow(self.game_hwnd)
time.sleep(0.5)#等待窗口激活
returnTrue
defcapture_screen(self):
"""截取游戏窗口画面"""
ifnotself.game_rect:
returnNone
lefttopwidthheight=self.game_rect
screenshot=pyautogui.screenshot(region=(lefttopwidthheight))
returncv2.cvtColor(np.array(screenshot)cv2.COLOR_RGB2BGR)
deffind_template(selftemplatethreshold=0.7):
"""在屏幕上查找模板"""
screen=self.capture_screen()
ifscreenisNone:
returnNone
screen_gray=cv2.cvtColor(screencv2.COLOR_BGR2GRAY)
result=cv2.matchTemplate(screen_graytemplatecv2.TM_CCOEFF_NORMED)
min_valmax_valmin_locmax_loc=cv2.minMaxLoc(result)
ifmax_val>=threshold:
hw=template.shape
center_x=max_loc[0]+w//2
center_y=max_loc[1]+h//2
return(center_xcenter_ymax_val)
returnNone
defrecognize_status(self):
"""识别游戏状态(血量、魔法值、背包等)"""
self._recognize_hp()
self._recognize_mp()
self._recognize_inventory()
def_recognize_hp(self):
"""识别当前血量"""
result=self.find_template(self.templates["hp_bar"]threshold=0.8)
ifresult:
xyconfidence=result
#这里需要根据实际游戏的血条位置和颜色进行分析
#简化实现,实际应用中可能需要更复杂的处理
screen=self.capture_screen()
hp_region=screen[y-5:y+5x-50:x+50]
hsv=cv2.cvtColor(hp_regioncv2.COLOR_BGR2HSV)
#定义红色范围(血条通常是红色)
lower_red=np.array([0100100])
upper_red=np.array([10255255])
mask1=cv2.inRange(hsvlower_redupper_red)
lower_red=np.array([160100100])
upper_red=np.array([180255255])
mask2=cv2.inRange(hsvlower_redupper_red)
mask=mask1+mask2
hp_percentage=(np.count_nonzero(mask)/mask.size)*100
self.hp_percentage=hp_percentage
logger.debug(f"当前血量:{hp_percentage:.1f}%")
else:
logger.warning("无法识别血量")
def_recognize_mp(self):
"""识别当前魔法值"""
#实现类似_recognize_hp,但针对魔法条
#简化实现
self.mp_percentage=random.randint(1100)
logger.debug(f"当前魔法值:{self.mp_percentage:.1f}%")
def_recognize_inventory(self):
"""识别背包状态"""
#实现背包状态识别
#简化实现
self.inventory_full=random.random()>0.7
logger.debug(f"背包状态:{'满'ifself.inventory_fullelse'未满'}")
defclick_position(selfxybutton='left'delay=0.3):
"""点击指定位置"""
ifnotself.game_rect:
return
#转换为屏幕坐标
screen_x=self.game_rect[0]+x
screen_y=self.game_rect[1]+y
#添加随机延迟,模拟人类操作
time.sleep(random.uniform(0.1delay))
#移动鼠标并点击
pyautogui.moveTo(screen_xscreen_yduration=0.2+random.random()*0.3)
pyautogui.click(button=button)
defattack_monster(self):
"""寻找并攻击怪物"""
result=self.find_template(self.templates["monster"])
ifresult:
xyconfidence=result
logger.info(f"找到怪物,位置:({x}{y})匹配度:{confidence:.2f}")
self.click_position(xy)
self.current_state=GameState.FIGHTING
returnTrue
logger.info("未找到怪物")
self.current_state=GameState.IDLE
returnFalse
defpick_items(self):
"""寻找并拾取物品"""
result=self.find_template(self.templates["item"])
ifresult:
xyconfidence=result
logger.info(f"找到物品,位置:({x}{y})匹配度:{confidence:.2f}")
self.click_position(xy)
self.current_state=GameState.PICKING
time.sleep(1.0)#等待拾券画
returnTrue
logger.info("未找到物品")
returnFalse
defuse_hp_potion(self):
"""使用血药"""
logger.info("血量过低,使用血药")
pyautogui.press('f4')#假设F4是血药快捷键
time.sleep(0.5)#等待喝药动画
defuse_mp_potion(self):
"""使用蓝药"""
logger.info("魔法值过低,使用蓝药")
pyautogui.press('f5')#假设F5是蓝药快捷键
time.sleep(0.5)#等待喝药动画
defreturn_to_town(self):
"""返回城镇"""
logger.info("准备回城")
pyautogui.press('f2')#假设F2是回城快捷键
self.current_state=GameState.RETURNING
time.sleep(self.config["return_delay"])#等待回城动画
defrepair_equipment(self):
"""修理装备"""
logger.info("准备修理装备")
#寻找NPC
result=self.find_template(self.templates["town_npc"])
ifresult:
xyconfidence=result
logger.info(f"找到NPC,位置:({x}{y})匹配度:{confidence:.2f}")
self.click_position(xy)
time.sleep(1.0)#等待对话打开
#点击修理按钮
repair_result=self.find_template(self.templates["repair_button"])
ifrepair_result:
rxryrconfidence=repair_result
logger.info(f"找到修理按钮,位置:({rx}{ry})匹配度:{rconfidence:.2f}")
self.click_position(rxry)
time.sleep(1.0)#等待修理完成
returnTrue
logger.warning("无法完成修理")
returnFalse
defbuy_supplies(self):
"""购买补给品"""
logger.info("准备购买补给品")
#寻找NPC
result=self.find_template(self.templates["town_npc"])
ifresult:
xyconfidence=result
logger.info(f"找到NPC,位置:({x}{y})匹配度:{confidence:.2f}")
self.click_position(xy)
time.sleep(1.0)#等待对话打开
#点击购买按钮
buy_result=self.find_template(self.templates["buy_button"])
ifbuy_result:
bxbybconfidence=buy_result
logger.info(f"找到购买按钮,位置:({bx}{by})匹配度:{bconfidence:.2f}")
self.click_position(bxby)
time.sleep(1.0)#等待商店打开
#购买操作...
#这里需要根据实际游戏商店界面实现
returnTrue
logger.warning("无法完成购买")
returnFalse
defrun_bot(self):
"""运行脚本主循环"""
ifnotself.find_game_window():
return
logger.info("脚本开始运行,按Ctrl+C终止")
try:
whileTrue:
#识别当前状态
self.recognize_status()
#根据状态决定行动
ifself.hp_percentage<self.config["hp_threshold"]:
self.use_hp_potion()
elifself.mp_percentage<self.config["mp_threshold"]:
self.use_mp_potion()
elifself.inventory_full:
self.return_to_town()
self.repair_equipment()
self.buy_supplies()
#离开城镇返回战斗区域
#这里需要根据实际游戏实现
time.sleep(5.0)
else:
#正常战斗状态
ifnotself.attack_monster():
#没找到怪物,尝试拾取物品
self.pick_items()
#添加随机延迟,避免操作过于规律
delay=random.uniform(0.51.5)
time.sleep(delay)
exceptKeyboardInterrupt:
logger.info("用户中断,脚本停止运行")
#运行脚本
if__name__=="__main__":
bot=LegendBot()
bot.run_bot()
```
####四、图像识别优化技术
为了提高脚本的稳定性和可靠性,我们可以采用以下图像识别优化技术:
1.**多尺度模板匹配**:
```python
deffind_template_multi_scale(selftemplatethreshold=0.7scales=[1.00.91.1]):
"""多尺度模板匹配"""
screen=self.capture_screen()
ifscreenisNone:
returnNone
screen_gray=cv2.cvtColor(screencv2.COLOR_BGR2GRAY)
best_match=None
forscaleinscales:
#调整模板大小
resized_template=cv2.resize(templateNonefx=scalefy=scaleinterpolation=cv2.INTER_CUBIC)
ifresized_template.shape[0]>screen_gray.shape[0]orresized_template.shape[1]>screen_gray.shape[1]:
continue
result=cv2.matchTemplate(screen_grayresized_templatecv2.TM_CCOEFF_NORMED)
min_valmax_valmin_locmax_loc=cv2.minMaxLoc(result)
ifmax_val>thresholdand(best_matchisNoneormax_val>best_match[2]):
hw=resized_template.shape
center_x=max_loc[0]+w//2
center_y=max_loc[1]+h//2
best_match=(center_xcenter_ymax_val)
returnbest_match
```
2.**特征点匹配**:
```python
deffind_template_keypoints(selftemplatethreshold=10):
"""使用特征点匹配"""
screen=self.capture_screen()
ifscreenisNone:
returnNone
screen_gray=cv2.cvtColor(screencv2.COLOR_BGR2GRAY)
#初始化ORB检测器
orb=cv2.ORB_create()
#找到关键点和描述符
kp1des1=orb.detectAndCompute(templateNone)
kp2des2=orb.detectAndCompute(screen_grayNone)
#创建BFMatcher对象
bf=cv2.BFMatcher(cv2.NORM_HAMMINGcrossCheck=True)
#匹配描述符
matches=bf.match(des1des2)
#按距离排序
matches=sorted(matcheskey=lambdax:x.distance)
#如果有足够的匹配点,计算中心点
iflen(matches)>threshold:
points=[kp2[m.trainIdx].ptforminmatches[:threshold]]
center_x=int(sum([p[0]forpinpoints])/len(points))
center_y=int(sum([p[1]forpinpoints])/len(points))
return(center_xcenter_ylen(matches))
returnNone
```
3.**图像预处理**:
```python
defpreprocess_image(selfimage):
"""图像预处理"""
#高斯模糊
blurred=cv2.GaussianBlur(image(55)0)
#灰度转换
gray=cv2.cvtColor(blurredcv2.COLOR_BGR2GRAY)
#直方图均衡化
equalized=cv2.equalizeHist(gray)
#边缘检测
edges=cv2.Canny(equalized50150)
returnedges
```
####五、反检测技术
为了降低被游戏检测到的风险,我们可以采用以下反检测技术:
1.**操作随机化**:
```python
defrandomized_click(selfxybutton='left'):
"""带随机化的点击操作"""
#随机偏移
offset_x=random.randint(-55)
offset_y=random.randint(-55)
#随机移动速度
duration=random.uniform(0.20.5)
#转换为屏幕坐标
screen_x=self.game_rect[0]+x+offset_x
screen_y=self.game_rect[1]+y+offset_y
#移动鼠标并点击
pyautogui.moveTo(screen_xscreen_yduration=duration)
pyautogui.click(button=button)
#随机延迟
time.sleep(random.uniform(0.30.8))
```
2.**行为多样化**:
```python
defrandom_idle_action(self):
"""随机执行一些空闲动作,模拟人类玩家"""
ifrandom.random()<0.1:#10%的概率执行空闲动作
actions=["look_around""check_inventory""adjust_equipment"]
action=random.choice(actions)
ifaction=="look_around":
logger.info("随机环顾四周")
#模拟鼠标移动,环顾四周
pyautogui.moveRel(random.randint(-100100)random.randint(-100100)duration=0.5)
time.sleep(random.uniform(1.02.0))
elifaction=="check_inventory":
logger.info("检查背包")
pyautogui.press('i')#假设I键是背包快捷键
time.sleep(random.uniform(1.02.0))
pyautogui.press('i')
elifaction=="adjust_equipment":
logger.info("调整装备")
pyautogui.press('e')#假设E键是装备快捷键
time.sleep(random.uniform(1.02.0))
pyautogui.press('e')
```
3.**异常处理**:
```python
defhandle_exception(selfe):
"""异常处理,模拟人类反应"""
logger.error(f"发生异常:{str(e)}")
#模拟人类反应
pyautogui.moveRel(random.randint(-5050)random.randint(-5050)duration=0.3)
time.sleep(random.uniform(1.03.0))
#重试机制
retry_count=0
whileretry_count<3:
try:
#尝试恢复操作
self.find_game_window()
time.sleep(2.0)
returnTrue
exceptExceptionasretry_e:
logger.error(f"重试失败:{str(retry_e)}")
retry_count+=1
time.sleep(2.0)
returnFalse
```
####六、脚本使用与配置指南
1.**模板图片准备**:
-在项目目录下创建`templates`文件夹
-截取游戏中的各种元素作为模板,包括怪物、物品、血条、NPC等
-保存为PNG格式,确保图片清晰且背景简单
2.**配置参数调整**:
-根据自己的游戏设置调整快捷键
-根据角色属性调整血量、魔法值阈值
-根据背包大小调整背包满的阈值
3.**脚本运行**:
-确保游戏已启动并可见
-运行脚本,它会自动找到游戏窗口
-脚本将根据游戏状态自动执行相应操作
4.**调试与优化**:
-使用日志信息了解脚本运行状态
-如果识别不准确,调整模板图片或匹配阈值
-如果操作无响应,检查游戏窗口是否被遮挡
通过以上技术和方法,你可以开发出一个功能完整、安全可靠的复古传奇自动化脚本。记住,使用脚本应遵守游戏规则,避免过度依赖,保持游戏的乐趣。
在开发复古传奇自动化脚本之前,我们需要了解一些基础原理。游戏自动化脚本主要通过以下几种方式实现:
1.**键鼠模拟**:通过程序控制鼠标移动和点击,以及键盘按键
2.**图像识别**:识别游戏画面中的元素,如怪物、血条、物品等
3.**内存操作**:直接读取或修改游戏内存数据(此方法容易被检测)
4.**网络拦截**:拦截和分析游戏网络数据包(需要更高级的技术)
对于大多数玩家而言,基于键鼠模拟和图像识别的脚本是最安全和可行的选择。这种脚本通过分析游戏画面来做出决策,并通过模拟人类操作来执行这些决策。
####二、开发环境搭建
首先,我们需要搭建开发环境并安装必要的库:
```bash
#安装Python3.9或更高版本
#安装必要的库
pipinstallpyautoguiopencv-pythonnumpypillowpywin32
```
我们将使用以下库:
-**PyAutoGUI**:用于控制鼠标和键盘
-**OpenCV**:用于图像识别和处理
-**NumPy**:用于数值计算
-**Pillow**:用于图像处理
-**pywin32**:用于Windows窗口管理
####三、核心功能实现
下面是一个完整的复古传奇自动化脚本实现,包含了自动打怪、拾取物品、喝药和回城等核心功能:
```python
importpyautogui
importcv2
importnumpyasnp
importtime
importwin32gui
importwin32con
importrandom
importlogging
fromenumimportEnum
#配置日志
logging.basicConfig(level=logging.INFOformat='%(asctime)s-%(levelname)s-%(message)s')
logger=logging.getLogger(__name__)
#游戏状态枚举
classGameState(Enum):
IDLE=1#空闲状态
FIGHTING=2#战斗状态
PICKING=3#拾取状态
RETURNING=4#回城状态
REPAIRING=5#修理状态
BUYING=6#购买状态
classLegendBot:
def__init__(self):
#游戏窗口信息
self.game_title="复古传奇"
self.game_hwnd=None
self.game_rect=None
#游戏状态
self.current_state=GameState.IDLE
self.hp_percentage=100
self.mp_percentage=100
self.inventory_full=False
#配置参数
self.config={
"hp_threshold":30#血量低于此值时喝药
"mp_threshold":20#魔法值低于此值时喝蓝
"inventory_threshold":80#背包满的阈值(百分比)
"fight_interval":(1.02.0)#攻击间隔(秒)
"pick_interval":3.0#拾取间隔(秒)
"return_delay":10.0#回城延迟(秒)
"templates_path":"templates/"#模板图片路径
}
#模板图片
self.templates={
"monster":None
"item":None
"hp_bar":None
"mp_bar":None
"inventory":None
"town_npc":None
"repair_button":None
"buy_button":None
}
#加载模板图片
self._load_templates()
def_load_templates(self):
"""加载所有模板图片"""
try:
forkeyinself.templates:
template_path=f"{self.config['templates_path']}{key}.png"
self.templates[key]=cv2.imread(template_path0)
ifself.templates[key]isnotNone:
logger.info(f"成功加载模板:{key}")
else:
logger.warning(f"无法加载模板:{key}")
exceptExceptionase:
logger.error(f"加载模板时出错:{str(e)}")
deffind_game_window(self):
"""查找并激活游戏窗口"""
self.game_hwnd=win32gui.FindWindow(Noneself.game_title)
ifnotself.game_hwnd:
logger.error(f"未找到游戏窗口:{self.game_title}")
returnFalse
#获取窗口位置和大小
rect=win32gui.GetWindowRect(self.game_hwnd)
self.game_rect=(rect[0]rect[1]rect[2]-rect[0]rect[3]-rect[1])
logger.info(f"找到游戏窗口:位置{self.game_rect}")
#激活窗口
win32gui.SetForegroundWindow(self.game_hwnd)
time.sleep(0.5)#等待窗口激活
returnTrue
defcapture_screen(self):
"""截取游戏窗口画面"""
ifnotself.game_rect:
returnNone
lefttopwidthheight=self.game_rect
screenshot=pyautogui.screenshot(region=(lefttopwidthheight))
returncv2.cvtColor(np.array(screenshot)cv2.COLOR_RGB2BGR)
deffind_template(selftemplatethreshold=0.7):
"""在屏幕上查找模板"""
screen=self.capture_screen()
ifscreenisNone:
returnNone
screen_gray=cv2.cvtColor(screencv2.COLOR_BGR2GRAY)
result=cv2.matchTemplate(screen_graytemplatecv2.TM_CCOEFF_NORMED)
min_valmax_valmin_locmax_loc=cv2.minMaxLoc(result)
ifmax_val>=threshold:
hw=template.shape
center_x=max_loc[0]+w//2
center_y=max_loc[1]+h//2
return(center_xcenter_ymax_val)
returnNone
defrecognize_status(self):
"""识别游戏状态(血量、魔法值、背包等)"""
self._recognize_hp()
self._recognize_mp()
self._recognize_inventory()
def_recognize_hp(self):
"""识别当前血量"""
result=self.find_template(self.templates["hp_bar"]threshold=0.8)
ifresult:
xyconfidence=result
#这里需要根据实际游戏的血条位置和颜色进行分析
#简化实现,实际应用中可能需要更复杂的处理
screen=self.capture_screen()
hp_region=screen[y-5:y+5x-50:x+50]
hsv=cv2.cvtColor(hp_regioncv2.COLOR_BGR2HSV)
#定义红色范围(血条通常是红色)
lower_red=np.array([0100100])
upper_red=np.array([10255255])
mask1=cv2.inRange(hsvlower_redupper_red)
lower_red=np.array([160100100])
upper_red=np.array([180255255])
mask2=cv2.inRange(hsvlower_redupper_red)
mask=mask1+mask2
hp_percentage=(np.count_nonzero(mask)/mask.size)*100
self.hp_percentage=hp_percentage
logger.debug(f"当前血量:{hp_percentage:.1f}%")
else:
logger.warning("无法识别血量")
def_recognize_mp(self):
"""识别当前魔法值"""
#实现类似_recognize_hp,但针对魔法条
#简化实现
self.mp_percentage=random.randint(1100)
logger.debug(f"当前魔法值:{self.mp_percentage:.1f}%")
def_recognize_inventory(self):
"""识别背包状态"""
#实现背包状态识别
#简化实现
self.inventory_full=random.random()>0.7
logger.debug(f"背包状态:{'满'ifself.inventory_fullelse'未满'}")
defclick_position(selfxybutton='left'delay=0.3):
"""点击指定位置"""
ifnotself.game_rect:
return
#转换为屏幕坐标
screen_x=self.game_rect[0]+x
screen_y=self.game_rect[1]+y
#添加随机延迟,模拟人类操作
time.sleep(random.uniform(0.1delay))
#移动鼠标并点击
pyautogui.moveTo(screen_xscreen_yduration=0.2+random.random()*0.3)
pyautogui.click(button=button)
defattack_monster(self):
"""寻找并攻击怪物"""
result=self.find_template(self.templates["monster"])
ifresult:
xyconfidence=result
logger.info(f"找到怪物,位置:({x}{y})匹配度:{confidence:.2f}")
self.click_position(xy)
self.current_state=GameState.FIGHTING
returnTrue
logger.info("未找到怪物")
self.current_state=GameState.IDLE
returnFalse
defpick_items(self):
"""寻找并拾取物品"""
result=self.find_template(self.templates["item"])
ifresult:
xyconfidence=result
logger.info(f"找到物品,位置:({x}{y})匹配度:{confidence:.2f}")
self.click_position(xy)
self.current_state=GameState.PICKING
time.sleep(1.0)#等待拾券画
returnTrue
logger.info("未找到物品")
returnFalse
defuse_hp_potion(self):
"""使用血药"""
logger.info("血量过低,使用血药")
pyautogui.press('f4')#假设F4是血药快捷键
time.sleep(0.5)#等待喝药动画
defuse_mp_potion(self):
"""使用蓝药"""
logger.info("魔法值过低,使用蓝药")
pyautogui.press('f5')#假设F5是蓝药快捷键
time.sleep(0.5)#等待喝药动画
defreturn_to_town(self):
"""返回城镇"""
logger.info("准备回城")
pyautogui.press('f2')#假设F2是回城快捷键
self.current_state=GameState.RETURNING
time.sleep(self.config["return_delay"])#等待回城动画
defrepair_equipment(self):
"""修理装备"""
logger.info("准备修理装备")
#寻找NPC
result=self.find_template(self.templates["town_npc"])
ifresult:
xyconfidence=result
logger.info(f"找到NPC,位置:({x}{y})匹配度:{confidence:.2f}")
self.click_position(xy)
time.sleep(1.0)#等待对话打开
#点击修理按钮
repair_result=self.find_template(self.templates["repair_button"])
ifrepair_result:
rxryrconfidence=repair_result
logger.info(f"找到修理按钮,位置:({rx}{ry})匹配度:{rconfidence:.2f}")
self.click_position(rxry)
time.sleep(1.0)#等待修理完成
returnTrue
logger.warning("无法完成修理")
returnFalse
defbuy_supplies(self):
"""购买补给品"""
logger.info("准备购买补给品")
#寻找NPC
result=self.find_template(self.templates["town_npc"])
ifresult:
xyconfidence=result
logger.info(f"找到NPC,位置:({x}{y})匹配度:{confidence:.2f}")
self.click_position(xy)
time.sleep(1.0)#等待对话打开
#点击购买按钮
buy_result=self.find_template(self.templates["buy_button"])
ifbuy_result:
bxbybconfidence=buy_result
logger.info(f"找到购买按钮,位置:({bx}{by})匹配度:{bconfidence:.2f}")
self.click_position(bxby)
time.sleep(1.0)#等待商店打开
#购买操作...
#这里需要根据实际游戏商店界面实现
returnTrue
logger.warning("无法完成购买")
returnFalse
defrun_bot(self):
"""运行脚本主循环"""
ifnotself.find_game_window():
return
logger.info("脚本开始运行,按Ctrl+C终止")
try:
whileTrue:
#识别当前状态
self.recognize_status()
#根据状态决定行动
ifself.hp_percentage<self.config["hp_threshold"]:
self.use_hp_potion()
elifself.mp_percentage<self.config["mp_threshold"]:
self.use_mp_potion()
elifself.inventory_full:
self.return_to_town()
self.repair_equipment()
self.buy_supplies()
#离开城镇返回战斗区域
#这里需要根据实际游戏实现
time.sleep(5.0)
else:
#正常战斗状态
ifnotself.attack_monster():
#没找到怪物,尝试拾取物品
self.pick_items()
#添加随机延迟,避免操作过于规律
delay=random.uniform(0.51.5)
time.sleep(delay)
exceptKeyboardInterrupt:
logger.info("用户中断,脚本停止运行")
#运行脚本
if__name__=="__main__":
bot=LegendBot()
bot.run_bot()
```
####四、图像识别优化技术
为了提高脚本的稳定性和可靠性,我们可以采用以下图像识别优化技术:
1.**多尺度模板匹配**:
```python
deffind_template_multi_scale(selftemplatethreshold=0.7scales=[1.00.91.1]):
"""多尺度模板匹配"""
screen=self.capture_screen()
ifscreenisNone:
returnNone
screen_gray=cv2.cvtColor(screencv2.COLOR_BGR2GRAY)
best_match=None
forscaleinscales:
#调整模板大小
resized_template=cv2.resize(templateNonefx=scalefy=scaleinterpolation=cv2.INTER_CUBIC)
ifresized_template.shape[0]>screen_gray.shape[0]orresized_template.shape[1]>screen_gray.shape[1]:
continue
result=cv2.matchTemplate(screen_grayresized_templatecv2.TM_CCOEFF_NORMED)
min_valmax_valmin_locmax_loc=cv2.minMaxLoc(result)
ifmax_val>thresholdand(best_matchisNoneormax_val>best_match[2]):
hw=resized_template.shape
center_x=max_loc[0]+w//2
center_y=max_loc[1]+h//2
best_match=(center_xcenter_ymax_val)
returnbest_match
```
2.**特征点匹配**:
```python
deffind_template_keypoints(selftemplatethreshold=10):
"""使用特征点匹配"""
screen=self.capture_screen()
ifscreenisNone:
returnNone
screen_gray=cv2.cvtColor(screencv2.COLOR_BGR2GRAY)
#初始化ORB检测器
orb=cv2.ORB_create()
#找到关键点和描述符
kp1des1=orb.detectAndCompute(templateNone)
kp2des2=orb.detectAndCompute(screen_grayNone)
#创建BFMatcher对象
bf=cv2.BFMatcher(cv2.NORM_HAMMINGcrossCheck=True)
#匹配描述符
matches=bf.match(des1des2)
#按距离排序
matches=sorted(matcheskey=lambdax:x.distance)
#如果有足够的匹配点,计算中心点
iflen(matches)>threshold:
points=[kp2[m.trainIdx].ptforminmatches[:threshold]]
center_x=int(sum([p[0]forpinpoints])/len(points))
center_y=int(sum([p[1]forpinpoints])/len(points))
return(center_xcenter_ylen(matches))
returnNone
```
3.**图像预处理**:
```python
defpreprocess_image(selfimage):
"""图像预处理"""
#高斯模糊
blurred=cv2.GaussianBlur(image(55)0)
#灰度转换
gray=cv2.cvtColor(blurredcv2.COLOR_BGR2GRAY)
#直方图均衡化
equalized=cv2.equalizeHist(gray)
#边缘检测
edges=cv2.Canny(equalized50150)
returnedges
```
####五、反检测技术
为了降低被游戏检测到的风险,我们可以采用以下反检测技术:
1.**操作随机化**:
```python
defrandomized_click(selfxybutton='left'):
"""带随机化的点击操作"""
#随机偏移
offset_x=random.randint(-55)
offset_y=random.randint(-55)
#随机移动速度
duration=random.uniform(0.20.5)
#转换为屏幕坐标
screen_x=self.game_rect[0]+x+offset_x
screen_y=self.game_rect[1]+y+offset_y
#移动鼠标并点击
pyautogui.moveTo(screen_xscreen_yduration=duration)
pyautogui.click(button=button)
#随机延迟
time.sleep(random.uniform(0.30.8))
```
2.**行为多样化**:
```python
defrandom_idle_action(self):
"""随机执行一些空闲动作,模拟人类玩家"""
ifrandom.random()<0.1:#10%的概率执行空闲动作
actions=["look_around""check_inventory""adjust_equipment"]
action=random.choice(actions)
ifaction=="look_around":
logger.info("随机环顾四周")
#模拟鼠标移动,环顾四周
pyautogui.moveRel(random.randint(-100100)random.randint(-100100)duration=0.5)
time.sleep(random.uniform(1.02.0))
elifaction=="check_inventory":
logger.info("检查背包")
pyautogui.press('i')#假设I键是背包快捷键
time.sleep(random.uniform(1.02.0))
pyautogui.press('i')
elifaction=="adjust_equipment":
logger.info("调整装备")
pyautogui.press('e')#假设E键是装备快捷键
time.sleep(random.uniform(1.02.0))
pyautogui.press('e')
```
3.**异常处理**:
```python
defhandle_exception(selfe):
"""异常处理,模拟人类反应"""
logger.error(f"发生异常:{str(e)}")
#模拟人类反应
pyautogui.moveRel(random.randint(-5050)random.randint(-5050)duration=0.3)
time.sleep(random.uniform(1.03.0))
#重试机制
retry_count=0
whileretry_count<3:
try:
#尝试恢复操作
self.find_game_window()
time.sleep(2.0)
returnTrue
exceptExceptionasretry_e:
logger.error(f"重试失败:{str(retry_e)}")
retry_count+=1
time.sleep(2.0)
returnFalse
```
####六、脚本使用与配置指南
1.**模板图片准备**:
-在项目目录下创建`templates`文件夹
-截取游戏中的各种元素作为模板,包括怪物、物品、血条、NPC等
-保存为PNG格式,确保图片清晰且背景简单
2.**配置参数调整**:
-根据自己的游戏设置调整快捷键
-根据角色属性调整血量、魔法值阈值
-根据背包大小调整背包满的阈值
3.**脚本运行**:
-确保游戏已启动并可见
-运行脚本,它会自动找到游戏窗口
-脚本将根据游戏状态自动执行相应操作
4.**调试与优化**:
-使用日志信息了解脚本运行状态
-如果识别不准确,调整模板图片或匹配阈值
-如果操作无响应,检查游戏窗口是否被遮挡
通过以上技术和方法,你可以开发出一个功能完整、安全可靠的复古传奇自动化脚本。记住,使用脚本应遵守游戏规则,避免过度依赖,保持游戏的乐趣。

