Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions bemani/backend/iidx/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
CHART_TYPE_A14: Final[int] = 5
# Beginner charts only save status
CHART_TYPE_B7: Final[int] = 6
# Some new chart ids added because of HV. No B14 charts
# yet but the should be ready "just in case"
CHART_TYPE_L7: Final[int] = 7
CHART_TYPE_B14: Final[int] = 8
CHART_TYPE_L14: Final[int] = 9

DAN_RANK_7_KYU: Final[int] = DBConstants.IIDX_DAN_RANK_7_KYU
DAN_RANK_6_KYU: Final[int] = DBConstants.IIDX_DAN_RANK_6_KYU
Expand Down
2,503 changes: 2,500 additions & 3 deletions bemani/backend/iidx/bistrover.py

Large diffs are not rendered by default.

2,461 changes: 2,458 additions & 3 deletions bemani/backend/iidx/heroicverse.py

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions bemani/format/iidxchart.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ class IIDXChart:
clear ranks for IIDX.
"""

CHART_POSITIONS: Final[List[int]] = [1, 0, 2, 7, 6, 8]
CHART_POSITIONS: Final[List[int]] = [1, 0, 2, 7, 6, 8, 3, 4, 9, 10]

def __init__(self, data: bytes) -> None:
self.__bpm_min: Optional[int] = None
self.__bpm_max: Optional[int] = None
self.__note_counts = [0, 0, 0, 0, 0, 0]
self.__note_counts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
self.__parse_charts(data)

def __parse_header(self, data: bytes) -> List[Tuple[int, int]]:
Expand All @@ -30,7 +30,7 @@ def __parse_header(self, data: bytes) -> List[Tuple[int, int]]:
def __parse_charts(self, data: bytes) -> None:
header = self.__parse_header(data)

for chart in [0, 1, 2, 3, 4, 5]:
for chart in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]:
offset, length = header[self.CHART_POSITIONS[chart]]
chartdata = data[offset : (offset + length)]
position = 0
Expand Down
83 changes: 61 additions & 22 deletions bemani/format/iidxmusicdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@ def __parse_db(self, data: bytes) -> None:
elif data[4] == 0x1A:
offset = 0xD300
leap = 0x344
elif data[4] == 0x1B:
offset = 0xDAD0
leap = 0x52C
elif data[4] == 0x1C:
offset = 0xE2A0
leap = 0x52C

if sig[0] != b"IIDX":
raise Exception(f"Invalid signature '{sig[0]}' found!")
Expand All @@ -100,36 +106,69 @@ def parse_string(string: bytes) -> str:
# Load songs
while True:
try:
songdata = struct.unpack_from(
"<64s64s64s64s24xB7xBBBBBB162xH",
data,
offset,
)
if data[4] < 0x1B:
songdata = struct.unpack_from(
"<64s64s64s64s24xB7x6B162xH",
data,
offset,
)
else:
# Heroic Verse and above have a completely different structure for song entries
songdata = struct.unpack_from(
"<64s64s64s64s24xB7x10B646xH",
data,
offset,
)
except struct.error:
# Out of input!
break

songoffset = offset
offset = offset + leap
song = IIDXSong(
songdata[11],
parse_string(songdata[0]),
parse_string(songdata[1]),
parse_string(songdata[2]),
parse_string(songdata[3]),
[
songdata[5],
songdata[6],
songdata[7],
songdata[8],
songdata[9],
songdata[10],
],
songdata[4],
)
if data[4] < 0x1B:
song = IIDXSong(
songdata[11],
parse_string(songdata[0]),
parse_string(songdata[1]),
parse_string(songdata[2]),
parse_string(songdata[3]),
[
songdata[5],
songdata[6],
songdata[7],
songdata[8],
songdata[9],
songdata[10],
],
songdata[4],
)
else:
song = IIDXSong(
songdata[15],
parse_string(songdata[0]),
parse_string(songdata[1]),
parse_string(songdata[2]),
parse_string(songdata[3]),
[
songdata[6],
songdata[7],
songdata[8],
songdata[11],
songdata[12],
songdata[13],
songdata[5],
songdata[9],
songdata[10],
songdata[14],
],
songdata[4],
)
if song.artist == "event_data" and song.genre == "event_data":
continue
self.__songs[songdata[11]] = (song, songoffset)
if data[4] < 0x1B:
self.__songs[songdata[11]] = (song, songoffset)
else:
self.__songs[songdata[15]] = (song, songoffset)

@property
def songs(self) -> List[IIDXSong]:
Expand Down
6 changes: 3 additions & 3 deletions bemani/frontend/iidx/endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,12 @@ def viewtopscores(musicid: int) -> Response:
name = None
artist = None
genre = None
difficulties = [0, 0, 0, 0, 0, 0]
notecounts = [0, 0, 0, 0, 0, 0]
difficulties = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
notecounts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

for version in versions:
for omniadd in [0, DBConstants.OMNIMIX_VERSION_BUMP]:
for chart in [0, 1, 2, 3, 4, 5]:
for chart in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]:
details = g.data.local.music.get_song(
GameConstants.IIDX, version + omniadd, musicid, chart
)
Expand Down
113 changes: 111 additions & 2 deletions bemani/frontend/iidx/iidx.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ class IIDXFrontend(FrontendBase):
IIDXBase.CHART_TYPE_N14,
IIDXBase.CHART_TYPE_H14,
IIDXBase.CHART_TYPE_A14,
IIDXBase.CHART_TYPE_B7,
IIDXBase.CHART_TYPE_L7,
IIDXBase.CHART_TYPE_B14,
IIDXBase.CHART_TYPE_L14,
]

valid_rival_types: List[str] = [
Expand Down Expand Up @@ -71,6 +75,111 @@ def get_duplicate_id(self, musicid: int, chart: int) -> Optional[Tuple[int, int]
16102: 21258,
16101: 21262,
14100: 21220,
28100: 27115,
# Tons of leggendarias here...
1017: 1100,
4005: 4100,
4001: 4101,
5014: 5100,
11032: 11100,
11012: 11101,
12002: 12100,
12016: 12101,
13010: 13100,
13038: 13101,
14009: 14100,
14046: 14101,
14022: 14102,
15023: 15101,
15007: 15102,
15061: 15103,
15004: 15104,
15045: 15105,
16050: 16101,
16045: 16102,
16031: 16103,
16015: 16104,
16002: 16105,
17060: 17101,
17028: 17102,
18025: 18100,
18011: 18103,
19063: 19100,
20100: 20103,
20039: 20104,
20068: 20105,
20024: 20106,
20019: 20107,
21012: 21100,
21059: 21101,
21069: 21102,
21073: 21103,
21052: 21104,
21048: 21105,
21050: 21106,
21029: 21107,
21089: 21108,
1005: 21204,
4020: 21205,
5007: 21206,
6013: 21207,
7038: 21208,
8023: 21209,
8024: 21210,
9001: 21211,
9051: 21212,
9033: 21213,
11028: 21215,
12010: 21216,
12052: 21217,
12053: 21218,
12054: 21219,
23054: 23100,
14053: 21222,
15000: 21223,
15001: 21224,
23031: 23101,
15014: 21227,
24041: 24100,
15015: 21228,
15016: 21229,
15020: 21230,
23070: 23102,
15025: 21232,
15026: 21233,
15032: 21234,
15041: 21235,
15054: 21236,
24011: 24101,
16000: 21238,
16001: 21239,
16011: 21241,
16016: 21243,
16017: 21244,
16018: 21245,
16020: 21246,
16021: 21247,
16022: 21248,
16024: 21249,
16025: 21250,
16028: 21251,
16030: 21252,
14012: 21264,
16034: 21254,
16038: 21255,
16040: 21256,
16042: 21257,
16047: 21259,
16049: 21260,
15005: 21261,
15008: 21263,
22008: 22101,
22013: 22102,
22024: 22103,
22027: 22104,
22031: 22105,
22089: 22106,
22006: 22107,
}
# Some charts were changed, and others kept the same on these
if chart in [0, 1, 2]:
Expand Down Expand Up @@ -269,8 +378,8 @@ def format_attempt(self, userid: UserID, attempt: Attempt) -> Dict[str, Any]:
return formatted_attempt

def format_song(self, song: Song) -> Dict[str, Any]:
difficulties = [0, 0, 0, 0, 0, 0]
notecounts = [0, 0, 0, 0, 0, 0]
difficulties = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
notecounts = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
difficulties[song.chart] = song.data.get_int("difficulty", 13)
notecounts[song.chart] = song.data.get_int("notecount", 5730)

Expand Down
Loading