def send(self, response): if not isinstance(self.player.state, PlayerState.Disconnected): if DEBUG_MODE: Common.console_message('[SEND] to %s: %s' % (self.request.getpeername()[0], response)) self.wfile.write(json.dumps(response['header']) + '\n') if response['object'] is not None: self.wfile.write(json.dumps(response['object']) + '\n')
def handle(self): Common.console_message('%s connected' % self.request.getpeername()[0]) self.player = Model.Player(self) self.player.state = PlayerState.NotLoggedIn() Model.players.append(self.player) self.last_message_id = 65535 while True: try: data = self.rfile.readline() except socket.error: self.player.state.disconnect(self.player) Common.console_message('Connection exception - %s disconnected' % self.player.username) break if data == '': # Socket disconnected self.player.state.disconnect(self.player) Common.console_message('%s (%s) disconnected' % (self.player.username, self.request.getpeername()[0])) break data = data.rstrip('\r\n') if DEBUG_MODE: Common.console_message('[GET] %s: %s' % (self.request.getpeername()[0], data)) # Get the object try: data = json.loads(data.strip()) if 'type' in data and 'id' in data and 'object' in data: # Here we add request to the query request_query.put((self.player, data)) else: # Missing fields id = data['id'] if 'id' in data else 0 response = Common.json_error('jsonMissingFields', id) self.player.socket.send(response) except ValueError: # Parsing failed response = Common.json_error('jsonParseFailed', 0) self.player.socket.send(response)
def run(self): """ This method runs everything, literally It's even called "run" But we call it with "GameManager.start()" I think it's not quite acceptable in this era that promotes equality so much, is it? "run" method has feelings too! It wants to be called too! Join now our movement at http://stoprundiscrimination.com/ and show them we're much more equal than they are! """ game = self.game game.state = Model.Game.IN_PROGRESS self.round = 1 self.round_commands = {} self.round_ready = [] self.round_fleets_to_deploy = {} # Do not create game entry in database if a player is autistic enough to play with themselves if len(game.players) > 1 and Database.USING_DATABASE: Database.create_game(self.game) for p in game.players: # Set 0 level tech for everyone game.tech[p] = { 'offensive': 0, 'defensive': 0, 'economic': 0, 'points': 0 } # Set 0 for every stat for everyone for (k, s) in game.stats.items(): s[p.username] = 0 # Put everyone in place game.map.set_starting_positions() Common.console_message('Game %d started!' % game.id) while game.state == Model.Game.IN_PROGRESS: # As long as game is not finished! self.round_ready = [] # We wait for players to be ready # TODO timeout while game.state == Model.Game.IN_PROGRESS: if self.has_game_ended(): # Has the game ended? self.game_end() return None if set(game.players).issubset(self.round_ready): # Everyone is ready! break # RatajException time.sleep(0.5) # Has someone lost in the previous round? for p in self.game.players: if len(p.planets) == 0: self.player_lost(p, True) # Thus, has the game ended? if self.has_game_ended(): self.game_end() return None self.round_commands = {} round_time = Constants.ROUND_TIME current_map = game.map.get_current_state() for p in game.players: fleets_to_deploy = self.game.map.fleets_per_turn(p) self.round_fleets_to_deploy[p] = fleets_to_deploy object_to_send = { 'players': [pl.username for pl in game.players], 'map': current_map, 'tech': game.tech[p], 'fleetsToDeploy': fleets_to_deploy, 'roundTime': round_time } p.socket.send(Common.json_message('roundStart', object_to_send, p.socket.get_next_message_id())) round_start_time = time.time() while time.time() - round_start_time < round_time and game.state == Model.Game.IN_PROGRESS: if self.has_game_ended(): # Has the game ended? self.game_end() return None if set(game.players).issubset(self.round_commands.keys()): # Everyone sent their orders break # RatajException time.sleep(0.5) # Assume that round has ended and we have everyone's orders # Zero, randomize the players! self.order_players() # First, we put them in order: deploys first, moves next commands = self.order_commands() # And now let's execute them, shall we? results = self.execute_commands(commands) # Then send the results to all players for p in self.game.players: p.socket.send(Common.json_message('roundEnd', results, p.socket.get_next_message_id())) # ...has someone won the game, accidentally? if self.has_game_ended(): self.game_end() return None # And to the next round! self.round += 1
if __name__ == "__main__": # Define the default server address HOST, PORT = "0.0.0.0", 23456 # Get the command line parameters for i, a in enumerate(sys.argv): if i > 0: # First entry is filename if a[0:2] == '--': if a == '--debug': Communication.DEBUG_MODE = True if a == '--database': Database.connect() if a == '--logging': # Turn on logging filename = 'logs/%d.txt' % time.time() Common.console_message('Saving log to %s' % filename) if not os.path.exists('logs'): os.mkdir('logs') Common.LOG_FILE = open(filename, 'w') else: if i == len(sys.argv) - 2: # Host HOST = str(a) if i == len(sys.argv) - 1: PORT = int(a) # Create server object server = Communication.Server((HOST, PORT), Communication.RequestHandler) server.allow_reuse_address = True ip, port = server.server_address Common.console_message('Server started on %s at %d!' % (HOST, PORT)) if Communication.DEBUG_MODE: