File size: 5,379 Bytes
2aa4e5a
 
 
 
 
ca649b3
5c2fcfe
ca649b3
 
 
2aa4e5a
 
 
 
 
5c2fcfe
 
2aa4e5a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ca649b3
 
892834b
2aa4e5a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ca649b3
892834b
2aa4e5a
 
78891bd
 
 
 
 
 
 
 
 
 
 
 
 
a45d567
78891bd
 
ca649b3
78891bd
2aa4e5a
 
 
 
892834b
2aa4e5a
 
 
a45d567
 
 
 
 
 
 
 
 
 
 
 
 
2aa4e5a
 
5c2fcfe
2aa4e5a
410992d
5c2fcfe
410992d
2aa4e5a
5c2fcfe
 
 
 
 
 
 
 
a45d567
 
 
 
2aa4e5a
a45d567
 
5c2fcfe
a45d567
a57cd04
a45d567
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import aiohttp
import asyncio
import random
from dateutil import parser
import os
import logging
import time

# Disable all logging except for critical errors
logging.basicConfig(level=logging.CRITICAL)

discord_webhook_url = os.environ['webhook']
api_batch_url = "https://epic-alligator-77.deno.dev/post"
asset_info_url = "https://economy.roproxy.com/v2/assets/"

last_working_time = time.time()

async def send_to_discord(session, asset_id, name, creator_id, creator_name, creator_type, asset_type, created_date):
    embed = {
        "embeds": [
            {
                "url": f"https://www.roblox.com/library/{asset_id}",
                "title": name or "Unknown Asset",
                "thumbnail": {
                    "url": f"https://rbxgleaks.pythonanywhere.com/asset/{asset_id}",
                },
                "fields": [
                    {
                        "name": "Creator Type",
                        "value": creator_type or "Unknown",
                        "inline": True
                    },
                    {
                        "name": "Creator ID",
                        "value": creator_id or "Unknown",
                        "inline": True
                    }
                ],
                "description": f"**Asset Type:** {asset_type}\n**ID:** ||{asset_id}||\n**Creator:** [{creator_name}](https://www.roblox.com/users/{creator_id}/profile)\n**Created:** {created_date}"
            }
        ],
        "content": "",
    }

    try:
        async with session.post(discord_webhook_url, json=embed) as response:
            await response.text()
    except (aiohttp.ClientError, asyncio.TimeoutError, ConnectionError):
        pass

async def check_asset_batch(session, asset_ids):
    payload = [{"assetId": asset_id} for asset_id in asset_ids]

    try:
        async with session.post(api_batch_url, json=payload, headers={
            'Content-Type': 'application/json',
            'Requester': 'Client',
            'User-Agent': 'Roblox/WinInetRobloxApp'
        }) as response:
            if response.status == 200:
                results = await response.json()
                if not results or (isinstance(results, list) and all("errors" in result for result in results)):
                    return

                tasks = []
                for asset_id in asset_ids:
                    if any(result.get("assetId") == asset_id and not result.get("IsCopyrightProtected", True) for result in results):
                        tasks.append(fetch_asset_info(session, asset_id))

                await asyncio.gather(*tasks)
    except (aiohttp.ClientError, asyncio.TimeoutError, ConnectionError):
        pass

async def fetch_asset_info(session, asset_id):
    try:
        async with session.get(f"{asset_info_url}{asset_id}/details") as asset_info_response:
            if asset_info_response.status == 200:
                asset_info = await asset_info_response.json()

                name = asset_info.get("Name", "Unknown")
                asset_type = asset_info.get("AssetTypeId", "Unknown")
                creator = asset_info.get("Creator", {})
                creator_id = creator.get("Id", "Unknown")
                creator_name = creator.get("Name", "Unknown")
                creator_type = creator.get("CreatorType", "Unknown")
                created_date_str = asset_info.get("Created", "Unknown")
                created_date = parse_iso8601(created_date_str)
                created_date_formatted = created_date.strftime("%Y-%m-%d %H:%M:%S") if created_date else "Unknown"

                await send_to_discord(session, asset_id, name, creator_id, creator_name, creator_type, asset_type, created_date_formatted)
    except (aiohttp.ClientError, asyncio.TimeoutError, ConnectionError):
        pass

def parse_iso8601(date_str):
    try:
        return parser.isoparse(date_str)
    except ValueError:
        return None

def generate_ids_batch(digit, batch_size=10000):
    base = random.randint(70000000000000, 140000000000000)
    for i in range(batch_size):
        yield str(base + i)

async def run_scanner_instance(digit, semaphore):
    async with aiohttp.ClientSession() as session:
        while True:
            try:
                async with semaphore:
                    batch = list(generate_ids_batch(digit))
                    await check_asset_batch(session, batch)
            except (aiohttp.ClientError, asyncio.TimeoutError, ConnectionError):
                await asyncio.sleep(1)

async def print_status_periodically():
    global last_working_time
    while True:
        print("Working")
        last_working_time = time.time()
        await asyncio.sleep(60)

async def check_restart():
    global last_working_time
    while True:
        if time.time() - last_working_time > 180:  # 3 minutes
            print("Restarting due to inactivity")
            os._exit(1)  # Force restart
        await asyncio.sleep(10)

async def main():
    semaphore = asyncio.Semaphore(100)  # Limit concurrent tasks
    tasks = []
    for i in range(160000):  # 20000 instances per digit * 8 digits
        digit = 7 + (i % 8)
        tasks.append(run_scanner_instance(digit, semaphore))
    tasks.append(print_status_periodically())
    tasks.append(check_restart())
    await asyncio.gather(*tasks)

if __name__ == "__main__":
    asyncio.run(main())