From 0a2c48424e30ef366824b8d7e166df4534da2e33 Mon Sep 17 00:00:00 2001 From: Walter Date: Sun, 9 Mar 2025 21:50:50 +0100 Subject: [PATCH] Initial commit --- .gitignore | 4 ++++ app.py | 11 ++++++++++ config_example.json | 8 ++++++++ methods/base.py | 43 +++++++++++++++++++++++++++++++++++++++ methods/economy_v1.py | 47 +++++++++++++++++++++++++++++++++++++++++++ requirements.txt | 3 +++ start.py | 7 +++++++ 7 files changed, 123 insertions(+) create mode 100644 .gitignore create mode 100644 app.py create mode 100644 config_example.json create mode 100644 methods/base.py create mode 100644 methods/economy_v1.py create mode 100644 requirements.txt create mode 100644 start.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0ded2d0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +config.json +.venv +venv +.idea \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..5a7bd1a --- /dev/null +++ b/app.py @@ -0,0 +1,11 @@ +import json + +from methods.economy_v1 import EconomyV1 + + +def run(): + with open("config.json") as f: + config = json.load(f) + + EconomyV1(roblosecurity=config["user"]["roblosecurity"], + asset_id=config["item"]["asset_id"]).buy() \ No newline at end of file diff --git a/config_example.json b/config_example.json new file mode 100644 index 0000000..a0f71f1 --- /dev/null +++ b/config_example.json @@ -0,0 +1,8 @@ +{ + "user": { + "roblosecurity": "" + }, + "item": { + "asset_id": 114702108643191 + } +} \ No newline at end of file diff --git a/methods/base.py b/methods/base.py new file mode 100644 index 0000000..b5ef978 --- /dev/null +++ b/methods/base.py @@ -0,0 +1,43 @@ +import logging +import time +import traceback + +import requests +from fake_useragent import UserAgent + + + +class Purchaser: + base_headers = { + "User-Agent": UserAgent().chrome + } + + def __init__(self, roblosecurity): + self.roblosecurity = roblosecurity + self.base_cookies = {".ROBLOSECURITY": self.roblosecurity} + self.logger = logging.getLogger(__name__) + + def request(self, url, method=requests.get, attempts=10, timeout=20, *args, **kwargs): + if "headers" not in kwargs: + kwargs["headers"] = {} + if "cookies" not in kwargs: + kwargs["cookies"] = {} + kwargs["headers"] = {**self.base_headers, **kwargs["headers"]} + kwargs["cookies"] = {**self.base_cookies, **kwargs["cookies"]} + + for attempt in range(attempts): + try: + r = method(url=url, timeout=timeout, *args, **kwargs) + if 500 > r.status_code > 600: + print(f"Statuscode {r.status_code} for {url}...") + time.sleep(5) + continue + return r + except requests.RequestException: + traceback.print_exc() + time.sleep(5) + + + def get_asset_metadata(self, asset_id): + return self.request(url=f"https://catalog.roblox.com/v1/catalog/items/{asset_id}/details", + params={"itemType": "asset"}).json() \ No newline at end of file diff --git a/methods/economy_v1.py b/methods/economy_v1.py new file mode 100644 index 0000000..f2c1d40 --- /dev/null +++ b/methods/economy_v1.py @@ -0,0 +1,47 @@ +import json + +import requests +from bs4 import BeautifulSoup + +from methods.base import Purchaser + + +class EconomyV1(Purchaser): + + def __init__(self, + asset_id: int, + *args, + **kwargs): + super().__init__(*args, **kwargs) + self.asset_id = asset_id + + def buy(self): + meta = self.get_asset_metadata(asset_id=self.asset_id) + item_type = meta["itemType"] + product_id = meta["productId"] + collectible_id = meta["collectibleItemId"] + + # TODO check if we need special handling for groups + creator_target_id = meta["creatorTargetId"] # UserID / ? + + url = f"https://www.roblox.com/{'bundles' if item_type == 'Bundle' else 'catalog'}/{self.asset_id}" + r = self.request(url=url) + + soup = BeautifulSoup(r.text, "html.parser") + csrf_token = soup.find("meta", {"name": "csrf-token"})["data-token"] + + r = self.request(url=f"https://economy.roblox.com/v1/purchases/products/{product_id}", + method=requests.post, + cookies=r.cookies, + headers={ + "x-csrf-token": csrf_token, + "Content-Type": "application/json; charset=utf-8", + }, + json={ + "expectedCurrency": 1, + "expectedPrice": 0, + "expectedSellerId": creator_target_id + }) + + data = r.json() + print(data, r.headers) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..729cc73 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,3 @@ +requests +bs4 +fake-useragent \ No newline at end of file diff --git a/start.py b/start.py new file mode 100644 index 0000000..27af431 --- /dev/null +++ b/start.py @@ -0,0 +1,7 @@ +import logging + +import app + +if __name__ == "__main__": + logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG) + app.run() \ No newline at end of file