def perform_getpd(self, data_parsed): profile = self.db.pd_get(self.profileid, data_parsed['dindex'], data_parsed['ptype']) data = "" keys = data_parsed['keys'].split('\x01') profile_data = None if profile != None and 'data' in profile: profile_data = gs_query.parse_gamespy_message("\\prof\\" + profile['data'] + "\\final\\") if profile_data != None: profile_data = profile_data[0][0] for key in keys: if key != "__cmd__" and key != "__cmd_val__" and key != "": data += "\\" data += key data += "\\" if key in profile_data: data += profile_data[key] modified = int(time.time()) msg_d = [] msg_d.append(('__cmd__', "getpdr")) msg_d.append(('__cmd_val__', 1)) msg_d.append(('lid', self.lid)) msg_d.append(('pid', self.profileid)) msg_d.append(('mod', modified)) msg_d.append(('length', len(data))) msg_d.append(('data', data)) msg = gs_query.create_gamespy_message(msg_d) self.log(logging.DEBUG, "SENDING: '%s'..." % msg)
def rawDataReceived(self, data): try: # Decrypt packet self.remaining_message += data if "\\final\\" not in data: return msg = str(self.crypt(self.remaining_message)) self.data = msg self.remaining_message = "" commands, self.remaining_message = gs_query.parse_gamespy_message(msg) logger.log(logging.DEBUG, "STATS RESPONSE: %s" % msg) cmds = { "auth": self.perform_auth, "authp": self.perform_authp, "ka": self.perform_ka, "setpd": self.perform_setpd, "getpd": self.perform_getpd, "newgame": self.perform_newgame, "updgame": self.perform_updgame, } def cmd_err(data_parsed): logger.log(logging.DEBUG, "Found unknown command, don't know how to handle '%s'.", data_parsed['__cmd__']) for data_parsed in commands: print(data_parsed) cmds.get(data_parsed['__cmd__'], cmd_err)(data_parsed) except: self.log(logging.ERROR, "Unknown exception: %s" % traceback.format_exc())
def rawDataReceived(self, data): # Decrypt packet msg = str(self.crypt(data)) logger.log(logging.DEBUG, "STATS RESPONSE: %s" % msg) #data = self.leftover + data commands, self.leftover = gs_query.parse_gamespy_message(msg) print commands for data_parsed in commands: print data_parsed if data_parsed['__cmd__'] == "auth": self.perform_auth(data_parsed) elif data_parsed['__cmd__'] == "authp": self.perform_authp(data_parsed) elif data_parsed['__cmd__'] == "ka": self.perform_ka(data_parsed) elif data_parsed['__cmd__'] == "setpd": self.perform_setpd(data_parsed, msg) elif data_parsed['__cmd__'] == "getpd": self.perform_getpd(data_parsed) elif data_parsed['__cmd__'] == "newgame": self.perform_newgame(data_parsed) elif data_parsed['__cmd__'] == "updgame": self.perform_updgame(data_parsed) else: logger.log( logging.DEBUG, "Found unknown command, don't know how to handle '%s'." % data_parsed['__cmd__'])
def rawDataReceived(self, data): # Decrypt packet msg = str(self.crypt(data)) logger.log(logging.DEBUG, "STATS RESPONSE: %s" % msg) #data = self.leftover + data commands, self.leftover = gs_query.parse_gamespy_message(msg) print commands for data_parsed in commands: print data_parsed if data_parsed['__cmd__'] == "auth": self.perform_auth(data_parsed) elif data_parsed['__cmd__'] == "authp": self.perform_authp(data_parsed) elif data_parsed['__cmd__'] == "ka": self.perform_ka(data_parsed) elif data_parsed['__cmd__'] == "setpd": self.perform_setpd(data_parsed, msg) elif data_parsed['__cmd__'] == "getpd": self.perform_getpd(data_parsed) elif data_parsed['__cmd__'] == "newgame": self.perform_newgame(data_parsed) elif data_parsed['__cmd__'] == "updgame": self.perform_updgame(data_parsed) else: logger.log(logging.DEBUG, "Found unknown command, don't know how to handle '%s'." % data_parsed['__cmd__'])
def rawDataReceived(self, data): self.log(logging.DEBUG, "RESPONSE: '%s'..." % data) # In the case where command string is too big to fit into one read, any parts that could not be successfully # parsed are stored in the variable remaining_message. On the next rawDataReceived command, the remaining # message and the data are combined to create a full command. data = self.remaining_message + data commands, self.remaining_message = gs_query.parse_gamespy_message(data) for data_parsed in commands: self.log(-1, data_parsed) if data_parsed['__cmd__'] == "login": self.perform_login(data_parsed) elif data_parsed['__cmd__'] == "logout": self.perform_logout(data_parsed) elif data_parsed['__cmd__'] == "getprofile": self.perform_getprofile(data_parsed) elif data_parsed['__cmd__'] == "updatepro": self.perform_updatepro(data_parsed) elif data_parsed['__cmd__'] == "ka": self.perform_ka(data_parsed) elif data_parsed['__cmd__'] == "status": self.perform_status(data_parsed) elif data_parsed['__cmd__'] == "bm": self.perform_bm(data_parsed) elif data_parsed['__cmd__'] == "addbuddy": self.perform_addbuddy(data_parsed) elif data_parsed['__cmd__'] == "delbuddy": self.perform_delbuddy(data_parsed) elif data_parsed['__cmd__'] == "authadd": self.perform_authadd(data_parsed) else: # Maybe write unknown commands to a separate file later so new data can be collected more easily? self.log(logging.ERROR, "Found unknown command, don't know how to handle '%s'." % data_parsed['__cmd__'])
def perform_getpd(self, data_parsed): profile = self.db.pd_get(self.profileid, data_parsed['dindex'], data_parsed['ptype']) keys = data_parsed['keys'].split('\x01') profile_data = None if profile != None and 'data' in profile: profile_data = gs_query.parse_gamespy_message("\\prof\\" + profile['data'] + "\\final\\") data = "" if profile_data != None: profile_data = profile_data[0][0] for key in (key for key in keys if key not in ("__cmd__", "__cmd_val__", "")): data += "\\" + key + "\\" # this WILL error if profile_data isn't properly set above if key in profile_data: data += profile_data[key] modified = int(time.time()) msg = gs_query.create_gamespy_message([ ('__cmd__', "getpdr"), ('__cmd_val__', 1), ('lid', self.lid), ('pid', self.profileid), ('mod', modified), ('length', len(data)), ('data', data), ]) self.log(logging.DEBUG, "SENDING: '%s'..." % msg)
def rawDataReceived(self, data): try: self.log(logging.DEBUG, "RESPONSE: '%s'...", data) # In the case where command string is too big to fit into one # read, any parts that could not be successfully parsed are # stored in the variable remaining_message. On the next # rawDataReceived command, the remaining message and the data # are combined to create a full command. data = self.remaining_message + data # Check to make sure the data buffer starts with a valid command. if len(data) > 0 and data[0] != '\\': # There is data in the buffer but it doesn't start with a \ so # there's no chance of it being valid. Look for the first # instance of \final\ and remove everything before it. If # \final\ is not in the command string then ignore it. final = "\\final\\" data = data[data.index(final) + len(final):] \ if final in data else "" commands, self.remaining_message = \ gs_query.parse_gamespy_message(data) if self.db.is_ip_banned({'ipaddr': self.address.host}): self.log(logging.DEBUG, "**** Banned user, closing network socket for %s...", self.address.host) self.transport.abortConnection() return cmds = { "login": self.perform_login, "logout": self.perform_logout, "getprofile": self.perform_getprofile, "updatepro": self.perform_updatepro, "ka": self.perform_ka, "status": self.perform_status, "bm": self.perform_bm, "addbuddy": self.perform_addbuddy, "delbuddy": self.perform_delbuddy, "authadd": self.perform_authadd, } def cmd_err(data_parsed): # Maybe write unknown commands to a separate file later so # new data can be collected more easily? self.log( logging.ERROR, "Found unknown command, don't know how to handle" " '%s'.", data_parsed['__cmd__']) for data_parsed in commands: # self.log(-1, data_parsed) self.log(logging.DEBUG, "%s", data_parsed) cmds.get(data_parsed['__cmd__'], cmd_err)(data_parsed) except: self.log(logging.ERROR, "Unknown exception: %s", traceback.format_exc())
def rawDataReceived(self, data): try: self.log(logging.DEBUG, "RESPONSE: '%s'...", data) # In the case where command string is too big to fit into one # read, any parts that could not be successfully parsed are # stored in the variable remaining_message. On the next # rawDataReceived command, the remaining message and the data # are combined to create a full command. data = self.remaining_message + data # Check to make sure the data buffer starts with a valid command. if len(data) > 0 and data[0] != '\\': # There is data in the buffer but it doesn't start with a \ so # there's no chance of it being valid. Look for the first # instance of \final\ and remove everything before it. If # \final\ is not in the command string then ignore it. final = "\\final\\" data = data[data.index(final) + len(final):] \ if final in data else "" commands, self.remaining_message = \ gs_query.parse_gamespy_message(data) cmds = { "login": self.perform_login, "logout": self.perform_logout, "getprofile": self.perform_getprofile, "updatepro": self.perform_updatepro, "ka": self.perform_ka, "status": self.perform_status, "bm": self.perform_bm, "addbuddy": self.perform_addbuddy, "delbuddy": self.perform_delbuddy, "authadd": self.perform_authadd, } def cmd_err(data_parsed): # Maybe write unknown commands to a separate file later so # new data can be collected more easily? self.log(logging.ERROR, "Found unknown command, don't know how to handle" " '%s'.", data_parsed['__cmd__']) for data_parsed in commands: # self.log(-1, data_parsed) self.log(logging.DEBUG, "%s", data_parsed) cmds.get(data_parsed['__cmd__'], cmd_err)(data_parsed) except: self.log(logging.ERROR, "Unknown exception: %s", traceback.format_exc())
def rawDataReceived(self, data): self.log(logging.DEBUG, "SEARCH RESPONSE: %s" % data) data = self.leftover + data commands, self.leftover = gs_query.parse_gamespy_message(data) for data_parsed in commands: print data_parsed if data_parsed['__cmd__'] == "otherslist": self.perform_otherslist(data_parsed) else: self.log(logging.DEBUG, "Found unknown search command, don't know how to handle '%s'." % data_parsed['__cmd__'])
def perform_getpd(self, data_parsed): pid = int(data_parsed['pid']) profile = self.db.pd_get(pid, data_parsed['dindex'], data_parsed['ptype']) if profile == None: self.log(logging.WARNING, "Could not find profile for %d %s %s" % (pid, data_parsed['dindex'], data_parsed['ptype'])) keys = data_parsed['keys'].split('\x01') profile_data = None data = "" # Someone figure out if this is actually a good way to handle this when no profile is found if profile != None and 'data' in profile: profile_data = profile['data'] if profile_data.endswith("\\"): profile_data = profile_data[:-1] profile_data = gs_query.parse_gamespy_message("\\prof\\" + profile_data + "\\final\\") if profile_data != None: profile_data = profile_data[0][0] else: self.log(logging.WARNING, "Could not get data section from profile for %d" % pid) if len(keys) > 0 and keys[0] != "": for key in (key for key in keys if key not in ("__cmd__", "__cmd_val__", "")): data += "\\" + key + "\\" if profile_data != None and key in profile_data: data += profile_data[key] else: self.log(logging.WARNING, "No keys requested, defaulting to all keys: %s" % (profile['data'])) data = profile['data'] modified = int(time.time()) msg = gs_query.create_gamespy_message([ ('__cmd__', "getpdr"), ('__cmd_val__', 1), ('lid', self.lid), ('pid', pid), ('mod', modified), ('length', len(data)), ('data', data), ]) self.log(logging.DEBUG, "SENDING: '%s'..." % msg) msg = self.crypt(msg) self.transport.write(bytes(msg))
def rawDataReceived(self, data): logger.log(logging.DEBUG, "SEARCH RESPONSE: %s" % data) data = self.leftover + data commands, self.leftover = gs_query.parse_gamespy_message(data) for data_parsed in commands: print data_parsed if data_parsed['__cmd__'] == "otherslist": self.perform_otherslist(data_parsed) else: logger.log( logging.DEBUG, "Found unknown search command, don't know how to handle '%s'." % data_parsed['__cmd__'])
def rawDataReceived(self, data): try: logger.log(logging.DEBUG, "SEARCH RESPONSE: %s", data) data = self.leftover + data commands, self.leftover = gs_query.parse_gamespy_message(data) for data_parsed in commands: print data_parsed if data_parsed['__cmd__'] == "otherslist": self.perform_otherslist(data_parsed) else: logger.log( logging.DEBUG, "Found unknown search command, don't know" " how to handle '%s'.", data_parsed['__cmd__']) except: logger.log(logging.ERROR, "Unknown exception: %s", traceback.format_exc())
def rawDataReceived(self, data): try: logger.log(logging.DEBUG, "SEARCH RESPONSE: %s", data) data = self.leftover + data commands, self.leftover = gs_query.parse_gamespy_message(data) for data_parsed in commands: print data_parsed if data_parsed['__cmd__'] == "otherslist": self.perform_otherslist(data_parsed) else: logger.log(logging.DEBUG, "Found unknown search command, don't know" " how to handle '%s'.", data_parsed['__cmd__']) except: logger.log(logging.ERROR, "Unknown exception: %s", traceback.format_exc())
def rawDataReceived(self, data): self.log(logging.DEBUG, "RESPONSE: '%s'..." % data) # In the case where command string is too big to fit into one read, any parts that could not be successfully # parsed are stored in the variable remaining_message. On the next rawDataReceived command, the remaining # message and the data are combined to create a full command. data = self.remaining_message + data commands, self.remaining_message = gs_query.parse_gamespy_message(data) for data_parsed in commands: #self.log(-1, data_parsed) self.log(logging.DEBUG, data_parsed) if data_parsed['__cmd__'] == "login": self.perform_login(data_parsed) elif data_parsed['__cmd__'] == "logout": self.perform_logout(data_parsed) elif data_parsed['__cmd__'] == "getprofile": self.perform_getprofile(data_parsed) elif data_parsed['__cmd__'] == "updatepro": self.perform_updatepro(data_parsed) elif data_parsed['__cmd__'] == "ka": self.perform_ka(data_parsed) elif data_parsed['__cmd__'] == "status": self.perform_status(data_parsed) elif data_parsed['__cmd__'] == "bm": self.perform_bm(data_parsed) elif data_parsed['__cmd__'] == "addbuddy": self.perform_addbuddy(data_parsed) elif data_parsed['__cmd__'] == "delbuddy": self.perform_delbuddy(data_parsed) elif data_parsed['__cmd__'] == "authadd": self.perform_authadd(data_parsed) else: # Maybe write unknown commands to a separate file later so new data can be collected more easily? self.log( logging.ERROR, "Found unknown command, don't know how to handle '%s'." % data_parsed['__cmd__'])
def perform_getpd(self, data_parsed): pid = int(data_parsed['pid']) profile = self.db.pd_get(pid, data_parsed['dindex'], data_parsed['ptype']) if profile is None: self.log(logging.WARNING, "Could not find profile for %d %s %s", pid, data_parsed['dindex'], data_parsed['ptype']) keys = data_parsed['keys'].split('\x01') profile_data = None data = "" # Someone figure out if this is actually a good way to handle this # when no profile is found if profile is not None and 'data' in profile: profile_data = profile['data'] if profile_data.endswith("\\"): profile_data = profile_data[:-1] profile_data = \ gs_query.parse_gamespy_message("\\prof\\" + profile_data + "\\final\\") if profile_data is not None: profile_data = profile_data[0][0] else: self.log(logging.WARNING, "Could not get data section from profile for %d", pid) if len(keys): # TODO: more clean/pythonic way to do (join?) for key in keys: if key in ("__cmd__", "__cmd_val__", ""): continue data += "\\" + key + "\\" if profile_data is not None and key in profile_data: data += profile_data[key] else: self.log(logging.WARNING, "No keys requested, defaulting to all keys: %s", profile['data']) data = profile['data'] modified = int(time.time()) msg = gs_query.create_gamespy_message([ ('__cmd__', "getpdr"), ('__cmd_val__', 1), ('lid', self.lid), ('pid', pid), ('mod', modified), ('length', len(data)), ('data', data), ]) # data needs to be preceded by an extra slash msg = msg.replace("\\data\\", "\\data\\\\") datastring = "" try: datastring = re.findall('.*data\\\\(.*)', msg)[0] \ .replace("\\final\\", "") except: pass # This works because the data string is a key-value pair, splitting # the string by \ should yield a list with an even number of elements. # But, because of the extra \ prepended to the datastring, it'll be # odd. So ultimately I expect the list to have an odd number of # elements. If it's even, len(list)%2 will be zero... and that means # the last field in the datastring is empty and doesn't have a # closing \. if datastring and not len(datastring.split('\\')) % 2: # An empty field must be terminated by \ before \final\ msg = msg.replace("\\final\\", "\\\\final\\") self.log(logging.DEBUG, "SENDING: '%s'...", msg) msg = self.crypt(msg) self.transport.write(bytes(msg))
def perform_getpd(self, data_parsed): pid = int(data_parsed['pid']) profile = self.db.pd_get(pid, data_parsed['dindex'], data_parsed['ptype']) if profile == None: self.log(logging.WARNING, "Could not find profile for %d %s %s" % (pid, data_parsed['dindex'], data_parsed['ptype'])) keys = data_parsed['keys'].split('\x01') profile_data = None data = "" # Someone figure out if this is actually a good way to handle this when # no profile is found if profile != None and 'data' in profile: profile_data = profile['data'] if profile_data.endswith("\\"): profile_data = profile_data[:-1] profile_data = gs_query.parse_gamespy_message("\\prof\\" + profile_data + "\\final\\") if profile_data != None: profile_data = profile_data[0][0] else: self.log(logging.WARNING, "Could not get data section from profile for %d" % pid) if len(keys): for key in (key for key in keys if key not in ("__cmd__", "__cmd_val__", "")): data += "\\" + key + "\\" if profile_data != None and key in profile_data: data += profile_data[key] else: self.log(logging.WARNING, "No keys requested, defaulting to all keys: %s" % (profile['data'])) data = profile['data'] modified = int(time.time()) msg = gs_query.create_gamespy_message([('__cmd__', "getpdr"), ('__cmd_val__', 1), ('lid', self.lid), ('pid', pid), ('mod', modified), ('length', len(data)), ('data', data),]) msg = msg.replace("\\data\\","\\data\\\\") # data needs to be preceded by an extra slash datastring = "" try: datastring = re.findall('.*data\\\\(.*)',msg)[0].replace("\\final\\","") except: pass # This works because the data string is a key-value pair, splitting the # string by \ should yield a list with an even number of elements. # But, # because of the extra \ prepended to the datastring, it'll be odd. # So ultimately I expect the list to have an odd number of elements. # If it's even, len(list)%2 will be zero... and that means the last # field in the datastring is empty and doesn't have a closing \. if datastring and not len(datastring.split('\\')) % 2: msg = msg.replace("\\final\\","\\\\final\\") # An empty field must be terminated by \ before \final\ self.log(logging.DEBUG, "SENDING: '%s'..." % msg) msg = self.crypt(msg) self.transport.write(bytes(msg))
def perform_getpd(self, data_parsed): pid = int(data_parsed['pid']) profile = self.db.pd_get(pid, data_parsed['dindex'], data_parsed['ptype']) if profile is None: self.log(logging.WARNING, "Could not find profile for %d %s %s", pid, data_parsed['dindex'], data_parsed['ptype']) keys = data_parsed['keys'].split('\x01') profile_data = None data = "" # Someone figure out if this is actually a good way to handle this # when no profile is found if profile is not None and 'data' in profile: profile_data = profile['data'] if profile_data.endswith("\\"): profile_data = profile_data[:-1] profile_data = \ gs_query.parse_gamespy_message("\\prof\\" + profile_data + "\\final\\") if profile_data is not None: profile_data = profile_data[0][0] else: self.log(logging.WARNING, "Could not get data section from profile for %d", pid) if len(keys): # TODO: more clean/pythonic way to do (join?) for key in keys: if key in ("__cmd__", "__cmd_val__", ""): continue data += "\\" + key + "\\" if profile_data is not None and key in profile_data: data += profile_data[key] else: self.log(logging.WARNING, "No keys requested, defaulting to all keys: %s", profile['data']) data = profile['data'] modified = int(time.time()) # Check if there is a nul byte and data after it data_blocks = data.split('\x00') if len(data_blocks) > 1 and any(block for block in data_blocks[1:]): self.log(logging.WARNING, "Data after nul byte: %s", data) data = data_blocks[0] msg = gs_query.create_gamespy_message([ ('__cmd__', "getpdr"), ('__cmd_val__', 1), ('lid', self.lid), ('pid', pid), ('mod', modified), ('length', len(data)), ('data', ''), (data,) ]) if msg.count('\\') % 2: # An empty field must be terminated by \ before \final\ msg = msg.replace("\\final\\", "\\\\final\\") self.log(logging.DEBUG, "SENDING: '%s'...", msg) msg = self.crypt(msg) self.transport.write(bytes(msg))
def perform_getpd(self, data_parsed): pid = int(data_parsed['pid']) profile = self.db.pd_get(pid, data_parsed['dindex'], data_parsed['ptype']) if profile is None: self.log(logging.WARNING, "Could not find profile for %d %s %s", pid, data_parsed['dindex'], data_parsed['ptype']) keys = data_parsed['keys'].split('\x01') profile_data = None data = "" # Someone figure out if this is actually a good way to handle this # when no profile is found if profile is not None and 'data' in profile: profile_data = profile['data'] if profile_data.endswith("\\"): profile_data = profile_data[:-1] profile_data = \ gs_query.parse_gamespy_message("\\prof\\" + profile_data + "\\final\\") if profile_data is not None: profile_data = profile_data[0][0] else: self.log(logging.WARNING, "Could not get data section from profile for %d", pid) if len(keys): # TODO: more clean/pythonic way to do (join?) for key in keys: if key in ("__cmd__", "__cmd_val__", ""): continue data += "\\" + key + "\\" if profile_data is not None and key in profile_data: data += profile_data[key] else: self.log(logging.WARNING, "No keys requested, defaulting to all keys: %s", profile['data']) data = profile['data'] modified = int(time.time()) # Check if there is a nul byte and data after it data_blocks = data.split('\x00') if len(data_blocks) > 1 and any(block for block in data_blocks[1:]): self.log(logging.WARNING, "Data after nul byte: %s", data) data = data_blocks[0] msg = gs_query.create_gamespy_message([('__cmd__', "getpdr"), ('__cmd_val__', 1), ('lid', self.lid), ('pid', pid), ('mod', modified), ('length', len(data)), ('data', ''), (data, )]) if msg.count('\\') % 2: # An empty field must be terminated by \ before \final\ msg = msg.replace("\\final\\", "\\\\final\\") self.log(logging.DEBUG, "SENDING: '%s'...", msg) msg = self.crypt(msg) self.transport.write(bytes(msg))