Compare commits

...

10 Commits
v1.0 ... v2.1.1

Author SHA1 Message Date
DLmaster
286ee9e51e 添加修改管理密钥功能 2024-02-15 20:15:05 +08:00
DLmaster
9a2a88384b Create LICENSE 2024-02-15 15:08:30 +08:00
DLmaster
68068b29e1 适配v2.1的内容更新 2024-02-11 20:38:56 +08:00
DLmaster
3b0b50670d 用户密码加密部分上线,SQL指令更新防止注入攻击 2024-02-11 19:45:28 +08:00
DLmaster
863b6dd220 重新编入Repobeats 2024-02-07 19:26:53 +08:00
DLmaster
e3c9e3088b 无足轻重的补充 2024-02-07 16:43:42 +08:00
DLmaster
27bdfc8581 更新有关图标的说明 2024-02-07 16:29:18 +08:00
DLmaster
a2b1731fac 添加README 2024-02-07 16:19:04 +08:00
DLmaster
f96c9253fe README相关图片 2024-02-07 16:06:03 +08:00
DLmaster
9e93b6ef35 2.0版本(去除对第三方代码的依赖,添加定时功能,主程序上线) 2024-02-06 21:12:49 +08:00
35 changed files with 588 additions and 195 deletions

BIN
AUTO_MAA.exe Normal file

Binary file not shown.

29
AUTO_MAA.py Normal file
View 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)

View File

@@ -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;
}

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 DLmaster
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

262
README.md Normal file
View File

@@ -0,0 +1,262 @@
# AUTO_MAA
MAA多账号管理与自动化软件
!["软件图标"](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/AUTO_MAA.png "软件图标")
----------------------------------------------------------------------------------------------
## 免责声明
本软件是一个外部工具旨在优化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小时内过期的理智药”
![MAA配置1](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/MAA配置1.png "MAA配置1")
3.确保当前配置名为“Default”取消所有“定时执行”
![MAA配置2](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/MAA配置2.png "MAA配置2")
4.取消勾选“开机自启动MAA”勾选“启动MAA后直接运行”和“启动MAA后自动开启模拟器”。配置自己模拟器所在的位置并根据实际情况填写“等待模拟器启动时间”建议预留10s以防意外。如果是多开用户需要填写“附加命令”具体填写值参见多开模拟器对应快捷方式路径如“-v 1”
![MAA配置3](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/MAA配置3.png "MAA配置3")
5.勾选“定时检查更新”、“自动下载更新包”和“自动安装更新包”
![MAA配置4](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/MAA配置4.png "MAA配置4")
## 下载AUTO_MAA软件包 [![](https://img.shields.io/github/downloads/DLmaster361/AUTO_MAA/total?color=66ccff)](https://github.com/DLmaster361/AUTO_MAA/releases)
GitHub下载地址 [GitHub下载](https://github.com/DLmaster361/AUTO_MAA/releases)
## 配置用户信息与相关参数
**注意:** 当前所有的密码输入部分都存在一点“小问题”请在输入密码时避免输入Delete、F12、Tab等功能键。
-------------------------------------------------
### 第一次启动
双击启动`manage.exe`输入MAA所在文件夹路径并回车注意使用斜杠的种类不要使用反斜杠然后设置管理密钥密钥可以包含字母大小写与特殊字符
![信息配置1](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置1.png "信息配置1")
管理密钥是解密用户密码的唯一凭证,与数据库绑定。密钥丢失或`data/key/`目录下任一文件损坏都将导致解密无法正常进行。
本项目采用自主开发的混合加密模式,项目组也无法找回您的管理密钥或修复`data/key/`目录下的文件。如果不幸的事发生,建议您删除`data/data.db`重新录入信息。
### 添加用户
输入“+”以开始添加用户。依次输入:
**用户名:** 管理用户的惟一凭证
**手机号码:** 允许隐去中间四位以“****”代替
**代理天数:** 这个还要我解释吗?
![信息配置2](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置2.png "信息配置2")
### 删除用户
输入用户名+“-”以删除用户。格式:
```
用户名 -
```
![信息配置3](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置3.png "信息配置3")
### 配置用户状态
**启用代理:** 输入用户名+“y”以启用该用户的代理。格式
```
用户名 y
```
![信息配置4](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置4.png "信息配置4")
**禁用代理:** 输入用户名+“n”以禁用该用户的代理。格式
```
用户名 n
```
![信息配置5](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置5.png "信息配置5")
### 续期
输入用户名+续期天数+“+”以延长该用户的代理天数。格式:
```
用户名 续期天数 +
```
![信息配置6](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置6.png "信息配置6")
### 修改刷取关卡
输入用户名+关卡号+“~”以更改该用户的代理关卡。格式:
```
用户名 关卡号 ~
```
![信息配置7](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置7.png "信息配置7")
**特别的:**
你可以自定义关卡号替换方案。程序会读取`gameid.txt`中的数据,依据此进行关卡号的替换,便于常用关卡的使用。`gameid.txt`在初始已经存储了一些常用资源本的替代方案。
![gameid](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/gameid.png "gameid")
### 设置MAA路径
输入“/”+新的MAA文件夹路径以修改MAA安装位置的配置。格式
```
/新的MAA文件夹路径
```
**注意:** /’与路径间没有空格,路径同样不能使用反斜杠
![信息配置8](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置8.png "信息配置8")
### 设置启动时间
**添加启动时间:** 输入“:+”+时间以添加定时启动时间。格式:
```
:+小时:分钟
```
**注意:** 所有输入间没有空格
![信息配置9](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置9.png "信息配置9")
**删除启动时间:** 输入“:-”+时间以删除定时启动时间。格式:
```
:-小时:分钟
```
**注意:** 所有输入间没有空格
![信息配置10](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置10.png "信息配置10")
### 检索信息
**检索所有信息:** `manage.exe`打开时会打印所有用户与配置信息。除此之外你可以通过输入“all ?”以打印所有信息,如下:
```
all ?
```
![信息配置11](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置11.png "信息配置11")
**检索MAA路径** 输入“maa ?”以检索MAA安装路径如下
```
maa ?
```
![信息配置12](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置12.png "信息配置12")
**检索启动时间:** 输入“time ?”以检索定时启动的时间,如下:
```
time ?
```
![信息配置13](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置13.png "信息配置13")
**检索指定用户:** 输入用户名+“?”以检索指定用户信息,如下:
```
用户名 ?
```
**注意:** 由于需要检索用户密码,每一次`manage.exe`启动后的首次查询需要验证管理密钥。为了方便操作,之后的查询不会再要求重复验证。因此,完成密码查询后,请及时关闭`manage.exe`
![信息配置14](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置14.png "信息配置14")
### 修改管理密钥
输入“*”以开始修改管理密钥。依次输入:
**旧管理密钥:** 当数据库中没有存储用户信息时,允许跳过验证直接配置新管理密钥
**新管理密钥:** 请妥善保管,丢失无法找回。
![信息配置15](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/信息配置15.png "信息配置15")
### 退出
输入“-”以退出`manage.exe`,如下:
```
-
```
## 运行代理
### 直接运行
双击`run.exe`直接运行
### 定时运行
双击`AUTO_MAA.exe`打开,不要关闭。它会读取设定时间,在该时刻自动运行
**注意:** 周一将自动进行剿灭代理
## 关于
项目图标由文心一格AI生成
----------------------------------------------------------------------------------------------
欢迎加入AUTO_MAA项目组欢迎反馈bug
QQ群暂时没有
----------------------------------------------------------------------------------------------
如果喜欢本项目,可以打赏送作者一杯咖啡喵!
![打赏](https://github.com/DLmaster361/AUTO_MAA/blob/main/res/README/payid.png "打赏")
----------------------------------------------------------------------------------------------
## 贡献者
感谢以下贡献者对本项目做出的贡献
<a href="https://github.com/DLmaster361/AUTO_MAA/graphs/contributors">
<img src="https://contrib.rocks/image?repo=DLmaster361/AUTO_MAA" />
</a>
![Alt](https://repobeats.axiom.co/api/embed/6c2f834141eff1ac297db70d12bd11c6236a58a5.svg "Repobeats analytics image")
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=DLmaster361/AUTO_MAA&type=Date)](https://star-history.com/#DLmaster361/AUTO_MAA&Date)

BIN
manage.exe Normal file

Binary file not shown.

280
manage.py
View File

@@ -1,6 +1,147 @@
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)
note=decrypter.decrypt(note)
return note.decode("utf-8")
#修改管理密钥
def changePASSWORD():
#获取用户信息
db=sqlite3.connect(DATABASE)
cur=db.cursor()
cur.execute("SELECT * FROM adminx WHERE True")
data=cur.fetchall()
cur.close()
db.close()
data=[list(row) for row in data]
global PASSWORD
#验证管理密钥
PASSWORDold=readpass("请输入旧管理密钥:")
if len(data)==0:
print("当前无用户,验证自动通过")
PASSWORDnew=readpass("请输入新管理密钥:")
getPASSWORD(PASSWORDnew)
PASSWORD=PASSWORDnew
return "管理密钥修改成功"
while decryptx(data[0][6],PASSWORDold)=="管理密钥错误":
print("管理密钥错误")
PASSWORDold=readpass("请输入旧管理密钥:")
print("验证通过")
#修改管理密钥
PASSWORDnew=readpass("请输入新管理密钥:")
#使用旧管理密钥解密
for i in range(len(data)):
data[i][6]=decryptx(data[i][6],PASSWORDold)
#使用新管理密钥重新加密
getPASSWORD(PASSWORDnew)
db=sqlite3.connect(DATABASE)
cur=db.cursor()
for i in range(len(data)):
cur.execute("UPDATE adminx SET password=? WHERE admin=?",(encryptx(data[i][6]),data[i][0]))
db.commit()
cur.close()
db.close()
PASSWORD=PASSWORDnew
return "管理密钥修改成功"
#添加用户
def add():
@@ -14,9 +155,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 +169,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 +184,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 +251,12 @@ def search(id,book):
data[i][3]="禁用"
if id=="all":
data[i][6]="******"
else:
#解密
global PASSWORD
if PASSWORD==0 or decryptx(data[i][6],PASSWORD)=="管理密钥错误":
PASSWORD=readpass("请输入管理密钥:")
data[i][6]=decryptx(data[i][6],PASSWORD)
#制表输出
if book==1:
print('')
@@ -89,7 +265,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 +280,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 +298,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 +325,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 +345,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 +355,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 +413,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!")
@@ -217,22 +437,26 @@ while True:
read=input()
if len(read)==0:
print("无法识别的输入")
elif read[0]=='+':
elif read[0]=='+' and len(read)==1:
print(add())
elif read[0]=='-':
elif read[0]=='-' and len(read)==1:
exit()
elif read[0]=='/':
print(setpath(read[1:]))
elif read[0]=='*' and len(read)==1:
print(changePASSWORD())
elif read[0]==':' and (read[1]=='+' or read[1]=='-'):
print(settime(read[1],read[2:]))
else:
if read[-1]=='?':
if read[-1]=='?' and read[-2]==' ':
print(search(read[:-2],1))
elif read[-1]=='+':
elif read[-1]=='+' and read[-2]==' ':
print(renewal(read[:-2]))
elif read[-1]=='-':
elif read[-1]=='-' and read[-2]==' ':
print(delete(read[:-2]))
elif read[-1]=='~':
elif read[-1]=='~' and read[-2]==' ':
print(gameid(read[:-2]))
elif read[-1]=='y' or read[-1]=='n':
elif (read[-1]=='y' or read[-1]=='n') and read[-2]==' ':
print(turn(read[:-2],read[-1]))
else:
print("无法识别的输入")

Binary file not shown.

BIN
res/AUTO_MAA.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
res/AUTO_MAA.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

BIN
res/README/MAA配置1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

BIN
res/README/MAA配置2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

BIN
res/README/MAA配置3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

BIN
res/README/MAA配置4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
res/README/gameid.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
res/README/payid.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 746 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

BIN
run.exe Normal file

Binary file not shown.

46
run.py
View File

@@ -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
View 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")

View File

@@ -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