├── Blooket Hack GUI.py ├── README.md └── chromedriver.exe /Blooket Hack GUI.py: -------------------------------------------------------------------------------- 1 | # Imports necessary packages 2 | try: 3 | import requests,json,sys,math,os,time 4 | import PySimpleGUI as sg 5 | from colorama import init, Fore, Back, Style 6 | from selenium.webdriver.common.keys import Keys 7 | from seleniumwire import webdriver 8 | except Exception: 9 | import os 10 | print("Installing required packages") 11 | os.system("pip install requests") 12 | os.system("pip install PySimpleGUI") 13 | os.system("pip install selenium") 14 | os.system("pip install selenium-wire") 15 | os.system("pip install colorama") 16 | os.system("pip install webdriver-manager") 17 | import requests,json 18 | import PySimpleGUI as sg 19 | from colorama import init, Fore, Back, Style 20 | from selenium.webdriver.common.keys import Keys 21 | from seleniumwire import webdriver 22 | init(autoreset=True) 23 | 24 | # Sets color; defines place 25 | sg.theme('DarkAmber') 26 | def place(elem): 27 | return sg.Column([[elem]], pad=(0,0)) 28 | 29 | # Defines useful function for later 30 | def checkDouble(lst): 31 | count={} 32 | for item in lst: 33 | if item not in count: 34 | count[item]=1 35 | else: 36 | return True 37 | return False 38 | 39 | # Functions to make windows with layouts 40 | # I use functions and seperate windows because the only way to make a dynamic layout is to put it inside a new window 41 | def make_win1(): 42 | layout = [[sg.Text('Game ID:'), sg.Text(size=(15,1), key='-OUTPUT-')], 43 | [sg.Input(key='-IN-')], 44 | [sg.Button('Set ID'), sg.Button('Exit')]] 45 | return sg.Window('Blooket Hack: Kick', layout, finalize=True) 46 | 47 | def make_win2(): 48 | return sg.Window('Blooket Hack: Player Kick List', layout2, finalize=True) 49 | 50 | def make_win3(): 51 | layout3 = [ 52 | [sg.Text('Game ID:'), sg.Input(key='gameID')], 53 | [sg.Text('Bot Name:'), sg.Input(key='botsName')], 54 | [sg.Text('Number of Bots'), sg.Input(key='tempBots')], 55 | [sg.Button('Flood'), sg.Button('Exit')] 56 | ] 57 | return sg.Window('Blooket Hack: Bots', layout3, finalize=True) 58 | 59 | def make_win4(): 60 | layout4 = [ 61 | [sg.Text('Blooket Hack GUI')], 62 | [sg.Button('Add Bots'), sg.Button('Kick Players'), sg.Button('Information'), sg.Button('Auto')] 63 | ] 64 | return sg.Window('Blooket Hack GUI', layout4, finalize=True, size=(320, 75)) 65 | 66 | def make_win5(): 67 | layout5 = [ 68 | [sg.Text('Game ID:'), sg.Input(key='gamePin')], 69 | [sg.Text('Name:'), sg.Input(key='gameName')], 70 | [sg.Button('Set ID', key='ID2'), sg.Button('Exit')]] 71 | return sg.Window('Blooket Hack: Auto Answer', layout5, finalize=True) 72 | 73 | def make_win6(): 74 | return sg.Window('Blooket Hack: Answer', layout6, finalize=True) 75 | 76 | # Creates Windows, sets up Window 4 as the main one 77 | window1, window2, window3, window4, window5, window6 = None, None, None, make_win4(), None, None 78 | tempAnswer, Answer = None, None 79 | StopLoop = None 80 | 81 | # Sets up the Chrome Driver 82 | webdriver_location="chromedriver.exe" 83 | options=webdriver.ChromeOptions() 84 | options.use_chromium=True 85 | options.add_experimental_option('excludeSwitches',['enable-logging']) 86 | 87 | # Finds Chrome Path 88 | ChromePresent = True 89 | if os.path.isfile(r'C:\Program Files\Google\Chrome\Application\chrome.exe'): 90 | options.binary_location=r'C:\Program Files\Google\Chrome\Application\chrome.exe' 91 | elif os.path.isfile(r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'): 92 | options.binary_location=r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe' 93 | else: 94 | sg.popup("Blooket Auto Answer Requires Chrome To Be Installed.\nYou can still use the other features.") 95 | ChromePresent = False 96 | 97 | # Event Loop 98 | while True: 99 | window, event, values = sg.read_all_windows(timeout=100) 100 | # Breaks event loop, effectivly closes window 101 | if event == sg.WIN_CLOSED or event == 'Exit': 102 | try: 103 | window.close() 104 | except Exception: # In case all windows are closed 105 | sys.exit() 106 | if window == window2: # If closing win 2, mark as closed 107 | window2 = None 108 | elif window == window1: # If closing win 1, emark as closed, ect. 109 | window1 = None 110 | elif window == window3: 111 | window3 = None 112 | elif window == window4: 113 | window4 = None 114 | elif window == window5: 115 | window5 = None 116 | elif window == window6: 117 | window6 = None 118 | 119 | # Activates when Setting game code 120 | if event == 'Set ID': 121 | if not window2: 122 | window['-OUTPUT-'].update(values['-IN-']) 123 | gamePin = str(values['-IN-']) 124 | 125 | # Checks that the game pin is 6 characters 126 | if len(gamePin) != 6: 127 | sg.popup("The GameID should be 6 characters") 128 | else: 129 | 130 | # kgsenseis code to obtain a list of names in a lobby 131 | r=requests.put("https://api.blooket.com/api/firebase/join",data={"id":gamePin,"name":"blooketbad"},headers={"Referer":"https://www.blooket.com/"}) 132 | joinText=r.text 133 | r=requests.delete(f"https://api.blooket.com/api/firebase/client?id={gamePin}&name=blooketbad",headers={"Referer":"https://www.blooket.com/"}) 134 | 135 | if joinText == """{"success":false,"msg":"no game"}""": 136 | sg.popup("No game found!") 137 | else: 138 | players=json.loads(joinText)["host"]["c"].keys() 139 | 140 | # Some protection to ensure that people dont name themselves after my keys and break it 141 | play = [] 142 | for playerName in players: 143 | tempName = 'player' + playerName 144 | play.append(tempName) 145 | 146 | # Splits the list into equally sized chunks that make up a square array 147 | 148 | Square = int(math.ceil(len(play) ** (1/2))) 149 | play = [play[i:i + Square] for i in range(0, len(play), Square)] 150 | print(play) 151 | 152 | # Adds empty lists in case of error 153 | 154 | if len(play) != Square: 155 | play.append([]) 156 | 157 | # Second layout listing the names from previous code 158 | i = 0 159 | layout2 = [[[place(sg.Button(playerName[6:], size=(10, 5), key=(playerName), pad=(0,0))) for playerName in play[i]] for i in range(Square)], 160 | [sg.Button("Kick All", key='-KICK-'), sg.Button("Exit")]] 161 | window2 = make_win2() 162 | else: 163 | sg.popup('Close your current Kicking window to open another.') 164 | 165 | # Activates when you click a players name 166 | try : 167 | if event[:6] == 'player': 168 | print(event[:6]) 169 | # Kicks the player with the name 170 | r=requests.delete(f"https://api.blooket.com/api/firebase/client?id={gamePin}&name={event[6:]}",headers={"Referer":"https://www.blooket.com/"}) 171 | window[event].update(visible=False) 172 | except Exception: 173 | pass 174 | 175 | # Activates when kicking all 176 | if event == '-KICK-': 177 | tempPlay = [item for sublist in play for item in sublist] 178 | for playerName in tempPlay: # A loop to kick everyone 179 | r=requests.delete(f"https://api.blooket.com/api/firebase/client?id={gamePin}&name={playerName[6:]}",headers={"Referer":"https://www.blooket.com/"}) 180 | window[playerName].update(visible=False) 181 | sg.popup('Success! All players kicked.') 182 | 183 | # Information pop up 184 | if event == 'Information': 185 | sg.popup('This is a GUI prodcued by CopyCat',"It is based off kgsenseis' Blooket Hack",'https://github.com/kgsensei/BlooketHack','\nAt the moment it does not work with main.py') 186 | 187 | # Opens the window to kick players, checks window is not currently open 188 | if event == 'Kick Players': 189 | if not window1: 190 | window1 = make_win1() 191 | else: 192 | sg.popup("Close your previous Kick window before opening another") 193 | 194 | # Opens the window to bot players, checks window is not currently open 195 | if event == 'Add Bots': 196 | if not window3: 197 | window3 = make_win3() 198 | else: 199 | sg.popup("Close your previous Bot window before opening another") 200 | 201 | # Begins the process of adding bots 202 | # I forgot Continue was a thing... 203 | if event == 'Flood': 204 | if len(str(values['gameID'])) != 6: 205 | print(str(values['gameID'])) 206 | sg.popup("The GameID should be 6 characters") # Checks that the game ID is 6 characters 207 | else: 208 | try: 209 | botsInt = int(values['tempBots']) 210 | Error = False 211 | except ValueError: 212 | sg.popup("The bot number must be an integer") 213 | Error = True 214 | if Error == True: # Is false if try caught error 215 | pass 216 | else: 217 | if botsInt > 60: 218 | botsInt = 60 219 | sg.popup("Bots changed to 60","You can only have a maximum of 60 players in a Blooket game.") # Changes bots to 60 220 | for i in range(0,botsInt): 221 | r = requests.put("https://api.blooket.com/api/firebase/join", data={"id":str(values['gameID']),"name":str(values['botsName'])+' '+str(i)},headers={"Referer":"https://www.blooket.com/"}) 222 | if r.text == """{"success":false,"msg":"taken"}""": # Identifies Errors 223 | sg.popup(str(values['botsName'])+' '+str(i) + " was Taken! Choose a different name!") 224 | if r.text == """{"success":false,"msg":"no game"}""": 225 | if i > 0: 226 | sg.popup("Game Full! " + str(i) + "bots added.") 227 | break 228 | sg.popup("No game found!") 229 | break 230 | 231 | # Opens the Auto Answer Input 232 | if event == 'Auto': 233 | if ChromePresent == False: 234 | continue 235 | if window5 != None: 236 | sg.popup('Close your current Auto Answer window to open another.') 237 | continue 238 | window5 = make_win5() 239 | 240 | # Starts the Auto Answer 241 | if event == 'ID2': 242 | driver=webdriver.Chrome(options=options,executable_path=webdriver_location) 243 | questionList=[] 244 | driver.get('https://www.blooket.com/play') 245 | time.sleep(1) 246 | # Enters the Name and Pin into the respective places 247 | gamepinenter=driver.find_elements_by_xpath('//*[@id="app"]/div/div/div[2]/div/form/input') 248 | gamepinenter[0].send_keys(values['gamePin']) 249 | gamepinjoin=driver.find_elements_by_xpath('//*[@id="app"]/div/div/div[2]/div/form/div[2]') 250 | gamepinjoin[0].click() 251 | time.sleep(3) 252 | # Detects error 253 | try: 254 | nameinenter=driver.find_elements_by_xpath('//*[@id="app"]/div/div/div[2]/div/form/div[2]/input') 255 | nameinenter[0].send_keys(values['gameName']) 256 | nameinjoin=driver.find_elements_by_xpath('//*[@id="app"]/div/div/div[2]/div/form/div[2]/div') 257 | nameinjoin[0].click() 258 | except Exception: 259 | sg.popup("Error: Invalid Game Pin or Error Joining.\nTry again with a correct Pin / Name") 260 | driver.close() 261 | window.close() 262 | window5 = None 263 | continue 264 | sg.popup("\nPress 'OK' When Ready To Start Cheat\n Warning, it may take a while to load") 265 | # Defines more stuff 266 | for request in driver.requests: 267 | if request.response: 268 | if "https://api.blooket.com/api/games?gameId=" in request.url: 269 | jsondata=request.response.body 270 | jsondata=jsondata.decode("utf-8") 271 | jsondata=json.loads(jsondata) 272 | 273 | for question in jsondata['questions']: 274 | questionList.append(question["question"]) 275 | # Checks that no question has more than 2 answers 276 | if checkDouble(questionList): 277 | sg.popup("The bot cannot answer a question with the same text as another question.\n The bot may glitch a little if this happens.") 278 | # Starts Answer loop 279 | StopLoop = False 280 | 281 | # Begins Answer Loop 282 | if StopLoop == False: 283 | # Finds the question, gets the answer, checks 3 different paths 284 | if driver.find_elements_by_xpath('//*[@id="app"]/div/div/div[2]/div[1]/div/div'): 285 | try: 286 | questionShown=driver.find_elements_by_xpath('//*[@id="app"]/div/div/div[2]/div[1]/div/div') 287 | questionShown=questionShown[0].get_attribute("textContent") 288 | for question in jsondata['questions']: 289 | if str(question["question"])==questionShown: 290 | Answer = (str(question["correctAnswers"][0])) 291 | except Exception: 292 | pass 293 | 294 | elif driver.find_elements_by_xpath('//*[@id="left"]/div/div[1]/div'): 295 | try: 296 | questionShown=driver.find_elements_by_xpath('//*[@id="left"]/div/div[1]/div') 297 | questionShown=questionShown[0].get_attribute("textContent") 298 | for question in jsondata['questions']: 299 | if str(question["question"])==questionShown: 300 | Answer = (str(question["correctAnswers"][0])) 301 | except Exception: 302 | pass 303 | 304 | elif driver.find_elements_by_xpath('//*[@id="body"]/div[3]/div/div[1]/div'): 305 | try: 306 | questionShown=driver.find_elements_by_xpath('//*[@id="body"]/div[3]/div/div[1]/div') 307 | questionShown=questionShown[0].get_attribute("textContent") 308 | for question in jsondata['questions']: 309 | if str(question["question"])==questionShown: 310 | Answer = (str(question["correctAnswers"][0])) 311 | except Exception: 312 | pass 313 | 314 | # Creates a window with the answer, closes and opens a new window for each Answer 315 | if Answer == tempAnswer: 316 | pass 317 | else: 318 | if window6 != None: 319 | window6.close() 320 | layout6 = [[sg.Text('Answer: ' + Answer,justification='center')], 321 | [sg.Button('Auto Answer'), sg.Button('Stop')]] 322 | window6 = make_win6() 323 | 324 | try: 325 | tempAnswer = Answer 326 | except Exception: 327 | pass 328 | 329 | # Checks for different event flags 330 | if event == 'Stop': 331 | StopLoop = True0 332 | window6.close() 333 | driver.close() 334 | 335 | # Closes the window, should effectivly end the program 336 | sys.exit() 337 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Blooket-Hack-GUI 2 | A GUI for hacking blooket games 3 | ### Created by: Copycat#8110 4 | 5 | ## How to use: 6 | 7 | Have both python 3 and pip installed on your computer. 8 | Run the BlooketHackGUI.py file. 9 | 10 | Does not work on linux nor mac. 11 | Message me on discord at CopyCat#8110 for help 12 | 13 | ## Uses code from: 14 | - kgsensei 15 | 16 | ## Features: 17 | - Botting 18 | - - Adds customly names bots to games 19 | - - Up to 60 for free game, 1000 for premium games 20 | - Kicking 21 | - - GUI to kick players by name 22 | - - Mass Kick 23 | - Answer Finder 24 | - - Automatically finds the correct answer for the question 25 | - - Must use chromewebdriver 26 | - More to come 27 | -------------------------------------------------------------------------------- /chromedriver.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Copycat8110/Blooket-Hack-GUI/573e345b066963b641bd03b98cc563f1a824fe73/chromedriver.exe --------------------------------------------------------------------------------