Beispiel #1
0
def buildFullReplay(scoreID=None, scoreData=None, rawReplay=None):
    if all(v is None for v in (scoreID, scoreData)) or all(
            v is not None for v in (scoreID, scoreData)):
        raise AttributeError(
            "Either scoreID or scoreData must be provided, not neither or both"
        )

    if scoreData is None:
        scoreData = glob.db.fetch(
            "SELECT scores.*, users.username FROM scores LEFT JOIN users ON scores.userid = users.id "
            "WHERE scores.id = %s", [scoreID])
    else:
        scoreID = scoreData["id"]
    if scoreData is None or scoreID is None:
        raise exceptions.scoreNotFoundError()

    if rawReplay is None:
        # Make sure raw replay exists
        fileName = getFirstReplayFileName(scoreID)
        if fileName is None:
            raise FileNotFoundError()

        # Read raw replay
        with open(fileName, "rb") as f:
            rawReplay = f.read()

    # Calculate missing replay data
    rank = generalUtils.getRank(int(scoreData["play_mode"]),
                                int(scoreData["mods"]),
                                int(scoreData["accuracy"]),
                                int(scoreData["300_count"]),
                                int(scoreData["100_count"]),
                                int(scoreData["50_count"]),
                                int(scoreData["misses_count"]))
    magicHash = generalUtils.stringMd5(
        "{}p{}o{}o{}t{}a{}r{}e{}y{}o{}u{}{}{}".format(
            int(scoreData["100_count"]) + int(scoreData["300_count"]),
            scoreData["50_count"], scoreData["gekis_count"],
            scoreData["katus_count"], scoreData["misses_count"],
            scoreData["beatmap_md5"], scoreData["max_combo"],
            "True" if int(scoreData["full_combo"]) == 1 else "False",
            scoreData["username"], scoreData["score"], rank, scoreData["mods"],
            "True"))
    # Add headers (convert to full replay)
    fullReplay = binaryHelper.binaryWrite([
        [scoreData["play_mode"], dataTypes.byte],
        [20150414, dataTypes.uInt32],
        [scoreData["beatmap_md5"], dataTypes.string],
        [scoreData["username"], dataTypes.string],
        [magicHash, dataTypes.string],
        [scoreData["300_count"], dataTypes.uInt16],
        [scoreData["100_count"], dataTypes.uInt16],
        [scoreData["50_count"], dataTypes.uInt16],
        [scoreData["gekis_count"], dataTypes.uInt16],
        [scoreData["katus_count"], dataTypes.uInt16],
        [scoreData["misses_count"], dataTypes.uInt16],
        [scoreData["score"], dataTypes.uInt32],
        [scoreData["max_combo"], dataTypes.uInt16],
        [scoreData["full_combo"], dataTypes.byte],
        [scoreData["mods"], dataTypes.uInt32],
        [0, dataTypes.byte],
        [toDotTicks(int(scoreData["time"])), dataTypes.uInt64],
        [rawReplay, dataTypes.rawReplay],
        [0, dataTypes.uInt32],
        [0, dataTypes.uInt32],
    ])

    # Return full replay
    return fullReplay
Beispiel #2
0
def buildFullReplay(scoreID=None, scoreData=None, rawReplay=None, relax=0):
    if all(v is None for v in (scoreID, scoreData)) or all(
            v is not None for v in (scoreID, scoreData)):
        raise AttributeError(
            "Either scoreID or scoreData must be provided, not neither or both"
        )

    if scoreData is None:
        if features.MASTER_SCORE_TABLE:
            scoreData = glob.db.fetch(
                "SELECT s.*, users.username FROM scores_master as s LEFT JOIN users ON s.userid = users.id "
                "WHERE s.id = %s AND special_mode = %s",
                [scoreID, int(relax)])
        else:
            scoreData = glob.db.fetch(
                f"SELECT s.*, users.username FROM {modeSwitches.score[relax]} as s LEFT JOIN users ON s.userid = users.id "
                "WHERE s.id = %s", [scoreID])
    else:
        scoreID = scoreData["id"]
    if scoreData is None or scoreID is None:
        raise exceptions.scoreNotFoundError()

    if rawReplay is None:
        # Make sure raw replay exists
        fileName = "{}{}/replay_{}.osr".format(
            glob.conf.config["server"]["replayspath"],
            modeSwitches.rp_folder[relax], scoreID)
        if not os.path.isfile(fileName):
            log.error('[SM{}] Trying to open {}...'.format(relax, fileName))
            raise FileNotFoundError()

        # Read raw replay
        with open(fileName, "rb") as f:
            rawReplay = f.read()

    # Calculate missing replay data
    rank = generalUtils.getRank(int(scoreData["play_mode"]),
                                int(scoreData["mods"]),
                                int(scoreData["accuracy"]),
                                int(scoreData["300_count"]),
                                int(scoreData["100_count"]),
                                int(scoreData["50_count"]),
                                int(scoreData["misses_count"]))
    magicHash = generalUtils.stringMd5(
        "{}p{}o{}o{}t{}a{}r{}e{}y{}o{}u{}{}{}".format(
            int(scoreData["100_count"]) + int(scoreData["300_count"]),
            scoreData["50_count"], scoreData["gekis_count"],
            scoreData["katus_count"], scoreData["misses_count"],
            scoreData["beatmap_md5"], scoreData["max_combo"],
            "True" if int(scoreData["full_combo"]) == 1 else "False",
            scoreData["username"], scoreData["score"], rank, scoreData["mods"],
            "True"))
    # Add headers (convert to full replay)
    fullReplay = binaryHelper.binaryWrite([
        [scoreData["play_mode"], dataTypes.byte],
        [20150414, dataTypes.uInt32],
        [scoreData["beatmap_md5"], dataTypes.string],
        [scoreData["username"], dataTypes.string],
        [magicHash, dataTypes.string],
        [scoreData["300_count"], dataTypes.uInt16],
        [scoreData["100_count"], dataTypes.uInt16],
        [scoreData["50_count"], dataTypes.uInt16],
        [scoreData["gekis_count"], dataTypes.uInt16],
        [scoreData["katus_count"], dataTypes.uInt16],
        [scoreData["misses_count"], dataTypes.uInt16],
        [scoreData["score"], dataTypes.uInt32],
        [scoreData["max_combo"], dataTypes.uInt16],
        [scoreData["full_combo"], dataTypes.byte],
        [scoreData["mods"], dataTypes.uInt32],
        [0, dataTypes.byte],
        [generalHelper.toDotTicks(int(scoreData["time"])), dataTypes.uInt64],
        [rawReplay, dataTypes.rawReplay],
        [0, dataTypes.uInt32],
        [scoreData['id'], dataTypes.uInt64],
    ])

    # Return full replay
    return fullReplay
Beispiel #3
0
def buildFullReplay(scoreID=None, scoreData=None, rawReplay=None):
    if all(v is None for v in (scoreID, scoreData)) or all(
            v is not None for v in (scoreID, scoreData)):
        raise AttributeError(
            "Either scoreID or scoreData must be provided, not neither or both"
        )

    mode = 0
    # TODO: Implement better way to handle this
    if scoreData is None:
        scoreData = glob.db.fetch(
            "SELECT osu_scores_high.*, phpbb_users.username FROM osu_scores_high LEFT JOIN phpbb_users ON osu_scores_high.user_id = phpbb_users.user_id "
            "WHERE osu_scores_high.score_id = %s", [scoreID])
        if scoreData is None:
            mode = 1
            scoreData = glob.db.fetch(
                "SELECT osu_scores_taiko_high.*, phpbb_users.username FROM osu_scores_taiko_high LEFT JOIN phpbb_users ON osu_scores_taiko_high.user_id = phpbb_users.user_id "
                "WHERE osu_scores_taiko_high.score_id = %s", [scoreID])
            if scoreData is None:
                mode = 2
                scoreData = glob.db.fetch(
                    "SELECT osu_scores_fruits_high.*, phpbb_users.username FROM osu_scores_fruits_high LEFT JOIN phpbb_users ON osu_scores_fruits_high.user_id = phpbb_users.user_id "
                    "WHERE osu_scores_fruits_high.score_id = %s", [scoreID])
                if scoreData is None:
                    mode = 3
                    scoreData = glob.db.fetch(
                        "SELECT osu_scores_mania_high.*, phpbb_users.username FROM osu_scores_mania_high LEFT JOIN phpbb_users ON osu_scores_mania_high.user_id = phpbb_users.user_id "
                        "WHERE osu_scores_mania_high.score_id = %s", [scoreID])
    else:
        scoreID = scoreData["id"]
    if scoreData is None or scoreID is None:
        raise exceptions.scoreNotFoundError()
    scoreID = int(scoreID)

    if rawReplay is None:
        rawReplay = getRawReplayS3(scoreID)

    # Calculate missing replay data
    rank = generalUtils.getRank(int(mode), int(scoreData["mods"]),
                                int(scoreData["accuracy"]),
                                int(scoreData["count300"]),
                                int(scoreData["count100"]),
                                int(scoreData["count50"]),
                                int(scoreData["countmiss"]))
    checksum = glob.db.fetch(
        "SELECT checksum FROM osu_beatmaps WHERE beatmap_id = %s LIMIT 1",
        (scoreData["beatmap_id"]))
    magicHash = generalUtils.stringMd5(
        "{}p{}o{}o{}t{}a{}r{}e{}y{}o{}u{}{}{}".format(
            int(scoreData["count100"]) + int(scoreData["count300"]),
            scoreData["count50"],
            scoreData["countgeki"],
            scoreData["countkatu"],
            scoreData["countmiss"],
            checksum,
            scoreData["maxcombo"],
            "True" if int(scoreData["perfect"]) == 1 else
            "False",  # TODO: check whether full combo or not (or "perfect" means "full combo"?)
            scoreData["username"],
            scoreData["score"],
            rank,
            scoreData["enabled_mods"],
            "True"))
    # Add headers (convert to full replay)
    fullReplay = binaryHelper.binaryWrite([
        [mode, dataTypes.byte],
        [20150414, dataTypes.uInt32],
        [scoreData["checksum"], dataTypes.string],
        [scoreData["username"], dataTypes.string],
        [magicHash, dataTypes.string],
        [scoreData["count300"], dataTypes.uInt16],
        [scoreData["count100"], dataTypes.uInt16],
        [scoreData["count50"], dataTypes.uInt16],
        [scoreData["countgeki"], dataTypes.uInt16],
        [scoreData["countkatu"], dataTypes.uInt16],
        [scoreData["countmiss"], dataTypes.uInt16],
        [scoreData["score"], dataTypes.uInt32],
        [scoreData["maxcombo"], dataTypes.uInt16],
        [scoreData["perfect"], dataTypes.byte],
        [scoreData["enabled_mods"], dataTypes.uInt32],
        [0, dataTypes.byte],
        [toDotTicks(int(scoreData["date"])), dataTypes.uInt64],
        [rawReplay, dataTypes.rawReplay],
        [0, dataTypes.uInt32],
        [0, dataTypes.uInt32],
    ])

    # Return full replay
    return fullReplay
    def asyncGet(self, replayID):
        try:
            # Make sure the score exists
            scoreData = glob.db.fetch(
                "SELECT scores.*, users.username FROM scores LEFT JOIN users ON scores.userid = users.id WHERE scores.id = %s",
                [replayID])
            if scoreData is None:
                raise exceptions.fileNotFoundException(MODULE_NAME, replayID)

            # Make sure raw replay exists
            fileName = ".data/replays/replay_{}.osr".format(replayID)
            if not os.path.isfile(fileName):
                raise exceptions.fileNotFoundException(MODULE_NAME, fileName)

            # Read raw replay
            with open(fileName, "rb") as f:
                rawReplay = f.read()

            # Calculate missing replay data
            rank = generalUtils.getRank(int(scoreData["play_mode"]),
                                        int(scoreData["mods"]),
                                        int(scoreData["accuracy"]),
                                        int(scoreData["300_count"]),
                                        int(scoreData["100_count"]),
                                        int(scoreData["50_count"]),
                                        int(scoreData["misses_count"]))
            magicHash = generalUtils.stringMd5(
                "{}p{}o{}o{}t{}a{}r{}e{}y{}o{}u{}{}{}".format(
                    int(scoreData["100_count"]) + int(scoreData["300_count"]),
                    scoreData["50_count"], scoreData["gekis_count"],
                    scoreData["katus_count"], scoreData["misses_count"],
                    scoreData["beatmap_md5"], scoreData["max_combo"],
                    "True" if int(scoreData["full_combo"]) == 1 else "False",
                    scoreData["username"], scoreData["score"], rank,
                    scoreData["mods"], "True"))
            # Add headers (convert to full replay)
            fullReplay = binaryHelper.binaryWrite([
                [scoreData["play_mode"], dataTypes.byte],
                [20150414, dataTypes.uInt32],
                [scoreData["beatmap_md5"], dataTypes.string],
                [scoreData["username"], dataTypes.string],
                [magicHash, dataTypes.string],
                [scoreData["300_count"], dataTypes.uInt16],
                [scoreData["100_count"], dataTypes.uInt16],
                [scoreData["50_count"], dataTypes.uInt16],
                [scoreData["gekis_count"], dataTypes.uInt16],
                [scoreData["katus_count"], dataTypes.uInt16],
                [scoreData["misses_count"], dataTypes.uInt16],
                [scoreData["score"], dataTypes.uInt32],
                [scoreData["max_combo"], dataTypes.uInt16],
                [scoreData["full_combo"], dataTypes.byte],
                [scoreData["mods"], dataTypes.uInt32],
                [0, dataTypes.byte],
                [
                    int((scoreData["time"] * 10000000) + 621355968000000000),
                    dataTypes.uInt64
                ],
                [rawReplay, dataTypes.rawReplay],
                [0, dataTypes.uInt32],
                [0, dataTypes.uInt32],
            ])

            # Serve full replay
            self.write(fullReplay)
            self.add_header("Content-type", "application/octet-stream")
            self.set_header("Content-length", len(fullReplay))
            self.set_header("Content-Description", "File Transfer")
            self.set_header(
                "Content-Disposition",
                "attachment; filename=\"{}.osr\"".format(scoreData["id"]))
        except exceptions.fileNotFoundException:
            self.write("Replay not found")
Beispiel #5
0
            scoreData["beatmap_md5"], scoreData["max_combo"],
            "True" if int(scoreData["full_combo"]) == 1 else "False",
            scoreData["username"], scoreData["score"], rank, scoreData["mods"],
            "True"))
    # Add headers (convert to full replay)
    fullReplay = binaryHelper.binaryWrite([
        [scoreData["play_mode"], dataTypes.byte],
        [20150414, dataTypes.uInt32],
        [scoreData["beatmap_md5"], dataTypes.string],
        [scoreData["username"], dataTypes.string],
        [magicHash, dataTypes.string],
        [scoreData["300_count"], dataTypes.uInt16],
        [scoreData["100_count"], dataTypes.uInt16],
        [scoreData["50_count"], dataTypes.uInt16],
        [scoreData["gekis_count"], dataTypes.uInt16],
        [scoreData["katus_count"], dataTypes.uInt16],
        [scoreData["misses_count"], dataTypes.uInt16],
        [scoreData["score"], dataTypes.uInt32],
        [scoreData["max_combo"], dataTypes.uInt16],
        [scoreData["full_combo"], dataTypes.byte],
        [scoreData["mods"], dataTypes.uInt32],
        [0, dataTypes.byte],
        [generalHelper.toDotTicks(int(scoreData["time"])), dataTypes.uInt64],
        [rawReplay, dataTypes.rawReplay],
        [0, dataTypes.uInt32],
        [scoreData['id'], dataTypes.uInt64],
    ])

    # Return full replay
    return fullReplay