From 45b27d569c83042701cee62b5cf63b03f0a18a38 Mon Sep 17 00:00:00 2001 From: MistEO Date: Thu, 9 Dec 2021 00:06:49 +0800 Subject: [PATCH] =?UTF-8?q?docs.=E6=9B=B4=E6=96=B0Python=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 +- src/MeoAssistance/Assistance.cpp | 2 +- src/Python/interface.py | 106 ++++++++++++- src/Python/message.py | 255 +++++++++++++++++++++++++++++++ src/Python/msg.py | 43 ------ 5 files changed, 356 insertions(+), 53 deletions(-) create mode 100644 src/Python/message.py delete mode 100644 src/Python/msg.py diff --git a/README.md b/README.md index a3a85f3996..b504ccb847 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,8 @@ A game assistance for Arknights 一款明日方舟的游戏助手,自动刷理智、智能基建换班、公招识别等,一键完成所有日常,全自动长草!!! -纯图像识别,非内存挂,全图形化界面,兼容模拟器和安卓设备,开罐即食,绝赞开发中!✿✿ヽ(°▽°)ノ✿ +纯图像识别,非内存挂!全图形化界面,开罐即食!并提供了[Python接口](src/Python/interface.py)供自行DIY!绝赞开发中!✿✿ヽ(°▽°)ノ✿ +
## 功能介绍 diff --git a/src/MeoAssistance/Assistance.cpp b/src/MeoAssistance/Assistance.cpp index 9450306865..91434d6f22 100644 --- a/src/MeoAssistance/Assistance.cpp +++ b/src/MeoAssistance/Assistance.cpp @@ -292,7 +292,7 @@ bool Assistance::start_recruit_calc(const std::vector& select_level, bool s auto task_ptr = std::make_shared(task_callback, (void*)this); task_ptr->set_param(select_level, set_time); task_ptr->set_retry_times(OpenRecruitTaskRetryTimesDefault); - task_ptr->set_task_chain("OpenRecruit"); + task_ptr->set_task_chain("RecruitCalc"); m_tasks_queue.emplace(task_ptr); return start(false); diff --git a/src/Python/interface.py b/src/Python/interface.py index 7d72b8f418..b121a4d3d6 100644 --- a/src/Python/interface.py +++ b/src/Python/interface.py @@ -2,14 +2,28 @@ import ctypes import os import json import pathlib -from msg import Msg +from message import Message class Asst: CallBackType = ctypes.CFUNCTYPE( None, ctypes.c_int, ctypes.c_char_p, ctypes.c_void_p) + """ + 回调函数,使用实例可参照my_callback + + :params: + ``param1 message``: 消息类型 + ``param2 details``: gbk json string + ``param3 arg``: 自定义参数 + """ def __init__(self, dirname: str, callback: CallBackType, arg=None): + """ + :params: + ``dirname``: DLL及资源所在文件夹路径 + ``callback``: 回调函数 + ``arg``: 自定义参数 + """ os.chdir(dirname) self.__dllpath = pathlib.Path(dirname) / 'MeoAssistance.dll' self.__dll = ctypes.WinDLL(str(self.__dllpath)) @@ -23,36 +37,80 @@ class Asst: self.__dll.AsstDestroy(self.__ptr) def catch_default(self) -> bool: + """ + 连接配置文件中的默认选项(模拟器or安卓手机) + + :return: 是否连接成功 + """ self.__dll.AsstCatchDefault.argtypes = (ctypes.c_void_p,) return self.__dll.AsstCatchDefault(self.__ptr) def catch_emulator(self) -> bool: + """ + 连接模拟器 + + :return: 是否连接成功 + """ self.__dll.AsstCatchEmulator.argtypes = (ctypes.c_void_p,) return self.__dll.AsstCatchEmulator(self.__ptr) def catch_custom(self, address: str) -> bool: + """ + 连接自定义设备 + + :return: 是否连接成功 + """ self.__dll.AsstCatchCustom.argtypes = ( ctypes.c_void_p, ctypes.c_char_p,) return self.__dll.AsstCatchCustom(self.__ptr, address) def append_fight(self, max_medicine: int, max_stone: int, max_times: int) -> bool: + """ + 添加刷理智任务 + + :params: + ``max_medicine``: 最多吃多少理智药 + ``max_stone``: 最多吃多少源石 + ``max_times``: 最多刷多少 + """ self.__dll.AsstAppendFight.argtypes = ( ctypes.c_void_p, ctypes.c_int, ctypes.c_int, ctypes.c_int,) return self.__dll.AsstAppendFight(self.__ptr, max_medicine, max_stone, max_times) def append_award(self) -> bool: + """ + 添加领取每日奖励任务 + """ self.__dll.AsstAppendAward.argtypes = (ctypes.c_void_p,) return self.__dll.AsstAppendAward(self.__ptr) def append_visit(self) -> bool: + """ + 添加访问好友任务 + """ self.__dll.AsstAppendVisit.argtypes = (ctypes.c_void_p,) return self.__dll.AsstAppendVisit(self.__ptr) def append_mall(self, with_shopping: bool) -> bool: + """ + 添加信用商店任务 + + :params: + ``with_shopping``: 是否信用商店购物 + """ self.__dll.AsstAppendMall.argtypes = (ctypes.c_void_p, ctypes.c_bool) return self.__dll.AsstAppendMall(self.__ptr, with_shopping) def append_infrast(self, work_mode: int, order_list: list, uses_of_drones: str, dorm_threshold: float) -> bool: + """ + 添加基建任务 + + :params: + ``work_mode``: 工作模式,当前仅支持传 1 + ``order_list``: 换班顺序,str list,例如 [ "Mfg", "Trade", "Control", "Power", "Reception", "Office", "Dorm"] + ``uses_of_drones``: 无人机用途,支持以下之一:"_NotUse"、"Money"、"SyntheticJade"、"CombatRecord"、"PureGold"、"OriginStone"、"Chip" + ``dorm_threshold``: 宿舍心情阈值,取值 [0, 1.0] + """ order_len = len(order_list) order_arr = (ctypes.c_char_p * order_len)() order_arr[:] = order_list @@ -66,6 +124,15 @@ class Asst: uses_of_drones, dorm_threshold) def append_recruit(self, max_times: int, select_level: list, confirm_level: list, need_refresh: bool) -> bool: + """ + 添加自动公招任务 + + :params: + ``max_times``: 自动公招次数 + ``select_level``: 要点击的Tags等级(例如3级Tags不选也可以直接确认),int list + ``confirm_level``: 要确认开始招募的Tags等级,int list + ``need_refresh``: 是否刷新3级Tags + """ select_len = len(select_level) select_arr = (ctypes.c_int * select_len)() select_arr[:] = select_level @@ -83,10 +150,20 @@ class Asst: confirm_arr, confirm_len, need_refresh) def start(self) -> bool: + """ + 开始任务 + """ self.__dll.AsstStart.argtypes = (ctypes.c_void_p,) return self.__dll.AsstStart(self.__ptr) - def start_recurit_clac(self, select_level: list, set_time: bool) -> bool: + def start_recurit_calc(self, select_level: list, set_time: bool) -> bool: + """ + 进行公招计算 + + :params: + ``select_level``: 要点击的Tags等级,int list + ``set_time``: 是否要点击9小时 + """ select_len = len(select_level) select_arr = (ctypes.c_int * select_len)() select_arr[:] = select_level @@ -96,27 +173,40 @@ class Asst: return self.__dll.AsstStartRecruitCalc(self.__ptr, select_arr, select_len, set_time) def stop(self) -> bool: + """ + 停止并清空所有任务 + """ self.__dll.AsstStop.argtypes = (ctypes.c_void_p,) return self.__dll.AsstStop(self.__ptr) def set_penguin_id(self, id: str) -> bool: + """ + 设置企鹅物流ID + + :params: + ``id``: 企鹅物流ID,仅数字部分 + """ self.__dll.AsstSetPenguinId.argtypes = ( ctypes.c_void_p, ctypes.c_char_p) return self.__dll.AsstSetPenguinId(self.__ptr, id) def get_version(self) -> str: + """ + 获取DLL版本号 + + :return: 版本号 + """ self.__dll.AsstGetVersion.restype = ctypes.c_char_p return self.__dll.AsstGetVersion() -@Asst.CallBackType -def my_callback(msg, details, arg): - d = json.loads(details.decode('gbk')) - print(Msg(msg), d, arg) - - if __name__ == "__main__": + @Asst.CallBackType + def my_callback(msg, details, arg): + d = json.loads(details.decode('gbk')) + print(Message(msg), d, arg) + asst = Asst('D:\\Code\\MeoAssistance\\x64\\Release\\', my_callback) if asst.catch_default(): print('连接成功') diff --git a/src/Python/message.py b/src/Python/message.py new file mode 100644 index 0000000000..6a119e2867 --- /dev/null +++ b/src/Python/message.py @@ -0,0 +1,255 @@ +from enum import Enum, unique, auto + + + +@unique +class Message(Enum): + """ + 回调消息类型 + + 注释部分仅展示常用消息的回调JSON格式,完全的回调JSON请参考C++侧实现代码 + """ + + PtrIsNull = auto() + """ + 指针为空 + """ + + ImageIsEmpty = auto() + """ + 图像为空 + """ + + WindowMinimized = auto() + """ + [已弃用] 窗口被最小化了 + """ + + InitFaild = auto() + """ + 初始化失败 + """ + + TaskError = auto() + """ + 任务错误(任务一直出错,retry次数达到上限) + """ + + OcrResultError = auto() + """ + Ocr识别结果错误。公招如果识别的Tags数量不足5个,会报这个错 + """ + + TaskStart = 1000 + """ + 单个原子任务开始 + """ + + TaskMatched = auto() + """ + 任务匹配成功 + """ + + ReachedLimit = auto() + """ + 单个原子任务达到次数上限 + """ + + ReadyToSleep = auto() + """ + 准备开始睡眠 + """ + + EndOfSleep = auto() + """ + 睡眠结束 + """ + + AppendProcessTask = auto() + """ + [已弃用] 新增流程任务,Assistance内部消息,外部不需要处理 + """ + + AppendTask = auto() + """ + [已弃用] 新增任务,Assistance内部消息,外部不需要处理 + """ + + TaskCompleted = auto() + """ + 单个原子任务完成 + + :Json格式: + { "name": string, "type": int, "exec_time": int, "max_times": int, "task_type" : string, "algorithm" : int} + + :字段解释: + ``name`` 任务名 + :常见值: + ``StartButton2`` 开始行动(橙色按钮) + ``MedicineConfirm`` 使用理智药 + ``StoneConfirm`` 使用源石 + ``RecruitRefresh`` 公招刷新标签 + + ``type`` 操作类型 + + ``exec_times`` 已执行次数 + + ``max_times`` 最大执行次数 + + ``task_type`` 任务类型 + + ``algorithm`` 算法类型 + """ + + PrintWindow = auto() + """ + 截图消息 + """ + + ProcessTaskStopAction = auto() + """ + 流程任务执行到了Stop的动作 + """ + + TaskChainCompleted = auto() + """ + 任务链完成 + + :Json格式: + { "task_chain": string } + + :字段解释: + ``task_chain`` 任务链名称 + """ + + ProcessTaskNotMatched = auto() + """ + 流程任务识别错误 + """ + + AllTasksCompleted = auto() + """ + 所有任务完成 + + :Json格式: + null + """ + + TaskChainStart = auto() + """ + 开始任务链 + + :Json格式: + { "task_chain": string } + :字段解释: + ``task_chain`` 任务链名称 + :常见值: + "Fight" 刷理智 + "Award" 领取每日奖励 + "Visit" 访问好友 + "Mall" 信用商店 + "Infrast" 基建 + "Recruit" 自动公招 + "RecruitCalc" 公招计算 + """ + + TextDetected = 2000 + """ + 识别到文字 + """ + + ImageFindResult = auto() + """ + 查找图像的结果 + """ + + ImageMatched = auto() + """ + 图像匹配成功 + """ + + StageDrops = auto() + """ + 关卡掉落信息 + + :Json格式: + {"exceptions":[],"resultLabel":true,"drops":[{"dropType":"NORMAL_DROP","itemId":"2002","quantity":1,"itemName":"初级作战记录"},{"dropType":"NORMAL_DROP","itemId":"2003","quantity":1,"itemName":"中级作战记录"},{"dropType":"NORMAL_DROP","itemId":"2004","quantity":3,"itemName":"高级作战记录"}],"dropTypes":[{"dropTypes":"LMB"},{"dropTypes":"NORMAL_DROP"}],"stage":{"stageCode":"LS-5","stageId":"wk_kc_5"},"stars":3,"fingerprint":"598b253d3b24247b756f39202052375138233b75653c2a575a111f59462a2d413c092e50421a1731ff0c07b07809070e131715bfad4a44300a1c0e0a5d0b620c","md5":"43084d95fcf1c0a0cce3fdeab8c41334","cost":33.7536,"statistics":[{"itemId":"2004","itemName":"高级作战记录","count":15},{"itemId":"2002","itemName":"初级作战记录","count":5},{"itemId":"2003","itemName":"中级作战记录","count":5}]} + + :字段解释: + ``drops`` 当次掉落 + ``statistics`` 掉落统计 + """ + + RecruitTagsDetected = 3000 + """ + 公招识别到了Tags + + :Json格式: + {"tags":["近卫干员","狙击干员","医疗干员","新手","输出"]} + """ + + RecruitSpecialTag = auto() + """ + 公招识别到了特殊的Tag + + :Json格式: + { "tag": string} + + 字段解释 + ``tag`` 特殊Tag + :常见值: + "高级资深干员" + "支援机械" + """ + + RecruitResult = auto() + """ + 公开招募结果 + + :Json格式: + {"result":[{"tags":["近卫干员","群攻"],"tag_level":3,"opers":[{"name":"幽灵鲨","level":5},{"name":"布洛卡","level":5},{"name":"艾丝黛尔","level":4},{"name":"泡普卡","level":3}]},{"tags":["群攻"],"tag_level":3,"opers":[{"name":"陨星","level":5},{"name":"送葬人","level":5},{"name":"幽灵鲨","level":5},{"name":"布洛卡","level":5},{"name":"远山","level":4},{"name":"格雷伊","level":4},{"name":"白雪","level":4},{"name":"艾丝黛尔","level":4},{"name":"泡普卡","level":3},{"name":"炎熔","level":3},{"name":"空爆","level":3}]},{"tags":["费用回复"],"tag_level":3,"opers":[{"name":"德克萨斯","level":5},{"name":"凛冬","level":5},{"name":"苇草","level":5},{"name":"清道夫","level":4},{"name":"红豆","level":4},{"name":"桃金娘","level":4},{"name":"翎羽","level":3},{"name":"香草","level":3},{"name":"芬","level":3}]},{"tags":["近卫干员"],"tag_level":3,"opers":[{"name":"诗怀雅","level":5},{"name":"星极","level":5},{"name":"因陀罗","level":5},{"name":"幽灵鲨","level":5},{"name":"布洛卡","level":5},{"name":"猎蜂","level":4},{"name":"杜宾","level":4},{"name":"艾丝黛尔","level":4},{"name":"慕斯","level":4},{"name":"霜叶","level":4},{"name":"缠丸","level":4},{"name":"泡普卡","level":3},{"name":"玫兰莎","level":3},{"name":"月见夜","level":3},{"name":"Castle-3","level":1}]},{"tags":["术师干员"],"tag_level":3,"opers":[{"name":"夜魔","level":5},{"name":"远山","level":4},{"name":"格雷伊","level":4},{"name":"夜烟","level":4},{"name":"史都华德","level":3},{"name":"炎熔","level":3},{"name":"12F","level":2},{"name":"杜林","level":2}]},{"tags":["术师干员","群攻"],"tag_level":3,"opers":[{"name":"远山","level":4},{"name":"格雷伊","level":4},{"name":"炎熔","level":3}]},{"tags":["新手"],"tag_level":2,"opers":[{"name":"黑角","level":2},{"name":"巡林者","level":2},{"name":"12F","level":2},{"name":"杜林","level":2},{"name":"夜刀","level":2}]},{"tags":["新手","术师干员"],"tag_level":2,"opers":[{"name":"12F","level":2},{"name":"杜林","level":2}]}],"maybe_level":3} + + :字段解释: + ``result`` 识别结果 + ``maybe_level`` 可能出的等级 + """ + + RecruitSelected = auto() + """ + 选择了Tags + + :Json格式: + {"tags":["术师干员","减速"]} + """ + + InfrastSkillsDetected = 4000 + """ + 识别到了基建技能(当前页面) + """ + + InfrastSkillsResult = auto() + """ + 识别到的所有可用技能 + """ + + InfrastComb = auto() + """ + 当前房间的最优干员组合 + """ + + EnterFacility = auto() + """ + 进入某个房间 + + :Json格式: + { "facility": string, "index": int } + :字段解释: + ``facility`` 房间名 + ``index`` 第几个该类房间 + """ + + # + FacilityInfo = auto() + """ + 当前设施信息 + """ diff --git a/src/Python/msg.py b/src/Python/msg.py deleted file mode 100644 index 4612b4bd59..0000000000 --- a/src/Python/msg.py +++ /dev/null @@ -1,43 +0,0 @@ -from enum import Enum, unique, auto - - -@unique -class Msg(Enum): - # Error Msg - PtrIsNull = auto() # 指针为空 - ImageIsEmpty = auto() # 图像为空 - WindowMinimized = auto() # [已弃用] 窗口被最小化了 - InitFaild = auto() # 初始化失败 - TaskError = auto() # 任务错误(任务一直出错,retry次数达到上限) - OcrResultError = auto() # Ocr识别结果错误 - # Info Msg: about Task - TaskStart = 1000 # 任务开始 - TaskMatched = auto() # 任务匹配成功 - ReachedLimit = auto() # 单个原子任务达到次数上限 - ReadyToSleep = auto() # 准备开始睡眠 - EndOfSleep = auto() # 睡眠结束 - AppendProcessTask = auto() # [已弃用] 新增流程任务,Assistance内部消息,外部不需要处理 - AppendTask = auto() # [已弃用] 新增任务,Assistance内部消息,外部不需要处理 - TaskCompleted = auto() # 单个原子任务完成 - PrintWindow = auto() # 截图消息 - ProcessTaskStopAction = auto() # 流程任务执行到了Stop的动作 - TaskChainCompleted = auto() # 任务链完成 - ProcessTaskNotMatched = auto() # 流程任务识别错误 - AllTasksCompleted = auto() # 所有任务完成 - TaskChainStart = auto() # 开始任务链 - # Info Msg: about Identify */ - TextDetected = 2000 # 识别到文字 - ImageFindResult = auto() # 查找图像的结果 - ImageMatched = auto() # 图像匹配成功 - StageDrops = auto() # 关卡掉落信息 - # Open Recruit Msg */ - RecruitTagsDetected = 3000 # 公招识别到了Tags - RecruitSpecialTag = auto() # 公招识别到了特殊的Tag - RecruitResult = auto() # 公开招募结果 - RecruitSelected = auto() # 选择了Tags - # Infrast Msg */ - InfrastSkillsDetected = 4000 # 识别到了基建技能(当前页面) - InfrastSkillsResult = auto() # 识别到的所有可用技能 - InfrastComb = auto() # 当前房间的最优干员组合 - EnterFacility = auto() # 进入某个房间 - FacilityInfo = auto() # 当前设施信息