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:
parent
2582f0e523
commit
a1c786a525
@ -119,11 +119,18 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
|
|||||||
return Node.void('pcb24')
|
return Node.void('pcb24')
|
||||||
|
|
||||||
@abstractmethod
|
@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:
|
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')
|
phase = Node.void('phase')
|
||||||
root.add_child(phase)
|
root.add_child(phase)
|
||||||
phase.add_child(Node.s16('event_id', phaseid))
|
phase.add_child(Node.s16('event_id', phaseid))
|
||||||
@ -199,7 +206,8 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
|
|||||||
subnode.add_child(Node.u8('clear_type', ach.data.get_int('clear_type')))
|
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')))
|
subnode.add_child(Node.u8('clear_rank', ach.data.get_int('clear_rank')))
|
||||||
|
|
||||||
for area_id in range(0, 16):
|
if send_areas:
|
||||||
|
for area_id in range(1, 16):
|
||||||
area = Node.void('area')
|
area = Node.void('area')
|
||||||
root.add_child(area)
|
root.add_child(area)
|
||||||
area.add_child(Node.s16('area_id', area_id))
|
area.add_child(Node.s16('area_id', area_id))
|
||||||
@ -958,6 +966,18 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
|
|||||||
if 'navi_points' in profile:
|
if 'navi_points' in profile:
|
||||||
navi_data.add_child(Node.s32_array('raisePoint', profile.get_int_array('navi_points', 5)))
|
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
|
# Set up achievements
|
||||||
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
|
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
|
||||||
for achievement in achievements:
|
for achievement in achievements:
|
||||||
@ -967,8 +987,6 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
|
|||||||
is_new = achievement.data.get_bool('is_new')
|
is_new = achievement.data.get_bool('is_new')
|
||||||
get_time = achievement.data.get_int('get_time')
|
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 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
|
# 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
|
# 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
|
# 4: 1
|
||||||
# 5: 1
|
# 5: 1
|
||||||
# 6: 60
|
# 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.u8('type', itemtype))
|
||||||
item.add_child(Node.u16('id', achievement.id))
|
item.add_child(Node.u16('id', achievement.id))
|
||||||
item.add_child(Node.u16('param', param))
|
item.add_child(Node.u16('param', param))
|
||||||
@ -1223,6 +1247,7 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Extract achievements
|
# Extract achievements
|
||||||
|
game_config = self.get_game_config()
|
||||||
for node in request.children:
|
for node in request.children:
|
||||||
if node.name == 'item':
|
if node.name == 'item':
|
||||||
itemid = node.child_value('id')
|
itemid = node.child_value('id')
|
||||||
@ -1231,6 +1256,10 @@ class PopnMusicModernBase(PopnMusicBase, ABC):
|
|||||||
is_new = node.child_value('is_new')
|
is_new = node.child_value('is_new')
|
||||||
get_time = node.child_value('get_time')
|
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.data.local.user.put_achievement(
|
||||||
self.game,
|
self.game,
|
||||||
self.version,
|
self.version,
|
||||||
|
@ -164,7 +164,7 @@ class PopnMusicEclale(PopnMusicBase):
|
|||||||
phase.add_child(Node.s16('phase', phases[phaseid]))
|
phase.add_child(Node.s16('phase', phases[phaseid]))
|
||||||
|
|
||||||
if game_config.get_bool('starmaker_enable'):
|
if game_config.get_bool('starmaker_enable'):
|
||||||
for areaid in range(51):
|
for areaid in range(1, 51):
|
||||||
area = Node.void('area')
|
area = Node.void('area')
|
||||||
root.add_child(area)
|
root.add_child(area)
|
||||||
area.add_child(Node.s16('area_id', areaid))
|
area.add_child(Node.s16('area_id', areaid))
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# vim: set fileencoding=utf-8
|
# 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.base import PopnMusicBase
|
||||||
from bemani.backend.popn.common import PopnMusicModernBase
|
from bemani.backend.popn.common import PopnMusicModernBase
|
||||||
@ -18,10 +18,11 @@ class PopnMusicPeace(PopnMusicModernBase):
|
|||||||
def previous_version(self) -> PopnMusicBase:
|
def previous_version(self) -> PopnMusicBase:
|
||||||
return PopnMusicUsaNeko(self.data, self.config, self.model)
|
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
|
# Event phases
|
||||||
# TODO: Hook event mode settings up to the front end.
|
# TODO: Hook event mode settings up to the front end.
|
||||||
return {
|
return (
|
||||||
|
{
|
||||||
# Default song phase availability (0-23)
|
# Default song phase availability (0-23)
|
||||||
0: 23,
|
0: 23,
|
||||||
# Unknown event (0-2)
|
# Unknown event (0-2)
|
||||||
@ -72,4 +73,6 @@ class PopnMusicPeace(PopnMusicModernBase):
|
|||||||
23: 1,
|
23: 1,
|
||||||
# Unknown event (0-1)
|
# Unknown event (0-1)
|
||||||
24: 1,
|
24: 1,
|
||||||
}
|
},
|
||||||
|
False,
|
||||||
|
)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# vim: set fileencoding=utf-8
|
# 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.base import PopnMusicBase
|
||||||
from bemani.backend.popn.common import PopnMusicModernBase
|
from bemani.backend.popn.common import PopnMusicModernBase
|
||||||
@ -18,12 +18,105 @@ class PopnMusicUsaNeko(PopnMusicModernBase):
|
|||||||
def previous_version(self) -> PopnMusicBase:
|
def previous_version(self) -> PopnMusicBase:
|
||||||
return PopnMusicEclale(self.data, self.config, self.model)
|
return PopnMusicEclale(self.data, self.config, self.model)
|
||||||
|
|
||||||
def get_phases(self) -> Dict[int, int]:
|
@classmethod
|
||||||
# Event phases
|
def get_settings(cls) -> Dict[str, Any]:
|
||||||
# TODO: Hook event mode settings up to the front end.
|
"""
|
||||||
|
Return all of our front-end modifiably settings.
|
||||||
|
"""
|
||||||
return {
|
return {
|
||||||
|
'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)
|
# Default song phase availability (0-11)
|
||||||
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)
|
# Unknown event (0-2)
|
||||||
1: 2,
|
1: 2,
|
||||||
# Unknown event (0-2)
|
# Unknown event (0-2)
|
||||||
@ -41,13 +134,31 @@ class PopnMusicUsaNeko(PopnMusicModernBase):
|
|||||||
# Unknown event (0-2)
|
# Unknown event (0-2)
|
||||||
8: 2,
|
8: 2,
|
||||||
# Daily Mission (0-2)
|
# Daily Mission (0-2)
|
||||||
9: 2,
|
9: 2 if daily_mission_enabled else 0,
|
||||||
# NAVI-kun Song phase availability (0-15)
|
# NAVI-kun Song phase availability (0-15)
|
||||||
10: 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)
|
# Unknown event (0-1)
|
||||||
11: 1,
|
11: 1,
|
||||||
# Unknown event (0-2)
|
# Unknown event (0-2)
|
||||||
12: 2,
|
12: 2,
|
||||||
# Enable Pop'n Peace preview song (0-1)
|
# Enable Pop'n Peace preview song (1703) (0-1)
|
||||||
13: 1,
|
13: 1,
|
||||||
}
|
},
|
||||||
|
navikun_enabled,
|
||||||
|
)
|
||||||
|
@ -41,10 +41,13 @@ class PopnMusicUsaNekoClient(BaseClient):
|
|||||||
def __verify_common(self, root: str, resp: Node) -> None:
|
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/event_id")
|
||||||
self.assert_path(resp, f"response/{root}/phase/phase")
|
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")
|
# Area stuff is only necessary if navikun event is active.
|
||||||
self.assert_path(resp, f"response/{root}/area/medal_id")
|
# self.assert_path(resp, f"response/{root}/area/area_id")
|
||||||
self.assert_path(resp, f"response/{root}/area/is_limit")
|
# 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/choco_id")
|
||||||
self.assert_path(resp, f"response/{root}/choco/param")
|
self.assert_path(resp, f"response/{root}/choco/param")
|
||||||
self.assert_path(resp, f"response/{root}/goods/item_id")
|
self.assert_path(resp, f"response/{root}/goods/item_id")
|
||||||
|
Loading…
Reference in New Issue
Block a user