Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b0b50670d | ||
|
|
863b6dd220 | ||
|
|
e3c9e3088b | ||
|
|
27bdfc8581 | ||
|
|
a2b1731fac | ||
|
|
f96c9253fe | ||
|
|
9e93b6ef35 |
BIN
AUTO_MAA.exe
Normal file
29
AUTO_MAA.py
Normal file
@@ -0,0 +1,29 @@
|
||||
import sqlite3
|
||||
import subprocess
|
||||
import datetime
|
||||
import time
|
||||
import os
|
||||
from termcolor import colored
|
||||
|
||||
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]
|
||||
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)
|
||||
@@ -1,133 +0,0 @@
|
||||
#include"stdafx.h"
|
||||
#include<iostream>
|
||||
#include<Windows.h>
|
||||
#include "boost/filesystem.hpp"
|
||||
#include "boost/iostreams/stream.hpp"
|
||||
#include "boost/format.hpp"
|
||||
#include "boost/algorithm/algorithm.hpp"
|
||||
#include "boost/algorithm/string.hpp"
|
||||
using namespace std;
|
||||
|
||||
#define READ_ONE_NUM 1024
|
||||
|
||||
/*
|
||||
ɱ<><C9B1>ָ<EFBFBD><D6B8>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><D0BD><EFBFBD>
|
||||
*/
|
||||
BOOL KillSpecifiedProcess(const std::string& p_strPath)
|
||||
{
|
||||
/*
|
||||
C:\Users\10139>wmic process where name="notepad.exe" get executablepath,processid
|
||||
ExecutablePath ProcessId
|
||||
C:\WINDOWS\system32\notepad.exe 6196
|
||||
C:\WINDOWS\system32\notepad.exe 6056
|
||||
|
||||
|
||||
C:\Users\10139>taskkill /F /PID 6196 /PID 6056
|
||||
<20>ɹ<EFBFBD>: <20><><EFBFBD><EFBFBD>ֹ PID Ϊ 6196 <20>Ľ<EFBFBD><C4BD>̡<EFBFBD>
|
||||
<20>ɹ<EFBFBD>: <20><><EFBFBD><EFBFBD>ֹ PID Ϊ 6056 <20>Ľ<EFBFBD><C4BD>̡<EFBFBD>
|
||||
*/
|
||||
if(!boost::filesystem::exists(p_strPath))
|
||||
{
|
||||
cout << p_strPath << " not exist" << endl;
|
||||
return FALSE;
|
||||
}
|
||||
int index = p_strPath.rfind("\\");
|
||||
std::string strName = p_strPath.substr(index + 1);
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
sa.bInheritHandle = TRUE;
|
||||
sa.lpSecurityDescriptor = NULL;
|
||||
HANDLE hStdOutRead = NULL, hStdOutWrite = NULL;
|
||||
if (!CreatePipe(&hStdOutRead, &hStdOutWrite, &sa, 0))
|
||||
{
|
||||
cout << "create pipe error," << GetLastError() << endl;
|
||||
return FALSE;
|
||||
}
|
||||
STARTUPINFOA startInfo;
|
||||
PROCESS_INFORMATION procInfo;
|
||||
BOOL bSuccess = FALSE;
|
||||
ZeroMemory(&procInfo, sizeof(PROCESS_INFORMATION));
|
||||
ZeroMemory(&startInfo, sizeof(STARTUPINFOA));
|
||||
startInfo.cb = sizeof(STARTUPINFOA);
|
||||
startInfo.hStdOutput = hStdOutWrite;
|
||||
startInfo.dwFlags |= (STARTF_USESTDHANDLES |STARTF_USESHOWWINDOW) ;
|
||||
startInfo.wShowWindow = SW_HIDE;
|
||||
|
||||
boost::format fmt("wmic process where name=\"%1%\" get executablepath,processid");
|
||||
fmt % strName;
|
||||
std::string strSQL = fmt.str();
|
||||
bSuccess = CreateProcessA(NULL, (char*)strSQL.data(), NULL, NULL, TRUE, 0, NULL, NULL, &startInfo, &procInfo);
|
||||
if (!bSuccess)
|
||||
{
|
||||
cout << "create process error," << GetLastError() << endl;
|
||||
return FALSE;
|
||||
}
|
||||
WaitForSingleObject(procInfo.hProcess,INFINITE);
|
||||
CloseHandle(hStdOutWrite);
|
||||
DWORD byteRead = 0;
|
||||
std::string strContent;
|
||||
char buffer[READ_ONE_NUM] = {0};
|
||||
while (true)
|
||||
{
|
||||
byteRead = 0;
|
||||
memset(buffer, 0, READ_ONE_NUM);
|
||||
BOOL bRead = ReadFile(hStdOutRead, buffer, (READ_ONE_NUM-1)* sizeof(buffer[0]) , &byteRead, NULL);
|
||||
if (!bRead)
|
||||
{
|
||||
break;
|
||||
}
|
||||
strContent.append(buffer);
|
||||
}
|
||||
CloseHandle(hStdOutRead);
|
||||
std::vector<std::string> splitVec;
|
||||
boost::split(splitVec, strContent, boost::is_any_of("\r\n"), boost::token_compress_on);
|
||||
if(splitVec.size() > 0)
|
||||
{
|
||||
if( !boost::icontains(splitVec[0], "ExecutablePath") )
|
||||
{
|
||||
// û<><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||
cout << strName << " is not runing" << endl;
|
||||
return FALSE;
|
||||
}
|
||||
// <20><><EFBFBD><EFBFBD>for<6F><72><EFBFBD>룺<EFBFBD><EBA3BA><EFBFBD><EFBFBD><EFBFBD>Ż<EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD>ͳ<EFBFBD><CDB3><EFBFBD>PID
|
||||
// <20><>1<EFBFBD>к<EFBFBD><D0BA><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD>
|
||||
for(int i = 1; i < splitVec.size() -1; i++)
|
||||
{
|
||||
std::vector<std::string> splitVec2;
|
||||
boost::split(splitVec2, splitVec[i], boost::is_any_of(" "), boost::token_compress_on);
|
||||
int size = splitVec2.size();
|
||||
if(size >= 3)
|
||||
{
|
||||
std::string exePath;
|
||||
// ȡ<><C8A1>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>·<EFBFBD><C2B7>
|
||||
for(int i = 0; i < size -1 -1; i++)
|
||||
{
|
||||
exePath.append(splitVec2[i]);
|
||||
exePath.append(" ");
|
||||
}
|
||||
// <20>ж<EFBFBD>·<EFBFBD><C2B7><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ȫƥ<C8AB><C6A5>
|
||||
if( !boost::icontains(exePath, p_strPath) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// <20><><EFBFBD><EFBFBD>·<EFBFBD><C2B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>пո<D5B8><F1A3ACB5><EFBFBD><EFBFBD><EFBFBD>2<EFBFBD><32>Ϊpid
|
||||
std::string pId = splitVec2[size -1 -1];
|
||||
std::string cmd = "taskkill /F /PID ";
|
||||
cmd.append(pId);
|
||||
cout << p_strPath << "->" << cmd << endl;
|
||||
WinExec(cmd.c_str(), SW_HIDE);
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
for(int i = 1; i < argc ; i++)
|
||||
{
|
||||
KillSpecifiedProcess(argv[i]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
252
README.md
Normal file
@@ -0,0 +1,252 @@
|
||||
# AUTO_MAA
|
||||
MAA多账号管理与自动化软件
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
## 免责声明
|
||||
本软件是一个外部工具,旨在优化MAA多账号功能体验。该软件包可以存储多账号数据,并通过修改MAA配置文件、读取MAA日志等行为自动完成多账号代理。
|
||||
|
||||
This software is open source, free of charge and for learning and exchange purposes only. The developer team has the final right to interpret this project. All problems arising from the use of this software are not related to this project and the developer team. If you encounter a merchant using this software to practice on your behalf and charging for it, it may be the cost of equipment and time, etc. The problems and consequences arising from this software have nothing to do with it.
|
||||
|
||||
本软件开源、免费,仅供学习交流使用。开发者团队拥有本项目的最终解释权。使用本软件产生的所有问题与本项目与开发者团队无关。若您遇到商家使用本软件进行代练并收费,可能是设备与时间等费用,产生的问题及后果与本软件无关。
|
||||
|
||||
## 安装与配置MAA
|
||||
|
||||
本软件是MAA的外部工具,需要安装配置MAA后才能使用。
|
||||
|
||||
#### MAA安装
|
||||
|
||||
什么是MAA? [官网](https://maa.plus/)/[GitHub](https://github.com/CHNZYX/Auto_Simulated_Universe/archive/refs/heads/main.zip)
|
||||
|
||||
MAA下载地址 [GitHub下载](https://github.com/MaaAssistantArknights/MaaAssistantArknights/releases)
|
||||
|
||||
#### MAA配置
|
||||
|
||||
1.完成MAA的adb配置等基本配置
|
||||
|
||||
2.在“完成后”菜单,选择“退出MAA和模拟器”。勾选“手动输入关卡名”和“无限吃48小时内过期的理智药”
|
||||
|
||||

|
||||
|
||||
3.确保当前配置名为“Default”,取消所有“定时执行”
|
||||
|
||||

|
||||
|
||||
4.取消勾选“开机自启动MAA”,勾选“启动MAA后直接运行”和“启动MAA后自动开启模拟器”。配置自己模拟器所在的位置并根据实际情况填写“等待模拟器启动时间”(建议预留10s以防意外)。如果是多开用户,需要填写“附加命令”,具体填写值参见多开模拟器对应快捷方式路径(如“-v 1”)。
|
||||
|
||||

|
||||
|
||||
5.勾选“定时检查更新”、“自动下载更新包”和“自动安装更新包”
|
||||
|
||||

|
||||
|
||||
## 下载AUTO_MAA软件包 [](https://github.com/DLmaster361/AUTO_MAA/releases)
|
||||
|
||||
GitHub下载地址 [GitHub下载](https://github.com/DLmaster361/AUTO_MAA/releases)
|
||||
|
||||
## 配置用户信息与相关参数
|
||||
|
||||
注意:当前所有的密码输入部分都存在一点“小问题”,请在输入密码时避免输入Delete、F12、Tab等功能键。
|
||||
|
||||
-------------------------------------------------
|
||||
|
||||
#### 第一次启动
|
||||
|
||||
双击启动`manage.exe`,输入MAA所在文件夹路径并回车(注意使用斜杠的种类,不要使用反斜杠),然后设置管理密钥。
|
||||
|
||||

|
||||
|
||||
管理密钥是解密用户密码的唯一凭证,与数据库绑定。密钥丢失或`data/key/`目录下任一文件损坏都将导致解密无法正常进行。
|
||||
|
||||
本项目采用自主组建的混合加密模式,项目组也无法找回您的管理密钥或修复`data/key/`目录下的文件。如果不幸的事发生,建议您删除`data/data.db`重新录入信息。
|
||||
|
||||
当前暂不支持修改管理密钥,请等待后续更新。
|
||||
|
||||
#### 添加用户
|
||||
|
||||
输入“+”以开始添加用户。依次输入:
|
||||
|
||||
用户名:管理用户的惟一凭证
|
||||
|
||||
手机号码:允许隐去中间四位以“****”代替
|
||||
|
||||
代理天数:这个还要我解释吗?
|
||||
|
||||
密码:警告!密码功能暂未开发,输入的信息会以明文存储,有泄露风险,请勿使用。可以用无意义的字符串代替。由于忽略警告导致的信息泄露,本项目组概不负责
|
||||
|
||||

|
||||
|
||||
#### 删除用户
|
||||
|
||||
输入用户名+“-”以删除用户。格式:
|
||||
|
||||
```plaintext
|
||||
用户名 -
|
||||
```
|
||||
|
||||

|
||||
|
||||
#### 配置用户状态
|
||||
|
||||
启用代理:输入用户名+“y”以启用该用户的代理。格式:
|
||||
|
||||
```plaintext
|
||||
用户名 y
|
||||
```
|
||||
|
||||

|
||||
|
||||
禁用代理:输入用户名+“n”以禁用该用户的代理。格式:
|
||||
|
||||
```plaintext
|
||||
用户名 n
|
||||
```
|
||||
|
||||

|
||||
|
||||
#### 续期
|
||||
|
||||
输入用户名+续期天数+“+”以延长该用户的代理天数。格式:
|
||||
|
||||
```plaintext
|
||||
用户名 续期天数 +
|
||||
```
|
||||
|
||||

|
||||
|
||||
#### 修改刷取关卡
|
||||
|
||||
输入用户名+关卡号+“~”以更改该用户的代理关卡。格式:
|
||||
|
||||
```plaintext
|
||||
用户名 关卡号 ~
|
||||
```
|
||||
|
||||

|
||||
|
||||
特别的:
|
||||
|
||||
你可以自定义关卡号替换方案。程序会读取`gameid.txt`中的数据,依据此进行关卡号的替换,便于常用关卡的使用。`gameid.txt`在初始已经存储了一些常用资源本的替代方案。
|
||||
|
||||

|
||||
|
||||
#### 设置MAA路径
|
||||
|
||||
输入“/”+新的MAA文件夹路径以修改MAA安装位置的配置。格式:
|
||||
|
||||
```plaintext
|
||||
/新的MAA文件夹路径
|
||||
```
|
||||
|
||||
注意:‘/’与路径间没有空格,路径同样不能使用反斜杠
|
||||
|
||||

|
||||
|
||||
#### 设置启动时间
|
||||
|
||||
添加启动时间:输入“:+”+时间以添加定时启动时间。格式:
|
||||
|
||||
```plaintext
|
||||
:+小时:分钟
|
||||
```
|
||||
|
||||
注意:所有输入间没有空格
|
||||
|
||||

|
||||
|
||||
删除启动时间:输入“:-”+时间以删除定时启动时间。格式:
|
||||
|
||||
```plaintext
|
||||
:-小时:分钟
|
||||
```
|
||||
|
||||
注意:所有输入间没有空格
|
||||
|
||||

|
||||
|
||||
#### 检索信息
|
||||
|
||||
检索所有信息:`manage.exe`打开时会打印所有用户与配置信息。除此之外,你可以通过输入“all ?”以打印所有信息,如下:
|
||||
|
||||
```plaintext
|
||||
all ?
|
||||
```
|
||||
|
||||

|
||||
|
||||
检索MAA路径:输入“maa ?”以检索MAA安装路径,如下:
|
||||
|
||||
```plaintext
|
||||
maa ?
|
||||
```
|
||||
|
||||

|
||||
|
||||
检索启动时间:输入“time ?”以检索定时启动的时间,如下:
|
||||
|
||||
```plaintext
|
||||
time ?
|
||||
```
|
||||
|
||||

|
||||
|
||||
检索指定用户:输入用户名+“?”以检索指定用户信息,如下:
|
||||
|
||||
```plaintext
|
||||
用户名 ?
|
||||
```
|
||||
|
||||

|
||||
|
||||
#### 退出
|
||||
|
||||
输入“-”以退出`manage.exe`,如下:
|
||||
|
||||
```plaintext
|
||||
-
|
||||
```
|
||||
|
||||
## 运行代理
|
||||
|
||||
#### 直接运行
|
||||
|
||||
双击`run.exe`直接运行
|
||||
|
||||
#### 定时运行
|
||||
|
||||
双击`AUTO_MAA.exe`打开,不要关闭。它会读取设定时间,在该时刻自动运行
|
||||
|
||||
注意:周一将自动进行剿灭代理
|
||||
|
||||
## 关于
|
||||
|
||||
项目图标由文心一格AI生成
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
欢迎加入,欢迎反馈bug
|
||||
|
||||
QQ群:没有
|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
|
||||
如果喜欢本项目,可以打赏送作者一杯咖啡喵!
|
||||
|
||||

|
||||
|
||||
----------------------------------------------------------------------------------------------
|
||||
## 贡献者
|
||||
|
||||
感谢以下贡献者对本项目做出的贡献
|
||||
|
||||
<a href="https://github.com/DLmaster361/AUTO_MAA/graphs/contributors">
|
||||
|
||||
<img src="https://contrib.rocks/image?repo=DLmaster361/AUTO_MAA" />
|
||||
|
||||
</a>
|
||||
|
||||

|
||||
|
||||
## Star History
|
||||
|
||||
[](https://star-history.com/#DLmaster361/AUTO_MAA&Date)
|
||||
BIN
manage.exe
Normal file
224
manage.py
@@ -1,6 +1,107 @@
|
||||
import sqlite3
|
||||
import datetime
|
||||
import msvcrt
|
||||
import sys
|
||||
import os
|
||||
import hashlib
|
||||
import random
|
||||
import secrets
|
||||
from Crypto.Cipher import AES
|
||||
from Crypto.PublicKey import RSA
|
||||
from Crypto.Cipher import PKCS1_OAEP
|
||||
from Crypto.Util.Padding import pad,unpad
|
||||
|
||||
#读入密码
|
||||
def readpass(text):
|
||||
sys.stdout=sys.__stdout__
|
||||
sys.stdout.write(text)
|
||||
sys.stdout.flush()
|
||||
p=''
|
||||
while True:
|
||||
typed=msvcrt.getch()
|
||||
if len(p)!=0:
|
||||
if typed==b'\r':
|
||||
sys.stdout.write('\b*')
|
||||
sys.stdout.flush()
|
||||
break
|
||||
elif typed==b'\b':
|
||||
p=p[:-1]
|
||||
sys.stdout.write('\b \b')
|
||||
sys.stdout.flush()
|
||||
else:
|
||||
p+=typed.decode("utf-8")
|
||||
sys.stdout.write('\b*'+typed.decode("utf-8"))
|
||||
sys.stdout.flush()
|
||||
elif typed!=b'\r' and typed!=b'\b':
|
||||
p+=typed.decode("utf-8")
|
||||
sys.stdout.write(typed.decode("utf-8"))
|
||||
sys.stdout.flush()
|
||||
|
||||
print('')
|
||||
return p
|
||||
|
||||
#配置密钥
|
||||
def getPASSWORD(PASSWORD):
|
||||
#生成RSA密钥对
|
||||
key=RSA.generate(2048)
|
||||
public_key_local=key.publickey()
|
||||
private_key=key
|
||||
#保存RSA公钥
|
||||
with open('data/key/public_key.pem','wb') as f:
|
||||
f.write(public_key_local.exportKey())
|
||||
#生成密钥转换与校验随机盐
|
||||
PASSWORDsalt=secrets.token_hex(random.randint(32,1024))
|
||||
with open("data/key/PASSWORDsalt.txt","w",encoding="utf-8") as f:
|
||||
print(PASSWORDsalt,file=f)
|
||||
verifysalt=secrets.token_hex(random.randint(32,1024))
|
||||
with open("data/key/verifysalt.txt","w",encoding="utf-8") as f:
|
||||
print(verifysalt,file=f)
|
||||
#将管理密钥转化为AES-256密钥
|
||||
AES_password=hashlib.sha256((PASSWORD+PASSWORDsalt).encode("utf-8")).digest()
|
||||
#生成AES-256密钥校验哈希值并保存
|
||||
AES_password_verify=hashlib.sha256(AES_password+verifysalt.encode("utf-8")).digest()
|
||||
with open("data/key/AES_password_verify.bin","wb") as f:
|
||||
f.write(AES_password_verify)
|
||||
#AES-256加密RSA私钥并保存密文
|
||||
AES_key=AES.new(AES_password,AES.MODE_ECB)
|
||||
private_key_local=AES_key.encrypt(pad(private_key.exportKey(),32))
|
||||
with open("data/key/private_key.bin","wb") as f:
|
||||
f.write(private_key_local)
|
||||
|
||||
#加密
|
||||
def encryptx(note):
|
||||
#读取RSA公钥
|
||||
with open('data/key/public_key.pem','rb') as f:
|
||||
public_key_local=RSA.import_key(f.read())
|
||||
#使用RSA公钥对数据进行加密
|
||||
cipher=PKCS1_OAEP.new(public_key_local)
|
||||
encrypted=cipher.encrypt(note.encode("utf-8"))
|
||||
return encrypted
|
||||
|
||||
#解密
|
||||
def decryptx(note,PASSWORD):
|
||||
#读入RSA私钥密文、盐与校验哈希值
|
||||
with open("data/key/private_key.bin","rb") as f:
|
||||
private_key_local=f.read().strip()
|
||||
with open("data/key/PASSWORDsalt.txt","r",encoding="utf-8") as f:
|
||||
PASSWORDsalt=f.read().strip()
|
||||
with open("data/key/verifysalt.txt","r",encoding="utf-8") as f:
|
||||
verifysalt=f.read().strip()
|
||||
with open("data/key/AES_password_verify.bin","rb") as f:
|
||||
AES_password_verify=f.read().strip()
|
||||
#将管理密钥转化为AES-256密钥并验证
|
||||
AES_password=hashlib.sha256((PASSWORD+PASSWORDsalt).encode("utf-8")).digest()
|
||||
AES_password_SHA=hashlib.sha256(AES_password+verifysalt.encode("utf-8")).digest()
|
||||
if AES_password_SHA!=AES_password_verify:
|
||||
return "管理密钥错误"
|
||||
else:
|
||||
#AES解密RSA私钥
|
||||
AES_key=AES.new(AES_password,AES.MODE_ECB)
|
||||
private_key_pem=unpad(AES_key.decrypt(private_key_local),32)
|
||||
private_key=RSA.import_key(private_key_pem)
|
||||
#使用RSA私钥解密数据
|
||||
decrypter=PKCS1_OAEP.new(private_key)
|
||||
return decrypter.decrypt(note)
|
||||
|
||||
#添加用户
|
||||
def add():
|
||||
@@ -14,9 +115,10 @@ def add():
|
||||
numberx=input("手机号码:")
|
||||
dayx=int(input("代理天数:"))
|
||||
gamex=input("关卡号:")
|
||||
passwordx=input("密码:")
|
||||
passwordx=readpass("密码:")
|
||||
passwordx=encryptx(passwordx)
|
||||
#应用更新
|
||||
cur.execute("INSERT INTO adminx(admin,number,day,status,last,game,password) VALUES('%s','%s',%d,'y','2000-01-01','%s','%s')" %(adminx,numberx,dayx,gamex,passwordx))
|
||||
cur.execute("INSERT INTO adminx VALUES(?,?,?,'y','2000-01-01',?,?)",(adminx,numberx,dayx,gamex,passwordx))
|
||||
db.commit()
|
||||
cur.close()
|
||||
db.close()
|
||||
@@ -27,12 +129,12 @@ def delete(id):
|
||||
db=sqlite3.connect(DATABASE)
|
||||
cur=db.cursor()
|
||||
#检查用户是否存在
|
||||
cur.execute("SELECT * FROM adminx WHERE admin='%s'" %(id))
|
||||
cur.execute("SELECT * FROM adminx WHERE admin=?",(id,))
|
||||
data=cur.fetchall()
|
||||
if len(data)==0:
|
||||
return "未找到"+id
|
||||
#应用更新
|
||||
cur.execute("DELETE FROM adminx WHERE admin='%s'" %(id))
|
||||
cur.execute("DELETE FROM adminx WHERE admin=?",(id,))
|
||||
db.commit()
|
||||
cur.close()
|
||||
db.close()
|
||||
@@ -42,27 +144,55 @@ def delete(id):
|
||||
def search(id,book):
|
||||
db=sqlite3.connect(DATABASE)
|
||||
cur=db.cursor()
|
||||
#处理启动时间查询
|
||||
if id=="time":
|
||||
cur.execute("SELECT * FROM timeset WHERE True")
|
||||
timex=cur.fetchall()
|
||||
timex=[list(row) for row in timex]
|
||||
cur.close()
|
||||
db.close()
|
||||
if len(timex)==0:
|
||||
return "启动时间未设置"
|
||||
else:
|
||||
for i in range(len(timex)):
|
||||
print(timex[i][0])
|
||||
return ""
|
||||
#处理MAA路径查询
|
||||
if id=="maa":
|
||||
cur.execute("SELECT * FROM setting WHERE True")
|
||||
cur.execute("SELECT * FROM pathset WHERE True")
|
||||
pathx=cur.fetchall()
|
||||
if len(pathx)>0:
|
||||
cur.close()
|
||||
db.close()
|
||||
return pathx[0][0]
|
||||
else:
|
||||
cur.close()
|
||||
db.close()
|
||||
return "MAA路径未设置"
|
||||
#处理用户查询与全部信息查询
|
||||
if id=="all":
|
||||
cur.execute("SELECT * FROM adminx WHERE True")
|
||||
else:
|
||||
cur.execute("SELECT * FROM adminx WHERE admin='%s'" %(id))
|
||||
cur.execute("SELECT * FROM adminx WHERE admin=?",(id,))
|
||||
data=cur.fetchall()
|
||||
#处理全部信息查询时的MAA路径与启动时间查询
|
||||
if id=="all":
|
||||
cur.execute("SELECT * FROM setting WHERE True")
|
||||
cur.execute("SELECT * FROM pathset WHERE True")
|
||||
pathx=cur.fetchall()
|
||||
if len(pathx)>0:
|
||||
print("\nMAA路径:"+pathx[0][0])
|
||||
else:
|
||||
print("\nMAA路径未设置")
|
||||
cur.execute("SELECT * FROM timeset WHERE True")
|
||||
timex=cur.fetchall()
|
||||
timex=[list(row) for row in timex]
|
||||
if len(timex)==0:
|
||||
print("\n启动时间未设置")
|
||||
else:
|
||||
print("启动时间:",end='')
|
||||
for i in range(len(timex)):
|
||||
print(timex[i][0],end=' ')
|
||||
print('')
|
||||
cur.close()
|
||||
db.close()
|
||||
data=[list(row) for row in data]
|
||||
@@ -81,6 +211,12 @@ def search(id,book):
|
||||
data[i][3]="禁用"
|
||||
if id=="all":
|
||||
data[i][6]="******"
|
||||
else:
|
||||
#解密
|
||||
global PASSWORD
|
||||
if PASSWORD==0:
|
||||
PASSWORD=input("请输入管理密钥:")
|
||||
data[i][6]=decryptx(data[i][6],PASSWORD).decode("utf-8")
|
||||
#制表输出
|
||||
if book==1:
|
||||
print('')
|
||||
@@ -89,7 +225,7 @@ def search(id,book):
|
||||
print(unit(data[i][0],15),unit(data[i][1],12),unit(data[i][2],8),unit(data[i][3],4),unit(data[i][4],10),unit(data[i][5],10),unit(data[i][6],25))
|
||||
return ""
|
||||
elif id=="all":
|
||||
return "当前没有用户记录"
|
||||
return "\n当前没有用户记录"
|
||||
else:
|
||||
return "未找到"+id
|
||||
|
||||
@@ -104,12 +240,14 @@ def renewal(readxx):
|
||||
#检查用户是否存在
|
||||
db=sqlite3.connect(DATABASE)
|
||||
cur=db.cursor()
|
||||
cur.execute("SELECT * FROM adminx WHERE admin='%s'" %(id))
|
||||
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=%d WHERE admin='%s'" %(data[0][2]+dayp,id))
|
||||
cur.execute("UPDATE adminx SET day=? WHERE admin=?",(data[0][2]+dayp,id))
|
||||
db.commit()
|
||||
cur.close()
|
||||
db.close()
|
||||
@@ -120,13 +258,14 @@ def turn(id,t):
|
||||
#检查用户是否存在
|
||||
db=sqlite3.connect(DATABASE)
|
||||
cur=db.cursor()
|
||||
cur.execute("SELECT * FROM adminx WHERE admin='%s'" %(id))
|
||||
cur.execute("SELECT * FROM adminx WHERE admin=?",(id,))
|
||||
data=cur.fetchall()
|
||||
if len(data)==0:
|
||||
cur.close()
|
||||
db.close()
|
||||
return "未找到"+id
|
||||
#应用更新
|
||||
if t=='y' or t=='n':
|
||||
cur.execute("UPDATE adminx SET status='%s' WHERE admin='%s'" %(t,id))
|
||||
cur.execute("UPDATE adminx SET status=? WHERE admin=?",(t,id))
|
||||
db.commit()
|
||||
cur.close()
|
||||
db.close()
|
||||
@@ -146,9 +285,11 @@ def gameid(readxx):
|
||||
#检查用户是否存在
|
||||
db=sqlite3.connect(DATABASE)
|
||||
cur=db.cursor()
|
||||
cur.execute("SELECT * FROM adminx WHERE admin='%s'" %(id))
|
||||
cur.execute("SELECT * FROM adminx WHERE admin=?",(id,))
|
||||
data=cur.fetchall()
|
||||
if len(data)==0:
|
||||
cur.close()
|
||||
db.close()
|
||||
return "未找到"+id
|
||||
#导入与应用特殊关卡规则
|
||||
games={}
|
||||
@@ -164,7 +305,7 @@ def gameid(readxx):
|
||||
if gamep in games:
|
||||
gamep=games[gamep]
|
||||
#应用更新
|
||||
cur.execute("UPDATE adminx SET game='%s' WHERE admin='%s'" %(gamep,id))
|
||||
cur.execute("UPDATE adminx SET game=? WHERE admin=?",(gamep,id))
|
||||
db.commit()
|
||||
cur.close()
|
||||
db.close()
|
||||
@@ -174,17 +315,52 @@ def gameid(readxx):
|
||||
def setpath(pathx):
|
||||
db=sqlite3.connect(DATABASE)
|
||||
cur=db.cursor()
|
||||
cur.execute("SELECT * FROM setting WHERE True")
|
||||
cur.execute("SELECT * FROM pathset WHERE True")
|
||||
pathold=cur.fetchall()
|
||||
if len(pathold)>0:
|
||||
cur.execute("UPDATE setting SET path='%s' WHERE True" %(pathx))
|
||||
cur.execute("UPDATE pathset SET path=? WHERE True",(pathx,))
|
||||
else:
|
||||
cur.execute("INSERT INTO setting(path) VALUES('%s')" %(pathx))
|
||||
cur.execute("INSERT INTO pathset VALUES(?)",(pathx,))
|
||||
db.commit()
|
||||
cur.close()
|
||||
db.close()
|
||||
return "MAA路径已设置为"+pathx
|
||||
|
||||
#设置启动时间
|
||||
def settime(book,timex):
|
||||
db=sqlite3.connect(DATABASE)
|
||||
cur=db.cursor()
|
||||
#检查待操作对象存在情况
|
||||
cur.execute("SELECT * FROM timeset WHERE True")
|
||||
timeold=cur.fetchall()
|
||||
timeold=[list(row) for row in timeold]
|
||||
timenew=[]
|
||||
timenew.append(timex)
|
||||
#添加时间设置
|
||||
if book=='+':
|
||||
if timenew in timeold:
|
||||
cur.close()
|
||||
db.close()
|
||||
return "已存在"+timex
|
||||
else:
|
||||
cur.execute("INSERT INTO timeset VALUES(?)",(timex,))
|
||||
db.commit()
|
||||
cur.close()
|
||||
db.close()
|
||||
return "已添加"+timex
|
||||
#删除时间设置
|
||||
elif book=='-':
|
||||
if timenew in timeold:
|
||||
cur.execute("DELETE FROM timeset WHERE time=?",(timex,))
|
||||
db.commit()
|
||||
cur.close()
|
||||
db.close()
|
||||
return "已删除"+timex
|
||||
else:
|
||||
cur.close()
|
||||
db.close()
|
||||
return "未找到"+timex
|
||||
|
||||
#统一制表单元
|
||||
def unit(x,m):
|
||||
#字母与连接符占1位,中文占2位
|
||||
@@ -197,16 +373,20 @@ def unit(x,m):
|
||||
|
||||
#初期检查
|
||||
DATABASE="data/data.db"
|
||||
PASSWORD=0
|
||||
if not os.path.exists(DATABASE):
|
||||
db=sqlite3.connect(DATABASE)
|
||||
cur=db.cursor()
|
||||
db.execute("CREATE TABLE adminx(admin text,number text,day int,status text,last date,game text,password text)")
|
||||
db.execute("CREATE TABLE setting(path text)")
|
||||
db.execute("CREATE TABLE adminx(admin text,number text,day int,status text,last date,game text,password byte)")
|
||||
db.execute("CREATE TABLE pathset(path text)")
|
||||
db.execute("CREATE TABLE timeset(time text)")
|
||||
readx=input("首次启动,请设置MAA路径:")
|
||||
cur.execute("INSERT INTO setting(path) VALUES('%s')" %(readx))
|
||||
cur.execute("INSERT INTO pathset VALUES(?)",(readx,))
|
||||
db.commit()
|
||||
cur.close()
|
||||
db.close()
|
||||
PASSWORD=readpass("请设置管理密钥(密钥与数据库绑定且唯一不可变):")
|
||||
getPASSWORD(PASSWORD)
|
||||
|
||||
#初始界面
|
||||
print("Good evening!")
|
||||
@@ -223,6 +403,8 @@ while True:
|
||||
exit()
|
||||
elif read[0]=='/':
|
||||
print(setpath(read[1:]))
|
||||
elif read[0]==':' and (read[1]=='+' or read[1]=='-'):
|
||||
print(settime(read[1],read[2:]))
|
||||
else:
|
||||
if read[-1]=='?':
|
||||
print(search(read[:-2],1))
|
||||
|
||||
BIN
mytaskkill.exe
BIN
res/AUTO_MAA.ico
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
BIN
res/AUTO_MAA.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
res/README/MAA配置1.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
res/README/MAA配置2.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
res/README/MAA配置3.png
Normal file
|
After Width: | Height: | Size: 60 KiB |
BIN
res/README/MAA配置4.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
BIN
res/README/gameid.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
res/README/payid.png
Normal file
|
After Width: | Height: | Size: 746 KiB |
BIN
res/README/信息配置1.png
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
res/README/信息配置10.png
Normal file
|
After Width: | Height: | Size: 93 KiB |
BIN
res/README/信息配置11.png
Normal file
|
After Width: | Height: | Size: 97 KiB |
BIN
res/README/信息配置12.png
Normal file
|
After Width: | Height: | Size: 94 KiB |
BIN
res/README/信息配置13.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
BIN
res/README/信息配置14.png
Normal file
|
After Width: | Height: | Size: 96 KiB |
BIN
res/README/信息配置2.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
res/README/信息配置3.png
Normal file
|
After Width: | Height: | Size: 69 KiB |
BIN
res/README/信息配置4.png
Normal file
|
After Width: | Height: | Size: 73 KiB |
BIN
res/README/信息配置5.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
BIN
res/README/信息配置6.png
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
res/README/信息配置7.png
Normal file
|
After Width: | Height: | Size: 86 KiB |
BIN
res/README/信息配置8.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
BIN
res/README/信息配置9.png
Normal file
|
After Width: | Height: | Size: 92 KiB |
46
run.py
@@ -1,10 +1,12 @@
|
||||
import os
|
||||
import subprocess
|
||||
import sqlite3
|
||||
import datetime
|
||||
import time
|
||||
import json
|
||||
from termcolor import colored
|
||||
|
||||
#判断MAA程序运行状态
|
||||
def ifoff():
|
||||
while True:
|
||||
time.sleep(10)
|
||||
@@ -17,16 +19,9 @@ def ifoff():
|
||||
elif ("请检查连接设置或尝试重启模拟器与 ADB 或重启电脑" in log) or ("已停止" in log):
|
||||
return False
|
||||
|
||||
def killpath(maapath):
|
||||
kpath='.\\mytaskkill.exe '
|
||||
for i in maapath:
|
||||
if i=='/':
|
||||
kpath=kpath+'\\'
|
||||
else:
|
||||
kpath=kpath+i
|
||||
return kpath
|
||||
|
||||
def runmaa(tel,game):
|
||||
#执行MAA任务
|
||||
def runmaa(tel,game,num=2):
|
||||
#配置MAA运行参数
|
||||
with open(setpath,"r",encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
data["Configurations"]["Default"]["Start.AccountName"]=tel[:3]+"****"+tel[7:]
|
||||
@@ -37,31 +32,26 @@ def runmaa(tel,game):
|
||||
data["Configurations"]["Default"]["MainFunction.Stage1"]=game
|
||||
with open(setpath,"w",encoding="utf-8") as f:
|
||||
json.dump(data,f)
|
||||
os.system('start '+maapath)
|
||||
time.sleep(60)
|
||||
if ifoff():
|
||||
return True
|
||||
else:
|
||||
command=killpath(maapath)
|
||||
os.system(command)
|
||||
os.system('start '+maapath)
|
||||
#开始运行
|
||||
for i in range(num):
|
||||
maa=subprocess.Popen([maapath])
|
||||
maapid=maa.pid
|
||||
time.sleep(60)
|
||||
if ifoff():
|
||||
return True
|
||||
else:
|
||||
command=killpath(maapath)
|
||||
os.system(command)
|
||||
return False
|
||||
os.system('taskkill /F /T /PID '+str(maapid))
|
||||
return False
|
||||
|
||||
#更新已完成用户的数据
|
||||
def updata(id):
|
||||
db=sqlite3.connect(DATABASE)
|
||||
cur=db.cursor()
|
||||
cur.execute("SELECT * FROM adminx WHERE admin='%s'" %(id))
|
||||
cur.execute("SELECT * FROM adminx WHERE admin=?",(id,))
|
||||
info=cur.fetchall()
|
||||
cur.execute("UPDATE adminx SET day=%d WHERE admin='%s'" %(info[0][2]-1,id))
|
||||
cur.execute("UPDATE adminx SET day=? WHERE admin=?",(info[0][2]-1,id))
|
||||
db.commit()
|
||||
cur.execute("UPDATE adminx SET last='%s' WHERE admin='%s'" %(curdate,id))
|
||||
print("upcurdate")
|
||||
cur.execute("UPDATE adminx SET last=? WHERE admin=?",(curdate,id))
|
||||
db.commit()
|
||||
cur.close()
|
||||
db.close()
|
||||
@@ -71,7 +61,7 @@ def updata(id):
|
||||
DATABASE="data/data.db"
|
||||
db=sqlite3.connect(DATABASE)
|
||||
cur=db.cursor()
|
||||
cur.execute("SELECT * FROM setting WHERE True")
|
||||
cur.execute("SELECT * FROM pathset WHERE True")
|
||||
path=cur.fetchall()
|
||||
path=str(path[0][0])
|
||||
setpath=path+"/config/gui.json"
|
||||
@@ -109,4 +99,6 @@ with open("log.txt","w", encoding="utf-8") as f:
|
||||
if len(idfail)!=0:
|
||||
print("代理未完成的用户:",file=f)
|
||||
for i in range(len(idfail)):
|
||||
print(idfail[i],file=f)
|
||||
print(idfail[i],file=f)
|
||||
with open("OVER","w", encoding="utf-8") as f:
|
||||
print("OVER",file=f)
|
||||
5
toexe.py
Normal file
@@ -0,0 +1,5 @@
|
||||
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")
|
||||
@@ -1,7 +0,0 @@
|
||||
声明:
|
||||
|
||||
KillSpecifiedProcess.cpp与mytaskkill.exe来自CSDN博主的文章,遵循CC 4.0 BY-SA 版权协议附加以下信息:
|
||||
|
||||
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
|
||||
|
||||
原文链接:https://blog.csdn.net/qq_29542611/article/details/122003681
|
||||