From: <Blu...@us...> - 2009-12-23 13:17:17
|
Revision: 330 http://virtplayground.svn.sourceforge.net/virtplayground/?rev=330&view=rev Author: BlueWolf_ Date: 2009-12-23 13:17:00 +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 Modified Paths: -------------- trunk/client/core/callback.py trunk/client/core/client.py trunk/client/core/parser.py Modified: trunk/client/core/callback.py =================================================================== --- trunk/client/core/callback.py 2009-12-23 13:16:28 UTC (rev 329) +++ trunk/client/core/callback.py 2009-12-23 13:17:00 UTC (rev 330) @@ -109,7 +109,7 @@ """ pass - def logged_in(self, username, cid): + def logged_in(self, username, cid, owner): """ Called when we are logged in. @@ -120,6 +120,9 @@ cid: The unique client-id for this connection. Also available in client.cid + owner: + This is the owner-username for this bot. This variable + will be None when you log in as a normal user This is a placeholder. If you want to catch this event, overwrite this in your own callback @@ -139,6 +142,8 @@ * "bot limit reached" - There're to much bots logged in for your account * "login blocked" - You (or your IP) are blocked + * "duplicate user" - There is already someone + online with this username """ pass Modified: trunk/client/core/client.py =================================================================== --- trunk/client/core/client.py 2009-12-23 13:16:28 UTC (rev 329) +++ trunk/client/core/client.py 2009-12-23 13:17:00 UTC (rev 330) @@ -58,32 +58,40 @@ self.__sock = None self.__pinger = None + # This will be available ([sh]ared) to al modules in the core + self.__sh = {} + + self.__sh['call'] = callback_class + self.__sh['core'] = self + self.__sh['isbot'] = None + # Create all default settings self.__config_default(config) - self.__config = config + self.__sh['config'] = config - # Class that parsers all incomming data - self.__parse = Parser(self.__call, self) - # So the client knows if we are online. Is used for # disconnecting - self.__is_online = False + self.__sh['is_online'] = False # Treading-event so that run() waits before it's allowed to # connect self.__do_connect = threading.Event() self.__do_connect.clear() - # Auto log in after connecting. Used by self.connect - self.__login_after_connecting = () + # Auto log in after connecting. + self.__sh['login_after_connecting'] = () # RSA - self.__rsakey = None + self.__sh['rsakey'] = None # Info after logging in self.username = None + self.owner = None self.cid = None # Connection-id + # Class that parsers all incomming data + self.__parse = Parser(self.__sh) + threading.Thread.__init__(self) self.setDaemon(True) @@ -91,18 +99,19 @@ def __config_default(self, config): - config.setdefault('app_name', __name__) - config.setdefault('app_version', __version__) + config['app_name'] = str(config.get('app_name', __name__)) + config['app_version'] = str(config.get('app_version', + __version__)) - def connect(self, host, port, usr = None, pwd = None, bot = False): + def connect(self, host, port): """ Will (try to) connect to the server on `host`:`port`. If you want to reconnect, you have to close the connection first, if it's still open. - You can optionally let it login automatically. See client.login - for the usr, pwd and bot variables. + You can to Client.login and Client.bot_login directly after + this. It will be done as soon as it has received a rsa-key. """ self.__host = host @@ -111,13 +120,6 @@ if self.__sock: raise ConnectionError("You are already connected!") - # Should we login after connecting? - if usr and pwd: - self.__login_after_connecting = (usr, pwd, bot) - else: - self.__login_after_connecting = (); - - self.__do_connect.set() # Releasing the hounds @@ -128,7 +130,7 @@ while 1: self.__do_connect.wait() # Wait to connect - self.__is_online = True + self.__sh['is_online'] = True disconnect_reason = None self.__sock = socket.socket(socket.AF_INET, @@ -137,7 +139,7 @@ while 1: try: self.__sock.connect((self.__host, - self.__port)) + self.__port)) break except: time.sleep(1) @@ -171,15 +173,14 @@ for msg in data: self.__parse(simplejson.loads(msg)) - if self.__is_online: + if self.__sh['is_online']: self.close(disconnect_reason) - def login(self, usr, pwd, bot = False): + def login(self, usr, pwd): """ - Log in to the server. You should have received the RSA-key - before calling this! - pwd is expected to be sha1. Bot should be True or False. Bots - have different functions in VP. + Log in to the server as a normal user. If the RSA-key wasn't + received yet, it will login after is has received the key. pwd + is expected to be sha1. >>> import hashlib >>> hashlib.sha1("MyVerySecretPassword").hexdigest() @@ -189,34 +190,71 @@ if self.cid != None: raise LoginError("You are already logged in") - # Get our login - if not (usr and pwd): - if self.__login_after_connecting: - usr, pwd, bot = self.__login_after_connecting - else: - return # Just ignore it.. + if not self.__sh['rsakey']: + # Save this + self.__sh['login_after_connecting'] = (self.login, + (usr, pwd)) + return if not self.__sock: raise ConnectionError("You are not connected!") - if not self.__rsakey: - raise LoginError("No rsa-key available") + self.__sh['isbot'] = False # Convert pwd - pwd = rsa.encrypt(pwd, self.__rsakey) + pwd = rsa.encrypt(pwd, self.__sh['rsakey']) # Log in self.send("login", { "usr": usr, "pwd": pwd, - "bot": bool(bot), + "bot": False, "for": "VP", - "client": ( self.__config['app_name'], - self.__config['app_version'] + "client": ( self.__sh['config']['app_name'], + self.__sh['config']['app_version'] ) }) + def login_bot(self, owner, pwd, screenname): + """ + Log in as a bot. If the RSA-key wasn't received yet, it will + login after is has received the key. pwd is expected to be sha1. + + >>> import hashlib + >>> hashlib.sha1("MyVerySecretPassword").hexdigest() + 'dc2275e9f1e53926dce503ec7d9df9ac9ce07dfc' + """ + + if self.cid != None: + raise LoginError("You are already logged in") + + if not self.__sh['rsakey']: + # Save this + self.__sh['login_after_connecting'] = (self.login_bot, + (owner, pwd, screenname)) + return + + if not self.__sock: + raise ConnectionError("You are not connected!") + + self.__sh['isbot'] = True + + # Convert pwd + pwd = rsa.encrypt(pwd, self.__sh['rsakey']) + + # Log in + self.send("login", { + "usr": owner, + "pwd": pwd, + "name": screenname, + "bot": True, + "for": "VP", + "client": ( self.__sh['config']['app_name'], + self.__sh['config']['app_version'] + ) + }) + def send(self, data_header, data_body = {}): """ Sends `data_body` of type `data_header` to the server. It will @@ -240,7 +278,7 @@ callback. If not, you can reuse this class by calling `connect`. """ - if not self.__is_online: + if not self.__sh['is_online']: if reason == "manual": # Annoy the user raise ConnectionError("The connection is " + \ @@ -251,13 +289,14 @@ self.__do_connect.clear() # Block the thread-loop - self.__is_online = False + self.__sh['is_online'] = False self.__pinger.cancel() self.__pinger = None # Reset variables - self.__rsa = None + self.__sh['rsakey'] = None self.username = None + self.owner = None self.cid = None try: self.__sock.shutdown(0) @@ -268,6 +307,9 @@ if self.__call.disconnected(reason): # Reconnect self.__do_connect.set() + else: + # Remove auto-login + self.__sh['login_after_connecting'] = () class __Pinger(): @@ -288,7 +330,7 @@ if self.running == False: return #Ping! - self.send('PNG', {}) + self.send('ping', {}) #Start again self.timer = threading.Timer(30, self.run) Modified: trunk/client/core/parser.py =================================================================== --- trunk/client/core/parser.py 2009-12-23 13:16:28 UTC (rev 329) +++ trunk/client/core/parser.py 2009-12-23 13:17:00 UTC (rev 330) @@ -16,15 +16,16 @@ ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. class Parser(): - def __init__(self, callback, client): + def __init__(self, sh): """ This class parses all received messages from the server. """ - self.callback = callback - self.client = client + self.sh = sh + self.call = sh['call'] + self.core = sh['core'] def __call__(self, msg): - self.callback.data_received(msg) + self.call.data_received(msg) head = msg.keys()[0] body = msg[head] @@ -45,7 +46,7 @@ """ # reason - Why it's going to disconnect us - self.client.close(msg["reason"]) + self.core.close(msg["reason"]) def rsa(self, msg): """ @@ -54,23 +55,37 @@ * public - The public rsa-key, which contains e & n """ - self.client._Client__rsakey = msg['public'] + self.sh['rsakey'] = msg['public'] - self.callback.received_rsa(msg['public']) + self.call.received_rsa(msg['public']) - self.client.login(None, None) + if self.sh['login_after_connecting'] != (): + login = self.sh['login_after_connecting'] + login[0](*login[1]) + def login(self, msg): """ Called when we can log in * username - The username (with right caps) * cid - The server's connection-id + * owner - The owner for this bot (only when logging in + as bot!) """ - self.client.username = msg['username'] - self.client.cid = msg['cid'] + if self.sh['isbot']: # Logging in as bot + self.core.owner = msg['owner'] + self.core.username = msg['username'] + self.core.cid = msg['cid'] + + self.call.logged_in(msg['username'], msg['cid'], + msg['owner']) - self.callback.logged_in(msg['username'], msg['cid']) + else: # Logging in as user + self.core.username = msg['username'] + self.core.cid = msg['cid'] + + self.call.logged_in(msg['username'], msg['cid'], None) def error(self, msg): """ @@ -80,14 +95,18 @@ "login not allowed" - User may not log in right now "bot limit reached" - Too much bots logged in for this user "login blocked" - The user (or IP) is blocked + "duplicate user" - There is already someone online with + this username """ if msg['reason'] == "bad login": - self.callback.failed_logging_in("bad login") + self.call.failed_logging_in("bad login") elif msg['reason'] == "login not allowed": - self.callback.failed_logging_in("login not allowed") + self.call.failed_logging_in("login not allowed") elif msg['reason'] == "bot limit reached": - self.callback.failed_logging_in("bot limit reached") + self.call.failed_logging_in("bot limit reached") elif msg['reason'] == "login blocked": - self.callback.failed_logging_in("login blocked") + self.call.failed_logging_in("login blocked") + elif msg['reason'] == "duplicate user": + self.call.failed_logging_in("duplicate user") This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |