This commit is contained in:
Jonas Weinz 2019-03-24 16:44:20 +01:00
parent 049cb43264
commit eb5f473de0
5 changed files with 205 additions and 2 deletions

View File

@ -287,3 +287,62 @@ client:
**friend request**:
```json
{
"type": "friend_request",
"data" : {
"user": "<friend>"
}
}
```
response:
```json
{
"type": "friend_request_response",
"data": {
"success": <true|false>
"msg": "..."
}
}
```
**unfriend**:
```json
{
"type": "unfriend_request",
"data" : {
"user": "<friend>"
}
}
```
response:
```json
{
"type": "unfriend_request_response",
"data": {
"success": <true|false>
"msg": "..."
}
}
```
**friend update**:
```json
{
"type": "friends_update",
"data": {
"friends": "<list of friends>"
}
}
```

View File

@ -131,6 +131,7 @@ class ConnectionHandler(object):
"msg": "" "msg": ""
} }
})) }))
await self.send_friends(conn)
await self._on_match_state_req(conn, None) await self._on_match_state_req(conn, None)
return conn return conn
await conn.send(json.dumps({ await conn.send(json.dumps({
@ -231,6 +232,7 @@ class ConnectionHandler(object):
})) }))
if success: if success:
await self.send_friends(conn)
await self._on_match_state_req(conn, None) await self._on_match_state_req(conn, None)
return conn return conn
@ -337,6 +339,35 @@ class ConnectionHandler(object):
try: try:
if len(opponent) <= 16 and '\'' not in opponent and '"' not in opponent: if len(opponent) <= 16 and '\'' not in opponent and '"' not in opponent:
if len(self.user_manager.get_user(opponent)) > 0: if len(self.user_manager.get_user(opponent)) > 0:
if len(self.match_manager.get_matches_for_user(conn.user_name)) >= 5:
await conn.websocket.send(
json.dumps(
{
"type": "match_request_response",
"data": {
"success": False,
"msg": "player " + opponent + " has too many open matches"
}
}
)
)
return
if (self.match_manager.is_match(conn.user_name, opponent)):
await conn.websocket.send(
json.dumps(
{
"type": "match_request_response",
"data": {
"success": False,
"msg": "you are already plaing against " + opponent
}
}
)
)
return
await self._start_match(conn.user_name, opponent) await self._start_match(conn.user_name, opponent)
await conn.websocket.send( await conn.websocket.send(
@ -461,13 +492,88 @@ class ConnectionHandler(object):
if match is not None: if match is not None:
match_state = match.to_json_state() match_state = match.to_json_state()
conn.send(json.dumps({ await conn.send(json.dumps({
'type': 'match_update', 'type': 'match_update',
'data': { 'data': {
'match_state': json.loads(match_state) 'match_state': json.loads(match_state)
} }
})) }))
async def _on_friend_request(self, conn, data):
msg = "error in handling friend request"
success = False
try:
friend = data['user'].lower()
# check for user:
if "\"" not in friend and "'" not in friend and ";" not in friend:
if friend in self.user_manager.get_friends_for_user(conn.user_name):
success = False
msg = f"'{friend}' is already your friend"
elif self.user_manager.add_friend_to_user(conn.user_name, friend):
success = True
msg = f"added '{friend}' as a friend"
else:
success = False
msg = f"player '{friend}' not found"
else:
success = False
msg = "misformated friend request"
finally:
await conn.send(json.dumps({
'type': 'friend_request_response',
'data': {
'success': success,
'msg': msg
}
}))
if success:
await self.send_friends(conn)
async def _on_unfriend_request(self, conn, data):
success = False
msg = "error in handling unfriend request"
try:
friend = data['user'].lower()
if "\"" not in friend and "'" not in friend and ";" not in friend:
if friend not in self.user_manager.get_friends_for_user(conn.user_name):
success = False
msg = f"cannot end friendship with '{friend}': it's not one of your friends"
else:
self.user_manager.remove_friend_from_user(
conn.user_name, friend)
success = True
msg = f"removed '{friend}' from your friend list"
finally:
await conn.send(json.dumps({
'type': 'unfriend_request_response',
'data': {
'success': success,
'msg': msg
}
}))
if success:
await self.send_friends(conn)
async def send_friends(self, conn):
friends = list(self.user_manager.get_friends_for_user(conn.user_name))
await conn.send(json.dumps({
'type': 'friends_update',
'data': {
'friends': friends
}
}))
async def disconnect(self, conn): async def disconnect(self, conn):
self._del_connection(conn) self._del_connection(conn)
@ -494,5 +600,11 @@ class ConnectionHandler(object):
elif t == "match_states_request": elif t == "match_states_request":
await self._on_match_state_req(conn, msg['data']) await self._on_match_state_req(conn, msg['data'])
elif t == "friend_request":
await self._on_friend_request(conn, msg['data'])
elif t == "unfriend_request":
await self._on_unfriend_request(conn, msg['data'])
else: else:
print("could not interpret message: " + msg_str) print("could not interpret message: " + msg_str)

View File

@ -18,9 +18,11 @@ def create_tables():
"DROP TABLE IF EXISTS matches", "DROP TABLE IF EXISTS matches",
"DROP TABLE IF EXISTS sessions", "DROP TABLE IF EXISTS sessions",
"DROP TABLE IF EXISTS users", "DROP TABLE IF EXISTS users",
"DROP TABLE IF EXISTS friends",
"CREATE TABLE users (name varchar(16) NOT NULL, pw_hash varchar(128) NOT NULL, pw_salt varchar(32) NOT NULL, last_seen datetime NOT NULL, PRIMARY KEY (name)) CHARACTER SET " + settings.db_charset, "CREATE TABLE users (name varchar(16) NOT NULL, pw_hash varchar(128) NOT NULL, pw_salt varchar(32) NOT NULL, last_seen datetime NOT NULL, PRIMARY KEY (name)) CHARACTER SET " + settings.db_charset,
"CREATE TABLE matches (id varchar(32) NOT NULL, user_a varchar(16) NOT NULL, user_b varchar(16) NOT NULL, match_state varchar(4096) NOT NULL, active_user varchar(16), last_active datetime NOT NULL, FOREIGN KEY (user_a) REFERENCES users(name), FOREIGN KEY (user_b) REFERENCES users(name), FOREIGN KEY (active_user) REFERENCES users(name)) CHARACTER SET " + settings.db_charset, "CREATE TABLE matches (id varchar(32) NOT NULL, user_a varchar(16) NOT NULL, user_b varchar(16) NOT NULL, match_state varchar(4096) NOT NULL, active_user varchar(16), last_active datetime NOT NULL, FOREIGN KEY (user_a) REFERENCES users(name), FOREIGN KEY (user_b) REFERENCES users(name), FOREIGN KEY (active_user) REFERENCES users(name)) CHARACTER SET " + settings.db_charset,
"CREATE TABLE sessions (id varchar(32) NOT NULL, registered_user varchar(16), temp_user varchar(16), last_seen datetime NOT NULL, PRIMARY KEY (id), FOREIGN KEY(registered_user) REFERENCES users(name)) CHARACTER SET " + settings.db_charset "CREATE TABLE sessions (id varchar(32) NOT NULL, registered_user varchar(16), temp_user varchar(16), last_seen datetime NOT NULL, PRIMARY KEY (id), FOREIGN KEY(registered_user) REFERENCES users(name)) CHARACTER SET " + settings.db_charset,
"CREATE TABLE friends (user varchar(16) NOT NULL, friend varchar(16) NOT NULL, FOREIGN KEY(user) REFERENCES users(name), FOREIGN KEY(friend) REFERENCES users(name)) CHARACTER SET " + settings.db_charset
] ]
for query in queries: for query in queries:

View File

@ -54,6 +54,10 @@ class MatchManager(object):
print("updated match") print("updated match")
return match return match
def is_match(self, player_a, player_b):
query = f"SELECT * FROM matches WHERE (user_a='{player_a}' AND user_b='{player_b}') OR (user_a='{player_b}' AND user_b='{player_a}')"
return len(DatabaseConnection.global_single_query(query))
def delete_match(self, match_id): def delete_match(self, match_id):
query = f"DELETE FROM matches WHERE id='{match_id}'" query = f"DELETE FROM matches WHERE id='{match_id}'"
DatabaseConnection.global_single_execution(query) DatabaseConnection.global_single_execution(query)

View File

@ -17,6 +17,13 @@ class UserManager(object):
query = f"DELETE FROM users where name='{user_name}'" query = f"DELETE FROM users where name='{user_name}'"
DatabaseConnection.global_single_execution(query) DatabaseConnection.global_single_execution(query)
# remove from friends:
query = f"DELETE FROM friends WHERE user='{user_name}'"
DatabaseConnection.global_single_execution(query)
query = f"DELETE FROM friends WHERE friend='{user_name}'"
DatabaseConnection.global_single_execution(query)
def verify_user(self, user_name, pw): def verify_user(self, user_name, pw):
query = f"SELECT * FROM users where name='{user_name}'" query = f"SELECT * FROM users where name='{user_name}'"
users = DatabaseConnection.global_single_query(query) users = DatabaseConnection.global_single_query(query)
@ -43,6 +50,25 @@ class UserManager(object):
query = f"UPDATE users SET last_seen='{datetime.datetime.now()}' WHERE name='{user_name}'" query = f"UPDATE users SET last_seen='{datetime.datetime.now()}' WHERE name='{user_name}'"
DatabaseConnection.global_single_execution(query) DatabaseConnection.global_single_execution(query)
def add_friend_to_user(self, user_name, friend_name):
if len(self.get_user(friend_name)) > 0:
query = f"INSERT INTO friends (user, friend) VALUES ( '{user_name}', '{friend_name}')"
DatabaseConnection.global_single_execution(query)
return True
return False
def get_friends_for_user(self, user_name):
query = f"SELECT friend FROM friends WHERE user='{user_name}'"
tmp = DatabaseConnection.global_single_query(query)
friends = set()
for entry in tmp:
friends.add(entry['friend'])
return friends
def remove_friend_from_user(self, user_name, friend_name):
query = f"DELETE FROM friends WHERE user='{user_name}' AND friend='{friend_name}'"
DatabaseConnection.global_single_execution(query)
def get_all_users(self): def get_all_users(self):
query = "SELECT name, last_seen FROM users" query = "SELECT name, last_seen FROM users"
return DatabaseConnection.global_single_query(query) return DatabaseConnection.global_single_query(query)