教你用 Python 实现微信跳一跳(Mac+iOS版)


Posted in Python onJanuary 04, 2018

这几天看网上好多微信跳一跳破解了,不过都是安卓的,无奈苹果不是开源也没办法。这个教程是 Mac + iOS , 要下xcode 要配置环境小白估计是没戏了,有iOS 开发经验的可以看看 。不过其实可以没事帮同事刷一下,让他们请吃个饭什么的,哈哈。 

先发个战果

教你用 Python 实现微信跳一跳(Mac+iOS版)

一.WebDriverAgent

首先去 https://github.com/facebook/WebDriverAgent 下一份代码

教你用 Python 实现微信跳一跳(Mac+iOS版) 

选择 WebDriverAgentRunner 用真机 然后 test 运行一下 , 看到IP地址就说明成功了

教你用 Python 实现微信跳一跳(Mac+iOS版) 

手机打开跳一跳 ,在电脑上访问 IP , 如我的 192.168.1.101:8100/inspector ,可以看到下面的东西

教你用 Python 实现微信跳一跳(Mac+iOS版) 

如果电脑访问 ip连接有问题 在命令行执行下面命令

$   iproxy 8100 8100

用电脑代理一下手机的8100端口

二. 去下载 wechat_jump_game

去github 下 https://github.com/wangshub/wechat_jump_game

下好之后要下载一些依赖库

$  pip install -r requirements.txt

记得 拷贝 wechat_jump_game-master ./config/iPhone 目录下对应的设备配置文件,重命名并替换到 ./config.json

教你用 Python 实现微信跳一跳(Mac+iOS版) 

将手机点击到《跳一跳》小程序界面,然后在命令行 执行 下面代码就可以自由的刷分了

$ python wechat_jump_auto_iOS.py

------------------------我是分割线------------------------------

既然身为码农就要有跟技术死磕的精神 ,比较技术就是饭碗嘛 。个人觉得python 是个神奇的东西,有着丰富的库,上可以写爬虫抓数据,下可以玩web服务。

代码核心其实就是计算出棋子和下一个砖的距离 然后 乘以 一个弹跳系数 来得到 press_time

源代码PO出来学习一下

# coding: utf-8
import os
import shutil
import time
import math
import wda
from PIL import Image, ImageDraw
import random
import json
# === 思路 ===
# 核心:每次落稳之后截图,根据截图算出棋子的坐标和下一个块顶面的中点坐标,
# 根据两个点的距离乘以一个时间系数获得长按的时间
# 识别棋子:靠棋子的颜色来识别位置,通过截图发现最下面一行大概是一条直线,就从上往下一行一行遍历,
#  比较颜色(颜色用了一个区间来比较)找到最下面的那一行的所有点,然后求个中点,
#  求好之后再让 Y 轴坐标减小棋子底盘的一半高度从而得到中心点的坐标
# 识别棋盘:靠底色和方块的色差来做,从分数之下的位置开始,一行一行扫描,由于圆形的块最顶上是一条线,
#  方形的上面大概是一个点,所以就用类似识别棋子的做法多识别了几个点求中点,
#  这时候得到了块中点的 X 轴坐标,这时候假设现在棋子在当前块的中心,
#  根据一个通过截图获取的固定的角度来推出中点的 Y 坐标
# 最后:根据两点的坐标算距离乘以系数来获取长按时间(似乎可以直接用 X 轴距离)
# TODO: 解决定位偏移的问题
# TODO: 看看两个块中心到中轴距离是否相同,如果是的话靠这个来判断一下当前超前还是落后,便于矫正
# TODO: 一些固定值根据截图的具体大小计算
# TODO: 直接用 X 轴距离简化逻辑
with open('config.json', 'r') as f:
 config = json.load(f)
# Magic Number,不设置可能无法正常执行,请根据具体截图从上到下按需设置
under_game_score_y = config['under_game_score_y'] # 截图中刚好低于分数显示区域的 Y 坐标,300 是 1920x1080 的值,2K 屏、全面屏请根据实际情况修改
press_coefficient = config['press_coefficient'] # 长按的时间系数,请自己根据实际情况调节
piece_base_height_1_2 = config['piece_base_height_1_2'] # 二分之一的棋子底座高度,可能要调节
piece_body_width = config['piece_body_width']  # 棋子的宽度,比截图中量到的稍微大一点比较安全,可能要调节
time_coefficient = config['press_coefficient']
# 模拟按压的起始点坐标,需要自动重复游戏请设置成“再来一局”的坐标
if config.get('swipe'):
 swipe = config['swipe']
else:
 swipe = {
 "x1": 320,
 "y1": 410,
 "x2": 320,
 "y2": 410
 }
c = wda.Client()
s = c.session()
screenshot_backup_dir = 'screenshot_backups/'
if not os.path.isdir(screenshot_backup_dir):
 os.mkdir(screenshot_backup_dir)
def pull_screenshot():
 c.screenshot('1.png')
def jump(distance):
 press_time = distance * time_coefficient / 1000
 print('press time: {}'.format(press_time))
 s.tap_hold(200, 200, press_time)
def backup_screenshot(ts):
 # 为了方便失败的时候 debug
 if not os.path.isdir(screenshot_backup_dir):
 os.mkdir(screenshot_backup_dir)
 shutil.copy('1.png', '{}{}.png'.format(screenshot_backup_dir, ts))
def save_debug_creenshot(ts, im, piece_x, piece_y, board_x, board_y):
 draw = ImageDraw.Draw(im)
 # 对debug图片加上详细的注释
 draw.line((piece_x, piece_y) + (board_x, board_y), fill=2, width=3)
 draw.line((piece_x, 0, piece_x, im.size[1]), fill=(255, 0, 0))
 draw.line((0, piece_y, im.size[0], piece_y), fill=(255, 0, 0))
 draw.line((board_x, 0, board_x, im.size[1]), fill=(0, 0, 255))
 draw.line((0, board_y, im.size[0], board_y), fill=(0, 0, 255))
 draw.ellipse((piece_x - 10, piece_y - 10, piece_x + 10, piece_y + 10), fill=(255, 0, 0))
 draw.ellipse((board_x - 10, board_y - 10, board_x + 10, board_y + 10), fill=(0, 0, 255))
 del draw
 im.save('{}{}_d.png'.format(screenshot_backup_dir, ts))
def set_button_position(im):
 # 将swipe设置为 `再来一局` 按钮的位置
 global swipe_x1, swipe_y1, swipe_x2, swipe_y2
 w, h = im.size
 left = w / 2
 top = 1003 * (h / 1280.0) + 10
 swipe_x1, swipe_y1, swipe_x2, swipe_y2 = left, top, left, top
def find_piece_and_board(im):
 w, h = im.size
 print("size: {}, {}".format(w, h))
 piece_x_sum = 0
 piece_x_c = 0
 piece_y_max = 0
 board_x = 0
 board_y = 0
 scan_x_border = int(w / 8) # 扫描棋子时的左右边界
 scan_start_y = 0 # 扫描的起始y坐标
 im_pixel = im.load()
 # 以50px步长,尝试探测scan_start_y
 for i in range(under_game_score_y, h, 50):
 last_pixel = im_pixel[0, i]
 for j in range(1, w):
  pixel = im_pixel[j, i]
  # 不是纯色的线,则记录scan_start_y的值,准备跳出循环
  if pixel[0] != last_pixel[0] or pixel[1] != last_pixel[1] or pixel[2] != last_pixel[2]:
  scan_start_y = i - 50
  break
 if scan_start_y:
  break
 print("scan_start_y: ", scan_start_y)
 # 从scan_start_y开始往下扫描,棋子应位于屏幕上半部分,这里暂定不超过2/3
 for i in range(scan_start_y, int(h * 2 / 3)):
 for j in range(scan_x_border, w - scan_x_border): # 横坐标方面也减少了一部分扫描开销
  pixel = im_pixel[j, i]
  # 根据棋子的最低行的颜色判断,找最后一行那些点的平均值,这个颜色这样应该 OK,暂时不提出来
  if (50 < pixel[0] < 60) and (53 < pixel[1] < 63) and (95 < pixel[2] < 110):
  piece_x_sum += j
  piece_x_c += 1
  piece_y_max = max(i, piece_y_max)
 if not all((piece_x_sum, piece_x_c)):
 return 0, 0, 0, 0
 piece_x = piece_x_sum / piece_x_c
 piece_y = piece_y_max - piece_base_height_1_2 # 上移棋子底盘高度的一半
 for i in range (int (h / 3), int (h * 2 / 3)):
 last_pixel = im_pixel[0, i]
 if board_x or board_y:
  break
 board_x_sum = 0
 board_x_c = 0
 for j in range(w):
  pixel = im_pixel[j, i]
  # 修掉脑袋比下一个小格子还高的情况的 bug
  if abs(j - piece_x) < piece_body_width:
  continue
  # 修掉圆顶的时候一条线导致的小 bug,这个颜色判断应该 OK,暂时不提出来
  if abs(pixel[0] - last_pixel[0]) + abs(pixel[1] - last_pixel[1]) + abs(pixel[2] - last_pixel[2]) > 10:
  board_x_sum += j
  board_x_c += 1
 if board_x_sum:
  board_x = board_x_sum / board_x_c
 # 按实际的角度来算,找到接近下一个 board 中心的坐标 这里的角度应该是30°,值应该是tan 30°, math.sqrt(3) / 3
 board_y = piece_y - abs(board_x - piece_x) * math.sqrt(3) / 3
 if not all((board_x, board_y)):
 return 0, 0, 0, 0
 return piece_x, piece_y, board_x, board_y
def main():
 while True:
 pull_screenshot()
 im = Image.open("./1.png")
 # 获取棋子和 board 的位置
 piece_x, piece_y, board_x, board_y = find_piece_and_board(im)
 ts = int(time.time())
 print(ts, piece_x, piece_y, board_x, board_y)
 if piece_x == 0:
  return
 set_button_position(im)
 distance = math.sqrt((board_x - piece_x) ** 2 + (board_y - piece_y) ** 2)
 jump(distance)
 save_debug_creenshot(ts, im, piece_x, piece_y, board_x, board_y)
 backup_screenshot(ts)
 time.sleep(random.uniform(1, 1.1)) # 为了保证截图的时候应落稳了,多延迟一会儿
if __name__ == '__main__':
 main()

总结

以上所述是小编给大家介绍的教你用 Python 来玩微信跳一跳(Mac+iOS版),希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
tensorflow使用神经网络实现mnist分类
Sep 08 Python
Python图像处理之gif动态图的解析与合成操作详解
Dec 30 Python
Python3.5面向对象与继承图文实例详解
Apr 24 Python
Python实现九宫格式的朋友圈功能内附“马云”朋友圈
May 07 Python
python小程序实现刷票功能详解
Jul 17 Python
详解使用django-mama-cas快速搭建CAS服务的实现
Oct 30 Python
python 实现视频 图像帧提取
Dec 10 Python
Python 实现opencv所使用的图片格式与 base64 转换
Jan 09 Python
TensorFlow 显存使用机制详解
Feb 03 Python
解决pyCharm中 module 调用失败的问题
Feb 12 Python
django 读取图片到页面实例
Mar 27 Python
django orm模块中的 is_delete用法
May 20 Python
基于python实现在excel中读取与生成随机数写入excel中
Jan 04 #Python
python实现简易云音乐播放器
Jan 04 #Python
Python语言描述连续子数组的最大和
Jan 04 #Python
一个月入门Python爬虫学习,轻松爬取大规模数据
Jan 03 #Python
Python编程pygame模块实现移动的小车示例代码
Jan 03 #Python
python编程实现随机生成多个椭圆实例代码
Jan 03 #Python
Python通过Pygame绘制移动的矩形实例代码
Jan 03 #Python
You might like
PHP的面向对象编程
2006/10/09 PHP
基于linnux+phantomjs实现生成图片格式的网页快照
2015/04/15 PHP
微信公众平台开发之天气预报功能
2015/08/31 PHP
javascript比较文档位置
2008/04/08 Javascript
javascript 动态数据下的锚点错位问题解决方法
2008/12/24 Javascript
JavaScript实现删除,移动和复制文件的方法
2015/08/05 Javascript
基于JavaScript制作霓虹灯文字 代码 特效
2015/09/01 Javascript
jquery实现简单实用的弹出层效果代码
2015/10/15 Javascript
详解使用vue脚手架工具搭建vue-webpack项目
2017/05/10 Javascript
js CSS3实现卡牌旋转切换效果
2017/07/04 Javascript
Vue Cli与BootStrap结合实现表格分页功能
2017/08/18 Javascript
使用react实现手机号的数据同步显示功能的示例代码
2018/04/03 Javascript
Vue Router去掉url中默认的锚点#
2018/08/01 Javascript
layDate插件设置开始和结束时间
2018/11/15 Javascript
vue实现五子棋游戏
2020/05/28 Javascript
vue 子组件watch监听不到prop的解决
2020/08/09 Javascript
[02:48]DOTA2超级联赛专访海涛:你们的选择没有错
2013/06/07 DOTA
Python 过滤字符串的技巧,map与itertools.imap
2008/09/06 Python
Python实现句子翻译功能
2017/11/14 Python
Android基于TCP和URL协议的网络编程示例【附demo源码下载】
2018/01/23 Python
用python实现将数组元素按从小到大的顺序排列方法
2018/07/02 Python
深入理解Python中的 __new__ 和 __init__及区别介绍
2018/09/17 Python
python基于opencv检测程序运行效率
2019/12/28 Python
pycharm 代码自动补全的实现方法(图文)
2020/09/18 Python
Python中return函数返回值实例用法
2020/11/19 Python
Python+Opencv实现把图片、视频互转的示例
2020/12/17 Python
美国南加州的原创极限运动潮牌:Vans(范斯)
2016/08/05 全球购物
毕业生求职推荐信
2013/11/04 职场文书
毕业生自荐书
2014/02/03 职场文书
办公室主任主任岗位责任制
2014/02/11 职场文书
辞职信如何写
2015/02/27 职场文书
2015年小学数学教师工作总结
2015/05/20 职场文书
企业催款函范本
2015/06/24 职场文书
青年联谊会致辞
2015/07/31 职场文书
高二数学教学反思
2016/02/18 职场文书
详解如何使用Node.js实现热重载页面
2021/05/06 Javascript