玩游戏你还在自己动手玩?
前阵子,媳妇迷上了动物餐厅这款小游戏。卡哇伊萌萌的画风,简单无脑的操作,看广告就可以变强的设定,能整理出excel满满一sheet的攻略,无限制打发无聊的时间,让双手再也停不下来。这些近乎完美的优点,完美地契合着甲方爸爸的需求。先让大家看看画风是怎样的。(此处真不是安利这款小游戏,当然要是愿意给我打广告费我也不介意)

这个游戏的核心很简单,就是要你不停的在线接客人,赚小鱼干,买道具,然后就可以继续赚更多的小鱼干,再买更高级的道具。越到后面,东西贵的离谱。从我一个码农的角度来说,道具价值多少小鱼干,完全是码农在后台改一个数字的事。之所以阶梯价把目标定的越来越高,就是为了pua玩家,这大概是现在所有游戏的套路吧。一直在玩,就会沉浸进去,局外人感觉很无聊,你自己要是有几天不玩也就会觉得没啥意思了。
为了搞清楚这个游戏怎么玩的,我也成功入坑,成为不折不扣的小鱼干打工奴。看上面的图,可以看到有一个手机宣传的按钮。这个按钮你只要一直点着,不管是单击还是长按,恭喜你,幸福的源泉开始了。会有源源不断的客人来你餐厅吃饭消费,给你小鱼干,说白点,就是刷钱。这么蠢的动作,居然需要耗费一个人来不停操作,太奢侈了。码农二话不说,不能忍,我得写个外挂解放沉迷赚小鱼干的媳妇。
废话不多说,直奔今天的主题。游戏在微信小程序里面,运行在手机端。python+adb控制方案再合适不过了。从网上下载好adb,配好环境变量,在cmd窗口输入adb version 查看版本号,建议安装最新版的adb,旧版本的会有一些问题。如果能够正确的看到版本号,就是安装好了。
连接手机。手机打开开发者选项,开启usb调试。命令行输入adb devices,如果可以看到设备节点,就是连接成功了。接下来就可以输入adb命令来控制手机了。
先小试牛刀,点击事件:
adb shell input tap 960 2100可以看到屏幕上坐标是(960,2100)的区域点击了一下。(开发者模式选项卡中,开启显示点击事件和指针坐标显示)长按事件:adb shell input swipe 960 2100 960 2100 10000在屏幕上(960,2100)的位置长按10s
接下来的任务就是优化了,根据屏幕分辨率识别不同的手机,按比例点击相应的坐标,再在脚本里实现完整的自动控制。
实现长按手机宣传还不够,仙女还有更高的要求。要能够自动收花。怎么个收花法?就是下面视频这样。
收花的位置是固定的,可以使用坐标来解决。播种的位置和收花的位置接近,固定坐标也可以解决。确认播种的操作用坐标也行,但如果花还没成熟,点击那个坐标就会进入许愿池看广告,很可能就点出游戏了,所以这里图像识别安排上了。详细代码如下:
import osimport sysfrom time import sleepimport reimport cv2 as cvimport numpy as npfrom datetime import datetimedef get_screen_size():#'获取手机屏幕大小'size_str = os.popen('adb shell wm size').read()if not size_str:print('请安装 ADB 及驱动并配置环境变量')sys.exit()m = re.search(r'(\d+)x(\d+)', size_str)if m:return "{height}x{width}".format(height=m.group(2), width=m.group(1))return "1920x1080"def get_location_bz():img_rgb = cv.imread('test.jpg')img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)template = cv.imread('template/bozhong.jpg',0)w, h = template.shape[::-1]res = cv.matchTemplate(img_gray,template,cv.TM_CCOEFF_NORMED) #-?到1的系数threshold = 0.85x = 0y = 0loc = np.where(res >= threshold)for pt in zip(*loc[::-1]):x, y = pt[0] + w / 2, pt[1] + h / 2return x,ydef flower_auto(signal,name):os.system(signal)print('收了一朵{}'.format(name))sleep(2)os.system('adb exec-out screencap -p > test.jpg')sleep(1)x, y = get_location_bz()print(x, y)if x:os.system('adb shell input tap {0} {1}'.format(x, y))print('成功播种')sleep(0.5)if __name__ == "__main__":#第一步,读取分辨率,识别手机screen_size = get_screen_size()phone = ''print(screen_size)if '2400' in screen_size:print('这是狗顺的手机')phone = 'gs'fish = 'adb shell input swipe 960 2200 960 2200 10000'blank = 'adb shell input tap 500 500'flower1 = 'adb shell input tap 273 1015'flower2 = 'adb shell input tap 829 1075'flower3 = 'adb shell input tap 292 1375'flower4 = 'adb shell input tap 800 1370'else:print('这是小仙女的手机')phone = 'xxn'fish = 'adb shell input swipe 960 2100 960 2100 10000'blank = 'adb shell input tap 500 500'flower1 = 'adb shell input tap 273 950'flower2 = 'adb shell input tap 800 950'flower3 = 'adb shell input tap 292 1283'flower4 = 'adb shell input tap 800 1278'capture_time = datetime.now()screen_time = datetime.now()flower_time = datetime.now()print('开始时间为{}'.format(capture_time))while True:current_time = datetime.now()duration1 = current_time-capture_timeduration2 = current_time-screen_timeduration3 = current_time-flower_time#先点一下空白的地方,去掉对话框页面os.system(blank)sleep(0.1)# 持续点击10sos.system(fish)# 截屏保存到桌面并保存,10s更新一次图片if duration1.seconds >= 10:os.system('adb exec-out screencap -p > test.jpg')print('截图成功')capture_time = datetime.now()# 30s发送一次亮屏指令if duration2.seconds >= 30:os.system('adb shell input keyevent 224')print('点亮屏幕')screen_time = datetime.now()#优先进行图像识别,如果有播种文字点击播种文字,没有播种文字点击播种图片if duration3.seconds >= 360:# 第一遍摘花flower_auto(flower1,'小雏菊')flower_auto(flower2,'向日葵')flower_auto(flower3,'小红梅')flower_auto(flower4,'紫罗兰')# 第二遍播种flower_auto(flower1, '小雏菊')flower_auto(flower2, '向日葵')flower_auto(flower3, '小红梅')flower_auto(flower4, '紫罗兰')flower_time = datetime.now()
程序思路:每隔10秒截图一次并保存在电脑上。每个30s点亮一次屏幕防止锁屏,每次长按手机宣传按钮10s,点击宣传之前先点击一下空白的地方,防止有对话框冒出来。每隔10分钟去收一次花,再播种一次。(花的成熟周期要大于10分钟)。为了防止误点击,播种采用了图像识别里的图像匹配方法,识别到播种文字再点击。
一顿操作之后,成功实现了自动收花和自动点手机宣传功能。嗯,学会写代码,可以有利于家庭和谐,社会稳定。
当然,需要改进优化和添加的功能还有很多。比如不要总是点击一个位置,每次间隔的时间不要是固定的,做一些其他的点击滑动操作,跑个一个小时消停会儿等等。游戏是有一定的检测外挂功能的,还有有一些机制设定,比如时不时冒出对话框啦等操作。

玩游戏啦,放松一下还是可以的,不可太急功近利,追求太多身外之物的小鱼干。写个小外挂也只是为了试试代码好不好使。在我完成第一版本功能之后,出于对自己有要求,不能玩游戏玩不停考虑,仙女已经删掉了这个游戏,(可能是意识到这个游戏的无聊了)转战刷淘宝。莫非,岂不是甲方爸爸的下个需求是搞个淘宝自动抢购商品的程序?不觉瑟瑟发抖。还好仙女不懂代码,不然我操作代码的时候,可能会在旁边说,“呦,写bug呢”!
下期再会。
