mirror of
https://github.com/drmext/MonkeyBusiness.git
synced 2026-03-21 18:04:48 -05:00
Fix
This commit is contained in:
parent
f076453f64
commit
0065087bac
|
|
@ -34,11 +34,11 @@ async def iidx32gamesystem_systeminfo(request: Request):
|
|||
E.grade_course(
|
||||
E.play_style(0, __type="s32"),
|
||||
E.grade_id(15, __type="s32"),
|
||||
E.music_id_0(25090, __type="s32"),
|
||||
E.music_id_0(19022, __type="s32"),
|
||||
E.class_id_0(3, __type="s32"),
|
||||
E.music_id_1(23068, __type="s32"),
|
||||
E.class_id_1(3, __type="s32"),
|
||||
E.music_id_2(19004, __type="s32"),
|
||||
E.music_id_2(27013, __type="s32"),
|
||||
E.class_id_2(3, __type="s32"),
|
||||
E.music_id_3(29045, __type="s32"),
|
||||
E.class_id_3(3, __type="s32"),
|
||||
|
|
@ -47,33 +47,33 @@ async def iidx32gamesystem_systeminfo(request: Request):
|
|||
E.grade_course(
|
||||
E.play_style(0, __type="s32"),
|
||||
E.grade_id(16, __type="s32"),
|
||||
E.music_id_0(23005, __type="s32"),
|
||||
E.music_id_0(27034, __type="s32"),
|
||||
E.class_id_0(3, __type="s32"),
|
||||
E.music_id_1(27078, __type="s32"),
|
||||
E.music_id_1(24023, __type="s32"),
|
||||
E.class_id_1(3, __type="s32"),
|
||||
E.music_id_2(22065, __type="s32"),
|
||||
E.music_id_2(16009, __type="s32"),
|
||||
E.class_id_2(3, __type="s32"),
|
||||
E.music_id_3(27060, __type="s32"),
|
||||
E.music_id_3(25085, __type="s32"),
|
||||
E.class_id_3(3, __type="s32"),
|
||||
E.is_valid(1, __type="bool"),
|
||||
),
|
||||
E.grade_course(
|
||||
E.play_style(0, __type="s32"),
|
||||
E.grade_id(17, __type="s32"),
|
||||
E.music_id_0(29007, __type="s32"),
|
||||
E.music_id_0(26087, __type="s32"),
|
||||
E.class_id_0(3, __type="s32"),
|
||||
E.music_id_1(26108, __type="s32"),
|
||||
E.music_id_1(19002, __type="s32"),
|
||||
E.class_id_1(3, __type="s32"),
|
||||
E.music_id_2(19002, __type="s32"),
|
||||
E.music_id_2(29050, __type="s32"),
|
||||
E.class_id_2(3, __type="s32"),
|
||||
E.music_id_3(18004, __type="s32"),
|
||||
E.music_id_3(30024, __type="s32"),
|
||||
E.class_id_3(3, __type="s32"),
|
||||
E.is_valid(1, __type="bool"),
|
||||
),
|
||||
E.grade_course(
|
||||
E.play_style(0, __type="s32"),
|
||||
E.grade_id(18, __type="s32"),
|
||||
E.music_id_0(25007, __type="s32"),
|
||||
E.music_id_0(30052, __type="s32"),
|
||||
E.class_id_0(3, __type="s32"),
|
||||
E.music_id_1(18032, __type="s32"),
|
||||
E.class_id_1(3, __type="s32"),
|
||||
|
|
@ -86,11 +86,11 @@ async def iidx32gamesystem_systeminfo(request: Request):
|
|||
E.grade_course(
|
||||
E.play_style(1, __type="s32"),
|
||||
E.grade_id(15, __type="s32"),
|
||||
E.music_id_0(15032, __type="s32"),
|
||||
E.music_id_0(12002, __type="s32"),
|
||||
E.class_id_0(3, __type="s32"),
|
||||
E.music_id_1(29033, __type="s32"),
|
||||
E.music_id_1(31063, __type="s32"),
|
||||
E.class_id_1(3, __type="s32"),
|
||||
E.music_id_2(27092, __type="s32"),
|
||||
E.music_id_2(23046, __type="s32"),
|
||||
E.class_id_2(3, __type="s32"),
|
||||
E.music_id_3(30020, __type="s32"),
|
||||
E.class_id_3(3, __type="s32"),
|
||||
|
|
@ -99,11 +99,11 @@ async def iidx32gamesystem_systeminfo(request: Request):
|
|||
E.grade_course(
|
||||
E.play_style(1, __type="s32"),
|
||||
E.grade_id(16, __type="s32"),
|
||||
E.music_id_0(10028, __type="s32"),
|
||||
E.music_id_0(26106, __type="s32"),
|
||||
E.class_id_0(3, __type="s32"),
|
||||
E.music_id_1(26070, __type="s32"),
|
||||
E.music_id_1(14021, __type="s32"),
|
||||
E.class_id_1(3, __type="s32"),
|
||||
E.music_id_2(28091, __type="s32"),
|
||||
E.music_id_2(29052, __type="s32"),
|
||||
E.class_id_2(3, __type="s32"),
|
||||
E.music_id_3(23075, __type="s32"),
|
||||
E.class_id_3(3, __type="s32"),
|
||||
|
|
@ -112,9 +112,9 @@ async def iidx32gamesystem_systeminfo(request: Request):
|
|||
E.grade_course(
|
||||
E.play_style(1, __type="s32"),
|
||||
E.grade_id(17, __type="s32"),
|
||||
E.music_id_0(26012, __type="s32"),
|
||||
E.music_id_0(29042, __type="s32"),
|
||||
E.class_id_0(3, __type="s32"),
|
||||
E.music_id_1(28002, __type="s32"),
|
||||
E.music_id_1(26043, __type="s32"),
|
||||
E.class_id_1(3, __type="s32"),
|
||||
E.music_id_2(17017, __type="s32"),
|
||||
E.class_id_2(3, __type="s32"),
|
||||
|
|
@ -125,9 +125,9 @@ async def iidx32gamesystem_systeminfo(request: Request):
|
|||
E.grade_course(
|
||||
E.play_style(1, __type="s32"),
|
||||
E.grade_id(18, __type="s32"),
|
||||
E.music_id_0(28008, __type="s32"),
|
||||
E.music_id_0(25007, __type="s32"),
|
||||
E.class_id_0(3, __type="s32"),
|
||||
E.music_id_1(15001, __type="s32"),
|
||||
E.music_id_1(29017, __type="s32"),
|
||||
E.class_id_1(3, __type="s32"),
|
||||
E.music_id_2(19002, __type="s32"),
|
||||
E.class_id_2(3, __type="s32"),
|
||||
|
|
@ -135,8 +135,62 @@ async def iidx32gamesystem_systeminfo(request: Request):
|
|||
E.class_id_3(3, __type="s32"),
|
||||
E.is_valid(1, __type="bool"),
|
||||
),
|
||||
E.arena_schedule(
|
||||
E.season(1, __type="u8"),
|
||||
E.phase(4, __type="u8"),
|
||||
E.rule_type(0, __type="u8"),
|
||||
E.start(current_time - 600, __type="u32"),
|
||||
E.end(current_time + 600, __type="u32"),
|
||||
),
|
||||
*[
|
||||
E.arena_reward(
|
||||
E.index(unlock.index(mid), __type="s32"),
|
||||
E.cube_num((unlock.index(mid) + 1) * 50, __type="s32"),
|
||||
E.kind(0, __type="s32"),
|
||||
E.value(mid, __type="str"),
|
||||
)
|
||||
for mid in unlock
|
||||
],
|
||||
*[
|
||||
E.arena_music_difficult(
|
||||
E.play_style(sp_dp, __type="s32"),
|
||||
E.arena_class(arena_class, __type="s32"),
|
||||
E.low_difficult(8, __type="s32"),
|
||||
E.high_difficult(12, __type="s32"),
|
||||
E.is_leggendaria(1, __type="bool"),
|
||||
E.force_music_list_id(0, __type="s32"),
|
||||
)
|
||||
for sp_dp in (0, 1)
|
||||
for arena_class in range(20)
|
||||
],
|
||||
*[
|
||||
E.arena_cpu_define(
|
||||
E.play_style(sp_dp, __type="s32"),
|
||||
E.arena_class(arena_class, __type="s32"),
|
||||
E.grade_id(18, __type="s32"),
|
||||
E.low_music_difficult(8, __type="s32"),
|
||||
E.high_music_difficult(12, __type="s32"),
|
||||
E.is_leggendaria(0, __type="bool"),
|
||||
)
|
||||
for sp_dp in (0, 1)
|
||||
for arena_class in range(20)
|
||||
],
|
||||
*[
|
||||
E.maching_class_range(
|
||||
E.play_style(sp_dp, __type="s32"),
|
||||
E.matching_class(arena_class, __type="s32"),
|
||||
E.low_arena_class(arena_class, __type="s32"),
|
||||
E.high_arena_class(arena_class, __type="s32"),
|
||||
)
|
||||
for sp_dp in (0, 1)
|
||||
for arena_class in range(20)
|
||||
],
|
||||
E.Event1Phase(val=0),
|
||||
E.isNewSongAnother12OpenFlg(val=1),
|
||||
E.isKiwamiOpenFlg(val=1),
|
||||
E.WorldTourismOpenList(val=-1),
|
||||
E.OldBPLBattleOpenPhase(val=3),
|
||||
E.BPLBattleOpenPhase(val=3),
|
||||
)
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ from fastapi import APIRouter, Request, Response
|
|||
|
||||
from core_common import core_process_request, core_prepare_response, E
|
||||
|
||||
router = APIRouter(prefix="/lobby", tags=["lobby"])
|
||||
router = APIRouter(prefix="/lobby2", tags=["lobby2"])
|
||||
router.model_whitelist = ["LDJ"]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -216,6 +216,97 @@ async def iidx32pc_get(request: Request):
|
|||
keyboard_kind=profile.get("lightning_setting_keyboard_kind", 0),
|
||||
brightness=profile.get("lightning_setting_brightness", 0),
|
||||
),
|
||||
E.arena_data(
|
||||
E.achieve_data(
|
||||
play_style=0,
|
||||
arena_class=19,
|
||||
rating_value=90,
|
||||
now_top_class_continuing=19,
|
||||
best_top_class_continuing=19,
|
||||
win_count=0,
|
||||
now_winning_streak_count=0,
|
||||
best_winning_streak_count=0,
|
||||
perfect_win_count=0,
|
||||
counterattack_num=0,
|
||||
mission_clear_num=0,
|
||||
),
|
||||
E.achieve_data(
|
||||
play_style=1,
|
||||
arena_class=19,
|
||||
rating_value=90,
|
||||
now_top_class_continuing=19,
|
||||
best_top_class_continuing=19,
|
||||
win_count=0,
|
||||
now_winning_streak_count=0,
|
||||
best_winning_streak_count=0,
|
||||
perfect_win_count=0,
|
||||
counterattack_num=0,
|
||||
mission_clear_num=0,
|
||||
),
|
||||
E.cube_data(
|
||||
cube=200,
|
||||
season_id=0,
|
||||
),
|
||||
E.ranker_data(
|
||||
play_style=0,
|
||||
pref_id=0,
|
||||
rank_num=(random.choice([random.randint(1, 5), 573])),
|
||||
),
|
||||
E.ranker_data(
|
||||
play_style=1,
|
||||
pref_id=0,
|
||||
rank_num=(random.choice([random.randint(1, 5), 573])),
|
||||
),
|
||||
E.lose_data(
|
||||
play_style=0,
|
||||
lose_value=0,
|
||||
),
|
||||
E.lose_data(
|
||||
play_style=1,
|
||||
lose_value=0,
|
||||
),
|
||||
E.chat_data(
|
||||
E.is_chat_0(1, __type="bool"),
|
||||
E.is_chat_1(1, __type="bool"),
|
||||
E.is_chat_2(1, __type="bool"),
|
||||
E.is_chat_3(1, __type="bool"),
|
||||
chat_type_0="hi",
|
||||
chat_type_1="やあ",
|
||||
chat_type_2="こんにちは",
|
||||
chat_type_3="おす",
|
||||
),
|
||||
E.tendency(
|
||||
play_style=0,
|
||||
rank0=1,
|
||||
rank1=2,
|
||||
rank2=3,
|
||||
rank3=4,
|
||||
rank4=3,
|
||||
rank5=1,
|
||||
),
|
||||
E.default_chat(),
|
||||
# E.player_kind_data(
|
||||
# kind=(random.choice([random.randint(0, 13), 0])),
|
||||
# ),
|
||||
E.setting(
|
||||
E.hide_shopname(0, __type="bool"),
|
||||
stats_type=0,
|
||||
),
|
||||
E.qpro_motion(
|
||||
motion_0=1,
|
||||
motion_1=2,
|
||||
motion_2=3,
|
||||
),
|
||||
play_num=6,
|
||||
play_num_dp=3,
|
||||
play_num_sp=3,
|
||||
prev_best_class_sp=18,
|
||||
prev_best_class_dp=18,
|
||||
),
|
||||
E.arena_pre_data(
|
||||
season_id=1,
|
||||
play_num=6,
|
||||
),
|
||||
# E.weekly_achieve_sp(
|
||||
# weekly_achieve_0=0,
|
||||
# weekly_achieve_1=0,
|
||||
|
|
|
|||
|
|
@ -1,36 +1,28 @@
|
|||
import argparse
|
||||
import ctypes
|
||||
import json
|
||||
import struct
|
||||
|
||||
|
||||
def read_string(infile, length, encoding="cp932"):
|
||||
string_data = infile.read(length)
|
||||
try:
|
||||
return string_data.decode(encoding).strip("\0")
|
||||
except UnicodeDecodeError:
|
||||
# Can't decode truncated string with half multibyte sequence appended (0x83)
|
||||
return string_data[:-1].decode(encoding).strip("\0")
|
||||
return infile.read(length).decode(encoding, errors="ignore").rstrip("\0")
|
||||
|
||||
|
||||
def write_string(outfile, input, length, fill="\0", encoding="cp932"):
|
||||
def write_string(outfile, input, length, encoding="cp932"):
|
||||
string_data = input[:length].encode(encoding)
|
||||
outfile.write(string_data)
|
||||
|
||||
if len(input) < length:
|
||||
outfile.write("".join([fill] * (length - len(string_data))).encode("utf-8"))
|
||||
outfile.write(b"\0" * (length - len(string_data)))
|
||||
|
||||
|
||||
def reader(data_ver, infile, song_count):
|
||||
song_entries = []
|
||||
def reader(version, infile, song_count):
|
||||
all_song_entries = []
|
||||
|
||||
for i in range(song_count):
|
||||
if data_ver >= 32:
|
||||
if version >= 32 and version != 80:
|
||||
title = read_string(infile, 0x100, encoding="utf-16-le")
|
||||
title_ascii = read_string(infile, 0x40)
|
||||
genre = read_string(infile, 0x80, encoding="utf-16-le")
|
||||
artist = read_string(infile, 0x100, encoding="utf-16-le")
|
||||
unk_sect0 = infile.read(0x100)
|
||||
subtitle = read_string(infile, 0x100, encoding="utf-16-le")
|
||||
else:
|
||||
title = read_string(infile, 0x40)
|
||||
title_ascii = read_string(infile, 0x40)
|
||||
|
|
@ -44,25 +36,23 @@ def reader(data_ver, infile, song_count):
|
|||
texture_load,
|
||||
texture_list,
|
||||
) = struct.unpack("<IIIII", infile.read(20))
|
||||
if data_ver >= 32:
|
||||
texture_unk = struct.unpack("<I", infile.read(4))[0]
|
||||
if version >= 32 and version != 80:
|
||||
texture_subtitle = struct.unpack("<I", infile.read(4))[0]
|
||||
font_idx, game_version = struct.unpack("<IH", infile.read(6))
|
||||
if data_ver >= 32:
|
||||
if version >= 32 and version != 80:
|
||||
(
|
||||
other_folder,
|
||||
bemani_folder,
|
||||
unk_folder0,
|
||||
unk_folder1,
|
||||
unk_folder2,
|
||||
beginner_rec_folder,
|
||||
iidx_rec_folder,
|
||||
bemani_rec_folder,
|
||||
splittable_diff,
|
||||
unk_folder3,
|
||||
unk_unused,
|
||||
) = struct.unpack("<HHHHHHH", infile.read(14))
|
||||
else:
|
||||
other_folder, bemani_folder, splittable_diff = struct.unpack(
|
||||
"<HHH", infile.read(6)
|
||||
)
|
||||
other_folder, bemani_folder, splittable_diff = struct.unpack("<HHH", infile.read(6))
|
||||
|
||||
if data_ver >= 27:
|
||||
if version >= 27:
|
||||
(
|
||||
SPB_level,
|
||||
SPN_level,
|
||||
|
|
@ -89,16 +79,16 @@ def reader(data_ver, infile, song_count):
|
|||
SPL_level = 0
|
||||
DPL_level = 0
|
||||
|
||||
if data_ver == 80:
|
||||
if version == 80:
|
||||
unk_sect1 = infile.read(0x146)
|
||||
elif data_ver >= 27:
|
||||
elif version >= 27:
|
||||
unk_sect1 = infile.read(0x286)
|
||||
else:
|
||||
unk_sect1 = infile.read(0xA0)
|
||||
|
||||
song_id, volume = struct.unpack("<II", infile.read(8))
|
||||
|
||||
if data_ver >= 27:
|
||||
if version >= 27:
|
||||
(
|
||||
SPB_ident,
|
||||
SPN_ident,
|
||||
|
|
@ -125,28 +115,21 @@ def reader(data_ver, infile, song_count):
|
|||
SPL_ident = 48
|
||||
DPL_ident = 48
|
||||
|
||||
bga_delay = ctypes.c_short(struct.unpack("<H", infile.read(2))[0]).value
|
||||
bga_delay = struct.unpack("<h", infile.read(2))[0]
|
||||
|
||||
if data_ver <= 26 or data_ver == 80:
|
||||
if version <= 26 or version == 80:
|
||||
unk_sect2 = infile.read(2)
|
||||
|
||||
bga_filename = read_string(infile, 0x20)
|
||||
|
||||
if data_ver == 80:
|
||||
if version == 80:
|
||||
unk_sect3 = infile.read(2)
|
||||
|
||||
afp_flag = struct.unpack("<I", infile.read(4))[0]
|
||||
|
||||
if data_ver >= 22:
|
||||
afp_data = []
|
||||
for x in range(10):
|
||||
afp_data.append(infile.read(0x20).hex())
|
||||
else:
|
||||
afp_data = []
|
||||
for x in range(9):
|
||||
afp_data.append(infile.read(0x20).hex())
|
||||
afp_data = [read_string(infile, 0x20) for _ in range(10 if version >= 22 else 9)]
|
||||
|
||||
if data_ver >= 26:
|
||||
if version >= 26:
|
||||
unk_sect4 = infile.read(4)
|
||||
|
||||
entries = {
|
||||
|
|
@ -192,96 +175,59 @@ def reader(data_ver, infile, song_count):
|
|||
"afp_data": afp_data,
|
||||
}
|
||||
|
||||
if data_ver >= 32:
|
||||
# if data_ver == 80:
|
||||
# unk = {
|
||||
# "unk_sect1": unk_sect1.hex(),
|
||||
# "unk_sect2": unk_sect2.hex(),
|
||||
# "unk_sect3": unk_sect3.hex(),
|
||||
# "unk_sect4": unk_sect4.hex(),
|
||||
# }
|
||||
unk = {
|
||||
"unk_sect0": unk_sect0.hex(),
|
||||
"texture_unk": texture_unk,
|
||||
"unk_folder0": unk_folder0,
|
||||
"unk_folder1": unk_folder1,
|
||||
"unk_folder2": unk_folder2,
|
||||
"unk_folder3": unk_folder3,
|
||||
# "unk_sect1": unk_sect1.hex(),
|
||||
# "unk_sect2": unk_sect2.hex(),
|
||||
# "unk_sect3": unk_sect3.hex(),
|
||||
# "unk_sect4": unk_sect4.hex(),
|
||||
if version >= 32 and version != 80:
|
||||
new_version_entries = {
|
||||
"subtitle": subtitle,
|
||||
"texture_subtitle": texture_subtitle,
|
||||
"beginner_rec_folder": beginner_rec_folder,
|
||||
"iidx_rec_folder": iidx_rec_folder,
|
||||
"bemani_rec_folder": bemani_rec_folder,
|
||||
"unk_unused": unk_unused,
|
||||
}
|
||||
# elif data_ver >= 27:
|
||||
# unk = {
|
||||
# "unk_sect1": unk_sect1.hex(),
|
||||
# "unk_sect4": unk_sect4.hex(),
|
||||
# }
|
||||
# elif data_ver == 26:
|
||||
# unk = {
|
||||
# "unk_sect1": unk_sect1.hex(),
|
||||
# "unk_sect2": unk_sect2.hex(),
|
||||
# "unk_sect4": unk_sect4.hex(),
|
||||
# }
|
||||
# elif data_ver <= 25:
|
||||
# unk = {
|
||||
# "unk_sect1": unk_sect1.hex(),
|
||||
# "unk_sect2": unk_sect2.hex(),
|
||||
# }
|
||||
entries.update(new_version_entries)
|
||||
|
||||
entries.update(unk)
|
||||
all_song_entries.append(entries)
|
||||
|
||||
song_entries.append(entries)
|
||||
|
||||
return song_entries
|
||||
return all_song_entries
|
||||
|
||||
|
||||
def writer(data_ver, outfile, data):
|
||||
DATA_VERSION = data_ver
|
||||
MAX_ENTRIES = data_ver * 1000 + 1000
|
||||
CUR_STYLE_ENTRIES = MAX_ENTRIES - 1000
|
||||
def writer(version, outfile, data):
|
||||
cur_style_entries = version * 1000
|
||||
max_entries = cur_style_entries + 1000
|
||||
entries_struct_format = "<i" if version >= 32 and version != 80 else "<h"
|
||||
|
||||
# Write header
|
||||
outfile.write(b"IIDX")
|
||||
if data_ver >= 32:
|
||||
outfile.write(struct.pack("<IHHI", DATA_VERSION, len(data), 0, MAX_ENTRIES))
|
||||
if version >= 32:
|
||||
outfile.write(struct.pack("<IHHI", version, len(data), 0, max_entries))
|
||||
else:
|
||||
outfile.write(struct.pack("<IHHI", DATA_VERSION, len(data), MAX_ENTRIES, 0))
|
||||
outfile.write(struct.pack("<IHHI", version, len(data), max_entries, 0))
|
||||
|
||||
# Write song index table
|
||||
exist_ids = {}
|
||||
for i in range(len(data)):
|
||||
exist_ids[data[i]["song_id"]] = i
|
||||
|
||||
cur_song = 0
|
||||
entries_struct_format = "<i" if data_ver >= 32 else "<h"
|
||||
|
||||
for i in range(MAX_ENTRIES):
|
||||
current_song = 0
|
||||
for i in range(max_entries):
|
||||
if i in exist_ids:
|
||||
outfile.write(struct.pack(entries_struct_format, cur_song))
|
||||
cur_song += 1
|
||||
elif i >= CUR_STYLE_ENTRIES:
|
||||
outfile.write(struct.pack(entries_struct_format, current_song))
|
||||
current_song += 1
|
||||
elif i >= cur_style_entries:
|
||||
outfile.write(struct.pack(entries_struct_format, 0))
|
||||
else:
|
||||
outfile.write(struct.pack(entries_struct_format, -1))
|
||||
|
||||
# Write song entries
|
||||
for k in sorted(exist_ids.keys()):
|
||||
for k in sorted(exist_ids):
|
||||
song_data = data[exist_ids[k]]
|
||||
|
||||
if data_ver >= 32:
|
||||
if version >= 32 and version != 80:
|
||||
write_string(outfile, song_data["title"], 0x100, encoding="utf-16-le")
|
||||
write_string(outfile, song_data["title_ascii"], 0x40)
|
||||
write_string(outfile, song_data["genre"], 0x80, encoding="utf-16-le")
|
||||
write_string(outfile, song_data["artist"], 0x100, encoding="utf-16-le")
|
||||
outfile.write(
|
||||
bytes.fromhex(
|
||||
song_data.get(
|
||||
"unk_sect0",
|
||||
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
)
|
||||
)
|
||||
)
|
||||
write_string(outfile, song_data.get("subtitle", ""), 0x100, encoding="utf-16-le")
|
||||
else:
|
||||
write_string(outfile, song_data["title"], 0x40)
|
||||
write_string(outfile, song_data["title_ascii"], 0x40)
|
||||
|
|
@ -298,22 +244,20 @@ def writer(data_ver, outfile, data):
|
|||
song_data["texture_list"],
|
||||
)
|
||||
)
|
||||
if data_ver >= 32:
|
||||
outfile.write(struct.pack("<I", song_data.get("texture_unk", 0)))
|
||||
outfile.write(
|
||||
struct.pack("<IH", song_data["font_idx"], song_data["game_version"])
|
||||
)
|
||||
if data_ver >= 32:
|
||||
if version >= 32 and version != 80:
|
||||
outfile.write(struct.pack("<I", song_data.get("texture_subtitle", 0)))
|
||||
outfile.write(struct.pack("<IH", song_data["font_idx"], song_data["game_version"]))
|
||||
if version >= 32 and version != 80:
|
||||
outfile.write(
|
||||
struct.pack(
|
||||
"<HHHHHHH",
|
||||
song_data["other_folder"],
|
||||
song_data["bemani_folder"],
|
||||
song_data.get("unk_folder0", 0),
|
||||
song_data.get("unk_folder1", 0),
|
||||
song_data.get("unk_folder2", 0),
|
||||
song_data.get("beginner_rec_folder", 0),
|
||||
song_data.get("iidx_rec_folder", 0),
|
||||
song_data.get("bemani_rec_folder", 0),
|
||||
song_data["splittable_diff"],
|
||||
song_data.get("unk_folder3", 0),
|
||||
song_data.get("unk_unused", 0),
|
||||
)
|
||||
)
|
||||
else:
|
||||
|
|
@ -326,7 +270,7 @@ def writer(data_ver, outfile, data):
|
|||
)
|
||||
)
|
||||
|
||||
if data_ver >= 27:
|
||||
if version >= 27:
|
||||
outfile.write(
|
||||
struct.pack(
|
||||
"<BBBBBBBBBB",
|
||||
|
|
@ -357,34 +301,18 @@ def writer(data_ver, outfile, data):
|
|||
)
|
||||
)
|
||||
|
||||
if data_ver == 80:
|
||||
outfile.write(
|
||||
bytes.fromhex(
|
||||
"0000000000000100000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000030000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
)
|
||||
)
|
||||
elif data_ver >= 32:
|
||||
outfile.write(
|
||||
bytes.fromhex(
|
||||
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
)
|
||||
)
|
||||
elif data_ver >= 27:
|
||||
outfile.write(
|
||||
bytes.fromhex(
|
||||
"00000000000001000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
)
|
||||
)
|
||||
if version == 80:
|
||||
outfile.write(bytes.fromhex(f"{1:014}{2:08}{3:0248}{4:08}{3:0120}{4:08}{0:0246}"))
|
||||
elif version >= 32:
|
||||
outfile.write(bytes.fromhex(f"{0:01292}"))
|
||||
elif version >= 27:
|
||||
outfile.write(bytes.fromhex(f"{1:014}{2:08}{3:0248}{4:08}{0:01014}"))
|
||||
else:
|
||||
outfile.write(
|
||||
bytes.fromhex(
|
||||
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
||||
)
|
||||
)
|
||||
outfile.write(bytes.fromhex(f"{0:0320}"))
|
||||
|
||||
outfile.write(struct.pack("<II", song_data["song_id"], song_data["volume"]))
|
||||
|
||||
if data_ver >= 27:
|
||||
if version >= 27:
|
||||
outfile.write(
|
||||
struct.pack(
|
||||
"<BBBBBBBBBB",
|
||||
|
|
@ -417,111 +345,24 @@ def writer(data_ver, outfile, data):
|
|||
|
||||
outfile.write(struct.pack("<h", song_data["bga_delay"]))
|
||||
|
||||
if data_ver <= 26 or data_ver == 80:
|
||||
outfile.write(bytes.fromhex("0000"))
|
||||
if version <= 26 or version == 80:
|
||||
outfile.write(bytes.fromhex("00" * 2))
|
||||
|
||||
write_string(outfile, song_data["bga_filename"], 0x20)
|
||||
|
||||
if data_ver == 80:
|
||||
outfile.write(bytes.fromhex("0000"))
|
||||
if version == 80:
|
||||
outfile.write(bytes.fromhex("00" * 2))
|
||||
|
||||
outfile.write(struct.pack("<I", song_data["afp_flag"]))
|
||||
|
||||
if data_ver >= 22:
|
||||
for afp_data in song_data["afp_data"]:
|
||||
outfile.write(bytes.fromhex(afp_data))
|
||||
if len(song_data["afp_data"]) == 9:
|
||||
outfile.write(
|
||||
bytes.fromhex(
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
)
|
||||
)
|
||||
elif len(song_data["afp_data"]) == 10 and data_ver <= 21:
|
||||
for afp_data in song_data["afp_data"][:9]:
|
||||
outfile.write(bytes.fromhex(afp_data))
|
||||
elif len(song_data["afp_data"]) == 9 and data_ver <= 21:
|
||||
for afp_data in song_data["afp_data"]:
|
||||
outfile.write(bytes.fromhex(afp_data))
|
||||
for idx in range(10 if version >= 22 else 9):
|
||||
try:
|
||||
write_string(outfile, song_data["afp_data"][idx], 0x20)
|
||||
except IndexError:
|
||||
write_string(outfile, "", 0x20)
|
||||
|
||||
if data_ver >= 26:
|
||||
outfile.write(bytes.fromhex("00000000"))
|
||||
|
||||
|
||||
def course_reader(infile, total_entries):
|
||||
course_entries = []
|
||||
|
||||
for i in range(total_entries):
|
||||
is_DP, course_num, stages = struct.unpack("<HIH", infile.read(8))
|
||||
|
||||
stage_num = []
|
||||
for i in range(0x20):
|
||||
extract = struct.unpack("<I", infile.read(4))
|
||||
if extract[0] != 0xFFFFFFFF:
|
||||
stage_num.extend(extract)
|
||||
|
||||
song_id = []
|
||||
for i in range(0x20):
|
||||
extract = struct.unpack("<I", infile.read(4))
|
||||
if extract[0] != 0xFFFFFFFF:
|
||||
song_id.extend(extract)
|
||||
|
||||
song_diff = []
|
||||
for i in range(0x20):
|
||||
extract = struct.unpack("<I", infile.read(4))
|
||||
if extract[0] != 0xFFFFFFFF:
|
||||
song_diff.extend(extract)
|
||||
|
||||
course_entries.append(
|
||||
{
|
||||
"is_DP": is_DP,
|
||||
"course_num": course_num,
|
||||
"stages": stages,
|
||||
"stage_num": stage_num,
|
||||
"song_id": song_id,
|
||||
"song_diff": song_diff,
|
||||
}
|
||||
)
|
||||
|
||||
return course_entries
|
||||
|
||||
|
||||
def course_writer(outfile, data, data_ver):
|
||||
TOTAL_ENTRIES = len(data)
|
||||
|
||||
# Write header
|
||||
outfile.write(b"IIDXDANE")
|
||||
outfile.write(struct.pack("<III", data_ver, TOTAL_ENTRIES, 0))
|
||||
|
||||
# Write course entries
|
||||
for song_data in data:
|
||||
outfile.write(
|
||||
struct.pack(
|
||||
"<HIH", song_data["is_DP"], song_data["course_num"], song_data["stages"]
|
||||
)
|
||||
)
|
||||
|
||||
stage = 0
|
||||
|
||||
for i in range(0x20):
|
||||
if i in range(song_data["stages"]):
|
||||
outfile.write(struct.pack("<I", stage))
|
||||
stage += 1
|
||||
else:
|
||||
outfile.write(struct.pack("<I", 0xFFFFFFFF))
|
||||
|
||||
for i in range(0x20):
|
||||
if i in range(song_data["stages"]):
|
||||
outfile.write(struct.pack("<I", song_data["song_id"][i]))
|
||||
stage += 1
|
||||
else:
|
||||
outfile.write(struct.pack("<I", 0xFFFFFFFF))
|
||||
|
||||
for i in range(0x20):
|
||||
if i in range(song_data["stages"]):
|
||||
outfile.write(struct.pack("<I", song_data["song_diff"][i]))
|
||||
stage += 1
|
||||
else:
|
||||
outfile.write(struct.pack("<I", 0xFFFFFFFF))
|
||||
if version >= 26:
|
||||
outfile.write(bytes.fromhex("00" * 4))
|
||||
|
||||
|
||||
handlers = {
|
||||
|
|
@ -545,246 +386,91 @@ handlers = {
|
|||
def extract_file(input, output, in_memory=False):
|
||||
with open(input, "rb") as infile:
|
||||
if infile.read(4) != b"IIDX":
|
||||
print("Invalid", input)
|
||||
exit(-1)
|
||||
raise SystemExit(f"Input file ({input}) is not valid")
|
||||
|
||||
infile.seek(4, 0)
|
||||
data_ver = int.from_bytes(infile.read(4), "little")
|
||||
version = struct.unpack("<I", infile.read(4))[0]
|
||||
entries_struct_format = "<i" if version >= 32 and version != 80 else "<h"
|
||||
|
||||
if data_ver >= 32:
|
||||
available_entries, unk4, total_entries = struct.unpack(
|
||||
"<HHI", infile.read(8)
|
||||
)
|
||||
if version >= 32:
|
||||
available_entries, unk4, total_entries = struct.unpack("<HHI", infile.read(8))
|
||||
else:
|
||||
available_entries, total_entries, unk4 = struct.unpack(
|
||||
"<HIH", infile.read(8)
|
||||
)
|
||||
available_entries, total_entries, unk4 = struct.unpack("<HIH", infile.read(8))
|
||||
|
||||
song_ids = {}
|
||||
existing_song_ids = {}
|
||||
for i in range(total_entries):
|
||||
if data_ver >= 32:
|
||||
song_id = struct.unpack("<I", infile.read(4))[0]
|
||||
else:
|
||||
song_id = struct.unpack("<H", infile.read(2))[0]
|
||||
song_id = struct.unpack(entries_struct_format, infile.read(struct.calcsize(entries_struct_format)))[0]
|
||||
|
||||
if (
|
||||
song_id != 0xFFFF
|
||||
or song_id != 0xFFFFFFFF
|
||||
and (len(song_ids) == 0 or song_id != 0)
|
||||
):
|
||||
song_ids[i] = song_id
|
||||
if song_id != struct.pack(entries_struct_format, -1) and (len(existing_song_ids) == 0 or song_id != 0):
|
||||
existing_song_ids[i] = song_id
|
||||
|
||||
if data_ver in handlers:
|
||||
output_data = reader(data_ver, infile, available_entries)
|
||||
if version in handlers:
|
||||
output_data = reader(version, infile, available_entries)
|
||||
output_data = {
|
||||
"data_ver": data_ver,
|
||||
"data_ver": version,
|
||||
"data": output_data,
|
||||
}
|
||||
|
||||
if in_memory:
|
||||
return output_data
|
||||
|
||||
json.dump(
|
||||
output_data,
|
||||
open(output, "w", encoding="utf8"),
|
||||
indent=4,
|
||||
ensure_ascii=False,
|
||||
)
|
||||
with open(output, "w", encoding="utf-8") as f:
|
||||
json.dump(output_data, f, indent=4, ensure_ascii=False)
|
||||
|
||||
else:
|
||||
print("Couldn't find a handler for this data version")
|
||||
exit(-1)
|
||||
raise SystemExit("Couldn't find a handler for this data version")
|
||||
|
||||
return []
|
||||
|
||||
|
||||
def create_file(input, output, data_version):
|
||||
data = json.load(open(input, "r", encoding="utf8"))
|
||||
data_ver = data.get("data_ver", data_version)
|
||||
def create_file(input, output, placeholder):
|
||||
with open(input, "r", encoding="utf-8") as f:
|
||||
data = json.load(f)
|
||||
version = data.get("data_ver", placeholder)
|
||||
|
||||
if not data_ver:
|
||||
print("Couldn't find data version")
|
||||
exit(-1)
|
||||
if not version:
|
||||
raise SystemExit("Couldn't find data version")
|
||||
|
||||
if data_ver in handlers:
|
||||
writer(data_ver, open(output, "wb"), data["data"])
|
||||
if version in handlers:
|
||||
with open(output, "wb") as f:
|
||||
writer(version, f, data["data"])
|
||||
else:
|
||||
print("Couldn't find a handler for this data version")
|
||||
exit(-1)
|
||||
|
||||
|
||||
def convert_file(input, output, data_version):
|
||||
with open(input, "rb") as infile:
|
||||
if infile.read(4) != b"IIDX":
|
||||
print("Invalid", input)
|
||||
exit(-1)
|
||||
|
||||
data_ver, available_entries, total_entries, unk4 = struct.unpack(
|
||||
"<IHIH", infile.read(12)
|
||||
)
|
||||
|
||||
song_ids = {}
|
||||
for i in range(total_entries):
|
||||
song_id = struct.unpack("<H", infile.read(2))[0]
|
||||
|
||||
if song_id != 0xFFFF and (len(song_ids) == 0 or song_id != 0):
|
||||
song_ids[i] = song_id
|
||||
|
||||
if data_ver in handlers:
|
||||
output_data = reader(data_ver, infile, available_entries)
|
||||
writer(data_ver, open(output, "wb"), output_data)
|
||||
else:
|
||||
print("Couldn't find a handler for this input data version")
|
||||
exit(-1)
|
||||
raise SystemExit("Couldn't find a handler for this data version")
|
||||
|
||||
|
||||
def merge_files(input, basefile, output, diff=False):
|
||||
with open(input, "rb") as infile:
|
||||
if infile.read(4) != b"IIDX":
|
||||
print("Invalid", input)
|
||||
exit(-1)
|
||||
old_data = extract_file(input, None, in_memory=True)
|
||||
new_data = extract_file(basefile, None, in_memory=True)
|
||||
|
||||
infile.seek(4, 0)
|
||||
data_ver = int.from_bytes(infile.read(4), "little")
|
||||
new_song_ids = {song_data["song_id"] for song_data in new_data["data"]}
|
||||
merged_songs = [song_data for song_data in old_data["data"] if song_data["song_id"] not in new_song_ids]
|
||||
|
||||
if data_ver >= 32:
|
||||
available_entries, unk4, total_entries = struct.unpack(
|
||||
"<HHI", infile.read(8)
|
||||
)
|
||||
else:
|
||||
available_entries, total_entries, unk4 = struct.unpack(
|
||||
"<HIH", infile.read(8)
|
||||
)
|
||||
|
||||
song_ids = {}
|
||||
for i in range(total_entries):
|
||||
if data_ver >= 32:
|
||||
song_id = struct.unpack("<I", infile.read(4))[0]
|
||||
else:
|
||||
song_id = struct.unpack("<H", infile.read(2))[0]
|
||||
|
||||
if (
|
||||
song_id != 0xFFFF
|
||||
or song_id != 0xFFFFFFFF
|
||||
and (len(song_ids) == 0 or song_id != 0)
|
||||
):
|
||||
song_ids[i] = song_id
|
||||
|
||||
if data_ver in handlers:
|
||||
old_data = reader(data_ver, infile, available_entries)
|
||||
else:
|
||||
print("Couldn't find a handler for this input data version")
|
||||
exit(-1)
|
||||
|
||||
with open(basefile, "rb") as infile:
|
||||
if infile.read(4) != b"IIDX":
|
||||
print("Invalid", basefile)
|
||||
exit(-1)
|
||||
|
||||
infile.seek(4, 0)
|
||||
data_ver = int.from_bytes(infile.read(4), "little")
|
||||
|
||||
if data_ver >= 32:
|
||||
available_entries, unk4, total_entries = struct.unpack(
|
||||
"<HHI", infile.read(8)
|
||||
)
|
||||
else:
|
||||
available_entries, total_entries, unk4 = struct.unpack(
|
||||
"<HIH", infile.read(8)
|
||||
)
|
||||
|
||||
song_ids = {}
|
||||
for i in range(total_entries):
|
||||
if data_ver >= 32:
|
||||
song_id = struct.unpack("<I", infile.read(4))[0]
|
||||
else:
|
||||
song_id = struct.unpack("<H", infile.read(2))[0]
|
||||
|
||||
if (
|
||||
song_id != 0xFFFF
|
||||
or song_id != 0xFFFFFFFF
|
||||
and (len(song_ids) == 0 or song_id != 0)
|
||||
):
|
||||
song_ids[i] = song_id
|
||||
|
||||
if data_ver in handlers:
|
||||
new_data = reader(data_ver, infile, available_entries)
|
||||
else:
|
||||
print("Couldn't find a handler for this input data version")
|
||||
exit(-1)
|
||||
|
||||
# Create list of
|
||||
exist_ids_new = {}
|
||||
for song_data in new_data:
|
||||
exist_ids_new[song_data["song_id"]] = True
|
||||
|
||||
for song_data in old_data:
|
||||
if song_data["song_id"] not in exist_ids_new:
|
||||
new_data.append(song_data)
|
||||
|
||||
writer(data_ver, open(output, "wb"), new_data)
|
||||
new_data["data"].extend(merged_songs)
|
||||
with open(output, "wb") as f:
|
||||
writer(new_data["data_ver"], f, new_data["data"])
|
||||
|
||||
if diff:
|
||||
new_data.clear()
|
||||
|
||||
for song_data in old_data:
|
||||
if song_data["song_id"] not in exist_ids_new:
|
||||
new_data.append(song_data)
|
||||
|
||||
writer(data_ver, open(output[:-4] + "_diff.bin", "wb"), new_data)
|
||||
with open(output[:-4] + "_diff.bin", "wb") as f:
|
||||
writer(new_data["data_ver"], f, merged_songs)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--input", help="Input file", required=True)
|
||||
parser.add_argument("--output", help="Output file", required=True)
|
||||
parser.add_argument(
|
||||
"--extract", help="Extraction mode", default=False, action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--create", help="Creation mode", default=False, action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--convert", help="Conversion mode", default=False, action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--merge", help="Merge mode", default=False, action="store_true"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--data-version",
|
||||
help="Force a data version (usedful for converts)",
|
||||
default=None,
|
||||
type=int,
|
||||
)
|
||||
parser.add_argument(
|
||||
"--diff", help="Create diff file with merge", default=False, action="store_true"
|
||||
)
|
||||
parser.add_argument("--extract", help="Extraction mode", default=False, action="store_true")
|
||||
parser.add_argument("--create", help="Creation mode", default=False, action="store_true")
|
||||
parser.add_argument("--merge", help="Merge mode", default=False, action="store_true")
|
||||
parser.add_argument("--diff", help="Create _diff.bin output with merge", default=False, action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
if (
|
||||
args.create is False
|
||||
and args.extract is False
|
||||
and args.convert is False
|
||||
and args.merge is False
|
||||
):
|
||||
print("You must specify either --extract or --create or --convert or --merge")
|
||||
exit(-1)
|
||||
|
||||
if args.convert is True:
|
||||
if args.data_version is None:
|
||||
print("You must specify a target --data-version with --convert")
|
||||
exit(-1)
|
||||
elif args.data_version not in handlers:
|
||||
print("Don't know how to handle specified data version")
|
||||
exit(-1)
|
||||
if not any([args.extract, args.create, args.merge]):
|
||||
raise SystemExit("You must specify either --extract or --create or --merge")
|
||||
|
||||
if args.extract:
|
||||
extract_file(args.input, args.output)
|
||||
|
||||
elif args.create:
|
||||
create_file(args.input, args.output, args.data_version)
|
||||
|
||||
elif args.convert:
|
||||
convert_file(args.input, args.output, args.data_version)
|
||||
create_file(args.input, args.output, None)
|
||||
|
||||
elif args.merge:
|
||||
merge_files(args.input, args.output, args.output, args.diff)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user