diff --git a/AUTO_MAA.exe b/AUTO_MAA.exe index e2c45bf..e0052df 100644 Binary files a/AUTO_MAA.exe and b/AUTO_MAA.exe differ diff --git a/AUTO_MAA.py b/AUTO_MAA.py index ec713aa..5466642 100644 --- a/AUTO_MAA.py +++ b/AUTO_MAA.py @@ -20,30 +20,55 @@ import sqlite3 import subprocess +import atexit import datetime import time import os from termcolor import colored +#资源回收 +def cleanup(): + if os.path.exists("state/BEGIN"): + os.remove("state/BEGIN") + DATABASE="data/data.db" -db=sqlite3.connect(DATABASE) -cur=db.cursor() -cur.execute("SELECT * FROM timeset WHERE True") -timeset=cur.fetchall() -timeset=[list(row) for row in timeset] + +#设置回调函数 +atexit.register(cleanup) while True: - curtime=datetime.datetime.now().strftime("%H:%M") - print(colored("当前时间:"+curtime,'green')) - timenew=[] - timenew.append(curtime) - if timenew in timeset: - print(colored("开始执行",'yellow')) - maa=subprocess.Popen(["run.exe"]) - maapid=maa.pid - while True: - if os.path.exists("OVER"): - os.system('taskkill /F /T /PID '+str(maapid)) - os.remove("OVER") - print(colored("执行完毕",'yellow')) - break - time.sleep(1) \ No newline at end of file + db=sqlite3.connect(DATABASE) + cur=db.cursor() + cur.execute("SELECT * FROM timeset WHERE True") + timeset=cur.fetchall() + cur.close() + db.close() + timeset=[list(row) for row in timeset] + timeset=[timeset[i][0] for i in range(len(timeset))] + for i in range(60): + #展示当前信息 + curtime=datetime.datetime.now().strftime("%H:%M") + os.system('cls') + if len(timeset)!=0: + print(colored("设定时间:"+','.join(timeset),'green')) + print(colored("当前时间:"+curtime,'green')) + print(colored("运行日志:",'green')) + if os.path.exists("state/running"): + print(colored("正在运行代理",'yellow')) + elif os.path.exists("log.txt"): + with open("log.txt",'r',encoding="utf-8") as f: + linex=f.read() + print(colored(linex,'light_green')) + else: + print(colored("暂无",'light_green')) + if (curtime in timeset) and not os.path.exists("running"): + with open("state/BEGIN","w",encoding="utf-8") as f: + print("BEGIN",file=f) + maa=subprocess.Popen(["run.exe"]) + maapid=maa.pid + while True: + if os.path.exists("state/END"): + os.system('taskkill /F /T /PID '+str(maapid)) + os.remove("state/END") + break + os.remove("state/BEGIN") + time.sleep(1) \ No newline at end of file diff --git a/README.md b/README.md index bee0d44..167fb47 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,10 @@ MAA多账号管理与自动化软件 以上细则是本项目对GPL的相关补充与强调。未提及的以GPL为准,发生冲突的以GPL为准。如有不清楚的部分,请发Issues询问。若发生纠纷,相关内容也没有在Issues上提及的,项目组拥有最终解释权 +**注意** +- 由于本软件有修改其它目录JSON文件等行为,使用前请将AUTO_MAA添加入Windows Defender信任区以及防病毒软件的信任区或开发者目录,避免被误杀 +- 如程序无法正常启动,请删除`state`目录下所有文件后重试 + ## 安装与配置MAA 本软件是MAA的外部工具,需要安装配置MAA后才能使用。 diff --git a/data/gameid.txt b/data/gameid.txt index 8a41ae0..6c05329 100644 --- a/data/gameid.txt +++ b/data/gameid.txt @@ -1,5 +1,5 @@ 龙门币:CE-6 技能:CA-5 红票:AP-5 -经验:CA-5 +经验:LS-6 剿灭模式:Annihilation \ No newline at end of file diff --git a/manage.exe b/manage.exe index 71559f5..86126dd 100644 Binary files a/manage.exe and b/manage.exe differ diff --git a/manage.py b/manage.py index 37bd8d4..b9d1b7f 100644 --- a/manage.py +++ b/manage.py @@ -165,8 +165,6 @@ def changePASSWORD(): #添加用户 def add(): - db=sqlite3.connect(DATABASE) - cur=db.cursor() adminx=input("用户名:") #用户名重复验证 while search(adminx,0)=="": @@ -178,6 +176,8 @@ def add(): passwordx=readpass("密码:") passwordx=encryptx(passwordx) #应用更新 + db=sqlite3.connect(DATABASE) + cur=db.cursor() cur.execute("INSERT INTO adminx VALUES(?,?,?,'y','2000-01-01',?,?)",(adminx,numberx,dayx,gamex,passwordx)) db.commit() cur.close() @@ -186,14 +186,12 @@ def add(): #删除用户信息 def delete(id): - db=sqlite3.connect(DATABASE) - cur=db.cursor() #检查用户是否存在 - cur.execute("SELECT * FROM adminx WHERE admin=?",(id,)) - data=cur.fetchall() - if len(data)==0: + if search(id,0)!="": return "未找到"+id #应用更新 + db=sqlite3.connect(DATABASE) + cur=db.cursor() cur.execute("DELETE FROM adminx WHERE admin=?",(id,)) db.commit() cur.close() @@ -298,15 +296,13 @@ def renewal(readxx): dayp=int(readxx[i+1:]) break #检查用户是否存在 + if search(id,0)!="": + return "未找到"+id + #应用更新 db=sqlite3.connect(DATABASE) cur=db.cursor() cur.execute("SELECT * FROM adminx WHERE admin=?",(id,)) data=cur.fetchall() - if len(data)==0: - cur.close() - db.close() - return "未找到"+id - #应用更新 cur.execute("UPDATE adminx SET day=? WHERE admin=?",(data[0][2]+dayp,id)) db.commit() cur.close() @@ -316,15 +312,11 @@ def renewal(readxx): #用户状态配置 def turn(id,t): #检查用户是否存在 - db=sqlite3.connect(DATABASE) - cur=db.cursor() - cur.execute("SELECT * FROM adminx WHERE admin=?",(id,)) - data=cur.fetchall() - if len(data)==0: - cur.close() - db.close() + if search(id,0)!="": return "未找到"+id #应用更新 + db=sqlite3.connect(DATABASE) + cur=db.cursor() cur.execute("UPDATE adminx SET status=? WHERE admin=?",(t,id)) db.commit() cur.close() @@ -343,13 +335,7 @@ def gameid(readxx): gamep=readxx[i+1:] break #检查用户是否存在 - db=sqlite3.connect(DATABASE) - cur=db.cursor() - cur.execute("SELECT * FROM adminx WHERE admin=?",(id,)) - data=cur.fetchall() - if len(data)==0: - cur.close() - db.close() + if search(id,0)!="": return "未找到"+id #导入与应用特殊关卡规则 games={} @@ -365,6 +351,8 @@ def gameid(readxx): if gamep in games: gamep=games[gamep] #应用更新 + db=sqlite3.connect(DATABASE) + cur=db.cursor() cur.execute("UPDATE adminx SET game=? WHERE admin=?",(gamep,id)) db.commit() cur.close() diff --git a/res/README/gameid.png b/res/README/gameid.png index 5e4f358..ff25fa6 100644 Binary files a/res/README/gameid.png and b/res/README/gameid.png differ diff --git a/res/info.txt b/res/info.txt new file mode 100644 index 0000000..0be8ea1 --- /dev/null +++ b/res/info.txt @@ -0,0 +1,30 @@ +# UTF-8 +VSVersionInfo( + ffi=FixedFileInfo( +#filevers和prodvers应该始终是包含四个项的元组:(1、2、3、4),将不需要的项设置为0 +filevers=(2,1,2,0), # 文件版本******,鼠标悬浮exe会显示,也显示在 详细信息-文件版本,这个是检测版本的依据 +prodvers=(0,0,0,0), # 生产商,未见显示在哪里 +mask=0x3f, # 两个位掩码 +flags=0x0, +OS=0x4, # 为其设计此文件的操作系统,0x4-NT,无需更改它 +fileType=0x1, # 文件的常规类型,0x1-该文件是一个应用程序 +subtype=0x0, # 文件的功能,0x0表示该文件类型未定义 +date=(0,0) # 创建日期和时间戳 +), + kids=[ +StringFileInfo( + [ + StringTable( + u'040904B0', + [StringStruct(u'CompanyName', u'AUTO_MAA项目组'), # 鼠标悬浮exe会显示 + StringStruct(u'FileDescription', u'AUTO_MAA组件'), # 文件说明,鼠标悬浮exe会显示,也会显示在 详细信息-文件说明 + StringStruct(u'FileVersion', u'2.1.2'), # 没见哪里显示 + StringStruct(u'InternalName', u'AUTO_MAA'), + StringStruct(u'LegalCopyright', u'DLmaster_361'), #版权,会显示在 详细信息-版权 + StringStruct(u'OriginalFilename', u'AUTO_MAA源代码'), #原始文件名,会显示在 详细信息-原始文件名 + StringStruct(u'ProductName', u'AUTO_MAA'), #产品名称,会显示在 详细信息-产品名称 + StringStruct(u'ProductVersion', u'2.1.2')]) #产品版本,会显示在 详细信息-产品版本 + ]), +VarFileInfo([VarStruct(u'Translation', [2052, 1200])]) # 语言,中文简体 + ] +) \ No newline at end of file diff --git a/run.exe b/run.exe index 7a87b8c..e18a77a 100644 Binary files a/run.exe and b/run.exe differ diff --git a/run.py b/run.py index 6c5b055..d08cacc 100644 --- a/run.py +++ b/run.py @@ -20,49 +20,81 @@ import os import subprocess +import atexit import sqlite3 import datetime import time import json from termcolor import colored -#判断MAA程序运行状态 -def ifoff(): - while True: - time.sleep(10) - with open(logpath,'r',encoding='utf-8') as f: - logs=f.readlines()[-1:-10:-1] - log=''.join(logs) - print(colored('\n'.join(logs[::-1]),"green")) - if "任务已全部完成!" in log: - return True - elif ("请检查连接设置或尝试重启模拟器与 ADB 或重启电脑" in log) or ("已停止" in log): - return False - #执行MAA任务 -def runmaa(tel,game,num=2): +def runmaa(id,tel,game,num=3): #配置MAA运行参数 with open(setpath,"r",encoding="utf-8") as f: - data = json.load(f) + data=json.load(f) data["Configurations"]["Default"]["Start.AccountName"]=tel[:3]+"****"+tel[7:] - week=str(datetime.datetime.now().strftime('%A')) - if week=="Monday": - data["Configurations"]["Default"]["MainFunction.Stage1"]="Annihilation" - else: - data["Configurations"]["Default"]["MainFunction.Stage1"]=game + data["Configurations"]["Default"]["MainFunction.Stage1"]="Annihilation" + data["Configurations"]["Default"]["Fight.RemainingSanityStage"]=game + data["Configurations"]["Default"]["Fight.UseRemainingSanityStage"]="True" + data["Configurations"]["Default"]["GUI.CustomStageCode"]="True" with open(setpath,"w",encoding="utf-8") as f: json.dump(data,f) #开始运行 for i in range(num): + global idnew,idold,idfail,idall,logx,logi + #创建MAA任务 maa=subprocess.Popen([maapath]) maapid=maa.pid - time.sleep(60) - if ifoff(): - return True + #等待MAA启动 + idsuccess=idnew+idold + idwait=[idx for idx in idall if not idx in idsuccess+idfail+[id]] + os.system('cls') + if i==0: + print(colored("正在代理:",'white')+colored(id,'blue')) else: - os.system('taskkill /F /T /PID '+str(maapid)) + print(colored("正在代理:",'white')+colored(id,'light_blue')) + print(colored("等待代理:",'white')+colored(','.join(idwait),'yellow')) + print(colored("代理成功:",'white')+colored(','.join(idsuccess),'green')) + print(colored("代理失败:",'white')+colored(','.join(idfail),'red')) + print(colored("运行日志:",'white')+colored("等待MAA初始化",'light_green')) + time.sleep(60) + #监测MAA运行状态 + while True: + #打印基本信息 + os.system('cls') + if i==0: + print(colored("正在代理:",'white')+colored(id,'blue')) + else: + print(colored("正在代理:",'white')+colored(id,'light_blue')) + print(colored("等待代理:",'white')+colored(','.join(idwait),'yellow')) + print(colored("代理成功:",'white')+colored(','.join(idsuccess),'green')) + print(colored("代理失败:",'white')+colored(','.join(idfail),'red')) + print(colored("运行日志:",'white')) + #读取并保存MAA日志 + with open(logpath,'r',encoding='utf-8') as f: + logs=f.readlines()[-1:-10:-1] + print(colored(''.join(logs[::-1]),'light_green')) + log=''.join(logs) + logx[logi]=log + logi=(logi+1) % len(logx) + #判断MAA程序运行状态 + if ("任务已全部完成!" in log): + return True + elif ("请检查连接设置或尝试重启模拟器与 ADB 或重启电脑" in log) or ("已停止" in log) or ("MaaAssistantArknights GUI exited" in log) or timeout(): + os.system('taskkill /F /T /PID '+str(maapid)) + break + time.sleep(10) return False +#检查是否超时 +def timeout(): + global logx + log0=logx[0] + for i in range(len(logx)): + if logx[i]!=log0: + return False + return True + #更新已完成用户的数据 def updata(id): db=sqlite3.connect(DATABASE) @@ -77,6 +109,19 @@ def updata(id): db.close() return 0 +#资源回收 +def cleanup(): + if os.path.exists("state/RUNNING"): + os.remove("state/RUNNING") + +#读取运行情况 +if os.path.exists("state/RUNNING"): + exit() +#标记当前正在运行 +with open("state/RUNNING","w",encoding="utf-8") as f: + print("RUNNING",file=f) +#设置回调函数 +atexit.register(cleanup) #获取PATH与用户数据 DATABASE="data/data.db" db=sqlite3.connect(DATABASE) @@ -93,32 +138,39 @@ data=[list(row) for row in data] cur.close() db.close() #开始执行 -curdate=datetime.date.today() -curdate=curdate.strftime('%Y-%m-%d') +curdate=datetime.date.today().strftime('%Y-%m-%d') +begintime=datetime.datetime.now().strftime("%H:%M") idnew=[] idold=[] idfail=[] +idall=[data[i][0] for i in range(len(data))] +LOGXLEN=60 +logx=['' for i in range(LOGXLEN)] +logi=0 for i in range(len(data)): if data[i][3]=='y' and data[i][4]!=curdate and data[i][2]>0: - book=runmaa(data[i][1],data[i][5]) + book=runmaa(data[i][0],data[i][1],data[i][5]) if book: updata(data[i][0]) idnew.append(data[i][0]) - print(colored("已完成"+data[i][0]+"今日的代理","yellow")) else: idfail.append(data[i][0]) - print(colored("异常中止"+data[i][0]+"的代理","red")) for i in range(len(data)): if data[i][3]=='y' and data[i][4]==curdate and data[i][2]>0: - book=runmaa(data[i][1],data[i][5]) + book=runmaa(data[i][0],data[i][1],data[i][5]) if book: idold.append(data[i][0]) - print(colored("已重复完成"+data[i][0]+"今日的代理","yellow")) -with open("log.txt","w", encoding="utf-8") as f: - print("任务结束,已完成数:"+str(len(idnew))+",未完成数:"+str(len(idfail))+",重复执行数:"+str(len(idold)),file=f) + else: + idall.remove(data[i][0]) +endtime=datetime.datetime.now().strftime("%H:%M") +with open("log.txt","w",encoding="utf-8") as f: + print("任务开始时间:"+begintime+",结束时间:"+endtime,file=f) + print("已完成数:"+str(len(idnew))+",未完成数:"+str(len(idfail))+",重复执行数:"+str(len(idold)),file=f) if len(idfail)!=0: print("代理未完成的用户:",file=f) for i in range(len(idfail)): print(idfail[i],file=f) -with open("OVER","w", encoding="utf-8") as f: - print("OVER",file=f) \ No newline at end of file +if os.path.exists("state/BEGIN"): + with open("state/END","w",encoding="utf-8") as f: + print("END",file=f) +exit() \ No newline at end of file diff --git a/toexe.py b/toexe.py index fd6de7a..af53cfb 100644 --- a/toexe.py +++ b/toexe.py @@ -20,6 +20,6 @@ import os -os.system("pyinstaller -F -i res/AUTO_MAA.ico manage.py") -os.system("pyinstaller -F -i res/AUTO_MAA.ico run.py") -os.system("pyinstaller -F -i res/AUTO_MAA.ico AUTO_MAA.py") \ No newline at end of file +os.system("pyinstaller -F -w --version-file res/info.txt -i res/AUTO_MAA.ico manage.py") +os.system("pyinstaller -F -w --version-file res/info.txt -i res/AUTO_MAA.ico run.py") +os.system("pyinstaller -F -w --version-file res/info.txt -i res/AUTO_MAA.ico AUTO_MAA.py") \ No newline at end of file