This repository has been archived by the owner on Dec 16, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit b26ca1a
Showing
7 changed files
with
192 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
[ | ||
"avtr_621a3748-4ea7-4bc9-99e3-ed70784829d3", | ||
"avtr_798c17cd-6de5-43b8-8efb-91765eb93801", | ||
"avtr_a860b337-92ec-4c2a-aaf8-2055b6c5fe27", | ||
"avtr_671b0605-31bb-4285-9685-6ad34433585d", | ||
"avtr_12ff3caf-2a25-4b64-acc2-f02fc15be4ef", | ||
"avtr_475b6fe3-785b-44e2-9907-fa5c82f1efc4", | ||
"avtr_3bc018f9-cabe-41a8-906e-3d2d0ce67d77", | ||
"avtr_a0e9acc2-7ebb-4af2-a946-f7ab23b896fb", | ||
"avtr_c75e5055-f3ea-4785-bd47-64238c641dfc", | ||
"avtr_c18675a6-7646-43d6-9c32-3f27c85ce121", | ||
"avtr_f06823a6-85de-48da-81e3-65db84d1098e", | ||
"avtr_ff322e51-b954-4d27-8795-0d1b9ad7b47H", | ||
"avtr_6fd9452d-538e-4c8f-8c19-d799b577fca0", | ||
"avtr_be752824-1e1a-43b7-9b09-3152873616ab", | ||
"avtr_50f8c228-8ba7-444a-8c71-1f375c6dfa16", | ||
"avtr_d83be81e-c543-4263-8377-4c5b81a96996", | ||
"avtr_c6062f64-cbd9-4027-a52d-78b73dd6b367", | ||
"avtr_87aa8946-b086-440f-bcda-c4fddb03ae8d", | ||
"avtr_9e3e9944-b826-4c9d-9cc7-5bd7ac567cf1", | ||
"avtr_4bc338fe-8a6b-4abb-a5dc-ae3fd6835e55", | ||
"avtr_697038e6-b1ea-4d2f-8565-75bafed91fb3", | ||
"avtr_95c375f0-1696-4944-9730-647be0371800", | ||
"avtr_4afde5d4-ce00-454f-95e1-92cdce95f88f", | ||
"avtr_8bc748a4-a290-4ed6-93aa-90549d7efa31", | ||
"avtr_81e063ce-8df9-42d1-9012-b9b55b247048", | ||
"avtr_284441cd-4a6e-44c4-ae07-0046c88e4fbb", | ||
"avtr_7b49fd0d-d1d6-4b7d-9c4d-ba85777ce44e", | ||
"avtr_90e96c92-ea92-424e-b8f9-982d847ffd1a", | ||
"avtr_94a0e038-40e0-496f-b867-0bb16296fcb3", | ||
"avtr_2034b67a-e9d8-42e5-9f69-8b0cb3e61081", | ||
"avtr_447aa8bd-78c5-4f60-a026-6babec60bdbc", | ||
"avtr_94fc9b29-f2e1-4dc5-9420-4248d9349598", | ||
"avtr_658aa5c9-483e-4cda-be91-b4b22bfa9e33", | ||
"avtr_2292547b-1932-420d-8e99-3b454a0863b7", | ||
"avtr_5bfd100d-2ba4-4ee2-ae73-034e20465feb" | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import os | ||
import re | ||
import requests | ||
import concurrent.futures | ||
import webbrowser | ||
import colorama | ||
from watchdog.observers import Observer | ||
from watchdog.events import FileSystemEventHandler | ||
import asyncio | ||
import aiohttp | ||
import threading | ||
from concurrent.futures import ThreadPoolExecutor | ||
from .plugs.logger import * | ||
import json |
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
from core import * | ||
|
||
class logger: | ||
def __init__(self, prefix: str = "Vrc"): | ||
self.WHITE: str = "\u001b[37m" | ||
self.MAGENTA: str = "\033[38;5;97m" | ||
self.RED: str = "\033[38;5;196m" | ||
self.GREEN: str = "\033[38;5;40m" | ||
self.YELLOW: str = "\033[38;5;220m" | ||
self.BLUE: str = "\033[38;5;21m" | ||
self.PINK: str = "\033[38;5;176m" | ||
self.CYAN: str = "\033[96m" | ||
self.DARKBLUE = "\033[38;5;18m" | ||
self.LIGHTRED: str = "\033[38;5;203m" | ||
self.prefix: str = f"{self.LIGHTRED}[{self.RED}{prefix}{self.LIGHTRED}]" | ||
def message(self, level: str, message: str) -> str: | ||
return f" {self.prefix} {self.WHITE}| {self.LIGHTRED}[{level}{self.LIGHTRED}] {self.WHITE}-> {self.RED}[{self.RED}{message}{self.RED}]" | ||
|
||
def success(self, message: str, level: str = "Success"): | ||
print(self.message(f"{self.GREEN}{level}", f"{self.GREEN}{message}")) | ||
|
||
def warning(self, message: str, level: str = "Warning"): | ||
print(self.message(f"{self.YELLOW}{level}", f"{self.YELLOW}{message}")) | ||
|
||
def info(self, message: str, level: str = "Info"): | ||
print(self.message(f"{self.RED}{level}", f"{self.RED}{message}")) | ||
|
||
def failure(self, message: str, level: str = "Failure"): | ||
print(self.message(f"{self.RED}{level}", f"{self.RED}{message}")) | ||
|
||
def debug(self, message: str, level: str = "Debug"): | ||
print(self.message(f"{self.MAGENTA}{level}", f"{self.MAGENTA}{message}")) | ||
|
||
def scraper(self, message: str, level: str = "Scraper"): | ||
print(self.message(f"{self.BLUE}{level}", f"{self.BLUE}{message}"), end="\r", flush=True,) | ||
|
||
def captcha(self, message: str, level: str = "Captcha"): | ||
print(self.message(f"{self.CYAN}{level}", f"{self.CYAN}{message}")) | ||
|
||
def PETC(self): | ||
input(f" {self.LIGHTRED}[{self.RED}Press Enter To Continue{self.LIGHTRED}]") | ||
def ask(self, message: str, level: str = "Ask"): | ||
ask = input(f" {self.LIGHTRED}[{self.RED}{message}{self.LIGHTRED}]{self.RED} -> ") | ||
return ask | ||
|
||
|
||
|
||
|
||
log = logger() |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
from core import * | ||
|
||
def parse_avatar_ids_from_cache(cache_dir, output_file): | ||
avatar_ids = load_existing_avatar_ids(output_file) | ||
|
||
try: | ||
for directory in os.listdir(cache_dir): | ||
if os.path.isdir(os.path.join(cache_dir, directory)): | ||
for subdirectory in os.listdir(os.path.join(cache_dir, directory)): | ||
if os.path.isdir(os.path.join(cache_dir, directory, subdirectory)): | ||
data_file_path = os.path.join( | ||
cache_dir, directory, subdirectory, '__data') | ||
try: | ||
with open(data_file_path, 'r', encoding='utf-8', errors='ignore') as file: | ||
file_content = file.read() | ||
matches = re.findall( | ||
r'avtr_\w{8}-\w{4}-\w{4}-\w{4}-\w{12}', file_content) | ||
for avatar_id in matches: | ||
if avatar_id not in avatar_ids: | ||
log.debug(f"[Found avatar ID: {avatar_id}]") | ||
avatar_ids.append(avatar_id) | ||
save_avatar_ids(avatar_ids, output_file) | ||
else: | ||
log.debug(f"[Duplicate avatar ID: {avatar_id}]") | ||
break | ||
|
||
except Exception as e: | ||
log.failure(f"Error reading {data_file_path}: {str(e)}") | ||
except Exception as e: | ||
raise ValueError(f"Error reading cache directory {cache_dir}: {str(e)}") | ||
|
||
return avatar_ids | ||
|
||
def get_avatar_data(avatar_id): | ||
res = requests.get(f"https://api.vrchat.cloud/api/1/avatars/{avatar_id}", headers={ | ||
"X-Unity-Version": "2019.4.40f1", | ||
"X-Platform": "standalonewindows", | ||
"Accept": "*/*", | ||
"user-agent": "UnityPlayer/2022.3.6f1-DWR (UnityWebRequest/1.0, libcurl/7.80.0-DEV)", | ||
}) | ||
if res.status_code == 429: | ||
log.failure(f"Failed to get avatar data for avatar ID {avatar_id}: Rate limited") | ||
elif res.status_code == 404: | ||
log.failure(f"Avatar ID {avatar_id} not found") | ||
else: | ||
return res.json() if res.status_code == 200 else None | ||
|
||
def load_existing_avatar_ids(file_path): | ||
if os.path.exists(file_path): | ||
with open(file_path, 'r') as json_file: | ||
return json.load(json_file) | ||
return [] | ||
|
||
def save_avatar_ids(avatar_ids, file_path='avatar_ids.json'): | ||
with open(file_path, 'w') as json_file: | ||
json.dump(avatar_ids, json_file, indent=4) | ||
|
||
def save_avatar_data(avatar_data_list, file_path='avatar_data.json'): | ||
with open(file_path, 'w') as json_file: | ||
json.dump(avatar_data_list, json_file, indent=4) | ||
|
||
def main(): | ||
colorama.init() | ||
pc_user = os.getlogin() | ||
cache_dir = f'C:/Users/{pc_user}/AppData/LocalLow/VRChat/VRChat/Cache-WindowsPlayer' | ||
avatar_ids_file = 'avatar_ids.json' | ||
avatar_ids = [] | ||
|
||
with concurrent.futures.ThreadPoolExecutor() as executor: | ||
futures = [executor.submit(parse_avatar_ids_from_cache, cache_dir, avatar_ids_file)] | ||
for future in concurrent.futures.as_completed(futures): | ||
avatar_ids.extend(future.result()) | ||
|
||
if not avatar_ids: | ||
log.failure("No avatar IDs found.") | ||
return | ||
|
||
avatar_data_list = [] | ||
|
||
with concurrent.futures.ThreadPoolExecutor() as executor: | ||
futures = {executor.submit(get_avatar_data, avatar_id): avatar_id for avatar_id in avatar_ids} | ||
for future in concurrent.futures.as_completed(futures): | ||
avatar_data = future.result() | ||
if avatar_data: | ||
avatar_data_list.append(avatar_data) | ||
|
||
save_avatar_data(avatar_data_list) | ||
log.info(f"Total Avatars Retrieved: {len(avatar_data_list)}") | ||
log.ask("Press Enter To Exit") | ||
|
||
if __name__ == "__main__": | ||
main() |