artemis/titles/chuni/read.py

267 lines
12 KiB
Python
Raw Normal View History

import xml.etree.ElementTree as ET
2024-03-22 16:22:07 +00:00
from os import path, walk
from typing import Optional
from core.config import CoreConfig
2024-03-22 16:22:07 +00:00
from read import BaseReader
from titles.chuni.const import ChuniConstants
2024-03-22 16:22:07 +00:00
from titles.chuni.database import ChuniData
2023-03-09 16:38:58 +00:00
class ChuniReader(BaseReader):
2023-03-09 16:38:58 +00:00
def __init__(
self,
config: CoreConfig,
version: int,
bin_dir: Optional[str],
opt_dir: Optional[str],
extra: Optional[str],
) -> None:
super().__init__(config, version, bin_dir, opt_dir, extra)
self.data = ChuniData(config)
try:
2023-03-09 16:38:58 +00:00
self.logger.info(
f"Start importer for {ChuniConstants.game_ver_to_string(version)}"
)
except IndexError:
self.logger.error(f"Invalid chunithm version {version}")
exit(1)
2023-03-09 16:38:58 +00:00
2024-03-22 16:22:07 +00:00
async def read(self) -> None:
data_dirs = []
if self.bin_dir is not None:
data_dirs += self.get_data_directories(self.bin_dir)
2023-03-09 16:38:58 +00:00
if self.opt_dir is not None:
2023-03-09 16:38:58 +00:00
data_dirs += self.get_data_directories(self.opt_dir)
for dir in data_dirs:
self.logger.info(f"Read from {dir}")
2024-03-22 16:22:07 +00:00
await self.read_events(f"{dir}/event")
await self.read_music(f"{dir}/music")
await self.read_charges(f"{dir}/chargeItem")
await self.read_avatar(f"{dir}/avatarAccessory")
await self.read_login_bonus(f"{dir}/")
2024-03-22 16:22:07 +00:00
async def read_login_bonus(self, root_dir: str) -> None:
for root, dirs, files in walk(f"{root_dir}loginBonusPreset"):
for dir in dirs:
if path.exists(f"{root}/{dir}/LoginBonusPreset.xml"):
with open(f"{root}/{dir}/LoginBonusPreset.xml", "rb") as fp:
bytedata = fp.read()
strdata = bytedata.decode("UTF-8")
xml_root = ET.fromstring(strdata)
for name in xml_root.findall("name"):
id = name.find("id").text
name = name.find("str").text
is_enabled = (
True if xml_root.find("disableFlag").text == "false" else False
)
2024-03-22 16:22:07 +00:00
result = await self.data.static.put_login_bonus_preset(
self.version, id, name, is_enabled
)
if result is not None:
self.logger.info(f"Inserted login bonus preset {id}")
else:
2023-08-08 14:17:56 +00:00
self.logger.warning(f"Failed to insert login bonus preset {id}")
for bonus in xml_root.find("infos").findall("LoginBonusDataInfo"):
for name in bonus.findall("loginBonusName"):
bonus_id = name.find("id").text
bonus_name = name.find("str").text
if path.exists(
f"{root_dir}/loginBonus/loginBonus{bonus_id}/LoginBonus.xml"
):
with open(
f"{root_dir}/loginBonus/loginBonus{bonus_id}/LoginBonus.xml",
"rb",
) as fp:
bytedata = fp.read()
strdata = bytedata.decode("UTF-8")
bonus_root = ET.fromstring(strdata)
for present in bonus_root.findall("present"):
present_id = present.find("id").text
present_name = present.find("str").text
item_num = int(bonus_root.find("itemNum").text)
need_login_day_count = int(
bonus_root.find("needLoginDayCount").text
)
login_bonus_category_type = int(
bonus_root.find("loginBonusCategoryType").text
)
2024-03-22 16:22:07 +00:00
result = await self.data.static.put_login_bonus(
self.version,
id,
bonus_id,
bonus_name,
present_id,
present_name,
item_num,
need_login_day_count,
login_bonus_category_type,
)
if result is not None:
self.logger.info(f"Inserted login bonus {bonus_id}")
else:
2023-08-08 14:17:56 +00:00
self.logger.warning(
f"Failed to insert login bonus {bonus_id}"
)
2023-03-09 16:38:58 +00:00
2024-03-22 16:22:07 +00:00
async def read_events(self, evt_dir: str) -> None:
for root, dirs, files in walk(evt_dir):
for dir in dirs:
if path.exists(f"{root}/{dir}/Event.xml"):
2023-03-09 16:38:58 +00:00
with open(f"{root}/{dir}/Event.xml", "rb") as fp:
bytedata = fp.read()
2023-03-09 16:38:58 +00:00
strdata = bytedata.decode("UTF-8")
xml_root = ET.fromstring(strdata)
2023-03-09 16:38:58 +00:00
for name in xml_root.findall("name"):
id = name.find("id").text
name = name.find("str").text
for substances in xml_root.findall("substances"):
event_type = substances.find("type").text
2024-03-22 16:22:07 +00:00
result = await self.data.static.put_event(
2023-03-09 16:38:58 +00:00
self.version, id, event_type, name
)
if result is not None:
self.logger.info(f"Inserted event {id}")
else:
2023-08-08 14:17:56 +00:00
self.logger.warning(f"Failed to insert event {id}")
2024-03-22 16:22:07 +00:00
async def read_music(self, music_dir: str) -> None:
for root, dirs, files in walk(music_dir):
for dir in dirs:
if path.exists(f"{root}/{dir}/Music.xml"):
2023-03-09 16:38:58 +00:00
with open(f"{root}/{dir}/Music.xml", "rb") as fp:
bytedata = fp.read()
2023-03-09 16:38:58 +00:00
strdata = bytedata.decode("UTF-8")
xml_root = ET.fromstring(strdata)
2023-03-09 16:38:58 +00:00
for name in xml_root.findall("name"):
song_id = name.find("id").text
title = name.find("str").text
for artistName in xml_root.findall("artistName"):
artist = artistName.find("str").text
2023-03-09 16:38:58 +00:00
for genreNames in xml_root.findall("genreNames"):
for list_ in genreNames.findall("list"):
for StringID in list_.findall("StringID"):
genre = StringID.find("str").text
2023-03-09 16:38:58 +00:00
for jaketFile in xml_root.findall("jaketFile"): # nice typo, SEGA
jacket_path = jaketFile.find("path").text
2023-03-09 16:38:58 +00:00
for fumens in xml_root.findall("fumens"):
for MusicFumenData in fumens.findall("MusicFumenData"):
fumen_path = MusicFumenData.find("file").find("path")
if fumen_path is not None:
chart_type = MusicFumenData.find("type")
chart_id = chart_type.find("id").text
chart_diff = chart_type.find("str").text
2024-03-22 16:22:07 +00:00
if chart_diff == "WorldsEnd" and (
chart_id == "4" or chart_id == "5"
): # 4 in SDBT, 5 in SDHD
level = float(xml_root.find("starDifType").text)
2023-03-09 16:38:58 +00:00
we_chara = (
xml_root.find("worldsEndTagName")
.find("str")
.text
)
else:
2023-03-09 16:38:58 +00:00
level = float(
f"{MusicFumenData.find('level').text}.{MusicFumenData.find('levelDecimal').text}"
)
we_chara = None
2023-03-09 16:38:58 +00:00
2024-03-22 16:22:07 +00:00
result = await self.data.static.put_music(
self.version,
song_id,
2023-03-09 16:38:58 +00:00
chart_id,
title,
artist,
level,
genre,
jacket_path,
2023-03-09 16:38:58 +00:00
we_chara,
)
if result is not None:
2023-03-09 16:38:58 +00:00
self.logger.info(
f"Inserted music {song_id} chart {chart_id}"
)
else:
2023-08-08 14:17:56 +00:00
self.logger.warning(
2023-03-09 16:38:58 +00:00
f"Failed to insert music {song_id} chart {chart_id}"
)
2024-03-22 16:22:07 +00:00
async def read_charges(self, charge_dir: str) -> None:
for root, dirs, files in walk(charge_dir):
for dir in dirs:
if path.exists(f"{root}/{dir}/ChargeItem.xml"):
2023-03-09 16:38:58 +00:00
with open(f"{root}/{dir}/ChargeItem.xml", "rb") as fp:
bytedata = fp.read()
2023-03-09 16:38:58 +00:00
strdata = bytedata.decode("UTF-8")
xml_root = ET.fromstring(strdata)
2023-03-09 16:38:58 +00:00
for name in xml_root.findall("name"):
id = name.find("id").text
name = name.find("str").text
expirationDays = xml_root.find("expirationDays").text
consumeType = xml_root.find("consumeType").text
sellingAppeal = bool(xml_root.find("sellingAppeal").text)
2024-03-22 16:22:07 +00:00
result = await self.data.static.put_charge(
2023-03-09 16:38:58 +00:00
self.version,
id,
name,
expirationDays,
consumeType,
sellingAppeal,
)
if result is not None:
self.logger.info(f"Inserted charge {id}")
else:
2023-08-08 14:17:56 +00:00
self.logger.warning(f"Failed to insert charge {id}")
2024-03-22 16:22:07 +00:00
async def read_avatar(self, avatar_dir: str) -> None:
for root, dirs, files in walk(avatar_dir):
for dir in dirs:
if path.exists(f"{root}/{dir}/AvatarAccessory.xml"):
2023-03-09 16:38:58 +00:00
with open(f"{root}/{dir}/AvatarAccessory.xml", "rb") as fp:
bytedata = fp.read()
2023-03-09 16:38:58 +00:00
strdata = bytedata.decode("UTF-8")
xml_root = ET.fromstring(strdata)
2023-03-09 16:38:58 +00:00
for name in xml_root.findall("name"):
id = name.find("id").text
name = name.find("str").text
category = xml_root.find("category").text
for image in xml_root.findall("image"):
iconPath = image.find("path").text
for texture in xml_root.findall("texture"):
texturePath = texture.find("path").text
2024-03-22 16:22:07 +00:00
result = await self.data.static.put_avatar(
2023-03-09 16:38:58 +00:00
self.version, id, name, category, iconPath, texturePath
)
if result is not None:
self.logger.info(f"Inserted avatarAccessory {id}")
else:
2023-08-08 14:17:56 +00:00
self.logger.warning(f"Failed to insert avatarAccessory {id}")