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": ""
}
}))
await self.send_friends(conn)
await self._on_match_state_req(conn, None)
return conn
await conn.send(json.dumps({
@ -231,6 +232,7 @@ class ConnectionHandler(object):
}))
if success:
await self.send_friends(conn)
await self._on_match_state_req(conn, None)
return conn
@ -337,6 +339,35 @@ class ConnectionHandler(object):
try:
if len(opponent) <= 16 and '\'' not in opponent and '"' not in opponent:
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 conn.websocket.send(
@ -461,13 +492,88 @@ class ConnectionHandler(object):
if match is not None:
match_state = match.to_json_state()
conn.send(json.dumps({
await conn.send(json.dumps({
'type': 'match_update',
'data': {
'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):
self._del_connection(conn)
@ -494,5 +600,11 @@ class ConnectionHandler(object):
elif t == "match_states_request":
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:
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 sessions",
"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 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:

View File

@ -54,6 +54,10 @@ class MatchManager(object):
print("updated 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):
query = f"DELETE FROM matches WHERE id='{match_id}'"
DatabaseConnection.global_single_execution(query)

View File

@ -17,6 +17,13 @@ class UserManager(object):
query = f"DELETE FROM users where name='{user_name}'"
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):
query = f"SELECT * FROM users where name='{user_name}'"
users = DatabaseConnection.global_single_query(query)
@ -42,6 +49,25 @@ class UserManager(object):
assert len(matches) == 1
query = f"UPDATE users SET last_seen='{datetime.datetime.now()}' WHERE name='{user_name}'"
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):
query = "SELECT name, last_seen FROM users"