初始化

This commit is contained in:
hnking
2025-09-13 14:20:00 +08:00
commit 6a176e5347
94 changed files with 47438 additions and 0 deletions

525
电信/0点权益.py Normal file
View File

@@ -0,0 +1,525 @@
#!/usr/bin/env python3
import os
import re
import sys
import ssl
import time
import json
import base64
import random
import certifi
import aiohttp
import asyncio
import datetime
import requests
import binascii
from http import cookiejar
from Crypto.Cipher import DES3
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
from Crypto.Util.Padding import pad, unpad
from aiohttp import ClientSession, TCPConnector
# 在全局变量区域添加停止事件
stop_all_event = asyncio.Event() # 控制所有任务停止
# 🌸 标题 🌸
LOGO = f'''
✧・゚: *✧・゚:* 电信金豆换话费脚本 ✧・゚: *✧・゚:*
'''
run_num = os.environ.get('reqNUM') or "50"
MAX_RETRIES = 3
RATE_LIMIT = 15 # 每秒请求数限制
# 🌸 日志相关设置 🌸
yf = datetime.datetime.now().strftime("%Y%m")
try:
with open('电信金豆换话费.log') as fr:
dhjl = json.load(fr)
except:
dhjl = {}
if yf not in dhjl:
dhjl[yf] = {}
class RateLimiter:
def __init__(self, rate_limit):
self.rate_limit = rate_limit
self.tokens = rate_limit
self.updated_at = time.monotonic()
async def acquire(self):
while self.tokens < 1:
self.add_new_tokens()
await asyncio.sleep(0.1)
self.tokens -= 1
def add_new_tokens(self):
now = time.monotonic()
time_since_update = now - self.updated_at
new_tokens = time_since_update * self.rate_limit
if new_tokens > 1:
self.tokens = min(self.tokens + new_tokens, self.rate_limit)
self.updated_at = now
class AsyncSessionManager:
def __init__(self):
self.session = None
self.connector = None
async def __aenter__(self):
ssl_context = ssl.create_default_context(cafile=certifi.where())
ssl_context.set_ciphers('DEFAULT@SECLEVEL=1')
self.connector = TCPConnector(ssl=ssl_context, limit=1000)
self.session = ClientSession(connector=self.connector)
return self.session
async def __aexit__(self, exc_type, exc_val, exc_tb):
await self.session.close()
await self.connector.close()
async def retry_request(session, method, url, **kwargs):
for attempt in range(MAX_RETRIES):
try:
await asyncio.sleep(1)
async with session.request(method, url, **kwargs) as response:
return await response.json()
except (aiohttp.ClientConnectionError, aiohttp.ServerTimeoutError) as e:
print(f"{Color.LIGHT_PINK}💔 请求失败,第 {attempt + 1} 次重试: {e}{Color.ENDC}")
if attempt == MAX_RETRIES - 1:
raise
await asyncio.sleep(2 ** attempt)
class BlockAll(cookiejar.CookiePolicy):
return_ok = set_ok = domain_return_ok = path_return_ok = lambda self, *args, **kwargs: False
netscape = True
rfc2965 = hide_cookie2 = False
# 🌸 输出函数 🌸
def printn(m):
current_time = datetime.datetime.now().strftime("%H:%M:%S.%f")[:-3]
print(f'\n🌸 [{current_time} {m}]')
context = ssl.create_default_context()
context.set_ciphers('DEFAULT@SECLEVEL=1') # 低安全级别0/1
context.check_hostname = False # 禁用主机
context.verify_mode = ssl.CERT_NONE # 禁用证书
class DESAdapter(requests.adapters.HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
kwargs['ssl_context'] = context
return super().init_poolmanager(*args, **kwargs)
requests.packages.urllib3.disable_warnings()
ss = requests.session()
ss.headers = {
"User-Agent": "Mozilla/5.0 (Linux; Android 13; 22081212C Build/TKQ1.220829.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.97 Mobile Safari/537.36",
"Referer": "https://wapact.189.cn:9001/JinDouMall/JinDouMall_independentDetails.html"}
ss.mount('https://', DESAdapter())
ss.cookies.set_policy(BlockAll())
runTime = 0
key = b'1234567`90koiuyhgtfrdews'
iv = 8 * b'\0'
public_key_b64 = '''-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBkLT15ThVgz6/NOl6s8GNPofdWzWbCkWnkaAm7O2LjkM1H7dMvzkiqdxU02jamGRHLX/ZNMCXHnPcW/sDhiFCBN18qFvy8g6VYb9QtroI09e176s+ZCtiv7hbin2cCTj99iUpnEloZm19lwHyo69u5UMiPMpq0/XKBO8lYhN/gwIDAQAB
-----END PUBLIC KEY-----'''
public_key_data = '''-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+ugG5A8cZ3FqUKDwM57GM4io6JGcStivT8UdGt67PEOihLZTw3P7371+N47PrmsCpnTRzbTgcupKtUv8ImZalYk65dU8rjC/ridwhw9ffW2LBwvkEnDkkKKRi2liWIItDftJVBiWOh17o6gfbPoNrWORcAdcbpk2L+udld5kZNwIDAQAB
-----END PUBLIC KEY-----'''
def get_first_three(value):
if isinstance(value, (int, float)):
return f"{str(value)[:3]}****{str(value)[-4:]}"
elif isinstance(value, str):
return f"{value[:3]}****{value[-4:]}"
else:
raise TypeError("error")
def run_Time(hour, miute, second):
date = datetime.datetime.now()
date_zero = datetime.datetime.now().replace(year=date.year, month=date.month, day=date.day, hour=hour, minute=miute,
second=second)
date_zero_time = int(time.mktime(date_zero.timetuple()))
return date_zero_time
def encrypt(text):
cipher = DES3.new(key, DES3.MODE_CBC, iv)
ciphertext = cipher.encrypt(pad(text.encode(), DES3.block_size))
return ciphertext.hex()
def decrypt(text):
ciphertext = bytes.fromhex(text)
cipher = DES3.new(key, DES3.MODE_CBC, iv)
plaintext = unpad(cipher.decrypt(ciphertext), DES3.block_size)
return plaintext.decode()
def b64(plaintext):
public_key = RSA.import_key(public_key_b64)
cipher = PKCS1_v1_5.new(public_key)
ciphertext = cipher.encrypt(plaintext.encode())
return base64.b64encode(ciphertext).decode()
def encrypt_para(plaintext):
if not isinstance(plaintext, str):
plaintext = json.dumps(plaintext)
public_key = RSA.import_key(public_key_data)
cipher = PKCS1_v1_5.new(public_key)
key_size = public_key.size_in_bytes()
max_chunk_size = key_size - 11
plaintext_bytes = plaintext.encode()
ciphertext = b''
for i in range(0, len(plaintext_bytes), max_chunk_size):
chunk = plaintext_bytes[i:i + max_chunk_size]
encrypted_chunk = cipher.encrypt(chunk)
ciphertext += encrypted_chunk
return binascii.hexlify(ciphertext).decode()
def encode_phone(text):
encoded_chars = []
for char in text:
encoded_chars.append(chr(ord(char) + 2))
return ''.join(encoded_chars)
def getApiTime(api_url):
try:
with requests.get(api_url) as response:
if (not response or not response.text):
return time.time()
json_data = json.loads(response.text)
if (json_data.get("api") and json_data.get("api") not in ("time")):
timestamp_str = json_data.get('data', {}).get('t', '')
else:
timestamp_str = json_data.get('currentTime', {})
timestamp = int(timestamp_str) / 1000.0 # 将毫秒转为秒
difftime = time.time() - timestamp
return difftime;
except Exception as e:
print(f"💔 获取时间失败: {e}")
return 0;
def userLoginNormal(phone, password):
alphabet = 'abcdef0123456789'
uuid = [''.join(random.sample(alphabet, 8)), ''.join(random.sample(alphabet, 4)),
'4' + ''.join(random.sample(alphabet, 3)), ''.join(random.sample(alphabet, 4)),
''.join(random.sample(alphabet, 12))]
timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
loginAuthCipherAsymmertric = 'iPhone 14 15.4.' + uuid[0] + uuid[1] + phone + timestamp + password[:6] + '0$$$0.'
try:
r = ss.post('https://appgologin.189.cn:9031/login/client/userLoginNormal', json={
"headerInfos": {"code": "userLoginNormal", "timestamp": timestamp, "broadAccount": "", "broadToken": "",
"clientType": "#11.3.0#channel35#Xiaomi Redmi K30 Pro#", "shopId": "20002",
"source": "110003", "sourcePassword": "Sid98s", "token": "",
"userLoginName": encode_phone(phone)}, "content": {"attach": "test",
"fieldData": {"loginType": "4",
"accountType": "",
"loginAuthCipherAsymmertric": b64(
loginAuthCipherAsymmertric),
"deviceUid": uuid[0] +
uuid[1] +
uuid[2],
"phoneNum": encode_phone(
phone),
"isChinatelecom": "0",
"systemVersion": "12",
"authentication": encode_phone(
password)}}}).json()
l = r['responseData']['data']['loginSuccessResult']
if l:
ticket = get_ticket(phone, l['userId'], l['token'])
return ticket
return False
except Exception as e:
print(f"💔 登录失败: {e}")
return False
async def exchangeForDay(phone, session, run_num, rid, stime, accId):
async def delayed_conversion(delay):
await asyncio.sleep(delay)
await conversionRights(phone, rid, session, accId)
tasks = [asyncio.create_task(delayed_conversion(i * stime)) for i in range(int(run_num))]
await asyncio.gather(*tasks)
def get_ticket(phone, userId, token):
try:
r = ss.post('https://appgologin.189.cn:9031/map/clientXML',
data='<Request><HeaderInfos><Code>getSingle</Code><Timestamp>' + datetime.datetime.now().strftime(
"%Y%m%d%H%M%S") + '</Timestamp><BroadAccount></BroadAccount><BroadToken></BroadToken><ClientType>#9.6.1#channel50#iPhone 14 Pro Max#</ClientType><ShopId>20002</ShopId><Source>110003</Source><SourcePassword>Sid98s</SourcePassword><Token>' + token + '</Token><UserLoginName>' + phone + '</UserLoginName></HeaderInfos><Content><Attach>test</Attach><FieldData><TargetId>' + encrypt(
userId) + '</TargetId><Url>4a6862274835b451</Url></FieldData></Content></Request>',
headers={'user-agent': 'CtClient;10.4.1;Android;13;22081212C;NTQzNzgx!#!MTgwNTg1'},
verify=certifi.where())
tk = re.findall('<Ticket>(.*?)</Ticket>', r.text)
if len(tk) == 0:
return False
return decrypt(tk[0])
except Exception as e:
print(f"💔 获取ticket失败: {e}")
return False
async def exchange(s, phone, title, aid, jsexec, ckvalue):
try:
url = "https://wapact.189.cn:9001/gateway/standExchange/detailNew/exchange"
get_url = await asyncio.to_thread(jsexec.call, "getUrl", "POST", url)
async with s.post(get_url, cookies=ckvalue, json={"activityId": aid}) as response:
pass
except Exception as e:
print(f"💔 兑换出错: {e}")
async def check(s, item, ckvalue):
checkGoods = s.get('https://wapact.189.cn:9001/gateway/stand/detailNew/check?activityId=' + item,
cookies=ckvalue).json()
return checkGoods
async def conversionRights(phone, aid, session, accId):
try:
value = {
"id": aid,
"accId": accId,
"showType": "9003",
"showEffect": "8",
"czValue": "0"
}
paraV = encrypt_para(value)
printn(f"{get_first_three(phone)}: 开始兑换啦~ ✨")
response = await asyncio.to_thread(
session.post,
'https://wappark.189.cn/jt-sign/paradise/receiverRights',
json={"para": paraV}
)
login = response.json()
printn(f"💔 {get_first_three(phone)}: 结果是 {login} 💬")
if '兑换成功' in response.text:
printn(f"{Color.MINT}🎉 恭喜呀!{get_first_three(phone)} 兑换成功啦!🎉")
dhjl[yf]['等级话费'] += "#" + phone
with open('电信金豆换话费.log', 'w') as f:
json.dump(dhjl, f, ensure_ascii=False)
return
elif '已兑换' in response.text:
printn(f"💖 {get_first_three(phone)} 已经兑换过咯~")
dhjl[yf]['等级话费'] += "#" + phone
with open('电信金豆换话费.log', 'w') as f:
json.dump(dhjl, f, ensure_ascii=False)
return
except Exception as e:
printn(f"💔 {get_first_three(phone)} 兑换时出错了: {str(e)}")
async def getLevelRightsList(phone, session, accId):
try:
value = {
"type": "hg_qd_djqydh",
"accId": accId,
"shopId": "20001"
}
paraV = encrypt_para(value)
response = session.post(
'https://wappark.189.cn/jt-sign/paradise/queryLevelRightInfo',
json={"para": paraV}
)
data = response.json()
if data.get('code') == 401:
print(f"💔 获取失败: {data}, 可能是sign过期了呢")
return None
current_level = int(data['currentLevel'])
key_name = 'V' + str(current_level)
ids = [item['activityId'] for item in data.get(key_name, []) if '话费' in item.get('title', '')]
return ids
except Exception as e:
print(f"💔 获取失败, 重试一次: {str(e)}")
try:
paraV = encrypt_para(value)
response = session.post(
'https://wappark.189.cn/jt-sign/paradise/queryLevelRightInfo',
json={"para": paraV}
)
data = response.json()
if data.get('code') == 401:
print(f"💔 重试获取失败: {data}, 可能是sign过期了呢")
return None
current_level = int(data['currentLevel'])
key_name = 'V' + str(current_level)
ids = [item['id'] for item in data.get(key_name, []) if item.get('name') == '话费']
return ids
except Exception as e:
print(f"💔 重试也失败了: {str(e)}")
return None
async def getSign(ticket, session):
try:
response = session.get(
'https://wappark.189.cn/jt-sign/ssoHomLogin?ticket=' + ticket,
headers={
'User-Agent': "Mozilla/5.0 (Linux; Android 13; 22081212C Build/TKQ1.220829.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.97 Mobile Safari/537.36"}
).json()
if response.get('resoultCode') == '0':
sign = response.get('sign')
accId = response.get('accId')
return sign, accId
else:
print(f"💔 获取sign失败[{response.get('resoultCode')}]: {response}")
except Exception as e:
print(f"💔 getSign 出错了: {str(e)}")
return None, None
async def qgNight(phone, ticket, timeDiff, isTrue):
if isTrue:
runTime = run_Time(23, 58, 30)
else:
runTime = 0
if runTime > (time.time() + timeDiff):
difftime = runTime - time.time() - timeDiff
print(f"⏰ 当前时间: {str(datetime.datetime.now())[11:23]}, 要等一会儿哦~ 还要等 {difftime:.2f}")
await asyncio.sleep(difftime)
session = requests.Session()
session.mount('https://', DESAdapter())
session.verify = False # 禁用证书验证
sign, accId = await getSign(ticket, session)
if sign:
session.headers = {
"User-Agent": "Mozilla/5.0 (Linux; Android 13; 22081212C Build/TKQ1.220829.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.97 Mobile Safari/537.36",
"sign": sign}
printn(f"{get_first_three(phone)} 获取到sign啦 太好了!😊")
else:
print(f"{get_first_three(phone)} 💔 没有获取到sign呢...")
return
rightsId = await getLevelRightsList(phone, session, accId)
if rightsId:
printn(f"{get_first_three(phone)} 找到rightsId了: {rightsId[0]} 🌟")
else:
print(f"{get_first_three(phone)} 💔 没找到rightsId呢...")
return
if isTrue:
runTime2 = run_Time(23, 59, 59) + 0.5
difftime = runTime2 - time.time() - timeDiff
printn(f"再等 {difftime:.2f} 秒就开始啦~ ⏳")
await asyncio.sleep(difftime)
else:
# 测试模式:不等待,直接执行
printn(f"测试模式,执行兑换测试~ 🧪")
await exchangeForDay(phone, session, run_num, rightsId[0], 0.05, accId)
async def qgDay(phone, ticket, timeDiff, isTrue):
async with AsyncSessionManager() as s:
pass
async def main(timeDiff, isTRUE, hour):
print(LOGO)
print(f"✨ 脚本启动中~ 准备开始兑换话费啦!✨\n")
tasks = []
accounts = []
for key, value in os.environ.items():
if key == 'chinaTelecomAccount':
accounts.extend(re.split(r'@|&',value))
if not accounts:
print(f"💔 错误: 没有设置 chinaTelecomAccount 环境变量哦~ 要写成 账号#密码 的格式呀 多账号用@分开~")
return
account_count = len(accounts)
print(f"💖 发现 {len(accounts)} 个账号呢,准备开始处理啦~")
for phoneV in accounts:
value = phoneV.split('#')
if len(value) != 2:
print(f"💔 跳过无效格式: {phoneV},要写成 账号#密码 哦 多账号用@分开~")
continue
phone, password = value[0], value[1]
if '等级话费' not in dhjl[yf]:
dhjl[yf]['等级话费'] = ""
if phone in dhjl[yf]['等级话费']:
printn(f"{get_first_three(phone)} 的等级话费已经兑换过啦~ 不用再弄咯~ 💖")
continue
printn(f'{get_first_three(phone)} 开始登录啦~ 🌸')
ticket = userLoginNormal(phone, password)
if ticket:
printn(f'{get_first_three(phone)} 登录成功!太棒啦!🎉')
if hour > 15:
tasks.append(qgNight(phone, ticket, timeDiff, isTRUE))
else:
tasks.append(qgNight(phone, ticket, timeDiff, isTRUE))
else:
printn(f'{get_first_three(phone)} 登录失败了... 有点小伤心呢 💔')
await asyncio.gather(*tasks)
if __name__ == "__main__":
h = datetime.datetime.now().hour
print(f"⏰ 当前时间是 {h} 点哦~")
if 10 > h > 0:
print(f"☀️ 现在是 {h} 点,准备抢十点场次的话费啦~")
wttime = run_Time(9, 59, 8) # 抢十点场次
elif 14 >= h >= 10:
print(f"☀️ 现在是 {h} 点,准备抢十四点场次的话费啦~")
wttime = run_Time(13, 59, 8) # 抢十四点场次
else:
print(f"🌙 现在是 {h} 点,准备抢凌晨场次的话费啦~")
wttime = run_Time(23, 57, 57) # 抢凌晨场次
isTRUE = True # 实际用的时候设为True测试的时候可以设为False哦
if wttime > time.time():
wTime = wttime - time.time()
print(f"⏳ 还要等 {wTime:.2f} 秒才到时间呢~ 耐心等一下下哦~")
if isTRUE:
print(f"💡 小贴士: 记得先测试一下哦~ 要根据自己的网络调整参数呢~")
print(f"💤 开始等待啦... 不要关掉窗口哦~")
time.sleep(wTime)
timeValue = 0 # 时间获取
timeDiff = timeValue if timeValue > 0 else 0
try:
asyncio.run(main(timeDiff, isTRUE, h))
except Exception as e:
print(f"💔 脚本运行的时候出错了: {str(e)}")
finally:
print(f"\n💖 所有任务都完成啦~ 💖")

255
电信/Ruishu.py Normal file
View File

@@ -0,0 +1,255 @@
import os
import ssl
import time
import json
import execjs
import base64
import random
import certifi
import aiohttp
import asyncio
import requests
from http import cookiejar
from Crypto.Cipher import DES3
from Crypto.Util.Padding import pad, unpad
from aiohttp import ClientSession, TCPConnector
import httpx
httpx._config.DEFAULT_CIPHERS += ":ALL:@SECLEVEL=1"
diffValue = 2
filename='Cache.js'
if os.path.exists(filename):
with open(filename, 'r', encoding='utf-8') as file:
fileContent = file.read()
else:
fileContent=''
class BlockAll(cookiejar.CookiePolicy):
return_ok = set_ok = domain_return_ok = path_return_ok = lambda self, *args, **kwargs: False
netscape = True
rfc2965 = hide_cookie2 = False
def printn(m):
print(f'\n{m}')
context = ssl.create_default_context()
context.set_ciphers('DEFAULT@SECLEVEL=1') # 低安全级别0/1
context.check_hostname = False # 禁用主机
context.verify_mode = ssl.CERT_NONE # 禁用证书
class DESAdapter(requests.adapters.HTTPAdapter):
def init_poolmanager(self, *args, **kwargs):
kwargs['ssl_context'] = context
return super().init_poolmanager(*args, **kwargs)
requests.DEFAULT_RETRIES = 0
requests.packages.urllib3.disable_warnings()
ss = requests.session()
ss.headers = {"User-Agent": "Mozilla/5.0 (Linux; Android 13; 22081212C Build/TKQ1.220829.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.97 Mobile Safari/537.36", "Referer": "https://wapact.189.cn:9001/JinDouMall/JinDouMall_independentDetails.html"}
ss.mount('https://', DESAdapter())
ss.cookies.set_policy(BlockAll())
runTime = 0
sleepTime = 1
key = b'1234567`90koiuyhgtfrdews'
iv = 8 * b'\0'
def encrypt(text):
cipher = DES3.new(key, DES3.MODE_CBC, iv)
ciphertext = cipher.encrypt(pad(text.encode(), DES3.block_size))
return ciphertext.hex()
def decrypt(text):
ciphertext = bytes.fromhex(text)
cipher = DES3.new(key, DES3.MODE_CBC, iv)
plaintext = unpad(cipher.decrypt(ciphertext), DES3.block_size)
return plaintext.decode()
def initCookie(getUrl='https://wapact.189.cn:9001/gateway/standQuery/detailNew/exchange'):
global js_code_ym, fileContent
cookie = ''
response = httpx.post(getUrl)
content = response.text.split(' content="')[2].split('" r=')[0]
code1 = response.text.split('$_ts=window')[1].split('</script><script type="text/javascript"')[0]
code1Content = '$_ts=window' + code1
Url = response.text.split('$_ts.lcd();</script><script type="text/javascript" charset="utf-8" src="')[1].split('" r=')[0]
urls = getUrl.split('/')
rsurl = urls[0] + '//' + urls[2] + Url
filename = 'Cache.js'
if fileContent == '':
if not os.path.exists(filename):
fileRes = httpx.get(rsurl)
fileContent = fileRes.text
if fileRes.status_code == 200:
with open(filename, 'w', encoding='utf-8') as file:
file.write(fileRes.text)
else:
print(f"Failed to download {rsurl}. Status code: {fileRes.status_code}")
if response.headers['Set-Cookie']:
cookie = response.headers['Set-Cookie'].split(';')[0].split('=')[1]
runJs = js_code_ym.replace('content_code', content).replace("'ts_code'", code1Content + fileContent)
execjsRun = RefererCookie(runJs)
return {
'cookie': cookie,
'execjsRun': execjsRun
}
def RefererCookie(runJs):
try:
execjsRun = execjs.compile(runJs)
return execjsRun
except execjs._exceptions.CompileError as e:
print(f"JavaScript 编译错误: {e}")
except execjs._exceptions.RuntimeError as e:
print(f"JavaScript 运行时错误: {e}")
except Exception as e:
print(f"其他错误: {e}")
js_code_ym = '''delete __filename
delete __dirname
ActiveXObject = undefined
window = global;
content="content_code"
navigator = {"platform": "Linux aarch64"}
navigator = {"userAgent": "CtClient;11.0.0;Android;13;22081212C;NTIyMTcw!#!MTUzNzY"}
location={
"href": "https://",
"origin": "",
"protocol": "",
"host": "",
"hostname": "",
"port": "",
"pathname": "",
"search": "",
"hash": ""
}
i = {length: 0}
base = {length: 0}
div = {
getElementsByTagName: function (res) {
console.log('div中的getElementsByTagName', res)
if (res === 'i') {
return i
}
return '<div></div>'
}
}
script = {
}
meta = [
{charset:"UTF-8"},
{
content: content,
getAttribute: function (res) {
console.log('meta中的getAttribute', res)
if (res === 'r') {
return 'm'
}
},
parentNode: {
removeChild: function (res) {
console.log('meta中的removeChild', res)
return content
}
},
}
]
form = '<form></form>'
window.addEventListener= function (res) {
console.log('window中的addEventListener:', res)
}
document = {
createElement: function (res) {
console.log('document中的createElement', res)
if (res === 'div') {
return div
} else if (res === 'form') {
return form
}
else{return res}
},
addEventListener: function (res) {
console.log('document中的addEventListener:', res)
},
appendChild: function (res) {
console.log('document中的appendChild', res)
return res
},
removeChild: function (res) {
console.log('document中的removeChild', res)
},
getElementsByTagName: function (res) {
console.log('document中的getElementsByTagName', res)
if (res === 'script') {
return script
}
if (res === 'meta') {
return meta
}
if (res === 'base') {
return base
}
},
getElementById: function (res) {
console.log('document中的getElementById', res)
if (res === 'root-hammerhead-shadow-ui') {
return null
}
}
}
setInterval = function () {}
setTimeout = function () {}
window.top = window
'ts_code'
function main() {
cookie = document.cookie.split(';')[0]
return cookie
}'''
async def main(timeValue):
global runTime, js_codeRead
tasks = []
init_result = initCookie()
if init_result:
cookie = init_result['cookie']
execjsRun = init_result['execjsRun']
else:
print("初始化 cookies 失败")
return
runcookie = {
'cookie': cookie,
'execjsRun': execjsRun
}
# 添加输出 cookies 的代码
cookies = {
'yiUIIlbdQT3fO': runcookie['cookie'],
'yiUIIlbdQT3fP': runcookie['execjsRun'].call('main').split('=')[1]
}
print(json.dumps(cookies)) # 确保输出是 JSON 格式的
if __name__ == "__main__":
asyncio.run(main(0))

205
电信/ruishucookie.py Normal file
View File

@@ -0,0 +1,205 @@
# ruishucookie.py
import os
import execjs
import httpx
httpx._config.DEFAULT_CIPHERS += ":ALL:@SECLEVEL=1"
filename = 'Cache.js'
if os.path.exists(filename):
with open(filename, 'r', encoding='utf-8') as file:
fileContent = file.read()
else:
fileContent = ''
def initCookie(getUrl='https://wapact.189.cn:9001/gateway/standQuery/detailNew/exchange'):
global js_code_ym, fileContent
cookie = ''
response = httpx.post(getUrl)
content = response.text.split(' content="')[2].split('" r=')[0]
code1 = response.text.split('$_ts=window')[1].split('</script><script type="text/javascript"')[0]
code1Content = '$_ts=window' + code1
Url = response.text.split('$_ts.lcd();</script><script type="text/javascript" charset="utf-8" src="')[1].split('" r=')[0]
urls = getUrl.split('/')
rsurl = urls[0] + '//' + urls[2] + Url
filename = 'Cache.js'
if fileContent == '':
if not os.path.exists(filename):
fileRes = httpx.get(rsurl)
fileContent = fileRes.text
if fileRes.status_code == 200:
with open(filename, 'w', encoding='utf-8') as file:
file.write(fileRes.text)
else:
print(f"Failed to download {rsurl}. Status code: {fileRes.status_code}")
if response.headers['Set-Cookie']:
cookie = response.headers['Set-Cookie'].split(';')[0].split('=')[1]
runJs = js_code_ym.replace('content_code', content).replace("'ts_code'", code1Content + fileContent)
execjsRun = RefererCookie(runJs)
# 将 cookies 转换为字符串格式
cookies_str = f"yiUIIlbdQT3fO={cookie}; yiUIIlbdQT3fP={execjsRun.call('main').split('=')[1]}"
return cookies_str
def RefererCookie(runJs):
try:
execjsRun = execjs.compile(runJs)
return execjsRun
except execjs._exceptions.CompileError as e:
print(f"JavaScript 编译错误: {e}")
except execjs._exceptions.RuntimeError as e:
print(f"JavaScript 运行时错误: {e}")
except Exception as e:
print(f"其他错误: {e}")
js_code_ym = '''delete __filename
delete __dirname
ActiveXObject = undefined
window = global;
content="content_code"
navigator = {"platform": "Linux aarch64"}
navigator = {"userAgent": "CtClient;11.0.0;Android;13;22081212C;NTIyMTcw!#!MTUzNzY"}
location={
"href": "https://",
"origin": "",
"protocol": "",
"host": "",
"hostname": "",
"port": "",
"pathname": "",
"search": "",
"hash": ""
}
i = {length: 0}
base = {length: 0}
div = {
getElementsByTagName: function (res) {
console.log('div中的getElementsByTagName', res)
if (res === 'i') {
return i
}
return '<div></div>'
}
}
script = {
}
meta = [
{charset:"UTF-8"},
{
content: content,
getAttribute: function (res) {
console.log('meta中的getAttribute', res)
if (res === 'r') {
return 'm'
}
},
parentNode: {
removeChild: function (res) {
console.log('meta中的removeChild', res)
return content
}
},
}
]
form = '<form></form>'
window.addEventListener= function (res) {
console.log('window中的addEventListener:', res)
}
document = {
createElement: function (res) {
console.log('document中的createElement', res)
if (res === 'div') {
return div
} else if (res === 'form') {
return form
}
else{return res}
},
addEventListener: function (res) {
console.log('document中的addEventListener:', res)
},
appendChild: function (res) {
console.log('document中的appendChild', res)
return res
},
removeChild: function (res) {
console.log('document中的removeChild', res)
},
getElementsByTagName: function (res) {
console.log('document中的getElementsByTagName', res)
if (res === 'script') {
return script
}
if (res === 'meta') {
return meta
}
if (res === 'base') {
return base
}
},
getElementById: function (res) {
console.log('document中的getElementById', res)
if (res === 'root-hammerhead-shadow-ui') {
return null
}
}
}
setInterval = function () {}
setTimeout = function () {}
window.top = window
'ts_code'
function main() {
cookie = document.cookie.split(';')[0]
return cookie
}'''
async def main(timeValue):
global runTime, js_codeRead
tasks = []
init_result = initCookie()
if init_result:
cookie = init_result['cookie']
execjsRun = init_result['execjsRun']
else:
print("初始化 cookies 失败")
return
runcookie = {
'cookie': cookie,
'execjsRun': execjsRun
}
# 添加输出 cookies 的代码
cookies = {
'yiUIIlbdQT3fO': runcookie['cookie'],
'yiUIIlbdQT3fP': runcookie['execjsRun'].call('main').split('=')[1]
}
print(f"Cookies: {cookies}")
if __name__ == "__main__":
asyncio.run(main(0))

139
电信/瑞数通杀.js Normal file
View File

@@ -0,0 +1,139 @@
/*
const $ = new Env("瑞数通杀");
*/
delete __filename
delete __dirname
ActiveXObject = undefined
window = global;
content="content_code"
navigator = {"platform": "Linux aarch64"}
navigator = {"userAgent": "CtClient;11.0.0;Android;13;22081212C;NTIyMTcw!#!MTUzNzY"}
location={
"href": "https://",
"origin": "",
"protocol": "",
"host": "",
"hostname": "",
"port": "",
"pathname": "",
"search": "",
"hash": ""
}
i = {length: 0}
base = {length: 0}
div = {
getElementsByTagName: function (res) {
console.log('div中的getElementsByTagName', res)
if (res === 'i') {
return i
}
return '<div></div>'
}
}
script = {
}
meta = [
{charset:"UTF-8"},
{
content: content,
getAttribute: function (res) {
console.log('meta中的getAttribute', res)
if (res === 'r') {
return 'm'
}
},
parentNode: {
removeChild: function (res) {
console.log('meta中的removeChild', res)
return content
}
},
}
]
form = '<form></form>'
window.addEventListener= function (res) {
console.log('window中的addEventListener:', res)
}
document = {
createElement: function (res) {
console.log('document中的createElement', res)
if (res === 'div') {
return div
} else if (res === 'form') {
return form
}
else{return res}
},
addEventListener: function (res) {
console.log('document中的addEventListener:', res)
},
appendChild: function (res) {
console.log('document中的appendChild', res)
return res
},
removeChild: function (res) {
console.log('document中的removeChild', res)
},
getElementsByTagName: function (res) {
console.log('document中的getElementsByTagName', res)
if (res === 'script') {
return script
}
if (res === 'meta') {
return meta
}
if (res === 'base') {
return base
}
},
getElementById: function (res) {
console.log('document中的getElementById', res)
if (res === 'root-hammerhead-shadow-ui') {
return null
}
}
}
setInterval = function () {}
setTimeout = function () {}
window.top = window
'ts_code'
function main() {
cookie = document.cookie.split(';')[0]
return cookie
}

2569
电信/电信营业厅.js Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

688
电信/话费兑换.py Normal file
View File

@@ -0,0 +1,688 @@
"""
cron: 0 59 9,13 * * *
new Env('电信金豆兑换话费');
"""
import subprocess
import sys
import asyncio
import aiohttp
import os
import execjs
import requests
import re
import time as time_module # 重命名导入以避免冲突
import json
import random
import datetime
import base64
import ssl
import certifi
import traceback
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_v1_5
from Crypto.Cipher import DES3
from Crypto.Util.Padding import pad, unpad
from Crypto.Cipher import AES
from http import cookiejar
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
def get_network_time():
"""从淘宝接口获取网络时间"""
url = "https://acs.m.taobao.com/gw/mtop.common.getTimestamp/"
try:
response = requests.get(url)
if response.status_code == 200:
data = response.json()
if "data" in data and "t" in data["data"]:
timestamp = int(data["data"]["t"])
return datetime.datetime.fromtimestamp(timestamp / 1000)
else:
raise ValueError("接口返回数据格式错误")
else:
raise Exception(f"获取网络时间失败,状态码: {response.status_code}")
except Exception as e:
print(f"{str(get_network_time())[11:22]} 🌸获取网络时间失败: {e}")
return datetime.datetime.now()
# 获取本地时间和网络时间
local_time = datetime.datetime.now()
network_time = get_network_time()
# 计算时间差
time_diff = network_time - local_time
# 输出时间差,精确到微秒
print(f"💖本地时间: {local_time.strftime('%Y-%m-%d %H:%M:%S.%f')}")
print(f"💖网络时间: {network_time.strftime('%Y-%m-%d %H:%M:%S.%f')}")
print(f"💖时间差: {time_diff.total_seconds():.6f}")
# 默认兑换策略
MEXZ = os.getenv("MEXZ")
# 定义时间段
morning_start = datetime.time(9, 30, 3)
morning_end = datetime.time(10, 10, 30)
afternoon_start = datetime.time(13, 30, 3)
afternoon_end = datetime.time(14, 10, 30)
# 获取当前时间
now = get_network_time().time()
# 判断当前时间是否在指定的时间段内
if (morning_start <= now <= morning_end) or (afternoon_start <= now <= afternoon_end):
if not MEXZ:
MEXZ = "0.5,5,6;1,10,3"
else:
MEXZ = "0.5,5,6;1,10,3"
# 解析 MEXZ 配置
morning_exchanges, afternoon_exchanges = MEXZ.split(';')
morning_exchanges = [f"{x}元话费" for x in morning_exchanges.split(',')]
afternoon_exchanges = [f"{x}元话费" for x in afternoon_exchanges.split(',')]
# 从环境变量中获取代理池地址
DY_PROXY = os.getenv("DY_PROXY123")
# 新增从环境变量获取外层循环次数默认20次
OUTER_LOOP_COUNT = int(os.getenv("OUTER_LOOP_COUNT", "20"))
INNER_LOOP_COUNT = int(os.getenv("INNER_LOOP_COUNT", "10"))
async def get_proxy_from_pool():
"""从代理池获取代理IP"""
if not DY_PROXY:
raise ValueError("DY_PROXY 环境变量未设置")
async with aiohttp.ClientSession() as session:
async with session.get(DY_PROXY) as response:
if response.status != 200:
raise Exception(f"从代理池获取代理IP失败状态码: {response.status}")
proxy_ip = await response.text()
return proxy_ip.strip()
class BlockAll(cookiejar.CookiePolicy):
return_ok = set_ok = domain_return_ok = path_return_ok = lambda self, *args, **kwargs: False
netscape = True
rfc2965 = hide_cookie2 = False
def printn(m):
print(f'\n{m}')
def print_time_log(m):
print(f'{str(get_network_time())[11:22]} 🌸{m}')
ORIGIN_CIPHERS = ('DEFAULT@SECLEVEL=1')
class DESAdapter(HTTPAdapter):
def __init__(self, *args, **kwargs):
CIPHERS = ORIGIN_CIPHERS.split(':')
random.shuffle(CIPHERS)
CIPHERS = ':'.join(CIPHERS)
self.CIPHERS = CIPHERS + ':!aNULL:!eNULL:!MD5'
super().__init__(*args, **kwargs)
def init_poolmanager(self, *args, **kwargs):
context = create_urllib3_context(ciphers=self.CIPHERS)
context.check_hostname = False
kwargs['ssl_context'] = context
return super(DESAdapter, self).init_poolmanager(*args, **kwargs)
def proxy_manager_for(self, *args, **kwargs):
context = create_urllib3_context(ciphers=self.CIPHERS)
context.check_hostname = False
kwargs['ssl_context'] = context
return super(DESAdapter, self).proxy_manager_for(*args, **kwargs)
requests.packages.urllib3.disable_warnings()
ssl_context = ssl.create_default_context()
ssl_context.set_ciphers("DEFAULT@SECLEVEL=1")
ss = requests.session()
ss.verify = certifi.where()
ss.headers = {
"User-Agent": "Mozilla/5.0 (Linux; Android 13; 22081212C Build/TKQ1.220829.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.97 Mobile Safari/537.36",
"Referer": "https://wapact.189.cn:9001/JinDouMall/JinDouMall_independentDetails.html"
}
ss.mount('https://', DESAdapter())
ss.cookies.set_policy(BlockAll())
yc = 1
wt = 0
kswt = 0.1
yf = get_network_time().strftime("%Y%m")
ip_list = []
jp = {"9": {}, "13": {}}
try:
with open('电信金豆换话费.log') as fr:
dhjl = json.load(fr)
except:
dhjl = {}
if yf not in dhjl:
dhjl[yf] = {}
else:
# 将现有字符串记录转换为集合(仅首次加载时执行)
for di in dhjl[yf]:
if isinstance(dhjl[yf][di], str):
# 拆分字符串为列表,去重后转为集合
phone_list = dhjl[yf][di].strip('#').split('#') if dhjl[yf][di] else []
dhjl[yf][di] = set(phone_list)
load_token_file = 'chinaTelecom_cache.json'
try:
with open(load_token_file, 'r') as f:
load_token = json.load(f)
except:
load_token = {}
errcode = {
"0": "兑换成功✨",
"412": "兑换次数已达上限💔",
"413": "商品已兑完💨",
"420": "未知错误😥",
"410": "该活动未开始⏳",
"501": "服务器处理错误💻",
"Y0001": "当前等级不足,去升级兑当前话费📈",
"Y0002": "使用翼相连网络600分钟可兑换此奖品📶",
"Y0003": "共享流量400M可兑换此奖品💧",
"Y0004": "共享流量2GB可兑换此奖品💧",
"Y0005": "当前等级不足,去升级兑当前话费📈",
"E0001": "您的网龄不足10年暂不能兑换⏳"
}
key = b'1234567`90koiuyhgtfrdews'
iv = 8 * b'\0'
public_key_b64 = '''-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDBkLT15ThVgz6/NOl6s8GNPofdWzWbCkWnkaAm7O2LjkM1H7dMvzkiqdxU02jamGRHLX/ZNMCXHnPcW/sDhiFCBN18qFvy8g6VYb9QtroI09e176s+ZCtiv7hbin2cCTj99iUpnEloZm19lwHyo69u5UMiPMpq0/XKBO8lYhN/gwIDAQAB
-----END PUBLIC KEY-----'''
public_key_data = '''-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+ugG5A8cZ3FqUKDwM57GM4io6JGcStivT8UdGt67PEOihLZTw3P7371+N47PrmsCpnTRzbTgcupKtUv8ImZalYk65dU8rjC/ridwhw9ffW2LBwvkEnDkkKKRi2liWIItDftJVBiWOh17o6gfbPoNrWORcAdcbpk2L+udld5kZNwIDAQAB
-----END PUBLIC KEY-----'''
def t(h):
date = get_network_time()
date_zero = date.replace(hour=h, minute=59, second=20)
date_zero_time = time_module.mktime(date_zero.timetuple())
return date_zero_time
def encrypt(text):
cipher = DES3.new(key, DES3.MODE_CBC, iv)
ciphertext = cipher.encrypt(pad(text.encode(), DES3.block_size))
return ciphertext.hex()
def decrypt(text):
ciphertext = bytes.fromhex(text)
cipher = DES3.new(key, DES3.MODE_CBC, iv)
plaintext = unpad(cipher.decrypt(ciphertext), DES3.block_size)
return plaintext.decode()
def b64(plaintext):
public_key = RSA.import_key(public_key_b64)
cipher = PKCS1_v1_5.new(public_key)
ciphertext = cipher.encrypt(plaintext.encode())
return base64.b64encode(ciphertext).decode()
def encrypt_para(plaintext):
public_key = RSA.import_key(public_key_data)
cipher = PKCS1_v1_5.new(public_key)
ciphertext = cipher.encrypt(plaintext.encode())
return ciphertext.hex()
def encode_phone(text):
encoded_chars = []
for char in text:
encoded_chars.append(chr(ord(char) + 2))
return ''.join(encoded_chars)
def ophone(t):
key = b'34d7cb0bcdf07523'
utf8_t = t.encode('utf-8')
cipher = AES.new(key, AES.MODE_ECB)
ciphertext = cipher.encrypt(pad(utf8_t, AES.block_size))
return ciphertext.hex()
def send(uid, content):
appToken = os.getenv("WXPUSHER_APP_TOKEN")
uid = os.getenv("WXPUSHER_UID")
if not appToken or not uid:
raise ValueError("WXPUSHER_APP_TOKEN 或 WXPUSHER_UID 未设置")
r = requests.post('https://wxpusher.zjiecode.com/api/send/message',
json={"appToken": appToken, "content": content, "contentType": 1, "uids": [uid]}).json()
return r
def userLoginNormal(phone, password):
alphabet = 'abcdef0123456789'
uuid = [''.join(random.sample(alphabet, 8)), ''.join(random.sample(alphabet, 4)),
'4' + ''.join(random.sample(alphabet, 3)), ''.join(random.sample(alphabet, 4)),
''.join(random.sample(alphabet, 12))]
timestamp = get_network_time().strftime("%Y%m%d%H%M%S")
loginAuthCipherAsymmertric = 'iPhone 14 15.4.' + uuid[0] + uuid[1] + phone + timestamp + password[:6] + '0$$$0.'
try:
r = ss.post('https://appgologin.189.cn:9031/login/client/userLoginNormal',
json={"headerInfos": {"code": "userLoginNormal", "timestamp": timestamp,
"broadAccount": "", "broadToken": "",
"clientType": "#10.5.0#channel50#iPhone 14 Pro Max#",
"shopId": "20002", "source": "110003",
"sourcePassword": "Sid98s", "token": "",
"userLoginName": encode_phone(phone)},
"content": {"attach": "test", "fieldData": {"loginType": "4",
"accountType": "",
"loginAuthCipherAsymmertric": b64(loginAuthCipherAsymmertric),
"deviceUid": uuid[0] + uuid[1] + uuid[2],
"phoneNum": encode_phone(phone),
"isChinatelecom": "0",
"systemVersion": "15.4.0",
"authentication": encode_phone(password)}}}).json()
except Exception as e:
print(f"登录请求失败,错误信息: {e}")
return False
if r is None:
print(f"登录请求失败,返回值为 None")
return False
if 'responseData' not in r or r['responseData'] is None:
print(f"登录请求失败responseData 不存在或为 None: {r}")
return False
if 'data' not in r['responseData'] or r['responseData']['data'] is None:
print(f"登录请求失败data 不存在或为 None: {r}")
return False
if 'loginSuccessResult' not in r['responseData']['data']:
print(f"登录请求失败loginSuccessResult 不存在: {r}")
return False
l = r['responseData']['data']['loginSuccessResult']
if l:
load_token[phone] = l
with open(load_token_file, 'w') as f:
json.dump(load_token, f)
ticket = get_ticket(phone, l['userId'], l['token'])
return ticket
return False
def get_ticket(phone, userId, token):
r = ss.post('https://appgologin.189.cn:9031/map/clientXML',
data='<Request><HeaderInfos><Code>getSingle</Code><Timestamp>' + get_network_time().strftime("%Y%m%d%H%M%S") +
'</Timestamp><BroadAccount></BroadAccount><BroadToken></BroadToken><ClientType>#9.6.1#channel50#iPhone 14 Pro Max#</ClientType>' +
'<ShopId>20002</ShopId><Source>110003</Source><SourcePassword>Sid98s</SourcePassword><Token>' + token +
'</Token><UserLoginName>' + phone + '</UserLoginName></HeaderInfos><Content><Attach>test</Attach>' +
'<FieldData><TargetId>' + encrypt(userId) + '</TargetId><Url>4a6862274835b451</Url></FieldData></Content></Request>',
headers={'user-agent': 'CtClient;10.4.1;Android;13;22081212C;NTQzNzgx!#!MTgwNTg1'})
tk = re.findall('<Ticket>(.*?)</Ticket>', r.text)
if len(tk) == 0:
return False
return decrypt(tk[0])
async def exchange(phone, s, title, aid, uid, amount):
global h
masked_phone = phone[:3] + '****' + phone[-4:]
try:
tt = time_module.time()
start_time = time_module.time()
end_time = time_module.time()
#print_time_log(f"📱{masked_phone} 准备兑换 {title} 啦~ ⏳用时: {end_time - start_time:.3f} 秒")
now = get_network_time()
if h is None:
h = now.hour
if h == 9:
first_target_time = now.replace(hour=h, minute=59, second=30, microsecond=0)
elif h == 13:
first_target_time = now.replace(hour=h, minute=59, second=30, microsecond=0)
first_time_diff = (first_target_time - now).total_seconds()
if 0 <= first_time_diff <= 300:
print_time_log(f"📱{masked_phone} 等待 {first_time_diff:.2f} 秒后开始哦~")
await asyncio.sleep(first_time_diff)
morning_start = datetime.time(9, 30, 50)
morning_end = datetime.time(10, 10, 5)
afternoon_start = datetime.time(13, 30, 40)
afternoon_end = datetime.time(14, 10, 5)
current_time = now.time()
proxy = None
#if (morning_start <= current_time <= morning_end) or (afternoon_start <= current_time <= afternoon_end):
#if DY_PROXY:
#try:
#proxy_ip = await get_proxy_from_pool()
#proxy = f"http://{proxy_ip}"
#print_time_log(f"📱{masked_phone} 拿到代理IP啦~ 🌐{proxy_ip}")
#except ValueError as e:
#print_time_log(f"📱{masked_phone} {e} 用本地网络哦~ 📶")
#else:
#print_time_log(f"📱{masked_phone} 用本地网络啦~ 📶")
#else:
#print_time_log(f"📱{masked_phone} 用本地网络哦~ 📶")
#if h == 9:
#second_target_time = now.replace(hour=h, minute=59, second=56, microsecond=803600)
#elif h == 13:
#second_target_time = now.replace(hour=h, minute=59, second=56, microsecond=793600)
#second_time_diff = (second_target_time - get_network_time()).total_seconds()
#if 0 <= second_time_diff <= 300:
#print_time_log(f"📱{masked_phone} 再等 {second_time_diff:.2f} 秒就好啦~")
#await asyncio.sleep(second_time_diff)
#if proxy:
#print_time_log(f"📱{masked_phone} 正在用代理IP: {proxy} 哦~")
#else:
#print_time_log(f"📱{masked_phone} 正在用本地网络~")
url = "https://wapact.189.cn:9001/gateway/standExchange/detailNew/exchange"
request_start_time = datetime.datetime.now()
async with s.post(url, json={"activityId": aid}, proxy=proxy) as r:
request_end_time = datetime.datetime.now()
print(f'\n{str(get_network_time())[11:22]}')
print(f"📱{masked_phone} 发送兑换请求时间: {request_start_time.strftime('%Y-%m-%d %H:%M:%S.%f')}")
print(f"📱{masked_phone} 请求耗时: {(request_end_time - request_start_time).total_seconds():.6f}")
if r.status == 412:
print(f"📱{masked_phone} 遇到连续412错误终止兑换啦~ 😢")
return
print(f"📱{masked_phone} 响应码: {r.status} {await r.text()}")
if r.status == 200:
r_json = await r.json()
if r_json["code"] == 0:
if r_json["biz"] != {} and r_json["biz"]["resultCode"] in errcode:
print(f'📱{masked_phone} ------ {str(get_network_time())[11:22]} ------ {title} {errcode[r_json["biz"]["resultCode"]]}')
if r_json["biz"]["resultCode"] in ["0", "412"]:
if r_json["biz"]["resultCode"] == "0":
msg = phone + ":" + title + "兑换成功啦~ ✨"
send(uid, msg)
if phone not in dhjl[yf][title]:
dhjl[yf][title].add(phone)
with open('电信金豆换话费.log', 'w') as f:
temp_dhjl = {k: {m: list(n) for m, n in v.items()} for k, v in dhjl.items()}
json.dump(temp_dhjl, f, ensure_ascii=False)
else:
print_time_log(f'📱{masked_phone} {r_json}')
else:
print_time_log(f"📱{masked_phone} 兑换请求失败: {await r.text()}")
except Exception as e:
print_time_log(f"📱{masked_phone} 发生错误: {e}")
async def dh(phone, s, title, aid, wt, uid):
global h
masked_phone = phone[:3] + '****' + phone[-4:]
print_time_log(f"📱{masked_phone} 💕{title} 开始兑换咯~")
cs = 0
tasks = []
creat_start_time = datetime.datetime.now()
# 每个账号10次兑换循环
while cs < INNER_LOOP_COUNT:
amount = title.split('')[0]
if (h == 9 and title in morning_exchanges) or (h == 13 and title in afternoon_exchanges):
tasks.append(exchange(phone, s, title, aid, uid, amount))
else:
print_time_log(f"📱{masked_phone} 💕{title} 不在兑换时间哦,跳过啦~")
cs += 1
await asyncio.sleep(0.3)
creat_end_time = datetime.datetime.now()
print_time_log(f"📱{masked_phone} 创建了【{cs}】个任务 用时:{(creat_end_time - creat_start_time).total_seconds():.6f}")
while wt > get_network_time().timestamp():
await asyncio.sleep(1)
await asyncio.gather(*tasks)
def aes_ecb_encrypt(plaintext, key):
key = key.encode('utf-8')
if len(key) not in [16, 24, 32]:
raise ValueError("密钥长度必须为16/24/32字节哦~")
padded_data = pad(plaintext.encode('utf-8'), AES.block_size)
cipher = AES.new(key, AES.MODE_ECB)
ciphertext = cipher.encrypt(padded_data)
return base64.b64encode(ciphertext).decode('utf-8')
async def ks(phone, ticket, uid):
global h, wt
masked_phone = phone[:3] + '****' + phone[-4:]
print_time_log(f"📱{masked_phone} 准备开始兑换流程啦~")
headers = {
"User-Agent": "Mozilla/5.0 (Linux; Android 13; 22081212C Build/TKQ1.220829.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.97 Mobile Safari/537.36",
"Referer": "https://wapact.189.cn:9001/JinDouMall/JinDouMall_independentDetails.html"
}
timeout = aiohttp.ClientTimeout(total=20)
async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(ssl=ssl_context), headers=headers, timeout=timeout) as s:
try:
login_data = {
"ticket": ticket,
"backUrl": "https%3A%2F%2Fwapact.189.cn%3A9001",
"platformCode": "P201010301",
"loginType": 2
}
encrypted_data = aes_ecb_encrypt(json.dumps(login_data), 'telecom_wap_2018')
max_retries = 3
retries = 0
while retries < max_retries:
try:
login_response = await s.post(
'https://wapact.189.cn:9001/unified/user/login',
data=encrypted_data,
headers={
"Content-Type": "application/json;charset=UTF-8",
"Accept": "application/json, text/javascript, */*; q=0.01"
}
)
if login_response.status == 200:
login = await login_response.json()
break
elif login_response.status == 412:
print_time_log(f"📱{masked_phone} 登录失败,重新尝试~")
return await ks(phone, ticket, uid)
else:
print_time_log(f"📱{masked_phone} 登录请求失败,状态码: {login_response.status}")
print_time_log(f"响应内容: {await login_response.text()}")
except (aiohttp.ClientError, asyncio.TimeoutError) as e:
retries += 1
print_time_log(f"📱{masked_phone} 登录失败,重试 {retries}/{max_retries}... 错误: {e}")
await asyncio.sleep(2 ** retries)
if retries == max_retries:
print_time_log(f"📱{masked_phone} 登录失败,重新尝试~")
return await ks(phone, ticket, uid)
if 'login' in locals() and login['code'] == 0:
s.headers["Authorization"] = "Bearer " + login["biz"]["token"]
r = await s.get('https://wapact.189.cn:9001/gateway/golden/api/queryInfo')
r_json = await r.json()
amountTotal = r_json["biz"]["amountTotal"]
print_time_log(f'📱{masked_phone} 金豆余额:{amountTotal} 个~ ✨')
queryBigDataAppGetOrInfo = await s.get('https://wapact.189.cn:9001/gateway/golden/goldGoods/getGoodsList?floorType=0&userType=1&page=1&order=3&tabOrder=')
queryBigDataAppGetOrInfo_json = await queryBigDataAppGetOrInfo.json()
if "biz" in queryBigDataAppGetOrInfo_json and "ExchangeGoodslist" in queryBigDataAppGetOrInfo_json["biz"]:
for i in queryBigDataAppGetOrInfo_json["biz"]["ExchangeGoodslist"]:
if '话费' not in i["title"]:
continue
for j in morning_exchanges:
if j in i["title"]:
jp["9"][j] = i["id"]
for j in afternoon_exchanges:
if j in i["title"]:
jp["13"][j] = i["id"]
else:
print_time_log(f"📱{masked_phone} 获取商品列表失败啦~")
h = get_network_time().hour
if 11 > h:
h = 9
else:
h = 13
if len(sys.argv) == 2:
h = int(sys.argv[1])
d = jp[str(h)]
wt = t(h) + kswt
# 优化后:提前过滤,仅保留未兑换的商品
valid_products = []
for di in sorted(d.keys(), key=lambda x: float(x.replace('元话费', '')), reverse=True):
if phone not in dhjl[yf].get(di, set()): # 用集合快速判断
valid_products.append(di)
# 新增:外层循环控制
for loop in range(OUTER_LOOP_COUNT):
print_time_log(f"📱{masked_phone} 开始第 {loop + 1}/{OUTER_LOOP_COUNT} 轮兑换")
tasks = []
for di in valid_products:
if wt - time_module.time() > 30 * 60:
print_time_log(f"等待太久啦,退出咯~")
return
tasks.append(dh(phone, s, di, d[di], wt, uid))
print_time_log(f"📱{masked_phone}{loop + 1} 轮共有【{len(tasks)}】个兑换任务哦~")
await asyncio.gather(*tasks)
# 轮次之间休息3秒避免请求过于频繁
if loop < OUTER_LOOP_COUNT - 1:
await asyncio.sleep(0.01)
else:
print_time_log(f"📱{masked_phone} 获取token失败: {login['message']}")
except Exception as e:
print_time_log(f"📱{masked_phone} 发生错误: {e}")
return
async def main():
global wt, rs, h
headers = {
"User-Agent": "Mozilla/5.0 (Linux; Android 13; 22081212C Build/TKQ1.220829.002) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.97 Mobile Safari/537.36",
"Referer": "https://wapact.189.cn:9001/JinDouMall/JinDouMall_independentDetails.html"
}
timeout = aiohttp.ClientTimeout(total=20)
rs = 0
accounts = []
for key, value in os.environ.items():
if key == 'chinaTelecomAccount':
accounts.extend(re.split(r'@|&',value))
if not accounts:
print("没有检测到账号哦~")
return
account_count = len(accounts)
print_time_log(f"💖检测到 【{account_count}】 个账号")
print_time_log(f"💖外层兑换循环次数: 【{OUTER_LOOP_COUNT}】 次")
batch_size = 20
for i in range(0, account_count, batch_size):
batch_accounts = accounts[i:i + batch_size]
tasks = []
for account in batch_accounts:
account_info = account.split('#')
phone = account_info[0]
password = account_info[1]
uid = account_info[-1]
ticket = False
masked_phone = phone[:3] + '****' + phone[-4:]
if phone in load_token:
print_time_log(f'📱{masked_phone} 用缓存登录啦~ ✨')
ticket = get_ticket(phone, load_token[phone]['userId'], load_token[phone]['token'])
if not ticket:
print_time_log(f'📱{masked_phone} 用密码登录啦~ 🔑')
ticket = userLoginNormal(phone, password)
if ticket:
tasks.append(ks(phone, ticket, uid))
else:
print_time_log(f'📱{masked_phone} 登录失败啦~ ❌')
continue
while wt > datetime.datetime.now().timestamp():
await asyncio.sleep(1)
await asyncio.gather(*tasks)
print_time_log(f"✅完成第 {i // batch_size + 1} 批账号处理~")
await asyncio.sleep(2)
START_LOG = rf'''
+--------------------------------------------------------------------+
| 🌸 欢迎使用 金豆兑换话费 ✨
+--------------------------------------------------------------------+
'''
if __name__ == "__main__":
print(START_LOG)
print(f"💌 提醒:程序会提前【{kswt} 秒】准备好哦~")
if len(sys.argv) > 1:
h = int(sys.argv[1])
else:
h = None
asyncio.run(main())
current_month = get_network_time().strftime("%Y%m")
try:
with open('电信金豆换话费.log', 'r') as fr:
dhjl = json.load(fr)
except FileNotFoundError:
dhjl = {}
dhjl2 = {}
if current_month in dhjl:
records = dhjl[current_month]
for fee, phones in records.items():
if isinstance(phones, list):
phone_list = phones
else:
phone_list = phones.strip('#').split('#')
for phone in phone_list:
if phone not in dhjl2:
dhjl2[phone] = {}
if current_month not in dhjl2[phone]:
dhjl2[phone][current_month] = []
dhjl2[phone][current_month].append(fee)
with open('电信金豆换话费2.log', 'w') as fw:
json.dump(dhjl2, fw, ensure_ascii=False, indent=4)
current_time = get_network_time()
start_time_1 = current_time.replace(hour=10, minute=0, second=30)
end_time_1 = current_time.replace(hour=10, minute=10, second=0)
start_time_2 = current_time.replace(hour=14, minute=0, second=30)
end_time_2 = current_time.replace(hour=14, minute=10, second=0)
if (start_time_1 <= current_time < end_time_1) or (start_time_2 <= current_time < end_time_2):
print("任务执行完成~")
else:
print("当前不在推送时间哦~")