예제 #1
0
    def setUpClass(cls):
        super().setUpClass()

        cls.user = User(
            2757689,
            "1-2")  # toy, #1=sidetracked day, #2=View of The River Styx
        cls.user1 = User(2757689, "1-2", cache=False)
        cls.user2 = User(2757689, "1-2", mods=Mod.HT)
        cls.user3 = User(2757689, "1")

        cls.map = Map(
            1754777, "1-4")  #sidetracked day: umbre, karthy, -duckleader-, toy
        cls.map1 = Map(1754777, "1-4", cache=False)
        cls.map2 = Map(1754777, "1-4", mods=Mod.HD)
        cls.map3 = Map(1754777, "1-2")

        cls.r = ReplayMap(1754777, 2766034)  # umbre +HDHR on sidetracked day
        cls.r1 = ReplayMap(1754777, 2766034, cache=True)
        cls.r2 = ReplayMap(1754777, 2766034, mods=Mod.NF)

        cls.r3 = ReplayPath(RES / "legit" / "legit-1.osr")
        cls.r4 = ReplayPath(RES / "legit" / "legit-1.osr", cache=True)
        cls.r5 = ReplayPath(RES / "stolen_replay1.osr")

        cls.cg.load_info(cls.user)
        cls.cg.load_info(cls.user1)
        cls.cg.load_info(cls.user2)

        cls.cg.load_info(cls.map)
        cls.cg.load_info(cls.map1)
        cls.cg.load_info(cls.map2)
예제 #2
0
    def setUpClass(cls):
        super().setUpClass()
        cls.timewarped1 = ReplayPath(RES / "timewarped" / "timewarped-1.osr")
        cls.timewarped2 = ReplayPath(RES / "timewarped" / "timewarped-2.osr")
        cls.timewarped3 = ReplayPath(RES / "timewarped" / "timewarped-3.osr")
        cls.timewarped4 = ReplayPath(RES / "timewarped" / "timewarped-4.osr")

        cls.legit = ReplayPath(RES / "legit" / "legit-1.osr")
예제 #3
0
 def setUpClass(cls):
     super().setUpClass()
     cls.r1 = ReplayPath(RES / "corrected_replay1.osr")
     # TODO replays r2 and r5 might not have been properly named, r2 has 0
     # snaps
     cls.r2 = ReplayPath(RES / "legit" / "legit_snaps-1.osr")
     cls.r3 = ReplayPath(RES / "legit" / "legit_snaps-2.osr")
     cls.r4 = ReplayPath(RES / "legit" / "legit_snaps-3.osr")
     cls.r5 = ReplayPath(RES / "legit" / "legit_snaps-4.osr")
예제 #4
0
 def test_loading_replaypath(self):
     r = ReplayPath(RES / "example_replay.osr")
     self.assertFalse(r.loaded)
     self.cg.load(r)
     self.assertEqual(r.mods, Mod.HD + Mod.DT)
     self.assertEqual(r.replay_id, 2029801532)
     self.assertEqual(r.username, "MarthXT")
     self.assertEqual(r.user_id, 2909663)
     self.assertEqual(r.weight, RatelimitWeight.LIGHT)
     self.assertTrue(r.loaded)
     self.assertEqual(r.beatmap_hash, "c7f9bc1fea826c0f371db08bc5ebc1cc")
     self.assertEqual(r.replay_hash, "266bc8a5f6e9ac0557862da6760388ef")
     self.assertEqual(r.count_300, 154)
     self.assertEqual(r.count_100, 0)
     self.assertEqual(r.count_50, 0)
     self.assertEqual(r.count_geki, 23)
     self.assertEqual(r.count_katu, 0)
     self.assertEqual(r.count_miss, 0)
     self.assertEqual(r.score, 1083482)
     self.assertEqual(r.max_combo, 186)
     self.assertTrue(r.is_perfect_combo)
     self.assertEqual(r.life_bar_graph, None)
     self.assertEqual(
         r.timestamp, datetime(2015,
                               12,
                               16,
                               19,
                               40,
                               39,
                               tzinfo=timezone.utc))
예제 #5
0
 def test_loading_replaypath(self):
     r = ReplayPath(RES / "example_replay.osr")
     self.kcg.load(r)
     self.assertRaises(ValueError, lambda: r.map_id)
     self.assertRaises(ValueError, lambda: r.user_id)
     self.assertEqual(r.mods, Mod.HD + Mod.DT, "Mods was not correct")
     self.assertEqual(r.replay_id, 2029801532, "Replay id was not correct")
     self.assertEqual(r.username, "MarthXT", "Username was not correct")
     self.assertTrue(r.loaded, "Loaded status was not correct")
예제 #6
0
    def test_robustness_to_translation(self):
        # copy replay to avoid any missahaps when we mutate the data
        stolen2 = ReplayPath(self.stolen2.path)
        self.cg.load(stolen2)
        TestSimilarity.add_noise_and_positional_translation_to_replay(stolen2, 10, 3)
        sim = self.cg.similarity(self.stolen1, stolen2, method="similarity")
        corr = self.cg.similarity(self.stolen1, stolen2, method="correlation")

        self.assertLess(sim, Circleguard.SIM_LIMIT, "Cheated replays were not detected as cheated with sim")
        self.assertGreater(corr, Circleguard.CORR_LIMIT, "Cheated replays were not detected as cheated with correlation")
예제 #7
0
 def test_loading_replaypath(self):
     r = ReplayPath(RES / "example_replay.osr")
     self.assertFalse(r.loaded, "Loaded status was not correct")
     self.cg.load(r)
     self.assertEqual(r.mods, Mod.HD + Mod.DT, "Mods was not correct")
     self.assertEqual(r.replay_id, 2029801532, "Replay id was not correct")
     self.assertEqual(r.username, "MarthXT", "Username was not correct")
     self.assertEqual(r.user_id, 2909663, "User id was not correct")
     self.assertEqual(r.weight, RatelimitWeight.LIGHT,
                      "RatelimitWeight was not correct")
     self.assertTrue(r.loaded, "Loaded status was not correct")
예제 #8
0
 def setUpClass(cls):
     super().setUpClass()
     # TODO check `legit-12.osr` as well once ur calc notelock issues are
     # dealt with, which causes us to be ~3 ur off from the actual for it
     cls.replays = [
         ReplayPath(RES / "legit" / f"legit-{i}.osr") for i in range(1, 12)
     ]
     cls.urs = [
         66.74, 66.56, 242.73, 115.54, 254.56, 90.88, 121.62, 163.01,
         207.31, 198.79, 138.25
     ]
예제 #9
0
 def setUpClass(cls):
     super().setUpClass()
     cls.stolen1 = ReplayPath(RES / "stolen_replay1.osr")
     cls.stolen2 = ReplayPath(RES / "stolen_replay2.osr")
     cls.legit1 = ReplayPath(RES / "legit" / "legit-1.osr")
     cls.legit2 = ReplayPath(RES / "legit" / "legit-2.osr")
     cls.time_shifted1 = ReplayPath(RES / "stealing" / "stolen-time-shifted-1-1.osr")
     cls.time_shifted2 = ReplayPath(RES / "stealing" / "stolen-time-shifted-1-2.osr")
예제 #10
0
    def process_beatmap(self):
        cur = utils.osu_db.execute(
            'SELECT beatmap_id, folder_name, map_file, artist, '
            'title, difficulty, mapper FROM maps WHERE md5_hash=?',
            (self.replay.beatmap_hash, ))
        result = cur.fetchone()
        cur.close()

        if result is None:
            print(
                color(
                    "Beatmap not in osu!.db, defaulting to Circleguard version.",
                    fg='red'))
            self.cg_replay = ReplayPath(self.replay_path)
            beatmap = utils.cg.beatmap(self.cg_replay)

            self.beatmap_id = self.cg_replay.map_info.map_id
            if self.beatmap_id is None:
                print(color("Beatmap not found.", fg='red'))
            print(color("Cached beatmap found!", fg='green'))

            folder_name = utils.cg.library.path
            cur = utils.cg.library._db.execute(
                'SELECT path from beatmaps WHERE md5=?',
                (self.replay.beatmap_hash, ))
            map_file = cur.fetchone()[0]
            self.map_path = folder_name / map_file
            cur.close()

            self.artist = beatmap.artist
            self.title = beatmap.title
            self.difficulty = beatmap.version
            self.mapper = beatmap.creator
            return True

        self.beatmap_id, folder_name, map_file, self.artist, \
            self.title, self.difficulty, self.mapper = result
        map_folder = utils.BEATMAPS_DIR / folder_name
        self.map_path = map_folder / map_file

        with open(self.map_path) as file:
            lines = file.readlines()
        groups = Beatmap._find_groups(lines)
        events = groups['Events']
        for line in events:
            if any(ext in line for ext in ['.jpg', '.jpeg', '.png']):
                bg_file = search('"(.+?)"', line).group(1)
                break
        self.bg_path = map_folder / bg_file
        return False
예제 #11
0
    def setUpClass(cls):
        super().setUpClass()
        cls.timewarped1 = ReplayPath(RES / "timewarped" / "timewarped-1.osr")
        cls.timewarped2 = ReplayPath(RES / "timewarped" / "timewarped-2.osr")
        cls.timewarped3 = ReplayPath(RES / "timewarped" / "timewarped-3.osr")
        cls.timewarped4 = ReplayPath(RES / "timewarped" / "timewarped-4.osr")

        cls.relax_legit = ReplayPath(RES / "legit" / "legit_144fps_nmrx.osr")

        cls.legit = ReplayPath(RES / "legit_replay1.osr")
예제 #12
0
    def test_robustness_to_translation(self):
        # copy replay to avoid any missahaps when we mutate the data
        stolen2 = ReplayPath(self.stolen2.path)
        replays = [self.stolen1, stolen2]
        self.cg.load(stolen2)
        TestSteal.add_noise_and_positional_translation_to_replay(
            stolen2, 10, 3)
        results = list(
            self.cg.steal_check(replays,
                                method=Detect.STEAL_CORR | Detect.STEAL_SIM))

        self.assertEqual(len(results), 2,
                         f"{len(results)} results returned instead of 2")
        for r in results:
            if isinstance(r, StealResultSim):
                self.assertLess(
                    r.similarity, Detect.SIM_LIMIT,
                    "Cheated replays were not detected as cheated with sim")
            if isinstance(r, StealResultCorr):
                self.assertGreater(
                    r.correlation, Detect.CORR_LIMIT,
                    "Cheated replays were not detected as cheated with corr")
예제 #13
0
 def _parse_replay(self, path):
     replay = ReplayPath(path)
     self.cg.load(replay)
     if self.map_id is None or len(
             self.replays) == 0:  # store map_id if nothing stored
         log.info(f"Changing map_id from {self.map_id} to {replay.map_id}")
         self.map_id = replay.map_id
         self.update_map_id_label()
     elif replay.map_id != self.map_id:  # ignore replay with diffrent map_ids
         log.error(
             f"replay {replay} doesn't match with current map_id ({replay.map_id} != {self.map_id})"
         )
         return
     if not any(replay.replay_id == r.data.replay_id
                for r in self.replays):  # check if already stored
         log.info(
             f"adding new replay {replay} with replay id {replay.replay_id} on map {replay.map_id}"
         )
         self.q.put(replay)
     else:
         log.info(
             f"skipping replay {replay} with replay id {replay.replay_id} on map {replay.map_id} since it's already saved"
         )
예제 #14
0
 def benchmark_func():
     replay = ReplayPath(RES / "legit" / "legit-1.osr")
     cg.ur(replay)
예제 #15
0
 def benchmark_func():
     # creating a new cg object is a hacky way to force a new slider
     # cache
     cg = Circleguard(KEY)
     replay = ReplayPath(RES / "legit" / "legit-1.osr")
     cg.ur(replay)
예제 #16
0
# Benchmarks for circleguard. These are not strictly "tests" and will not be run
# by unittest, but it felt appropriate to place them in the tests folder.

import cProfile
from pstats import Stats

from circleguard import Circleguard, ReplayPath
# pylint has trouble with files named "utils" apparently
from utils import KEY, RES  # pylint: disable=no-name-in-module

cg = Circleguard(KEY)

replay1 = ReplayPath(RES / "legit" / "legit-1.osr")
cg.load(replay1)


def benchmark_ur(with_cache):
    """
    Parameters
    ----------
    with_cache: {"none", "replay", "beatmap", "both"}
        What caches to use when calculating the ur of the replay. If "replay",
        a replay that has already been loaded is used. If "beatmap", the beatmap
        is downloaded on the first call, and is cached thereafter. If "both",
        both of the above caches apply.
    """
    profiler = cProfile.Profile()

    if with_cache == "none":
        num_calls = 10
예제 #17
0
 def setUpClass(cls):
     super().setUpClass()
     cls.r1 = ReplayPath(RES / "corrected_replay1.osr")
예제 #18
0
 def test_no_replay_data_raises(self):
     r = ReplayPath(RES / "other" / "empty_replay_data.osr")
     self.assertRaises(ValueError, lambda: self.cg.load(r))
예제 #19
0
 def find_ur(self):
     if self.cg_replay is None:
         self.cg_replay = ReplayPath(self.replay_path)
     self.ur = utils.cg.ur(self.cg_replay)