191 lines
7.9 KiB
Python
Executable File
191 lines
7.9 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
import datetime
|
|
from typing import IO
|
|
from utils.readfunctions import *
|
|
from enum import Enum, auto
|
|
import json
|
|
|
|
def parse_osu_db_beatmaps(file: IO[any],beatmap_count: int,version:int) -> list[dict]:
|
|
""" This function parse the beatmaps from the osu!.db file and returns the
|
|
data as a list of dictionaries, each dictionary represent a beatmap
|
|
|
|
Args:
|
|
file (IO[any]): the osu!.db file to read from
|
|
beatmap_count (_type_): the number of beatmaps to read
|
|
version (_type_): the version of the osu!.db file
|
|
|
|
Returns:
|
|
list[dict]: a list of dictionaries, each dictionary represent a beatmap
|
|
"""
|
|
beatmaps = []
|
|
for number in range(beatmap_count):
|
|
number_of_dash = int(((number+1)/beatmap_count)*50)
|
|
string = f"[{'#'*number_of_dash}{' '*(50 - number_of_dash)}] {number+1}/{beatmap_count}"
|
|
print(string,end="\r")
|
|
beatmap = {}
|
|
if version < 20191106:
|
|
beatmap["Data byte size"] = read_int(file)
|
|
beatmap["Artist name"] = read_string(file)
|
|
beatmap["Artist name (unicode)"] = read_string(file)
|
|
beatmap["Song name"] = read_string(file)
|
|
beatmap["Song name (unicode)"] = read_string(file)
|
|
beatmap["Creator name"] = read_string(file)
|
|
beatmap["Difficulty"] = read_string(file)
|
|
beatmap["Audio file name"] = read_string(file)
|
|
beatmap["MD5 hash"] = read_string(file)
|
|
beatmap[".osu filename"] = read_string(file)
|
|
ranked_status = read_byte(file)
|
|
ranked_status_str = ""
|
|
match ranked_status:
|
|
case 0:
|
|
ranked_status_str = "unknown"
|
|
case 1:
|
|
ranked_status_str = "unsubmitted"
|
|
case 2:
|
|
ranked_status_str = "pending/wip/graveyard"
|
|
case 3:
|
|
ranked_status_str = "unused"
|
|
case 4:
|
|
ranked_status_str = "ranked"
|
|
case 5:
|
|
ranked_status_str = "approved"
|
|
case 6:
|
|
ranked_status_str = "qualified"
|
|
case 7:
|
|
ranked_status_str = "loved"
|
|
case _:
|
|
ranked_status_str = "unknown"
|
|
|
|
beatmap["Ranked status"] = ranked_status
|
|
beatmap["Ranked status text"] = ranked_status_str
|
|
beatmap["Hitcircle number"] = read_short(file)
|
|
beatmap["Slider number"] = read_short(file)
|
|
beatmap["Spinner number"] = read_short(file)
|
|
beatmap["Last modification time"] = read_long(file)
|
|
beatmap["Approach rate"] = read_byte(file) if version <20140609 else read_single(file)
|
|
beatmap["Circle size"] = read_byte(file) if version <20140609 else read_single(file)
|
|
beatmap["HP drain"] = read_byte(file) if version <20140609 else read_single(file)
|
|
beatmap["Overall difficulty"] = read_byte(file) if version <20140609 else read_single(file)
|
|
beatmap["Slider velocity"] = read_double(file)
|
|
if version >= 20140609:
|
|
beatmap["Osu!Standard stars ratings"] = []
|
|
pair_number = read_int(file)
|
|
for i in range(pair_number):
|
|
beatmap["Osu!Standard stars ratings"].append(read_int_double_pair(file))
|
|
if version >= 20140609:
|
|
beatmap["Taiko stars ratings"] = []
|
|
pair_number = read_int(file)
|
|
for i in range(pair_number):
|
|
beatmap["Taiko stars ratings"].append(read_int_double_pair(file))
|
|
if version >= 20140609:
|
|
beatmap["CTB stars ratings"] = []
|
|
pair_number = read_int(file)
|
|
for i in range(pair_number):
|
|
beatmap["CTB stars ratings"].append(read_int_double_pair(file))
|
|
if version >= 20140609:
|
|
beatmap["Mania stars ratings"] = []
|
|
pair_number = read_int(file)
|
|
for i in range(pair_number):
|
|
beatmap["Mania stars ratings"].append(read_int_double_pair(file))
|
|
beatmap["Drain time"] = read_int(file)
|
|
beatmap["Total time"] = read_int(file)
|
|
beatmap["Audio preview time"] = read_int(file)
|
|
beatmap["Timing points"] = []
|
|
timing_point_number = read_int(file)
|
|
for i in range(timing_point_number):
|
|
beatmap["Timing points"].append(read_timing_point(file))
|
|
beatmap["Difficulty ID"] = read_int(file)
|
|
beatmap["Beatmap ID"] = read_int(file)
|
|
beatmap["Thread ID"] = read_int(file)
|
|
beatmap["Standard grade"] = read_byte(file)
|
|
beatmap["Taiko grade"] = read_byte(file)
|
|
beatmap["CTB grade"] = read_byte(file)
|
|
beatmap["Mania grade"] = read_byte(file)
|
|
beatmap["Local offset"] = read_short(file)
|
|
beatmap["Stack leniency"] = read_single(file)
|
|
game_mode = read_byte(file)
|
|
beatmap["Gameplay mode"] = game_mode
|
|
game_mode_str = ""
|
|
match game_mode:
|
|
case 0:
|
|
game_mode_str = "Osu!Standard"
|
|
case 1:
|
|
game_mode_str = "Taiko"
|
|
case 2:
|
|
game_mode_str = "CTB"
|
|
case 3:
|
|
game_mode_str = "Mania"
|
|
case _:
|
|
game_mode_str = "unknown"
|
|
beatmap["Gameplay mode text"] = game_mode_str
|
|
beatmap["Song source"] = read_string(file)
|
|
beatmap["Song tags"] = read_string(file)
|
|
beatmap["Online offset"] = read_short(file)
|
|
beatmap["Font used"] = read_string(file)
|
|
beatmap["Is unplayed"] = read_bool(file)
|
|
beatmap["Last play time"] = read_long(file)
|
|
beatmap["Is osz2"] = read_bool(file)
|
|
beatmap["Folder name"] = read_string(file)
|
|
beatmap["Last check time"] = read_long(file)
|
|
beatmap["Ignore beatmap sounds"] = read_bool(file)
|
|
beatmap["Ignore beatmap skin"] = read_bool(file)
|
|
beatmap["Disable storyboard"] = read_bool(file)
|
|
beatmap["Disable video"] = read_bool(file)
|
|
beatmap["Visual override"] = read_bool(file)
|
|
if version < 20140609:
|
|
beatmap["Unknown"] = read_byte(file)
|
|
beatmap["Last modification time"] = read_int(file)
|
|
beatmap["Mania scroll speed"] = read_byte(file)
|
|
beatmaps.append(beatmap)
|
|
print(80*" ",end="\r")
|
|
return beatmaps
|
|
|
|
def parse_osu_db(filepath:str)->dict:
|
|
""" This function parse the osu!.db file and returns the data as a dictionary
|
|
|
|
Args:
|
|
filepath (str): the path to the osu!.db file
|
|
|
|
Returns:
|
|
dict: a dictionary containing the data from the osu!.db file
|
|
"""
|
|
data = {}
|
|
with open(filepath,'rb') as db_file:
|
|
version = read_int(db_file)
|
|
data["version"] = version
|
|
data['folder count'] = read_int(db_file)
|
|
data['account blocked'] = read_bool(db_file)
|
|
data['unblock date'] = read_date_time(db_file).strftime("%d/%m/%Y, %H:%M:%S")
|
|
data['username'] = read_string(db_file)
|
|
beatmap_count = read_int(db_file)
|
|
data['beatmap count'] = beatmap_count
|
|
data['beatmaps'] = parse_osu_db_beatmaps(db_file,beatmap_count,version)
|
|
data['User permissions'] = read_int(db_file)
|
|
return data
|
|
|
|
def parse_collection_db(filepath:str)->dict:
|
|
""" This function parse the collection.db file and returns the data as a dictionary
|
|
|
|
Args:
|
|
filepath (str): the path to the collection.db file
|
|
|
|
Returns:
|
|
dict: a dictionary containing the data from the collection.db file
|
|
"""
|
|
data = {}
|
|
with open(filepath,'rb') as db_file:
|
|
version = read_int(db_file)
|
|
data["version"] = version
|
|
collection_count = read_int(db_file)
|
|
data["collection count"] = collection_count
|
|
data["collections"] = []
|
|
for i in range(collection_count):
|
|
collection = {}
|
|
collection["Name"] = read_string(db_file)
|
|
beatmap_count = read_int(db_file)
|
|
collection["Beatmap count"] = beatmap_count
|
|
collection["Beatmaps"] = []
|
|
for j in range(beatmap_count):
|
|
collection["Beatmaps"].append(read_string(db_file))
|
|
data["collections"].append(collection)
|
|
return data |