提高了bot用户体验
This commit is contained in:
@@ -21,4 +21,4 @@ echo ""
|
|||||||
echo "现在你可以运行:"
|
echo "现在你可以运行:"
|
||||||
echo " checker # 运行命令行工具"
|
echo " checker # 运行命令行工具"
|
||||||
echo " python -m checker # 或使用模块方式"
|
echo " python -m checker # 或使用模块方式"
|
||||||
echo " uv run python -m checker # 使用uv运行"
|
echo " uv run python -m checker.bot.main # 使用uv运行"
|
||||||
|
|||||||
@@ -27,34 +27,52 @@ async def start(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
|||||||
"1. <b>/chk</b> - 检测卡片\n"
|
"1. <b>/chk</b> - 检测卡片\n"
|
||||||
" <code>/chk cc|mm|yy|cvv</code>\n\n"
|
" <code>/chk cc|mm|yy|cvv</code>\n\n"
|
||||||
"2. <b>/gen</b> - 生成卡片\n"
|
"2. <b>/gen</b> - 生成卡片\n"
|
||||||
" <code>/gen 10 536737xxxx</code> (生成10张)\n"
|
" <code>/gen 536737xxxx</code> (默认10张)\n"
|
||||||
" <code>/gen 10 536737xxxx /chk</code> (生成并检测)"
|
" <code>/gen 20 536737xxxx</code> (生成20张)\n"
|
||||||
|
" <code>/gen 536737xxxx /chk</code> (生成并检测)"
|
||||||
)
|
)
|
||||||
|
|
||||||
async def gen_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
async def gen_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||||
"""响应 /gen 命令"""
|
"""响应 /gen 命令"""
|
||||||
# 格式: /gen <count> <pattern> [/chk]
|
# 格式: /gen [count] <pattern> [/chk]
|
||||||
if not context.args or len(context.args) < 2:
|
# 默认数量为 10
|
||||||
|
if not context.args or len(context.args) < 1:
|
||||||
await update.message.reply_html(
|
await update.message.reply_html(
|
||||||
"❌ <b>格式错误</b>\n\n"
|
"❌ <b>格式错误</b>\n\n"
|
||||||
"用法:\n"
|
"用法:\n"
|
||||||
"<code>/gen 10 536737xxxxxxxxxx</code>\n"
|
"<code>/gen 536737xxxxxxxxxx</code> (默认10张)\n"
|
||||||
"<code>/gen 10 536737xxxxxxxxxx /chk</code>"
|
"<code>/gen 20 536737xxxxxxxxxx</code> (指定数量)\n"
|
||||||
|
"<code>/gen 536737xxxxxxxxxx /chk</code> (生成并检测)"
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
# 智能解析参数
|
||||||
count = int(context.args[0])
|
count = 10 # 默认数量
|
||||||
pattern = context.args[1]
|
pattern = None
|
||||||
except ValueError:
|
|
||||||
await update.message.reply_text("❌ 数量必须是数字。")
|
|
||||||
return
|
|
||||||
|
|
||||||
# 检查是否有 /chk
|
|
||||||
do_check = False
|
do_check = False
|
||||||
if len(context.args) > 2 and '/chk' in context.args[2:]:
|
|
||||||
|
# 检查是否有 /chk 参数
|
||||||
|
args_without_chk = [arg for arg in context.args if arg != '/chk']
|
||||||
|
if '/chk' in context.args:
|
||||||
do_check = True
|
do_check = True
|
||||||
|
|
||||||
|
# 解析数量和模式
|
||||||
|
if len(args_without_chk) == 1:
|
||||||
|
# /gen <pattern>
|
||||||
|
pattern = args_without_chk[0]
|
||||||
|
elif len(args_without_chk) >= 2:
|
||||||
|
# 尝试第一个参数是否为数字
|
||||||
|
try:
|
||||||
|
count = int(args_without_chk[0])
|
||||||
|
pattern = args_without_chk[1]
|
||||||
|
except ValueError:
|
||||||
|
# 如果第一个参数不是数字,则当作模式,使用默认数量
|
||||||
|
pattern = args_without_chk[0]
|
||||||
|
|
||||||
|
if not pattern:
|
||||||
|
await update.message.reply_text("❌ 请提供卡片模式。")
|
||||||
|
return
|
||||||
|
|
||||||
# 限制生成数量
|
# 限制生成数量
|
||||||
if count > 1000:
|
if count > 1000:
|
||||||
await update.message.reply_text("❌ 一次最多生成 1000 张卡片。")
|
await update.message.reply_text("❌ 一次最多生成 1000 张卡片。")
|
||||||
@@ -143,7 +161,8 @@ async def process_input_text(update: Update, context: ContextTypes.DEFAULT_TYPE,
|
|||||||
"dead": 0,
|
"dead": 0,
|
||||||
"unknown": 0,
|
"unknown": 0,
|
||||||
"total": len(cards),
|
"total": len(cards),
|
||||||
"checked": 0
|
"checked": 0,
|
||||||
|
"results": [] # 存储所有检测结果
|
||||||
}
|
}
|
||||||
|
|
||||||
# 4. 创建并发任务
|
# 4. 创建并发任务
|
||||||
@@ -156,27 +175,35 @@ async def process_input_text(update: Update, context: ContextTypes.DEFAULT_TYPE,
|
|||||||
await asyncio.gather(*tasks)
|
await asyncio.gather(*tasks)
|
||||||
|
|
||||||
# 5. 最终报告
|
# 5. 最终报告
|
||||||
report = (
|
report_lines = [
|
||||||
f"<b>🏁 检测完成</b>\n\n"
|
f"<b>🏁 检测完成</b>\n",
|
||||||
f"Total: {stats['total']}\n"
|
f"Total: {stats['total']}",
|
||||||
f"Live: {stats['live']} ✅\n"
|
f"Live: {stats['live']} ✅",
|
||||||
f"Dead: {stats['dead']} ❌\n"
|
f"Dead: {stats['dead']} ❌",
|
||||||
f"Unknown: {stats['unknown']} ⚠️"
|
f"Unknown: {stats['unknown']} ⚠️\n"
|
||||||
)
|
]
|
||||||
|
|
||||||
|
# 添加所有卡片的详细结果
|
||||||
|
if stats['results']:
|
||||||
|
report_lines.append("<b>详细结果:</b>")
|
||||||
|
for result_info in stats['results']:
|
||||||
|
report_lines.append(result_info)
|
||||||
|
|
||||||
|
report = "\n".join(report_lines)
|
||||||
await status_msg.edit_text(report, parse_mode=ParseMode.HTML)
|
await status_msg.edit_text(report, parse_mode=ParseMode.HTML)
|
||||||
|
|
||||||
async def process_card(
|
async def process_card(
|
||||||
card: Card,
|
card: Card,
|
||||||
checker: StripeChecker,
|
checker: StripeChecker,
|
||||||
update: Update,
|
update: Update,
|
||||||
stats: dict
|
stats: dict
|
||||||
):
|
):
|
||||||
"""异步处理单张卡片"""
|
"""异步处理单张卡片"""
|
||||||
loop = asyncio.get_running_loop()
|
loop = asyncio.get_running_loop()
|
||||||
|
|
||||||
# 每个任务独立的 Session
|
# 每个任务独立的 Session
|
||||||
session = requests.Session()
|
session = requests.Session()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 在线程池中运行阻塞的检测逻辑
|
# 在线程池中运行阻塞的检测逻辑
|
||||||
result = await loop.run_in_executor(
|
result = await loop.run_in_executor(
|
||||||
@@ -186,20 +213,32 @@ async def process_card(
|
|||||||
session,
|
session,
|
||||||
None # 暂时不使用代理,后续可扩展
|
None # 暂时不使用代理,后续可扩展
|
||||||
)
|
)
|
||||||
|
|
||||||
stats["checked"] += 1
|
stats["checked"] += 1
|
||||||
|
|
||||||
|
# 格式化结果信息
|
||||||
|
card_info = f"<code>{card.formatted}</code>"
|
||||||
|
|
||||||
if result.status == CheckStatus.LIVE:
|
if result.status == CheckStatus.LIVE:
|
||||||
stats["live"] += 1
|
stats["live"] += 1
|
||||||
|
result_line = f"{card_info} - {result.message} ✅"
|
||||||
|
stats["results"].append(result_line)
|
||||||
await send_live_alert(update, result)
|
await send_live_alert(update, result)
|
||||||
elif result.status == CheckStatus.DEAD:
|
elif result.status == CheckStatus.DEAD:
|
||||||
stats["dead"] += 1
|
stats["dead"] += 1
|
||||||
|
result_line = f"{card_info} - {result.message} ❌"
|
||||||
|
stats["results"].append(result_line)
|
||||||
else:
|
else:
|
||||||
stats["unknown"] += 1
|
stats["unknown"] += 1
|
||||||
|
result_line = f"{card_info} - {result.message} ⚠️"
|
||||||
|
stats["results"].append(result_line)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error checking card {card.formatted}: {e}")
|
logger.error(f"Error checking card {card.formatted}: {e}")
|
||||||
stats["unknown"] += 1
|
stats["unknown"] += 1
|
||||||
|
card_info = f"<code>{card.formatted}</code>"
|
||||||
|
result_line = f"{card_info} - Error: {str(e)} ⚠️"
|
||||||
|
stats["results"].append(result_line)
|
||||||
finally:
|
finally:
|
||||||
session.close()
|
session.close()
|
||||||
|
|
||||||
|
|||||||
@@ -67,30 +67,52 @@ class CardGenerator:
|
|||||||
def parse_date_cvv(self, card_num: str, m_req: Optional[str], y_req: Optional[str], c_req: Optional[str]) -> Tuple[str, str, str]:
|
def parse_date_cvv(self, card_num: str, m_req: Optional[str], y_req: Optional[str], c_req: Optional[str]) -> Tuple[str, str, str]:
|
||||||
"""
|
"""
|
||||||
处理日期和CVV的占位符逻辑
|
处理日期和CVV的占位符逻辑
|
||||||
|
支持 (m), (y), (cvv), rnd 或任何非纯数字的值作为随机标记
|
||||||
"""
|
"""
|
||||||
# --- Month ---
|
# --- Month ---
|
||||||
if m_req in ['(m)', 'rnd', '', None]:
|
if self._is_random_placeholder(m_req):
|
||||||
month = str(random.randint(1, 12)).zfill(2)
|
month = str(random.randint(1, 12)).zfill(2)
|
||||||
else:
|
else:
|
||||||
month = m_req.strip()
|
month = m_req.strip()
|
||||||
|
|
||||||
# --- Year ---
|
# --- Year ---
|
||||||
if y_req in ['(y)', 'rnd', '', None]:
|
if self._is_random_placeholder(y_req):
|
||||||
year = str(self.current_year + random.randint(2, 5))
|
year = str(self.current_year + random.randint(2, 5))
|
||||||
else:
|
else:
|
||||||
year = y_req.strip()
|
year = y_req.strip()
|
||||||
|
|
||||||
# --- CVV ---
|
# --- CVV ---
|
||||||
if c_req in ['(cvv)', 'rnd', '', None]:
|
if self._is_random_placeholder(c_req):
|
||||||
if card_num.startswith(('34', '37')):
|
if card_num.startswith(('34', '37')):
|
||||||
cvv = str(random.randint(1102, 9999))
|
cvv = str(random.randint(1102, 9999))
|
||||||
else:
|
else:
|
||||||
cvv = str(random.randint(112, 999))
|
cvv = str(random.randint(112, 999))
|
||||||
else:
|
else:
|
||||||
cvv = c_req.strip()
|
cvv = c_req.strip()
|
||||||
|
|
||||||
return month, year, cvv
|
return month, year, cvv
|
||||||
|
|
||||||
|
def _is_random_placeholder(self, value: Optional[str]) -> bool:
|
||||||
|
"""
|
||||||
|
判断值是否为随机占位符
|
||||||
|
支持: None, '', '(m)', '(y)', '(cvv)', 'rnd', 或任何非纯数字的值(如 'xxx', 'abc' 等)
|
||||||
|
"""
|
||||||
|
if value is None or value.strip() == '':
|
||||||
|
return True
|
||||||
|
|
||||||
|
value = value.strip()
|
||||||
|
|
||||||
|
# 已知的占位符
|
||||||
|
known_placeholders = ['(m)', '(y)', '(cvv)', 'rnd']
|
||||||
|
if value in known_placeholders:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# 如果是非纯数字的字符串,视为占位符
|
||||||
|
if not value.isdigit():
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
def process_line(self, raw_input: str, count: int = 1) -> List[str]:
|
def process_line(self, raw_input: str, count: int = 1) -> List[str]:
|
||||||
"""
|
"""
|
||||||
生成指定数量的卡片
|
生成指定数量的卡片
|
||||||
|
|||||||
Reference in New Issue
Block a user