Pastefi mark
Main.py
/6bd9af30
Paste view
NONE PUBLIC 37 views
6bd9af30
2025-12-24 08:19:22
import requests
import os
from datetime import datetime
from typing import Dict, List, Optional, Tuple
from colorama import init, Fore, Style
from concurrent.futures import ThreadPoolExecutor, as_completed
import threading

init(autoreset=True)

OUTPUT_FOLDER = "output"

TARGET_QUEST_IDS = {
    "1448436561082585220",
    "1448423146049896448",
}

print_lock = threading.Lock()
file_locks = {}

def create_output_folders():
    """Create output folder with timestamp subdirectory"""
    os.makedirs(OUTPUT_FOLDER, exist_ok=True)

def get_file_lock(path: str):
    if path not in file_locks:
        file_locks[path] = threading.Lock()
    return file_locks[path]

def parse_token_line(line: str) -> Optional[Tuple[str, str]]:
    line = line.strip()
    if not line or line.startswith('#'):
        return None
    
    parts = line.split(':')
    
    if len(parts) == 1:
        return (parts[0], parts[0])
    
    if len(parts) >= 3:
        return (line, parts[-1])
    
    return None

def load_tokens(filename: str = "token.txt") -> List[Tuple[str, str]]:
    tokens = []
    try:
        with open(filename, 'r', encoding='utf-8') as f:
            for line in f:
                result = parse_token_line(line)
                if result:
                    tokens.append(result)
        return tokens
    except FileNotFoundError:
        with print_lock:
            print(f"{Fore.RED}ERROR • token.txt not found!")
        return []
    except Exception as e:
        with print_lock:
            print(f"{Fore.RED}ERROR • Failed to read token.txt: {e}")
        return []

def load_proxies(filename: str = "proxy.txt") -> List[str]:
    proxies = []
    try:
        with open(filename, 'r', encoding='utf-8') as f:
            for line in f:
                line = line.strip()
                if line and not line.startswith('#'):
                    proxies.append(line)
        return proxies
    except FileNotFoundError:
        return []
    except Exception as e:
        with print_lock:
            print(f"{Fore.YELLOW}WARNING • Failed to read proxy.txt: {e}")
        return []

def format_proxy(proxy: str) -> Dict:
    if '://' not in proxy:
        proxy = f'http://{proxy}'
    return {
        'http': proxy,
        'https': proxy
    }

def get_all_quests(token: str, proxy: Optional[str] = None) -> Dict:
    url = "https://discord.com/api/v9/quests/@me"
    
    headers = {
        "accept": "*/*",
        "accept-language": "en-US,en;q=0.9",
        "authorization": token,
        "priority": "u=1, i",
        "sec-ch-ua": "\"Microsoft Edge\";v=\"143\", \"Chromium\";v=\"143\", \"Not A(Brand\";v=\"24\"",
        "sec-ch-ua-mobile": "?0",
        "sec-ch-ua-platform": "\"Windows\"",
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "same-origin",
        "x-debug-options": "bugReporterEnabled",
        "x-discord-locale": "en-US",
        "x-discord-timezone": "Asia/Calcutta",
        "x-super-properties": "eyJvcyI6IldpbmRvd3MiLCJicm93c2VyIjoiQ2hyb21lIiwiZGV2aWNlIjoiIiwic3lzdGVtX2xvY2FsZSI6ImVuLVVTIiwiaGFzX2NsaWVudF9tb2RzIjpmYWxzZSwiYnJvd3Nlcl91c2VyX2FnZW50IjoiTW96aWxsYS81LjAgKFdpbmRvd3MgTlQgMTAuMDsgV2luNjQ7IHg2NCkgQXBwbGVXZWJLaXQvNTM3LjM2IChLSFRNTCwgbGlrZSBHZWNrbykgQ2hyb21lLzE0My4wLjAuMCBTYWZhcmkvNTM3LjM2IEVkZy8xNDMuMC4wLjAiLCJicm93c2VyX3ZlcnNpb24iOiIxNDMuMC4wLjAiLCJvc192ZXJzaW9uIjoiMTAiLCJyZWZlcnJlciI6IiIsInJlZmVycmluZ19kb21haW4iOiIiLCJyZWZlcnJlcl9jdXJyZW50IjoiIiwicmVmZXJyaW5nX2RvbWFpbl9jdXJyZW50IjoiIiwicmVsZWFzZV9jaGFubmVsIjoic3RhYmxlIiwiY2xpZW50X2J1aWxkX251bWJlciI6NDgyMjg1LCJjbGllbnRfZXZlbnRfc291cmNlIjpudWxsfQ==",
        "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36 Edg/143.0.0.0"
    }
    
    proxies = format_proxy(proxy) if proxy else None
    
    try:
        response = requests.get(url, headers=headers, proxies=proxies, timeout=30)
        
        if response.status_code == 200:
            data = response.json()
            if isinstance(data, list):
                return {"success": True, "data": data}
            elif isinstance(data, dict) and "quests" in data:
                return {"success": True, "data": data["quests"]}
            else:
                return {"success": True, "data": []}
        elif response.status_code == 401:
            return {"success": False, "error": "Invalid token"}
        elif response.status_code == 403:
            return {"success": False, "error": "Quest Not visible"}
        elif response.status_code == 404:
            return {"success": False, "error": "Endpoint not found"}
        else:
            return {"success": False, "error": f"HTTP {response.status_code}"}
    except Exception as e:
        return {"success": False, "error": str(e)}

def save_token_to_file(full_line: str, filename: str, output_dir: str):
    """Save token to a specific file in the output directory"""
    filepath = os.path.join(output_dir, filename)
    
    lock = get_file_lock(filepath)
    with lock:
        with open(filepath, 'a', encoding='utf-8') as f:
            f.write(f"{full_line}\n")

def check_specific_quests(full_line: str, token: str, proxy: Optional[str] = None, output_dir: str = None):
    time_now = datetime.now().strftime("%H:%M:%S")
    masked_token = f"{token[:30]}..."
    
    result = get_all_quests(token, proxy)
    
    if not result.get("success"):
        with print_lock:
            print(f"[{time_now}] {Fore.RED}FAILED{Style.RESET_ALL}  •  TOKEN [{Fore.CYAN}{masked_token}{Style.RESET_ALL}] | ERROR: {result.get('error')}")
        save_token_to_file(full_line, "failed.txt", output_dir)
        return
    
    quests = result.get("data", [])
    
    if not quests:
        with print_lock:
            print(f"[{time_now}] {Fore.RED}NO QUESTS{Style.RESET_ALL}  •  TOKEN [{Fore.CYAN}{masked_token}{Style.RESET_ALL}] | NO QUESTS FOUND")
        save_token_to_file(full_line, "noquest.txt", output_dir)
        return
    
    # Store quest statuses
    quest_statuses = {}
    
    for quest_id in TARGET_QUEST_IDS:
        quest = None
        for q in quests:
            if q.get("id") == quest_id:
                quest = q
                break
        
        if quest:
            user_status = quest.get("user_status", {})
            quest_statuses[quest_id] = {
                "visible": True,
                "enrolled": bool(user_status.get("enrolled_at")),
                "completed": bool(user_status.get("completed_at")),
                "claimed": bool(user_status.get("claimed_at"))
            }
        else:
            quest_statuses[quest_id] = {
                "visible": False,
                "enrolled": False,
                "completed": False,
                "claimed": False
            }
    
    quest_ids = list(TARGET_QUEST_IDS)
    q1_status = quest_statuses[quest_ids[0]]
    q2_status = quest_statuses[quest_ids[1]]
    
    # Determine output file based on quest statuses
    filename = None
    status_color = Fore.GREEN
    status_text = "SUCCESS"
    
    # Both claimed
    if q1_status["claimed"] and q2_status["claimed"]:
        filename = "bothclaimed.txt"
        status_color = Fore.YELLOW
        status_text = "CLAIMED"
    # Both completed but not claimed (BEST)
    elif q1_status["completed"] and not q1_status["claimed"] and q2_status["completed"] and not q2_status["claimed"]:
        filename = "bothcompleted_notclaimed.txt"
        status_color = Fore.GREEN
        status_text = "BEST"
    # Only first quest completed not claimed
    elif q1_status["completed"] and not q1_status["claimed"] and not (q2_status["completed"] and not q2_status["claimed"]):
        filename = f"{quest_ids[0]}_completed_notclaimed.txt"
        status_color = Fore.GREEN
        status_text = "PARTIAL"
    # Only second quest completed not claimed
    elif q2_status["completed"] and not q2_status["claimed"] and not (q1_status["completed"] and not q1_status["claimed"]):
        filename = f"{quest_ids[1]}_completed_notclaimed.txt"
        status_color = Fore.GREEN
        status_text = "PARTIAL"
    # Both enrolled but not completed
    elif q1_status["enrolled"] and not q1_status["completed"] and q2_status["enrolled"] and not q2_status["completed"]:
        filename = "bothenrolled_notcompleted.txt"
        status_color = Fore.YELLOW
        status_text = "ENROLLED"
    # Only first quest enrolled not completed
    elif q1_status["enrolled"] and not q1_status["completed"] and not (q2_status["enrolled"] and not q2_status["completed"]):
        filename = f"{quest_ids[0]}_enrolled_notcompleted.txt"
        status_color = Fore.YELLOW
        status_text = "ENROLLED"
    # Only second quest enrolled not completed
    elif q2_status["enrolled"] and not q2_status["completed"] and not (q1_status["enrolled"] and not q1_status["completed"]):
        filename = f"{quest_ids[1]}_enrolled_notcompleted.txt"
        status_color = Fore.YELLOW
        status_text = "ENROLLED"
    # Both visible but not started
    elif q1_status["visible"] and not q1_status["enrolled"] and q2_status["visible"] and not q2_status["enrolled"]:
        filename = "bothvisible_notstarted.txt"
        status_color = Fore.CYAN
        status_text = "VISIBLE"
    # Only first quest visible
    elif q1_status["visible"] and not q2_status["visible"]:
        filename = f"{quest_ids[0]}_visible.txt"
        status_color = Fore.CYAN
        status_text = "VISIBLE"
    # Only second quest visible
    elif q2_status["visible"] and not q1_status["visible"]:
        filename = f"{quest_ids[1]}_visible.txt"
        status_color = Fore.CYAN
        status_text = "VISIBLE"
    # No quests found
    else:
        filename = "noquest.txt"
        status_color = Fore.RED
        status_text = "NO QUEST"
    
    # Build status line
    q1_visible = "✓" if q1_status["visible"] else "✗"
    q1_enrolled = "E" if q1_status["enrolled"] else "-"
    q1_completed = "C" if q1_status["completed"] else "-"
    q1_claimed = "X" if q1_status["claimed"] else "-"
    
    q2_visible = "✓" if q2_status["visible"] else "✗"
    q2_enrolled = "E" if q2_status["enrolled"] else "-"
    q2_completed = "C" if q2_status["completed"] else "-"
    q2_claimed = "X" if q2_status["claimed"] else "-"
    
    status_line = (f"[{time_now}] {status_color}{status_text}{Style.RESET_ALL}  •  "
                   f"TOKEN [{Fore.CYAN}{masked_token}{Style.RESET_ALL}] | "
                   f"Q1[{q1_visible}{q1_enrolled}{q1_completed}{q1_claimed}] Q2[{q2_visible}{q2_enrolled}{q2_completed}{q2_claimed}] → {filename}")
    
    with print_lock:
        print(status_line)
    
    save_token_to_file(full_line, filename, output_dir)

if __name__ == "__main__":
    create_output_folders()
    
    try:
        threads = int(input(f"{Fore.YELLOW}Enter number of threads (default 5): {Style.RESET_ALL}") or "5")
        if threads < 1:
            threads = 5
    except ValueError:
        threads = 5
    
    print(f"\n{Fore.GREEN}✓ Using {threads} threads{Style.RESET_ALL}\n")
    
    tokens = load_tokens("token.txt")
    proxies = load_proxies("proxy.txt")
    
    if proxies:
        print(f"{Fore.GREEN}✓ Loaded {len(proxies)} proxies{Style.RESET_ALL}\n")
    else:
        print(f"{Fore.YELLOW}⚠ No proxies found, using direct connection{Style.RESET_ALL}\n")
    
    if not tokens:
        print(f"{Fore.RED}ERROR • No valid tokens found in token.txt")
    else:
        print(f"{Fore.GREEN}✓ Loaded {len(tokens)} tokens{Style.RESET_ALL}\n")
        
        # Create timestamped output directory
        timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
        output_dir = os.path.join(OUTPUT_FOLDER, timestamp)
        os.makedirs(output_dir, exist_ok=True)
        
        print(f"{Fore.CYAN}Output directory: {output_dir}{Style.RESET_ALL}\n")
        
        with ThreadPoolExecutor(max_workers=threads) as executor:
            futures = []
            for i, (full_line, token) in enumerate(tokens):
                proxy = proxies[i % len(proxies)] if proxies else None
                future = executor.submit(check_specific_quests, full_line, token, proxy, output_dir)
                futures.append(future)
            
            for future in as_completed(futures):
                try:
                    future.result()
                except Exception as e:
                    print(f"{Fore.RED}ERROR • Thread exception: {e}{Style.RESET_ALL}")
        
        print(f"\n{Fore.CYAN}{'=' * 80}{Style.RESET_ALL}")
        print(f"{Fore.GREEN}✓ All tokens processed and saved to: {output_dir}{Style.RESET_ALL}")
        print(f"{Fore.CYAN}{'=' * 80}{Style.RESET_ALL}\n")

Comments (0)

Log in to leave a comment.

No comments yet.