mirror of
https://gitea.tendokyu.moe/Hay1tsme/artemis.git
synced 2026-03-21 18:04:18 -05:00
mai2: pre-dx music reading
This commit is contained in:
parent
d75f62bcb4
commit
2d2b24739d
|
|
@ -53,6 +53,10 @@ class Mai2Reader(BaseReader):
|
|||
self.logger.error(f"tables directory not found in {self.bin_dir}")
|
||||
return
|
||||
|
||||
if not os.path.exists(f"{self.opt_dir}/tables"):
|
||||
self.logger.warning(f"tables directory not found in {self.opt_dir}, not using")
|
||||
self.opt_dir = None
|
||||
|
||||
if self.version >= Mai2Constants.VER_MAIMAI_MILK:
|
||||
if self.extra is None:
|
||||
self.logger.error("Milk - Finale requre an AES key via a hex string send as the --extra flag")
|
||||
|
|
@ -63,41 +67,54 @@ class Mai2Reader(BaseReader):
|
|||
else:
|
||||
key = None
|
||||
|
||||
evt_table = self.load_table_raw(f"{self.bin_dir}/tables", "mmEvent.bin", key)
|
||||
txt_table = self.load_table_raw(f"{self.bin_dir}/tables", "mmtextout_jp.bin", key)
|
||||
score_table = self.load_table_raw(f"{self.bin_dir}/tables", "mmScore.bin", key)
|
||||
evt_table = self.load_table_raw(f"{self.bin_dir}/tables", "mmEvent.bin", key, f"{self.opt_dir}/tables" if self.opt_dir else None)
|
||||
jp_table = self.load_table_raw(f"{self.bin_dir}/tables", "mmtextout_jp.bin", key, f"{self.opt_dir}/tables" if self.opt_dir else None)
|
||||
#en_table = self.load_table_raw(f"{self.bin_dir}/tables", "mmtextout_ex.bin", key, f"{self.opt_dir}/tables" if self.opt_dir else None)
|
||||
en_table = []
|
||||
score_table = self.load_table_raw(f"{self.bin_dir}/tables", "mmScore.bin", key, f"{self.opt_dir}/tables" if self.opt_dir else None)
|
||||
music_table = self.load_table_raw(f"{self.bin_dir}/tables", "mmMusic.bin", key, f"{self.opt_dir}/tables" if self.opt_dir else None)
|
||||
genre_table = self.load_table_raw(f"{self.bin_dir}/tables", "mmGenre.bin", key, f"{self.opt_dir}/tables" if self.opt_dir else None)
|
||||
|
||||
txt_table = {} # Build our translation table
|
||||
for entry in jp_table:
|
||||
vals = list(entry.values())
|
||||
txt_table[vals[0]] = ", ".join(vals[1:])
|
||||
for entry in en_table:
|
||||
vals = list(entry.values())
|
||||
txt_table[vals[0]] = ", ".join(vals[1:])
|
||||
|
||||
genre_lookup = {}
|
||||
for entry in genre_table:
|
||||
genre_lookup[entry['ID']] = txt_table[entry['名前テキスト']]
|
||||
|
||||
self.logger.info(f"Insert {len(evt_table)} events")
|
||||
await self.read_old_events(evt_table)
|
||||
await self.read_old_music(score_table, txt_table)
|
||||
|
||||
if self.opt_dir is not None:
|
||||
evt_table = self.load_table_raw(f"{self.opt_dir}/tables", "mmEvent.bin", key)
|
||||
txt_table = self.load_table_raw(f"{self.opt_dir}/tables", "mmtextout_jp.bin", key)
|
||||
score_table = self.load_table_raw(f"{self.opt_dir}/tables", "mmScore.bin", key)
|
||||
|
||||
await self.read_old_events(evt_table)
|
||||
await self.read_old_music(score_table, txt_table)
|
||||
|
||||
return
|
||||
self.logger.info(f"Insert {len(score_table)} charts")
|
||||
await self.read_old_music(music_table, score_table, txt_table, genre_lookup)
|
||||
|
||||
def load_table_raw(self, dir: str, file: str, key: Optional[bytes]) -> Optional[List[Dict[str, str]]]:
|
||||
if not os.path.exists(f"{dir}/{file}"):
|
||||
def load_table_raw(self, dir: str, file: str, key: Optional[bytes], opt_dir: Optional[str] = None) -> Optional[List[Dict[str, str]]]:
|
||||
if opt_dir is not None and os.path.exists(f"{opt_dir}/{file}"):
|
||||
fpath = f"{opt_dir}/{file}"
|
||||
else:
|
||||
fpath = f"{dir}/{file}"
|
||||
|
||||
if not os.path.exists(fpath):
|
||||
self.logger.warning(f"file {file} does not exist in directory {dir}, skipping")
|
||||
return
|
||||
|
||||
self.logger.info(f"Load table {file} from {dir}")
|
||||
self.logger.info(f"Load table {fpath}")
|
||||
if key is not None:
|
||||
cipher = AES.new(key, AES.MODE_CBC)
|
||||
with open(f"{dir}/{file}", "rb") as f:
|
||||
with open(fpath, "rb") as f:
|
||||
f_encrypted = f.read()
|
||||
f_data = cipher.decrypt(f_encrypted)[0x10:]
|
||||
|
||||
else:
|
||||
with open(f"{dir}/{file}", "rb") as f:
|
||||
with open(fpath, "rb") as f:
|
||||
f_data = f.read()[0x10:]
|
||||
|
||||
if f_data is None or not f_data:
|
||||
self.logger.warning(f"file {dir} could not be read, skipping")
|
||||
self.logger.warning(f"file {fpath} could not be read, skipping")
|
||||
return
|
||||
|
||||
f_data_deflate = zlib.decompress(f_data, wbits = zlib.MAX_WBITS | 16)[0x12:] # lop off the junk at the beginning
|
||||
|
|
@ -325,20 +342,37 @@ class Mai2Reader(BaseReader):
|
|||
|
||||
for event in events:
|
||||
evt_id = int(event.get('イベントID', '0'))
|
||||
evt_expire_time = float(event.get('オフ時強制時期', '0.0'))
|
||||
is_exp = bool(int(event.get('海外許可', '0')))
|
||||
is_aou = bool(int(event.get('AOU許可', '0')))
|
||||
name = event.get('comment', f'evt_{evt_id}')
|
||||
|
||||
await self.data.static.put_game_event(self.version, 0, evt_id, name)
|
||||
|
||||
if not (is_exp or is_aou):
|
||||
await self.data.static.toggle_game_event(self.version, evt_id, False)
|
||||
|
||||
async def read_old_music(self, scores: Optional[List[Dict[str, str]]], text: Optional[List[Dict[str, str]]]) -> None:
|
||||
if scores is None or text is None:
|
||||
async def read_old_music(self, music: Optional[List[Dict[str, str]]], scores: Optional[List[Dict[str, str]]], text: Optional[Dict[str, str]], genre: Dict[str, str]) -> None:
|
||||
if music is None or scores is None or text is None:
|
||||
return
|
||||
# TODO
|
||||
|
||||
last_music = music[0]
|
||||
for score in scores:
|
||||
mid = score['ID'][:-2]
|
||||
cid = score['ID'][-2:]
|
||||
|
||||
if last_music['ID'] != mid:
|
||||
for x in range(len(music)):
|
||||
if music[x]['ID'] == mid:
|
||||
last_music = music[x]
|
||||
break
|
||||
|
||||
await self.data.static.put_game_music(
|
||||
self.version,
|
||||
int(mid),
|
||||
int(cid),
|
||||
text[last_music['タイトル']],
|
||||
text[last_music['アーティスト']],
|
||||
genre[last_music['GenreID']],
|
||||
last_music['BPM'],
|
||||
last_music['Ver'],
|
||||
float(score['LV']),
|
||||
text[f"RST_SCORECREATOR_{int(score['譜面作者ID']):04d}"]
|
||||
)
|
||||
|
||||
async def read_opt_info(self, directory: str) -> Optional[int]:
|
||||
datacfg_file = os.path.join(directory, "DataConfig.xml")
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user