Fixed some buddy list things.

Also, for some reason Phantasy Star Zero matchmaking lobbies work now. I
didn't change anything that should've affected that but who knows?
This commit is contained in:
polaris
2014-04-09 18:46:48 -04:00
parent 29160bf721
commit 23aae4d552
3 changed files with 114 additions and 23 deletions

View File

@@ -2,6 +2,7 @@ import sqlite3
import hashlib
import itertools
import other.utils as utils
import time
class GamespyDatabase(object):
def __init__(self, filename='gpcm.db'):
@@ -21,7 +22,7 @@ class GamespyDatabase(object):
# evidence yet to say otherwise as far as Nintendo DS games go.
c.execute('''CREATE TABLE users (profileid INT, userid TEXT, password TEXT, gsbrcd TEXT, email TEXT, uniquenick TEXT, pid TEXT, lon TEXT, lat TEXT, loc TEXT, firstname TEXT, lastname TEXT, stat TEXT, partnerid TEXT, console INT, csnum TEXT, cfc TEXT, bssid TEXT, devname TEXT, birth TEXT, sig TEXT)''')
c.execute('''CREATE TABLE sessions (session TEXT, profileid INT)''')
c.execute('''CREATE TABLE buddies (userProfileid INT, buddyProfileId INT, status INT)''')
c.execute('''CREATE TABLE buddies (userProfileId INT, buddyProfileId INT, time INT, status INT, notified INT)''')
self.conn.commit()
def get_dict(self, row):
@@ -32,6 +33,7 @@ class GamespyDatabase(object):
# User functions
def get_next_free_profileid(self):
# TODO: Make profile ids start at 1 for each game?
c = self.conn.cursor()
c.execute("SELECT max(profileid) FROM users")
@@ -152,9 +154,7 @@ class GamespyDatabase(object):
for field in fields:
print "UPDATE users SET %s = %s WHERE profileid = %s" % (field[0], field[1], profileid)
c.execute("UPDATE users SET %s = ? WHERE profileid = ?" % (field[0]), [field[1], profileid])
self.conn.commit()
self.conn.commit()
# Session functions
# TODO: Cache session keys so we don't have to query the database every time we get a profile id.
@@ -231,7 +231,8 @@ class GamespyDatabase(object):
# Buddy functions
def add_buddy(self, userProfileId, buddyProfileId):
c = self.conn.cursor()
c.execute("INSERT INTO buddies VALUES (?, ?, ?)", [userProfileId, buddyProfileId, 0]) # 0 will mean not authorized
now = int(time.time())
c.execute("INSERT INTO buddies VALUES (?, ?, ?, ?, ?)", [userProfileId, buddyProfileId, now, 0, 0]) # 0 will mean not authorized
self.conn.commit()
def auth_buddy(self, userProfileId, buddyProfileId):
@@ -239,6 +240,16 @@ class GamespyDatabase(object):
c.execute("UPDATE buddies SET status = ? WHERE userProfileId = ? AND buddyProfileId = ?", [1, userProfileId, buddyProfileId]) # 1 will mean authorized
self.conn.commit()
def get_buddy(self, userProfileId, buddyProfileId):
profile = {}
if userProfileId != None and buddyProfileId != None:
c = self.conn.cursor()
c.execute("SELECT * FROM buddies WHERE userProfileId = ? AND buddyProfileId = ?", [userProfileId, buddyProfileId])
profile = self.get_dict(c.fetchone())
c.close()
return profile
def delete_buddy(self, userProfileId, buddyProfileId):
c = self.conn.cursor()
c.execute("DELETE FROM buddies WHERE userProfileId = ? AND buddyProfileId = ?", [userProfileId, buddyProfileId])
@@ -252,3 +263,26 @@ class GamespyDatabase(object):
users.append(self.get_dict(row))
return users
def get_pending_buddy_requests(self, userProfileId):
c = self.conn.cursor()
users = []
for row in c.execute("SELECT * FROM buddies WHERE buddyProfileId = ? AND status = 0", [userProfileId]):
users.append(self.get_dict(row))
return users
def buddy_need_auth_message(self, userProfileId):
c = self.conn.cursor()
users = []
for row in c.execute("SELECT * FROM buddies WHERE buddyProfileId = ? AND status = 1 AND notified = 0", [userProfileId]):
users.append(self.get_dict(row))
return users
def buddy_sent_auth_message(self, userProfileId, buddyProfileId):
c = self.conn.cursor()
c.execute("UPDATE buddies SET notified = ? WHERE userProfileId = ? AND buddyProfileId = ?", [1, userProfileId, buddyProfileId]) # 1 will mean that the player has been sent the "
self.conn.commit()

View File

@@ -71,6 +71,8 @@ class PlayerSession(LineReceiver):
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:
@@ -260,8 +262,14 @@ class PlayerSession(LineReceiver):
self.statstring = data_parsed['statstring']
self.locstring = data_parsed['locstring']
# Send authorization requests to client
self.get_buddy_requests()
# Send authorizationed message to client
self.get_buddy_authorized()
self.send_status_to_friends()
def perform_bm(self, data_parsed):
if data_parsed['__cmd_val__'] == "1": # Message to/from clients?
if "t" in data_parsed:
@@ -281,29 +289,33 @@ class PlayerSession(LineReceiver):
def perform_addbuddy(self, data_parsed):
if int(data_parsed['newprofileid']) == self.profileid:
print "Can't add self as friend"
return
# Sample: \addbuddy\\sesskey\231601763\newprofileid\476756820\reason\\final\
buddies = self.db.get_buddy_list(self.profileid)
buddy_exists = False
for buddy in buddies:
if buddy['buddyProfileId'] == data_parsed['newprofileid']:
if buddy['buddyProfileId'] == int(data_parsed['newprofileid']):
buddy_exists = True
break
if not buddy_exists:
self.db.add_buddy(self.profileid, data_parsed['newprofileid'])
if buddy_exists == False:
self.db.add_buddy(self.profileid, int(data_parsed['newprofileid']))
# In the case that the user is already a buddy:
# \bm\2\f\217936895\msg\|signed|f259f26d3273f8bda23c7c5e4bd8c5aa\final\
# \error\\err\1539\errmsg\The profile requested is already a buddy.\final\
# Handle later?
def perform_delbuddy(self, data_parsed):
# Sample: \delbuddy\\sesskey\61913621\delprofileid\1\final\
self.db.delete_buddy(self.profileid, int(data_parsed['delprofileid']))
def perform_authadd(self, data_parsed):
# Sample: \authadd\\sesskey\231587549\fromprofileid\217936895\sig\f259f26d3273f8bda23c7c5e4bd8c5aa\final\
self.db.auth_buddy(self.profileid, data_parsed['newprofileid'])
# Authorize the other person's friend request.
self.db.auth_buddy(int(data_parsed['fromprofileid']), self.profileid)
# After authorization, send the person who was authorized a message like so:
# \bm\1\f\476756820\msg\I have authorized your request to add me to your list\final\
self.get_buddy_authorized()
def send_status_to_friends(self):
# TODO: Cache buddy list so we don't have to query the database every time
@@ -328,17 +340,58 @@ class PlayerSession(LineReceiver):
buddies = self.db.get_buddy_list(self.profileid)
for buddy in buddies:
print buddy
if buddy['status'] != 1:
continue
if buddy['buddyProfileId'] in self.sessions and self.sessions[buddy['buddyProfileId']].gameid == self.gameid:
status_msg = "|s|%s|ss|%s|ls|%s|ip|%d|p|0|qm|0" % (self.sessions[buddy['buddyProfileId']].status, self.sessions[buddy['buddyProfileId']].statstring, self.sessions[buddy['buddyProfileId']].locstring, self.get_ip_as_int(self.sessions[buddy['buddyProfileId']].address.host))
else:
status_msg = "|s|0|ss|Offline"
msg_d = []
msg_d.append(('__cmd__', "bm"))
msg_d.append(('__cmd_val__', "100"))
msg_d.append(('f', buddy['buddyProfileId']))
msg_d.append(('msg', status_msg))
msg = gs_query.create_gamespy_message(msg_d)
msg_d = []
msg_d.append(('__cmd__', "bm"))
msg_d.append(('__cmd_val__', "100"))
msg_d.append(('f', buddy['buddyProfileId']))
msg_d.append(('msg', status_msg))
msg = gs_query.create_gamespy_message(msg_d)
self.transport.write(bytes(msg))
self.transport.write(bytes(msg))
def get_buddy_authorized(self):
buddies = self.db.buddy_need_auth_message(self.profileid)
for buddy in buddies:
msg_d = []
msg_d.append(('__cmd__', "bm"))
msg_d.append(('__cmd_val__', "1"))
msg_d.append(('f', buddy['userProfileId']))
msg_d.append(('msg', "I have authorized your request to add me to your list"))
msg = gs_query.create_gamespy_message(msg_d)
self.transport.write(bytes(msg))
self.db.buddy_sent_auth_message(buddy['userProfileId'], buddy['buddyProfileId'])
def get_buddy_requests(self):
# Get list people who have added the user but haven't been accepted yet.
buddies = self.db.get_pending_buddy_requests(self.profileid)
profile = self.db.get_profile_from_profileid(self.profileid)
msg = "\r\n\r\n"
if "sig" in profile:
msg += "|signed|" + profile['sig']
for buddy in buddies:
msg_d = []
msg_d.append(('__cmd__', "bm"))
msg_d.append(('__cmd_val__', "2"))
msg_d.append(('f', buddy['userProfileId']))
msg_d.append(('date', buddy['time']))
msg_d.append(('msg', msg))
msg = gs_query.create_gamespy_message(msg_d)
self.transport.write(bytes(msg))
class PlayerSearch(LineReceiver):

View File

@@ -317,8 +317,10 @@ def update_server_list(gameid, session, value):
# Add new server
value['__session__'] = session
utils.print_log("Added %s to the server list for %s" % (value, gameid))
server_list[gameid].append(value)
print "%s servers: %d" % (gameid, len(server_list[gameid]))
def delete_server(gameid, session):
if not gameid in server_list:
@@ -326,8 +328,10 @@ def delete_server(gameid, session):
return
# Remove all servers hosted by the given session id.
print "Deleting all %s servers where session = %d" % (gameid, session)
count = len(server_list[gameid])
server_list[gameid] = [x for x in server_list[gameid] if x['__session__'] != session]
count -= len(server_list[gameid])
print "Deleted %d %s servers where session = %d" % (count, gameid, session)
def find_server_by_address(ip, port, gameid = None):
if gameid == None: