commit 90a49e3c5a8ebb3ed92e6696288454131018b52f Author: Abhorrent_Anger Date: Thu Dec 14 12:47:40 2023 +0200 Broken Scrap.TF public raffle bot diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7a3094a --- /dev/null +++ b/LICENSE @@ -0,0 +1,11 @@ +DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE +Version 2, December 2004 + +Copyright (C) 2004 Sam Hocevar + +Everyone is permitted to copy and distribute verbatim or modified copies of this license document, and changing it is allowed as long as the name is changed. + +DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7d41f59 --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# ScrapTFRaffleBot + +Enters Public Raffles. Call as `python main.py `. + +Deprecated due to the site implementing Cloudflare's turnstile key. + +## Dependencies: +``` +pip install urllib2 +pip install termcolor +``` \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..592850b --- /dev/null +++ b/main.py @@ -0,0 +1,107 @@ +import urllib +import time +import sys +try: + from BeautifulSoup import BeautifulSoup +except ImportError: + from bs4 import BeautifulSoup +import re +from termcolor import colored + + +SCR_SESSION = '' +USER_ID = '' +SCRAPTF = '' +CF_CLEARANCE = '' +USERNAME = '' +BASE_URL = 'https://scrap.tf' +RAFFLE_URL = '/raffles/' +ENTER_RAFFLE_URL = '/ajax/viewraffle/EnterRaffle' + +def load_arguments(): + global SCRAPTF, CF_CLEARANCE, USERNAME + SCRAPTF = sys.argv[1] + CF_CLEARANCE = sys.argv[2] + USERNAME = sys.argv[3] + +def fetch_raw(url): + request = urllib.request.Request(url) + request = add_headers(request) + page = urllib.request.urlopen(request).read() + return page + +def post_raw(url, data): + request = urllib.request.Request(url, urllib.parse.urlencode(data).encode()) + request = add_headers(request) + page = urllib.request.urlopen(request) + return page + +def add_headers(request): + request.add_header("Cookie", 'scraptf=' + SCRAPTF + '; cf_clearance=' + CF_CLEARANCE) + request.add_header("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36") + return request + +def fetch(url): + html = fetch_raw(url) + return BeautifulSoup(html, 'lxml') + +def check_notifications(parsed_html): + notices = parsed_html.select('.user-notices-count')[0].text + if notices != '0': + print(colored('You have ' + notices + ' new notices!', 'red')) + +def unentered_raffles(): + parsed_html = fetch(BASE_URL + RAFFLE_URL) + raffles = parsed_html.select('#raffles-list .panel-raffle:not(.raffle-entered)') + raffle_list = [] + for element in raffles: + link_element = element.find('a') + relative_url = link_element.attrs['href'].replace(RAFFLE_URL, '') + if relative_url: + raffle_list.append(relative_url) + print(colored('There are ' + str(len(raffle_list)) + ' raffles to enter for ' + USERNAME + '...', 'blue')) + check_notifications(parsed_html) + return raffle_list + +def get_hash(parsed_html): + button = parsed_html.select('.btn.btn-embossed.btn-info.btn-lg:not(#raffle-enter):not([style*="display: none"])') + if not button: + print(colored('Didn\'t enter ' + parsed_html.find('title').text[:-19] + ' due to a missing enter button!', 'red')) + return False + onclick = button[0].attrs['onclick'] + quote_text = re.findall(r"'([^']*)'", onclick) + return quote_text[1] + +def get_csrf(parsed_html): + form = parsed_html.select('#logoutForm')[0] + input_element = form.find('input') + return input_element.attrs['value'] + +def enter_raffle(raffle): + parsed_html = fetch(BASE_URL + RAFFLE_URL + raffle) + password = get_hash(parsed_html) + if not password: + return 418 + # TODO: Somehow fetch the turnstile key, rendered client-side + turnstile = parsed_html.select('#turnstile-container input')[0].value + csrf = get_csrf(parsed_html) + data = {'raffle' : raffle, + 'captcha' : '', + 'hash' : password, + 'flag' : 'false', + 'turnstile_token' : turnstile, + 'csrf' : csrf} + result = post_raw(BASE_URL + ENTER_RAFFLE_URL, data) + if result.status == 200: + print(colored('Succesfully entered ' + parsed_html.find('title').text[:-19] + ' (' + raffle + ')!', 'green')) + time.sleep(5) + return result + +def enter_raffles(): + raffles = unentered_raffles() + for raffle in raffles: + enter_raffle(raffle) + +load_arguments() +enter_raffles() +