diff --git a/gamespy/gs_database.py b/gamespy/gs_database.py index d692229..8ea0875 100644 --- a/gamespy/gs_database.py +++ b/gamespy/gs_database.py @@ -35,7 +35,7 @@ class GamespyDatabase(object): logger.log(-1, q) c.execute(q) - q = "CREATE TABLE sessions (session TEXT, profileid INT)" + q = "CREATE TABLE sessions (session TEXT, profileid INT, loginticket TEXT)" logger.log(-1, q) c.execute(q) @@ -294,6 +294,18 @@ class GamespyDatabase(object): c.close() return profileid + def get_profileid_from_loginticket(self, loginticket): + q = "SELECT profileid FROM sessions WHERE loginticket = ?" + logger.log(-1, q.replace("?", "%s") % (loginticket)) + + c = self.conn.cursor() + c.execute(q, (loginticket,)) + + profileid = int(c.fetchone()[0]) + + c.close() + return profileid + def get_profile_from_session_key(self, session_key): profileid = self.get_profileid_from_session_key(session_key) @@ -333,7 +345,7 @@ class GamespyDatabase(object): c.execute(q, [profileid]) self.conn.commit() - def create_session(self, profileid): + def create_session(self, profileid, loginticket): if profileid != None and self.check_profile_exists(profileid) == False: return None @@ -343,12 +355,12 @@ class GamespyDatabase(object): # Create new session session_key = self.generate_session_key(8) - q ="INSERT INTO sessions VALUES (?, ?)" - q2 = q.replace("?", "%s") % (session_key, profileid) + q ="INSERT INTO sessions VALUES (?, ?, ?)" + q2 = q.replace("?", "%s") % (session_key, profileid, loginticket) logger.log(-1, q2) c = self.conn.cursor() - c.execute(q, [session_key, profileid]) + c.execute(q, [session_key, profileid, loginticket]) self.conn.commit() return session_key diff --git a/gamespy_gamestats_server.py b/gamespy_gamestats_server.py index 0e0835d..fd93552 100644 --- a/gamespy_gamestats_server.py +++ b/gamespy_gamestats_server.py @@ -213,7 +213,7 @@ class Gamestats(LineReceiver): if profileid != None: # Successfully logged in or created account, continue creating session. - sesskey = self.db.create_session(profileid) + sesskey = self.db.create_session(profileid, '') self.sessions[profileid] = self diff --git a/gamespy_profile_server.py b/gamespy_profile_server.py index bcafd90..6206d84 100644 --- a/gamespy_profile_server.py +++ b/gamespy_profile_server.py @@ -235,7 +235,8 @@ class PlayerSession(LineReceiver): if profileid != None: # Successfully logged in or created account, continue creating session. - self.sesskey = self.db.create_session(profileid) + loginticket = gs_utils.base64_encode(utils.generate_random_str(16)) + self.sesskey = self.db.create_session(profileid, loginticket) self.sessions[profileid] = self @@ -247,7 +248,7 @@ class PlayerSession(LineReceiver): msg_d.append(('userid', userid)) msg_d.append(('profileid', profileid)) msg_d.append(('uniquenick', uniquenick)) - msg_d.append(('lt', gs_utils.base64_encode(utils.generate_random_str(16)))) # Some kind of token... don't know it gets used or generated, but it doesn't seem to have any negative effects if it's not properly generated. + msg_d.append(('lt', loginticket)) # Some kind of token... don't know it gets used or generated, but it doesn't seem to have any negative effects if it's not properly generated. msg_d.append(('id', data_parsed['id'])) msg = gs_query.create_gamespy_message(msg_d) diff --git a/storage_server.py b/storage_server.py index dc98736..27eb7d8 100644 --- a/storage_server.py +++ b/storage_server.py @@ -6,6 +6,7 @@ import sqlite3 import xml.dom.minidom as minidom import other.utils as utils +import gamespy.gs_database as gs_database logger_output_to_console = True logger_output_to_file = True @@ -26,6 +27,8 @@ class StorageHTTPServer(BaseHTTPServer.HTTPServer): def __init__(self, server_address, RequestHandlerClass): BaseHTTPServer.HTTPServer.__init__(self, server_address, RequestHandlerClass) + self.gamespydb = gs_database.GamespyDatabase() + self.db = sqlite3.connect('storage.db') self.tables = {} @@ -35,17 +38,19 @@ class StorageHTTPServer(BaseHTTPServer.HTTPServer): cursor.execute('CREATE TABLE typedata (tbl TEXT, col TEXT, type TEXT)') if not self.table_exists('g2050_box_us_eu'): - cursor.execute('CREATE TABLE g2050_box_us_eu (recordid INT PRIMARY KEY AUTOINCREMENT, ownerid INT, m_enable INT, m_type INT, m_index INT, m_file_id INT, m_header TEXT, m_file_id___size INT, m_file_id___create_time DATETIME, m_file_id___downloads INT)') + cursor.execute('CREATE TABLE g2050_box_us_eu (recordid INTEGER PRIMARY KEY AUTOINCREMENT, ownerid INT, m_enable INT, m_type INT, m_index INT, m_file_id INT, m_header TEXT, m_file_id___size INT, m_file_id___create_time DATETIME, m_file_id___downloads INT)') cursor.execute('INSERT INTO typedata VALUES ("g2050_box_us_eu", "recordid", "intValue"), ("g2050_box_us_eu", "ownerid", "intValue"), ("g2050_box_us_eu", "m_enable", "booleanValue"), ("g2050_box_us_eu", "m_type", "intValue"), ("g2050_box_us_eu", "m_index", "intValue"), ("g2050_box_us_eu", "m_file_id", "intValue"), ("g2050_box_us_eu", "m_header", "binaryDataValue"), ("g2050_box_us_eu", "m_file_id___size", "intValue"), ("g2050_box_us_eu", "m_file_id___create_time", "dateAndTimeValue"), ("g2050_box_us_eu", "m_file_id___downloads", "intValue")') + cursor.execute('CREATE TRIGGER g2050ti_box_us_eu AFTER INSERT ON g2050_box_us_eu BEGIN UPDATE g2050_box_us_eu SET m_file_id___create_time = date(\'now\'), m_file_id___size = 0, m_file_id___downloads = 0 WHERE recordid = NEW.recordid; END') + cursor.execute('CREATE TRIGGER g2050tu_box_us_eu AFTER UPDATE ON g2050_box_us_eu BEGIN UPDATE g2050_box_us_eu SET m_file_id___create_time = date(\'now\') WHERE recordid = NEW.recordid; END') if not self.table_exists('g2649_bbdx_player'): - cursor.execute('CREATE TABLE g2649_bbdx_player (recordid INT PRIMARY KEY AUTOINCREMENT, stat INT)') + cursor.execute('CREATE TABLE g2649_bbdx_player (recordid INTEGER PRIMARY KEY AUTOINCREMENT, stat INT)') cursor.execute('INSERT INTO typedata VALUES ("g2649_bbdx_player", "recordid", "intValue"), ("g2649_bbdx_player", "stat", "intValue")') if not self.table_exists('g2649_bbdx_info'): cursor.execute('CREATE TABLE g2649_bbdx_info (serialid INT, stat INT, message TEXT)') cursor.execute('INSERT INTO typedata VALUES ("g2649_bbdx_info", "serialid", "intValue"), ("g2649_bbdx_info", "stat", "intValue"), ("g2649_bbdx_info", "message", "unicodeStringValue")') if not self.table_exists('g2649_bbdx_search'): - cursor.execute('CREATE TABLE g2649_bbdx_search (recordid INT PRIMARY KEY AUTOINCREMENT, song_name TEXT, creator_name TEXT, average_rating REAL, serialid INT, filestore INT, is_lyric INT, num_ratings INT)') + cursor.execute('CREATE TABLE g2649_bbdx_search (recordid INTEGER PRIMARY KEY AUTOINCREMENT, song_name TEXT, creator_name TEXT, average_rating REAL, serialid INT, filestore INT, is_lyric INT, num_ratings INT)') cursor.execute('INSERT INTO typedata VALUES ("g2649_bbdx_search", "recordid", "intValue"), ("g2649_bbdx_search", "song_name", "asciiStringValue"), ("g2649_bbdx_search", "creator_name", "asciiStringValue"), ("g2649_bbdx_search", "average_rating", "floatValue"), ("g2649_bbdx_search", "serialid", "intValue"), ("g2649_bbdx_search", "filestore", "intValue"), ("g2649_bbdx_search", "is_lyric", "booleanValue"), ("g2649_bbdx_search", "num_ratings", "intValue")') # load column info into memory, unfortunately there's no simple way @@ -114,6 +119,7 @@ class StorageHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): data = dom.getElementsByTagName('SOAP-ENV:Body')[0].getElementsByTagName('ns1:' + shortaction)[0] gameid = str(int(data.getElementsByTagName('ns1:gameid')[0].firstChild.data)) tableid = data.getElementsByTagName('ns1:tableid')[0].firstChild.data + loginticket = data.getElementsByTagName('ns1:loginTicket')[0].firstChild.data table = 'g' + gameid + '_' + tableid @@ -124,8 +130,6 @@ class StorageHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): ret += '<' + shortaction + 'Response xmlns="http://gamespy.net/sake">' ret += '<' + shortaction + 'Result>Success' - # TODO: Actually make GetMyRecords only return *my* records - # ownerid == profileid, ask profile server via login ticket if shortaction == 'SearchForRecords' or shortaction == 'GetMyRecords' or shortaction == 'GetSpecificRecords': columndata = data.getElementsByTagName('ns1:fields')[0].getElementsByTagName('ns1:string') try: @@ -140,8 +144,12 @@ class StorageHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): for c in columns[1:]: statement += ',' + c statement += ' FROM ' + table + + if shortaction == 'GetMyRecords': + profileid = self.server.gamespydb.get_profileid_from_loginticket(loginticket) + statement += ' WHERE ownerid = ' + str(profileid) - if shortaction == 'GetSpecificRecords': + elif shortaction == 'GetSpecificRecords': recordids = data.getElementsByTagName('ns1:recordids')[0].getElementsByTagName('ns1:int') # limit to requested records @@ -193,6 +201,8 @@ class StorageHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): if shortaction == 'UpdateRecord': recordid = int(data.getElementsByTagName('ns1:recordid')[0].firstChild.data) + profileid = self.server.gamespydb.get_profileid_from_loginticket(loginticket) + columndata = [] values = data.getElementsByTagName('ns1:values')[0] recordfields = values.getElementsByTagName('ns1:RecordField') @@ -222,22 +232,23 @@ class StorageHTTPServerHandler(BaseHTTPServer.BaseHTTPRequestHandler): statement += columns[0] + ' = ?' for c in columns[1:]: statement += ', ' + c + ' = ?' - statement += ' WHERE recordid = ?' + statement += ' WHERE recordid = ? AND ownerid = ?' rowdata.append( recordid ) + rowdata.append( profileid ) elif shortaction == 'CreateRecord': statement = 'INSERT INTO ' + table + ' (' - statement += columns[0] - for c in columns[1:]: - statement += ', ' + c - statement += ') VALUES (?' - for i in xrange(len(columns)-1): - statement += ', ?' - statement += ')' + for c in columns: + statement += c + ', ' + statement += 'ownerid) VALUES (' + for i in xrange(len(columns)): + statement += '?, ' + statement += '?)' + rowdata.append( profileid ) else: logger.log(logging.ERROR, 'Illegal Action %s in database insert/update path!', shortaction) return - + cursor = self.server.db.cursor() cursor.execute(statement, tuple(rowdata))