Skip to content

Commit

Permalink
Update kechao task
Browse files Browse the repository at this point in the history
  • Loading branch information
DawningW committed Feb 23, 2021
1 parent 8128f7e commit 14d17ca
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 26 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -129,4 +129,7 @@ dmypy.json
.pyre/

# Visual Studio
.vs
.vs

# swy-bot
saved
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ PS: 每次做菜都剩下一大堆食材好烦啊

PSS: 那个活动的跑酷恶心死我了啊啊啊啊

**空桑好, 策划爬**

## 食用方式
详见程序内指引

Expand Down Expand Up @@ -45,6 +47,8 @@ PSS: 那个活动的跑酷恶心死我了啊啊啊啊

2021/2/21 使用装饰器注册挂机任务, 完成Scrcpy模式, 更新版本号至V1.3

2021/2/23 重做客潮挂机任务, 更新版本号至V1.4

## 厨师
详见CONTRIBUTOR.md

Expand Down
15 changes: 10 additions & 5 deletions main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def main():
setnodpi()
settitle("欢迎使用食物语挂机脚本")
print('''=============================================
食物语挂机脚本 V1.3 作者: WC
食物语挂机脚本 V1.4 作者: WC
本脚本仅供个人代肝使用, 严禁用于商业用途
使用本脚本造成的一切法律纠纷由使用者自行承担
项目地址: https://github.com/DawningW/swy-bot
Expand All @@ -31,8 +31,9 @@ def main():
2. ADB模式(需手机连接电脑开启调试模式并打开食物语)
3. 混合模式(使用scrcpy快速获取手机截屏并模拟点击)(*推荐*)
4. 调试模式(将读取程序目录下的test.png并进行图像识别)
8. 线性规划做菜计算器
9. 用默认浏览器打开食物语wiki
7. 线性规划做菜计算器
8. 用默认浏览器打开食物语wiki
9. 打开截图文件夹
0. 退出''')
str = input("请选择: ")
global player
Expand All @@ -46,12 +47,15 @@ def main():
player = PlayerScrcpy()
elif str == "4":
player = PlayerTest()
elif str == "8":
elif str == "7":
print("正在开发中")
continue
elif str == "9":
elif str == "8":
os.system("start https://wiki.biligame.com/swy");
continue
elif str == "9":
os.system("start saved");
continue
else:
continue
if (player.init()):
Expand Down Expand Up @@ -87,6 +91,7 @@ def run():
while not canceled:
times += 1
print("第 {} 次运行脚本: {}".format(times, task.name))
task.init()
origin = time.perf_counter()
phase = Phases.BEGIN
while True:
Expand Down
2 changes: 1 addition & 1 deletion player.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ class PlayerScrcpy(PlayerBase):

def init(self):
super().init()
self.client = ScrcpyClient()
self.client = ScrcpyClient(max_fps=30, queue_length=2)
if not self.client.start():
print("连接失败")
return False
Expand Down
1 change: 1 addition & 0 deletions scrcpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def __init__(self, max_size=0, bit_rate=8000000, max_fps=0, crop='-',
:param max_size: frame width that will be broadcast from android server
:param bit_rate:
:param max_fps: 0 means not max fps
:param crop:
:param libs_path: path to 'scrcpy-server.jar'
:param adb_path: path to ADB
:param ip: scrcpy server IP
Expand Down
107 changes: 89 additions & 18 deletions task.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import math
import numpy
import cv2
from utils import readimage
from utils import readimage, writeimage

class Phases(IntEnum):
"""任务执行的阶段"""
Expand Down Expand Up @@ -47,6 +47,9 @@ class TaskBase(object):

def __init__(self):
"""初始化"""
return

def init(self):
self.image = None
return

Expand All @@ -69,64 +72,132 @@ def getImageCache(self):
@Task("自动客潮", "请将界面停留在餐厅")
class TaskKeChao(TaskBase):
"""客潮自动化"""

def __init__(self):
super().__init__()
self.templateButton = readimage("kechao_btn")
self.templateDish = readimage("kechao_dish_part")
self.templateTitle = readimage("kechao_title_part")
return

def init(self):
super().init()
self.lastTime = 0
self.dialog = False
self.step = 0
# 0:餐厅界面 1:客潮对话框 2:客潮进行中 3:客潮结束结算界面
self.pointCache = []
return

def begin(self, player, t):
"""需要玩家位于餐厅界面"""
self.image = player.screenshot()
if not self.dialog:
if self.step == 0:
points = findcircle(self.image, 25)
for x, y in points:
if x > (self.image.shape[1] * 0.9) and y < (self.image.shape[0] * 0.2):
# 找到客潮按钮
player.clickaround(x, y)
self.dialog = True
else:
points = findtemplate(self.image, self.templateButton)
for x, y in points:
player.clickaround(x, y)
time.sleep(1)
return Results.SUCCESS
self.lastTime = t
self.step = 1
return Results.PASS
if t - self.lastTime > 3:
# 没找到客潮按钮且超时
print("未找到客潮按钮, 请确认您正位于餐厅界面")
return Results.FAIL
elif self.step == 1 or self.step == 2:
if t - self.lastTime > 2:
points = findtemplate(self.image, self.templateButton)
for x, y in points:
# 找到开始按钮
if self.step == 2:
print("点击按钮后没有开始, 可能是客潮开启次数不足")
return Results.FAIL
player.clickaround(x, y)
self.lastTime = t
self.step = 2
return Results.PASS
# 找不到开始按钮
if self.step == 2:
# 点过开始按钮了, 进入客潮
self.lastTime = t
print("进入客潮")
return Results.SUCCESS
# 还没点过开始按钮, 回退到第0步
self.lastTime = t
self.step = 0
return Results.PASS
return Results.PASS

def run(self, player, t):
"""客潮挂机中"""
self.image = player.screenshot()
# 处理点的缓存
self.pointCache = [(x, y, time - 1) for x, y, time in self.pointCache if time > 1]
# 识别圆来寻找菜(旧版本用模版匹配, 效果不好)
points = findcircle(self.image, 25)
points2 = []
for x, y in points:
if x > (self.image.shape[1] * 0.9): continue
if y > (self.image.shape[0] * 0.8): return Results.SUCCESS
if y > (self.image.shape[0] * 0.8):
# 客潮结束回到餐厅
self.lastTime = t
self.step = 3
print("客潮结束")
return Results.SUCCESS
cv2.circle(self.image, (x, y), 25, (0, 0, 255), 3)
points2.append((x, y))
if not self.containPoint(x, y):
points2.append((x, y))
if len(points2) > 0:
x, y = random.choice(points2)
player.clickaround(x, y)
self.pointCache.append((x, y, 10))
self.lastTime = t
return Results.PASS
if t - self.lastTime > 15:
# 没人点菜, 停止挂机?
print("超过15秒钟没有客人点菜了, 停止挂机")
return Results.FAIL
return Results.PASS

def end(self, player, t):
"""结束客潮"""
self.image = player.screenshot()
points = findtemplate(self.image, self.templateTitle)
for x, y in points:
time.sleep(2)
player.clickaround(x, y)
time.sleep(2)
return Results.SUCCESS
if self.step == 3:
if t - self.lastTime > 2:
points = findtemplate(self.image, self.templateTitle)
for x, y in points:
# 正位于客潮结算界面
filename = "KeChao_" + time.strftime("%Y-%m-%d-%H-%M-%S")
writeimage(filename, self.image)
print("已将客潮结算界面截图保存至: saved/%s.png" % filename)
player.clickaround(x, y)
self.lastTime = t
return Results.PASS
# 结算完了
self.lastTime = t
return Results.SUCCESS
return Results.PASS

def containPoint(self, x, y):
for cx, cy, time in self.pointCache:
if math.sqrt(math.pow(int(x) - int(cx), 2) + math.pow(int(y) - int(cy), 2)) < 5:
return True
return False

@Task("自动小游戏", "尚未编写")
class TaskMiniGames(TaskBase):
"""活动小游戏 算了放弃了 毁灭吧赶紧的"""

def __init__(self):
super().__init__()
self.lastTime = 0
return

def begin(self, player, t):
"""开始小游戏"""
print("我不想做了")
return Results.FAIL

def findtemplate(image, template, threshold = 0.75, outline = False):
theight, twidth = template.shape[:2]
result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)
Expand Down
2 changes: 1 addition & 1 deletion utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ def readimage(name):
return cv2.imread("./data/" + name + ".png", cv2.IMREAD_UNCHANGED)

def writeimage(name, image):
cv2.imwrite("./data/saved/" + name + ".png", image, [int(cv2.IMWRITE_PNG_COMPRESSION), 3])
cv2.imwrite("./saved/" + name + ".png", image, [int(cv2.IMWRITE_PNG_COMPRESSION), 3])
return

0 comments on commit 14d17ca

Please sign in to comment.