From: <Blu...@us...> - 2009-12-23 13:16:43
|
Revision: 329 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=329&view=rev Author: BlueWolf_ Date: 2009-12-23 13:16:28 +0000 (Wed, 23 Dec 2009) Log Message: ----------- Client can now log in as bot! The core is now using a dict to share variables across all modules. Fixing a bot where a client sometimes couldn't log in. Modified Paths: -------------- trunk/server/core/callback.py trunk/server/core/parser.py trunk/server/core/server.py Modified: trunk/server/core/callback.py =================================================================== --- trunk/server/core/callback.py 2009-12-19 20:59:37 UTC (rev 328) +++ trunk/server/core/callback.py 2009-12-23 13:16:28 UTC (rev 329) @@ -170,7 +170,7 @@ return False - def may_login(self, username, ip, bot, bots): + def may_login(self, username, screenname, ip, bot, bots): """ This is called after (a succesfull) callback.check_login. Use this to block certain users or IP's or block an additional bot @@ -179,13 +179,17 @@ Return True when the user (or bot) may log in and False when it may not. This will send an "not allowed" error. If you wish to send an other error, return the error. An example may be: - * "login not allowed" - * "bot limit reached" - * "login blocked" + * "login not allowed" - Login is not allowed right now + * "bot limit reached" - User has to much bots running + * "login blocked" - User is blocked + This function will return True by default. username: - The username for this user + The username for this user / owner for this bot + screenname: + The name the users see. This is only different from + username when a bot logs in ip: The IP-adress this user has bot: Modified: trunk/server/core/parser.py =================================================================== --- trunk/server/core/parser.py 2009-12-19 20:59:37 UTC (rev 328) +++ trunk/server/core/parser.py 2009-12-23 13:16:28 UTC (rev 329) @@ -18,18 +18,19 @@ import rsa, hashlib class Parser(): - def __init__(self, callback, server): + def __init__(self, sh): """ This class parses all received messages from the client. """ - self.callback = callback - self.server = server + self.sh = sh + self.call = sh['call'] + self.core = sh['core'] # Shortkeys - self.clients = self.server.clients + self.clients = self.core.clients def __call__(self, cid, msg): - self.callback.data_received(cid, msg) + self.call.data_received(cid, msg) head = msg.keys()[0] body = msg[head] @@ -38,7 +39,35 @@ if (func): func(cid, body) + def _check_double_user(self, isbot, screenname, data): + """ + Checks for an user or bot with the same name + """ + + # Check if there isn't already a bot online + # with this name + for id, cl in self.clients.items(): + if cl['status'] == "VP" and \ + cl['bot'] == True and \ + cl['user'] == screenname: + # Our client cannot log in + data.send("error", { + "reason": "duplicate user" + }) + return False + + if isbot == False: + # Check for the same user + for id, cl in self.clients.items(): + if cl['status'] == "VP" and \ + cl['bot'] == False and \ + cl['user'] == screenname: + # Disconnect this user + cl['con'].close_msg('duplicate') + + return True + def login(self, cid, msg): """ Send when the users wants to log in @@ -64,9 +93,9 @@ pwd = hashlib.sha1(pwd).hexdigest() if msg['for'] == 'VP': - + # Check for login - username = self.callback.check_login(msg['usr'], pwd) + username = self.call.check_login(msg['usr'], pwd) if username == False: # No login, bad user! @@ -77,15 +106,21 @@ # Find out how many bots this user has running bots = [] - for id, client in self.clients.items(): - if client['status'] == 'VP' and \ - client['user'] == username and \ - client['bot'] == True: + for id, cl in self.clients.items(): + if cl['status'] == 'VP' and \ + cl['owner'] == username and \ + cl['bot'] == True: bots.append(id) + # Get screenname + screenname = username + if msg['bot']: + screenname = self.sh['config']['bot_names'] % \ + msg['name'] + # Check if the user may log in - may_login = self.callback.may_login(username, - data.get_ip(), msg['bot'], bots) + may_login = self.call.may_login(username, + screenname, data.get_ip(), msg['bot'], bots) if may_login != True: # User may not login if may_login == False: @@ -99,20 +134,14 @@ if msg['bot'] == False: # Just an ordinary user - - # Check if the user is already logged in - for id, cl in self.clients.items(): - if cl['status'] == "VP" and \ - cl['bot'] == False and \ - cl['user'] == username: - # Disconnect user - cl['con'].send("disconnect", - {'reason':'duplicate'}) - cl['con'].close('duplicate') - - + + if self._check_double_user(False, username, + data) == False: + return + + # Log the user in - client['user'] = username + client['user'] = screenname client['bot'] = False client['status'] = "VP" @@ -122,5 +151,21 @@ }) else: # Client is bot - pass #TODO + if self._check_double_user(True, screenname, + data) == False: + return + + + # log the bot in + client['user'] = screenname + client['bot'] = True + client['owner'] = username + client['status'] = "VP" + + data.send("login", { + "username": screenname, + "owner": username, + "cid": cid + }) + Modified: trunk/server/core/server.py =================================================================== --- trunk/server/core/server.py 2009-12-19 20:59:37 UTC (rev 328) +++ trunk/server/core/server.py 2009-12-23 13:16:28 UTC (rev 329) @@ -65,6 +65,13 @@ -rsa_bits: How many bits the rsa uses for encrypting the password. More = more secure but slower to generate. Default is 64 + + -bot_names + How the name for a bot should be. Use %s where the + suggested name should be. Default is [%s]. When a bot + logs in as "test", it will be displayed as "[test]". + Choose something that won't interfere with existing + users. """ @@ -72,12 +79,18 @@ self.__sock = None self.__call = callback_class + # This will be available ([sh]ared) to al modules in the core + self.__sh = {} + + self.__sh['call'] = callback_class + self.__sh['core'] = self + # Create all default settings self.__config_default(config) - self.__config = config + self.__sh['config'] = config self.clients = {} - self.__parse = Parser(self.__call, self) + self.__parse = Parser(self.__sh) threading.Thread.__init__(self) @@ -85,10 +98,12 @@ """ Create all the config-defaults """ - config.setdefault('host', '') - config.setdefault('port', 5162) - config.setdefault('max_connections', 0) - config.setdefault('rsa_bits', 64) + config['host'] = str(config.get('host', '')) + config['port'] = int(config.get('port', 5162)) + config['max_connections'] = int( + config.get('max_connections', 0)) + config['rsa_bits'] = int(config.get('rsa_bits', 64)) + config['bot_names'] = str(config.get('bot_names', "[%s]")) def start_server(self): @@ -119,8 +134,8 @@ #Try to claim the pre-specified port while 1: try: - self.__sock.bind((self.__config['host'], - self.__config['port'])) + self.__sock.bind((self.__sh['config']['host'], + self.__sh['config']['port'])) break except: time.sleep(1) @@ -135,14 +150,14 @@ # Server has gone offline return - if self.__config['max_connections'] and \ + if self.__sh['config']['max_connections'] and \ len(self.clients) >= \ - self.__config['max_connections']: + self.__sh['config']['max_connections']: #We exceeded our connection limit, but maybe #this is a special occasion? Send callback! if not self.__call.connection_limit_exceeded( len(self.clients), - self.__config['max_connections'], + self.__sh['config']['max_connections'], addr[0], addr[1]): #We're full, kick him out @@ -164,9 +179,8 @@ self.clients[cid] = { "status": "", - "con": Client(cid, sock, self.clients, - self.__call, self.__parse, - self.__config) + "con": Client(cid, sock, self.__sh, + self.__parse) } if self.__call.connection_opened(cid, @@ -202,14 +216,14 @@ Each client has it's own class. """ - def __init__(self, cid, sock, clients, callback, parser, config): + def __init__(self, cid, sock, sh, parser): self.__cid = cid self.__sock = sock - self.__clients = clients - self.__call = callback + self.__sh = sh self.__parser = parser - self.__config = config + self.__clients = sh['core'].clients + self.__call = sh['call'] self.is_online = True threading.Thread.__init__(self) @@ -247,7 +261,7 @@ # Before the client can log in, we first need to create a # rsa-key public, private = rsa.gen_pubpriv_keys( - self.__config['rsa_bits']) + self.__sh['config']['rsa_bits']) self.__clients[self.__cid]['rsa'] = private self.send("rsa", {"public": public}) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |