ongeki: add opts to reader

This commit is contained in:
2025-04-08 17:59:19 -04:00
parent 47affd898f
commit 9a14e54328
2 changed files with 85 additions and 25 deletions

View File

@ -58,12 +58,13 @@ class OngekiReader(BaseReader):
data_dirs += self.get_data_directories(self.opt_dir) data_dirs += self.get_data_directories(self.opt_dir)
for dir in data_dirs: for dir in data_dirs:
await self.read_events(f"{dir}/event") this_opt_id = await self.read_opt_info(dir)
await self.read_music(f"{dir}/music") await self.read_events(f"{dir}/event", this_opt_id)
await self.read_card(f"{dir}/card") await self.read_music(f"{dir}/music", this_opt_id)
await self.read_reward(f"{dir}/reward") await self.read_card(f"{dir}/card", this_opt_id)
await self.read_reward(f"{dir}/reward", this_opt_id)
async def read_card(self, base_dir: str) -> None: async def read_card(self, base_dir: str, opt_id: int = None) -> None:
self.logger.info(f"Reading cards from {base_dir}...") self.logger.info(f"Reading cards from {base_dir}...")
for root, dirs, files in os.walk(base_dir): for root, dirs, files in os.walk(base_dir):
@ -75,6 +76,7 @@ class OngekiReader(BaseReader):
card_id = int(troot.find("Name").find("id").text) card_id = int(troot.find("Name").find("id").text)
# skip already existing cards # skip already existing cards
# Hay1tsme 2025/04/08: What is this for, and why does it only check for BM cards?
if ( if (
await self.data.static.get_card( await self.data.static.get_card(
OngekiConstants.VER_ONGEKI_BRIGHT_MEMORY, card_id OngekiConstants.VER_ONGEKI_BRIGHT_MEMORY, card_id
@ -108,6 +110,7 @@ class OngekiReader(BaseReader):
await self.data.static.put_card( await self.data.static.put_card(
self.parse_version(troot), self.parse_version(troot),
card_id, card_id,
opt_id,
name=name, name=name,
charaId=chara_id, charaId=chara_id,
nickName=nick_name, nickName=nick_name,
@ -122,7 +125,7 @@ class OngekiReader(BaseReader):
) )
self.logger.info(f"Added card {card_id}") self.logger.info(f"Added card {card_id}")
async def read_events(self, base_dir: str) -> None: async def read_events(self, base_dir: str, opt_id: int = None) -> None:
self.logger.info(f"Reading events from {base_dir}...") self.logger.info(f"Reading events from {base_dir}...")
for root, dirs, files in os.walk(base_dir): for root, dirs, files in os.walk(base_dir):
@ -140,10 +143,10 @@ class OngekiReader(BaseReader):
if troot.find("EventType").text == "MissionEvent": if troot.find("EventType").text == "MissionEvent":
name = (troot.find("Event").find("MissionName").find("str").text) name = (troot.find("Event").find("MissionName").find("str").text)
await self.data.static.put_event(self.version, id, event_type, name) await self.data.static.put_event(self.version, id, event_type, name, opt_id)
self.logger.info(f"Added event {id}") self.logger.info(f"Added event {id}")
async def read_music(self, base_dir: str) -> None: async def read_music(self, base_dir: str, opt_id: int = None) -> None:
self.logger.info(f"Reading music from {base_dir}...") self.logger.info(f"Reading music from {base_dir}...")
for root, dirs, files in os.walk(base_dir): for root, dirs, files in os.walk(base_dir):
@ -178,11 +181,11 @@ class OngekiReader(BaseReader):
) )
await self.data.static.put_chart( await self.data.static.put_chart(
version, song_id, chart_id, title, artist, genre, level version, song_id, chart_id, title, artist, genre, level, opt_id
) )
self.logger.info(f"Added song {song_id} chart {chart_id}") self.logger.info(f"Added song {song_id} chart {chart_id}")
async def read_reward(self, base_dir: str) -> None: async def read_reward(self, base_dir: str, opt_id: int = None) -> None:
self.logger.info(f"Reading rewards from {base_dir}...") self.logger.info(f"Reading rewards from {base_dir}...")
for root, dirs, files in os.walk(base_dir): for root, dirs, files in os.walk(base_dir):
@ -204,5 +207,53 @@ class OngekiReader(BaseReader):
itemKind = OngekiConstants.REWARD_TYPES[troot.find("ItemType").text].value itemKind = OngekiConstants.REWARD_TYPES[troot.find("ItemType").text].value
itemId = troot.find("RewardItem").find("ItemName").find("id").text itemId = troot.find("RewardItem").find("ItemName").find("id").text
await self.data.static.put_reward(self.version, rewardId, rewardname, itemKind, itemId) await self.data.static.put_reward(self.version, rewardId, rewardname, itemKind, itemId, opt_id)
self.logger.info(f"Added reward {rewardId}") self.logger.info(f"Added reward {rewardId}")
async def read_opt_info(self, directory: str) -> Optional[int]:
datacfg_file = os.path.join(directory, "DataConfig.xml")
if not os.path.exists(datacfg_file):
self.logger.warning(f"{datacfg_file} does not contain DataConfig.xml, opt info will not be read")
return None
with open(datacfg_file, encoding="utf-8") as f:
troot = ET.fromstring(f.read())
if troot.find("DataConfig/version") is None:
self.logger.warning(f"{directory}/DataConfig.xml contains no Version section, opt info will not be read")
return None
ver_maj = troot.find("DataConfig/version/major")
ver_min = troot.find("DataConfig/version/minor")
ver_rel = troot.find("DataConfig/version/release")
cm_maj = troot.find("DataConfig/cardMakerVersion/major")
cm_min = troot.find("DataConfig/cardMakerVersion/minor")
cm_rel = troot.find("DataConfig/cardMakerVersion/release")
if ver_maj is None: # Probably not worth checking that the other sections exist
self.logger.warning(f"{datacfg_file} contains no major item in the Version section, opt info will not be read")
return None
if ver_min is None: # Probably not worth checking that the other sections exist
self.logger.warning(f"{datacfg_file} contains no minor item in the Version section, opt info will not be read")
return None
if ver_rel is None: # Probably not worth checking that the other sections exist
self.logger.warning(f"{datacfg_file} contains no release item in the Version section, opt info will not be read")
return None
opt_folder = os.path.basename(os.path.normpath(directory))
opt_id = await self.data.static.get_opt_by_version_folder(self.version, opt_folder)
if not opt_id:
opt_id = await self.data.static.put_opt(self.version, opt_folder, int(ver_rel.text), int(cm_rel.text) if cm_rel else None)
if not opt_id:
self.logger.error(f"Failed to put opt folder info for {opt_folder}")
return None
else:
opt_id = opt_id['id']
self.logger.info(
f"Opt folder {opt_folder} (Database ID {opt_id}) contains v{ver_maj.text}.{ver_min.text}.{ver_rel.text} (cm v{cm_maj.text if cm_maj else 'None'}.{cm_min.text if cm_min else 'None'}.{cm_rel.text if cm_rel else 'None'})"
)
return opt_id

View File

@ -5,6 +5,7 @@ from sqlalchemy.schema import ForeignKey
from sqlalchemy.sql import func, select from sqlalchemy.sql import func, select
from sqlalchemy.engine import Row from sqlalchemy.engine import Row
from sqlalchemy.dialects.mysql import insert from sqlalchemy.dialects.mysql import insert
from sqlalchemy.sql.functions import coalesce
from core.data.schema import BaseData, metadata from core.data.schema import BaseData, metadata
from core.data.schema.arcade import machine from core.data.schema.arcade import machine
@ -212,10 +213,10 @@ game_point = Table(
) )
class OngekiStaticData(BaseData): class OngekiStaticData(BaseData):
async def put_card(self, version: int, card_id: int, **card_data) -> Optional[int]: async def put_card(self, version: int, card_id: int, opt_id: int = None, **card_data) -> Optional[int]:
sql = insert(cards).values(version=version, cardId=card_id, **card_data) sql = insert(cards).values(version=version, cardId=card_id, opt=coalesce(cards.c.opt, opt_id), **card_data)
conflict = sql.on_duplicate_key_update(**card_data) conflict = sql.on_duplicate_key_update(opt=coalesce(cards.c.opt, opt_id), **card_data)
result = await self.execute(conflict) result = await self.execute(conflict)
if result is None: if result is None:
@ -342,7 +343,7 @@ class OngekiStaticData(BaseData):
return result.fetchall() return result.fetchall()
async def put_event( async def put_event(
self, version: int, event_id: int, event_type: int, event_name: str self, version: int, event_id: int, event_type: int, event_name: str, opt_id: int = None
) -> Optional[int]: ) -> Optional[int]:
sql = insert(events).values( sql = insert(events).values(
version=version, version=version,
@ -350,10 +351,11 @@ class OngekiStaticData(BaseData):
type=event_type, type=event_type,
name=event_name, name=event_name,
endDate=f"2038-01-01 00:00:00", endDate=f"2038-01-01 00:00:00",
opt=coalesce(events.c.opt, opt_id)
) )
conflict = sql.on_duplicate_key_update( conflict = sql.on_duplicate_key_update(
name=event_name, name=event_name, opt=coalesce(events.c.opt, opt_id)
) )
result = await self.execute(conflict) result = await self.execute(conflict)
@ -399,6 +401,7 @@ class OngekiStaticData(BaseData):
artist: str, artist: str,
genre: str, genre: str,
level: float, level: float,
opt_id: int = None
) -> Optional[int]: ) -> Optional[int]:
sql = insert(music).values( sql = insert(music).values(
version=version, version=version,
@ -408,6 +411,7 @@ class OngekiStaticData(BaseData):
artist=artist, artist=artist,
genre=genre, genre=genre,
level=level, level=level,
opt=coalesce(music.c.opt, opt_id)
) )
conflict = sql.on_duplicate_key_update( conflict = sql.on_duplicate_key_update(
@ -415,6 +419,7 @@ class OngekiStaticData(BaseData):
artist=artist, artist=artist,
genre=genre, genre=genre,
level=level, level=level,
opt=coalesce(music.c.opt, opt_id)
) )
result = await self.execute(conflict) result = await self.execute(conflict)
@ -449,17 +454,21 @@ class OngekiStaticData(BaseData):
return None return None
return result.fetchone() return result.fetchone()
async def put_reward(self, version: int, rewardId: int, rewardname: str, itemKind: int, itemId: int) -> Optional[int]: async def put_reward(self, version: int, rewardId: int, rewardname: str, itemKind: int, itemId: int, opt_id: int = None) -> Optional[int]:
sql = insert(rewards).values( sql = insert(rewards).values(
version=version, version=version,
rewardId=rewardId, rewardId=rewardId,
rewardname=rewardname, rewardname=rewardname,
itemKind=itemKind, itemKind=itemKind,
itemId=itemId, itemId=itemId,
) opt=coalesce(rewards.c.opt, opt_id)
)
conflict = sql.on_duplicate_key_update( conflict = sql.on_duplicate_key_update(
rewardname=rewardname, rewardname=rewardname,
) opt=coalesce(rewards.c.opt, opt_id)
)
result = await self.execute(conflict) result = await self.execute(conflict)
if result is None: if result is None:
self.logger.warning(f"Failed to insert reward! reward_id: {rewardId}") self.logger.warning(f"Failed to insert reward! reward_id: {rewardId}")