Collect authenticated Qinglong scripts batch

This commit is contained in:
Hermes Agent
2026-05-24 03:53:42 +00:00
parent 0d80b33d25
commit 28d62fef03
86 changed files with 18420 additions and 5 deletions

View File

@@ -0,0 +1,353 @@
# Source: https://github.com/Small-tailqwq/ql_script/blob/master/kuro/ql_kuro.py
# Raw: https://raw.githubusercontent.com/Small-tailqwq/ql_script/master/kuro/ql_kuro.py
# Repo: Small-tailqwq/ql_script
# Path: kuro/ql_kuro.py
# UploadedAt: 2026-05-23T15:50:58Z
# SHA256: 46013225510794598730a4bad8387ebfbcee626a372ce9a1e605ff7acbf18bac
# Category: web版/抓包
# Evidence: web/H5关键词 + cookie/token/header
# -*- coding: utf-8 -*-
"""
cron: 30 8 * * *
new Env('库街区自动签到');
基于 mxyooR/Kuro-autosignin (GPL-3.0) 精简适配青龙单文件版
上游版本: a334796 (2026-04-21)
最后更新: 2026-05-23 09:00 (UTC+8)
"""
import datetime
import json
import logging
import os
import random
import socket
import time
import uuid
from typing import Dict, List, Optional
import requests
try:
from sendNotify import send
except Exception:
try:
from notify import send
except Exception:
send = None
TIMEOUT = 30
GAME_WUWA_ID = "3"
GAME_PGR_ID = "2"
SERVER_WUWA = "76402e5b20be2c39f095a152090afddc"
SERVER_PGR = "1000"
MAX_RETRIES = 3
class API:
USER_MINE = "https://api.kurobbs.com/user/mineV2"
USER_SIGN_IN = "https://api.kurobbs.com/user/signIn"
USER_ROLE_LIST = "https://api.kurobbs.com/user/role/findRoleList"
FORUM_LIST = "https://api.kurobbs.com/forum/list"
FORUM_POST_DETAIL = "https://api.kurobbs.com/forum/getPostDetail"
FORUM_LIKE = "https://api.kurobbs.com/forum/like"
TASK_PROCESS = "https://api.kurobbs.com/encourage/level/getTaskProcess"
TASK_SHARE = "https://api.kurobbs.com/encourage/level/shareTask"
GAME_SIGN_IN = "https://api.kurobbs.com/encourage/signIn/v2"
GAME_SIGN_RECORD = "https://api.kurobbs.com/encourage/signIn/queryRecordV2"
def get_ip_address() -> str:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
s.connect(("8.8.8.8", 80))
return s.getsockname()[0]
except socket.error:
return "127.0.0.1"
finally:
s.close()
class KuroSigner:
def __init__(self, token_data: Dict[str, str]):
self.token = token_data['token']
self.note = token_data.get('note', '未命名账号')
self.ip = get_ip_address()
self.devcode = str(uuid.uuid4())
self.distinct_id = str(uuid.uuid4())
self.session = requests.Session()
self.user_id = None
self.wuwa_role_id = None
self.pgr_role_id = None
self.messages = []
self.success = True
def _log(self, msg: str):
logging.info(f"[{self.note}] {msg}")
self.messages.append(msg)
def _req(self, url: str, method: str = 'POST', data: Optional[dict] = None, req_type: str = 'bbs') -> dict:
headers = {
"Accept": "*/*",
"Accept-Language": "zh-CN,zh-Hans;q=0.9",
"Accept-Encoding": "gzip, deflate, br",
"Connection": "keep-alive",
"Host": "api.kurobbs.com",
"source": "ios",
}
if req_type == 'bbs':
headers.update({
"lang": "zh-Hans",
"User-Agent": "KuroGameBox/48 CFNetwork/1492.0.1 Darwin/23.3.0",
"channelId": "1",
"channel": "appstore",
"version": "2.2.0",
"model": "iPhone15,2",
"osVersion": "17.3",
"Content-Type": "application/x-www-form-urlencoded; charset=utf-8",
"Cookie": f"user_token={self.token}",
"Ip": self.ip,
"distinct_id": self.distinct_id,
"devCode": self.devcode,
"token": self.token,
})
elif req_type == 'game':
headers.update({
"Accept": "application/json, text/plain, */*",
"Sec-Fetch-Site": "same-site",
"source": "ios",
"Sec-Fetch-Mode": "cors",
"Origin": "https://web-static.kurobbs.com",
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 17_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) KuroGameBox/2.2.0",
"devCode": f"{self.ip}, Mozilla/5.0 (iPhone; CPU iPhone OS 17_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) KuroGameBox/2.2.0",
"token": self.token,
})
elif req_type == 'user_info':
headers.update({
"osversion": "Android",
"countrycode": "CN",
"ip": self.ip,
"model": "2211133C",
"source": "android",
"lang": "zh-Hans",
"version": "1.0.9",
"versioncode": "1090",
"content-type": "application/x-www-form-urlencoded",
"user-agent": "okhttp/3.10.0",
"devcode": self.devcode,
"distinct_id": self.distinct_id,
"token": self.token,
})
try:
if method == 'POST':
resp = self.session.post(url, headers=headers, data=data, timeout=TIMEOUT).json()
else:
resp = self.session.get(url, headers=headers, timeout=TIMEOUT).json()
return resp
except Exception as e:
return {"code": -1, "msg": f"请求异常: {str(e)}"}
def init_user_data(self) -> bool:
res = self._req(API.USER_MINE, req_type='user_info')
if res.get('code') != 200:
self._log(f"获取用户信息失败或Token已过期: {res.get('msg')}")
self.success = False
return False
self.user_id = res['data']['mine']['userId']
res_wuwa = self._req(API.USER_ROLE_LIST, data={"gameId": GAME_WUWA_ID}, req_type='user_info')
if res_wuwa.get('code') == 200 and res_wuwa.get('data'):
self.wuwa_role_id = res_wuwa['data'][0].get('roleId')
res_pgr = self._req(API.USER_ROLE_LIST, data={"gameId": GAME_PGR_ID}, req_type='user_info')
if res_pgr.get('code') == 200 and res_pgr.get('data'):
self.pgr_role_id = res_pgr['data'][0].get('roleId')
return True
def _get_sign_reward(self, game_name: str, game_id: str, server_id: str, role_id: str) -> Optional[str]:
try:
data = {
"gameId": game_id,
"serverId": server_id,
"roleId": role_id,
"userId": self.user_id,
}
res = self._req(API.GAME_SIGN_RECORD, data=data, req_type='game')
if res.get('code') == 200 and res.get('data'):
if isinstance(res['data'], list) and len(res['data']) > 0:
return res['data'][0].get('goodsName')
return None
except Exception:
return None
def game_sign(self):
month = datetime.datetime.now().strftime("%m")
def _do_sign(game_name, game_id, server_id, role_id):
if not role_id:
self._log(f"[{game_name}] 未找到角色ID跳过签到")
return
data = {
"gameId": game_id,
"serverId": server_id,
"roleId": role_id,
"userId": self.user_id,
"reqMonth": month,
}
res = self._req(API.GAME_SIGN_IN, data=data, req_type='game')
code = res.get('code')
if code == 200:
reward = self._get_sign_reward(game_name, game_id, server_id, role_id)
msg = f"[{game_name}] 签到成功"
if reward:
msg += f",奖励: {reward}"
self._log(msg)
elif code == 1511:
reward = self._get_sign_reward(game_name, game_id, server_id, role_id)
msg = f"[{game_name}] 今日已签到"
if reward:
msg += f",奖励: {reward}"
self._log(msg)
elif code == 1513:
self._log(f"[{game_name}] 签到失败:用户信息异常,即将禁用该账号")
self.success = False
elif code == 220:
self._log(f"[{game_name}] 签到失败:登录已过期,请重新登录")
self.success = False
else:
self._log(f"[{game_name}] 签到失败: {res.get('msg', '未知错误')} (code={code})")
raise Exception(f"{game_name} 签到失败: {res.get('msg', '未知错误')}")
_do_sign("鸣潮", GAME_WUWA_ID, SERVER_WUWA, self.wuwa_role_id)
time.sleep(1)
_do_sign("战双", GAME_PGR_ID, SERVER_PGR, self.pgr_role_id)
def forum_tasks(self):
res = self._req(API.USER_SIGN_IN, data={"gameId": "2"}, req_type='bbs')
if res.get('code') == 200:
self._log("论坛签到成功")
time.sleep(1)
res_tasks = self._req(API.TASK_PROCESS, data={"gameId": "0"}, req_type='bbs')
if res_tasks.get('code') != 200:
self._log("获取每日任务列表失败跳过")
return
tasks = res_tasks.get('data', {}).get('dailyTask', [])
tasks_map = {t.get('remark'): t.get('process') for t in tasks}
posts = []
if tasks_map.get("浏览3篇帖子", 1) == 0 or tasks_map.get("点赞5次", 1) == 0:
res_posts = self._req(API.FORUM_LIST, data={"forumId": "9", "gameId": "3", "pageIndex": "1", "pageSize": "20", "searchType": "3", "timeType": "0"}, req_type='bbs')
if res_posts.get('code') == 200:
posts = res_posts.get('data', {}).get('postList', [])
if tasks_map.get("浏览3篇帖子", 1) == 0 and posts:
view_count = 0
for p in posts[:3]:
self._req(API.FORUM_POST_DETAIL, data={"isOnlyPublisher": "0", "postId": p['postId'], "showOrderTyper": "2"}, req_type='bbs')
view_count += 1
time.sleep(random.uniform(1, 2))
self._log(f"完成浏览帖子任务 ({view_count}/3)")
if tasks_map.get("点赞5次", 1) == 0 and posts:
like_count = 0
for p in posts[:5]:
self._req(API.FORUM_LIKE, data={"forumId": 11, "gameId": 3, "likeType": 1, "operateType": 1, "postCommentId": "", "postCommentReplyId": "", "postId": p['postId'], "postType": 1, "toUserId": p['userId']}, req_type='bbs')
like_count += 1
time.sleep(random.uniform(1, 2))
self._log(f"完成点赞帖子任务 ({like_count}/5)")
if tasks_map.get("分享1次帖子", 1) == 0:
self._req(API.TASK_SHARE, data={"gameId": 3}, req_type='bbs')
self._log("完成分享帖子任务 (1/1)")
def run(self):
for attempt in range(MAX_RETRIES):
try:
if attempt > 0:
delay = random.uniform(5, 15)
self._log(f"将在 {delay:.1f} 秒后进行第 {attempt + 1}/{MAX_RETRIES} 次重试...")
time.sleep(delay)
if self.init_user_data():
self.game_sign()
self.forum_tasks()
if not self.success:
raise Exception("签到执行失败")
break
except Exception as e:
self._log(f"执行异常: {str(e)}")
self.success = False
if attempt < MAX_RETRIES - 1:
continue
else:
self._log(f"重试 {MAX_RETRIES} 次后仍然失败,放弃签到")
return "\n".join(self.messages)
def get_tokens() -> List[Dict[str, str]]:
raw = os.environ.get("KURO_TOKEN", "").strip()
if not raw:
return []
raw = raw.replace('&', '\n').replace(',', '\n')
token_list = []
for line in raw.split('\n'):
line = line.strip()
if not line:
continue
parts = line.split('#', 1)
token_val = parts[0].strip()
note = parts[1].strip() if len(parts) > 1 else f"账号{len(token_list) + 1}"
if token_val:
token_list.append({'token': token_val, 'note': note})
return token_list
def main():
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(message)s')
tokens = get_tokens()
if not tokens:
logging.error("未找到 Token请在环境变量中设置 'KURO_TOKEN'")
return
logging.info(f"✅ 检测到 {len(tokens)} 个账号,开始执行库街区签到...\n" + "-" * 30)
notify_content = []
for token_data in tokens:
signer = KuroSigner(token_data)
result_msg = signer.run()
status_icon = "" if signer.success else ""
header = f"{signer.note}{status_icon}"
notify_content.append(header)
notify_content.append(result_msg)
notify_content.append("-" * 20)
final_content = "\n".join(notify_content)
logging.info(f"\n{final_content}")
if send:
send("库街区签到", final_content)
if __name__ == '__main__':
main()