def load(self, loader, cache):
     if self.loaded:
         return
     decompressed = wtc.decompress(self.replay_data)
     parsed = osrparse.parse_replay(decompressed, pure_lzma=True)
     self._process_replay_data(parsed.play_data)
     self.loaded = True
Exemple #2
0
def parseReplay():
    byte_string = request.body.read()
    print(byte_string)
    byte_string = convert(byte_string.decode("ASCII"))
    print(byte_string)
    replay = parse_replay(byte_string)

    response = {
        'beatmap_hash': replay.replay_hash,
        'replay_hash': replay.replay_hash,
        'gamemode': replay.game_mode.value,
        'score': replay.score,
        'gekis': replay.gekis,
        'katus': replay.katus,
        'max_combo': replay.max_combo,
        'misses': replay.misses,
        'number_50s': replay.number_50s,
        'number_100s': replay.number_100s,
        'number_300s': replay.number_300s,
        'is_perfect_combo': replay.is_perfect_combo,
        'player_name': replay.player_name,
        'mod_combination': serializeMods(replay.mod_combination)
    }

    # Reverse katus and number_100s if on osu!mania due to API error
    if response['gamemode'] == 3:
        response['katus'], response['number_100s'] = response[
            'number_100s'], response['katus']

    return json.dumps(response)
Exemple #3
0
 def wrapper(*args, **kwargs):
     map_id = args[0]
     user_id = args[1]
     lzma = Cacher.check_cache(map_id, user_id)
     if (lzma):
         replay_data = osrparse.parse_replay(lzma, pure_lzma=True).play_data
         return Replay(replay_data, user_id)
     else:
         return function(*args, **kwargs)
    def setUpClass(cls):

        replay1_path = RES / "replay.osr"
        with open(replay1_path, "rb") as f:
            data = f.read()
        cls._replays = [
            parse_replay(data, pure_lzma=False),
            parse_replay_file(replay1_path)
        ]
        cls._combination_replay = parse_replay_file(RES / "replay2.osr")
Exemple #5
0
 def wrapper(*args, **kwargs):
     cacher = args[0]
     map_id = args[1]
     user_id = args[2]
     enabled_mods = args[4]
     lzma = cacher.check_cache(map_id, user_id)
     if (lzma):
         replay_data = osrparse.parse_replay(lzma, pure_lzma=True).play_data
         return Replay(replay_data, user_id, enabled_mods)
     else:
         return function(*args, **kwargs)
Exemple #6
0
    def wrapper(*args, **kwargs):
        self = args[0]
        replay_info = args[1]

        decompressed_lzma = self._check_cache(replay_info)
        if not decompressed_lzma:
            return function(*args, **kwargs)

        parsed = osrparse.parse_replay(decompressed_lzma,
                                       pure_lzma=True,
                                       decompressed_lzma=True)
        return parsed.play_data
Exemple #7
0
    def replay_data(self, replay_info, cache=None):
        """
        Retrieves replay data from the api, or from the cache if it is already
        cached.

        Parameters
        ----------
        replay_info: :class:`~.ReplayInfo`
            The replay info representing the replay to retrieve.

        Returns
        -------
        list[:class:`osrparse.replay.ReplayEvent`]
            The replay events with attributes ``x``, ``y``,
            ``time_delta``, and ``keys``.
        None
            If no replay data was available.

        Raises
        ------
        ReplayUnavailableException
            If ``user_info.replay_available` was 1, but we did not receive
            replay data from the api.
        """

        user_id = replay_info.user_id
        beatmap_id = replay_info.beatmap_id
        mods = replay_info.mods
        if not replay_info.replay_available:
            self.log.debug(
                "Replay data by user %d on map %d with mods %s not "
                "available", user_id, beatmap_id, mods)
            return None

        lzma_bytes = self.load_replay_data(beatmap_id, user_id, mods)
        if lzma_bytes is None:
            raise ReplayUnavailableException(
                "The api guaranteed there "
                "would be a replay available, but we did not receive any data."
            )
        try:
            parsed_replay = osrparse.parse_replay(lzma_bytes, pure_lzma=True)
        # see https://github.com/circleguard/circlecore/issues/61
        # api sometimes returns corrupt replays
        except LZMAError:
            self.log.warning(
                "lzma from %r could not be decompressed, api "
                "returned corrupt replay", replay_info)
            return None
        replay_data = parsed_replay.play_data
        if cache:
            self._cache(lzma_bytes, replay_info)
        return replay_data
Exemple #8
0
    def wrapper(*args, **kwargs):
        self = args[0]
        replay_info = args[1]

        if self.cacher is None:
            return function(*args, **kwargs)

        decompressed_lzma = self.cacher.check_cache(replay_info)
        if decompressed_lzma:
            parsed = osrparse.parse_replay(decompressed_lzma, \
                pure_lzma=True, decompressed_lzma=True)
            return parsed.play_data
        else:
            return function(*args, **kwargs)
Exemple #9
0
    def from_map(map_id, user_id, cache, replay_id):
        """
        Creates a Replay instance from a replay by the given user on the given map.

        Args:
            String map_id: The map_id to download the replay from.
            String user_id: The user id to download the replay of.
                            Also used as the username of the Replay.

        Returns:
            The Replay instance created with the given information.
        """

        lzma_bytes = Loader.replay_data(map_id, user_id)
        parsed_replay = osrparse.parse_replay(lzma_bytes, pure_lzma=True)
        replay_data = parsed_replay.play_data
        if (cache):
            Cacher.cache(map_id, user_id, lzma_bytes, replay_id)
        return OnlineReplay(replay_data, user_id)
Exemple #10
0
    def load(self, loader, cache):
        """
        Loads the data for this replay from the string replay data.

        Parameters
        ----------
        loader: :class:`~.loader.Loader`
            The :class:`~.loader.Loader` to load this replay with.
        cache: bool
            Whether to cache this replay after loading it. This only has an
            effect if ``self.cache`` is unset (``None``). Note that currently
            we do not cache :class:`~.ReplayString` regardless of this
            parameter.

        Notes
        -----
        If ``replay.loaded`` is ``True``, this method has no effect.
        ``replay.loaded`` is set to ``True`` after this method is finished.
        """

        self.log.debug("Loading ReplayString %r", self)
        if self.loaded:
            self.log.debug("%s already loaded, not loading", self)
            return

        loaded = osrparse.parse_replay(self.replay_data_str, pure_lzma=False)
        self.game_version = GameVersion(loaded.game_version, concrete=True)
        self.timestamp = loaded.timestamp
        self.map_id = loader.map_id(loaded.beatmap_hash)
        self.username = loaded.player_name
        # our `user_id` attribute is lazy loaded, so we need to retain the
        # `Loader#user_id` function to use later to load it.
        self._user_id_func = loader.user_id
        self._user_id = None
        self.mods = Mod(loaded.mod_combination)
        self.replay_id = loaded.replay_id
        self.beatmap_hash = loaded.beatmap_hash

        self._process_replay_data(loaded.play_data)
        self.loaded = True
        self.log.log(TRACE, "Finished loading %s", self)
Exemple #11
0
    def replay_data_from_id(self, replay_id, _cache):
        """
        Retrieves replay data from the api, given a replay id.

        Parameters
        ----------
        replay_id: int
            The id of the replay to retrieve data for.
        """
        content = self.api.get_replay(score_id=replay_id)
        lzma = base64.b64decode(content)
        replay_data = osrparse.parse_replay(lzma, pure_lzma=True).play_data
        # TODO cache the replay here, might require some restructuring/double
        # checking everything will work because we only have its id, not map
        # or user id. In fact I think our db asserts map and user id are nonull
        # so insertion into old dbs probably won't work (and we'd have to change
        # the schema).
        # TODO include a db version in the db for future scenarios like this?
        # look into how that's typically done, maybe just a `VERSION` table with
        # a single row
        return replay_data
Exemple #12
0
    def from_map(cacher, map_id, user_id, replay_id, enabled_mods):
        """
        Creates a Replay instance from a replay by the given user on the given map.

        Args:
            Cacher cacher: A cacher object containing a database connection.
            String map_id: The map_id to download the replay from.
            String user_id: The user id to download the replay of.
                            Also used as the username of the Replay.
            String replay_id: The id of the replay we are retrieving (used to cache).
            Integer enabled_mods: The base10 number representing the enabled mods

        Returns:
            The Replay instance created with the given information, or None if the replay was not available.
        """

        lzma_bytes = Loader.replay_data(map_id, user_id)
        if (lzma_bytes is None):
            return None
        parsed_replay = osrparse.parse_replay(lzma_bytes, pure_lzma=True)
        replay_data = parsed_replay.play_data
        cacher.cache(map_id, user_id, lzma_bytes, replay_id)
        return OnlineReplay(replay_data, user_id, enabled_mods, replay_id)
Exemple #13
0
import osrparse
from PIL import Image, ImageDraw, ImageFont
import os
import numpy as np

# replay = parse_replay_file("understand.osr")

with open("superdriver.osr", "rb") as f:
    data = f.read()

osu = Map("superdriver.osu")

replay = osrparse.parse_replay(data)

length1 = 0

events_to_use = []

intervals = [
    int(x * (1000 / 60))
    for x in range(0, int(replay.play_data[-1].timestamp / (1000 / 60)))
]

print(sorted(osu.hitobjects.keys())[-1])
print(replay.play_data[-1].timestamp)
print(len(replay.play_data))

plays = {}
for x in replay.play_data:
    plays[x.timestamp] = [x.x, x.y, x.keys_pressed]