def run(self): global _Logged_in global _InThreads global _OutThreads global _Logger global _User_Pings global _User_Pings_Lock global _Player_OQueues_Lock global _Player_OQueues global game_engine global _Shutdown global _Shutdown_Lock timeout = 15 to_rem = [] _Shutdown_Lock.acquire() done = _Shutdown _Shutdown_Lock.release() while not done: _User_Pings_Lock.acquire() for person in to_rem: del _User_Pings[person] to_rem = [] for player in _User_Pings: if time.time() - _User_Pings[player] > timeout: #This client has timed out print 'Player timed out: <%s>' % player logger.write_line('Removing <%s> from game: Timed out' % player) game_engine._Characters_Lock.acquire() if player in game_engine._Characters or player in game_engine._Characters_In_Builder: if player in game_engine._Characters: #Player in regular characters person = game_engine._Characters[player] loader.save_player(person) logger.write_line("Saving player file for <%s>" % player) elif player in game_engine._Characters_In_Builder: #Player in builder game_engine._Characters_In_Builder_Lock.acquire() person = game_engine._Characters_In_Builder[player] loader.save_player(person) logger.write_line("Saving player file for <%s>" % player) game_engine._Characters_In_Builder_Lock.release() game_engine.remove_player(player) else: logger.write_line("Error! Could not find player in _Characters or _Characters_In_Builder: <%s>" % player) game_engine._Characters_Lock.release() if player in _Logged_in: _Logged_in.remove(player) to_rem.append(player) _Player_OQueues_Lock.acquire() _Player_OQueues[player].put('Error, it appears this person has timed out.') _Player_OQueues_Lock.release() _User_Pings_Lock.release() _Shutdown_Lock.acquire() done = _Shutdown _Shutdown_Lock.release() time.sleep(0.05)
def remove_player(self, name): if name in self._Characters: self._Characters_Lock.acquire() player = self._Characters[name] del self._Characters[name] # Remove the player from the list of players in the game self._Characters_Lock.release() self._Rooms[player.coords].players.remove(player.name) # Remove the player from the room they are in elif name in self._Characters_In_Builder: self._Characters_In_Builder_Lock.acquire() player = self._Characters_In_Builder[name] del self._Rooms[player.coords] # Remove the room that was being built since it wasn't finished player.coords = player.prev_coords # Save the player in the previous room del self._Characters_In_Builder[name] # Remove the player from the list of players self._Characters_In_Builder_Lock.release() loader.save_player(player) # Save the player self.logger.write_line("Removed player '%s'" % player.name)
def shutdown_game(self): # Winds the game down and creates a directory with all of the saved state information self.logger.write_line('Shutting down the game.') self._IsRunning = False # Causes all of the threads to close for player in self._Characters.values(): # Save all of the player states if isinstance(player, Player): loader.save_player(player) self.logger.write_line('Saved player states.') save_num = 1 while 1: # Create a directory to save the game state in directory = 'SaveState%d' % save_num if not os.path.exists(directory): os.makedirs(directory) os.makedirs(directory + '/objects') os.makedirs(directory + '/rooms') objects = [] self._Objects_Lock.acquire() for object in self._Objects.values(): objects.append(object) self._Objects_Lock.release() loader.save_objects(objects, directory) # Save all objects in the game for coords in self._Rooms: # Save the rooms to the save state directory path = directory + '/rooms/%d_%d_%d_%d.xml' % coords loader.save_room(self._Rooms[coords], path) self.logger.write_line("Saved game state to '%s'" % directory) break else: save_num += 1
def register_player(self, name, password, connection): global _Logged_in global _Player_Loc_Lock global _Player_Locations global _Player_Data_Lock global _Player_Data global _User_Pings_Lock global _User_Pings global _Threads_Lock global _Threads global _Players_Lock global _Players path = "login_file/%s.txt" % name location = (0, 0, 1, 0) player_affil = {} # Initially blank affiliation items = [] prev_coords = (0, 0, 1, 0) fih = 30 vote_history = {} print "Creating user: <%s>" % name logger.write_line("Creating user: <%s>" % name) RAProtocol.sendMessage("_affiliation_get_", connection) # Let them know we need their affiliation temp_affil = RAProtocol.receiveMessage(connection) # Get their affiliation a_string = temp_affil.split() if len(a_string) == 10: # Affiliation data logger.write_line("Received a user affiliation, confirmed.") cur_person = "" for i in range(0, len(a_string)): if i % 2 == 1: # This is an odd numbered cell, and as such is an affinity. player_affil[cur_person] = int(a_string[i]) else: # Even numbered, person cur_person = a_string[i] player_affil[cur_person] = 0 fin = open(path, "w") fin.write(password) # Save the player file fin.close() logger.write_line("Player login file created") logged_in = True _Logged_in.append(name) _Player_Loc_Lock.acquire() _Player_Locations[name] = "lobby" # Log in to the lobby initially _Player_Loc_Lock.release() _Player_Data_Lock.acquire() _Player_Data[name] = [] _Player_Data[name].append(location) # Add the location tuple to the list. _Player_Data_Lock.release() person = engine_classes.Player(name, (0, 0, 1, 0), (0, 0, 1, 0), player_affil) # Make this person loader.save_player(person) logger.write_line("Saving newly created player %s" % name) else: RAProtocol.sendMessage("_reject_", connection) logger.write_line("User login attempt rejected") return False if logged_in: _User_Pings_Lock.acquire() _User_Pings[name] = time.time() logger.write_line("Putting user into _User_Pings") _User_Pings_Lock.release() _Player_Data_Lock.acquire() _Player_Data[name].append(player_affil) # This may be {}, but we check for that later. _Player_Data[name].append(prev_coords) # (0,0,1,0) unless loaded as otherwise. _Player_Data[name].append(items) # [] if not loaded. _Player_Data[name].append(fih) # 30 if not loaded as otherwise. _Player_Data[name].append(vote_history) # {} if not loaded as otherwise. _Player_Data_Lock.release() logger.write_line("Finished adding additional data to _Player_Data[%s]" % name) # *create player state and add to _Player_States (to be added) # add new player I/O queues oqueue = Queue.Queue() _Player_OQueues_Lock.acquire() _Player_OQueues[name] = oqueue _Player_OQueues_Lock.release() line = "\r\n" for world in _World_list: line += "\t" + world + "\r\n" oqueue.put( "Welcome to the RenAdventure lobby!\r\nThe following worlds are available (type: join name_of_world):" + line ) ###TEST logger.write_line("Sending welcome message") line = "The following people are in the lobby: \r\n" _Player_Loc_Lock.acquire() for person in _Player_Locations: if ( _Player_Locations[person] == "lobby" and person != name ): # This person is in the lobby, and isn't the person we're listing people to. line += "\t" + person + "\r\n" _Player_Loc_Lock.release() if line != "The following people are in the lobby: \r\n": # We added players to this line oqueue.put(line) else: # There are no people in the lobby but you oqueue.put("There is no one else in the lobby at present.") # oqueue.put(engine_classes.engine_helper.get_room_text(name, location, engine)) #####NEED FILTER RAProtocol.sendMessage("_get_ip_", connection) # Tell them we need their IP for outgoing messages logger.write_line("Getting IP from client...") ip = RAProtocol.receiveMessage( connection ) # Get their IP from the client and make an outgoing connection with it. logger.write_line("Received the following IP: %s" % ip) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: sock.connect((ip, 8888)) # Connect to client on port 8888 for sending messages logger.write_line("Connection to socket on port 8888 made.") RAProtocol.sendMessage("_out_conn_made_", connection) ot = PlayerOutput(name, sock) ot.start() _Threads_Lock.acquire() _Threads.append(ot) _Threads_Lock.release() except: RAProtocol.sendMessage("_conn_failure_", connection) logger.write_line("Failed to connect.") return True else: RAProtocol.sendMessage("_reject_", connection) logger.write_line("User log in rejected") return False
def verify_player(self, name, password, connection): global _Logged_in global _Banned_names global _Logger global _User_Pings global _Player_Loc_Lock global _Player_Locations global _World_list global _Player_Data global _Player_Data_Lock global _Threads_Lock global _Threads path = "login_file/%s.txt" % name logger.write_line("Verifying player credentials") player_affil = {} # Current player's affiliation data. prev_coords = (0, 0, 1, 0) items = [] fih = 30 vote_history = {} if ( name not in _Logged_in and name not in _Banned_names ): # This person is not already logged in to the game, they may proceed to the next step. logger.write_line("This player is not already logged in, or banned. Proceed") if os.path.exists(path): # This file exists logger.write_line("This player's login file does indeed exist.") fin = open(path) pwd = fin.readline() fin.close() if password == pwd: # Login successful print "User <%s> authenticated" % name logger.write_line("User <%s> authenticated." % name) _Logged_in.append(name) _Player_Loc_Lock.acquire() _Player_Locations[name] = "lobby" # Log in to the lobby initially _Player_Loc_Lock.release() _Player_Data_Lock.acquire() _Player_Data[name] = [] # [0]: location tuple, [1]: affiliation dict _Player_Data_Lock.release() player_path = "players/%s.xml" % name try: person = loader.load_player(player_path) logger.write_line("Loading player file %s successful." % player_path) logged_in = True prev_coords = person.prev_coords items = person.items fih = person.fih vote_history = person.vote_history except: logger.write_line("Error loading player file %s, file does not exist" % player_path) print "Error loading player file %s, file does not exist" % player_path return False player_affil = person.affiliation # Load in the players affiliation location = person.coords _Player_Data_Lock.acquire() _Player_Data[name].append(location) # Add the location tuple to the list. _Player_Data_Lock.release() else: print "User <%s> failed to authenticate." % name logger.write_line("User <%s> failed to authenticate." % name) RAProtocol.sendMessage("_invalid_", connection) return False else: # File does not exist, require them to register RAProtocol.sendMessage( "_requires_registration_", connection ) # Tell them they are required to register and drop them? logger.write_line("User is not registered, ending.") return False if logged_in: # They have been logged in and their player data is known. _User_Pings_Lock.acquire() _User_Pings[name] = time.time() _User_Pings_Lock.release() _Player_Data_Lock.acquire() _Player_Data[name].append(player_affil) # This may be {}, but we check for that later. _Player_Data[name].append(prev_coords) # (0,0,1,0) unless loaded as otherwise. _Player_Data[name].append(items) # [] if not loaded. _Player_Data[name].append(fih) # 30 if not loaded as otherwise. _Player_Data[name].append(vote_history) # {} if not loaded as otherwise. _Player_Data_Lock.release() loader.save_player(person) # Save the file logger.write_line("Saving player file for user <%s>" % name) # *create player state and add to _Player_States (to be added) # add new player I/O queues oqueue = Queue.Queue() line = "\r\n" for world in _World_list: line += "\t" + world + "\r\n" oqueue.put( "Welcome to the RenAdventure lobby!\r\nThe following worlds are available (type: join name_of_world):" + line ) ###TEST _Player_OQueues_Lock.acquire() _Player_OQueues[name] = oqueue _Player_OQueues_Lock.release() line = "The following people are in the lobby: \r\n" _Player_Loc_Lock.acquire() for person in _Player_Locations: if ( _Player_Locations[person] == "lobby" and person != name ): # This person is in the lobby, and isn't the person we're listing people to. line += "\t" + person + "\r\n" _Player_Loc_Lock.release() if line != "The following people are in the lobby: \r\n": # We added players to this line oqueue.put(line) else: # There are no people in the lobby but you oqueue.put("There is no one else in the lobby at present.") # oqueue.put(engine_classes.engine_helper.get_room_text(name, location, engine)) #####NEED FILTER RAProtocol.sendMessage("_get_ip_", connection) # Tell them we need their IP for outgoing messages logger.write_line("Getting IP from client..") ip = RAProtocol.receiveMessage( connection ) # Get their IP from the client and make an outgoing connection with it. logger.write_line("Received the following IP from the client: %s" % ip) sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: sock.connect((ip, 8888)) # Connect to client on port 8888 for sending messages logger.write_line("Connected to socket.") RAProtocol.sendMessage("_out_conn_made_", connection) ot = PlayerOutput(name, sock) # Output thread for this player ot.start() _Threads_Lock.acquire() _Threads.append(ot) _Threads_Lock.release() except: RAProtocol.sendMessage("_connection_fail_", connection) logger.write_line("Failed to connect") _Players_Lock.acquire() _Players.append(name) _Players_Lock.release() return True # Player has been logged in, et cetera if they made it this far. elif name not in _Banned_names: # Player name is in _Logged_in, and not in _Banned_names print "Error, attempt to log in to an account already signed on" logger.write_line("Error, attempting to log in to an account already signed on: <%s>" % name) RAProtocol.sendMessage("already_logged_in", connection) return False else: # player_name in _Banned_names print "Attempt to log in with a banned name <%s>, account creation rejected" % name logger.write_line("Attempt to log in with a banned name <%s>, account creation rejected" % name) RAProtocol.sendMessage("banned_name", connection) return False
def addPlayer(self, conn, addr): """ Add a new player to the game """ global _Logged_in global _Banned_names global _Logger global _User_Pings global _Player_Loc_Lock global _Player_Locations global _World_list global _Player_Data global _Player_Data_Lock # receive message logged_in = False input_data = RAProtocol.receiveMessage(conn) if isinstance(input_data, RAProtocol.command): a_string = str(input_data.body) else: a_string = input_data a_string = a_string.split() #Split on space player_name = a_string[0] player_pass = a_string[1] player_affil = {} #Current player's affiliation data. prev_coords = (0,0,1,0) items = [] fih = 30 vote_history = {} path = 'login_file/%s.txt' % player_name if player_name not in _Logged_in and player_name not in _Banned_names: #This person is not already logged in to the game if os.path.exists(path): #This file exists fin = open(path) pwd = fin.readline() fin.close() if player_pass == pwd: #Login successful print 'User <%s> logged in' % player_name logger.write_line('User <%s> logged in.'%player_name) logged_in = True _Logged_in.append(player_name) _Player_Loc_Lock.acquire() _Player_Locations[player_name] = "lobby" #Log in to the lobby initially _Player_Loc_Lock.release() _Player_Data_Lock.acquire() _Player_Data[player_name] = [] #[0]: location tuple, [1]: affiliation dict _Player_Data_Lock.release() player_path = 'players/%s.xml'%player_name try: person = loader.load_player(player_path) prev_coords = person.prev_coords items = person.items fih = person.fih vote_history = person.vote_history except: logger.write_line("Error loading player file %s, file does not exist" % player_path) print "Error loading player file %s, file does not exist" % player_path player_affil = person.affiliation #Load in the players affiliation location = person.coords _Player_Data_Lock.acquire() _Player_Data[player_name].append(location) #Add the location tuple to the list. _Player_Data_Lock.release() else: print 'User <%s> failed to authenticate.' % player_name logger.write_line('User <%s> failed to authenticate.'%player_name) RAProtocol.sendMessage('invalid', conn) else: #File does not exist if len(a_string) == 2: #We just got name and password, not affiliation RAProtocol.sendMessage('affiliation_get', conn) print 'Getting user affiliation' logger.write_line('Required user affiliation from <%s>'%player_name) elif len(a_string) == 12: #We got the affiliation data this time. print 'Creating user: <%s>'% player_name logger.write_line('Creating user: <%s>'%player_name) cur_person = '' for i in range(2, len(a_string)): if i % 2 == 1: #This is an odd numbered cell, and as such is an affinity. player_affil[cur_person] = int(a_string[i]) else: #Even numbered, person cur_person = a_string[i] player_affil[cur_person] = 0 fin = open(path, 'w') fin.write(player_pass) fin.close() location = (0,0,1,0) logged_in = True _Logged_in.append(player_name) _Player_Loc_Lock.acquire() _Player_Locations[player_name] = "lobby" #Log in to the lobby initially _Player_Loc_Lock.release() _Player_Data_Lock.acquire() _Player_Data[player_name] = [] _Player_Data[player_name].append(location) #Add the location tuple to the list. _Player_Data_Lock.release() person = engine_classes.Player(player_name, (0,0,1,0), (0,0,1,0), player_affil) #Make this person if logged_in: _User_Pings_Lock.acquire() _User_Pings[player_name] = time.time() _User_Pings_Lock.release() _Player_Data_Lock.acquire() _Player_Data[player_name].append(player_affil) #This may be {}, but we check for that later. _Player_Data[player_name].append(prev_coords) #(0,0,1,0) unless loaded as otherwise. _Player_Data[player_name].append(items) #[] if not loaded. _Player_Data[player_name].append(fih) #30 if not loaded as otherwise. _Player_Data[player_name].append(vote_history) #{} if not loaded as otherwise. _Player_Data_Lock.release() loader.save_player(person) #Save the file! logger.write_line("Creating player file for user <%s>" % player_name) # *create player state and add to _Player_States (to be added) # add new player I/O queues oqueue = Queue.Queue() line = "\r\n" for world in _World_list: eng = _World_list[world] if eng._IsRunning: line += "\t"+world+"\r\n" oqueue.put("Welcome to the RenAdventure lobby!\r\nThe following worlds are available (type: join name_of_world):"+line) ###TEST line = "The following people are in the lobby: \r\n" _Player_Loc_Lock.acquire() for person in _Player_Locations: if _Player_Locations[person] == 'lobby' and person != player_name: #This person is in the lobby, and isn't the person we're listing people to. line+= "\t"+person+'\r\n' _Player_Loc_Lock.release() if line != "The following people are in the lobby: \r\n": #We added players to this line oqueue.put(line) else: #There are no people in the lobby but you oqueue.put("There is no one else in the lobby at present.") #oqueue.put(engine_classes.engine_helper.get_room_text(player_name, location, engine)) #####NEED FILTER _Player_OQueues_Lock.acquire() _Player_OQueues[player_name] = oqueue _Player_Loc_Lock.acquire() for person in _Player_Locations: if _Player_Locations[person] == 'lobby' and person != player_name: #This person is in the lobby and is not who just joined. Tell everyone else. _Player_OQueues[person].put("%s has joined the lobby" % player_name) _Player_Loc_Lock.release() _Player_OQueues_Lock.release() # Get I/O port self.spawn_port_lock.acquire() iport = self.spawn_port oport = self.spawn_port + 1 self.spawn_port += 2 self.spawn_port_lock.release() # spin off new PlayerI/O threads ithread = PlayerInput(iport, player_name) othread = PlayerOutput(oqueue, addr, oport, player_name) _Threads_Lock.acquire() _Threads.append(ithread) _Threads.append(othread) _Threads_Lock.release() _InThreads[player_name] = True _OutThreads[player_name] = True ithread.start() othread.start() # send new I/O ports to communicate on ports = str(iport) + " " + str(oport) message = str(ports) RAProtocol.sendMessage(message, conn) # add player to _Players _Players_Lock.acquire() _Players.append(player_name) _Players_Lock.release() conn.close() print player_name + " added to the game." logger.write_line('<'+player_name+'>'+" added to the game.") elif player_name not in _Banned_names: #Player name is in _Logged_in, and not in _Banned_names print 'Error, attempt to log in to an account already signed on' logger.write_line('Error, attempting to log in to an account already signed on: <%s>'%player_name) RAProtocol.sendMessage('already_logged_in', conn) else: #player_name in _Banned_names print 'Attempt to log in with a banned name <%s>, account creation rejected' % player_name logger.write_line('Attempt to log in with a banned name <%s>, account creation rejected'%player_name) RAProtocol.sendMessage('banned_name',conn)