This commit is contained in:
Administrator
2025-11-12 12:54:37 +08:00
commit a0720d80dc
3954 changed files with 1158090 additions and 0 deletions

142
process/bit_process.py Normal file
View File

@@ -0,0 +1,142 @@
import time
from concurrent.futures import ThreadPoolExecutor
from models.tg_models import TelegramAccount
from process.tg_process import TG
from process.tools import get_host_ip
from loguru import logger
from DrissionPage import ChromiumPage, ChromiumOptions
from 比特.bit_tools import openBrowser
class BitProcess(object):
def __init__(self, bit_info):
self.bit_info = bit_info
self.tg = None
self.page = None
def get_page(self):
try:
port = openBrowser(id=self.bit_info.bit_id)["data"]["http"].split(":")
co = ChromiumOptions().set_local_port(port[1])
self.page = ChromiumPage(co)
return True
except:
pass
return False
def start_ld(self):
self.tg = TG(type1=1, tg_phone=self.bit_info, )
if self.tg.get_code():
return False
return True
def get_is_logged_in_telegram(self):
try:
self.page.ele('x://*[@id="LeftMainHeader"]/div[1]/button', timeout=50).click()
self.page.ele('x://button[text()="Settings"]', timeout=50)
self.bit_info.bit_is_logged_in_telegram = 1
self.bit_info.save()
return True
except:
pass
return False
def action(self):
if self.get_page():
logger.info(f"当前电话号码:{self.bit_info.ld_name},打开浏览器成功!!!")
else:
logger.error(f"当前电话号码:{self.bit_info.ld_name},打开浏览器失败!!!")
return
try:
for _, i in enumerate(self.page.get_tabs()):
if _ == 0:
continue
i.close()
except:
pass
if self.start_ld():
logger.info(f"当前电话号码:{self.bit_info.ld_name},打开模拟器成功!!!")
else:
logger.error(f"当前电话号码:{self.bit_info.ld_name},打开模拟器失败!!!")
self.page.get('https://web.telegram.org/a/')
if self.get_is_logged_in_telegram():
logger.info(f"当前电话号码:{self.bit_info.ld_name},登录成功!!!")
self.page.ele("x://button[text()='Log in by phone Number']", timeout=50).click()
time.sleep(10)
self.page.ele('x://*[@id="sign-in-phone-number"]').input(clear=True, vals=self.bit_info.ld_name)
time.sleep(5)
self.page.ele("x://button[text()='Next']", timeout=50).click()
time.sleep(10)
self.page.ele('x://*[@id="sign-in-code"]').input(self.tg.get_code1()[-1])
self.tg.close_ldplayer()
time.sleep(10)
self.page.ele('x://*[@id="sign-in-password"]').input("Qasdasd123.0")
time.sleep(10)
self.page.ele("x://button[text()='Next']", timeout=50).click()
if self.get_is_logged_in_telegram():
logger.info(f"当前电话号码:{self.bit_info.ld_name},登录成功!!!")
if __name__ == '__main__':
tg_phone_datas = TelegramAccount().select().where(
TelegramAccount.server_id == get_host_ip(),
TelegramAccount.is_logged_in_telegram == 1,
)
# 同时运行
max_threads = 1
delay_between_start = 15 # 每次启动线程之间的延迟时间(秒)
with ThreadPoolExecutor(max_workers=max_threads) as executor:
while True:
futures = []
for i in tg_phone_datas:
try:
tg = BitProcess(bit_info=i)
except Exception as e:
continue
# 提交线程任务到线程池
future = executor.submit(tg.action)
futures.append(future)
# 线程启动间隔
time.sleep(delay_between_start)
# 等待所有提交的任务完成
done = False
while not done:
done = True
for future in futures:
if not future.done():
done = False
time.sleep(60) # 可以根据需要调整休眠时间
break
time.sleep(600)

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
process/images/bitgit.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
process/images/bitgit1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
process/images/bitgit2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

BIN
process/images/bitgit3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
process/images/blum_buy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
process/images/blum_max.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
process/images/goat_ton.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

BIN
process/images/goat_x.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
process/images/hk_.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
process/images/ip_add.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

BIN
process/images/metamask.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
process/images/tg_send.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
process/images/xpin_okx.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
process/images/zoo_1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
process/images/zoo_2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

750
process/mumu_process.py Normal file
View File

@@ -0,0 +1,750 @@
import time
import threading
from concurrent.futures import ThreadPoolExecutor
from loguru import logger
import uiautomator2 as u2
from rich_progress import Haha
from mini_models.tg_phone_devices import TgPhoneDevices
from models.blum_tx import BlumTx
from models.device_info import DeviceInfo
from models.project_ip import ProjectType
from models.teleqram_account_mumu import TeleqramAccountMumu
from models.tg_models import TelegramAccount
from process.mumu_tools import mumu_quit, mumu_start, mumu_rename, mumu_create, mumu_get_list_all
from process.tools import get_host_ip, get_element, get_code, swipe_up, match_image, find_img, split_phone_number
lock = threading.Lock()
class MuTG:
def __init__(self, tg_phone, progress):
self.dev_info = None
self.tg_phone = tg_phone
self.progress = progress
self.d = None
self.index_id = None
def log_tg(self):
time.sleep(1)
type1, ele = get_element(self.d, type1="text", grammar='Start Messaging', timeout=5)
if type1:
ele.click()
type1, ele = get_element(self.d, type1="text", grammar='Continue', timeout=5)
if type1: # 点开过
ele.click()
type1, ele = get_element(self.d, type1="text", grammar='允许', timeout=5)
if type1: # 点开过
ele.click()
self.d.xpath('//*[@content-desc="Country code"]').set_text(self.tg_phone.one_phone_number)
self.d.xpath('//*[@content-desc="Phone number"]').set_text(self.tg_phone.telephone)
self.d.xpath('//*[@content-desc="Done"]').click()
self.d(text="Yes").click()
type1, ele = get_element(self.d, type1="text", grammar='Continue', timeout=5)
if type1: # 点开过
ele.click()
type1, ele = get_element(self.d, type1="text", grammar='允许', timeout=5)
if type1: # 点开过
ele.click()
# 获取验证码,密码
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="Check your Telegram messages"]',
timeout=100)
time.sleep(15)
code = get_code(phone=self.tg_phone.ld_name, ) # 连接获取2fa和验证码
# 输入验证码,密码
self.d.send_keys(code) # 输入密码
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="Your password"]',
timeout=100)
self.d.send_keys("Qasdasd123.0") # 输入2fa密码
time.sleep(5)
self.d.xpath('//*[@content-desc="Done"]').click()
# 使用链接打开tg的检测
def tg_testing(self):
self.progress.info(f"电话号码:{self.tg_phone.ld_name}:账号检测中》》》")
# 判断需要tg打开链接
for i in range(8):
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="Continue"]', timeout=0.5)
if type1:
ele.click()
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="允许"]', timeout=3)
if type1:
ele.click()
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="允许"]', timeout=3)
if type1:
ele.click()
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="OK"]', timeout=0.5)
if type1:
ele.click()
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="Remind me later"]', timeout=0.5)
if type1:
ele.click()
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="Telegram"]', timeout=0.5)
if type1:
ele.click()
time.sleep(5)
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="始终"]', timeout=0.5)
if type1: ele.click()
# 判断tg是否掉了
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="Start Messaging"]',
timeout=0.5) # 等待tg打开
if type1:
self.tg_phone.index_id = self.index_id
self.tg_phone.phone_type = 0
self.tg_phone.is_logged_in_telegram = 0
self.tg_phone.save()
self.progress.error(f"电话号码:{self.tg_phone.ld_name}:检测完成:未登录!!!")
return True
self.tg_phone.index_id = self.index_id
self.tg_phone.phone_type = 1
self.tg_phone.is_logged_in_telegram = 1
self.tg_phone.save()
self.progress.info(f"电话号码:{self.tg_phone.ld_name}:检测完成,已登录!!!")
return False
def metamask_add(self):
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="MetaMask"]', timeout=5)
if type1:
self.d.app_uninstall("io.metamask")
self.d.app_install("../data/metamask.apk")
time.sleep(3)
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@content-desc="开始使用"]', timeout=50)
if type1:
ele.click()
time.sleep(3)
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="创建新钱包"]', timeout=10)
if type1:
ele.click()
time.sleep(3)
self.d.xpath(
'//*[@text="我们将使用此数据来了解您如何与我们的营销通信交互。我们可能会分享相关资讯(例如产品特点)。"]').click()
swipe_up(d=self.d, start_y1=0.8, end_y1=0.2)
time.sleep(3)
self.d.xpath('//*[@text="我同意"]').click()
time.sleep(3)
self.d.xpath('//*[@text="我同意适用于我使用MetaMask及其所有功能的使用条款"]').click()
time.sleep(3)
self.d.xpath('//com.horcrux.svg.l').click()
time.sleep(3)
self.d.xpath('//*[@text="接受"]').click()
time.sleep(3)
rect = self.d.xpath('//*[@text="新密码"]').bounds
self.d.click(rect[2] - rect[0], rect[3] + 90)
self.d.send_keys('123456123456')
time.sleep(1)
rect = self.d.xpath('//*[@text="确认密码"]').bounds
self.d.click(rect[2] - rect[0], rect[3] + 90)
self.d.send_keys('123456123456')
time.sleep(5)
self.d.xpath('//*[@resource-id="i-understand-text"]').click()
time.sleep(1)
self.d.xpath('//*[@content-desc="submit-button"]').click()
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@content-desc="稍后提醒我"]', timeout=50)
if type1:
time.sleep(3)
ele.click()
time.sleep(3)
self.d.xpath('//*[@text="我了解丢失私钥助记词后将无法访问钱包。"]').click()
time.sleep(3)
self.d.xpath('//*[@text="跳过"]').click()
time.sleep(3)
self.d.xpath('//*[@text="已完成"]').click()
time.sleep(10)
self.d.xpath('//*[@text="不,谢谢"]').click()
time.sleep(3)
self.d.xpath('//*[@text="不,谢谢"]').click()
time.sleep(3)
self.d.xpath('//*[@text="稍后提醒我"]').click()
time.sleep(3)
self.d.xpath('//*[@text="我了解丢失私钥助记词后将无法访问钱包。"]').click()
time.sleep(3)
self.d.xpath('//*[@text="跳过"]').click()
time.sleep(3)
x_Y = match_image(d=self.d, template_path="images/metamask_add.png", retry_times=5, threshold=0.8)
if x_Y: self.d.click(x_Y[0][0], x_Y[0][1])
time.sleep(3)
self.d.xpath('//*[@content-desc="添加账户或硬件钱包"]').click()
time.sleep(3)
self.d.xpath('//*[@text="导入账户"]').click()
time.sleep(3)
self.d.click(401, 933)
time.sleep(3)
self.d.send_keys(self.tg_koni_info.address1[2:])
time.sleep(3)
swipe_up(d=self.d, start_y1=0.8, end_y1=0.5, duration=0.1)
time.sleep(3)
self.d.xpath('//*[@text="导入"]').click()
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="账户导入成功!"]', timeout=50)
time.sleep(3)
self.d.xpath('//*[@text=""]').click()
time.sleep(3)
self.d.xpath('//*[@text="Account 2"]').click()
time.sleep(3)
# self.d.xpath('//*[@resource-id="tab-bar-item-Browser"]').click()
# time.sleep(3)
# self.d.xpath('//*[@text="portfolio.metamask.io"]').click()
# time.sleep(3)
#
# # 模拟按键删除
# for _ in range(500):
# self.d.press("del")
#
# self.d.send_keys("https://chainlist.org/chain/1516")
# time.sleep(3)
# self.d.press("enter")
# time.sleep(20)
# swipe_up(d=self.d, start_y1=0.8, end_y1=0.6, duration=0.1)
# time.sleep(3)
# x_Y = match_image(d=self.d, template_path="images/metamask_ip_add.png", retry_times=5, threshold=0.8)
# if x_Y: self.d.click(x_Y[0][0], x_Y[0][1])
# time.sleep(3)
# self.d.xpath('//*[@content-desc="连接"]').click()
# time.sleep(3)
# self.d.xpath('//*[@content-desc="确认"]').click()
# time.sleep(3)
# self.d.xpath('//*[@text="切换网络"]').click()
# time.sleep(3)
# self.d.xpath('//*[@text="明白了"]').click()
x_Y = match_image(d=self.d, template_path="images/metamask_lian_add.png", retry_times=5, threshold=0.8)
if x_Y: self.d.click(x_Y[0][0], x_Y[0][1])
time.sleep(3)
self.d.xpath('//*[@resource-id="tab-bar-item-Actions"]').click()
time.sleep(3)
self.d.xpath('//*[@text="网络名称(可选)"]').set_text("Story Odyssey Testnet")
time.sleep(3)
self.d.xpath('//*[@resource-id="button-menu-select-test-id"]').click()
time.sleep(3)
self.d.xpath('//*[@resource-id="button-menu-select-test-id"]').click()
time.sleep(3)
self.d.xpath('(//*[@text="添加 RPC远程过程调用URL"])[2]').click()
time.sleep(3)
self.d.xpath('//*[@text="新 RPC 网络"]').set_text("https://story-testnet-evm.itrocket.net")
time.sleep(3)
self.d.xpath('(//*[@text="添加 RPC远程过程调用URL"])[2]').click()
time.sleep(3)
self.d.xpath('//*[@text="链 ID可选"]').set_text("1516")
time.sleep(3)
self.d.xpath('(//*[@text="符号"])[2]').set_text("IP")
time.sleep(3)
self.d.xpath('//*[@text="保存"]').click()
time.sleep(3)
self.d.xpath('//*[@text="保存"]').click()
time.sleep(3)
x_Y = match_image(d=self.d, template_path="images/metamask_lian_add.png", retry_times=5, threshold=0.8)
if x_Y: self.d.click(x_Y[0][0], x_Y[0][1])
time.sleep(3)
swipe_up(d=self.d, start_y1=0.8, end_y1=0.2)
time.sleep(3)
self.d.xpath('//*[@text="Story Odyssey Testnet"]').click()
time.sleep(3)
self.d.xpath('//*[@text="明白了"]').click()
time.sleep(10)
def start_mumu(self):
with lock:
try:
mumu_lists = mumu_get_list_all()
if mumu_lists:
for mumu_info in mumu_lists:
if mumu_info["name"] == self.tg_phone.ld_name:
self.index_id = mumu_info["index"]
self.progress.info(f"当前电话号码:{self.tg_phone.ld_name},找到模拟器名字!!!")
break
else:
self.progress.error(f"当前电话号码:{self.tg_phone.ld_name},没有找到模拟器名字!!!")
self.index_id = mumu_create()
time.sleep(5)
mumu_rename(id=self.index_id, name=self.tg_phone.ld_name)
time.sleep(10)
d_type = 0
# 连接模拟器
for i in range(3):
if d_type:
break
for i in range(3):
self.port = mumu_start(id=self.index_id)
time.sleep(15)
try:
self.d = u2.connect(f"127.0.0.1:{self.port}")
d_type = 1
break
except Exception as e:
pass
else:
mumu_quit(id=self.index_id)
return True
except:
pass
return False
def koni_wallet(self):
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="Got it"]', timeout=10)
if type1:
time.sleep(3)
ele.click()
time.sleep(3)
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="Connect now"]', timeout=10)
if type1:
time.sleep(3)
ele.click()
time.sleep(3)
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="Connect"]', timeout=10)
if type1:
time.sleep(3)
ele.click()
time.sleep(5)
x_Y = match_image(d=self.d, template_path="images/koni_mate.png", retry_times=50, threshold=0.8)
if x_Y: self.d.click(x_Y[0][0], x_Y[0][1])
time.sleep(5)
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="Retry"]', timeout=20)
if type1:
time.sleep(3)
ele.click()
time.sleep(10)
rect = self.d.xpath('//*[@text="密码"]').bounds
self.d.click(383, 727)
self.d.send_keys('123456123456')
self.d.xpath('//*[@text="登录"]').click()
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="连接"]', timeout=50)
if type1:
time.sleep(3)
ele.click()
time.sleep(5)
self.d.xpath('//*[@text="Continue"]').click()
time.sleep(5)
self.d.xpath('//*[@text="签名"]').click()
time.sleep(5)
self.d.xpath('//*[@text="Confirm"]').click()
def open_project(self, url):
# 打开小程序
self.d.open_url(url)
# 判断需要tg打开链接
for i in range(5):
type1, ele = get_element(d=self.d, type1='xpath', grammar='//*[@text="Start"]', timeout=1)
if type1:
ele.click()
time.sleep(3)
break
try:
type1, ele = get_element(d=self.d, type1='xpath', grammar="//*[contains(@text, 'Telegram')]", timeout=1)
if type1:
ele.click()
time.sleep(3)
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="始终"]', timeout=1)
if type1: ele.click()
except Exception as e:
pass
def action(self):
try:
if self.start_mumu():
self.progress.info(f"当前电话号码:{self.tg_phone.ld_name},启动成功!!!")
else:
self.progress.error(f"当前电话号码:{self.tg_phone.ld_name},启动失败!!!")
raise False
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="Telegram"]', timeout=5) # 等待tg打开
if type1:
ele.click()
else:
time.sleep(1)
self.d.app_install('../data/Telegram.apk')
if self.tg_testing():
self.log_tg()
time.sleep(10)
self.tg_phone.is_logged_in_telegram = 1
self.tg_phone.save()
except Exception as e:
print(e)
finally:
mumu_quit(id=self.index_id)
self.progress.update()
def tonkeeper_add(self):
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="Tonkeeper"]', timeout=10)
if type1:
self.d.app_uninstall('com.ton_keeper')
time.sleep(3)
self.d.app_install('../data/Tonkeeper.apk')
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="导入现有钱包"]', timeout=10)
if type1:
time.sleep(3)
ele.click()
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="使用24个秘密恢复词导入钱包"]', timeout=10)
if type1:
time.sleep(3)
ele.click()
time.sleep(3)
self.d.xpath('//*[@resource-id="com.ton_keeper:id/word_1"]').click()
time.sleep(3)
# 输入助记词
words = self.blum_tx_info.text.replace(" ", "\n")
self.d.send_keys(words)
time.sleep(3)
self.d.xpath('//*[@text="继续"]').click()
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="继续"]', timeout=10)
if type1:
type1, ele1 = get_element(d=self.d, type1="xpath", grammar='//*[@resource-id="com.ton_keeper:id/selected"]',
timeout=5)
if type1:
ele1.click()
time.sleep(3)
ele.click()
time.sleep(3)
for i in range(2):
for i in range(4):
self.d.xpath('//*[@text="1"]').click()
time.sleep(1)
self.d.xpath('//*[@text="之后"]').click()
time.sleep(3)
self.d.xpath('//*[@text="继续"]').click()
time.sleep(10)
res = self.d.xpath('//*[contains(@text, "您的地址")]').get_text().split('')[-1].split()[0]
if res != self.blum_tx_info.address[-4:]:
self.d.xpath('//*[@resource-id="com.ton_keeper:id/settings"]').click()
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="钱包 v4R2"]', timeout=10)
if type1:
time.sleep(3)
ele.click()
time.sleep(3)
for i in range(4):
self.d.xpath('//*[@text="1"]').click()
time.sleep(1)
res = self.d.xpath('//*[contains(@text, "您的地址")]').get_text().split('')[-1]
logger.warning(f"当前模拟器名字:{self.tg_phone.ld_name},助记词后四位:{res}")
if res == self.blum_tx_info.address[-4:]:
return True
else:
return True
return False
def blum_tx(self):
try:
if self.start_mumu():
logger.info(f"当前电话号码:{self.tg_phone.ld_name},启动成功!!!")
else:
logger.error(f"当前电话号码:{self.tg_phone.ld_name},启动失败!!!")
raise False
if self.tonkeeper_add():
logger.info(f"当前模拟器名字:{self.tg_phone.ld_name}tonkeeper绑定成功")
else:
logger.info(f"当前模拟器名字:{self.tg_phone.ld_name}tonkeeper绑定失败")
return
# 按下桌面按键
self.d.press("home")
self.d.xpath('//*[@text="Telegram"]').click()
# 链接打开后的tg检测检测
if self.tg_testing():
print("账号掉了!!!")
mumu_quit(id=self.index_id)
return
self.d.xpath('//*[@content-desc="Search"]').set_text('blum')
self.d.xpath('//*[contains(@text, "Blum, Verified")]').click()
# self.d.xpath('//*[@text="Blum, Verified\n, 12 994 072 users"]').click()
self.d.xpath('//*[@content-desc="Bot menu"]').click()
# //*[@text="Start"]
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="Start"]',
timeout=10) # 等待tg打开
if type1:
time.sleep(3)
ele.click()
# 重新连接钱包 --------------------------------------------------------------------------------------------
x_Y = find_img(d=self.d, template_path="images/blum_wallet.png", retry=500, threshold=0.8)
if x_Y: self.d.click(x_Y[0], x_Y[1])
x_Y = find_img(d=self.d, template_path="images/blum_wallet1.png", retry=10, threshold=0.8)
if x_Y: self.d.click(x_Y[0], x_Y[1])
x_Y = find_img(d=self.d, template_path="images/blum_wallet2.png", retry=10, threshold=0.8)
if x_Y: self.d.click(x_Y[0], x_Y[1])
x_Y = find_img(d=self.d, template_path="images/blum_wallet3.png", retry=10, threshold=0.8)
if x_Y: self.d.click(x_Y[0], x_Y[1])
x_Y = find_img(d=self.d, template_path="images/blum_wallet4.png", retry=10, threshold=0.8)
if x_Y: self.d.click(x_Y[0], x_Y[1])
x_Y = find_img(d=self.d, template_path="images/tonkeeper__.png", retry=100, threshold=0.8)
if x_Y: self.d.click(x_Y[0], x_Y[1])
try:
time.sleep(3)
for i in range(2):
for i in range(4):
self.d.xpath('//*[@text="1"]').click()
time.sleep(1)
except:
pass
x_Y = find_img(d=self.d, template_path="images/tonkeeper_x.png", retry=5, threshold=0.8)
if x_Y: self.d.click(x_Y[0], x_Y[1])
x_Y = find_img(d=self.d, template_path="images/blum_wallet5.png", retry=5, threshold=0.9)
if x_Y:
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="Memepad"]',
timeout=500) # 等待tg打开
if type1:
time.sleep(3)
ele.click()
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="Get Started"]',
timeout=10) # 等待tg打开
if type1: ele.click()
x_Y = find_img(d=self.d, template_path="images/blum_memepad.png", retry=500, threshold=0.8)
if x_Y: self.d.click(195, 1206)
x_Y = find_img(d=self.d, template_path="images/blum_buy.png", retry=10, threshold=0.9)
if x_Y: self.d.click(x_Y[0], x_Y[1])
x_Y = find_img(d=self.d, template_path="images/blum_max.png", retry=10, threshold=0.9)
if x_Y:
self.d.send_keys(str(self.blum_tx_info.balance - 0.5))
for i in range(5):
x_Y = find_img(d=self.d, template_path="images/blum_buy1.png", retry=3, threshold=0.9)
if x_Y: self.d.click(x_Y[0], x_Y[1])
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="滑动确认"]',
timeout=5) # 等待tg打开
if type1:
time.sleep(15)
self.d.swipe(91, 1458, 819, 1456, duration=1)
break
for i in range(4):
self.d.xpath('//*[@text="1"]').click()
time.sleep(1)
time.sleep(30)
self.blum_tx_info.buy_start = 1
self.blum_tx_info.save()
x_Y = find_img(d=self.d, template_path="images/tonkeeper_x.png", retry=5, threshold=0.8)
if x_Y: self.d.click(x_Y[0], x_Y[1])
else:
self.d.click(150, 1154)
time.sleep(5)
# 卖币 ------------------------------------------------------------------------------------------------------
# x_Y = match_image(d=self.d, template_path="images/blum_wallet.png", retry_times=500, threshold=0.8)
# if x_Y: self.d.click(x_Y[0][0], x_Y[0][1])
# time.sleep(15)
# x_Y = match_image(d=self.d, template_path="images/blum_wallet5.png", retry_times=20, threshold=0.8)
# if not x_Y:
# self.d.click(150, 1154)
# else:
# return
for i in range(3):
x_Y = find_img(d=self.d, template_path="images/blum_sell.png", retry=5, threshold=0.8)
if x_Y: self.d.click(x_Y[0], x_Y[1])
x_Y = find_img(d=self.d, template_path="images/blum_max.png", retry=5, threshold=0.8)
if x_Y: self.d.click(x_Y[0], x_Y[1])
x_Y = find_img(d=self.d, template_path="images/blum_sell1.png", retry=5, threshold=0.8)
if x_Y: self.d.click(x_Y[0], x_Y[1])
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="滑动确认"]',
timeout=5) # 等待tg打开
if type1:
time.sleep(15)
self.d.swipe(91, 1458, 819, 1456, duration=1)
break
for i in range(4):
self.d.xpath('//*[@text="1"]').click()
time.sleep(1)
time.sleep(30)
self.blum_tx_info.tx_start = 1
self.blum_tx_info.sell_start = 1
self.blum_tx_info.save()
except Exception as e:
print(e)
finally:
mumu_quit(id=self.index_id)
if __name__ == '__main__':
# pro_info = ProjectType.get_or_none(
# ProjectType.two_server_ip == get_host_ip(),
# )
#
# # 启动类型 0:id,1:名字
# action_type = 1
#
# tg_phone_datas = TelegramAccount().select().where(
# TelegramAccount.server_id == pro_info.server_ip,
# TelegramAccount.is_logged_in_telegram == 1,
# )
#
# # 同时运行
# max_threads = 1
# delay_between_start = 0.5 # 每次启动线程之间的延迟时间(秒)
#
# with ThreadPoolExecutor(max_workers=max_threads) as executor:
#
# while True:
# futures = []
# for i in tg_phone_datas:
#
# try:
# tg = MuTG(tg_phone=i, )
# except Exception as e:
# continue
#
# # 提交线程任务到线程池
# future = executor.submit(tg.blum_tx)
# futures.append(future)
#
# # 线程启动间隔
# time.sleep(delay_between_start)
#
# # 等待所有提交的任务完成
# done = False
# while not done:
# done = True
# for future in futures:
# if not future.done():
# done = False
# time.sleep(60) # 可以根据需要调整休眠时间
# break
#
# time.sleep(600)
# 启动类型 0:id,1:名字
action_type = 1
tg_phone_datas = TgPhoneDevices().select().where(
TgPhoneDevices.is_valid_session == 1,
).limit(400).offset(400)
# 同时运行
max_threads = 15
delay_between_start = 15 # 每次启动线程之间的延迟时间(秒)
with ThreadPoolExecutor(max_workers=max_threads) as executor:
while True:
futures = []
with Haha(
total=len(tg_phone_datas),
desc="mumu模拟器流程",
refresh_interval=50
) as progress:
for i in tg_phone_datas:
one_phone_number, telephone = split_phone_number(phone_number=i.phone)
tg_info, type1 = TeleqramAccountMumu.get_or_create(
server_id=get_host_ip(),
ld_name=i.phone,
one_phone_number=one_phone_number,
telephone=telephone,
)
try:
tg = MuTG(tg_phone=tg_info, progress=progress)
except Exception as e:
continue
# 提交线程任务到线程池
future = executor.submit(tg.action)
futures.append(future)
# 线程启动间隔
time.sleep(delay_between_start)
# 等待所有提交的任务完成
done = False
while not done:
done = True
for future in futures:
if not future.done():
done = False
time.sleep(60) # 可以根据需要调整休眠时间
break
time.sleep(600)

93
process/mumu_tools.py Normal file
View File

@@ -0,0 +1,93 @@
import json
import threading
import subprocess
import time
lock = threading.Lock()
def mumu_rename(id, name):
# 定义命令
command = [result1, "rename", "-v", f'{id}', "-n", f"{name}"]
# 运行命令并捕获输出,使用 utf-8 编码
result = subprocess.run(command, capture_output=True, text=True, encoding='utf-8')
def mumu_quit(id):
# 定义命令
command = [result1, "control", "-v", f'{id}', "shutdown"]
# 运行命令并捕获输出,使用 utf-8 编码
result = subprocess.run(command, capture_output=True, text=True, encoding='utf-8')
def mumu_create():
# 定义命令
command = [result1, "create", ]
# 运行命令并捕获输出,使用 utf-8 编码
result = subprocess.run(command, capture_output=True, text=True, encoding='utf-8')
# 将 JSON 字符串解析为字典
data = json.loads(result.stdout)
# 将 keys() 返回的 dict_keys 对象转换为列表
keys_list = list(data.keys())
# 获取第一个键
first_key = keys_list[0]
return first_key
def mumu_start(id):
# 定义命令
command = [result1, "control", "-v", f'{id}', "launch"]
# 运行命令并捕获输出,使用 utf-8 编码
result = subprocess.run(command, capture_output=True, text=True, encoding='utf-8')
with lock:
for i1 in range(250):
for i in mumu_get_list_all():
if i["index"] == str(id):
if i.get("adb_port"):
return i["adb_port"]
time.sleep(1)
return False
def mumu_get_list_all():
# 定义命令
command = [result1, "info", "-v", "all"]
# 运行命令并捕获输出,使用 utf-8 编码
result = subprocess.run(command, capture_output=True, text=True, encoding='utf-8')
# 检查命令是否成功执行
if result.returncode != 0:
return None
# 解析 JSON 输出
try:
info = json.loads(result.stdout)
infos = []
for i in info:
infos.append(info[i])
return infos # 返回一个包含嵌套字典的列表
except json.JSONDecodeError as e:
return None
result1 = r"MuMuManager.exe"
# if __name__ == '__main__':
# mumu_quit(id=1)
# for i in mumu_get_list_all():
# print(i)
# mumu_create()

View File

@@ -0,0 +1,17 @@
from models.tg_models import TelegramAccountMumu
from models.tg_phone_devices import TgPhoneDevices
if __name__ == '__main__':
tg_mumu_infos = TelegramAccountMumu.select().where(
TelegramAccountMumu.server_id == "192.168.50.77"
)
for tg_mumu_info in tg_mumu_infos:
tg_phone_info = TgPhoneDevices.get_or_none(
# TgPhoneDevices.server_ip == "192.168.50.58",
TgPhoneDevices.phone == tg_mumu_info.ld_name
)
print(f"192.168.50.220|{tg_phone_info.port}||||{tg_mumu_info.index_id}|")

10
process/text.py Normal file
View File

@@ -0,0 +1,10 @@
from pathlib import Path
# 获取当前脚本所在的文件夹路径
current_folder_path = Path(__file__).parent.resolve()
# 上一个路径
grandparent_folder_path = current_folder_path.parent
# 获取当前脚本所在文件夹下 data 文件夹的路径
data_folder_path = grandparent_folder_path / 'data'
print(data_folder_path)

2109
process/tg_process.py Normal file

File diff suppressed because it is too large Load Diff

509
process/tools.py Normal file
View File

@@ -0,0 +1,509 @@
import json
import os
import threading
import cv2
import time
import socket
import subprocess
import numpy as np
import requests
from PIL import Image
from faker import Faker
lock = threading.Lock()
def get_device_ids():
try:
result = subprocess.run(['adb', 'devices'], capture_output=True, text=True, check=True)
output = result.stdout
lines = output.splitlines()
devices = []
for line in lines[1:]:
if line.strip():
device_id = line.split()[0]
devices.append(device_id)
return devices
except subprocess.CalledProcessError as e:
print(f"命令执行失败: {e}")
return []
def get_nox_list():
command = r'powershell -Command "& \"C:\Program Files (x86)\Nox\bin\NoxConsole.exe\" list"'
result = subprocess.run(command, shell=True, capture_output=True, text=True)
output = result.stdout.strip()
lines = output.split('\n')
output_dict = {}
for line in lines:
parts = line.split(',')
if len(parts) >= 3:
key = parts[0].strip()
value = {
'NoxID': parts[1].strip(),
'名称': parts[2].strip()
}
output_dict[key] = value
return output_dict
def create_simulator(n):
command = [
r'C:\Program Files (x86)\Nox\bin\NoxConsole.exe',
'add',
f'-name:{n}',
'-systemtype:12'
]
subprocess.run(command, capture_output=True, text=True)
def updata_resolving_power(n):
command = [
r'C:\Program Files (x86)\Nox\bin\NoxConsole.exe',
'modify',
f'-name:{n}',
'-resolution:540,960,240'
]
subprocess.run(command, capture_output=True, text=True)
def start_simulator(n):
command = [
r'D:\Program Files\Nox\bin\NoxConsole.exe',
'launch',
f'-index:{n}',
]
subprocess.run(command, capture_output=True, text=True)
def clone_simulator(n):
command = [
r'D:\Program Files\Nox\bin\NoxConsole.exe',
'quit',
f'-index:{n}',
]
subprocess.run(command, capture_output=True, text=True)
def get_element(d, type1, grammar, timeout=5):
if type1 == "xpath":
end_time = time.time() + timeout
element = ""
while time.time() < end_time:
try:
element = d.xpath(grammar)
if element.exists:
return True, element
except Exception as e:
pass
time.sleep(0.1)
return False, element
elif type1 == "text":
ele = d(text=grammar)
return ele.exists(timeout=timeout), ele
def start_nox(index=None):
command = ["NoxConsole.exe", "launch"]
if index is not None:
command.append(f"-index:{index}")
result = subprocess.run(command, capture_output=True, text=True)
def exit_simulator(index=None):
command = ["NoxConsole.exe", "quit"]
if index is not None:
command.append(f"-index:{index}")
result = subprocess.run(command, capture_output=True, text=True)
def get_host_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ip = None
try:
s.connect(('8.8.8.8', 80))
ip = s.getsockname()[0]
finally:
s.close()
return ip
def preprocess_image(image):
alpha = 1.2
beta = 30
adjusted = cv2.convertScaleAbs(image, alpha=alpha, beta=beta)
return adjusted
def match_image(d, template_path: str, threshold: float = 0.8, retry_times: int = 3, wait_time: int = 1):
for attempt in range(retry_times):
screenshot_image = d.screenshot(format="opencv")
screenshot_image = preprocess_image(screenshot_image)
template_image = cv2.imread(template_path, cv2.IMREAD_COLOR)
if template_image is None:
return None
template_image = preprocess_image(template_image)
result = cv2.matchTemplate(screenshot_image, template_image, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)
if max_val < threshold:
if attempt < retry_times - 1:
time.sleep(wait_time)
else:
return None
else:
h, w = template_image.shape[:2]
center_x = int(max_loc[0] + w / 2)
center_y = int(max_loc[1] + h / 2)
return [(center_x, center_y)]
return None
def screenshot_and_crop(d, crop_area, save_path='wallet_connect.png'):
screenshot = d.screenshot()
cropped_img = screenshot.crop(crop_area)
cropped_img.save(save_path)
print(f'Cropped screenshot saved to {save_path}')
def generate_fake_info():
fake = Faker('en_US')
info = {}
full_name = fake.name()
first_name, last_name = full_name.split(' ', 1)
info['first_name'] = first_name
info['last_name'] = last_name
birthdate = fake.date_of_birth(minimum_age=18, maximum_age=80)
info['birth_year'] = birthdate.year
info['birth_month'] = birthdate.month
info['birth_day'] = birthdate.day
return info
def get_ldplayer_list():
command = [r"ldconsole", "list2"]
result = subprocess.run(command, capture_output=True, text=True, shell=True)
output = result.stdout.strip()
lines = output.split('\n')
ldplayer_list = []
for line in lines:
parts = line.split(',')
if len(parts) == 10:
ldplayer_info = {
"ID": int(parts[0]),
"Name": parts[1],
"Param1": int(parts[2]),
"Param2": int(parts[3]),
"Param3": int(parts[4]),
"Param4": int(parts[5]),
"Param5": int(parts[6]),
"Width": int(parts[7]),
"Height": int(parts[8]),
"DPI": int(parts[9]),
}
ldplayer_list.append(ldplayer_info)
return ldplayer_list
def swipe_up(d, start_y1, end_y1, duration=0.1):
width, height = d.window_size()
start_x = width / 2
start_y = height * start_y1
end_x = width / 2
end_y = height * end_y1
d.swipe(start_x, start_y, end_x, end_y, duration)
def close_ldplayer(simulator_id):
command = f"dnconsole quit --index {simulator_id}"
result = subprocess.run(command, capture_output=True, text=True, shell=True)
def start_ldplayer(simulator_id):
command = f"dnconsole launch --index {simulator_id}"
with lock:
result = subprocess.run(command, capture_output=True, text=True, shell=True)
ld_start = 0
for i in range(50):
for i in get_ldplayer_list():
if i['ID'] == simulator_id and i["Param3"] == 1:
ld_start = 1
break
if ld_start == 1:
break
time.sleep(1)
return ld_start
def create_ldplayer(name):
command = f"dnconsole add --name {name}"
with lock:
result = subprocess.run(command, capture_output=True, text=True, shell=True)
def rename_ldplayer(index, name):
command = f"dnconsole rename --index {index} --title {name}"
result = subprocess.run(command, capture_output=True, text=True, shell=True)
def mumu_get_list_all():
command = ["MuMuManager.exe", "info", "-v", "all"]
result = subprocess.run(command, capture_output=True, text=True, encoding='utf-8')
if result.returncode != 0:
print(f"Command failed with error: {result.stderr}")
return None
try:
info = json.loads(result.stdout)
return [info]
except json.JSONDecodeError as e:
print(f"Failed to parse JSON: {e}")
return None
def mumu_create(id):
command = ["MuMuManager.exe", "create", "-v", f'{id}']
result = subprocess.run(command, capture_output=True, text=True, encoding='utf-8')
def mumu_start(id):
command = ["MuMuManager.exe", "control", "-v", f'{id}', "launch"]
result = subprocess.run(command, capture_output=True, text=True, encoding='utf-8')
def mumu_quit(id):
command = ["MuMuManager.exe", "control", "-v", f'{id}', "shutdown"]
result = subprocess.run(command, capture_output=True, text=True, encoding='utf-8')
def mumu_rename(id, name):
command = ["MuMuManager.exe", "rename", "-v", f'{id}', "-n", f"{name}"]
result = subprocess.run(command, capture_output=True, text=True, encoding='utf-8')
def get_code(phone, device_mode=None):
url = f"http://192.168.50.175:9000/api/check_phone?phone={phone}"
res = requests.get(url)
return res.json()["data"]["verification_code"]
country_code_map = {
"1": "US",
"44": "GB",
"27": "ZA",
"20": "ZA",
"234": "NG",
"86": "CN",
"63": "PH",
"62": "PH",
"972": "PH",
}
def split_phone_number(phone_number):
if phone_number.startswith('+'):
phone_number = phone_number[1:]
for prefix in country_code_map:
if phone_number.startswith(prefix):
country_code = prefix
national_number = phone_number[len(prefix):]
return country_code, national_number
return None, None
def _read_and_scale_template(template_path: str, scale_ratio: float) -> np.ndarray:
template = cv2.imdecode(np.fromfile(template_path, dtype=np.uint8), cv2.IMREAD_COLOR)
if template is None:
raise FileNotFoundError(f"模板图片不存在: {template_path}")
if scale_ratio != 1.0:
h, w = template.shape[:2]
template = cv2.resize(
template,
(int(w * scale_ratio), int(h * scale_ratio)),
interpolation=cv2.INTER_AREA
)
return template
def find_img(d, template_path: str, threshold: float = 0.8, retry: int = 1, timeout=5, scale_ratio: float = 1.0):
template = _read_and_scale_template(template_path, scale_ratio)
for _ in range(retry):
try:
screenshot = d.screenshot(format='opencv')
match_result = cv2.matchTemplate(screenshot, template, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(match_result)
if max_val >= threshold:
h, w = template.shape[:2]
x = max_loc[0] + w // 2
y = max_loc[1] + h // 2
return (x, y)
except Exception as e:
print(f"图像识别异常: {str(e)}")
time.sleep(timeout)
return False
def adb_find_img(d, template_path: str, threshold: float = 0.8, retry: int = 1, timeout=5, scale_ratio: float = 1.0,
error_type=0):
template = _read_and_scale_template(template_path, scale_ratio)
remote_path = '/sdcard/screenshot.png'
for _ in range(retry):
try:
d.shell(['screencap', '-p', remote_path])
d.pull(remote_path, 'temp_screenshot.png')
screenshot_pil = Image.open('temp_screenshot.png')
screenshot = np.array(screenshot_pil)
screenshot = cv2.cvtColor(screenshot, cv2.COLOR_RGB2BGR)
match_result = cv2.matchTemplate(screenshot, template, cv2.TM_CCOEFF_NORMED)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(match_result)
if max_val >= threshold:
h, w = template.shape[:2]
x = max_loc[0] + w // 2
y = max_loc[1] + h // 2
if os.path.exists('temp_screenshot.png'):
os.remove('temp_screenshot.png')
return (x, y)
except Exception as e:
print(f"图像识别异常: {str(e)}")
if error_type:
raise ""
if os.path.exists('temp_screenshot.png'):
os.remove('temp_screenshot.png')
time.sleep(timeout)
return False
def u2_adb_screenshot_and_crop(d, crop_area, save_path='wallet_connect.png'):
remote_path = '/sdcard/screenshot.png'
d.shell(['screencap', '-p', remote_path])
d.pull(remote_path, 'temp_screenshot.png')
try:
screenshot = Image.open('temp_screenshot.png')
cropped_img = screenshot.crop(crop_area)
cropped_img.save(save_path)
print(f'Cropped screenshot saved to {save_path}')
except Exception as e:
print(f"裁剪图片时出错: {e}")
finally:
if os.path.exists('temp_screenshot.png'):
os.remove('temp_screenshot.png')
def get_page_user(phone, url1):
url = "http://192.168.50.97:9999/get_user_data"
json_data = {
"phone": phone,
"url": url1
}
res = requests.post(url, json=json_data)
return res.json()
def send_command_to_server(server_host, server_port, command):
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client_socket.connect((server_host, server_port))
client_socket.sendall(command.encode('utf-8'))
if command.lower() == 'exit':
return None
data_length = int(client_socket.recv(10).decode('utf-8'))
received_data = b''
while len(received_data) < data_length:
chunk = client_socket.recv(data_length - len(received_data))
if not chunk:
break
received_data += chunk
output = received_data.decode('utf-8')
return output
except Exception as e:
print(f"发生错误: {e}")
return None
finally:
client_socket.close()
# 打包拉取
def pull_simulator_backup(
d, # U2对象
phone, # 电话号码
package_name="org.telegram.messenger.web", # 包名
local_backup=r"D:\backups"
):
# 判断并创建目录
if not os.path.exists(local_backup):
try:
os.makedirs(local_backup)
print(f"目录已创建:{local_backup}")
except Exception as e:
print(f"创建目录失败:{e}")
else:
print(f"目录已存在:{local_backup}")
# 打包
extract_cmd = (
"su -c '"
"cd /data/data/ && "
f"tar -cf /data/local/tmp/{phone}.tar {package_name}"
"'"
)
d.shell(extract_cmd, )
# 拉取
d.pull(f"/data/local/tmp/{phone}.tar", f"{local_backup}/{phone}.tar")
# 删除临时文件
d.shell(f"su -c 'rm /data/local/tmp/{phone}.tar'")
# 传入解压移动
def deploy_and_extract_to_android(
d, # U2对象
phone, # 电话号码
package_name="org.telegram.messenger.web", # 包名
local_backup=r"D:\backups"
):
# # 获取包名
# package_name = None
# # 通过adb shell命令获取
# all_packages = d.shell('pm list packages').output
# # 格式化输出(去掉"package:"前缀)
# clean_packages = [pkg.split(':')[1] for pkg in all_packages.splitlines()]
# for i in clean_packages:
# if "telegram" in i:
# package_name = i
# break
# 将本地备份文件上传到模拟器
d.push(f"{local_backup}/{phone}.tar", "/data/local/tmp/telegram_backup.tar")
# 解压
extract_cmd = (
"su -c '"
"mkdir -p /data/local/tmp && "
"tar -xf /data/local/tmp/telegram_backup.tar -C /data/local/tmp"
"'"
)
d.shell(extract_cmd, )
# 获取解压后的目录列表
path = None
list_cmd = "su -c 'ls -d /data/local/tmp/*/'"
result = d.shell(list_cmd)
dirs = result.output.strip().split('\n')
for i in dirs:
if "telegram" in i:
path = i
# 复制文件
copy_cmd = f"su -c 'cp -r {path}* /data/data/{package_name}/'"
d.shell(copy_cmd)
# # 确保目标目录权限正确
# chmod_cmd = "su -c 'chmod -R 755 /data/data/org.telegram.messenger'"
# d.shell(chmod_cmd)
# 可选:删除临时文件
cleanup_cmd = f"su -c 'rm -rf {path.rstrip('/')}'"
d.shell(cleanup_cmd)
cleanup_cmd = f"su -c 'rm -rf /data/data/{package_name}/app_webview'"
d.shell(cleanup_cmd)

500
process/代理配置.txt Normal file
View File

@@ -0,0 +1,500 @@
192.168.50.220|27301||||515|
192.168.50.220|27302||||516|
192.168.50.220|27303||||517|
192.168.50.220|27304||||518|
192.168.50.220|27305||||519|
192.168.50.220|27306||||520|
192.168.50.220|27307||||521|
192.168.50.220|27308||||522|
192.168.50.220|27309||||523|
192.168.50.220|27310||||524|
192.168.50.220|27311||||525|
192.168.50.220|27312||||526|
192.168.50.220|27313||||527|
192.168.50.220|27314||||528|
192.168.50.220|27315||||529|
192.168.50.220|27316||||530|
192.168.50.220|27317||||531|
192.168.50.220|27318||||532|
192.168.50.220|27319||||533|
192.168.50.220|27320||||534|
192.168.50.220|27321||||535|
192.168.50.220|27322||||536|
192.168.50.220|27323||||537|
192.168.50.220|27324||||538|
192.168.50.220|27325||||539|
192.168.50.220|27326||||540|
192.168.50.220|27327||||541|
192.168.50.220|27328||||542|
192.168.50.220|27329||||543|
192.168.50.220|27330||||544|
192.168.50.220|27331||||545|
192.168.50.220|27332||||546|
192.168.50.220|27333||||547|
192.168.50.220|27334||||548|
192.168.50.220|27335||||549|
192.168.50.220|27336||||550|
192.168.50.220|27337||||551|
192.168.50.220|27338||||552|
192.168.50.220|27339||||553|
192.168.50.220|27340||||554|
192.168.50.220|27341||||555|
192.168.50.220|27342||||556|
192.168.50.220|27343||||557|
192.168.50.220|27344||||558|
192.168.50.220|27345||||559|
192.168.50.220|27346||||560|
192.168.50.220|27347||||561|
192.168.50.220|27348||||562|
192.168.50.220|27349||||563|
192.168.50.220|27350||||564|
192.168.50.220|27351||||565|
192.168.50.220|27352||||566|
192.168.50.220|27353||||567|
192.168.50.220|27354||||568|
192.168.50.220|27355||||569|
192.168.50.220|27356||||570|
192.168.50.220|27357||||571|
192.168.50.220|27358||||572|
192.168.50.220|27359||||573|
192.168.50.220|27360||||574|
192.168.50.220|27361||||575|
192.168.50.220|27362||||576|
192.168.50.220|27363||||577|
192.168.50.220|27364||||578|
192.168.50.220|27365||||579|
192.168.50.220|27366||||580|
192.168.50.220|27367||||581|
192.168.50.220|27368||||582|
192.168.50.220|27369||||583|
192.168.50.220|27370||||584|
192.168.50.220|27371||||585|
192.168.50.220|27372||||586|
192.168.50.220|27373||||587|
192.168.50.220|27374||||588|
192.168.50.220|27375||||589|
192.168.50.220|27376||||590|
192.168.50.220|27377||||591|
192.168.50.220|27378||||592|
192.168.50.220|27379||||593|
192.168.50.220|27380||||594|
192.168.50.220|27381||||595|
192.168.50.220|27382||||596|
192.168.50.220|27383||||597|
192.168.50.220|27384||||598|
192.168.50.220|27385||||599|
192.168.50.220|27386||||600|
192.168.50.220|27387||||601|
192.168.50.220|27388||||602|
192.168.50.220|27389||||603|
192.168.50.220|27390||||604|
192.168.50.220|27391||||605|
192.168.50.220|27392||||606|
192.168.50.220|27393||||607|
192.168.50.220|27394||||608|
192.168.50.220|27395||||609|
192.168.50.220|27396||||610|
192.168.50.220|27397||||611|
192.168.50.220|27398||||612|
192.168.50.220|27399||||613|
192.168.50.220|27400||||614|
192.168.50.220|27401||||615|
192.168.50.220|27402||||616|
192.168.50.220|27403||||617|
192.168.50.220|27404||||618|
192.168.50.220|27405||||619|
192.168.50.220|27406||||620|
192.168.50.220|27407||||621|
192.168.50.220|27408||||622|
192.168.50.220|27409||||623|
192.168.50.220|27410||||624|
192.168.50.220|27411||||625|
192.168.50.220|27412||||626|
192.168.50.220|27413||||627|
192.168.50.220|27414||||628|
192.168.50.220|27415||||629|
192.168.50.220|27416||||630|
192.168.50.220|27417||||631|
192.168.50.220|27418||||632|
192.168.50.220|27419||||633|
192.168.50.220|27420||||634|
192.168.50.220|27421||||635|
192.168.50.220|27422||||636|
192.168.50.220|27423||||637|
192.168.50.220|27424||||638|
192.168.50.220|27425||||639|
192.168.50.220|27426||||640|
192.168.50.220|27427||||641|
192.168.50.220|27428||||642|
192.168.50.220|27429||||643|
192.168.50.220|27430||||644|
192.168.50.220|27431||||645|
192.168.50.220|27432||||646|
192.168.50.220|27433||||647|
192.168.50.220|27434||||648|
192.168.50.220|27435||||649|
192.168.50.220|27436||||650|
192.168.50.220|27437||||651|
192.168.50.220|27438||||652|
192.168.50.220|27439||||653|
192.168.50.220|27440||||654|
192.168.50.220|27441||||655|
192.168.50.220|27442||||656|
192.168.50.220|27443||||657|
192.168.50.220|27444||||658|
192.168.50.220|27445||||659|
192.168.50.220|27446||||660|
192.168.50.220|27447||||661|
192.168.50.220|27448||||662|
192.168.50.220|27449||||663|
192.168.50.220|27450||||664|
192.168.50.220|27451||||665|
192.168.50.220|27452||||666|
192.168.50.220|27453||||667|
192.168.50.220|27454||||668|
192.168.50.220|27455||||669|
192.168.50.220|27456||||670|
192.168.50.220|27457||||671|
192.168.50.220|27458||||672|
192.168.50.220|27459||||673|
192.168.50.220|27460||||674|
192.168.50.220|27461||||675|
192.168.50.220|27462||||676|
192.168.50.220|27463||||677|
192.168.50.220|27464||||678|
192.168.50.220|27465||||679|
192.168.50.220|27466||||680|
192.168.50.220|27467||||681|
192.168.50.220|27468||||682|
192.168.50.220|27469||||683|
192.168.50.220|27470||||684|
192.168.50.220|27471||||685|
192.168.50.220|27472||||686|
192.168.50.220|27473||||687|
192.168.50.220|27474||||688|
192.168.50.220|27475||||689|
192.168.50.220|27476||||690|
192.168.50.220|27477||||691|
192.168.50.220|27478||||692|
192.168.50.220|27479||||693|
192.168.50.220|27480||||694|
192.168.50.220|27481||||695|
192.168.50.220|27482||||696|
192.168.50.220|27483||||697|
192.168.50.220|27484||||698|
192.168.50.220|27485||||699|
192.168.50.220|27486||||700|
192.168.50.220|27487||||701|
192.168.50.220|27488||||702|
192.168.50.220|27489||||703|
192.168.50.220|27490||||704|
192.168.50.220|27491||||705|
192.168.50.220|27492||||706|
192.168.50.220|27493||||707|
192.168.50.220|27494||||708|
192.168.50.220|27495||||709|
192.168.50.220|27496||||710|
192.168.50.220|27497||||711|
192.168.50.220|27498||||712|
192.168.50.220|27499||||713|
192.168.50.220|27500||||714|
192.168.50.220|27501||||715|
192.168.50.220|27502||||716|
192.168.50.220|27503||||717|
192.168.50.220|27504||||718|
192.168.50.220|27505||||719|
192.168.50.220|27506||||720|
192.168.50.220|27507||||721|
192.168.50.220|27508||||722|
192.168.50.220|27509||||723|
192.168.50.220|27510||||724|
192.168.50.220|27511||||725|
192.168.50.220|27512||||726|
192.168.50.220|27513||||727|
192.168.50.220|27514||||728|
192.168.50.220|27515||||729|
192.168.50.220|27516||||730|
192.168.50.220|27517||||731|
192.168.50.220|27518||||732|
192.168.50.220|27519||||733|
192.168.50.220|27520||||734|
192.168.50.220|27521||||735|
192.168.50.220|27522||||736|
192.168.50.220|27523||||737|
192.168.50.220|27524||||738|
192.168.50.220|27525||||739|
192.168.50.220|27526||||740|
192.168.50.220|27527||||741|
192.168.50.220|27528||||742|
192.168.50.220|27529||||743|
192.168.50.220|27530||||744|
192.168.50.220|27531||||745|
192.168.50.220|27532||||746|
192.168.50.220|27533||||747|
192.168.50.220|27534||||748|
192.168.50.220|27535||||749|
192.168.50.220|27536||||750|
192.168.50.220|27537||||751|
192.168.50.220|27538||||752|
192.168.50.220|27539||||753|
192.168.50.220|27540||||754|
192.168.50.220|27541||||755|
192.168.50.220|27542||||756|
192.168.50.220|27543||||757|
192.168.50.220|27544||||758|
192.168.50.220|27545||||759|
192.168.50.220|27546||||760|
192.168.50.220|27547||||761|
192.168.50.220|27548||||762|
192.168.50.220|27549||||763|
192.168.50.220|27550||||764|
192.168.50.220|27551||||765|
192.168.50.220|27552||||766|
192.168.50.220|27553||||767|
192.168.50.220|27554||||768|
192.168.50.220|27555||||769|
192.168.50.220|27556||||770|
192.168.50.220|27557||||771|
192.168.50.220|27558||||772|
192.168.50.220|27559||||773|
192.168.50.220|27560||||774|
192.168.50.220|27561||||775|
192.168.50.220|27562||||776|
192.168.50.220|27563||||777|
192.168.50.220|27564||||778|
192.168.50.220|27565||||779|
192.168.50.220|27566||||780|
192.168.50.220|27567||||781|
192.168.50.220|27568||||782|
192.168.50.220|27569||||783|
192.168.50.220|27570||||784|
192.168.50.220|27571||||785|
192.168.50.220|27572||||786|
192.168.50.220|27573||||787|
192.168.50.220|27574||||788|
192.168.50.220|27575||||789|
192.168.50.220|27576||||790|
192.168.50.220|27577||||791|
192.168.50.220|27578||||792|
192.168.50.220|27579||||793|
192.168.50.220|27580||||794|
192.168.50.220|27581||||795|
192.168.50.220|27582||||796|
192.168.50.220|27583||||797|
192.168.50.220|27584||||798|
192.168.50.220|27585||||799|
192.168.50.220|27586||||800|
192.168.50.220|27587||||801|
192.168.50.220|27588||||802|
192.168.50.220|27589||||803|
192.168.50.220|27590||||804|
192.168.50.220|27591||||805|
192.168.50.220|27592||||806|
192.168.50.220|27593||||807|
192.168.50.220|27594||||808|
192.168.50.220|27595||||809|
192.168.50.220|27596||||810|
192.168.50.220|27597||||811|
192.168.50.220|27598||||812|
192.168.50.220|27599||||813|
192.168.50.220|27600||||814|
192.168.50.220|27601||||815|
192.168.50.220|27602||||816|
192.168.50.220|27603||||817|
192.168.50.220|27604||||818|
192.168.50.220|27605||||819|
192.168.50.220|27606||||820|
192.168.50.220|27607||||821|
192.168.50.220|27608||||822|
192.168.50.220|27609||||823|
192.168.50.220|27610||||824|
192.168.50.220|27611||||825|
192.168.50.220|27612||||826|
192.168.50.220|27613||||827|
192.168.50.220|27614||||828|
192.168.50.220|27615||||829|
192.168.50.220|27616||||830|
192.168.50.220|27617||||831|
192.168.50.220|27618||||832|
192.168.50.220|27619||||833|
192.168.50.220|27620||||834|
192.168.50.220|27621||||835|
192.168.50.220|27622||||836|
192.168.50.220|27623||||837|
192.168.50.220|27624||||838|
192.168.50.220|27625||||839|
192.168.50.220|27626||||840|
192.168.50.220|27627||||841|
192.168.50.220|27628||||842|
192.168.50.220|27629||||843|
192.168.50.220|27630||||844|
192.168.50.220|27631||||845|
192.168.50.220|27632||||846|
192.168.50.220|27633||||847|
192.168.50.220|27634||||848|
192.168.50.220|27635||||849|
192.168.50.220|27636||||850|
192.168.50.220|27637||||851|
192.168.50.220|27638||||852|
192.168.50.220|27639||||853|
192.168.50.220|27640||||854|
192.168.50.220|27641||||855|
192.168.50.220|27642||||856|
192.168.50.220|27643||||857|
192.168.50.220|27644||||858|
192.168.50.220|27645||||859|
192.168.50.220|27646||||860|
192.168.50.220|27647||||861|
192.168.50.220|27648||||862|
192.168.50.220|27649||||863|
192.168.50.220|27650||||864|
192.168.50.220|27651||||865|
192.168.50.220|27652||||866|
192.168.50.220|27653||||867|
192.168.50.220|27654||||868|
192.168.50.220|27655||||869|
192.168.50.220|27656||||870|
192.168.50.220|27657||||871|
192.168.50.220|27658||||872|
192.168.50.220|27659||||873|
192.168.50.220|27660||||874|
192.168.50.220|27661||||875|
192.168.50.220|27662||||876|
192.168.50.220|27663||||877|
192.168.50.220|27664||||878|
192.168.50.220|27665||||879|
192.168.50.220|27666||||880|
192.168.50.220|27667||||881|
192.168.50.220|27668||||882|
192.168.50.220|27669||||883|
192.168.50.220|27670||||884|
192.168.50.220|27671||||885|
192.168.50.220|27672||||886|
192.168.50.220|27673||||887|
192.168.50.220|27674||||888|
192.168.50.220|27675||||889|
192.168.50.220|27676||||890|
192.168.50.220|27677||||891|
192.168.50.220|27678||||892|
192.168.50.220|27679||||893|
192.168.50.220|27680||||894|
192.168.50.220|27681||||895|
192.168.50.220|27682||||896|
192.168.50.220|27683||||897|
192.168.50.220|27684||||898|
192.168.50.220|27685||||899|
192.168.50.220|27686||||900|
192.168.50.220|27687||||901|
192.168.50.220|27688||||902|
192.168.50.220|27689||||903|
192.168.50.220|27690||||904|
192.168.50.220|27691||||905|
192.168.50.220|27692||||906|
192.168.50.220|27693||||907|
192.168.50.220|27694||||908|
192.168.50.220|27695||||909|
192.168.50.220|27696||||910|
192.168.50.220|27697||||911|
192.168.50.220|27698||||912|
192.168.50.220|27699||||913|
192.168.50.220|27700||||914|
192.168.50.220|27701||||915|
192.168.50.220|27702||||916|
192.168.50.220|27703||||917|
192.168.50.220|27704||||918|
192.168.50.220|27705||||919|
192.168.50.220|27706||||920|
192.168.50.220|27707||||921|
192.168.50.220|27708||||922|
192.168.50.220|27709||||923|
192.168.50.220|27710||||924|
192.168.50.220|27711||||925|
192.168.50.220|27712||||926|
192.168.50.220|27713||||927|
192.168.50.220|27714||||928|
192.168.50.220|27715||||929|
192.168.50.220|27716||||930|
192.168.50.220|27717||||931|
192.168.50.220|27718||||932|
192.168.50.220|27719||||933|
192.168.50.220|27720||||934|
192.168.50.220|27721||||935|
192.168.50.220|27722||||936|
192.168.50.220|27723||||937|
192.168.50.220|27724||||938|
192.168.50.220|27725||||939|
192.168.50.220|27726||||940|
192.168.50.220|27727||||941|
192.168.50.220|27728||||942|
192.168.50.220|27729||||943|
192.168.50.220|27730||||944|
192.168.50.220|27731||||945|
192.168.50.220|27732||||946|
192.168.50.220|27733||||947|
192.168.50.220|27734||||948|
192.168.50.220|27735||||949|
192.168.50.220|27736||||950|
192.168.50.220|27737||||951|
192.168.50.220|27738||||952|
192.168.50.220|27739||||953|
192.168.50.220|27740||||954|
192.168.50.220|27741||||955|
192.168.50.220|27742||||956|
192.168.50.220|27743||||957|
192.168.50.220|27744||||958|
192.168.50.220|27745||||959|
192.168.50.220|27746||||960|
192.168.50.220|27747||||961|
192.168.50.220|27748||||962|
192.168.50.220|27749||||963|
192.168.50.220|27750||||964|
192.168.50.220|27751||||965|
192.168.50.220|27752||||966|
192.168.50.220|27753||||967|
192.168.50.220|27754||||968|
192.168.50.220|27755||||969|
192.168.50.220|27756||||970|
192.168.50.220|27757||||971|
192.168.50.220|27758||||972|
192.168.50.220|27759||||973|
192.168.50.220|27760||||974|
192.168.50.220|27761||||975|
192.168.50.220|27762||||976|
192.168.50.220|27763||||977|
192.168.50.220|27764||||978|
192.168.50.220|27765||||979|
192.168.50.220|27766||||980|
192.168.50.220|27767||||981|
192.168.50.220|27768||||982|
192.168.50.220|27769||||983|
192.168.50.220|27770||||984|
192.168.50.220|27771||||985|
192.168.50.220|27772||||986|
192.168.50.220|27773||||987|
192.168.50.220|27774||||988|
192.168.50.220|27775||||989|
192.168.50.220|27776||||990|
192.168.50.220|27777||||991|
192.168.50.220|27778||||992|
192.168.50.220|27779||||993|
192.168.50.220|27780||||994|
192.168.50.220|27781||||995|
192.168.50.220|27782||||996|
192.168.50.220|27783||||997|
192.168.50.220|27784||||998|
192.168.50.220|27785||||999|
192.168.50.220|27786||||1000|
192.168.50.220|27787||||1001|
192.168.50.220|27788||||1002|
192.168.50.220|27789||||1003|
192.168.50.220|27790||||1004|
192.168.50.220|27791||||1005|
192.168.50.220|27792||||1006|
192.168.50.220|27793||||1007|
192.168.50.220|27794||||1008|
192.168.50.220|27795||||1009|
192.168.50.220|27796||||1010|
192.168.50.220|27797||||1011|
192.168.50.220|27798||||1012|
192.168.50.220|27799||||1013|
192.168.50.220|27800||||1014|

10
process/修改ip改变.py Normal file
View File

@@ -0,0 +1,10 @@
from models.tg_models import TelegramAccount
if __name__ == '__main__':
tg_phones = TelegramAccount.select().where(
TelegramAccount.server_id == "192.168.50.100"
)
for i in tg_phones:
i.server_id = "192.168.50.51"
i.save()

389
process/单机版ld.py Normal file
View File

@@ -0,0 +1,389 @@
import json
import time
from concurrent.futures import ThreadPoolExecutor
from process.tools import get_ldplayer_list, close_ldplayer, start_ldplayer, get_element, get_host_ip, \
split_phone_number, rename_ldplayer, pull_simulator_backup
from loguru import logger
import uiautomator2 as u2
from models.tg_models import TelegramAccount
import socket
import os
import sys
import struct
def send_file(file_path, server_ip='localhost', port=5001):
"""
发送任意类型文件到服务端
:param file_path: 本地文件路径(支持任意后缀名)
:param server_ip: 服务端IP地址默认localhost
:param port: 服务端端口默认5555
:return: 传输成功返回True失败返回False
"""
# 检查文件是否存在
if not os.path.exists(file_path):
print(f"[Error] File not found: {file_path}")
return False
file_name = os.path.basename(file_path)
client_sock = None
try:
# 创建Socket连接
client_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_sock.settimeout(10) # 设置超时时间
client_sock.connect((server_ip, port))
# 发送文件名(支持任意后缀)
file_name_encoded = file_name.encode()
# 先发送文件名长度4字节整数再发送文件名
client_sock.sendall(struct.pack('I', len(file_name_encoded)))
client_sock.sendall(file_name_encoded)
# 分块发送文件内容
print(f"[Transfer] Sending: {file_name} -> {server_ip}")
sent_bytes = 0
with open(file_path, 'rb') as f:
while chunk := f.read(4096): # 4KB分块传输
client_sock.sendall(chunk)
sent_bytes += len(chunk)
print(f"[Success] Sent {sent_bytes} bytes")
return True
except socket.error as e:
print(f"[Error] Network failure: {str(e)}")
return False
except Exception as e:
print(f"[Error] Unexpected error: {str(e)}")
return False
finally:
if client_sock:
client_sock.close()
def decorator(func):
def wrapper(self, *args, **kwargs):
result = None
# 这里可以在函数执行前增加逻辑
# 启动模拟器
if not self.start_d():
return
try:
result = func(self, *args, **kwargs)
except Exception as e:
logger.error(f"电话号码:{self.tg_phone_info.index_id}{e}")
# 这里可以在函数执行后增加逻辑
close_ldplayer(simulator_id=self.tg_phone_info.index_id)
return result
return wrapper
class Ld:
def __init__(self, tg_phone_info):
self.tg_phone_info = tg_phone_info
# for i in get_ldplayer_list():
# if self.tg_phone_info.ld_name == i["Name"]:
# self.index_id = i["ID"]
# break
self.id = "emulator-" + str(5554 + (int(self.tg_phone_info.index_id) * 2))
def start_d(self):
d_type = 0
# 连接模拟器
for i in range(3):
if d_type:
break
start_ldplayer(simulator_id=self.tg_phone_info.index_id)
for i in range(3):
time.sleep(15)
try:
self.d = u2.connect(self.id)
d_type = 1
break
except Exception as e:
pass
else:
logger.error(f"电话号码:{self.tg_phone_info.ld_name}:连接失败!!!")
self.tg_phone_info.is_logged_in_telegram = -1
self.tg_phone_info.save()
close_ldplayer(simulator_id=self.tg_phone_info.index_id, )
time.sleep(10)
return d_type
# 使用链接打开tg的检测
def tg_testing(self):
logger.info(f"电话号码:{self.tg_phone_info.ld_name}:账号检测中》》》")
# 判断需要tg打开链接
for i in range(8):
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="Continue"]', timeout=0.5)
if type1:
ele.click()
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="允许"]', timeout=3)
if type1:
ele.click()
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="允许"]', timeout=3)
if type1:
ele.click()
type1, ele = get_element(d=self.d, type1="xpath", grammar='//*[@text="OK"]', timeout=0.5)
if type1:
ele.click()
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="Remind me later"]', timeout=0.5)
if type1:
ele.click()
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="Telegram"]', timeout=0.5)
if type1:
ele.click()
time.sleep(5)
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="始终"]', timeout=0.5)
if type1: ele.click()
# 判断tg是否掉了
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="Start Messaging"]',
timeout=0.5) # 等待tg打开
if type1:
self.tg_phone_info.is_logged_in_telegram = 0
self.tg_phone_info.save()
logger.info(f"电话号码:{self.tg_phone_info.ld_name}:检测完成:未登录!!!")
return True
logger.warning(f"电话号码:{self.tg_phone_info.ld_name}:检测完成,已登录!!!")
return False
@decorator
def action(self):
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="Telegram"]', timeout=5) # 等待tg打开
if type1:
ele.click()
else:
self.tg_phone_info.is_logged_in_telegram = 0
self.tg_phone_info.save()
return
if self.tg_testing():
logger.error(f"雷电名称:{self.tg_phone_info.ld_name},掉了!!!")
return
logger.info(f"雷电名称:{self.tg_phone_info.ld_name},检测完成!!!")
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@content-desc="Open navigation menu"]',
timeout=0.5) # 等待tg打开
if type1:
ele.click()
# for i in range(3):
# type1, ele = get_element(self.d, type1="xpath", grammar='//*[@content-desc="Open navigation menu"]',
# timeout=0.5) # 等待tg打开
# if type1:
# ele.click()
#
# time.sleep(1)
#
# type1, ele = get_element(self.d, type1="xpath", grammar='//*[contains(@text, "+")]',
# timeout=0.5) # 等待tg打开
# if type1:
# break
phones = self.d.xpath('//*[contains(@text, "+")]').get_text().replace("-", "").replace(' ',
"").replace(
'(', "").replace(')', "").replace("+", "")
one_phone_number, telephone = split_phone_number(phone_number=phones)
# 修改名字
rename_ldplayer(index=self.tg_phone_info.index_id, name=f"{one_phone_number}{telephone}")
self.tg_phone_info.ld_name = f"{one_phone_number}{telephone}"
self.tg_phone_info.one_phone_number = one_phone_number
self.tg_phone_info.telephone = telephone
self.tg_phone_info.is_logged_in_telegram = 1
self.tg_phone_info.phone_type = 1
self.tg_phone_info.save()
# 模拟按下返回键
self.d.press("back")
time.sleep(3)
self.d.xpath('(//android.view.ViewGroup)[1]').click()
time.sleep(3)
type1, ele = get_element(
self.d,
type1="xpath",
grammar='//*[@text="Your account is frozen\nTap to view details"]',
timeout=5
) # 等待tg打开
if type1:
self.tg_phone_info.is_logged_in_telegram = 3
self.tg_phone_info.phone_type = 3
self.tg_phone_info.save()
@decorator
def bf(self):
type1, ele = get_element(self.d, type1="xpath", grammar='//*[@text="Telegram"]', timeout=5) # 等待tg打开
if type1:
ele.click()
else:
self.tg_phone_info.is_logged_in_telegram = 0
self.tg_phone_info.save()
return
if self.tg_testing():
logger.error(f"雷电名称:{self.tg_phone_info.ld_name},掉了!!!")
return
logger.info(f"雷电名称:{self.tg_phone_info.ld_name},检测完成!!!")
# 通过adb shell命令获取
all_packages = self.d.shell('pm list packages').output
# 格式化输出(去掉"package:"前缀)
clean_packages = [pkg.split(':')[1] for pkg in all_packages.splitlines()]
print("纯净包名列表:", clean_packages)
package_name = None
for i in clean_packages:
if "telegram" in i:
package_name = i
break
# 停止应用
self.d.app_stop(package_name)
time.sleep(5)
pull_simulator_backup(
d=self.d,
phone=self.tg_phone_info.ld_name,
local_backup=path
)
time.sleep(10)
send_file(file_path=fr"{path}\{self.tg_phone_info.ld_name}.tar", server_ip="192.168.50.122")
@decorator
def get_sb(self, ):
print(self.d.shell(f"adb -s {self.id} shell getprop ro.product.model"))
# adb -s 127.0.0.1:5555 shell getprop ro.product.model
def get_sb(tg_phone_info, directory, filename, ):
# 打开并读取配置文件
with open(os.path.join(directory, filename), 'r', encoding='utf-8') as file:
config_data = json.load(file)
# 提取所需的键值
phone_manufacturer = config_data.get('propertySettings.phoneManufacturer', 'N/A')
phone_model = config_data.get('propertySettings.phoneModel', 'N/A')
# 组合结果
result = f"{phone_manufacturer} {phone_model}"
tg_phone_info.manufacturer = result
tg_phone_info.save()
# 输出结果
print(f"文件名中的数字: {filename}, 设备信息: {result}")
if __name__ == '__main__':
directory = r"E:\leidian\LDPlayer9\vms\config"
ld_ids = []
for i in get_ldplayer_list():
ld_ids.append(i["ID"])
# print(i["ID"])
# 同时运行
max_threads = 15
delay_between_start = 15 # 每次启动线程之间的延迟时间(秒)
with ThreadPoolExecutor(max_workers=max_threads) as executor:
for _, id in enumerate(ld_ids):
tg_phone_info = TelegramAccount.get_or_none(
TelegramAccount.index_id == id,
TelegramAccount.server_id == get_host_ip(),
)
if not tg_phone_info.ld_name:
continue
get_sb(tg_phone_info=tg_phone_info, directory=directory, filename=f"leidian{id}.config", )
# ld = Ld(tg_phone_info, )
# executor.submit(ld.action)
# time.sleep(delay_between_start)
# # for i in get_ldplayer_list():
# # if id == i["ID"] and i["Name"] == "NoneNone":
# # ld = Ld(tg_phone_info, )
# # executor.submit(ld.action)
# # time.sleep(delay_between_start)
#
# if tg_phone_info.is_logged_in_telegram == -1:
# # logger.info(f"雷电名称:{id} 已经存在!!!")
# # continue
#
# ld = Ld(tg_phone_info, )
# executor.submit(ld.action)
#
# time.sleep(delay_between_start)
#
# if tg_phone_info.is_logged_in_telegram == -1:
# ld = Ld(tg_phone_info, )
# executor.submit(ld.action)
#
# time.sleep(delay_between_start)
# from pathlib import Path
#
# path = r"E:\backups"
#
# # 指定目录
# directory = Path(path)
#
# # 获取目录下的所有文件
# start = 0
# file_list = [str(file) for file in directory.rglob('*') if file.is_file()]
# for file in file_list:
# if tg_phone_info.ld_name in file:
# start = 1
# break
#
# if start:
# send_file(file_path=fr"{path}\{tg_phone_info.ld_name}.tar", server_ip="192.168.50.122")
# continue
#
# ld = Ld(tg_phone_info, )
# executor.submit(ld.bf)

71
process/设置ip.py Normal file
View File

@@ -0,0 +1,71 @@
import json
import subprocess
from loguru import logger
import uiautomator2 as u2
result1 = r"C:\Program Files\Netease\MuMu\nx_main"
def mumu_get_list_all():
# 定义命令
command = [result1 + r"\MuMuManager.exe", "info", "-v", "all"]
# 运行命令并捕获输出,使用 utf-8 编码
result = subprocess.run(command, capture_output=True, text=True, encoding='utf-8')
# 检查命令是否成功执行
if result.returncode != 0:
return None
# 解析 JSON 输出
try:
info = json.loads(result.stdout)
infos = []
for i in info:
infos.append(info[i])
return infos # 返回一个包含嵌套字典的列表
except json.JSONDecodeError as e:
return None
if __name__ == '__main__':
with open('代理配置.txt', 'r', encoding='utf-8') as f:
content = f.read()
lines = content.split('\n')
pro = {}
for line in lines:
pro[line.split("|")[-2]] = line.split("|")
mumu_lists = mumu_get_list_all()
if mumu_lists:
for mumu_info in mumu_lists:
if mumu_info.get("is_android_started"):
try:
d = u2.connect(f"127.0.0.1:{mumu_info.get("adb_port")}")
# 定义命令
command = [
fr'{result1}\adb.exe',
'-s',
f'127.0.0.1:{mumu_info.get("adb_port")}',
'shell',
'settings',
'put',
'global',
'http_proxy',
# f'{pro.get(mumu_info.get("index"))[0]}:{pro.get(mumu_info.get("index"))[1]}'
f':0'
]
# 运行命令并捕获输出,使用 utf-8 编码
result = subprocess.run(command, capture_output=True, text=True, encoding='utf-8')
logger.info(f"模拟器id{mumu_info.get('index')},修改代理成功!!!")
except Exception as e:
print(e)
logger.error(f"模拟器id{mumu_info.get('index')},修改代理失败!!!")