def put(self, request): """ """ # Si cambia el email puede generar problemas serios, por eso se retorna # un nuevo token decoded_token = decode_token(request.META) serializer = UserSerializer( MyUser.objects.get(email=decoded_token['email']), data=request.data, partial=True) if serializer.is_valid(): user = serializer.save() jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER payload = jwt_payload_handler(user) token = jwt_encode_handler(payload) return Response({"token": token}, status=status.HTTP_200_OK) else: return Response({ 'data': serializer.errors, 'message': 'User could not be created with the received data.' }, status=status.HTTP_400_BAD_REQUEST)
def create(self, request, *args, **kwargs): """ """ try: Application.objects.get(client_id=self.kwargs['client_id']) except Application.DoesNotExist: return Response({ 'message': 'Invalid client_id.' }, status=status.HTTP_400_BAD_REQUEST) decoded_token = decode_token(request.META) instance = Profile.objects.get( user=MyUser.objects.get( email=decoded_token['email'])) partial = kwargs.pop('partial', False) serializer = self.get_serializer( instance, data=request.data, partial=partial) if serializer.is_valid(): self.perform_update(serializer) return Response(serializer.data, status=status.HTTP_200_OK) return Response({ 'data': serializer.errors, 'message': 'Profile could not be updated with the received data.' }, status=status.HTTP_400_BAD_REQUEST)
def delete(self, request): """ """ decoded_token = decode_token(request.META) MyUser.objects.get(email=decoded_token['email']).delete() return Response("User deleted!", status=status.HTTP_204_NO_CONTENT)
def perform_update(self, serializer): """ """ decoded_token = decode_token(self.request.META) if decoded_token is not None: serializer.save( owner=MyUser.objects.get( email=decoded_token['email']))
def get_usertoken_data(self, token): token_data = decode_token(token) if not token_data: return None, response(400, 'Wrong token') if not self._validate_user(token_data['username']): return None, response(400, 'User doesn\'t exists') return token_data, None
def get(self, request): """ """ decoded_token = decode_token(request.META) serializer = UserSerializer( MyUser.objects.get( email=decoded_token['email'])) return Response(serializer.data, status=status.HTTP_200_OK)
def get_queryset(self): """ This view should return a list of all the applications for the currently authenticated user. """ decoded_token = decode_token(self.request.META) if decoded_token is not None: return Application.objects.filter( owner=MyUser.objects.get(email=decoded_token['email'])) return []
def filter_queryset(self, queryset): """ """ decoded_token = decode_token(self.request.META) try: # If the user is the owner # app = Application.objects.get(client_id=self.kwargs['client_id'], # owner__email=decoded_token['email']) return queryset except Application.DoesNotExist: return queryset.filter(user__email=decoded_token['email']) return queryset
def authenticate(): print("authenticating...") auth_header = request.headers.get('Authorization').split(' ')[1] if not auth_header: return make_response(json.dumps({'message': 'No authentication header'}), 403) user_id = decode_token(auth_header) if isinstance(user_id, int): print('token valid, user id is', user_id) return make_response(json.dumps({"message": user_id}), 200) else: print("auth fail") return make_response(json.dumps({"message": user_id}), 403)
def validate_jetson_data(self, device_data, data_dict=None): token_data = decode_token(device_data['token']) jetson = Jetson.query.filter_by(mac=token_data['mac']).first() truck = Truck.query.filter_by(id=device_data['truck_id']).first() if truck.jetson_id != jetson.id: return response(400, 'Wrong token') if data_dict: error = self._validate_data(**data_dict) if error: return error
def test_valid_fields(self): response = json.loads( self.client.post('/login', json=dict(email='*****@*****.**', )).data) token = response['token'] response = json.loads( self.client.post('/user/employee/profile', json=dict(firstname='test', lastname='test', birth='1900-01-01', city='test', telephone='+37061234567', description='test test test', work_experience=10), headers=dict(token=token)).data) assert response.get('status') == 'success' decoded_token = decode_token(token) with app.app_context(): assert Employee.query.filter_by( user_id=decoded_token['user_id']).first() != None
def play_game(screen, color_count, max_attempts, code, attempts): global line, client_socket score = 0 if len(attempts) > max_attempts: attempts = attempts[:max_attempts] for i, attempt in enumerate(attempts): utils.print_code(screen, utils.PREFIX, attempt, -1) line += 1 screen.move(line, 0) answer_bytes = utils.receive_packet( client_socket ) # We read the server's answer for the current attempt and find the corresponding perfect and partial pin counts if len(answer_bytes) == 2 and int.from_bytes(answer_bytes, "big") == 418: answer_bytes = utils.receive_packet(client_socket) perfect = int.from_bytes(answer_bytes[:2], "big") partial = int.from_bytes(answer_bytes[2:4], "big") if perfect == len( code ): # If all the pins are perfect, that means the guessed code was the right one screen.move(line - 1, len(utils.PREFIX) + 1 + (len(code) + 1) * 2) screen.addstr("Correct!\n\r" ) # Print "correct" next to the last guessed line screen.move(line, 0) score = max_attempts - i # His score is the number of attempts left screen.addstr( "You cracked the code! Score: {}\n\r".format(score) ) # Print a nice message for the user to know he got it right and show his score line += 1 break else: # Show the perfect and partial pins next to the guess offset = len(utils.PREFIX) + 1 + (len(code) + 1) * 2 screen.addstr(line - 1, offset, "Result:") offset += len("Result:") + 1 for i in range(perfect + partial): attr = curses.color_pair(2 if i < perfect else 1) screen.addstr(line - 1, offset + i * 2, " ", attr) screen.move(line, 0) else: if attempts: guess = attempts[-1].copy( ) # We take the last attempt as starting point for the next guess if there is one else: guess = [0] * len( code ) # Otherwise, the user's default guess will be only red pins (it could be any color, but the 0-th color is easier and always exists) for attempt in range( len(attempts), max_attempts ): # Limits the number of attempts to the chosen amount guess = input_guess(screen, len(code), color_count, guess) attempts.append(guess.copy()) guess_bytes = bytes( ) # While in an Online Ranked Game, instead of comparing the codes locally, we send the guess to the server # If guess is not the same size as code, cut it off or append zeros if len(guess) > len(code): guess = guess[:len(code)] elif len(guess) < len(code): guess += [0] * (len(code) - len(guess)) for color in guess: # Encode guess' colors on 16 bits (max. 65535 colors) guess_bytes += (min(color, 0xFFFF) & 0xFFFF).to_bytes(2, "big") utils.send_packet(client_socket, guess_bytes) answer_bytes = utils.receive_packet( client_socket ) # We then read the server's answer and find the corresponding perfect and partial pin counts if len(answer_bytes) == 2 and int.from_bytes(answer_bytes, "big") == 418: answer_bytes = utils.receive_packet(client_socket) perfect = int.from_bytes(answer_bytes[:2], "big") partial = int.from_bytes(answer_bytes[2:4], "big") if perfect == len( code ): # If all the pins are perfect, that means the guessed code is the right one screen.move(line - 1, len(utils.PREFIX) + 1 + (len(code) + 1) * 2) screen.addstr( "Correct!\n\r" ) # Print "correct" next to the last guessed line screen.move(line, 0) score = max_attempts - attempt # His score is the number of attempts left screen.addstr( "You cracked the code! Score: {}\n\r".format(score) ) # Print a nice message for the user to know he got it right and show his score line += 1 break else: # Show the perfect and partial pins next to the guess offset = len(utils.PREFIX) + 1 + (len(code) + 1) * 2 screen.addstr(line - 1, offset, "Result:") offset += len("Result:") + 1 for i in range(perfect + partial): attr = curses.color_pair(2 if i < perfect else 1) screen.addstr(line - 1, offset + i * 2, " ", attr) screen.move(line, 0) else: # If we reached the maximum number of attempts without quitting the loop, it means the user failed to guess the code and he lost token = utils.receive_packet(client_socket).decode("utf8") _, _, _, _, _, code, _ = utils.decode_token( token ) # Retrieve the real code from the server once the player lost utils.print_code(screen, "You failed! The code was:", code, -1) line += 1 screen.move(line, 0) screen.refresh( ) # Update the screen before going to sleep, or it would "freeze" before updating, not showing the final text before resetting curses.napms(3000) return score
def main(screen=None, color_count=None, max_attempts=None, code_length=None): if screen is None: try: token = curses.wrapper( main ) # Use curses to handle user input, screen clearing and simplify other display management tools if token is not None: # If the game has been interrupted and a token to resume was generated, show a message to inform the user print( "This game has been interrupted. To resume, copy paste this token:", token) except KeyboardInterrupt: pass except Exception as e: if utils.DEBUG: traceback.print_exc() else: print("Oops! An error occured:", e) return curses.start_color() # Enable curses' colors curses.use_default_colors() curses.curs_set( 0 ) # Hide the cursor as we will use a custom way to show the selected color if color_count is None or color_count <= 0: color_count = utils.DEFAULT_COLOR_COUNT if max_attempts is None or max_attempts <= 0: max_attempts = utils.DEFAULT_MAX_ATTEMPTS if code_length is None or code_length <= 0: code_length = utils.DEFAULT_CODE_LENGTH global score, games score, games = 0, 0 code, attempts = None, None # Create a token containing the settings requested by the user token = utils.encode_token(1, score, games, color_count, max_attempts, [0xFFFF] * code_length, []) global client_socket, line username = "" initialized, first = False, True while True: # Play an infinite number of games until the user quits the program (with Ctrl+C) if client_socket is None: # If the client isn't connected to the server yet, connect to it screen.clear() screen.addstr("Connecting to the server, please wait...\n\r") screen.refresh( ) # Refresh the screen, because the following code could block for a few seconds try: client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect( (utils.SERVER_HOST, utils.SERVER_PORT)) # Connect to socket server client_socket.settimeout( 2 ) # Let the server 2 seconds to understand our request and answer it, or disconnect except socket.error as e: screen.clear() raise Exception( "Failed to connect to server. Please try again later.") # TODO: GDPR Prompt utils.send_packet(client_socket, "OK".encode("utf8")) while not initialized: # While the game hasn't fully been created and started on the server, don't start it locally try: status = int.from_bytes(utils.receive_packet(client_socket), "big") if status == 401 or status == 403: # Status 401: Unknown user; Status 403: Unknown user, username provided taken username = "" while not username: screen.clear() screen.addstr( "Please enter a username which will represent you in the Online Ranked Games scoreboard.\n\r" ) screen.addstr( "WARNING: This username CAN NOT BE CHANGED and will be linked to your address. It must be UNIQUE.\n\r" ) screen.addstr("\n\r") screen.addstr("Username: \n\r") if status == 403: screen.addstr( "Invalid username. Please try again.") curses.curs_set(2) curses.echo() username = screen.getstr(3, 10).decode("utf8") curses.noecho() curses.curs_set(0) screen.clear() screen.addstr("Registering new user, please wait...\n\r") screen.refresh() utils.send_packet(client_socket, username.encode("utf8")) elif status == 204: # Status 204: Known user, no game started if not username: username = utils.receive_packet(client_socket).decode( "utf8") if not first: display_scoreboard(screen) screen.clear() screen.addstr( "Initializing new Online Ranked Game, please wait...\n\r" ) screen.refresh() utils.send_packet( client_socket, token.encode("utf8") ) # Send the token containing all the settings requested by the user to the server elif status == 200: # Status 200: Known user, game pending if not username: username = utils.receive_packet(client_socket).decode( "utf8") token = utils.receive_packet(client_socket).decode("utf8") # Get all the required information about the game from the server _, score, games, color_count, max_attempts, code, attempts = utils.decode_token( token) code_length = len(code) curses.init_pair(0, -1, utils.find_nearest_color(0, 0, 0)) curses.init_pair(1, -1, utils.find_nearest_color(1, 1, 1)) for color in range( 2, color_count + 2 ): # Initialize all the colors we will need, generating them around the color wheel # Each color is uniformly spread around the color spectrum, keeping its saturation and value to the max (excludes black and white) h, s, v = (color - 2) / color_count, 1.0, 1.0 r, g, b = colorsys.hsv_to_rgb( h, s, v ) # Convert the color from HSV (easier to generate) to RGB (easier to manipulate) # Because we can't use custom colors in most terminals, we find the closest available one and pair it to the color's id with a white foreground curses.init_pair(color, -1, utils.find_nearest_color(r, g, b)) initialized = True break elif status == 409: # Status 409: Known user, game already running screen.clear() raise Exception( "A user is already playing an Online Ranked Game from this address." ) elif not status: screen.clear() raise Exception( "Server disconnected unexpectedly. Please try again later." ) else: screen.clear() raise Exception( "Unknown status {} returned by server.".format(status)) except socket.timeout: pass screen.clear() line = 0 first = False try: if code is None: code = [0xFFFF] * code_length if attempts is None: attempts = [] game_score = play_game(screen, color_count, max_attempts, code, attempts) code, attempts = None, None # Reset the code and the attempts to make the next game independent except KeyboardInterrupt: screen.move(line, 0) screen.clrtoeol( ) # Clear the current line, just in case some text was there token = utils.encode_token(1, score, games, color_count, max_attempts, code, attempts) return token if game_score > 0: score += game_score # If the user won this game, we increment his score and the number of (consecutive) games he played games += 1 else: score, games = 0, 0 # If he lost, we reset his score and the number of (consecutive) games initialized = False
def tick_client(conn, address, data, user_list, scoreboard): try: buff = data["inputs"].pop( 0) if data["inputs"] else utils.receive_packet(conn) if buff: if data["status"] == 200: game = user_list[address[0]]["game"] guess = [0xFFFF] * len(game["code"]) for i in range(len(game["code"])): guess[i] = int.from_bytes(buff[2 * i:2 * (i + 1)], "big") perfect, partial = utils.compare_codes(guess, game["code"]) if game["color_count"] == 6 and len( game["code"]) == 4 and guess == [0, 1, 0, 0]: utils.send_packet(conn, (418).to_bytes(2, "big")) utils.send_packet( conn, perfect.to_bytes(2, "big") + partial.to_bytes(2, "big")) if perfect == len(game["code"]): game["score"] += game["max_attempts"] - len( game["attempts"]) game["games"] += 1 game["code"] = utils.generate_code(len(game["code"]), game["color_count"]) game["attempts"] = [] if utils.DEBUG: print("Client {}:{} won a game on thread #{}.".format( *address, thread.ident)) else: game["attempts"].append(guess) if len(game["attempts"]) >= game["max_attempts"]: token = utils.encode_token( game["gamemode"], game["score"], game["games"], game["color_count"], game["max_attempts"], game["code"], game["attempts"]) utils.send_packet(conn, token.encode("utf8")) total_attempts = (game["max_attempts"] + 1) * game["games"] - game["score"] normalized_score = game["score"] normalized_score *= game["color_count"]**len( game["code"]) / 1000 normalized_score /= 1.2**game["max_attempts"] / 10 normalized_score = int(normalized_score) entry = (address[0], user_list[address[0]]["username"], game["score"], game["games"], total_attempts, normalized_score, game["color_count"], len(game["code"]), game["max_attempts"], time.time()) for i, other in enumerate(scoreboard): if other[5] < entry[5] or ( other[5] == entry[5] and other[3] < entry[3] or (other[3] == entry[3] and other[4] > entry[4])): scoreboard.insert(i, entry) break else: scoreboard.append(entry) del user_list[address[0]]["game"] user_list[address[0]]["connected"] = False data["status"] = 204 utils.send_packet(conn, data["status"].to_bytes(2, "big")) if utils.DEBUG: print("Client {}:{} lost a game on thread #{}.". format(*address, thread.ident)) elif address[0] in user_list and "connected" in user_list[ address[0]] and user_list[address[0]]["connected"]: data["status"] = 409 utils.send_packet(conn, data["status"].to_bytes(2, "big")) conn.close() if utils.DEBUG: print( "Client {}:{} forcefully disconnected from thread #{}." .format(*address, thread.ident)) return False elif data["status"] == 204: token = buff.decode("utf8") if re.match(r"^SB:\d+ \d+$", token): page_size, offset = map(int, token[3:].split()) answer_bytes = bytes() if len(scoreboard) >= offset: for entry in scoreboard[ offset:min(offset + page_size, len(scoreboard))]: username = entry[1].encode("utf8") if 6 + len(answer_bytes) + len( username) + 6 > 65535: break answer_bytes += (min(len(username), 0xFFFF) & 0xFFFF).to_bytes(2, "big") answer_bytes += username answer_bytes += (min(entry[5], 0xFFFF) & 0xFFFF).to_bytes(2, "big") answer_bytes += (min(entry[3], 0xFFFF) & 0xFFFF).to_bytes(2, "big") answer_bytes += (min(entry[4], 0xFFFF) & 0xFFFF).to_bytes(2, "big") answer_bytes += (min(entry[4], 0xFFFF) & 0xFFFF).to_bytes(2, "big") answer_bytes += (min(entry[5], 0xFFFF) & 0xFFFF).to_bytes(2, "big") answer_bytes += (min(entry[6], 0xFFFF) & 0xFFFF).to_bytes(2, "big") answer_bytes += ( min(int(entry[8] * 1000), 2**64 - 1) & 2**64 - 1).to_bytes(8, "big") utils.send_packet(conn, answer_bytes) else: gamemode, score, games, color_count, max_attempts, code, attempts = utils.decode_token( token) score, games = 0, 0 code = utils.generate_code(len(code), color_count) user_list[address[0]]["connected"] = True game = { "gamemode": gamemode, "score": score, "games": games, "color_count": color_count, "max_attempts": max_attempts, "code": code, "attempts": [] } user_list[address[0]]["game"] = game if len(attempts) > max_attempts: attempts = attempts[:max_attempts] for attempt in attempts: attempt_bytes = bytes() if len(attempt) > len(code): attempt = attempt[:len(code)] elif len(attempt) < len(code): attempt += [0] * (len(code) - len(attempt)) for color in attempt: attempt_bytes += (min(color, 0xFFFF) & 0xFFFF).to_bytes(2, "big") data["inputs"].append(attempt_bytes) if attempt == code: break data["status"] = 200 utils.send_packet(conn, data["status"].to_bytes(2, "big")) fake_code = [0xFFFF] * len(game["code"]) fake_token = utils.encode_token(game["gamemode"], game["score"], game["games"], game["color_count"], game["max_attempts"], fake_code, attempts) utils.send_packet(conn, fake_token.encode("utf8")) if utils.DEBUG: print("Client {}:{} started a new game on thread #{}.". format(*address, thread.ident)) elif data["status"] == 401 or data["status"] == 403: username = buff.decode("utf8") if buff == b"\x36\x39": for chars in itertools.product(*[ [ b"\x4e", b"\x6e", b"\xc3\xb1", b"\xc5\x84", b"\xc3\x91", b"\xc5\x83" ], [ b"\x69", b"\x49", b"\xc3\xae", b"\xc3\xaf", b"\xc3\xac", b"\xc3\xad", b"\xc4\xaf", b"\xc4\xab", b"\xc3\x8e", b"\xc3\x8f", b"\xc3\x8c", b"\xc3\x8d", b"\xc4\xae", b"\xc4\xaa" ], [ b"\x63", b"\x43", b"\xc3\xa7", b"\xc4\x87", b"\xc4\x8d", b"\xc3\x87", b"\xc4\x86", b"\xc4\x8c" ], [ b"\x65", b"\x45", b"\xc3\xa9", b"\xc3\xa8", b"\xc3\xaa", b"\xc3\xab", b"\xc4\x99", b"\xc4\x97", b"\xc4\x93", b"\xc3\x89", b"\xc3\x88", b"\xc3\x8a", b"\xc3\x8b", b"\xc4\x98", b"\xc4\x96", b"\xc4\x92" ] ]): username = "".join( map(lambda x: x.decode("utf8"), chars)) for other_address in user_list: if username == user_list[other_address][ "username"]: data["status"] = 403 utils.send_packet( conn, data["status"].to_bytes(2, "big")) break else: break else: username = "" if 3 <= len(username) <= 32 and set( username) <= USERNAME_CHARACTERS: for other_address in user_list: if username == user_list[other_address]["username"]: data["status"] = 403 utils.send_packet( conn, data["status"].to_bytes(2, "big")) break else: user_list[address[0]] = {"username": username} data["status"] = 204 utils.send_packet(conn, data["status"].to_bytes(2, "big")) else: data["status"] = 403 utils.send_packet(conn, data["status"].to_bytes(2, "big")) elif data["status"] == 300: if buff.decode("utf8") == "OK": if address[0] in user_list: if not "connected" in user_list[address[ 0]] or not user_list[address[0]]["connected"]: if "game" in user_list[address[0]] and user_list[ address[0]]["game"] is not None: game = user_list[address[0]]["game"] user_list[address[0]]["connected"] = True attempts = game["attempts"] game["attempts"] = [] if len(attempts) > game["max_attempts"]: attempts = attempts[:game["max_attempts"]] for attempt in attempts: attempt_bytes = bytes() if len(attempt) > len(game["code"]): attempt = attempt[:len(game["code"])] elif len(attempt) < len(game["code"]): attempt += [0] * (len(game["code"]) - len(attempt)) for color in attempt: attempt_bytes += (min(color, 0xFFFF) & 0xFFFF).to_bytes( 2, "big") data["inputs"].append(attempt_bytes) if attempt == game["code"]: break data["status"] = 200 utils.send_packet( conn, data["status"].to_bytes(2, "big")) utils.send_packet( conn, user_list[address[0]] ["username"].encode("utf8")) fake_code = [0xFFFF] * len(game["code"]) fake_token = utils.encode_token( game["gamemode"], game["score"], game["games"], game["color_count"], game["max_attempts"], fake_code, attempts) utils.send_packet(conn, fake_token.encode("utf8")) if utils.DEBUG: print( "Client {}:{} resumed a game on thread #{}." .format(*address, thread.ident)) else: data["status"] = 204 utils.send_packet( conn, data["status"].to_bytes(2, "big")) utils.send_packet( conn, user_list[address[0]] ["username"].encode("utf8")) else: data["status"] = 409 utils.send_packet( conn, data["status"].to_bytes(2, "big")) conn.close() if utils.DEBUG: print( "Client {}:{} forcefully disconnected from thread #{}." .format(*address, thread.ident)) return False else: data["status"] = 401 utils.send_packet(conn, data["status"].to_bytes(2, "big")) return True except socket.error as e: if hasattr(e, "skipped_data"): data = e.skipped_data if data.decode("utf8").startswith("GET "): data += conn.recv(65536 - len(e.skipped_data)) if re.match(r"^GET .*? HTTP/\d+(?:\.\d+)*\r\n", data.decode("utf8")): conn.send( base64.b64decode( "SFRUUC8xLjEgMjAwIE9LDQpDb250ZW50LVR5cGU6aW1hZ2UvZ2lmDQpDb25uZWN0aW9uOmNsb3NlZA0KDQpHSUY4OWEQAA4A8gAA/wEqFf5J4esIoOc5K+7IycenAAAAAAAAIfkECQQAAAAh/hlPcHRpbWl6ZWQgdXNpbmcgZXpnaWYuY29tACH/C05FVFNDQVBFMi4wAwEAAAAh/wt4bXAgZGF0YXhtcP8/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG10YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4zLWMwMTEgNjYuMTQ1NjYxLCAyMDEyLzAyLzA2LTE0OjU2OjI3ICAgICAgICAiPjxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53Lm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZjphYm91dD0iIiD/eG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1uczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M2ICgxMy4wIDIwMTIwMzAubS40MTUgMjAxMi8wMy8wNToyMTowMDowMCkgIChNYWNpbnRvc2gpIiB4bXBNTTpJbnN0YWNlSUQ9/yJ4bXAuaWlkOjNFMDkxQkU1N0I3NTExRTE5QkY3ODJBQjU0NUZGMkI2IiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjNFMDkxQkU2N0I3NTExRTE5QkY3ODJBQjU0NUZGMkI2Ij4gPG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDozRTA5MUJFMzdCNzUxMUUxOUJGNzgyQUI1NDVGRjJCNiIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDozRTA5MUJFNDdCNzUxMUUxOUY3ODJBQjU0NUZGMkI2Ii8+IDwvcmRmOkRlc2Nyaf9wdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFrZXQgZW5kPSJyIj8+Af/+/fz7+vn49/b19PPy8fDv7u3s6+rp6Ofm5eTj4uHg397d3Nva2djX1tXU09LR0M/OzczLysnIx8bFxMPCwcC/vr28u7q5uLe2tbSzsrGwr66trKupqKempaSjoqGgn56dnJuamZiXlpWUk5KRkI+OjYyLiomIh4aFhIOCgYB/fn18e3p5eHd2dXRzcnFwb25tbGtqaWhnZmVkY2JhYF9eXVxbWllYV1ZVVFNSUVBPTk1MS0pJSEdGRURDQkFAPz49PDs6OTg3NjU0MzIyMTAvLi0sKyopKCcmJSQjIiEgHx4dHBsaGRgXFhUUExIREA8ODQwLCgkIBwYFBAMCAQAALAAAAAAQAA4AAAM7CLoM1I08EMKAKsgtMdVcB1XhNpYcM5DopAgryGkqXIF3I+yxVF2LwW4IiwEBKyGRWFAIlUviK0oFJAAAIfkECQQAAAAsAAAAAA8ADgCCAAAAKv4jqvgVGUf7ENfjsaXCAAAAAAAAAz8IukvEjIwBHClQuSKHy5UzeRO2cOJkUY2Vjkzgjmosz96zBLdrMQVez2JSCI5HIa9YQCKVAWPAmVQaqVWhIAEAIfkECQQAAAAsAQAAAA8ADgCCAAAAD/9BLDf5BdTlRu6/nbKwAAAAAAAAAzsIuiO1sBUhmoCMao3B+BsXhVtkkRQDopfyrSRDEDAIFUH+vg+U/7oBoacA5miDXC9pnAUIOQXUSA0AEgAh+QQJBAAAACwAAAAAEAAOAIIAAABMOfbGGvIG2udG7r9D338AAAAAAAADQgi6EPxACBUCgdSKsCeulSR6DCiaDxGGIwkMIDdWzACbUljbcfzYvN6FUbARgLwhkVAoHJE2YrMIHTAXzGbV5gQkAAAh+QQJBAAAACwAAAEADwANAIIAAAA5PfjdCN/WaMAEy/fgWIMAAAAAAAADOQi6MvugFTBEg9RW7WAIVjNsXmiGDxiORWGlqlaQyxef8L2mBGFbn46iR7TZCAti0RhAApQ9ZhOZAAAh+QQJBAAAACwAAAEADgANAIIAAADtR3H+EzBJLffbI9LJx6cAAAAAAAADOAi6EMUrBEXIhFYGISSuXLddFBFyGmmJZ7dUUuuW2ekBxFCtnUVQg2AmsHsogkjh7phsIgHOKCABACH5BAkEAAAALAAAAQANAA0AggAAAPk0O/q5BN0a2nVK7wAAAAAAAAAAAAMtCLrcHuGJCSEbNcx5M9UL5mlCBIjQRiko+bFtZg5xxhJ0PJwD4eO5He/nCwISACH5BAkEAAAALAAAAQAPAA0AggAAAPY8Q+DbBvG9CvIL08nHpwAAAAAAAAM7CLoswu2BMESBqhYnKg4UJ0JgJZpMwJnjErKtAoaik87s4MlEr1cDygUgCPR6s9nQeGyCHkVQ8ygFJAAAIfkECQQAAAAsAAABABAADQCCAAAA/SgnN/4K190Gu+EazqatAAAAAAAAAzsIugxTjREBByEwDlummJGzeRTYjML3TdliXWRKNMEbX/T2ysTADIEa7ML5BYM6XQt4bCIVOqdUJJ0CEgAh+QQFBAAAACwAAAAAEAAOAIIAAAD+QwQm/hsI/l3D2R1G7r8AAAAAAAADPwi63K5lifHULFjgSrT4Q+gQHTiAEUN+aDE1pRZmAhyH4WfH7KuSvE5KQQoEgEjComhsIlPIphFJJBylThIgAQA7" )) conn.close() if utils.DEBUG: print("Client {}:{} disconnected from thread #{}.". format(*address, thread.ident)) return False if e.errno == errno.EWOULDBLOCK: return True elif utils.DEBUG: traceback.print_exc() else: print(e) except Exception as e: if utils.DEBUG: traceback.print_exc() else: print(e) pass conn.close() if address[0] in user_list and "connected" in user_list[ address[0]] and user_list[address[0]]["connected"]: user_list[address[0]]["connected"] = False if utils.DEBUG: print("Client {}:{} disconnected from thread #{}.".format( *address, thread.ident)) return False
def main(screen=None): if screen is None: try: token = curses.wrapper( main ) # Use curses to handle user input, screen clearing and simplify other display management tools if token is not None: # If the game has been interrupted and a token to resume was generated, show a message to inform the user print( "This game has been interrupted. To resume, copy paste this token:", token) except KeyboardInterrupt: pass except Exception as e: if utils.DEBUG: traceback.print_exc() else: print("Oops! An error occured:", e) return curses.start_color() # Enable curses' colors curses.use_default_colors() curses.curs_set( 0 ) # Hide the cursor as we will use a custom way to show the selected color if len(sys.argv) > 1 and re.match( "^[A-Za-z0-9+/]*=*$", sys.argv[1] ): # If a (seemingly) valid token was provided, resume this game rather than starting a new one token = sys.argv[1] if len(token) % 4 > 0: token += "=" * ( 4 - len(token) % 4 ) # Fix Base64 padding by adding equal signs at the end of the token gamemode, score, games, color_count, max_attempts, code, attempts = utils.decode_token( token ) # Get all the required information about the pending game from the token code_length = len(code) else: gamemode, code_length, color_count, max_attempts = select_gamemode( screen) score, games = 0, 0 code, attempts = None, None if gamemode == 0: if code is None: code = utils.generate_code( code_length, color_count ) # Generate a random code to "play against the computer" return singleplayer.main(screen, color_count, max_attempts, score, games, code, attempts) elif gamemode == 1: return online_ranked.main(screen, color_count, max_attempts, code_length) elif gamemode == 2: if code is None: code = utils.generate_code( code_length, color_count ) # Generate a random code for the computer to guess return computer_vs_computer.main(screen, color_count, max_attempts, score, games, code, attempts) else: raise Exception("Unknown gamemode selected: {}".format(gamemode))