1
0
mirror of synced 2024-11-27 23:50:47 +01:00

Additional flag documentation as well as frontend config for UsaNeko. Also fixed NAVI-kun event to work. Also fixed Eclale area bounds that was mistakenly adjusted.

This commit is contained in:
Jennifer Taylor 2021-09-09 01:06:14 +00:00
parent 2582f0e523
commit a1c786a525
5 changed files with 249 additions and 103 deletions

View File

@ -119,11 +119,18 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
return Node.void('pcb24')
@abstractmethod
def get_phases(self) -> Dict[int, int]:
...
def get_common_config(self) -> Tuple[Dict[int, int], bool]:
"""
Return a tuple of configuration options for sending the common node back
to the client. The first parameter is a dictionary whose keys are event
IDs and values are the event phase number. The second parameter is a bool
representing whether or not to send areas.
"""
def __construct_common_info(self, root: Node) -> None:
for phaseid, phase_value in self.get_phases().items():
phases, send_areas = self.get_common_config()
for phaseid, phase_value in phases.items():
phase = Node.void('phase')
root.add_child(phase)
phase.add_child(Node.s16('event_id', phaseid))
@ -199,13 +206,14 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
subnode.add_child(Node.u8('clear_type', ach.data.get_int('clear_type')))
subnode.add_child(Node.u8('clear_rank', ach.data.get_int('clear_rank')))
for area_id in range(0, 16):
area = Node.void('area')
root.add_child(area)
area.add_child(Node.s16('area_id', area_id))
area.add_child(Node.u64('end_date', 0))
area.add_child(Node.s16('medal_id', area_id))
area.add_child(Node.bool('is_limit', False))
if send_areas:
for area_id in range(1, 16):
area = Node.void('area')
root.add_child(area)
area.add_child(Node.s16('area_id', area_id))
area.add_child(Node.u64('end_date', 0))
area.add_child(Node.s16('medal_id', area_id))
area.add_child(Node.bool('is_limit', False))
for choco_id in range(0, 5):
choco = Node.void('choco')
@ -958,6 +966,18 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
if 'navi_points' in profile:
navi_data.add_child(Node.s32_array('raisePoint', profile.get_int_array('navi_points', 5)))
game_config = self.get_game_config()
if game_config.get_bool('force_unlock_songs'):
songs = self.data.local.music.get_all_songs(self.game, self.version)
for song in songs:
item = Node.void('item')
root.add_child(item)
item.add_child(Node.u8('type', 0))
item.add_child(Node.u16('id', song.id))
item.add_child(Node.u16('param', 15))
item.add_child(Node.bool('is_new', False))
item.add_child(Node.u64('get_time', 0))
# Set up achievements
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
for achievement in achievements:
@ -967,8 +987,6 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
is_new = achievement.data.get_bool('is_new')
get_time = achievement.data.get_int('get_time')
item = Node.void('item')
root.add_child(item)
# Item type can be 0-6 inclusive and is the type of the unlock/item.
# Item 0 is music unlocks. In this case, the id is the song ID according
# to the game. Unclear what the param is supposed to be, but i've seen
@ -982,6 +1000,12 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
# 4: 1
# 5: 1
# 6: 60
if game_config.get_bool('force_unlock_songs') and itemtype == 0:
# We already sent song unlocks in the force unlock section above.
continue
item = Node.void('item')
root.add_child(item)
item.add_child(Node.u8('type', itemtype))
item.add_child(Node.u16('id', achievement.id))
item.add_child(Node.u16('param', param))
@ -1223,6 +1247,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
)
# Extract achievements
game_config = self.get_game_config()
for node in request.children:
if node.name == 'item':
itemid = node.child_value('id')
@ -1231,6 +1256,10 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
is_new = node.child_value('is_new')
get_time = node.child_value('get_time')
if game_config.get_bool('force_unlock_songs') and itemtype == 0:
# If we enabled force song unlocks, don't save songs to the profile.
continue
self.data.local.user.put_achievement(
self.game,
self.version,

View File

@ -164,7 +164,7 @@ class PopnMusicEclale(PopnMusicBase):
phase.add_child(Node.s16('phase', phases[phaseid]))
if game_config.get_bool('starmaker_enable'):
for areaid in range(51):
for areaid in range(1, 51):
area = Node.void('area')
root.add_child(area)
area.add_child(Node.s16('area_id', areaid))

View File

@ -1,5 +1,5 @@
# vim: set fileencoding=utf-8
from typing import Dict
from typing import Dict, Tuple
from bemani.backend.popn.base import PopnMusicBase
from bemani.backend.popn.common import PopnMusicModernBase
@ -18,58 +18,61 @@ class PopnMusicPeace(PopnMusicModernBase):
def previous_version(self) -> PopnMusicBase:
return PopnMusicUsaNeko(self.data, self.config, self.model)
def get_phases(self) -> Dict[int, int]:
def get_common_config(self) -> Tuple[Dict[int, int], bool]:
# Event phases
# TODO: Hook event mode settings up to the front end.
return {
# Default song phase availability (0-23)
0: 23,
# Unknown event (0-2)
1: 2,
# Unknown event (0-2)
2: 2,
# Unknown event (0-4)
3: 4,
# Unknown event (0-1)
4: 1,
# Enable Net Taisen, including win/loss display on song select (0-1)
5: 1,
# Enable NAVI-kun shunkyoku toujou, allows song 1608 to be unlocked (0-1)
6: 1,
# Unknown event (0-1)
7: 1,
# Unknown event (0-2)
8: 2,
# Daily Mission (0-2)
9: 2,
# NAVI-kun Song phase availability (0-30)
10: 30,
# Unknown event (0-1)
11: 1,
# Unknown event (0-2)
12: 2,
# Enable Pop'n Peace preview song (0-1)
13: 1,
# Unknown event (0-39)
14: 39,
# Unknown event (0-2)
15: 2,
# Unknown event (0-3)
16: 3,
# Unknown event (0-8)
17: 8,
# Unknown event (0-1)
28: 1,
# Unknown event (0-1)
19: 1,
# Unknown event (0-13)
20: 13,
# Pop'n event archive song phase availability (0-20)
21: 20,
# Unknown event (0-2)
22: 2,
# Unknown event (0-1)
23: 1,
# Unknown event (0-1)
24: 1,
}
return (
{
# Default song phase availability (0-23)
0: 23,
# Unknown event (0-2)
1: 2,
# Unknown event (0-2)
2: 2,
# Unknown event (0-4)
3: 4,
# Unknown event (0-1)
4: 1,
# Enable Net Taisen, including win/loss display on song select (0-1)
5: 1,
# Enable NAVI-kun shunkyoku toujou, allows song 1608 to be unlocked (0-1)
6: 1,
# Unknown event (0-1)
7: 1,
# Unknown event (0-2)
8: 2,
# Daily Mission (0-2)
9: 2,
# NAVI-kun Song phase availability (0-30)
10: 30,
# Unknown event (0-1)
11: 1,
# Unknown event (0-2)
12: 2,
# Enable Pop'n Peace preview song (0-1)
13: 1,
# Unknown event (0-39)
14: 39,
# Unknown event (0-2)
15: 2,
# Unknown event (0-3)
16: 3,
# Unknown event (0-8)
17: 8,
# Unknown event (0-1)
28: 1,
# Unknown event (0-1)
19: 1,
# Unknown event (0-13)
20: 13,
# Pop'n event archive song phase availability (0-20)
21: 20,
# Unknown event (0-2)
22: 2,
# Unknown event (0-1)
23: 1,
# Unknown event (0-1)
24: 1,
},
False,
)

View File

@ -1,5 +1,5 @@
# vim: set fileencoding=utf-8
from typing import Dict
from typing import Any, Dict, Tuple
from bemani.backend.popn.base import PopnMusicBase
from bemani.backend.popn.common import PopnMusicModernBase
@ -18,36 +18,147 @@ class PopnMusicUsaNeko(PopnMusicModernBase):
def previous_version(self) -> PopnMusicBase:
return PopnMusicEclale(self.data, self.config, self.model)
def get_phases(self) -> Dict[int, int]:
# Event phases
# TODO: Hook event mode settings up to the front end.
@classmethod
def get_settings(cls) -> Dict[str, Any]:
"""
Return all of our front-end modifiably settings.
"""
return {
# Default song phase availability (0-11)
0: 11,
# Unknown event (0-2)
1: 2,
# Unknown event (0-2)
2: 2,
# Unknown event (0-4)
3: 4,
# Unknown event (0-1)
4: 1,
# Enable Net Taisen, including win/loss display on song select (0-1)
5: 1,
# Enable NAVI-kun shunkyoku toujou, allows song 1608 to be unlocked (0-1)
6: 1,
# Unknown event (0-1)
7: 1,
# Unknown event (0-2)
8: 2,
# Daily Mission (0-2)
9: 2,
# NAVI-kun Song phase availability (0-15)
10: 15,
# Unknown event (0-1)
11: 1,
# Unknown event (0-2)
12: 2,
# Enable Pop'n Peace preview song (0-1)
13: 1,
'ints': [
{
'name': 'Music Open Phase',
'tip': 'Default music phase for all players.',
'category': 'game_config',
'setting': 'music_phase',
'values': {
0: 'No music unlocks',
1: 'Phase 1',
2: 'Phase 2',
3: 'Phase 3',
4: 'Phase 4',
5: 'Phase 5',
6: 'Phase 6',
7: 'Phase 7',
8: 'Phase 8',
9: 'Phase 9',
10: 'Phase 10',
11: 'Phase MAX',
}
},
{
'name': 'Active Event',
'tip': 'Active event for all players.',
'category': 'game_config',
'setting': 'active_event',
'values': {
0: 'No event',
1: 'NAVI-Kun event',
2: 'Daily Mission event',
},
},
{
'name': 'NAVI-Kun Event Phase',
'tip': 'NAVI-Kun event phase for all players.',
'category': 'game_config',
'setting': 'navikun_phase',
'values': {
0: 'Phase 1',
1: 'Phase 2',
2: 'Phase 3',
3: 'Phase 4',
4: 'Phase 5',
5: 'Phase 6',
6: 'Phase 7',
7: 'Phase 8',
8: 'Phase 9',
9: 'Phase 10',
10: 'Phase 11',
11: 'Phase 12',
12: 'Phase 13',
13: 'Phase 14',
14: 'Phase 15',
15: 'Phase MAX',
},
},
],
'bools': [
{
'name': 'Force Song Unlock',
'tip': 'Force unlock all songs.',
'category': 'game_config',
'setting': 'force_unlock_songs',
},
],
}
def get_common_config(self) -> Tuple[Dict[int, int], bool]:
game_config = self.get_game_config()
music_phase = game_config.get_int('music_phase')
active_event = game_config.get_int('active_event')
navikun_phase = game_config.get_int('navikun_phase')
navikun_enabled = active_event == 1
daily_mission_enabled = active_event == 2
# Event phases
return (
{
# Default song phase availability (0-11)
# The following songs are unlocked when the phase is at or above the number specified:
# 1 - 1589, 1590, 1591
# 2 - 1594, 1595
# 3 - 1596, 1597
# 4 - 1593
# 5 - 1602
# 6 - 1604
# 7 - 1629, 1630, 1631, 1633, 1641, 1642, 1643, 1644, 1645, 1646, 1647
# 8 - 1632
# 9 - 1651
# 10 - 1679, 1680, 1681
# 11 - 1669, 1670, 1669, 1670
0: music_phase,
# Unknown event (0-2)
1: 2,
# Unknown event (0-2)
2: 2,
# Unknown event (0-4)
3: 4,
# Unknown event (0-1)
4: 1,
# Enable Net Taisen, including win/loss display on song select (0-1)
5: 1,
# Enable NAVI-kun shunkyoku toujou, allows song 1608 to be unlocked (0-1)
6: 1,
# Unknown event (0-1)
7: 1,
# Unknown event (0-2)
8: 2,
# Daily Mission (0-2)
9: 2 if daily_mission_enabled else 0,
# NAVI-kun Song phase availability (0-15)
# The following songs are unlocked when the phase is at or above the number specified:
# 1 - 1553
# 2 - 1577, 1576, 1569
# 3 - 1575, 1557
# 4 - 1567
# 5 - 1587, 1588, 1585
# 6 - 1586
# 7 - 1601, 1600, 1599
# 8 - 1603
# 9 - 1606, 1607, 1605
# 10 - 1610, 1611, 1612
# 11 - 1616, 1613, 1614, 1615
# 12 - 1619, 1618, 1620, 1617
# 13 - 1624, 1621, 1623, 1622
# 14 - 1627, 1626, 1625
# 15 - 1628
10: navikun_phase,
# Unknown event (0-1)
11: 1,
# Unknown event (0-2)
12: 2,
# Enable Pop'n Peace preview song (1703) (0-1)
13: 1,
},
navikun_enabled,
)

View File

@ -41,10 +41,13 @@ class PopnMusicUsaNekoClient(BaseClient):
def __verify_common(self, root: str, resp: Node) -> None:
self.assert_path(resp, f"response/{root}/phase/event_id")
self.assert_path(resp, f"response/{root}/phase/phase")
self.assert_path(resp, f"response/{root}/area/area_id")
self.assert_path(resp, f"response/{root}/area/end_date")
self.assert_path(resp, f"response/{root}/area/medal_id")
self.assert_path(resp, f"response/{root}/area/is_limit")
# Area stuff is only necessary if navikun event is active.
# self.assert_path(resp, f"response/{root}/area/area_id")
# self.assert_path(resp, f"response/{root}/area/end_date")
# self.assert_path(resp, f"response/{root}/area/medal_id")
# self.assert_path(resp, f"response/{root}/area/is_limit")
self.assert_path(resp, f"response/{root}/choco/choco_id")
self.assert_path(resp, f"response/{root}/choco/param")
self.assert_path(resp, f"response/{root}/goods/item_id")