#!/usr/bin/env python3 """ 窗口钓鱼自动化脚本 功能:识别指定窗口,循环发送钓鱼和收杆消息,时间间隔相等 """ import time import logging import sys from typing import Optional # 尝试导入自动化库,如果缺失则提示安装 try: import pyautogui import pygetwindow as gw except ImportError as e: print(f"缺少依赖库: {e}") print("请使用 pip install pyautogui pygetwindow 安装") sys.exit(1) # 配置日志 logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler('fishing_bot.log', encoding='utf-8'), logging.StreamHandler() ] ) logger = logging.getLogger(__name__) class FishingBot: def __init__(self, window_title: str, interval: float = 5.0): """ 初始化钓鱼机器人 Args: window_title: 窗口标题(支持部分匹配) interval: 钓鱼和收杆之间的时间间隔(秒) """ self.window_title = window_title self.interval = interval self.running = False def find_window(self) -> Optional[gw.Window]: """ 查找包含指定标题的窗口 Returns: 找到的窗口对象,如果未找到则返回None """ try: windows = gw.getWindowsWithTitle(self.window_title) if windows: logger.info(f"找到窗口: {windows[0].title}") return windows[0] else: logger.warning(f"未找到包含标题 '{self.window_title}' 的窗口") return None except Exception as e: logger.error(f"查找窗口时出错: {e}") return None def activate_window(self, window: gw.Window) -> bool: """ 激活指定窗口 Args: window: 窗口对象 Returns: 是否成功激活 """ try: window.activate() time.sleep(0.5) # 等待窗口激活 logger.info(f"已激活窗口: {window.title}") return True except Exception as e: logger.error(f"激活窗口时出错: {e}") return False def send_fishing_message(self) -> bool: """ 发送钓鱼消息 Returns: 是否成功发送 """ try: # 这里根据实际需要修改发送方式 # 示例:模拟按下'F'键(常见游戏钓鱼键) pyautogui.press('f') logger.info("发送钓鱼消息") return True except Exception as e: logger.error(f"发送钓鱼消息时出错: {e}") return False def send_reel_message(self) -> bool: """ 发送收杆消息 Returns: 是否成功发送 """ try: # 这里根据实际需要修改发送方式 # 示例:模拟按下空格键(常见游戏收杆键) pyautogui.press('space') logger.info("发送收杆消息") return True except Exception as e: logger.error(f"发送收杆消息时出错: {e}") return False def run_cycle(self) -> bool: """ 运行一个完整的钓鱼周期 Returns: 周期是否成功完成 """ # 查找窗口 window = self.find_window() if not window: logger.error("无法找到目标窗口,跳过本次周期") return False # 激活窗口 if not self.activate_window(window): logger.error("无法激活窗口,跳过本次周期") return False # 发送钓鱼消息 if not self.send_fishing_message(): logger.error("发送钓鱼消息失败,跳过本次周期") return False # 等待间隔 logger.info(f"等待 {self.interval} 秒...") time.sleep(self.interval) # 发送收杆消息 if not self.send_reel_message(): logger.error("发送收杆消息失败") return False return True def start(self, cycles: int = 0): """ 启动钓鱼机器人 Args: cycles: 循环次数,0表示无限循环 """ self.running = True cycle_count = 0 logger.info(f"开始钓鱼机器人,窗口标题: '{self.window_title}', 间隔: {self.interval}秒") try: while self.running: cycle_count += 1 logger.info(f"开始第 {cycle_count} 个周期") success = self.run_cycle() if success: logger.info(f"第 {cycle_count} 个周期完成") else: logger.warning(f"第 {cycle_count} 个周期失败") # 如果指定了循环次数且已达到,则停止 if cycles > 0 and cycle_count >= cycles: logger.info(f"已完成指定的 {cycles} 个周期") break # 周期之间的短暂暂停,避免CPU占用过高 time.sleep(1) except KeyboardInterrupt: logger.info("用户中断执行") except Exception as e: logger.error(f"运行时发生未预期错误: {e}") finally: self.running = False logger.info("钓鱼机器人已停止") def stop(self): """停止钓鱼机器人""" self.running = False logger.info("停止信号已发送") def main(): """主函数""" import argparse parser = argparse.ArgumentParser(description='窗口钓鱼自动化脚本') parser.add_argument('--window', '-w', default='魔兽世界', help='目标窗口标题(支持部分匹配)') parser.add_argument('--interval', '-i', type=float, default=5.0, help='钓鱼和收杆之间的时间间隔(秒)') parser.add_argument('--cycles', '-c', type=int, default=0, help='循环次数(0表示无限循环)') parser.add_argument('--test', '-t', action='store_true', help='测试模式:只运行一个周期并显示详细信息') args = parser.parse_args() # 创建机器人实例 bot = FishingBot(args.window, args.interval) if args.test: logger.info("=== 测试模式 ===") logger.info(f"窗口标题: {args.window}") logger.info(f"间隔: {args.interval}秒") # 测试窗口查找 window = bot.find_window() if window: logger.info(f"✓ 找到窗口: {window.title}") else: logger.error("✗ 未找到窗口") return # 测试激活 if bot.activate_window(window): logger.info("✓ 窗口激活成功") else: logger.error("✗ 窗口激活失败") return logger.info("测试完成,请检查日志确认功能正常") return # 启动机器人 try: bot.start(args.cycles) except KeyboardInterrupt: logger.info("脚本被用户中断") except Exception as e: logger.error(f"脚本执行出错: {e}") return 1 return 0 if __name__ == "__main__": sys.exit(main())