diff --git a/src/endpoints/matchmaking.py b/src/endpoints/matchmaking.py index d9c56cf..cb7df77 100644 --- a/src/endpoints/matchmaking.py +++ b/src/endpoints/matchmaking.py @@ -43,7 +43,7 @@ def queue_info(): if side not in ["A", "B"]: return jsonify({"message": "Invalid side parameter"}), 400 - response_data = matchmaking_queue.getQueueStatus(side, session) + response_data = matchmaking_queue.getQueueStatus(side, session, region) return jsonify(response_data) # return jsonify({"A": {"Size": 1, "ETA": 100, "stable": True}, "B": {"Size": 5, "ETA": 100, "stable": True}, "SizeA": count_a, "SizeB": count_b}) except TimeoutError: @@ -111,7 +111,7 @@ def queue(): return jsonify(response_data) else: - response_data = matchmaking_queue.getQueueStatus(side, userid) + response_data = matchmaking_queue.getQueueStatus(side, userid, region) return jsonify(response_data) except Exception as e: @@ -163,6 +163,7 @@ def match(matchid_unsanitized): return jsonify({"MatchId": matchid, "Category": "Steam-te-18f25613-36778-ue4-374f864b", "Rank": 1}) try: response_data = matchmaking_queue.createMatchResponse(matchid) + logger.graylog_logger(level="debug", handler="match", message=response_data) return jsonify(response_data) except Exception as e: logger.graylog_logger(level="error", handler="match", message=e) @@ -206,7 +207,7 @@ def match_register(match_id_unsanitized): custom_data = data.get("customData", {}) session_settings = custom_data.get("SessionSettings", "") - response = matchmaking_queue.registerMatch(match_id, session_settings) + response = matchmaking_queue.registerMatch(match_id, session_settings, userid) if response: return jsonify(response) @@ -280,18 +281,55 @@ def match_create(): @app.route("/api/v1/extensions/progression/playerEndOfMatch", methods=["POST"]) def progression_player_end_of_match(): + # {"data":{"playerId":"619d6f42-db87-4f3e-8dc9-3c9995613614", + # "faction":"Runner","characterGroup":"RunnerGroupE", + # "playtime":79,"platform":"PC","hasQuit":false,"characterState":"Dead", + # "matchId":"63203229-1cd7-42da-8821-540eb87536c1", + # "experienceEvents":[{"type":"GardenFinale","amount":5}],"earnedCurrencies":[],"completedChallenges":[]}} check_for_game_client("strict") session_cookie = sanitize_input(request.cookies.get("bhvrSession")) userid = session_manager.get_user_id(session_cookie) try: logger.graylog_logger(level="info", handler="matchmaking_playerEndOfMatch", message=request.get_json()) - return jsonify("", 204) + return jsonify({"Player": {"Success": True}}) except TimeoutError: return jsonify({"status": "error"}) except Exception as e: logger.graylog_logger(level="error", handler="matchmaking_playerEndOfMatch", message=e) +@app.route("/api/v1/extensions/progression/endOfMatch", methods=["POST"]) +def progression_end_of_match(): + # todo Implent this fully + + # {"data":{"players":[ + # {"playerId":"619d6f42-db87-4f3e-8dc9-3c9995613614","faction":"Runner","characterGroup":"RunnerGroupE", + # "platform":"PC","hasQuit":false,"characterState":"Dead"}, + # {"playerId":"95041085-e7e4-4759-be3d-e72c69167578","faction":"Hunter","characterGroup":"HunterGroupB", + # "platform":"PC","hasQuit":false,"characterState":"InArena"}, + # {"playerId":"00658d11-2dfd-41e8-b6d2-2462e8f3aa47","faction":"Runner","characterGroup":"RunnerGroupB", + # "platform":"PC","hasQuit":false,"characterState":"Dead"}], + # "dominantFaction":"Hunter","matchId":"df9655d9-63ac-4dde-a9e9-129aaa249356"}} + check_for_game_client("strict") + session_cookie = sanitize_input(request.cookies.get("bhvrSession")) + userid = session_manager.get_user_id(session_cookie) + try: + players = [] + for player in request.get_json()["data"]["players"]: + players.append({"PlayerId": player["playerId"]}) + logger.graylog_logger(level="info", handler="matchmaking_endOfMatch", message=request.get_json()) + return jsonify({"Players": [ + {}, + {} + ]}) + sub_list = {"Level": 3, "Ratio": 0.4} + except TimeoutError: + return jsonify({"status": "error"}) + except Exception as e: + logger.graylog_logger(level="error", handler="matchmaking_endOfMatch", message=e) + + + @app.route("/file///", methods=["POST", "GET"]) def file_gold_rush(seed_unsanitized, map_name_unsanitized, game_version_unsanitized): check_for_game_client("strict") @@ -333,3 +371,20 @@ def metrics_matchmaking_event(): except Exception as e: logger.graylog_logger(level="error", handler="logging_matchmaking_Event", message=e) + +@app.route("/api/v1/match//user/", methods=["DELETE"]) +def remove_player_from_match(match_id_unsanitized, user_id): + check_for_game_client("strict") + session_cookie = sanitize_input(request.cookies.get("bhvrSession")) + userid = session_manager.get_user_id(session_cookie) + match_id = sanitize_input(match_id_unsanitized) + + try: + response = matchmaking_queue.remove_user_from_Match(match_id, user_id) + if response == {"status": "success"}: + return "", 204 + else: + return jsonify({"message": "Internal Server Error"}), 500 + except Exception as e: + logger.graylog_logger(level="error", handler="remove_player_from_match", message=e) + return jsonify({"message": "Internal Server Error"}), 500 \ No newline at end of file diff --git a/src/logic/queue_handler.py b/src/logic/queue_handler.py index 1684c49..b857edf 100644 --- a/src/logic/queue_handler.py +++ b/src/logic/queue_handler.py @@ -46,8 +46,9 @@ class MatchmakingQueue: def queuePlayer(self, side, userId): try: + current_timestamp, expiration_timestamp = get_time() queuedPlayer = QueuedPlayer(userId, side, - get_time()) + current_timestamp) self.queuedPlayers.append(queuedPlayer) except Exception as e: logger.graylog_logger(level="error", handler="matchmaking_queuePlayer", message=e) @@ -62,9 +63,9 @@ class MatchmakingQueue: logger.graylog_logger(level="error", handler="matchmaking_getQueuedPlayer", message=e) return None - def getQueueStatus(self, side, userid): + def getQueueStatus(self, side, userId, region): try: - queuedPlayer, index = self.getQueuedPlayer(userid) + queuedPlayer, index = self.getQueuedPlayer(userId) if not queuedPlayer: return {} if side == 'B': @@ -75,8 +76,7 @@ class MatchmakingQueue: if len(openLobby.nonHosts) < 4: openLobby.nonHosts.append(queuedPlayer) self.queuedPlayers.pop(index) - return self.createQueueResponseMatched(openLobby.host.userId, openLobby.id, - userid) + return self.createQueueResponseMatched(openLobby.host, openLobby.id, userId) else: return { @@ -92,7 +92,7 @@ class MatchmakingQueue: matchId = self.genMatchUUID() lobby = Lobby(False, queuedPlayer, [], matchId, False, False) self.openLobbies.append(lobby) - return self.createQueueResponseMatched(userid, matchId) + return self.createQueueResponseMatched(userId, matchId) except Exception as e: logger.graylog_logger(level="error", handler="matchmaking_getQueueStatus", message=e) return None @@ -114,9 +114,10 @@ class MatchmakingQueue: return killedLobby return None - def registerMatch(self, matchId, sessionSettings): + def registerMatch(self, matchId, sessionSettings, userId): lobby, _ = self.getLobbyById(matchId) if lobby: + lobby.host = userId lobby.isReady = True lobby.sessionSettings = sessionSettings return self.createMatchResponse(matchId) @@ -125,12 +126,13 @@ class MatchmakingQueue: lobby, index = self.getLobbyById(matchId) if lobby: self.openLobbies.pop(index) - killedLobby = KilledLobby(lobby.id, lobby.reason, get_time()) + current_timestamp, expiration_timestamp = get_time() + killedLobby = KilledLobby(lobby.id, "killed_by_host", current_timestamp) self.killedLobbies.append(killedLobby) def isOwner(self, matchId, userid): lobby, _ = self.getLobbyById(matchId) - return lobby and lobby.host.userid == userid + return lobby and lobby.host == userid def deleteOldMatches(self): current_time = get_time() @@ -143,96 +145,61 @@ class MatchmakingQueue: lobby = self.getLobbyById(matchId)[0] or self.getKilledLobbyById(matchId) if not lobby: return {} + host = lobby.host + current_timestamp, expiration_timestamp = get_time() + try: + sessionSettings = lobby.sessionSettings + except: + sessionSettings = "" return { - "category": "Steam-te-18f25613-36778-ue4-374f864b", - "churn": 0, - "creationDateTime": get_time(), - "creator": lobby.host.userId, + "Category": "Steam-te-18f25613-36778-ue4-374f864b", + "creationDateTime": current_timestamp, + "creator": host, "customData": { - "SessionSettings": lobby.sessionSettings or "", + "SessionSettings": sessionSettings, }, - "geolocation": {}, - "matchId": matchId, + "MatchId": matchId, "props": { "countA": 1, "countB": 4, "EncryptionKey": "Rpqy9fgpIWrHxjJpiwnJJtoZ2hbUZZ4paU+0n4K/iZI=", - "gameMode": "None", + "gameMode": "4cb782397d46fc432d10bdc24538097a", "platform": "Windows", }, "rank": 1, - "reason": lobby.reason or "", - "schema": 3, - "sideA": [lobby.host.userId], + "Schema": 3, + "sideA": host, "sideB": [player.userId for player in lobby.nonHosts], - "skill": { - "continent": "NA", - "country": "US", - "latitude": 0, - "longitude": 0, - "rank": 20, - "rating": { - "rating": 1500, - "RD": 347.4356, - "volatility": 0.06, - }, - "regions": { - "good": ["us-east-1"], - "ok": ["us-east-1"], - }, - "version": 2, - "x": 20, - }, - "status": "KILLED" if killed else "OPENED", - "version": 2, + "Players": [host] + [player.userId for player in lobby.nonHosts], + "status": "KILLED" if killed else "OPENED" } except Exception as e: logger.graylog_logger(level="error", handler="matchmaking_createMatchResponse", message=e) def createQueueResponseMatched(self, creatorId, matchId, joinerId=None): try: + current_timestamp, expiration_timestamp = get_time() return { "status": "MATCHED", "matchData": { "category": "Steam-te-18f25613-36778-ue4-374f864b", - "churn": 0, - "creationDateTime": get_time(), + "creationDateTime": current_timestamp, "creator": creatorId, "customData": {}, - "geolocation": {}, "matchId": matchId, "props": { "countA": 1, - "countB": 4, + "countB": 5, "EncryptionKey": "Rpqy9fgpIWrHxjJpiwnJJtoZ2hbUZZ4paU+0n4K/iZI=", - "gameMode": "None", + "gameMode": "4cb782397d46fc432d10bdc24538097a", "platform": "Windows", }, "rank": 1, - "reason": "", "schema": 3, "sideA": [creatorId], "sideB": [joinerId] if joinerId else [], - "skill": { - "continent": "NA", - "country": "US", - "latitude": 0, - "longitude": 0, - "rank": 20, - "rating": { - "rating": 1500, - "RD": 347.4356, - "volatility": 0.06, - }, - "regions": { - "good": ["us-east-1"], - "ok": ["us-east-1"], - }, - "version": 2, - "x": 20, - }, - "status": "CREATED", - "version": 1, + "Players": [creatorId] + ([joinerId] if joinerId else []), + "status": "CREATED" }, } except Exception as e: @@ -241,11 +208,11 @@ class MatchmakingQueue: def getSession(self, userid): try: for lobby in self.openLobbies: - if lobby.host.userId == userid: - return Session(lobby.host.userId, [player.userId for player in lobby.nonHosts]) + if lobby.host == userid: + return Session(lobby.host, [player.userId for player in lobby.nonHosts]) for player in lobby.nonHosts: if player.userId == userid: - return Session(lobby.host.userId, [player.userId for player in lobby.nonHosts]) + return Session(lobby.host, [player.userId for player in lobby.nonHosts]) return None except Exception as e: logger.graylog_logger(level="error", handler="getSession", message=e) @@ -253,5 +220,21 @@ class MatchmakingQueue: def genMatchUUID(self): return str(uuid.uuid4()) + def remove_user_from_Match(self, matchId, userId): + try: + lobby, _ = self.getLobbyById(matchId) + if lobby: + if lobby.host == userId: + self.deleteMatch(matchId) + else: + for i, player in enumerate(lobby.nonHosts): + if player.userId == userId: + lobby.nonHosts.pop(i) + break + return {"status": "success"} + except Exception as e: + logger.graylog_logger(level="error", handler="remove_user_from_Match", message=e) + return {"status": "error"} + matchmaking_queue = MatchmakingQueue()