1
0
mirror of https://github.com/Escartem/AnimeWwise.git synced 2026-06-27 23:50:31 +08:00

optimized mapping format

This commit is contained in:
Escartem
2024-05-19 12:59:08 +02:00
parent 6987f7997f
commit c6df77a04a
3 changed files with 130 additions and 59 deletions

View File

@@ -3,18 +3,18 @@ import sys
import mapper import mapper
import shutil import shutil
import filecmp import filecmp
import argparse
import wavescan import wavescan
import subprocess import subprocess
from halo import Halo from halo import Halo
from progress.bar import PixelBar from progress.bar import PixelBar
import argparse
print("Setting up...") print("Setting up...")
cwd = os.getcwd() cwd = os.getcwd()
path = lambda path: os.path.join(cwd, path) path = lambda path: os.path.join(cwd, path)
call = lambda args: subprocess.call(args, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) call = lambda args: subprocess.call(args, stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT)
mapper.load_mapping(path("mapping/latest.map")) mapper = mapper.Mapper(path("mapping/latest.map"))
spinner = Halo(text="spinner", spinner={'interval': 100, 'frames': ['', '', '', '', '', '']}, placement="right") spinner = Halo(text="spinner", spinner={'interval': 100, 'frames': ['', '', '', '', '', '']}, placement="right")
skips = "000000000" # used for debugging skips = "000000000" # used for debugging
@@ -30,6 +30,7 @@ skips = "000000000" # used for debugging
def main(): def main():
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
# TODO: add skip / select mapping option
parser.add_argument("--format", nargs="?", type=str, default="mp3", help="Output audio format, can be either mp3 or ogg") parser.add_argument("--format", nargs="?", type=str, default="mp3", help="Output audio format, can be either mp3 or ogg")
args = parser.parse_args() args = parser.parse_args()
@@ -290,6 +291,7 @@ def main():
if key_data is not None: if key_data is not None:
if lang is None: if lang is None:
lang = key_data[1] lang = key_data[1]
# TODO: use language for output path
print(f"\n: {lang} detected") print(f"\n: {lang} detected")
dir_path = path(f"{base_path}/{key_data[0]}.{audio_format}") dir_path = path(f"{base_path}/{key_data[0]}.{audio_format}")

131
mapper.py
View File

@@ -1,16 +1,11 @@
# reader for the .map format i've made to improve reading speed and mapping size # reader for the .map format i've made to improve reading speed and mapping size
from filereader import FileReader from filereader import FileReader
import os import os
import json
langs_offsets = {} class Mapper:
keys_data = {} def __init__(self, mapping_file):
reader = None
def load_mapping(mapping_file, langs=False):
global reader
file = open(mapping_file, "rb") file = open(mapping_file, "rb")
reader = FileReader(file, "little") # encoded as little reader = FileReader(file, "little") # encoded as little
@@ -21,47 +16,121 @@ def load_mapping(mapping_file, langs=False):
reader.ReadBytes(2) reader.ReadBytes(2)
if reader.ReadBytes(2) != b"\x56\x31": map_version = reader.ReadBytes(2)
if map_version == b"\x56\x31":
print(f"Warning: you are using an old version of the mapping that is no longer supported, please use a newer one or download an older version of this tool.")
raise Exception("outdated mapping")
elif map_version == b"\x56\x32":
self.reader = reader
self.process_map()
else:
file.close() file.close()
raise Exception("invalid mapping version") raise Exception("invalid mapping version")
def process_map(self):
reader = self.reader
# utils
val = lambda length: int.from_bytes(reader.ReadBytes(length), "little")
raw = lambda length: reader.ReadBytes(length).rstrip(b"\x00").decode("utf-8")
# get map meta
reader.ReadBytes(2) reader.ReadBytes(2)
games = {
b"ys": "Genshin"
# more later
}
infos = {
"game": games[reader.ReadBytes(2)],
"version": list(raw(2)),
"null": reader.ReadBytes(4)
# more later
}
print(f"> Loading mapping for {infos['game']} v{infos['version'][0]}.{infos['version'][1]}, this may take a few seconds...")
# read prefixes
prefixes = {}
n_prefixes = reader.ReadUInt8()
for i in range(n_prefixes):
prefix = raw(4)
marker = reader.ReadBytes(1)
prefixes[marker] = prefix
# read languages # read languages
n_langs = reader.ReadInt8() langs_offsets = {}
n_langs = reader.ReadUInt8()
for i in range(n_langs): for i in range(n_langs):
offset = reader.GetBufferPos() offset = reader.GetBufferPos()
lang_length = reader.ReadInt8() langs_offsets[offset] = raw(11)
langs_offsets[str(offset)] = reader.ReadBytes(lang_length).decode("utf-8")
# read folders
folder_offsets = {}
n_folders = reader.ReadUInt8()
for i in range(n_folders):
offset = reader.GetBufferPos()
length = reader.ReadUInt8()
prefix = reader.ReadBytes(1)
folder = raw(length)
folder = f"{prefixes[prefix]}{folder}"
folder_offsets[offset] = folder
# read files
files_offsets = {}
n_files = val(3)
for i in range(n_files):
offset = reader.GetBufferPos()
path_length = reader.ReadUInt8()
path = []
for i in range(path_length):
path.append(folder_offsets[reader.ReadUInt16()])
name_length = reader.ReadUInt8()
prefix = prefixes[reader.ReadBytes(1)]
name = raw(name_length)
name = f"{prefix}{name}"
path.append(name)
path = "\\".join(path)
files_offsets[offset] = path
# read keys # read keys
n_keys = reader.ReadInt32() keys_data = {}
n_keys = val(3)
for i in range(n_keys): for i in range(n_keys):
key_length = reader.ReadInt8() key = raw(16)
key = reader.ReadBytes(key_length).decode("utf-8")
lang_offset = reader.ReadInt8()
data_offset = reader.ReadInt32()
linked_lang = langs_offsets[str(lang_offset)]
keys_data[str(key)] = [linked_lang, data_offset]
if langs: lang_offset = reader.ReadUInt8()
return list(langs_offsets.values()) file_offset = val(3)
return True
keys_data[key] = [files_offsets[file_offset], langs_offsets[lang_offset]]
self.keys_data = keys_data
# done
print(f"> Finished loading mapping")
print(f": {n_langs} supported languages")
print(f": {n_files} mapped files")
print(f": {n_keys} available keys")
def get_key(key, lang=False): def get_key(self, key, lang=False):
keys_data = self.keys_data
if key not in keys_data.keys(): if key not in keys_data.keys():
return None return None
# search data key_data = keys_data[key]
data = keys_data[key] data = [key_data[0]]
lang = data[0]
reader.SetBufferPos(data[1])
data_length = reader.ReadInt8()
data = [reader.ReadBytes(data_length).decode("utf-8")]
if lang: if lang:
data.append(lang) data.append(key_data[1])
return data return data

Binary file not shown.