Beispiel #1
0
    def calc_diff(self, osu_file_path: Path) -> tuple[float, float]:
        """Calculate PP and star rating for our score."""
        mode_vn = self.mode.as_vanilla

        if mode_vn in (0, 1):  # osu, taiko
            with OppaiWrapper('oppai-ng/liboppai.so') as ezpp:
                if self.mods:
                    ezpp.set_mods(int(self.mods))

                if mode_vn:
                    ezpp.set_mode(mode_vn)

                ezpp.set_combo(self.max_combo)
                ezpp.set_nmiss(self.nmiss)  # clobbers acc
                ezpp.set_accuracy_percent(self.acc)

                ezpp.calculate(osu_file_path)

                return (ezpp.get_pp(), ezpp.get_sr())
        elif mode_vn == 2:  # catch
            return (0.0, 0.0)
        else:  # mania
            if self.bmap.mode.as_vanilla != 3:
                return (0.0, 0.0)  # maniera has no convert support

            if self.mods != Mods.NOMOD:
                mods = int(self.mods)
            else:
                mods = 0

            calc = Maniera(str(osu_file_path), mods, self.score)
            calc.calculate()

            return (calc.pp, calc.sr)
Beispiel #2
0
    async def calc_acc(self, acc: float) -> float:
        path = Path.cwd() / f"resources/maps/{self.id}.osu"
        if not path.exists():
            url = f"https://old.ppy.sh/osu/{self.id}"

            async with glob.web.get(url) as resp:
                if not resp or resp.status != 200:
                    return 0.0

                m = await resp.read()
                path.write_bytes(m)

        if self.mode.as_vn <= 1:
            with OppaiWrapper("oppai-ng/liboppai.so") as ezpp:
                ezpp.set_accuracy_percent(acc)
                ezpp.set_mode(self.mode.as_vn)

                ezpp.calculate(path)
                pp = round(ezpp.get_pp())  # returning sr soontm
        else:
            if self.mode.as_vn == 3:
                if acc == 100:
                    score = 1_000_000
                elif acc == 99:
                    score = 990_000
                elif acc == 97:
                    score = 970_000
                elif acc == 95:
                    score = 950_000
                else:
                    score = acc * 100_000
            else:
                score = 0

            _map = CalcBeatmap(path)
            calc = Calculator(
                acc=acc,
                miss=0,
                mode=self.mode.as_vn,
                score=score,
            ).calculate(_map)

            pp = calc.pp
            if math.isinf(pp) or math.isnan(pp):
                pp = 0.0
            else:
                pp = round(pp)

        return pp
Beispiel #3
0
    async def calc_pp(self, mode_vn: int) -> tuple[float, float]:
        path = Path.cwd() / f"resources/maps/{self.map.id}.osu"
        if not path.exists():
            url = f"https://old.ppy.sh/osu/{self.map.id}"

            async with glob.web.get(url) as resp:
                if not resp or resp.status != 200:
                    return (0.0, 0.0)

                m = await resp.read()
                path.write_bytes(m)

        if mode_vn <= 1:  # std/taiko: use oppai (cmyui wrapper op)
            with OppaiWrapper("oppai-ng/liboppai.so") as ezpp:
                if self.mods:
                    ezpp.set_mods(int(self.mods))

                ezpp.set_mode(int(mode_vn))

                if self.combo:
                    ezpp.set_combo(int(self.combo))

                if self.miss:
                    ezpp.set_nmiss(int(self.miss))

                ezpp.set_accuracy_percent(float(self.acc))

                ezpp.calculate(path)
                pp = ezpp.get_pp()

                if math.isinf(pp) or math.isnan(pp):
                    return (0.0, 0.0)

                return (pp, ezpp.get_sr())
        else:
            _map = CalcBeatmap(path)
            calc = Calculator(
                acc=self.acc,
                miss=self.miss,
                katu=self.katu,
                score=self.score,
                combo=self.combo,
                mode=mode_vn,
                mods=int(self.mods),
            ).calculate(_map)
            return calc.pp, calc.stars
Beispiel #4
0
    async def calc_acc(self, acc: float) -> float:
        path = Path.cwd() / f'resources/maps/{self.id}.osu'
        if not path.exists():
            url = f'https://old.ppy.sh/osu/{self.id}'

            async with glob.web.get(url) as resp:
                if not resp or resp.status != 200:
                    return 0.0

                m = await resp.read()
                path.write_bytes(m)

        if self.mode.as_vn <= 1:
            with OppaiWrapper('oppai-ng/liboppai.so') as ezpp:
                ezpp.set_accuracy_percent(acc)
                ezpp.set_mode(self.mode.as_vn)

                ezpp.calculate(path)
                return round(ezpp.get_pp()) # returning sr soontm
        elif self.mode.as_vn == 3: # mania: use maniera
            c = Maniera(str(path), 0, self.score)
            c.calculate()

            return round(c.pp)
        else: # ctb: use shitty osu-tools

            cmd = [f'./osu-tools/compiled/PerformanceCalculator simulate catch {str(path)}']
            cmd.append(f'-a {acc}')

            cmd.append('-j') # json formatting is godsend thank u peppy

            p = asyncio.subprocess.PIPE
            comp = ' '.join(cmd)
            pr = await asyncio.create_subprocess_shell(comp, stdout=p, stderr=p)
            ot, _ = await pr.communicate()
            o = orjson.loads(ot.decode('utf-8'))
            return round(o['pp'])
Beispiel #5
0
        query += " AND t.status = 2"
        sort = "pp"
        s_list = "2, 3"
    else:
        sort = "time"
        s_list = "2, 3, 4, 5"

    query += f" AND maps.status IN ({s_list}) ORDER BY {sort} DESC LIMIT %s"

    scores = await glob.db.fetch(query, [uid, mode.as_vn, limit])

    for score in scores:
        bmap = await Beatmap.from_md5(score.pop("md5"))

        if mode.as_vn <= 1:
            with OppaiWrapper("oppai-ng/liboppai.so") as ezpp:
                ezpp.set_mode(mode.as_vn)
                ezpp.set_mods(score["mods"])

                ezpp.calculate(Path.cwd() / f"resources/maps/{bmap.id}.osu")

                modded_sr = ezpp.get_sr()
        else:
            modded_sr = bmap.sr  # TODO

        score["map"] = ({
            "md5": bmap.md5,
            "id": bmap.id,
            "set_id": bmap.sid,
            "artist": bmap.artist,
            "title": bmap.title,
Beispiel #6
0
    async def calc_pp(self, mode_vn: int) -> tuple[float, float]:
        path = Path.cwd() / f'resources/maps/{self.map.id}.osu'
        if not path.exists():
            url = f'https://old.ppy.sh/osu/{self.map.id}'

            async with glob.web.get(url) as resp:
                if not resp or resp.status != 200:
                    return 0.0

                m = await resp.read()
                path.write_bytes(m)

        if mode_vn <= 1:  # std/taiko: use oppai (cmyui wrapper op)
            with OppaiWrapper('oppai-ng/liboppai.so') as ezpp:
                if self.mods:
                    ezpp.set_mods(int(self.mods))

                ezpp.set_mode(int(mode_vn))

                if self.combo:
                    ezpp.set_combo(int(self.combo))

                if self.miss:
                    ezpp.set_nmiss(int(self.miss))

                ezpp.set_accuracy_percent(float(self.acc))

                ezpp.calculate(path)
                return (ezpp.get_pp(), ezpp.get_sr())
        elif self.mode.value == 3:  # mania: use maniera
            if self.map.mode != 3:
                return 0.0  # no convert support

            if self.mods != Mods.NOMOD:
                mods = int(self.mods)
            else:
                mods = 0

            c = Maniera(str(path), mods, int(self.score))
            c.calculate()

            return (c.pp, c.sr)
        else:  # ctb: use shitty osu-tools

            cmd = [
                f'./osu-tools/compiled/PerformanceCalculator simulate catch {str(path)}'
            ]

            if self.combo:
                cmd.append(f'-c {self.combo}')  # max combo

            cmd.append(f'-X {self.miss}')  # miss count

            cmd.append(f'-D {self.n50}')  # 50s equivalent for catch?
            # hey note from len4ee here 50s for ctb is droplets xd

            for mod in re.findall('.{1,2}', self.readable_mods):
                if mod != 'NM':  # will confuse osu-tools xd
                    cmd.append(
                        f'-m {mod}'
                    )  # osu tool expects 1 arg per mod so we have to do this gay regex

            cmd.append('-j')  # json formatting is godsend thank u peppy

            p = asyncio.subprocess.PIPE
            comp = ' '.join(cmd)
            pr = await asyncio.create_subprocess_shell(comp,
                                                       stdout=p,
                                                       stderr=p)
            ot, _ = await pr.communicate()
            o = orjson.loads(ot.decode('utf-8'))
            return o['pp'], 0.0
Beispiel #7
0
    def calc_diff(self, osu_file_path: Path) -> tuple[float, float]:
        """Calculate PP and star rating for our score."""
        mode_vn = self.mode.as_vanilla

        if mode_vn == 0:  # std
            with OppaiWrapper("oppai-ng/liboppai.so") as ezpp:
                if self.mods:
                    ezpp.set_mods(int(self.mods))

                if mode_vn:
                    ezpp.set_mode(mode_vn)

                ezpp.set_combo(self.max_combo)
                ezpp.set_nmiss(self.nmiss)  # clobbers acc
                ezpp.set_accuracy_percent(self.acc)

                ezpp.calculate(osu_file_path)

                pp = ezpp.get_pp()

                if math.isnan(pp) or math.isinf(pp):
                    # TODO: report to logserver
                    return (0.0, 0.0)

                return (round(pp, 5), ezpp.get_sr())
        elif mode_vn in (1, 2):  # taiko, catch
            beatmap = PeaceMap(osu_file_path)
            peace = PeaceCalculator()

            if self.mods != Mods.NOMOD:
                peace.set_mods(int(self.mods))

            if mode_vn:
                peace.set_mode(mode_vn)

            peace.set_combo(self.max_combo)
            peace.set_miss(self.nmiss)
            peace.set_acc(self.acc)

            calculated = peace.calculate(beatmap)

            if math.isnan(calculated.pp) or math.isinf(calculated.pp):
                # TODO: report to logserver
                return (0.0, 0.0)

            return (round(calculated.pp, 5), calculated.stars)
        elif mode_vn == 3:  # mania
            beatmap = PeaceMap(osu_file_path)
            peace = PeaceCalculator()

            if self.mods != Mods.NOMOD:
                peace.set_mods(int(self.mods))

            if mode_vn:
                peace.set_mode(mode_vn)

            peace.set_score(self.score)
            calculated = peace.calculate(beatmap)

            if math.isnan(calculated.pp) or math.isinf(calculated.pp):
                # TODO: report to logserver
                return (0.0, 0.0)

            return (round(calculated.pp, 5), calculated.stars)
        else:
            raise ValueError(f"Invalid vanilla mode {mode_vn}")
Beispiel #8
0
        query += ' AND t.status = 2'
        sort = 'pp'
        s_list = '2, 3'
    else:
        sort = 'time'
        s_list = '2, 3, 4, 5'

    query += f' AND maps.status IN ({s_list}) ORDER BY {sort} DESC LIMIT %s'

    scores = await glob.db.fetch(query, [uid, mode.as_vn, limit])

    for score in scores:
        bmap = await Beatmap.from_md5(score.pop('md5'))

        if mode.as_vn <= 1:
            with OppaiWrapper('oppai-ng/liboppai.so') as ezpp:
                ezpp.set_mode(mode.as_vn)
                ezpp.set_mods(score['mods'])

                ezpp.calculate(Path.cwd() / f'resources/maps/{bmap.id}.osu')

                modded_sr = ezpp.get_sr()
        else:
            modded_sr = bmap.sr  # TODO

        score['map'] = {
            'md5': bmap.md5,
            'id': bmap.id,
            'set_id': bmap.sid,
            'artist': bmap.artist,
            'title': bmap.title,