1
0
mirror of synced 2025-01-18 14:14:03 +01:00

Switch profile operations to using a Profile class instead of a raw ValidatedDict.

This commit is contained in:
Jennifer Taylor 2021-08-20 04:43:13 +00:00
parent 5fe48fb1c3
commit b940e3143f
64 changed files with 724 additions and 624 deletions

View File

@ -2,18 +2,18 @@ from typing import Any, Dict, List, Set, Tuple
from bemani.api.exceptions import APIException
from bemani.api.objects.base import BaseObject
from bemani.common import ValidatedDict, GameConstants, APIConstants
from bemani.common import Profile, ValidatedDict, GameConstants, APIConstants
from bemani.data import UserID
class ProfileObject(BaseObject):
def __format_ddr_profile(self, profile: ValidatedDict, exact: bool) -> Dict[str, Any]:
def __format_ddr_profile(self, profile: Profile, exact: bool) -> Dict[str, Any]:
return {
'area': profile.get_int('area', -1) if exact else -1,
}
def __format_iidx_profile(self, profile: ValidatedDict, exact: bool) -> Dict[str, Any]:
def __format_iidx_profile(self, profile: Profile, exact: bool) -> Dict[str, Any]:
qpro = profile.get_dict('qpro')
return {
@ -27,26 +27,26 @@ class ProfileObject(BaseObject):
}
}
def __format_jubeat_profile(self, profile: ValidatedDict, exact: bool) -> Dict[str, Any]:
def __format_jubeat_profile(self, profile: Profile, exact: bool) -> Dict[str, Any]:
return {}
def __format_museca_profile(self, profile: ValidatedDict, exact: bool) -> Dict[str, Any]:
def __format_museca_profile(self, profile: Profile, exact: bool) -> Dict[str, Any]:
return {}
def __format_popn_profile(self, profile: ValidatedDict, exact: bool) -> Dict[str, Any]:
def __format_popn_profile(self, profile: Profile, exact: bool) -> Dict[str, Any]:
return {
'character': profile.get_int('chara', -1) if exact else -1,
}
def __format_reflec_profile(self, profile: ValidatedDict, exact: bool) -> Dict[str, Any]:
def __format_reflec_profile(self, profile: Profile, exact: bool) -> Dict[str, Any]:
return {
'icon': profile.get_dict('config').get_int('icon_id', -1) if exact else -1,
}
def __format_sdvx_profile(self, profile: ValidatedDict, exact: bool) -> Dict[str, Any]:
def __format_sdvx_profile(self, profile: Profile, exact: bool) -> Dict[str, Any]:
return {}
def __format_profile(self, cardids: List[str], profile: ValidatedDict, settings: ValidatedDict, exact: bool) -> Dict[str, Any]:
def __format_profile(self, cardids: List[str], profile: Profile, settings: ValidatedDict, exact: bool) -> Dict[str, Any]:
base = {
'name': profile.get_str('name'),
'cards': cardids,
@ -75,7 +75,7 @@ class ProfileObject(BaseObject):
def fetch_v1(self, idtype: APIConstants, ids: List[str], params: Dict[str, Any]) -> List[Dict[str, Any]]:
# Fetch the profiles
profiles: List[Tuple[UserID, ValidatedDict]] = []
profiles: List[Tuple[UserID, Profile]] = []
if idtype == APIConstants.ID_TYPE_SERVER:
profiles.extend(self.data.local.user.get_all_profiles(self.game, self.version))
elif idtype == APIConstants.ID_TYPE_SONG:

View File

@ -2,7 +2,7 @@ from abc import ABC
import traceback
from typing import Any, Dict, Iterator, List, Optional, Set, Tuple, Type
from bemani.common import Model, ValidatedDict, GameConstants, Time
from bemani.common import Model, ValidatedDict, Profile, GameConstants, Time
from bemani.data import Data, UserID, RemoteUser
@ -248,7 +248,7 @@ class Base(ABC):
"""
return self.data.local.user.get_profile(self.game, self.version, userid) is not None
def get_profile(self, userid: UserID) -> Optional[ValidatedDict]:
def get_profile(self, userid: UserID) -> Optional[Profile]:
"""
Return the profile for a user given this game/version on any connected server.
@ -260,7 +260,7 @@ class Base(ABC):
"""
return self.data.remote.user.get_profile(self.game, self.version, userid)
def get_any_profile(self, userid: UserID) -> ValidatedDict:
def get_any_profile(self, userid: UserID) -> Profile:
"""
Return ANY profile for a user in a game series.
@ -279,10 +279,15 @@ class Base(ABC):
"""
profile = self.data.remote.user.get_any_profile(self.game, self.version, userid)
if profile is None:
profile = ValidatedDict()
profile = Profile(
self.game,
self.version,
"",
0,
)
return profile
def get_any_profiles(self, userids: List[UserID]) -> List[Tuple[UserID, ValidatedDict]]:
def get_any_profiles(self, userids: List[UserID]) -> List[Tuple[UserID, Profile]]:
"""
Does the identical thing to the above function, but takes a list of user IDs to
fetch in bulk.
@ -297,11 +302,11 @@ class Base(ABC):
userids = list(set(userids))
profiles = self.data.remote.user.get_any_profiles(self.game, self.version, userids)
return [
(userid, profile if profile is not None else ValidatedDict())
(userid, profile if profile is not None else Profile(self.game, self.version, "", 0))
for (userid, profile) in profiles
]
def put_profile(self, userid: UserID, profile: ValidatedDict) -> None:
def put_profile(self, userid: UserID, profile: Profile) -> None:
"""
Save a new profile for this user given a game/version.

View File

@ -7,7 +7,7 @@ from typing import Any, Dict, List, Sequence, Union
from bemani.backend.bishi.base import BishiBashiBase
from bemani.backend.ess import EventLogHandler
from bemani.common import ValidatedDict, GameConstants, VersionConstants, Time
from bemani.common import Profile, GameConstants, VersionConstants, Time
from bemani.data import UserID
from bemani.protocol import Node
@ -215,7 +215,7 @@ class TheStarBishiBashi(
oldprofile = self.get_profile(userid)
is_new = False
if oldprofile is None:
oldprofile = ValidatedDict()
oldprofile = Profile(self.game, self.version, refid, 0)
is_new = True
newprofile = self.unformat_profile(userid, request, oldprofile, is_new)
@ -244,7 +244,7 @@ class TheStarBishiBashi(
root.add_child(Node.s32('result', 1)) # Unclear if this is the right thing to do here.
return root
def format_profile(self, userid: UserID, profiletype: str, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profiletype: str, profile: Profile) -> Node:
root = Node.void('playerdata')
root.add_child(Node.s32('result', 0))
player = Node.void('player')
@ -321,7 +321,7 @@ class TheStarBishiBashi(
player.add_child(Node.u32('record_num', records))
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict, is_new: bool) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile, is_new: bool) -> Profile:
# Profile save request, data values are base64 encoded.
# d is a CSV, and bin1 is binary data.
newprofile = copy.deepcopy(oldprofile)

View File

@ -3,7 +3,7 @@ from typing import Optional, Dict, List, Any
from bemani.backend.base import Base
from bemani.backend.core import CoreHandler, CardManagerHandler, PASELIHandler
from bemani.common import Model, ValidatedDict, GameConstants, DBConstants, Time
from bemani.common import Model, Profile, ValidatedDict, GameConstants, DBConstants, Time
from bemani.data import Data, Score, UserID, ScoreSaveException
from bemani.protocol import Node
@ -115,21 +115,21 @@ class DDRBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
"""
return None
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
"""
Base handler for a profile. Given a userid and a profile dictionary,
return a Node representing a profile. Should be overridden.
"""
return Node.void('game')
def format_scores(self, userid: UserID, profile: ValidatedDict, scores: List[Score]) -> Node:
def format_scores(self, userid: UserID, profile: Profile, scores: List[Score]) -> Node:
"""
Base handler for a score list. Given a userid, profile and a score list,
return a Node representing a score list. Should be overridden.
"""
return Node.void('game')
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
"""
Base handler for profile parsing. Given a request and an old profile,
return a new profile that's been updated with the contents of the request.
@ -165,10 +165,16 @@ class DDRBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
if userid is None:
return
defaultprofile = ValidatedDict({
'name': name,
'area': area,
})
defaultprofile = Profile(
self.game,
self.version,
refid,
0,
{
'name': name,
'area': area,
},
)
self.put_profile(userid, defaultprofile)
def put_profile_by_refid(self, refid: Optional[str], request: Node) -> None:

View File

@ -1,7 +1,7 @@
from typing import Dict, Optional, Tuple
from bemani.backend.ddr.base import DDRBase
from bemani.common import Time, ValidatedDict, intish
from bemani.common import Time, Profile, intish
from bemani.data import Score, UserID
from bemani.protocol import Node
@ -98,7 +98,7 @@ class DDRGameHiscoreHandler(DDRBase):
typenode.add_child(Node.u16('area', users[userid].get_int('area', 51)))
typenode.add_child(Node.u8('rank', gamerank))
typenode.add_child(Node.u8('combo_type', combo_type))
typenode.add_child(Node.u32('code', users[userid].get_int('extid')))
typenode.add_child(Node.u32('code', users[userid].extid))
return game
@ -154,7 +154,7 @@ class DDRGameAreaHiscoreHandler(DDRBase):
typenode.add_child(Node.u16('area', area_users[userid].get_int('area', 51)))
typenode.add_child(Node.u8('rank', gamerank))
typenode.add_child(Node.u8('combo_type', combo_type))
typenode.add_child(Node.u32('code', area_users[userid].get_int('extid')))
typenode.add_child(Node.u32('code', area_users[userid].extid))
return game
@ -303,7 +303,7 @@ class DDRGameOldHandler(DDRBase):
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
previous_version: Optional[DDRBase] = None
oldprofile: Optional[ValidatedDict] = None
oldprofile: Optional[Profile] = None
if userid is not None:
previous_version = self.previous_version()
@ -362,7 +362,7 @@ class DDRGameFriendHandler(DDRBase):
game = Node.void('game')
game.set_attribute('data', '1')
game.add_child(Node.u32('code', friend.get_int('extid')))
game.add_child(Node.u32('code', friend.extid))
game.add_child(Node.string('name', friend.get_str('name')))
game.add_child(Node.u8('area', friend.get_int('area', 51)))
game.add_child(Node.u32('exp', play_stats.get_int('exp')))

View File

@ -25,7 +25,7 @@ from bemani.backend.ddr.common import (
DDRGameTaxInfoHandler,
DDRGameTraceHandler,
)
from bemani.common import VersionConstants, ValidatedDict, Time, intish
from bemani.common import VersionConstants, Profile, Time, intish
from bemani.data import Score, UserID
from bemani.protocol import Node
@ -271,7 +271,7 @@ class DDR2013(
game = Node.void('game')
return game
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('game')
# Look up play stats we bridge to every mix
@ -279,7 +279,7 @@ class DDR2013(
# Basic game settings
root.add_child(Node.string('seq', ''))
root.add_child(Node.u32('code', profile.get_int('extid')))
root.add_child(Node.u32('code', profile.extid))
root.add_child(Node.string('name', profile.get_str('name')))
root.add_child(Node.u8('area', profile.get_int('area', 51)))
root.add_child(Node.u32('cnt_s', play_stats.get_int('single_plays')))
@ -424,7 +424,7 @@ class DDR2013(
friendnode.set_attribute('pos', str(pos))
friendnode.set_attribute('vs', '0')
friendnode.set_attribute('up', '0')
friendnode.add_child(Node.u32('code', friend.get_int('extid')))
friendnode.add_child(Node.u32('code', friend.extid))
friendnode.add_child(Node.string('name', friend.get_str('name')))
friendnode.add_child(Node.u8('area', friend.get_int('area', 51)))
friendnode.add_child(Node.u32('exp', play_stats.get_int('exp')))
@ -477,7 +477,7 @@ class DDR2013(
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
play_stats = self.get_play_statistics(userid)

View File

@ -22,7 +22,7 @@ from bemani.backend.ddr.common import (
DDRGameShopHandler,
DDRGameTaxInfoHandler,
)
from bemani.common import VersionConstants, ValidatedDict, Time, intish
from bemani.common import VersionConstants, Profile, Time, intish
from bemani.data import Score, UserID
from bemani.protocol import Node
@ -321,7 +321,7 @@ class DDR2014(
return game
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('game')
# Look up play stats we bridge to every mix
@ -329,7 +329,7 @@ class DDR2014(
# Basic game settings
root.add_child(Node.string('seq', ''))
root.add_child(Node.u32('code', profile.get_int('extid')))
root.add_child(Node.u32('code', profile.extid))
root.add_child(Node.string('name', profile.get_str('name')))
root.add_child(Node.u8('area', profile.get_int('area', 51)))
root.add_child(Node.u32('cnt_s', play_stats.get_int('single_plays')))
@ -479,7 +479,7 @@ class DDR2014(
friendnode.set_attribute('pos', str(pos))
friendnode.set_attribute('vs', '0')
friendnode.set_attribute('up', '0')
friendnode.add_child(Node.u32('code', friend.get_int('extid')))
friendnode.add_child(Node.u32('code', friend.extid))
friendnode.add_child(Node.string('name', friend.get_str('name')))
friendnode.add_child(Node.u8('area', friend.get_int('area', 51)))
friendnode.add_child(Node.u32('exp', play_stats.get_int('exp')))
@ -538,7 +538,7 @@ class DDR2014(
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
play_stats = self.get_play_statistics(userid)

View File

@ -5,7 +5,7 @@ from typing import Dict, List, Optional
from bemani.backend.ess import EventLogHandler
from bemani.backend.ddr.base import DDRBase
from bemani.backend.ddr.ddr2014 import DDR2014
from bemani.common import ValidatedDict, VersionConstants, CardCipher, Time, ID, intish
from bemani.common import Profile, ValidatedDict, VersionConstants, CardCipher, Time, ID, intish
from bemani.data import Achievement, Machine, Score, UserID
from bemani.protocol import Node
@ -470,7 +470,7 @@ class DDRAce(
machines_by_id: Dict[int, Optional[Machine]] = {thismachine.id: thismachine}
loadkind = requestdata.child_value('loadflag')
profiles_by_userid: Dict[UserID, ValidatedDict] = {}
profiles_by_userid: Dict[UserID, Profile] = {}
def get_machine(lid: int) -> Optional[Machine]:
if lid not in machines_by_id:
@ -551,7 +551,7 @@ class DDRAce(
record.add_child(Node.u8('flagdata', 0))
record.add_child(Node.string('name', profiledata.get_str('name')))
record.add_child(Node.s32('area', profiledata.get_int('area', 58)))
record.add_child(Node.s32('code', profiledata.get_int('extid')))
record.add_child(Node.s32('code', profiledata.extid))
record.add_child(Node.s32('score', score.points))
record.add_child(Node.s32('ghostid', score.key))
@ -560,13 +560,19 @@ class DDRAce(
raise Exception('Expecting valid UserID to create new profile!')
machine = self.data.local.machine.get_machine(self.config['machine']['pcbid'])
self.put_profile(userid, ValidatedDict({
'lid': machine.id,
}))
profile = self.get_profile(userid)
profile = Profile(
self.game,
self.version,
"",
0,
{
'lid': machine.id,
},
)
self.put_profile(userid, profile)
response.add_child(Node.string('seq', ID.format_extid(profile.get_int('extid'))))
response.add_child(Node.s32('code', profile.get_int('extid')))
response.add_child(Node.string('seq', ID.format_extid(profile.extid)))
response.add_child(Node.s32('code', profile.extid))
response.add_child(Node.string('shoparea', ''))
def __handle_inheritance(self, userid: Optional[UserID], requestdata: Node, response: Node) -> None:
@ -588,7 +594,7 @@ class DDRAce(
ghostdata = Node.void('ghostdata')
response.add_child(ghostdata)
ghostdata.add_child(Node.s32('code', profile.get_int('extid')))
ghostdata.add_child(Node.s32('code', profile.extid))
ghostdata.add_child(Node.u32('mcode', score.id))
ghostdata.add_child(Node.u8('notetype', self.db_to_game_chart(score.chart)))
ghostdata.add_child(Node.s32('ghostsize', len(score.data['ghost'])))
@ -632,7 +638,7 @@ class DDRAce(
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
if userid is not None:
profile = self.get_profile(userid) or ValidatedDict()
profile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
usergamedata = profile.get_dict('usergamedata')
for record in request.child('data/record').children:
@ -741,7 +747,7 @@ class DDRAce(
rival = usergamedata[ptype]['strdata'].split(b',')
lastdict = profile.get_dict('last')
friends: Dict[int, Optional[ValidatedDict]] = {}
friends: Dict[int, Optional[Profile]] = {}
for link in links:
if link.type[:7] != 'friend_':
continue
@ -775,7 +781,7 @@ class DDRAce(
}[rivalno]
rival[activeslot] = acehex(rivalno).encode('ascii')
rival[ddrcodeslot] = acehex(friendprofile.get_int('extid')).encode('ascii')
rival[ddrcodeslot] = acehex(friendprofile.extid).encode('ascii')
usergamedata[ptype]['strdata'] = b','.join(rival)

View File

@ -20,7 +20,7 @@ from bemani.backend.ddr.common import (
DDRGameShopHandler,
DDRGameTraceHandler,
)
from bemani.common import Time, VersionConstants, ValidatedDict, intish
from bemani.common import Time, VersionConstants, Profile, intish
from bemani.data import Score, UserID
from bemani.protocol import Node
@ -297,7 +297,7 @@ class DDRX2(
game = Node.void('game')
return game
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('game')
# Look up play stats we bridge to every mix
@ -305,7 +305,7 @@ class DDRX2(
# Basic game settings
root.add_child(Node.string('seq', ''))
root.add_child(Node.u32('code', profile.get_int('extid')))
root.add_child(Node.u32('code', profile.extid))
root.add_child(Node.string('name', profile.get_str('name')))
root.add_child(Node.u8('area', profile.get_int('area', 51)))
root.add_child(Node.u32('cnt_s', play_stats.get_int('single_plays')))
@ -470,7 +470,7 @@ class DDRX2(
friendnode.set_attribute('pos', str(pos))
friendnode.set_attribute('vs', '0')
friendnode.set_attribute('up', '0')
friendnode.add_child(Node.u32('code', friend.get_int('extid')))
friendnode.add_child(Node.u32('code', friend.extid))
friendnode.add_child(Node.string('name', friend.get_str('name')))
friendnode.add_child(Node.u8('area', friend.get_int('area', 51)))
friendnode.add_child(Node.u32('exp', play_stats.get_int('exp')))
@ -516,7 +516,7 @@ class DDRX2(
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
play_stats = self.get_play_statistics(userid)

View File

@ -23,7 +23,7 @@ from bemani.backend.ddr.common import (
DDRGameShopHandler,
DDRGameTraceHandler,
)
from bemani.common import ValidatedDict, VersionConstants, Time, intish
from bemani.common import Profile, VersionConstants, Time, intish
from bemani.data import Achievement, Score, UserID
from bemani.protocol import Node
@ -346,7 +346,7 @@ class DDRX3(
game = Node.void('game')
return game
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('game')
# Look up play stats we bridge to every mix
@ -354,7 +354,7 @@ class DDRX3(
# Basic game settings
root.add_child(Node.string('seq', ''))
root.add_child(Node.u32('code', profile.get_int('extid')))
root.add_child(Node.u32('code', profile.extid))
root.add_child(Node.string('name', profile.get_str('name')))
root.add_child(Node.u8('area', profile.get_int('area', 51)))
root.add_child(Node.u32('cnt_s', play_stats.get_int('single_plays')))
@ -499,7 +499,7 @@ class DDRX3(
friendnode.set_attribute('pos', str(pos))
friendnode.set_attribute('vs', '0')
friendnode.set_attribute('up', '0')
friendnode.add_child(Node.u32('code', friend.get_int('extid')))
friendnode.add_child(Node.u32('code', friend.extid))
friendnode.add_child(Node.string('name', friend.get_str('name')))
friendnode.add_child(Node.u8('area', friend.get_int('area', 51)))
friendnode.add_child(Node.u32('exp', play_stats.get_int('exp')))
@ -552,7 +552,7 @@ class DDRX3(
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
play_stats = self.get_play_statistics(userid)

View File

@ -4,7 +4,7 @@ from typing import Optional, Dict, Any, List, Tuple
from bemani.backend.base import Base
from bemani.backend.core import CoreHandler, CardManagerHandler, PASELIHandler
from bemani.common import ValidatedDict, Model, GameConstants, DBConstants, Parallel
from bemani.common import Profile, ValidatedDict, Model, GameConstants, DBConstants, Parallel
from bemani.data import Data, Score, Machine, UserID
from bemani.protocol import Node
@ -103,14 +103,14 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
'local2',
]
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
"""
Base handler for a profile. Given a userid and a profile dictionary,
return a Node representing a profile. Should be overridden.
"""
return Node.void('pc')
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
"""
Base handler for profile parsing. Given a request and an old profile,
return a new profile that's been updated with the contents of the request.
@ -138,7 +138,7 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
return None
return self.format_profile(userid, profile)
def new_profile_by_refid(self, refid: Optional[str], name: Optional[str], pid: Optional[int]) -> ValidatedDict:
def new_profile_by_refid(self, refid: Optional[str], name: Optional[str], pid: Optional[int]) -> Profile:
"""
Given a RefID and an optional name, create a profile and then return
that newly created profile.
@ -152,15 +152,20 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
pid = 51
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
defaultprofile = ValidatedDict({
'name': name,
'pid': pid,
'settings': {
'flags': 223 # Default to turning on all optional folders
profile = Profile(
self.game,
self.version,
refid,
0,
{
'name': name,
'pid': pid,
'settings': {
'flags': 223 # Default to turning on all optional folders
},
},
})
self.put_profile(userid, defaultprofile)
profile = self.get_profile(userid)
)
self.put_profile(userid, profile)
return profile
def put_profile_by_extid(self, extid: Optional[int], request: Node) -> None:
@ -454,7 +459,12 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
# Update profile if needed
profile = self.get_profile(userid)
if profile is None:
profile = ValidatedDict()
profile = Profile(
self.game,
self.version,
"",
0,
)
profile.replace_int(dantype, max(rank, profile.get_int(dantype, -1)))
self.put_profile(userid, profile)
@ -606,7 +616,7 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
# Return averages
return new_ex_score, struct.pack('b' * ghost_length, *delta_ghost)
def user_joined_arcade(self, machine: Machine, profile: Optional[ValidatedDict]) -> bool:
def user_joined_arcade(self, machine: Machine, profile: Optional[Profile]) -> bool:
if profile is None:
return False
@ -671,7 +681,12 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
# other users who have also joined that arcade.
my_profile = self.get_profile(userid)
if my_profile is None:
my_profile = ValidatedDict()
my_profile = Profile(
self.game,
self.version,
"",
0,
)
if 'shop_location' in my_profile:
shop_id = my_profile.get_int('shop_location')
@ -708,7 +723,7 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
'ghost': top_score.data.get_bytes('ghost'),
'name': top_profile.get_str('name'),
'pid': top_profile.get_int('pid'),
'extid': top_profile.get_int('extid'),
'extid': top_profile.extid,
}
break
@ -734,7 +749,12 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
]
my_profile = self.get_profile(userid)
if my_profile is None:
my_profile = ValidatedDict()
my_profile = Profile(
self.game,
self.version,
"",
0,
)
if is_dp:
dan_rank = my_profile.get_int(self.DAN_RANKING_DOUBLE, -1)
else:
@ -766,7 +786,7 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
'ghost': top_score.data.get_bytes('ghost'),
'name': top_profile.get_str('name'),
'pid': top_profile.get_int('pid'),
'extid': top_profile.get_int('extid'),
'extid': top_profile.extid,
}
break
@ -808,7 +828,7 @@ class IIDXBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
'ghost': top_score.data.get_bytes('ghost'),
'name': top_profile.get_str('name'),
'pid': top_profile.get_int('pid'),
'extid': top_profile.get_int('extid'),
'extid': top_profile.extid,
}
break

View File

@ -8,7 +8,7 @@ from bemani.backend.iidx.base import IIDXBase
from bemani.backend.iidx.course import IIDXCourse
from bemani.backend.iidx.sinobuz import IIDXSinobuz
from bemani.common import ValidatedDict, VersionConstants, BroadcastConstants, Time, ID, intish
from bemani.common import Profile, ValidatedDict, VersionConstants, BroadcastConstants, Time, ID, intish
from bemani.data import Data, UserID
from bemani.protocol import Node
@ -404,7 +404,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
]
totalscores: Dict[UserID, int] = {}
profiles: Dict[UserID, ValidatedDict] = {}
profiles: Dict[UserID, Profile] = {}
for songid in songids:
scores = self.data.local.music.get_all_scores(
self.game,
@ -421,7 +421,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
totalscores[score[0]] = 0
profile = self.get_any_profile(score[0])
if profile is None:
profile = ValidatedDict()
profile = Profile(self.game, self.version, "", 0)
profiles[score[0]] = profile
totalscores[score[0]] += score[1].points
@ -802,7 +802,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
data = Node.void('data')
ranklist.add_child(data)
data.set_attribute('iidx_id', str(profile.get_int('extid')))
data.set_attribute('iidx_id', str(profile.extid))
data.set_attribute('name', profile.get_str('name'))
machine_name = ''
@ -1257,7 +1257,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
root = Node.void('IIDX25pc')
root.set_attribute('name', profile.get_str('name'))
root.set_attribute('idstr', ID.format_extid(profile.get_int('extid')))
root.set_attribute('idstr', ID.format_extid(profile.extid))
root.set_attribute('pid', str(profile.get_int('pid')))
return root
@ -1269,7 +1269,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
root = Node.void('IIDX25pc')
if newprofile is not None:
root.set_attribute('id', str(newprofile.get_int('extid')))
root.set_attribute('id', str(newprofile.extid))
return root
def handle_IIDX25pc_reg_request(self, request: Node) -> Node:
@ -1280,8 +1280,8 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
root = Node.void('IIDX25pc')
if profile is not None:
root.set_attribute('id', str(profile.get_int('extid')))
root.set_attribute('id_str', ID.format_extid(profile.get_int('extid')))
root.set_attribute('id', str(profile.extid))
root.set_attribute('id_str', ID.format_extid(profile.extid))
return root
def handle_IIDX25pc_get_request(self, request: Node) -> Node:
@ -1417,7 +1417,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
return Node.void('IIDX25pc')
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('IIDX25pc')
# Look up play stats we bridge to every mix
@ -1430,8 +1430,8 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
# Profile data
pcdata = Node.void('pcdata')
root.add_child(pcdata)
pcdata.set_attribute('id', str(profile.get_int('extid')))
pcdata.set_attribute('idstr', ID.format_extid(profile.get_int('extid')))
pcdata.set_attribute('id', str(profile.extid))
pcdata.set_attribute('idstr', ID.format_extid(profile.extid))
pcdata.set_attribute('name', profile.get_str('name'))
pcdata.set_attribute('pid', str(profile.get_int('pid')))
pcdata.set_attribute('spnum', str(play_stats.get_int('single_plays')))
@ -1636,8 +1636,8 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
rival = Node.void('rival')
rlist.add_child(rival)
rival.set_attribute('spdp', rival_type)
rival.set_attribute('id', str(other_profile.get_int('extid')))
rival.set_attribute('id_str', ID.format_extid(other_profile.get_int('extid')))
rival.set_attribute('id', str(other_profile.extid))
rival.set_attribute('id_str', ID.format_extid(other_profile.extid))
rival.set_attribute('djname', other_profile.get_str('name'))
rival.set_attribute('pid', str(other_profile.get_int('pid')))
rival.set_attribute('sg', str(self.db_to_game_rank(other_profile.get_int(self.DAN_RANKING_SINGLE, -1), self.GAME_CLTYPE_SINGLE)))
@ -1860,7 +1860,7 @@ class IIDXCannonBallers(IIDXCourse, IIDXBase):
pay_per_use.set_attribute('item_num', '99')
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
play_stats = self.get_play_statistics(userid)

View File

@ -8,7 +8,7 @@ from bemani.backend.iidx.base import IIDXBase
from bemani.backend.iidx.course import IIDXCourse
from bemani.backend.iidx.pendual import IIDXPendual
from bemani.common import ValidatedDict, VersionConstants, BroadcastConstants, Time, ID
from bemani.common import Profile, ValidatedDict, VersionConstants, BroadcastConstants, Time, ID
from bemani.data import Data, UserID
from bemani.protocol import Node
@ -392,7 +392,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
]
totalscores: Dict[UserID, int] = {}
profiles: Dict[UserID, ValidatedDict] = {}
profiles: Dict[UserID, Profile] = {}
for songid in songids:
scores = self.data.local.music.get_all_scores(
self.game,
@ -406,7 +406,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
totalscores[score[0]] = 0
profile = self.get_any_profile(score[0])
if profile is None:
profile = ValidatedDict()
profile = Profile(self.game, self.version, "", 0)
profiles[score[0]] = profile
totalscores[score[0]] += score[1].points
@ -695,7 +695,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
data = Node.void('data')
ranklist.add_child(data)
data.set_attribute('iidx_id', str(profile.get_int('extid')))
data.set_attribute('iidx_id', str(profile.extid))
data.set_attribute('name', profile.get_str('name'))
machine_name = ''
@ -1320,7 +1320,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
root = Node.void('IIDX23pc')
root.set_attribute('name', profile.get_str('name'))
root.set_attribute('idstr', ID.format_extid(profile.get_int('extid')))
root.set_attribute('idstr', ID.format_extid(profile.extid))
root.set_attribute('pid', str(profile.get_int('pid')))
return root
@ -1332,7 +1332,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
root = Node.void('IIDX23pc')
if newprofile is not None:
root.set_attribute('id', str(newprofile.get_int('extid')))
root.set_attribute('id', str(newprofile.extid))
return root
if method == 'reg':
@ -1343,8 +1343,8 @@ class IIDXCopula(IIDXCourse, IIDXBase):
root = Node.void('IIDX23pc')
if profile is not None:
root.set_attribute('id', str(profile.get_int('extid')))
root.set_attribute('id_str', ID.format_extid(profile.get_int('extid')))
root.set_attribute('id', str(profile.extid))
root.set_attribute('id_str', ID.format_extid(profile.extid))
return root
if method == 'get':
@ -1379,7 +1379,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
if userid is not None:
profile = self.get_profile(userid)
if profile is None:
profile = ValidatedDict()
profile = Profile(self.game, self.version, "", extid)
profile.replace_int('shop_location', location)
self.put_profile(userid, profile)
@ -1469,7 +1469,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
return Node.void('IIDX23pc')
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('IIDX23pc')
# Look up play stats we bridge to every mix
@ -1482,8 +1482,8 @@ class IIDXCopula(IIDXCourse, IIDXBase):
# Profile data
pcdata = Node.void('pcdata')
root.add_child(pcdata)
pcdata.set_attribute('id', str(profile.get_int('extid')))
pcdata.set_attribute('idstr', ID.format_extid(profile.get_int('extid')))
pcdata.set_attribute('id', str(profile.extid))
pcdata.set_attribute('idstr', ID.format_extid(profile.extid))
pcdata.set_attribute('name', profile.get_str('name'))
pcdata.set_attribute('pid', str(profile.get_int('pid')))
pcdata.set_attribute('spnum', str(play_stats.get_int('single_plays')))
@ -1660,8 +1660,8 @@ class IIDXCopula(IIDXCourse, IIDXBase):
rival = Node.void('rival')
rlist.add_child(rival)
rival.set_attribute('spdp', rival_type)
rival.set_attribute('id', str(other_profile.get_int('extid')))
rival.set_attribute('id_str', ID.format_extid(other_profile.get_int('extid')))
rival.set_attribute('id', str(other_profile.extid))
rival.set_attribute('id_str', ID.format_extid(other_profile.extid))
rival.set_attribute('djname', other_profile.get_str('name'))
rival.set_attribute('pid', str(other_profile.get_int('pid')))
rival.set_attribute('sg', str(self.db_to_game_rank(other_profile.get_int(self.DAN_RANKING_SINGLE, -1), self.GAME_CLTYPE_SINGLE)))
@ -1869,7 +1869,7 @@ class IIDXCopula(IIDXCourse, IIDXBase):
root.add_child(Node.void('bind_eaappli'))
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
play_stats = self.get_play_statistics(userid)

View File

@ -8,7 +8,7 @@ from bemani.backend.iidx.base import IIDXBase
from bemani.backend.iidx.course import IIDXCourse
from bemani.backend.iidx.spada import IIDXSpada
from bemani.common import ValidatedDict, VersionConstants, BroadcastConstants, Time, ID
from bemani.common import Profile, ValidatedDict, VersionConstants, BroadcastConstants, Time, ID
from bemani.data import Data, UserID
from bemani.protocol import Node
@ -255,7 +255,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
]
totalscores: Dict[UserID, int] = {}
profiles: Dict[UserID, ValidatedDict] = {}
profiles: Dict[UserID, Profile] = {}
for songid in songids:
scores = self.data.local.music.get_all_scores(
self.game,
@ -269,7 +269,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
totalscores[score[0]] = 0
profile = self.get_any_profile(score[0])
if profile is None:
profile = ValidatedDict()
profile = Profile(self.game, self.version, "", 0)
profiles[score[0]] = profile
totalscores[score[0]] += score[1].points
@ -679,7 +679,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
data = Node.void('data')
ranklist.add_child(data)
data.set_attribute('iidx_id', str(profile.get_int('extid')))
data.set_attribute('iidx_id', str(profile.extid))
data.set_attribute('name', profile.get_str('name'))
machine_name = ''
@ -1233,7 +1233,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
root = Node.void('IIDX22pc')
root.set_attribute('name', profile.get_str('name'))
root.set_attribute('idstr', ID.format_extid(profile.get_int('extid')))
root.set_attribute('idstr', ID.format_extid(profile.extid))
root.set_attribute('pid', str(profile.get_int('pid')))
return root
@ -1245,7 +1245,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
root = Node.void('IIDX22pc')
if newprofile is not None:
root.set_attribute('id', str(newprofile.get_int('extid')))
root.set_attribute('id', str(newprofile.extid))
return root
if method == 'reg':
@ -1256,8 +1256,8 @@ class IIDXPendual(IIDXCourse, IIDXBase):
root = Node.void('IIDX22pc')
if profile is not None:
root.set_attribute('id', str(profile.get_int('extid')))
root.set_attribute('id_str', ID.format_extid(profile.get_int('extid')))
root.set_attribute('id', str(profile.extid))
root.set_attribute('id_str', ID.format_extid(profile.extid))
return root
if method == 'get':
@ -1292,7 +1292,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
if userid is not None:
profile = self.get_profile(userid)
if profile is None:
profile = ValidatedDict()
profile = Profile(self.game, self.version, "", extid)
profile.replace_int('shop_location', location)
self.put_profile(userid, profile)
@ -1382,7 +1382,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
return Node.void('IIDX22pc')
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('IIDX22pc')
# Look up play stats we bridge to every mix
@ -1395,8 +1395,8 @@ class IIDXPendual(IIDXCourse, IIDXBase):
# Profile data
pcdata = Node.void('pcdata')
root.add_child(pcdata)
pcdata.set_attribute('id', str(profile.get_int('extid')))
pcdata.set_attribute('idstr', ID.format_extid(profile.get_int('extid')))
pcdata.set_attribute('id', str(profile.extid))
pcdata.set_attribute('idstr', ID.format_extid(profile.extid))
pcdata.set_attribute('name', profile.get_str('name'))
pcdata.set_attribute('pid', str(profile.get_int('pid')))
pcdata.set_attribute('spnum', str(play_stats.get_int('single_plays')))
@ -1628,8 +1628,8 @@ class IIDXPendual(IIDXCourse, IIDXBase):
rival = Node.void('rival')
rlist.add_child(rival)
rival.set_attribute('spdp', rival_type)
rival.set_attribute('id', str(other_profile.get_int('extid')))
rival.set_attribute('id_str', ID.format_extid(other_profile.get_int('extid')))
rival.set_attribute('id', str(other_profile.extid))
rival.set_attribute('id_str', ID.format_extid(other_profile.extid))
rival.set_attribute('djname', other_profile.get_str('name'))
rival.set_attribute('pid', str(other_profile.get_int('pid')))
rival.set_attribute('sg', str(self.db_to_game_rank(other_profile.get_int(self.DAN_RANKING_SINGLE, -1), self.GAME_CLTYPE_SINGLE)))
@ -1715,7 +1715,7 @@ class IIDXPendual(IIDXCourse, IIDXBase):
root.add_child(Node.void('bind_eaappli'))
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
play_stats = self.get_play_statistics(userid)

View File

@ -8,7 +8,7 @@ from bemani.backend.iidx.base import IIDXBase
from bemani.backend.iidx.course import IIDXCourse
from bemani.backend.iidx.cannonballers import IIDXCannonBallers
from bemani.common import ValidatedDict, VersionConstants, BroadcastConstants, Time, ID, intish
from bemani.common import Profile, ValidatedDict, VersionConstants, BroadcastConstants, Time, ID, intish
from bemani.data import Data, UserID
from bemani.protocol import Node
@ -655,7 +655,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
data = Node.void('data')
ranklist.add_child(data)
data.set_attribute('iidx_id', str(profile.get_int('extid')))
data.set_attribute('iidx_id', str(profile.extid))
data.set_attribute('name', profile.get_str('name'))
machine_name = ''
@ -932,7 +932,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
root = Node.void('IIDX26pc')
root.set_attribute('name', profile.get_str('name'))
root.set_attribute('idstr', ID.format_extid(profile.get_int('extid')))
root.set_attribute('idstr', ID.format_extid(profile.extid))
root.set_attribute('pid', str(profile.get_int('pid')))
return root
@ -944,7 +944,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
root = Node.void('IIDX26pc')
if newprofile is not None:
root.set_attribute('id', str(newprofile.get_int('extid')))
root.set_attribute('id', str(newprofile.extid))
return root
def handle_IIDX26pc_reg_request(self, request: Node) -> Node:
@ -955,8 +955,8 @@ class IIDXRootage(IIDXCourse, IIDXBase):
root = Node.void('IIDX26pc')
if profile is not None:
root.set_attribute('id', str(profile.get_int('extid')))
root.set_attribute('id_str', ID.format_extid(profile.get_int('extid')))
root.set_attribute('id', str(profile.extid))
root.set_attribute('id_str', ID.format_extid(profile.extid))
return root
def handle_IIDX26pc_get_request(self, request: Node) -> Node:
@ -1092,7 +1092,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
matching_class_range.add_child(Node.s32('high_arena_class', 20))
return root
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('IIDX26pc')
# Look up play stats we bridge to every mix
@ -1105,8 +1105,8 @@ class IIDXRootage(IIDXCourse, IIDXBase):
# Profile data
pcdata = Node.void('pcdata')
root.add_child(pcdata)
pcdata.set_attribute('id', str(profile.get_int('extid')))
pcdata.set_attribute('idstr', ID.format_extid(profile.get_int('extid')))
pcdata.set_attribute('id', str(profile.extid))
pcdata.set_attribute('idstr', ID.format_extid(profile.extid))
pcdata.set_attribute('name', profile.get_str('name'))
pcdata.set_attribute('pid', str(profile.get_int('pid')))
pcdata.set_attribute('spnum', str(play_stats.get_int('single_plays')))
@ -1330,8 +1330,8 @@ class IIDXRootage(IIDXCourse, IIDXBase):
rival = Node.void('rival')
rlist.add_child(rival)
rival.set_attribute('spdp', rival_type)
rival.set_attribute('id', str(other_profile.get_int('extid')))
rival.set_attribute('id_str', ID.format_extid(other_profile.get_int('extid')))
rival.set_attribute('id', str(other_profile.extid))
rival.set_attribute('id_str', ID.format_extid(other_profile.extid))
rival.set_attribute('djname', other_profile.get_str('name'))
rival.set_attribute('pid', str(other_profile.get_int('pid')))
rival.set_attribute('sg', str(self.db_to_game_rank(other_profile.get_int(self.DAN_RANKING_SINGLE, -1), self.GAME_CLTYPE_SINGLE)))
@ -1572,7 +1572,7 @@ class IIDXRootage(IIDXCourse, IIDXBase):
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
play_stats = self.get_play_statistics(userid)

View File

@ -8,7 +8,7 @@ from bemani.backend.iidx.base import IIDXBase
from bemani.backend.iidx.course import IIDXCourse
from bemani.backend.iidx.copula import IIDXCopula
from bemani.common import ValidatedDict, VersionConstants, BroadcastConstants, Time, ID, intish
from bemani.common import Profile, ValidatedDict, VersionConstants, BroadcastConstants, Time, ID, intish
from bemani.data import Data, UserID
from bemani.protocol import Node
@ -404,7 +404,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
]
totalscores: Dict[UserID, int] = {}
profiles: Dict[UserID, ValidatedDict] = {}
profiles: Dict[UserID, Profile] = {}
for songid in songids:
scores = self.data.local.music.get_all_scores(
self.game,
@ -418,7 +418,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
totalscores[score[0]] = 0
profile = self.get_any_profile(score[0])
if profile is None:
profile = ValidatedDict()
profile = Profile(self.game, self.version, "", 0)
profiles[score[0]] = profile
totalscores[score[0]] += score[1].points
@ -799,7 +799,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
data = Node.void('data')
ranklist.add_child(data)
data.set_attribute('iidx_id', str(profile.get_int('extid')))
data.set_attribute('iidx_id', str(profile.extid))
data.set_attribute('name', profile.get_str('name'))
machine_name = ''
@ -1284,7 +1284,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
if userid is not None:
profile = self.get_profile(userid)
if profile is None:
profile = ValidatedDict()
profile = Profile(self.game, self.version, "", extid)
profile.replace_int('shop_location', location)
self.put_profile(userid, profile)
@ -1321,7 +1321,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
root = Node.void('IIDX24pc')
root.set_attribute('name', profile.get_str('name'))
root.set_attribute('idstr', ID.format_extid(profile.get_int('extid')))
root.set_attribute('idstr', ID.format_extid(profile.extid))
root.set_attribute('pid', str(profile.get_int('pid')))
return root
@ -1333,7 +1333,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
root = Node.void('IIDX24pc')
if newprofile is not None:
root.set_attribute('id', str(newprofile.get_int('extid')))
root.set_attribute('id', str(newprofile.extid))
return root
def handle_IIDX24pc_reg_request(self, request: Node) -> Node:
@ -1344,8 +1344,8 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
root = Node.void('IIDX24pc')
if profile is not None:
root.set_attribute('id', str(profile.get_int('extid')))
root.set_attribute('id_str', ID.format_extid(profile.get_int('extid')))
root.set_attribute('id', str(profile.extid))
root.set_attribute('id_str', ID.format_extid(profile.extid))
return root
def handle_IIDX24pc_get_request(self, request: Node) -> Node:
@ -1441,7 +1441,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
return Node.void('IIDX24pc')
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('IIDX24pc')
# Look up play stats we bridge to every mix
@ -1454,8 +1454,8 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
# Profile data
pcdata = Node.void('pcdata')
root.add_child(pcdata)
pcdata.set_attribute('id', str(profile.get_int('extid')))
pcdata.set_attribute('idstr', ID.format_extid(profile.get_int('extid')))
pcdata.set_attribute('id', str(profile.extid))
pcdata.set_attribute('idstr', ID.format_extid(profile.extid))
pcdata.set_attribute('name', profile.get_str('name'))
pcdata.set_attribute('pid', str(profile.get_int('pid')))
pcdata.set_attribute('spnum', str(play_stats.get_int('single_plays')))
@ -1652,8 +1652,8 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
rival = Node.void('rival')
rlist.add_child(rival)
rival.set_attribute('spdp', rival_type)
rival.set_attribute('id', str(other_profile.get_int('extid')))
rival.set_attribute('id_str', ID.format_extid(other_profile.get_int('extid')))
rival.set_attribute('id', str(other_profile.extid))
rival.set_attribute('id_str', ID.format_extid(other_profile.extid))
rival.set_attribute('djname', other_profile.get_str('name'))
rival.set_attribute('pid', str(other_profile.get_int('pid')))
rival.set_attribute('sg', str(self.db_to_game_rank(other_profile.get_int(self.DAN_RANKING_SINGLE, -1), self.GAME_CLTYPE_SINGLE)))
@ -1880,7 +1880,7 @@ class IIDXSinobuz(IIDXCourse, IIDXBase):
root.add_child(Node.void('bind_eaappli'))
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
play_stats = self.get_play_statistics(userid)

View File

@ -7,7 +7,7 @@ from typing import Optional, Dict, List, Tuple, Any
from bemani.backend.iidx.base import IIDXBase
from bemani.backend.iidx.tricoro import IIDXTricoro
from bemani.common import ValidatedDict, VersionConstants, BroadcastConstants, Time, ID
from bemani.common import Profile, ValidatedDict, VersionConstants, BroadcastConstants, Time, ID
from bemani.data import Data, UserID
from bemani.protocol import Node
@ -360,7 +360,7 @@ class IIDXSpada(IIDXBase):
]
totalscores: Dict[UserID, int] = {}
profiles: Dict[UserID, ValidatedDict] = {}
profiles: Dict[UserID, Profile] = {}
for songid in songids:
scores = self.data.local.music.get_all_scores(
self.game,
@ -374,7 +374,7 @@ class IIDXSpada(IIDXBase):
totalscores[score[0]] = 0
profile = self.get_any_profile(score[0])
if profile is None:
profile = ValidatedDict()
profile = Profile(self.game, self.version, "", 0)
profiles[score[0]] = profile
totalscores[score[0]] += score[1].points
@ -627,7 +627,7 @@ class IIDXSpada(IIDXBase):
data = Node.void('data')
ranklist.add_child(data)
data.set_attribute('iidx_id', str(profile.get_int('extid')))
data.set_attribute('iidx_id', str(profile.extid))
data.set_attribute('name', profile.get_str('name'))
machine_name = ''
@ -883,7 +883,7 @@ class IIDXSpada(IIDXBase):
root = Node.void('IIDX21pc')
root.set_attribute('name', profile.get_str('name'))
root.set_attribute('idstr', ID.format_extid(profile.get_int('extid')))
root.set_attribute('idstr', ID.format_extid(profile.extid))
root.set_attribute('pid', str(profile.get_int('pid')))
return root
@ -895,7 +895,7 @@ class IIDXSpada(IIDXBase):
root = Node.void('IIDX21pc')
if newprofile is not None:
root.set_attribute('id', str(newprofile.get_int('extid')))
root.set_attribute('id', str(newprofile.extid))
return root
if method == 'reg':
@ -906,8 +906,8 @@ class IIDXSpada(IIDXBase):
root = Node.void('IIDX21pc')
if profile is not None:
root.set_attribute('id', str(profile.get_int('extid')))
root.set_attribute('id_str', ID.format_extid(profile.get_int('extid')))
root.set_attribute('id', str(profile.extid))
root.set_attribute('id_str', ID.format_extid(profile.extid))
return root
if method == 'get':
@ -942,7 +942,7 @@ class IIDXSpada(IIDXBase):
if userid is not None:
profile = self.get_profile(userid)
if profile is None:
profile = ValidatedDict()
profile = Profile(self.game, self.version, "", extid)
profile.replace_int('shop_location', location)
self.put_profile(userid, profile)
@ -1081,7 +1081,7 @@ class IIDXSpada(IIDXBase):
return Node.void('IIDX21pc')
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('IIDX21pc')
# Look up play stats we bridge to every mix
@ -1094,8 +1094,8 @@ class IIDXSpada(IIDXBase):
# Profile data
pcdata = Node.void('pcdata')
root.add_child(pcdata)
pcdata.set_attribute('id', str(profile.get_int('extid')))
pcdata.set_attribute('idstr', ID.format_extid(profile.get_int('extid')))
pcdata.set_attribute('id', str(profile.extid))
pcdata.set_attribute('idstr', ID.format_extid(profile.extid))
pcdata.set_attribute('name', profile.get_str('name'))
pcdata.set_attribute('pid', str(profile.get_int('pid')))
pcdata.set_attribute('spnum', str(play_stats.get_int('single_plays')))
@ -1287,8 +1287,8 @@ class IIDXSpada(IIDXBase):
rival = Node.void('rival')
rlist.add_child(rival)
rival.set_attribute('spdp', rival_type)
rival.set_attribute('id', str(other_profile.get_int('extid')))
rival.set_attribute('id_str', ID.format_extid(other_profile.get_int('extid')))
rival.set_attribute('id', str(other_profile.extid))
rival.set_attribute('id_str', ID.format_extid(other_profile.extid))
rival.set_attribute('djname', other_profile.get_str('name'))
rival.set_attribute('pid', str(other_profile.get_int('pid')))
rival.set_attribute('sg', str(self.db_to_game_rank(other_profile.get_int(self.DAN_RANKING_SINGLE, -1), self.GAME_CLTYPE_SINGLE)))
@ -1464,7 +1464,7 @@ class IIDXSpada(IIDXBase):
root.add_child(Node.void('bind_eaappli'))
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
play_stats = self.get_play_statistics(userid)

View File

@ -6,7 +6,7 @@ from typing import Optional, Dict, List, Tuple, Any
from bemani.backend.iidx.base import IIDXBase
from bemani.backend.iidx.stubs import IIDXLincle
from bemani.common import ValidatedDict, VersionConstants, Time, ID
from bemani.common import Profile, ValidatedDict, VersionConstants, Time, ID
from bemani.data import Data, UserID
from bemani.protocol import Node
@ -359,7 +359,7 @@ class IIDXTricoro(IIDXBase):
]
totalscores: Dict[UserID, int] = {}
profiles: Dict[UserID, ValidatedDict] = {}
profiles: Dict[UserID, Profile] = {}
for songid in songids:
scores = self.data.local.music.get_all_scores(
self.game,
@ -373,7 +373,7 @@ class IIDXTricoro(IIDXBase):
totalscores[score[0]] = 0
profile = self.get_any_profile(score[0])
if profile is None:
profile = ValidatedDict()
profile = Profile(self.game, self.version, "", 0)
profiles[score[0]] = profile
totalscores[score[0]] += score[1].points
@ -626,7 +626,7 @@ class IIDXTricoro(IIDXBase):
data = Node.void('data')
ranklist.add_child(data)
data.set_attribute('iidx_id', str(profile.get_int('extid')))
data.set_attribute('iidx_id', str(profile.extid))
data.set_attribute('name', profile.get_str('name'))
machine_name = ''
@ -870,7 +870,7 @@ class IIDXTricoro(IIDXBase):
root = Node.void('pc')
root.set_attribute('name', profile.get_str('name'))
root.set_attribute('idstr', ID.format_extid(profile.get_int('extid')))
root.set_attribute('idstr', ID.format_extid(profile.extid))
root.set_attribute('pid', str(profile.get_int('pid')))
return root
@ -882,8 +882,8 @@ class IIDXTricoro(IIDXBase):
root = Node.void('pc')
if profile is not None:
root.set_attribute('id', str(profile.get_int('extid')))
root.set_attribute('id_str', ID.format_extid(profile.get_int('extid')))
root.set_attribute('id', str(profile.extid))
root.set_attribute('id_str', ID.format_extid(profile.extid))
return root
if method == 'get':
@ -918,7 +918,7 @@ class IIDXTricoro(IIDXBase):
if userid is not None:
profile = self.get_profile(userid)
if profile is None:
profile = ValidatedDict()
profile = Profile(self.game, self.version, "", extid)
profile.replace_int('shop_location', location)
self.put_profile(userid, profile)
@ -977,7 +977,7 @@ class IIDXTricoro(IIDXBase):
# Invalid method
return None
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('pc')
# Look up play stats we bridge to every mix
@ -990,8 +990,8 @@ class IIDXTricoro(IIDXBase):
# Profile data
pcdata = Node.void('pcdata')
root.add_child(pcdata)
pcdata.set_attribute('id', str(profile.get_int('extid')))
pcdata.set_attribute('idstr', ID.format_extid(profile.get_int('extid')))
pcdata.set_attribute('id', str(profile.extid))
pcdata.set_attribute('idstr', ID.format_extid(profile.extid))
pcdata.set_attribute('name', profile.get_str('name'))
pcdata.set_attribute('pid', str(profile.get_int('pid')))
pcdata.set_attribute('spnum', str(play_stats.get_int('single_plays')))
@ -1105,8 +1105,8 @@ class IIDXTricoro(IIDXBase):
rival = Node.void('rival')
rlist.add_child(rival)
rival.set_attribute('spdp', rival_type)
rival.set_attribute('id', str(other_profile.get_int('extid')))
rival.set_attribute('id_str', ID.format_extid(other_profile.get_int('extid')))
rival.set_attribute('id', str(other_profile.extid))
rival.set_attribute('id_str', ID.format_extid(other_profile.extid))
rival.set_attribute('djname', other_profile.get_str('name'))
rival.set_attribute('pid', str(other_profile.get_int('pid')))
rival.set_attribute('sg', str(self.db_to_game_rank(other_profile.get_int(self.DAN_RANKING_SINGLE, -1), self.GAME_CLTYPE_SINGLE)))
@ -1257,7 +1257,7 @@ class IIDXTricoro(IIDXBase):
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
play_stats = self.get_play_statistics(userid)

View File

@ -3,7 +3,7 @@ from typing import Dict, List, Optional
from bemani.backend.base import Base
from bemani.backend.core import CoreHandler, CardManagerHandler, PASELIHandler
from bemani.common import DBConstants, GameConstants, ValidatedDict
from bemani.common import DBConstants, GameConstants, Profile, ValidatedDict
from bemani.data import Score, UserID
from bemani.protocol import Node
@ -43,7 +43,7 @@ class JubeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
"""
return None
def put_profile(self, userid: UserID, profile: ValidatedDict) -> None:
def put_profile(self, userid: UserID, profile: Profile) -> None:
"""
Save a new profile for this user given a game/version. Overrides but calls
the same functionality in Base, to ensure we don't save calculated values.
@ -56,21 +56,21 @@ class JubeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
del profile['has_old_version']
super().put_profile(userid, profile)
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
"""
Base handler for a profile. Given a userid and a profile dictionary,
return a Node representing a profile. Should be overridden.
"""
return Node.void('gametop')
def format_scores(self, userid: UserID, profile: ValidatedDict, scores: List[Score]) -> Node:
def format_scores(self, userid: UserID, profile: Profile, scores: List[Score]) -> Node:
"""
Base handler for a score list. Given a userid, profile and a score list,
return a Node representing a score list. Should be overridden.
"""
return Node.void('gametop')
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
"""
Base handler for profile parsing. Given a request and an old profile,
return a new profile that's been updated with the contents of the request.
@ -114,14 +114,18 @@ class JubeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
# First, create and save the default profile
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
defaultprofile = ValidatedDict({
'name': name,
})
self.put_profile(userid, defaultprofile)
profile = Profile(
self.game,
self.version,
refid,
0,
{
'name': name,
},
)
self.put_profile(userid, profile)
# Now, reload and format the profile, looking up the has old version flag
profile = self.get_profile(userid)
oldversion = self.previous_version()
oldprofile = oldversion.get_profile(userid)
profile['has_old_version'] = oldprofile is not None

View File

@ -15,7 +15,7 @@ from bemani.backend.jubeat.common import (
from bemani.backend.jubeat.qubell import JubeatQubell
from bemani.backend.base import Status
from bemani.common import Time, ValidatedDict, VersionConstants
from bemani.common import Time, Profile, ValidatedDict, VersionConstants
from bemani.data import Data, Achievement, Score, Song, UserID
from bemani.protocol import Node
@ -1102,14 +1102,14 @@ class JubeatClan(
return Node.void('gameend')
def format_scores(self, userid: UserID, profile: ValidatedDict, scores: List[Score]) -> Node:
def format_scores(self, userid: UserID, profile: Profile, scores: List[Score]) -> Node:
root = Node.void('gametop')
datanode = Node.void('data')
root.add_child(datanode)
player = Node.void('player')
datanode.add_child(player)
player.add_child(Node.s32('jid', profile.get_int('extid')))
player.add_child(Node.s32('jid', profile.extid))
playdata = Node.void('mdata_list')
player.add_child(playdata)
@ -1185,7 +1185,7 @@ class JubeatClan(
return root
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('gametop')
data = Node.void('data')
root.add_child(data)
@ -1198,7 +1198,7 @@ class JubeatClan(
# Basic profile info
player.add_child(Node.string('name', profile.get_str('name', 'なし')))
player.add_child(Node.s32('jid', profile.get_int('extid')))
player.add_child(Node.s32('jid', profile.extid))
# Miscelaneous crap
player.add_child(Node.s32('session_id', 1))
@ -1288,7 +1288,7 @@ class JubeatClan(
rival = Node.void('rival')
rivallist.add_child(rival)
rival.add_child(Node.s32('jid', rprofile.get_int('extid')))
rival.add_child(Node.s32('jid', rprofile.extid))
rival.add_child(Node.string('name', rprofile.get_str('name')))
# This looks like a carry-over from prop's career and isn't displayed.
@ -1577,7 +1577,7 @@ class JubeatClan(
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
data = request.child('data')

View File

@ -16,7 +16,7 @@ from bemani.backend.jubeat.common import (
from bemani.backend.jubeat.course import JubeatCourse
from bemani.backend.jubeat.base import JubeatBase
from bemani.backend.jubeat.saucerfulfill import JubeatSaucerFulfill
from bemani.common import ValidatedDict, VersionConstants, Time
from bemani.common import Profile, ValidatedDict, VersionConstants, Time
from bemani.data import Data, Score, UserID
from bemani.protocol import Node
@ -205,7 +205,7 @@ class JubeatProp(
return (promotions, neutrals, demotions)
@classmethod
def _get_league_scores(cls, data: Data, current_id: int, profiles: List[Tuple[UserID, ValidatedDict]]) -> Tuple[List[Tuple[UserID, int]], List[UserID]]:
def _get_league_scores(cls, data: Data, current_id: int, profiles: List[Tuple[UserID, Profile]]) -> Tuple[List[Tuple[UserID, int]], List[UserID]]:
"""
Given the current League ID (calculated based on the date range) and a list of
all user profiles for this game/version, return a uple containing two lists.
@ -681,7 +681,7 @@ class JubeatProp(
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
profile = self.get_profile(userid)
if profile is None:
profile = ValidatedDict()
profile = Profile(self.game, self.version, "", extid)
# Player scores for courses
player_list = Node.void('player_list')
@ -725,7 +725,7 @@ class JubeatProp(
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
profile = self.get_profile(userid)
if profile is None:
profile = ValidatedDict()
profile = Profile(self.game, self.version, "", extid)
gametop = Node.void('gametop')
data = Node.void('data')
@ -786,7 +786,7 @@ class JubeatProp(
return gametop
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('gametop')
data = Node.void('data')
root.add_child(data)
@ -798,7 +798,7 @@ class JubeatProp(
# Basic profile info
player.add_child(Node.string('name', profile.get_str('name', 'なし')))
player.add_child(Node.s32('jid', profile.get_int('extid')))
player.add_child(Node.s32('jid', profile.extid))
# Miscelaneous crap
player.add_child(Node.s32('session_id', 1))
@ -950,7 +950,7 @@ class JubeatProp(
rival = Node.void('rival')
rivallist.add_child(rival)
rival.add_child(Node.s32('jid', rprofile.get_int('extid')))
rival.add_child(Node.s32('jid', rprofile.extid))
rival.add_child(Node.string('name', rprofile.get_str('name')))
rcareerdict = rprofile.get_dict('career')
@ -1082,7 +1082,7 @@ class JubeatProp(
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
data = request.child('data')
@ -1339,14 +1339,14 @@ class JubeatProp(
return newprofile
def format_scores(self, userid: UserID, profile: ValidatedDict, scores: List[Score]) -> Node:
def format_scores(self, userid: UserID, profile: Profile, scores: List[Score]) -> Node:
root = Node.void('gametop')
datanode = Node.void('data')
root.add_child(datanode)
player = Node.void('player')
datanode.add_child(player)
player.add_child(Node.s32('jid', profile.get_int('extid')))
player.add_child(Node.s32('jid', profile.extid))
playdata = Node.void('mdata_list')
player.add_child(playdata)

View File

@ -15,7 +15,7 @@ from bemani.backend.jubeat.common import (
)
from bemani.backend.jubeat.prop import JubeatProp
from bemani.common import ValidatedDict, VersionConstants
from bemani.common import Profile, ValidatedDict, VersionConstants
from bemani.data import Data, Score, UserID
from bemani.protocol import Node
@ -504,7 +504,7 @@ class JubeatQubell(
return Node.void('gameend')
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('gametop')
data = Node.void('data')
root.add_child(data)
@ -520,7 +520,7 @@ class JubeatQubell(
# Basic profile info
player.add_child(Node.string('name', profile.get_str('name', 'なし')))
player.add_child(Node.s32('jid', profile.get_int('extid')))
player.add_child(Node.s32('jid', profile.extid))
# Miscelaneous crap
player.add_child(Node.s32('session_id', 1))
@ -612,7 +612,7 @@ class JubeatQubell(
rival = Node.void('rival')
rivallist.add_child(rival)
rival.add_child(Node.s32('jid', rprofile.get_int('extid')))
rival.add_child(Node.s32('jid', rprofile.extid))
rival.add_child(Node.string('name', rprofile.get_str('name')))
# This looks like a carry-over from prop's career and isn't displayed.
@ -841,14 +841,14 @@ class JubeatQubell(
return root
def format_scores(self, userid: UserID, profile: ValidatedDict, scores: List[Score]) -> Node:
def format_scores(self, userid: UserID, profile: Profile, scores: List[Score]) -> Node:
root = Node.void('gametop')
datanode = Node.void('data')
root.add_child(datanode)
player = Node.void('player')
datanode.add_child(player)
player.add_child(Node.s32('jid', profile.get_int('extid')))
player.add_child(Node.s32('jid', profile.extid))
playdata = Node.void('mdata_list')
player.add_child(playdata)
@ -919,7 +919,7 @@ class JubeatQubell(
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
data = request.child('data')

View File

@ -14,7 +14,7 @@ from bemani.backend.jubeat.common import (
JubeatLoggerReportHandler,
)
from bemani.backend.jubeat.stubs import JubeatCopiousAppend
from bemani.common import ValidatedDict, VersionConstants, Time
from bemani.common import Profile, ValidatedDict, VersionConstants, Time
from bemani.data import Data, Score, UserID
from bemani.protocol import Node
@ -162,7 +162,7 @@ class JubeatSaucer(
root.set_attribute('status', str(Status.NO_PROFILE))
return root
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('gametop')
data = Node.void('data')
root.add_child(data)
@ -287,7 +287,7 @@ class JubeatSaucer(
rival = Node.void('rival')
rivallist.add_child(rival)
rival.add_child(Node.s32('jid', rprofile.get_int('extid')))
rival.add_child(Node.s32('jid', rprofile.extid))
rival.add_child(Node.string('name', rprofile.get_str('name')))
# Lazy way of keeping track of rivals, since we can only have 4
@ -450,8 +450,8 @@ class JubeatSaucer(
# Basic profile info
player.add_child(Node.string('name', profile.get_str('name', 'なし')))
player.add_child(Node.s32('jid', profile.get_int('extid')))
player.add_child(Node.string('refid', profile.get_str('refid')))
player.add_child(Node.s32('jid', profile.extid))
player.add_child(Node.string('refid', profile.refid))
# Miscelaneous history stuff
data.add_child(Node.u8('termver', 16))
@ -517,7 +517,7 @@ class JubeatSaucer(
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
data = request.child('data')
@ -657,14 +657,14 @@ class JubeatSaucer(
return newprofile
def format_scores(self, userid: UserID, profile: ValidatedDict, scores: List[Score]) -> Node:
def format_scores(self, userid: UserID, profile: Profile, scores: List[Score]) -> Node:
root = Node.void('gametop')
datanode = Node.void('data')
root.add_child(datanode)
player = Node.void('player')
datanode.add_child(player)
player.add_child(Node.s32('jid', profile.get_int('extid')))
player.add_child(Node.s32('jid', profile.extid))
playdata = Node.void('playdata')
player.add_child(playdata)
playdata.set_attribute('count', str(len(scores)))

View File

@ -15,7 +15,7 @@ from bemani.backend.jubeat.common import (
)
from bemani.backend.jubeat.course import JubeatCourse
from bemani.backend.jubeat.saucer import JubeatSaucer
from bemani.common import ValidatedDict, VersionConstants, Time
from bemani.common import Profile, ValidatedDict, VersionConstants, Time
from bemani.data import Data, Score, UserID
from bemani.protocol import Node
@ -205,7 +205,7 @@ class JubeatSaucerFulfill(
userid = self.data.remote.user.from_extid(self.game, self.version, extid)
profile = self.get_profile(userid)
if profile is None:
profile = ValidatedDict()
profile = Profile(self.game, self.version, "", extid)
# Player scores for courses
player_list = Node.void('player_list')
@ -293,7 +293,7 @@ class JubeatSaucerFulfill(
root.set_attribute('status', str(Status.NO_PROFILE))
return root
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('gametop')
data = Node.void('data')
root.add_child(data)
@ -471,7 +471,7 @@ class JubeatSaucerFulfill(
rival = Node.void('rival')
rivallist.add_child(rival)
rival.add_child(Node.s32('jid', rprofile.get_int('extid')))
rival.add_child(Node.s32('jid', rprofile.extid))
rival.add_child(Node.string('name', rprofile.get_str('name')))
# Lazy way of keeping track of rivals, since we can only have 4
@ -538,8 +538,8 @@ class JubeatSaucerFulfill(
# Basic profile info
player.add_child(Node.string('name', profile.get_str('name', 'なし')))
player.add_child(Node.s32('jid', profile.get_int('extid')))
player.add_child(Node.string('refid', profile.get_str('refid')))
player.add_child(Node.s32('jid', profile.extid))
player.add_child(Node.string('refid', profile.refid))
# Miscelaneous history stuff
data.add_child(Node.u8('termver', 16))
@ -598,7 +598,7 @@ class JubeatSaucerFulfill(
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
data = request.child('data')
@ -754,14 +754,14 @@ class JubeatSaucerFulfill(
return newprofile
def format_scores(self, userid: UserID, profile: ValidatedDict, scores: List[Score]) -> Node:
def format_scores(self, userid: UserID, profile: Profile, scores: List[Score]) -> Node:
root = Node.void('gametop')
datanode = Node.void('data')
root.add_child(datanode)
player = Node.void('player')
datanode.add_child(player)
player.add_child(Node.s32('jid', profile.get_int('extid')))
player.add_child(Node.s32('jid', profile.extid))
playdata = Node.void('playdata')
player.add_child(playdata)
playdata.set_attribute('count', str(len(scores)))

View File

@ -3,7 +3,7 @@ from typing import Dict, Optional, Any
from bemani.backend.base import Base
from bemani.backend.core import CoreHandler, CardManagerHandler, PASELIHandler
from bemani.common import ValidatedDict, GameConstants, DBConstants, Parallel, Model
from bemani.common import Profile, ValidatedDict, GameConstants, DBConstants, Parallel, Model
from bemani.data import UserID, Data
from bemani.protocol import Node
@ -100,24 +100,27 @@ class MusecaBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
# First, create and save the default profile
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
defaultprofile = ValidatedDict({
'name': name,
'loc': locid,
})
self.put_profile(userid, defaultprofile)
# Now, reload and format the profile, looking up the has old version flag
profile = self.get_profile(userid)
profile = Profile(
self.game,
self.version,
refid,
0,
{
'name': name,
'loc': locid,
},
)
self.put_profile(userid, profile)
return self.format_profile(userid, profile)
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
"""
Base handler for a profile. Given a userid and a profile dictionary,
return a Node representing a profile. Should be overridden.
"""
return Node.void('game')
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
"""
Base handler for profile parsing. Given a request and an old profile,
return a new profile that's been updated with the contents of the request.

View File

@ -56,7 +56,7 @@ class MusecaGameHiscoreHandler(MusecaBase):
info.add_child(Node.u32('id', score.id))
info.add_child(Node.u32('type', score.chart))
info.add_child(Node.string('name', profile.get_str('name')))
info.add_child(Node.string('seq', ID.format_extid(profile.get_int('extid'))))
info.add_child(Node.string('seq', ID.format_extid(profile.extid)))
info.add_child(Node.u32('score', score.points))
# Add to global scores
@ -89,7 +89,7 @@ class MusecaGameHiscoreHandler(MusecaBase):
info.add_child(Node.u32('id', score.id))
info.add_child(Node.u32('type', score.chart))
info.add_child(Node.string('name', profile.get_str('name')))
info.add_child(Node.string('seq', ID.format_extid(profile.get_int('extid'))))
info.add_child(Node.string('seq', ID.format_extid(profile.extid)))
info.add_child(Node.u32('score', score.points))
# Add to global scores

View File

@ -12,7 +12,7 @@ from bemani.backend.museca.common import (
MusecaGameSaveMusicHandler,
MusecaGameShopHandler,
)
from bemani.common import Time, VersionConstants, ValidatedDict, ID
from bemani.common import Time, VersionConstants, Profile, ID
from bemani.data import UserID
from bemani.protocol import Node
@ -200,12 +200,12 @@ class Museca1(
return game
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
game = Node.void('game_3')
# Generic profile stuff
game.add_child(Node.string('name', profile.get_str('name')))
game.add_child(Node.string('code', ID.format_extid(profile.get_int('extid'))))
game.add_child(Node.string('code', ID.format_extid(profile.extid)))
game.add_child(Node.u32('gamecoin_packet', profile.get_int('packet')))
game.add_child(Node.u32('gamecoin_block', profile.get_int('block')))
game.add_child(Node.s16('skill_name_id', profile.get_int('skill_name_id', -1)))
@ -289,7 +289,7 @@ class Museca1(
return game
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
# Update blaster energy and in-game currencies

View File

@ -13,7 +13,7 @@ from bemani.backend.museca.common import (
MusecaGameShopHandler,
)
from bemani.backend.museca.museca1 import Museca1
from bemani.common import Time, VersionConstants, ValidatedDict, ID
from bemani.common import Time, VersionConstants, Profile, ID
from bemani.data import UserID
from bemani.protocol import Node
@ -334,12 +334,12 @@ class Museca1Plus(
return game
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
game = Node.void('game_3')
# Generic profile stuff
game.add_child(Node.string('name', profile.get_str('name')))
game.add_child(Node.string('code', ID.format_extid(profile.get_int('extid'))))
game.add_child(Node.string('code', ID.format_extid(profile.extid)))
game.add_child(Node.u32('gamecoin_packet', profile.get_int('packet')))
game.add_child(Node.u32('gamecoin_block', profile.get_int('block')))
game.add_child(Node.s16('skill_name_id', profile.get_int('skill_name_id', -1)))
@ -428,7 +428,7 @@ class Museca1Plus(
return game
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
# Update blaster energy and in-game currencies

View File

@ -3,7 +3,7 @@ from typing import Dict, Optional, Sequence
from bemani.backend.base import Base
from bemani.backend.core import CoreHandler, CardManagerHandler, PASELIHandler
from bemani.common import ValidatedDict, Time, GameConstants, DBConstants
from bemani.common import Profile, ValidatedDict, Time, GameConstants, DBConstants
from bemani.data import UserID, Achievement, ScoreSaveException
from bemani.protocol import Node
@ -48,14 +48,14 @@ class PopnMusicBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
"""
return None
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
"""
Base handler for a profile. Given a userid and a profile dictionary,
return a Node representing a profile. Should be overridden.
"""
return Node.void('playerdata')
def format_conversion(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_conversion(self, userid: UserID, profile: Profile) -> Node:
"""
Base handler for profile conversion. Given a userid and a profile
dictionary, return a node which represents the converted profile for
@ -66,7 +66,7 @@ class PopnMusicBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
"""
return Node.void('playerdata')
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
"""
Base handler for profile parsing. Given a request and an old profile,
return a new profile that's been updated with the contents of the request.
@ -137,12 +137,18 @@ class PopnMusicBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
if userid is None:
raise Exception("Logic error! Didn't find user to tie profile to!")
defaultprofile = ValidatedDict({
'name': name,
})
profile = Profile(
self.game,
self.version,
refid,
0,
{
'name': name,
},
)
if chara is not None:
defaultprofile.replace_int('chara', chara)
self.put_profile(userid, defaultprofile)
profile.replace_int('chara', chara)
self.put_profile(userid, profile)
for achievement in achievements:
self.data.local.user.put_achievement(
self.game,
@ -152,10 +158,6 @@ class PopnMusicBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
achievement.type,
achievement.data,
)
profile = self.get_profile(userid)
if profile is None:
raise Exception("Logic error! Didn't find profile after writing it!")
return self.format_profile(userid, profile)
def update_score(

View File

@ -6,7 +6,7 @@ from typing import Dict, List, Optional
from bemani.backend.popn.base import PopnMusicBase
from bemani.backend.popn.lapistoria import PopnMusicLapistoria
from bemani.common import Time, ValidatedDict, VersionConstants
from bemani.common import Time, Profile, VersionConstants
from bemani.data import UserID, Link
from bemani.protocol import Node
@ -191,7 +191,7 @@ class PopnMusicEclale(PopnMusicBase):
userid = None
if userid is not None:
oldprofile = self.get_profile(userid) or ValidatedDict()
oldprofile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
newprofile = self.unformat_profile(userid, request, oldprofile)
if newprofile is not None:
@ -236,7 +236,7 @@ class PopnMusicEclale(PopnMusicBase):
if lumina >= price:
# Update player lumina balance
profile = self.get_profile(userid) or ValidatedDict()
profile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
profile.replace_int('lumina', lumina - price)
self.put_profile(userid, profile)
@ -323,7 +323,7 @@ class PopnMusicEclale(PopnMusicBase):
# Grab the links that we care about.
links = self.data.local.user.get_links(self.game, self.version, userid)
profiles: Dict[UserID, ValidatedDict] = {}
profiles: Dict[UserID, Profile] = {}
rivals: List[Link] = []
for link in links:
if link.type != 'rival':
@ -347,7 +347,7 @@ class PopnMusicEclale(PopnMusicBase):
friend = Node.void('friend')
root.add_child(friend)
friend.add_child(Node.s16('no', no))
friend.add_child(Node.string('g_pm_id', self.format_extid(rivalprofile.get_int('extid')))) # Eclale formats on its own
friend.add_child(Node.string('g_pm_id', self.format_extid(rivalprofile.extid))) # Eclale formats on its own
friend.add_child(Node.string('name', rivalprofile.get_str('name', 'なし')))
friend.add_child(Node.s16('chara', rivalprofile.get_int('chara', -1)))
# This might be for having non-active or non-confirmed friends, but setting to 0 makes the
@ -436,7 +436,7 @@ class PopnMusicEclale(PopnMusicBase):
self.update_score(userid, songid, chart, points, medal, combo=combo, stats=stats)
return root
def format_conversion(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_conversion(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('player23')
root.add_child(Node.string('name', profile.get_str('name', 'なし')))
root.add_child(Node.s16('chara', profile.get_int('chara', -1)))
@ -488,7 +488,7 @@ class PopnMusicEclale(PopnMusicBase):
crc = abs(binascii.crc32(data.encode('ascii'))) % 10000
return f'{data}{crc:04d}'
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('player23')
# Mark this as a current profile
@ -497,7 +497,7 @@ class PopnMusicEclale(PopnMusicBase):
# Account stuff
account = Node.void('account')
root.add_child(account)
account.add_child(Node.string('g_pm_id', self.format_extid(profile.get_int('extid')))) # Eclale formats on its own
account.add_child(Node.string('g_pm_id', self.format_extid(profile.extid))) # Eclale formats on its own
account.add_child(Node.string('name', profile.get_str('name', 'なし')))
account.add_child(Node.s8('tutorial', profile.get_int('tutorial')))
account.add_child(Node.s16('area_id', profile.get_int('area_id')))
@ -695,7 +695,7 @@ class PopnMusicEclale(PopnMusicBase):
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
# Set that we've seen this profile

View File

@ -6,7 +6,7 @@ from bemani.backend.popn.base import PopnMusicBase
from bemani.backend.popn.tunestreet import PopnMusicTuneStreet
from bemani.backend.base import Status
from bemani.common import ValidatedDict, VersionConstants, Time, ID
from bemani.common import Profile, VersionConstants, Time, ID
from bemani.data import Score, Link, UserID
from bemani.protocol import Node
@ -68,14 +68,14 @@ class PopnMusicFantasia(PopnMusicBase):
}[score.chart]
return medal << (position * 4)
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('playerdata')
# Set up the base profile
base = Node.void('base')
root.add_child(base)
base.add_child(Node.string('name', profile.get_str('name', 'なし')))
base.add_child(Node.string('g_pm_id', ID.format_extid(profile.get_int('extid'))))
base.add_child(Node.string('g_pm_id', ID.format_extid(profile.extid)))
base.add_child(Node.u8('mode', profile.get_int('mode', 0)))
base.add_child(Node.s8('button', profile.get_int('button', 0)))
base.add_child(Node.s8('last_play_flag', profile.get_int('last_play_flag', -1)))
@ -239,7 +239,7 @@ class PopnMusicFantasia(PopnMusicBase):
return root
def format_conversion(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_conversion(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('playerdata')
root.add_child(Node.string('name', profile.get_str('name', 'なし')))
@ -271,7 +271,7 @@ class PopnMusicFantasia(PopnMusicBase):
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
# For some reason, Pop'n 20 sends us two profile saves, one with 'not done yet'
# so we only want to process the done yet node. The 'not gameover' save has
# jubeat collabo stuff set in it, but we don't use that so it doesn't matter.
@ -422,7 +422,7 @@ class PopnMusicFantasia(PopnMusicBase):
if userid is None:
return root
oldprofile = self.get_profile(userid) or ValidatedDict()
oldprofile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
newprofile = self.unformat_profile(userid, request, oldprofile)
if newprofile is not None:
@ -443,7 +443,7 @@ class PopnMusicFantasia(PopnMusicBase):
# Grab the links that we care about.
links = self.data.local.user.get_links(self.game, self.version, userid)
profiles: Dict[UserID, ValidatedDict] = {}
profiles: Dict[UserID, Profile] = {}
rivals: List[Link] = []
for link in links:
if link.type != 'rival':
@ -470,7 +470,7 @@ class PopnMusicFantasia(PopnMusicBase):
# Set up some sane defaults.
friend.add_child(Node.string('name', rivalprofile.get_str('name', 'なし')))
friend.add_child(Node.string('g_pm_id', ID.format_extid(rivalprofile.get_int('extid'))))
friend.add_child(Node.string('g_pm_id', ID.format_extid(rivalprofile.extid)))
friend.add_child(Node.s16('chara', rivalprofile.get_int('chara', -1)))
# Perform hiscore/medal conversion.

View File

@ -6,7 +6,7 @@ from bemani.backend.popn.base import PopnMusicBase
from bemani.backend.popn.sunnypark import PopnMusicSunnyPark
from bemani.backend.base import Status
from bemani.common import ValidatedDict, VersionConstants, Time, ID
from bemani.common import Profile, VersionConstants, Time, ID
from bemani.data import UserID, Link
from bemani.protocol import Node
@ -168,7 +168,7 @@ class PopnMusicLapistoria(PopnMusicBase):
if userid is None:
return root
oldprofile = self.get_profile(userid) or ValidatedDict()
oldprofile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
newprofile = self.unformat_profile(userid, request, oldprofile)
if newprofile is not None:
@ -193,7 +193,7 @@ class PopnMusicLapistoria(PopnMusicBase):
# Grab the links that we care about.
links = self.data.local.user.get_links(self.game, self.version, userid)
profiles: Dict[UserID, ValidatedDict] = {}
profiles: Dict[UserID, Profile] = {}
rivals: List[Link] = []
for link in links:
if link.type != 'rival':
@ -217,7 +217,7 @@ class PopnMusicLapistoria(PopnMusicBase):
friend = Node.void('friend')
root.add_child(friend)
friend.add_child(Node.s16('no', no))
friend.add_child(Node.string('g_pm_id', ID.format_extid(rivalprofile.get_int('extid'))))
friend.add_child(Node.string('g_pm_id', ID.format_extid(rivalprofile.extid)))
friend.add_child(Node.string('name', rivalprofile.get_str('name', 'なし')))
friend.add_child(Node.s16('chara', rivalprofile.get_int('chara', -1)))
# This might be for having non-active or non-confirmed friends, but setting to 0 makes the
@ -319,7 +319,7 @@ class PopnMusicLapistoria(PopnMusicBase):
# Invalid method
return None
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('player22')
# Result
@ -329,7 +329,7 @@ class PopnMusicLapistoria(PopnMusicBase):
account = Node.void('account')
root.add_child(account)
account.add_child(Node.string('name', profile.get_str('name', 'なし')))
account.add_child(Node.string('g_pm_id', ID.format_extid(profile.get_int('extid'))))
account.add_child(Node.string('g_pm_id', ID.format_extid(profile.extid)))
account.add_child(Node.s8('tutorial', profile.get_int('tutorial', -1)))
account.add_child(Node.s16('read_news', profile.get_int('read_news', 0)))
account.add_child(Node.s8('staff', 0))
@ -548,7 +548,7 @@ class PopnMusicLapistoria(PopnMusicBase):
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
account = request.child('account')
@ -687,7 +687,7 @@ class PopnMusicLapistoria(PopnMusicBase):
return newprofile
def format_conversion(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_conversion(self, userid: UserID, profile: Profile) -> Node:
# Circular import, ugh
from bemani.backend.popn.eclale import PopnMusicEclale

View File

@ -6,7 +6,7 @@ from bemani.backend.popn.base import PopnMusicBase
from bemani.backend.popn.fantasia import PopnMusicFantasia
from bemani.backend.base import Status
from bemani.common import ValidatedDict, VersionConstants, Time, ID
from bemani.common import Profile, VersionConstants, Time, ID
from bemani.data import UserID, Link
from bemani.protocol import Node
@ -46,14 +46,14 @@ class PopnMusicSunnyPark(PopnMusicBase):
def previous_version(self) -> Optional[PopnMusicBase]:
return PopnMusicFantasia(self.data, self.config, self.model)
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('playerdata')
# Set up the base profile
base = Node.void('base')
root.add_child(base)
base.add_child(Node.string('name', profile.get_str('name', 'なし')))
base.add_child(Node.string('g_pm_id', ID.format_extid(profile.get_int('extid'))))
base.add_child(Node.string('g_pm_id', ID.format_extid(profile.extid)))
base.add_child(Node.u8('mode', profile.get_int('mode', 0)))
base.add_child(Node.s8('button', profile.get_int('button', 0)))
base.add_child(Node.s8('last_play_flag', profile.get_int('last_play_flag', -1)))
@ -292,7 +292,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
return root
def format_conversion(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_conversion(self, userid: UserID, profile: Profile) -> Node:
# Circular import, ugh
from bemani.backend.popn.lapistoria import PopnMusicLapistoria
@ -349,7 +349,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
newprofile.replace_int('option', request.child_value('option'))
newprofile.replace_int('chara', request.child_value('chara'))
@ -535,7 +535,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
if userid is None:
return root
oldprofile = self.get_profile(userid) or ValidatedDict()
oldprofile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
newprofile = self.unformat_profile(userid, request, oldprofile)
if newprofile is not None:
@ -556,7 +556,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
# Grab the links that we care about.
links = self.data.local.user.get_links(self.game, self.version, userid)
profiles: Dict[UserID, ValidatedDict] = {}
profiles: Dict[UserID, Profile] = {}
rivals: List[Link] = []
for link in links:
if link.type != 'rival':
@ -583,7 +583,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
# Set up some sane defaults.
friend.add_child(Node.string('name', rivalprofile.get_str('name', 'なし')))
friend.add_child(Node.string('g_pm_id', ID.format_extid(rivalprofile.get_int('extid'))))
friend.add_child(Node.string('g_pm_id', ID.format_extid(rivalprofile.extid)))
friend.add_child(Node.s16('chara', rivalprofile.get_int('chara', -1)))
# Set up player avatar.
@ -611,7 +611,7 @@ class PopnMusicSunnyPark(PopnMusicBase):
]:
continue
points = score.points + rivalprofile.get_int('extid') % 100
points = score.points
medal = {
self.PLAY_MEDAL_CIRCLE_FAILED: self.GAME_PLAY_MEDAL_CIRCLE_FAILED,
self.PLAY_MEDAL_DIAMOND_FAILED: self.GAME_PLAY_MEDAL_DIAMOND_FAILED,

View File

@ -6,7 +6,7 @@ from bemani.backend.popn.base import PopnMusicBase
from bemani.backend.popn.stubs import PopnMusicSengokuRetsuden
from bemani.backend.base import Status
from bemani.common import ValidatedDict, VersionConstants
from bemani.common import Profile, VersionConstants
from bemani.data import Score, UserID
from bemani.protocol import Node
@ -100,7 +100,7 @@ class PopnMusicTuneStreet(PopnMusicBase):
}[score.data.get_int('medal')]
return (flags << shift) | playedflag
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('playerdata')
# Format profile
@ -202,7 +202,7 @@ class PopnMusicTuneStreet(PopnMusicBase):
return root
def format_conversion(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_conversion(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('playerdata')
root.add_child(Node.string('name', profile.get_str('name', 'なし')))
@ -230,7 +230,7 @@ class PopnMusicTuneStreet(PopnMusicBase):
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
# Extract the playmode, important for scores later
@ -392,7 +392,7 @@ class PopnMusicTuneStreet(PopnMusicBase):
if userid is None:
return root
oldprofile = self.get_profile(userid) or ValidatedDict()
oldprofile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
newprofile = self.unformat_profile(userid, request, oldprofile)
if newprofile is not None:

View File

@ -6,7 +6,7 @@ from typing import Any, Dict, List, Optional, Tuple
from bemani.backend.popn.base import PopnMusicBase
from bemani.backend.popn.eclale import PopnMusicEclale
from bemani.common import Time, ID, ValidatedDict, VersionConstants, Parallel
from bemani.common import Time, ID, Profile, ValidatedDict, VersionConstants, Parallel
from bemani.data import Data, UserID, Achievement, Link
from bemani.protocol import Node
@ -205,7 +205,7 @@ class PopnMusicUsaNeko(PopnMusicBase):
)
# Cache of userID to profile
userid_to_profile: Dict[UserID, ValidatedDict] = {uid: profile for (uid, profile) in profiles}
userid_to_profile: Dict[UserID, Profile] = {uid: profile for (uid, profile) in profiles}
# Course ranking info for the last 256 courses
for course_info in course_infos[:256]:
@ -224,7 +224,7 @@ class PopnMusicUsaNeko(PopnMusicBase):
chart_rankings = course_rankings.get(name, [])
for pos, (uid, ach) in enumerate(chart_rankings[:20]):
profile = userid_to_profile.get(uid, ValidatedDict())
profile = userid_to_profile.get(uid, Profile(self.game, self.version, "", 0))
subnode = Node.void(name)
ranking_info.add_child(subnode)
@ -395,7 +395,7 @@ class PopnMusicUsaNeko(PopnMusicBase):
userid = None
if userid is not None:
oldprofile = self.get_profile(userid) or ValidatedDict()
oldprofile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
newprofile = self.unformat_profile(userid, request, oldprofile)
if newprofile is not None:
@ -453,7 +453,7 @@ class PopnMusicUsaNeko(PopnMusicBase):
# Handle fetching all scores
uids_and_courses, profile = Parallel.execute([
lambda: self.data.local.user.get_all_achievements(self.game, self.version),
lambda: self.get_profile(userid) or ValidatedDict()
lambda: self.get_profile(userid) or Profile(self.game, self.version, "", 0)
])
# Grab a sorted list of all scores for this course and chart
@ -513,7 +513,7 @@ class PopnMusicUsaNeko(PopnMusicBase):
# Grab the links that we care about.
links = self.data.local.user.get_links(self.game, self.version, userid)
profiles: Dict[UserID, ValidatedDict] = {}
profiles: Dict[UserID, Profile] = {}
rivals: List[Link] = []
for link in links:
if link.type != 'rival':
@ -537,7 +537,7 @@ class PopnMusicUsaNeko(PopnMusicBase):
friend = Node.void('friend')
root.add_child(friend)
friend.add_child(Node.s16('no', no))
friend.add_child(Node.string('g_pm_id', self.format_extid(rivalprofile.get_int('extid')))) # UsaNeko formats on its own
friend.add_child(Node.string('g_pm_id', self.format_extid(rivalprofile.extid))) # UsaNeko formats on its own
friend.add_child(Node.string('name', rivalprofile.get_str('name', 'なし')))
friend.add_child(Node.s16('chara', rivalprofile.get_int('chara', -1)))
# This might be for having non-active or non-confirmed friends, but setting to 0 makes the
@ -714,7 +714,7 @@ class PopnMusicUsaNeko(PopnMusicBase):
if lumina >= price:
# Update player lumina balance
profile = self.get_profile(userid) or ValidatedDict()
profile = self.get_profile(userid) or Profile(self.game, self.version, refid, 0)
profile.replace_int('player_point', lumina - price)
self.put_profile(userid, profile)
@ -733,7 +733,7 @@ class PopnMusicUsaNeko(PopnMusicBase):
return Node.void('player24')
def format_conversion(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_conversion(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('player24')
root.add_child(Node.string('name', profile.get_str('name', 'なし')))
root.add_child(Node.s16('chara', profile.get_int('chara', -1)))
@ -785,7 +785,7 @@ class PopnMusicUsaNeko(PopnMusicBase):
crc = abs(binascii.crc32(data.encode('ascii'))) % 10000
return f'{data}{crc:04d}'
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
root = Node.void('player24')
# Mark this as a current profile
@ -794,7 +794,7 @@ class PopnMusicUsaNeko(PopnMusicBase):
# Basic account info
account = Node.void('account')
root.add_child(account)
account.add_child(Node.string('g_pm_id', self.format_extid(profile.get_int('extid'))))
account.add_child(Node.string('g_pm_id', self.format_extid(profile.extid)))
account.add_child(Node.string('name', profile.get_str('name', 'なし')))
account.add_child(Node.s16('tutorial', profile.get_int('tutorial')))
account.add_child(Node.s16('area_id', profile.get_int('area_id')))
@ -1124,7 +1124,7 @@ class PopnMusicUsaNeko(PopnMusicBase):
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
# Set that we've seen this profile

View File

@ -3,7 +3,7 @@ from typing import Dict, List, Optional
from bemani.backend.base import Base
from bemani.backend.core import CoreHandler, CardManagerHandler, PASELIHandler
from bemani.common import ValidatedDict, GameConstants, DBConstants, Time
from bemani.common import Profile, ValidatedDict, GameConstants, DBConstants, Time
from bemani.data import Machine, ScoreSaveException, UserID
from bemani.protocol import Node
@ -51,14 +51,14 @@ class ReflecBeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
'lobby2',
]
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
"""
Base handler for a profile. Given a userid and a profile dictionary,
return a Node representing a profile. Should be overridden.
"""
return Node.void('pc')
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
"""
Base handler for profile parsing. Given a request and an old profile,
return a new profile that's been updated with the contents of the request.
@ -86,7 +86,7 @@ class ReflecBeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
return None
return self.format_profile(userid, profile)
def put_profile_by_refid(self, refid: Optional[str], request: Node) -> Optional[ValidatedDict]:
def put_profile_by_refid(self, refid: Optional[str], request: Node) -> Optional[Profile]:
"""
Given a RefID and a request node, unformat the profile and save it.
"""
@ -97,8 +97,8 @@ class ReflecBeatBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
oldprofile = self.get_profile(userid)
if oldprofile is None:
# Create one so we can get refid/extid
self.put_profile(userid, ValidatedDict())
oldprofile = self.get_profile(userid)
oldprofile = Profile(self.game, self.version, refid, 0)
self.put_profile(userid, oldprofile)
newprofile = self.unformat_profile(userid, request, oldprofile)
if newprofile is not None:
self.put_profile(userid, newprofile)

View File

@ -4,7 +4,7 @@ from typing import Optional, Dict, List, Tuple, Any
from bemani.backend.reflec.base import ReflecBeatBase
from bemani.backend.reflec.limelight import ReflecBeatLimelight
from bemani.common import ValidatedDict, VersionConstants, ID, Time
from bemani.common import Profile, ValidatedDict, VersionConstants, ID, Time
from bemani.data import UserID, Achievement
from bemani.protocol import Node
@ -234,13 +234,19 @@ class ReflecBeatColette(ReflecBeatBase):
}
# Handle anonymous comments by returning a default profile
uid_mapping[UserID(0)] = ValidatedDict({'name': '', 'extid': 0})
uid_mapping[UserID(0)] = Profile(
self.game,
self.version,
"",
0,
{'name': ''},
)
def add_comments(name: str, selected: List[Tuple[UserID, Achievement]]) -> None:
for (uid, ach) in selected:
cmnt = Node.void(name)
root.add_child(cmnt)
cmnt.add_child(Node.s32('uid', uid_mapping[uid].get_int('extid')))
cmnt.add_child(Node.s32('uid', uid_mapping[uid].extid))
cmnt.add_child(Node.string('name', uid_mapping[uid].get_str('name')))
cmnt.add_child(Node.s16('icon', ach.data.get_int('icon')))
cmnt.add_child(Node.s8('bln', ach.data.get_int('bln')))
@ -387,7 +393,7 @@ class ReflecBeatColette(ReflecBeatBase):
e.add_child(Node.s32('eid', lobby.get_int('id')))
e.add_child(Node.u16('mid', lobby.get_int('mid')))
e.add_child(Node.u8('ng', lobby.get_int('ng')))
e.add_child(Node.s32('uid', profile.get_int('extid')))
e.add_child(Node.s32('uid', profile.extid))
e.add_child(Node.s32('uattr', profile.get_int('uattr')))
e.add_child(Node.string('pn', profile.get_str('name')))
e.add_child(Node.s16('mg', profile.get_int('mg')))
@ -442,7 +448,7 @@ class ReflecBeatColette(ReflecBeatBase):
e.add_child(Node.s32('eid', lobby.get_int('id')))
e.add_child(Node.u16('mid', lobby.get_int('mid')))
e.add_child(Node.u8('ng', lobby.get_int('ng')))
e.add_child(Node.s32('uid', profile.get_int('extid')))
e.add_child(Node.s32('uid', profile.extid))
e.add_child(Node.s32('uattr', profile.get_int('uattr')))
e.add_child(Node.string('pn', profile.get_str('name')))
e.add_child(Node.s16('mg', profile.get_int('mg')))
@ -686,10 +692,10 @@ class ReflecBeatColette(ReflecBeatBase):
if profile is None:
root.add_child(Node.s32('uid', 0))
else:
root.add_child(Node.s32('uid', profile.get_int('extid')))
root.add_child(Node.s32('uid', profile.extid))
return root
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
statistics = self.get_play_statistics(userid)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
@ -713,7 +719,7 @@ class ReflecBeatColette(ReflecBeatBase):
account = Node.void('account')
pdata.add_child(account)
account.add_child(Node.s32('usrid', profile.get_int('extid')))
account.add_child(Node.s32('usrid', profile.extid))
account.add_child(Node.s32('tpc', statistics.get_int('total_plays', 0)))
account.add_child(Node.s32('dpc', today_count))
account.add_child(Node.s32('crd', 1))
@ -755,7 +761,7 @@ class ReflecBeatColette(ReflecBeatBase):
r = Node.void('r')
rival.add_child(r)
r.add_child(Node.s32('slot_id', slotid))
r.add_child(Node.s32('id', rprofile.get_int('extid')))
r.add_child(Node.s32('id', rprofile.extid))
r.add_child(Node.string('name', rprofile.get_str('name')))
r.add_child(Node.bool('friend', True))
r.add_child(Node.bool('locked', False))
@ -945,7 +951,7 @@ class ReflecBeatColette(ReflecBeatBase):
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
game_config = self.get_game_config()
newprofile = copy.deepcopy(oldprofile)

View File

@ -4,7 +4,7 @@ from typing import Optional, Dict, Any, List, Tuple
from bemani.backend.reflec.base import ReflecBeatBase
from bemani.backend.reflec.colette import ReflecBeatColette
from bemani.common import ValidatedDict, VersionConstants, ID, Time
from bemani.common import Profile, ValidatedDict, VersionConstants, ID, Time
from bemani.data import Achievement, Attempt, Score, UserID
from bemani.protocol import Node
@ -168,7 +168,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
e.add_child(Node.s32('eid', lobby.get_int('id')))
e.add_child(Node.u16('mid', lobby.get_int('mid')))
e.add_child(Node.u8('ng', lobby.get_int('ng')))
e.add_child(Node.s32('uid', profile.get_int('extid')))
e.add_child(Node.s32('uid', profile.extid))
e.add_child(Node.s32('uattr', profile.get_int('uattr')))
e.add_child(Node.string('pn', profile.get_str('name')))
e.add_child(Node.s32('plyid', info.get_int('id')))
@ -223,7 +223,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
e.add_child(Node.s32('eid', lobby.get_int('id')))
e.add_child(Node.u16('mid', lobby.get_int('mid')))
e.add_child(Node.u8('ng', lobby.get_int('ng')))
e.add_child(Node.s32('uid', profile.get_int('extid')))
e.add_child(Node.s32('uid', profile.extid))
e.add_child(Node.s32('uattr', profile.get_int('uattr')))
e.add_child(Node.string('pn', profile.get_str('name')))
e.add_child(Node.s32('plyid', info.get_int('id')))
@ -349,7 +349,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
data = Node.void('data')
rootnode.add_child(data)
data.add_child(Node.s16('day_id', int((Time.now() - timeoffset) / Time.SECONDS_IN_DAY)))
data.add_child(Node.s32('user_id', profile.get_int('extid')))
data.add_child(Node.s32('user_id', profile.extid))
data.add_child(Node.s16('icon_id', profile.get_dict('config').get_int('icon_id')))
data.add_child(Node.s16('point', min(points_by_user.get(userid, 0), 32767)))
data.add_child(Node.s32('update_time', Time.now()))
@ -421,7 +421,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
root.add_child(shop_score)
shop_score.add_child(Node.s32('time', Time.now()))
profiles: Dict[UserID, ValidatedDict] = {}
profiles: Dict[UserID, Profile] = {}
for songid in range(start_music_id, end_music_id + 1):
allscores = self.data.local.music.get_all_scores(
self.game,
@ -453,7 +453,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
data.add_child(Node.s16('music_id', songid))
data.add_child(Node.s8('note_grade', score.chart))
data.add_child(Node.s8('clear_type', self.__db_to_game_clear_type(score.data.get_int('clear_type'))))
data.add_child(Node.s32('user_id', profile.get_int('extid')))
data.add_child(Node.s32('user_id', profile.extid))
data.add_child(Node.s16('icon_id', profile.get_dict('config').get_int('icon_id')))
data.add_child(Node.s32('score', score.points))
data.add_child(Node.s32('time', score.timestamp))
@ -499,13 +499,19 @@ class ReflecBeatGroovin(ReflecBeatBase):
}
# Handle anonymous comments by returning a default profile
uid_mapping[UserID(0)] = ValidatedDict({'name': '', 'extid': 0})
uid_mapping[UserID(0)] = Profile(
self.game,
self.version,
"",
0,
{'name': ''},
)
def add_comments(name: str, selected: List[Tuple[UserID, Achievement]]) -> None:
for (uid, ach) in selected:
cmnt = Node.void(name)
root.add_child(cmnt)
cmnt.add_child(Node.s32('uid', uid_mapping[uid].get_int('extid')))
cmnt.add_child(Node.s32('uid', uid_mapping[uid].extid))
cmnt.add_child(Node.string('name', uid_mapping[uid].get_str('name')))
cmnt.add_child(Node.s16('icon', ach.data.get_int('icon')))
cmnt.add_child(Node.s8('bln', ach.data.get_int('bln')))
@ -909,10 +915,10 @@ class ReflecBeatGroovin(ReflecBeatBase):
if profile is None:
root.add_child(Node.s32('uid', 0))
else:
root.add_child(Node.s32('uid', profile.get_int('extid')))
root.add_child(Node.s32('uid', profile.extid))
return root
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
statistics = self.get_play_statistics(userid)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
@ -936,7 +942,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
# Account info
account = Node.void('account')
pdata.add_child(account)
account.add_child(Node.s32('usrid', profile.get_int('extid')))
account.add_child(Node.s32('usrid', profile.extid))
account.add_child(Node.s32('tpc', statistics.get_int('total_plays', 0)))
account.add_child(Node.s32('dpc', today_count))
account.add_child(Node.s32('crd', 1))
@ -995,7 +1001,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
r = Node.void('r')
rival.add_child(r)
r.add_child(Node.s32('slot_id', slotid))
r.add_child(Node.s32('id', rprofile.get_int('extid')))
r.add_child(Node.s32('id', rprofile.extid))
r.add_child(Node.string('name', rprofile.get_str('name')))
r.add_child(Node.s32('icon', profile.get_dict('config').get_int('icon_id')))
r.add_child(Node.s32('m_level', profile.get_int('mg')))
@ -1211,7 +1217,7 @@ class ReflecBeatGroovin(ReflecBeatBase):
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
game_config = self.get_game_config()
newprofile = copy.deepcopy(oldprofile)
@ -1375,8 +1381,8 @@ class ReflecBeatGroovin(ReflecBeatBase):
# I assume this is copypasta, but I want to be sure
extid = child.child_value('user_id')
if extid != newprofile.get_int('extid'):
raise Exception(f'Unexpected user ID, got {extid} expecting {newprofile.get_int("extid")}')
if extid != newprofile.extid:
raise Exception(f'Unexpected user ID, got {extid} expecting {newprofile.extid}')
episode_type = child.child_value('type')
episode_value0 = child.child_value('value0')

View File

@ -4,7 +4,7 @@ from typing import Optional, Dict, Any, Tuple
from bemani.backend.reflec.base import ReflecBeatBase
from bemani.backend.reflec.reflecbeat import ReflecBeat
from bemani.common import ValidatedDict, VersionConstants, ID, Time
from bemani.common import Profile, VersionConstants, ID, Time
from bemani.data import UserID
from bemani.protocol import Node
@ -215,7 +215,7 @@ class ReflecBeatLimelight(ReflecBeatBase):
c = Node.void('c')
commentnode.add_child(c)
c.add_child(Node.s32('uid', uid_mapping[uid].get_int('extid')))
c.add_child(Node.s32('uid', uid_mapping[uid].extid))
c.add_child(Node.string('p_name', uid_mapping[uid].get_str('name')))
c.add_child(Node.s32('exp', uid_mapping[uid].get_int('exp')))
c.add_child(Node.s32('customize', comment.data.get_int('customize')))
@ -241,7 +241,7 @@ class ReflecBeatLimelight(ReflecBeatBase):
s = Node.void('s')
statusnode.add_child(s)
s.add_child(Node.s32('uid', uid_mapping[uid].get_int('extid')))
s.add_child(Node.s32('uid', uid_mapping[uid].extid))
s.add_child(Node.string('p_name', uid_mapping[uid].get_str('name')))
s.add_child(Node.s32('exp', uid_mapping[uid].get_int('exp')))
s.add_child(Node.s32('customize', status.get_int('customize')))
@ -365,7 +365,7 @@ class ReflecBeatLimelight(ReflecBeatBase):
e.add_child(Node.s32('eid', lobby.get_int('id')))
e.add_child(Node.u16('mid', lobby.get_int('mid')))
e.add_child(Node.u8('ng', lobby.get_int('ng')))
e.add_child(Node.s32('uid', profile.get_int('extid')))
e.add_child(Node.s32('uid', profile.extid))
e.add_child(Node.string('pn', profile.get_str('name')))
e.add_child(Node.s32('uattr', profile.get_int('uattr')))
e.add_child(Node.s32('mopt', lobby.get_int('mopt')))
@ -415,7 +415,7 @@ class ReflecBeatLimelight(ReflecBeatBase):
e.add_child(Node.s32('eid', lobby.get_int('id')))
e.add_child(Node.u16('mid', lobby.get_int('mid')))
e.add_child(Node.u8('ng', lobby.get_int('ng')))
e.add_child(Node.s32('uid', profile.get_int('extid')))
e.add_child(Node.s32('uid', profile.extid))
e.add_child(Node.string('pn', profile.get_str('name')))
e.add_child(Node.s32('uattr', profile.get_int('uattr')))
e.add_child(Node.s32('mopt', lobby.get_int('mopt')))
@ -537,11 +537,11 @@ class ReflecBeatLimelight(ReflecBeatBase):
if profile is None:
root.add_child(Node.s32('uid', 0))
else:
root.add_child(Node.s32('uid', profile.get_int('extid')))
root.add_child(Node.s32('uid', profile.extid))
root.add_child(Node.s32('time', Time.now()))
return root
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
statistics = self.get_play_statistics(userid)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
@ -553,7 +553,7 @@ class ReflecBeatLimelight(ReflecBeatBase):
base = Node.void('base')
pdata.add_child(base)
base.add_child(Node.s32('uid', profile.get_int('extid')))
base.add_child(Node.s32('uid', profile.extid))
base.add_child(Node.string('name', profile.get_str('name')))
base.add_child(Node.s16('icon_id', profile.get_int('icon')))
base.add_child(Node.s16('lv', profile.get_int('lvl')))
@ -709,7 +709,7 @@ class ReflecBeatLimelight(ReflecBeatBase):
rival.add_child(r)
r.add_child(Node.u8('slot_id', slotid))
r.add_child(Node.string('name', rprofile.get_str('name')))
r.add_child(Node.s32('id', rprofile.get_int('extid')))
r.add_child(Node.s32('id', rprofile.extid))
r.add_child(Node.bool('friend', True))
r.add_child(Node.bool('locked', False))
r.add_child(Node.s32('rc', 0))
@ -747,7 +747,7 @@ class ReflecBeatLimelight(ReflecBeatBase):
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
game_config = self.get_game_config()
newprofile = copy.deepcopy(oldprofile)

View File

@ -3,7 +3,7 @@ from typing import Any, Dict, Tuple
from bemani.backend.reflec.base import ReflecBeatBase
from bemani.common import ValidatedDict, VersionConstants, ID, Time
from bemani.common import Profile, VersionConstants, ID, Time
from bemani.data import UserID
from bemani.protocol import Node
@ -178,7 +178,7 @@ class ReflecBeat(ReflecBeatBase):
e.add_child(Node.s32('eid', lobby.get_int('id')))
e.add_child(Node.u16('mid', lobby.get_int('mid')))
e.add_child(Node.u8('ng', lobby.get_int('ng')))
e.add_child(Node.s32('uid', profile.get_int('extid')))
e.add_child(Node.s32('uid', profile.extid))
e.add_child(Node.string('pn', profile.get_str('name')))
e.add_child(Node.s32('exp', profile.get_int('exp')))
e.add_child(Node.u8('mg', profile.get_int('mg')))
@ -221,7 +221,7 @@ class ReflecBeat(ReflecBeatBase):
e.add_child(Node.s32('eid', lobby.get_int('id')))
e.add_child(Node.u16('mid', lobby.get_int('mid')))
e.add_child(Node.u8('ng', lobby.get_int('ng')))
e.add_child(Node.s32('uid', profile.get_int('extid')))
e.add_child(Node.s32('uid', profile.extid))
e.add_child(Node.string('pn', profile.get_str('name')))
e.add_child(Node.s32('exp', profile.get_int('exp')))
e.add_child(Node.u8('mg', profile.get_int('mg')))
@ -298,11 +298,11 @@ class ReflecBeat(ReflecBeatBase):
if profile is None:
root.add_child(Node.s32('uid', 0))
else:
root.add_child(Node.s32('uid', profile.get_int('extid')))
root.add_child(Node.s32('uid', profile.extid))
root.add_child(Node.s32('time', Time.now()))
return root
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
statistics = self.get_play_statistics(userid)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
@ -313,7 +313,7 @@ class ReflecBeat(ReflecBeatBase):
base = Node.void('base')
pdata.add_child(base)
base.add_child(Node.s32('uid', profile.get_int('extid')))
base.add_child(Node.s32('uid', profile.extid))
base.add_child(Node.string('name', profile.get_str('name')))
base.add_child(Node.s16('lv', profile.get_int('lvl')))
base.add_child(Node.s32('exp', profile.get_int('exp')))
@ -408,7 +408,7 @@ class ReflecBeat(ReflecBeatBase):
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
game_config = self.get_game_config()
newprofile = copy.deepcopy(oldprofile)

View File

@ -5,7 +5,7 @@ from bemani.backend.reflec.base import ReflecBeatBase
from bemani.backend.reflec.volzzabase import ReflecBeatVolzzaBase
from bemani.backend.reflec.groovin import ReflecBeatGroovin
from bemani.common import ValidatedDict, VersionConstants, ID, Time
from bemani.common import Profile, ValidatedDict, VersionConstants, ID, Time
from bemani.data import Score, UserID
from bemani.protocol import Node
@ -139,7 +139,7 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
rl = Node.void('rl')
rival_data.add_child(rl)
rl.add_child(Node.s32('uid', rprofile.get_int('extid')))
rl.add_child(Node.s32('uid', rprofile.extid))
rl.add_child(Node.string('nm', rprofile.get_str('name')))
rl.add_child(Node.s16('ic', rprofile.get_dict('config').get_int('icon_id')))
@ -236,7 +236,7 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
)
minigame_scores = sorted(
[
all_profiles.get(userid, ValidatedDict()).get_int('mgsc')
all_profiles.get(userid, Profile(self.game, self.version, "", 0)).get_int('mgsc')
for userid in all_users
],
reverse=True,
@ -298,10 +298,10 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
if profile is None:
root.add_child(Node.s32('uid', 0))
else:
root.add_child(Node.s32('uid', profile.get_int('extid')))
root.add_child(Node.s32('uid', profile.extid))
return root
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
statistics = self.get_play_statistics(userid)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
@ -332,7 +332,7 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
# Account info
account = Node.void('account')
pdata.add_child(account)
account.add_child(Node.s32('usrid', profile.get_int('extid')))
account.add_child(Node.s32('usrid', profile.extid))
account.add_child(Node.s32('tpc', statistics.get_int('total_plays', 0)))
account.add_child(Node.s32('dpc', today_count))
account.add_child(Node.s32('crd', 1))
@ -380,7 +380,7 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
r = Node.void('r')
rival.add_child(r)
r.add_child(Node.s32('slot_id', slotid))
r.add_child(Node.s32('id', rprofile.get_int('extid')))
r.add_child(Node.s32('id', rprofile.extid))
r.add_child(Node.string('name', rprofile.get_str('name')))
r.add_child(Node.s32('icon', rprofile.get_dict('config').get_int('icon_id')))
r.add_child(Node.s32('class', rprofile.get_int('class')))
@ -554,7 +554,7 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
game_config = self.get_game_config()
newprofile = copy.deepcopy(oldprofile)
@ -652,8 +652,8 @@ class ReflecBeatVolzza(ReflecBeatVolzzaBase):
# I assume this is copypasta, but I want to be sure
extid = child.child_value('user_id')
if extid != newprofile.get_int('extid'):
raise Exception(f'Unexpected user ID, got {extid} expecting {newprofile.get_int("extid")}')
if extid != newprofile.extid:
raise Exception(f'Unexpected user ID, got {extid} expecting {newprofile.extid}')
episode_type = child.child_value('type')
episode_value0 = child.child_value('value0')

View File

@ -5,7 +5,7 @@ from bemani.backend.reflec.base import ReflecBeatBase
from bemani.backend.reflec.volzzabase import ReflecBeatVolzzaBase
from bemani.backend.reflec.volzza import ReflecBeatVolzza
from bemani.common import ValidatedDict, VersionConstants, ID, Time
from bemani.common import Profile, ValidatedDict, VersionConstants, ID, Time
from bemani.data import Score, UserID
from bemani.protocol import Node
@ -158,7 +158,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
rl = Node.void('rl')
rival_data.add_child(rl)
rl.add_child(Node.s32('uid', rprofile.get_int('extid')))
rl.add_child(Node.s32('uid', rprofile.extid))
rl.add_child(Node.string('nm', rprofile.get_str('name')))
rl.add_child(Node.s16('ic', rprofile.get_dict('config').get_int('icon_id')))
@ -255,7 +255,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
)
minigame_scores = sorted(
[
all_profiles.get(userid, ValidatedDict()).get_int('mgsc')
all_profiles.get(userid, Profile(self.game, self.version, "", 0)).get_int('mgsc')
for userid in all_users
],
reverse=True,
@ -317,15 +317,15 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
if profile is None:
root.add_child(Node.s32('uid', 0))
else:
root.add_child(Node.s32('uid', profile.get_int('extid')))
root.add_child(Node.s32('uid', profile.extid))
return root
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
statistics = self.get_play_statistics(userid)
game_config = self.get_game_config()
achievements = self.data.local.user.get_achievements(self.game, self.version, userid)
links = self.data.local.user.get_links(self.game, self.version, userid)
rprofiles: Dict[UserID, ValidatedDict] = {}
rprofiles: Dict[UserID, Profile] = {}
root = Node.void('player')
pdata = Node.void('pdata')
root.add_child(pdata)
@ -352,7 +352,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
# Account info
account = Node.void('account')
pdata.add_child(account)
account.add_child(Node.s32('usrid', profile.get_int('extid')))
account.add_child(Node.s32('usrid', profile.extid))
account.add_child(Node.s32('tpc', statistics.get_int('total_plays', 0)))
account.add_child(Node.s32('dpc', today_count))
account.add_child(Node.s32('crd', 1))
@ -407,7 +407,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
r = Node.void('r')
rival.add_child(r)
r.add_child(Node.s32('slot_id', slotid))
r.add_child(Node.s32('id', rprofile.get_int('extid')))
r.add_child(Node.s32('id', rprofile.extid))
r.add_child(Node.string('name', rprofile.get_str('name')))
r.add_child(Node.s32('icon', rprofile.get_dict('config').get_int('icon_id')))
r.add_child(Node.s32('class', rprofile.get_int('class')))
@ -647,7 +647,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
rec = Node.void('rec')
mycourse_f.add_child(rec)
rec.add_child(Node.s32('rival_id', rprofile.get_int('extid')))
rec.add_child(Node.s32('rival_id', rprofile.extid))
rec.add_child(Node.s16('mycourse_id', 1))
rec.add_child(Node.s32('music_id_1', mycoursedict.get_int('music_id_1', -1)))
rec.add_child(Node.s16('note_grade_1', mycoursedict.get_int('note_grade_1', -1)))
@ -665,7 +665,7 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
return root
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
game_config = self.get_game_config()
newprofile = copy.deepcopy(oldprofile)
@ -768,8 +768,8 @@ class ReflecBeatVolzza2(ReflecBeatVolzzaBase):
# I assume this is copypasta, but I want to be sure
extid = child.child_value('user_id')
if extid != newprofile.get_int('extid'):
raise Exception(f'Unexpected user ID, got {extid} expecting {newprofile.get_int("extid")}')
if extid != newprofile.extid:
raise Exception(f'Unexpected user ID, got {extid} expecting {newprofile.extid}')
episode_type = child.child_value('type')
episode_value0 = child.child_value('value0')

View File

@ -2,7 +2,7 @@ from typing import Dict, List, Tuple
from bemani.backend.reflec.base import ReflecBeatBase
from bemani.common import ID, Time, ValidatedDict
from bemani.common import ID, Time, Profile
from bemani.data import Attempt, UserID
from bemani.protocol import Node
@ -135,7 +135,7 @@ class ReflecBeatVolzzaBase(ReflecBeatBase):
data = Node.void('data')
rootnode.add_child(data)
data.add_child(Node.s16('day_id', int((Time.now() - timeoffset) / Time.SECONDS_IN_DAY)))
data.add_child(Node.s32('user_id', profile.get_int('extid')))
data.add_child(Node.s32('user_id', profile.extid))
data.add_child(Node.s16('icon_id', profile.get_dict('config').get_int('icon_id')))
data.add_child(Node.s16('point', min(points_by_user.get(userid, 0), 32767)))
data.add_child(Node.s32('update_time', Time.now()))
@ -206,7 +206,7 @@ class ReflecBeatVolzzaBase(ReflecBeatBase):
root.add_child(shop_score)
shop_score.add_child(Node.s32('time', Time.now()))
profiles: Dict[UserID, ValidatedDict] = {}
profiles: Dict[UserID, Profile] = {}
for songid in range(start_music_id, end_music_id + 1):
allscores = self.data.local.music.get_all_scores(
self.game,
@ -238,7 +238,7 @@ class ReflecBeatVolzzaBase(ReflecBeatBase):
data.add_child(Node.s16('music_id', songid))
data.add_child(Node.s8('note_grade', score.chart))
data.add_child(Node.s8('clear_type', self._db_to_game_clear_type(score.data.get_int('clear_type'))))
data.add_child(Node.s32('user_id', profile.get_int('extid')))
data.add_child(Node.s32('user_id', profile.extid))
data.add_child(Node.s16('icon_id', profile.get_dict('config').get_int('icon_id')))
data.add_child(Node.s32('score', score.points))
data.add_child(Node.s32('time', score.timestamp))
@ -291,7 +291,7 @@ class ReflecBeatVolzzaBase(ReflecBeatBase):
e.add_child(Node.s32('eid', lobby.get_int('id')))
e.add_child(Node.u16('mid', lobby.get_int('mid')))
e.add_child(Node.u8('ng', lobby.get_int('ng')))
e.add_child(Node.s32('uid', profile.get_int('extid')))
e.add_child(Node.s32('uid', profile.extid))
e.add_child(Node.s32('uattr', profile.get_int('uattr')))
e.add_child(Node.string('pn', profile.get_str('name')))
e.add_child(Node.s32('plyid', info.get_int('id')))
@ -345,7 +345,7 @@ class ReflecBeatVolzzaBase(ReflecBeatBase):
e.add_child(Node.s32('eid', lobby.get_int('id')))
e.add_child(Node.u16('mid', lobby.get_int('mid')))
e.add_child(Node.u8('ng', lobby.get_int('ng')))
e.add_child(Node.s32('uid', profile.get_int('extid')))
e.add_child(Node.s32('uid', profile.extid))
e.add_child(Node.s32('uattr', profile.get_int('uattr')))
e.add_child(Node.string('pn', profile.get_str('name')))
e.add_child(Node.s32('plyid', info.get_int('id')))

View File

@ -3,7 +3,7 @@ from typing import Dict, Optional
from bemani.backend.base import Base
from bemani.backend.core import CoreHandler, CardManagerHandler, PASELIHandler
from bemani.common import ValidatedDict, GameConstants, DBConstants, Parallel
from bemani.common import Profile, ValidatedDict, GameConstants, DBConstants, Parallel
from bemani.data import UserID
from bemani.protocol import Node
@ -78,24 +78,27 @@ class SoundVoltexBase(CoreHandler, CardManagerHandler, PASELIHandler, Base):
# First, create and save the default profile
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
defaultprofile = ValidatedDict({
'name': name,
'loc': locid,
})
self.put_profile(userid, defaultprofile)
# Now, reload and format the profile, looking up the has old version flag
profile = self.get_profile(userid)
profile = Profile(
self.game,
self.version,
refid,
0,
{
'name': name,
'loc': locid,
},
)
self.put_profile(userid, profile)
return self.format_profile(userid, profile)
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
"""
Base handler for a profile. Given a userid and a profile dictionary,
return a Node representing a profile. Should be overridden.
"""
return Node.void('game')
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
"""
Base handler for profile parsing. Given a request and an old profile,
return a new profile that's been updated with the contents of the request.

View File

@ -4,7 +4,7 @@ from typing import Any, Dict, Optional, Tuple
from bemani.backend.ess import EventLogHandler
from bemani.backend.sdvx.base import SoundVoltexBase
from bemani.common import ValidatedDict, VersionConstants, ID, intish
from bemani.common import Profile, VersionConstants, ID, intish
from bemani.data import Score, UserID
from bemani.protocol import Node
@ -430,12 +430,12 @@ class SoundVoltexBooth(
game.add_child(Node.s8('result', result))
return game
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
game = Node.void('game')
# Generic profile stuff
game.add_child(Node.string('name', profile.get_str('name')))
game.add_child(Node.string('code', ID.format_extid(profile.get_int('extid'))))
game.add_child(Node.string('code', ID.format_extid(profile.extid)))
game.add_child(Node.u32('gamecoin_packet', profile.get_int('packet')))
game.add_child(Node.u32('gamecoin_block', profile.get_int('block')))
game.add_child(Node.u32('exp_point', profile.get_int('exp')))
@ -469,7 +469,7 @@ class SoundVoltexBooth(
return game
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
# Update experience and in-game currencies

View File

@ -3,7 +3,7 @@ import copy
from typing import Any, Dict, List
from bemani.backend.sdvx.gravitywars import SoundVoltexGravityWars
from bemani.common import ID, Time, ValidatedDict
from bemani.common import ID, Time, Profile
from bemani.data import UserID
from bemani.protocol import Node
@ -3081,7 +3081,7 @@ class SoundVoltexGravityWarsSeason1(
info.add_child(Node.u32('id', score.id))
info.add_child(Node.u32('type', score.chart))
info.add_child(Node.string('name', profile.get_str('name')))
info.add_child(Node.string('code', ID.format_extid(profile.get_int('extid'))))
info.add_child(Node.string('code', ID.format_extid(profile.extid)))
info.add_child(Node.u32('score', score.points))
# Add to global scores
@ -3111,7 +3111,7 @@ class SoundVoltexGravityWarsSeason1(
info.add_child(Node.u32('id', score.id))
info.add_child(Node.u32('type', score.chart))
info.add_child(Node.string('name', profile.get_str('name')))
info.add_child(Node.string('code', ID.format_extid(profile.get_int('extid'))))
info.add_child(Node.string('code', ID.format_extid(profile.extid)))
info.add_child(Node.u32('score', score.points))
# Add to global scores
@ -3134,12 +3134,12 @@ class SoundVoltexGravityWarsSeason1(
return game
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
game = Node.void('game_3')
# Generic profile stuff
game.add_child(Node.string('name', profile.get_str('name')))
game.add_child(Node.string('code', ID.format_extid(profile.get_int('extid'))))
game.add_child(Node.string('code', ID.format_extid(profile.extid)))
game.add_child(Node.u32('gamecoin_packet', profile.get_int('packet')))
game.add_child(Node.u32('gamecoin_block', profile.get_int('block')))
game.add_child(Node.s16('skill_name_id', profile.get_int('skill_name_id', -1)))
@ -3272,7 +3272,7 @@ class SoundVoltexGravityWarsSeason1(
return game
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
# Update blaster energy and in-game currencies

View File

@ -3,7 +3,7 @@ import copy
from typing import Any, Dict, List, Tuple
from bemani.backend.sdvx.gravitywars import SoundVoltexGravityWars
from bemani.common import ID, Time, ValidatedDict
from bemani.common import ID, Time, Profile
from bemani.data import Score, UserID
from bemani.protocol import Node
@ -3905,7 +3905,7 @@ class SoundVoltexGravityWarsSeason2(
highscores.add_child(info)
info.add_child(Node.u32('id', musicid))
info.add_child(Node.u32('ty', chart))
info.add_child(Node.string('a_sq', ID.format_extid(global_profile.get_int('extid'))))
info.add_child(Node.string('a_sq', ID.format_extid(global_profile.extid)))
info.add_child(Node.string('a_nm', global_profile.get_str('name')))
info.add_child(Node.u32('a_sc', globalscore.points))
info.add_child(Node.s32('cr', int(clear_rate * 10000)))
@ -3913,7 +3913,7 @@ class SoundVoltexGravityWarsSeason2(
if 'area' in records[musicid][chart]:
(localuserid, localscore) = records[musicid][chart]['area']
local_profile = users[localuserid]
info.add_child(Node.string('l_sq', ID.format_extid(local_profile.get_int('extid'))))
info.add_child(Node.string('l_sq', ID.format_extid(local_profile.extid)))
info.add_child(Node.string('l_nm', local_profile.get_str('name')))
info.add_child(Node.u32('l_sc', localscore.points))
@ -3941,7 +3941,7 @@ class SoundVoltexGravityWarsSeason2(
rival = Node.void('rival')
game.add_child(rival)
rival.add_child(Node.s16('no', index))
rival.add_child(Node.string('seq', ID.format_extid(other_profile.get_int('extid'))))
rival.add_child(Node.string('seq', ID.format_extid(other_profile.extid)))
rival.add_child(Node.string('name', other_profile.get_str('name')))
# Return scores for this user on random charts
@ -3955,12 +3955,12 @@ class SoundVoltexGravityWarsSeason2(
return game
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
game = Node.void('game_3')
# Generic profile stuff
game.add_child(Node.string('name', profile.get_str('name')))
game.add_child(Node.string('code', ID.format_extid(profile.get_int('extid'))))
game.add_child(Node.string('code', ID.format_extid(profile.extid)))
game.add_child(Node.u32('gamecoin_packet', profile.get_int('packet')))
game.add_child(Node.u32('gamecoin_block', profile.get_int('block')))
game.add_child(Node.s16('skill_name_id', profile.get_int('chosen_skill_id', profile.get_int('skill_name_id', -1))))
@ -4134,7 +4134,7 @@ class SoundVoltexGravityWarsSeason2(
return game
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
# Update blaster energy and in-game currencies

View File

@ -5,7 +5,7 @@ from typing import Any, Dict, List, Optional, Tuple
from bemani.backend.ess import EventLogHandler
from bemani.backend.sdvx.base import SoundVoltexBase
from bemani.backend.sdvx.gravitywars import SoundVoltexGravityWars
from bemani.common import ID, Time, ValidatedDict, VersionConstants
from bemani.common import ID, Time, Profile, VersionConstants
from bemani.data import Score, UserID
from bemani.protocol import Node
@ -3470,7 +3470,7 @@ class SoundVoltexHeavenlyHaven(
highscores.add_child(info)
info.add_child(Node.u32('id', musicid))
info.add_child(Node.u32('ty', chart))
info.add_child(Node.string('a_sq', ID.format_extid(global_profile.get_int('extid'))))
info.add_child(Node.string('a_sq', ID.format_extid(global_profile.extid)))
info.add_child(Node.string('a_nm', global_profile.get_str('name')))
info.add_child(Node.u32('a_sc', globalscore.points))
info.add_child(Node.s32('cr', int(clear_rate * 10000)))
@ -3479,7 +3479,7 @@ class SoundVoltexHeavenlyHaven(
if 'area' in records[musicid][chart]:
(localuserid, localscore) = records[musicid][chart]['area']
local_profile = users[localuserid]
info.add_child(Node.string('l_sq', ID.format_extid(local_profile.get_int('extid'))))
info.add_child(Node.string('l_sq', ID.format_extid(local_profile.extid)))
info.add_child(Node.string('l_nm', local_profile.get_str('name')))
info.add_child(Node.u32('l_sc', localscore.points))
@ -3604,7 +3604,7 @@ class SoundVoltexHeavenlyHaven(
rival = Node.void('rival')
game.add_child(rival)
rival.add_child(Node.s16('no', index))
rival.add_child(Node.string('seq', ID.format_extid(other_profile.get_int('extid'))))
rival.add_child(Node.string('seq', ID.format_extid(other_profile.extid)))
rival.add_child(Node.string('name', other_profile.get_str('name')))
# Keep track of index
@ -3841,13 +3841,13 @@ class SoundVoltexHeavenlyHaven(
# Return a blank response
return Node.void('game')
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
game = Node.void('game')
# Generic profile stuff
game.add_child(Node.string('name', profile.get_str('name')))
game.add_child(Node.string('code', ID.format_extid(profile.get_int('extid'))))
game.add_child(Node.string('sdvx_id', ID.format_extid(profile.get_int('extid'))))
game.add_child(Node.string('code', ID.format_extid(profile.extid)))
game.add_child(Node.string('sdvx_id', ID.format_extid(profile.extid)))
game.add_child(Node.u16('appeal_id', profile.get_int('appealid')))
game.add_child(Node.s16('skill_base_id', profile.get_int('skill_base_id')))
game.add_child(Node.s16('skill_name_id', profile.get_int('skill_name_id')))
@ -4035,7 +4035,7 @@ class SoundVoltexHeavenlyHaven(
return game
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
# Update blaster energy and in-game currencies

View File

@ -5,7 +5,7 @@ from typing import Any, Dict, List, Optional
from bemani.backend.ess import EventLogHandler
from bemani.backend.sdvx.base import SoundVoltexBase
from bemani.backend.sdvx.booth import SoundVoltexBooth
from bemani.common import Time, ValidatedDict, VersionConstants, ID
from bemani.common import Time, Profile, VersionConstants, ID
from bemani.data import UserID
from bemani.protocol import Node
@ -1993,7 +1993,7 @@ class SoundVoltexInfiniteInfection(
info.add_child(Node.u32('id', score.id))
info.add_child(Node.u32('type', score.chart))
info.add_child(Node.string('name', profile.get_str('name')))
info.add_child(Node.string('code', ID.format_extid(profile.get_int('extid'))))
info.add_child(Node.string('code', ID.format_extid(profile.extid)))
info.add_child(Node.u32('score', score.points))
# Add to global scores
@ -2023,7 +2023,7 @@ class SoundVoltexInfiniteInfection(
info.add_child(Node.u32('id', score.id))
info.add_child(Node.u32('type', score.chart))
info.add_child(Node.string('name', profile.get_str('name')))
info.add_child(Node.string('code', ID.format_extid(profile.get_int('extid'))))
info.add_child(Node.string('code', ID.format_extid(profile.extid)))
info.add_child(Node.u32('score', score.points))
# Add to local scores
@ -2289,12 +2289,12 @@ class SoundVoltexInfiniteInfection(
game.add_child(Node.s8('result', result))
return game
def format_profile(self, userid: UserID, profile: ValidatedDict) -> Node:
def format_profile(self, userid: UserID, profile: Profile) -> Node:
game = Node.void('game_2')
# Generic profile stuff
game.add_child(Node.string('name', profile.get_str('name')))
game.add_child(Node.string('code', ID.format_extid(profile.get_int('extid'))))
game.add_child(Node.string('code', ID.format_extid(profile.extid)))
game.add_child(Node.u32('gamecoin_packet', profile.get_int('packet')))
game.add_child(Node.u32('gamecoin_block', profile.get_int('block')))
game.add_child(Node.s16('skill_name_id', profile.get_int('skill_name_id', -1)))
@ -2424,7 +2424,7 @@ class SoundVoltexInfiniteInfection(
return game
def unformat_profile(self, userid: UserID, request: Node, oldprofile: ValidatedDict) -> ValidatedDict:
def unformat_profile(self, userid: UserID, request: Node, oldprofile: Profile) -> Profile:
newprofile = copy.deepcopy(oldprofile)
# Update blaster energy and in-game currencies

View File

@ -1,5 +1,5 @@
from bemani.common.model import Model
from bemani.common.validateddict import ValidatedDict, intish
from bemani.common.validateddict import ValidatedDict, Profile, intish
from bemani.common.http import HTTP
from bemani.common.constants import APIConstants, GameConstants, VersionConstants, DBConstants, BroadcastConstants
from bemani.common.card import CardCipher, CardCipherException
@ -13,6 +13,7 @@ from bemani.common.pe import PEFile
__all__ = [
"Model",
"ValidatedDict",
"Profile",
"HTTP",
"APIConstants",
"GameConstants",

View File

@ -1,5 +1,7 @@
from typing import Optional, List, Dict, Any
from bemani.common.constants import GameConstants
def intish(val: Any, base: int=10) -> Optional[int]:
if val is None:
@ -437,3 +439,18 @@ class ValidatedDict(dict):
self[name] = 1
else:
self[name] = self[name] + 1
class Profile(ValidatedDict):
"""
A special case of a ValidatedDict, a profile is guaranteed to also contain
references to how it was created or loaded, including the game/version
combo and the refid and extid associated wit the profile.
"""
def __init__(self, game: GameConstants, version: int, refid: str, extid: int, initial_values: Dict[str, Any] = {}) -> None:
super().__init__(initial_values or {})
self.game = game
self.version = version
self.refid = refid
self.extid = extid

View File

@ -1,7 +1,6 @@
import copy
from typing import List, Tuple, Optional, Dict, Any
from typing import List, Tuple, Optional
from bemani.common import APIConstants, GameConstants, ValidatedDict, Parallel
from bemani.common import APIConstants, GameConstants, Profile, Parallel
from bemani.data.interfaces import APIProviderInterface
from bemani.data.api.base import BaseGlobalData
from bemani.data.mysql.user import UserData
@ -15,25 +14,20 @@ class GlobalUserData(BaseGlobalData):
super().__init__(api)
self.user = user
def __format_ddr_profile(self, profile: ValidatedDict) -> Dict[str, Any]:
updates = {}
def __format_ddr_profile(self, updates: Profile, profile: Profile) -> None:
area = profile.get_int('area', -1)
if area != -1:
updates['area'] = area
return updates
def __format_iidx_profile(self, profile: ValidatedDict) -> Dict[str, Any]:
updates: Dict[str, Any] = {
'qpro': {},
}
def __format_iidx_profile(self, updates: Profile, profile: Profile) -> None:
area = profile.get_int('area', -1)
if area != -1:
updates['pid'] = area
qpro = profile.get_dict('qpro')
updates['qpro'] = {}
head = qpro.get_int('head', -1)
if head != -1:
updates['qpro']['head'] = head
@ -50,62 +44,54 @@ class GlobalUserData(BaseGlobalData):
if hand != -1:
updates['qpro']['hand'] = hand
return updates
def __format_jubeat_profile(self, updates: Profile, profile: Profile) -> None:
pass
def __format_jubeat_profile(self, profile: ValidatedDict) -> Dict[str, Any]:
return {}
def __format_museca_profile(self, profile: ValidatedDict) -> Dict[str, Any]:
return {}
def __format_popn_profile(self, profile: ValidatedDict) -> Dict[str, Any]:
updates = {}
def __format_museca_profile(self, updates: Profile, profile: Profile) -> None:
pass
def __format_popn_profile(self, updates: Profile, profile: Profile) -> None:
chara = profile.get_int('character', -1)
if chara != -1:
updates['chara'] = chara
return updates
def __format_reflec_profile(self, profile: ValidatedDict) -> Dict[str, Any]:
updates = {}
def __format_reflec_profile(self, updates: Profile, profile: Profile) -> None:
icon = profile.get_int('icon', -1)
if icon != -1:
updates['config'] = {'icon_id': icon}
return updates
def __format_sdvx_profile(self, updates: Profile, profile: Profile) -> None:
pass
def __format_sdvx_profile(self, profile: ValidatedDict) -> Dict[str, Any]:
return {}
def __format_profile(self, profile: Profile) -> Profile:
new = Profile(
profile.game,
profile.version,
profile.refid,
profile.extid,
{
'name': profile.get('name', ''),
},
)
def __format_profile(self, profile: ValidatedDict) -> ValidatedDict:
base = {
'name': profile.get('name', ''),
'game': profile['game'],
'version': profile['version'],
'refid': profile['refid'],
'extid': profile['extid'],
}
if profile.game == GameConstants.DDR:
self.__format_ddr_profile(new, profile)
if profile.game == GameConstants.IIDX:
self.__format_iidx_profile(new, profile)
if profile.game == GameConstants.JUBEAT:
self.__format_jubeat_profile(new, profile)
if profile.game == GameConstants.MUSECA:
self.__format_museca_profile(new, profile)
if profile.game == GameConstants.POPN_MUSIC:
self.__format_popn_profile(new, profile)
if profile.game == GameConstants.REFLEC_BEAT:
self.__format_reflec_profile(new, profile)
if profile.game == GameConstants.SDVX:
self.__format_sdvx_profile(new, profile)
if profile['game'] == GameConstants.DDR:
base.update(self.__format_ddr_profile(profile))
if profile['game'] == GameConstants.IIDX:
base.update(self.__format_iidx_profile(profile))
if profile['game'] == GameConstants.JUBEAT:
base.update(self.__format_jubeat_profile(profile))
if profile['game'] == GameConstants.MUSECA:
base.update(self.__format_museca_profile(profile))
if profile['game'] == GameConstants.POPN_MUSIC:
base.update(self.__format_popn_profile(profile))
if profile['game'] == GameConstants.REFLEC_BEAT:
base.update(self.__format_reflec_profile(profile))
if profile['game'] == GameConstants.SDVX:
base.update(self.__format_sdvx_profile(profile))
return new
return ValidatedDict(base)
def __profile_request(self, game: GameConstants, version: int, userid: UserID, exact: bool) -> Optional[ValidatedDict]:
def __profile_request(self, game: GameConstants, version: int, userid: UserID, exact: bool) -> Optional[Profile]:
# First, get or create the extid/refid for this virtual user
cardid = RemoteUser.userid_to_card(userid)
refid = self.user.get_refid(game, version, userid)
@ -121,25 +107,22 @@ class GlobalUserData(BaseGlobalData):
for profile in profiles:
cards = [card.upper() for card in profile.get('cards', [])]
if cardid in cards:
# Sanitize the returned data
profile = copy.deepcopy(profile)
del profile['cards']
# Don't take non-exact matches.
exact_match = profile.get('match', 'partial') == 'exact'
if exact and (not exact_match):
# This is a partial match, not for this game/version
continue
if 'match' in profile:
del profile['match']
# Add in our defaults we always provide
profile['game'] = game
profile['version'] = version if exact_match else 0
profile['refid'] = refid
profile['extid'] = extid
return self.__format_profile(ValidatedDict(profile))
# Add in our defaults we always provide, convert it to a local format.
return self.__format_profile(
Profile(
game,
version,
refid,
extid,
profile,
)
)
return None
@ -155,19 +138,19 @@ class GlobalUserData(BaseGlobalData):
def from_extid(self, game: GameConstants, version: int, extid: int) -> Optional[UserID]:
return self.user.from_extid(game, version, extid)
def get_profile(self, game: GameConstants, version: int, userid: UserID) -> Optional[ValidatedDict]:
def get_profile(self, game: GameConstants, version: int, userid: UserID) -> Optional[Profile]:
if RemoteUser.is_remote(userid):
return self.__profile_request(game, version, userid, exact=True)
else:
return self.user.get_profile(game, version, userid)
def get_any_profile(self, game: GameConstants, version: int, userid: UserID) -> Optional[ValidatedDict]:
def get_any_profile(self, game: GameConstants, version: int, userid: UserID) -> Optional[Profile]:
if RemoteUser.is_remote(userid):
return self.__profile_request(game, version, userid, exact=False)
else:
return self.user.get_any_profile(game, version, userid)
def get_any_profiles(self, game: GameConstants, version: int, userids: List[UserID]) -> List[Tuple[UserID, Optional[ValidatedDict]]]:
def get_any_profiles(self, game: GameConstants, version: int, userids: List[UserID]) -> List[Tuple[UserID, Optional[Profile]]]:
if len(userids) == 0:
return []
@ -211,25 +194,24 @@ class GlobalUserData(BaseGlobalData):
continue
# Sanitize the returned data
profile = copy.deepcopy(profile)
del profile['cards']
exact_match = profile.get('match', 'partial') == 'exact'
if 'match' in profile:
del profile['match']
refid = self.user.get_refid(game, version, userid)
extid = self.user.get_extid(game, version, userid)
# Add in our defaults we always provide
profile['game'] = game
profile['version'] = version if exact_match else 0
profile['refid'] = refid
profile['extid'] = extid
local_profiles.append(
(userid, self.__format_profile(ValidatedDict(profile))),
(
userid,
self.__format_profile(
Profile(
game,
version if exact_match else 0,
refid,
extid,
profile,
),
),
),
)
# Mark that we saw this card/user
@ -241,7 +223,7 @@ class GlobalUserData(BaseGlobalData):
return local_profiles
def get_all_profiles(self, game: GameConstants, version: int) -> List[Tuple[UserID, ValidatedDict]]:
def get_all_profiles(self, game: GameConstants, version: int) -> List[Tuple[UserID, Profile]]:
# Fetch local and remote profiles, and then merge by adding remote profiles to local
# profiles when we don't have a profile for that user ID yet.
local_cards, local_profiles, remote_profiles = Parallel.execute([
@ -270,23 +252,24 @@ class GlobalUserData(BaseGlobalData):
# We have a local version of this profile!
continue
# Create a fake user with this profile
del profile['cards']
exact_match = profile.get('match', 'partial') == 'exact'
if not exact_match:
continue
# Create a fake user with this profile
userid = RemoteUser.card_to_userid(cardids[0])
refid = self.user.get_refid(game, version, userid)
extid = self.user.get_extid(game, version, userid)
# Add in our defaults we always provide
profile['game'] = game
profile['version'] = version
profile['refid'] = refid
profile['extid'] = extid
id_to_profile[userid] = self.__format_profile(ValidatedDict(profile))
id_to_profile[userid] = self.__format_profile(
Profile(
game,
version,
refid,
extid,
profile,
),
)
return [(userid, id_to_profile[userid]) for userid in id_to_profile]

View File

@ -133,6 +133,8 @@ class LobbyData(BaseData):
data = copy.deepcopy(data)
if 'id' in data:
del data['id']
if 'time' in data:
del data['time']
# Add json to player session
sql = (
@ -244,6 +246,7 @@ class LobbyData(BaseData):
for result in cursor.fetchall():
data = ValidatedDict(self.deserialize(result['data']))
data['id'] = result['id']
data['time'] = result['time']
ret.append((UserID(result['userid']), data))
return ret
@ -260,6 +263,8 @@ class LobbyData(BaseData):
data = copy.deepcopy(data)
if 'id' in data:
del data['id']
if 'time' in data:
del data['time']
# Add json to lobby
sql = (

View File

@ -1,4 +1,3 @@
import copy
import random
from sqlalchemy import Table, Column, UniqueConstraint # type: ignore
from sqlalchemy.types import String, Integer, JSON # type: ignore
@ -7,7 +6,7 @@ from sqlalchemy.exc import IntegrityError # type: ignore
from typing import Optional, Dict, List, Tuple, Any
from passlib.hash import pbkdf2_sha512 # type: ignore
from bemani.common import ValidatedDict, GameConstants, Time
from bemani.common import ValidatedDict, Profile, GameConstants, Time
from bemani.data.mysql.base import BaseData, metadata
from bemani.data.remoteuser import RemoteUser
from bemani.data.types import User, Achievement, Link, UserID, ArcadeID
@ -476,7 +475,7 @@ class UserData(BaseData):
sql = "UPDATE user SET password = :hash WHERE id = :userid"
self.execute(sql, {'hash': passhash, 'userid': userid})
def get_profile(self, game: GameConstants, version: int, userid: UserID) -> Optional[ValidatedDict]:
def get_profile(self, game: GameConstants, version: int, userid: UserID) -> Optional[Profile]:
"""
Given a game/version/userid, look up the associated profile.
@ -500,24 +499,24 @@ class UserData(BaseData):
return None
result = cursor.fetchone()
profile = {
'refid': result['refid'],
'extid': result['extid'],
'game': game,
'version': version,
}
profile = Profile(
game,
version,
result['refid'],
result['extid'],
)
sql = "SELECT data FROM profile WHERE refid = :refid"
cursor = self.execute(sql, {'refid': profile['refid']})
cursor = self.execute(sql, {'refid': profile.refid})
if cursor.rowcount != 1:
# Profile doesn't exist
return None
result = cursor.fetchone()
profile.update(self.deserialize(result['data']))
return ValidatedDict(profile)
return profile
def get_any_profile(self, game: GameConstants, version: int, userid: UserID) -> Optional[ValidatedDict]:
def get_any_profile(self, game: GameConstants, version: int, userid: UserID) -> Optional[Profile]:
"""
Given a game/version/userid, look up the associated profile. If the profile for that version
doesn't exist, try another profile, failing only if there is no profile for any version of
@ -542,7 +541,7 @@ class UserData(BaseData):
else:
return None
def get_any_profiles(self, game: GameConstants, version: int, userids: List[UserID]) -> List[Tuple[UserID, Optional[ValidatedDict]]]:
def get_any_profiles(self, game: GameConstants, version: int, userids: List[UserID]) -> List[Tuple[UserID, Optional[Profile]]]:
"""
Does the exact same thing as get_any_profile but across a list of users instead of one.
Provided purely as a convenience function.
@ -578,7 +577,7 @@ class UserData(BaseData):
profiles.append((GameConstants(result['game']), result['version']))
return profiles
def get_all_profiles(self, game: GameConstants, version: int) -> List[Tuple[UserID, ValidatedDict]]:
def get_all_profiles(self, game: GameConstants, version: int) -> List[Tuple[UserID, Profile]]:
"""
Given a game/version, look up all user profiles for that game.
@ -599,17 +598,17 @@ class UserData(BaseData):
profiles = []
for result in cursor.fetchall():
profile = {
'refid': result['refid'],
'extid': result['extid'],
'game': game,
'version': version,
}
profile = Profile(
game,
version,
result['refid'],
result['extid'],
)
profile.update(self.deserialize(result['data']))
profiles.append(
(
UserID(result['userid']),
ValidatedDict(profile),
profile,
)
)
@ -668,7 +667,7 @@ class UserData(BaseData):
return achievements
def put_profile(self, game: GameConstants, version: int, userid: UserID, profile: Dict[str, Any]) -> None:
def put_profile(self, game: GameConstants, version: int, userid: UserID, profile: Profile) -> None:
"""
Given a game/version/userid, save an associated profile.
@ -679,15 +678,6 @@ class UserData(BaseData):
profile - A dictionary that a game class will want to retrieve later.
"""
refid = self.get_refid(game, version, userid)
profile = copy.deepcopy(profile)
if 'refid' in profile:
del profile['refid']
if 'extid' in profile:
del profile['extid']
if 'game' in profile:
del profile['game']
if 'version' in profile:
del profile['version']
# Add profile json to game profile
sql = (
@ -697,6 +687,13 @@ class UserData(BaseData):
)
self.execute(sql, {'refid': refid, 'json': self.serialize(profile)})
# Update profile details just in case this was a new profile that was just saved.
profile.game = game
profile.version = version
profile.refid = refid
if profile.extid == 0:
profile.extid = self.get_extid(game, version, userid)
def get_achievement(self, game: GameConstants, version: int, userid: UserID, achievementid: int, achievementtype: str) -> Optional[ValidatedDict]:
"""
Given a game/version/userid and achievement id/type, find that achievement.

View File

@ -5,7 +5,7 @@ from typing import Any, Dict, Iterator, List, Optional, Set, Tuple
from flask_caching import Cache # type: ignore
from bemani.common import GameConstants, ValidatedDict, ID
from bemani.common import GameConstants, Profile, ValidatedDict, ID
from bemani.data import Data, Score, Attempt, Link, Song, UserID, RemoteUser
@ -67,14 +67,14 @@ class FrontendBase(ABC):
'points': attempt.points,
}
def format_rival(self, link: Link, profile: ValidatedDict) -> Dict[str, Any]:
def format_rival(self, link: Link, profile: Profile) -> Dict[str, Any]:
return {
'type': link.type,
'userid': str(link.other_userid),
'remote': RemoteUser.is_remote(link.other_userid),
}
def format_profile(self, profile: ValidatedDict, playstats: ValidatedDict) -> Dict[str, Any]:
def format_profile(self, profile: Profile, playstats: ValidatedDict) -> Dict[str, Any]:
return {
'name': profile.get_str('name'),
'extid': ID.format_extid(profile.get_int('extid')),

View File

@ -5,7 +5,7 @@ from typing import Any, Dict, Iterator, Tuple
from flask_caching import Cache # type: ignore
from bemani.backend.bishi import BishiBashiFactory
from bemani.common import ValidatedDict, ID, GameConstants
from bemani.common import Profile, ValidatedDict, ID, GameConstants
from bemani.data import Data
from bemani.frontend.base import FrontendBase
@ -36,7 +36,7 @@ class BishiBashiFrontend(FrontendBase):
return 'なし'
return name
def update_name(self, profile: ValidatedDict, name: str) -> ValidatedDict:
def update_name(self, profile: Profile, name: str) -> Profile:
newprofile = copy.deepcopy(profile)
for i in range(len(newprofile['strdatas'])):
strdata = newprofile['strdatas'][i]
@ -55,7 +55,7 @@ class BishiBashiFrontend(FrontendBase):
return newprofile
def format_profile(self, profile: ValidatedDict, playstats: ValidatedDict) -> Dict[str, Any]:
def format_profile(self, profile: Profile, playstats: ValidatedDict) -> Dict[str, Any]:
name = 'なし' # Nothing
shop = '未設定' # Not set
shop_area = '未設定' # Not set

View File

@ -3,7 +3,7 @@ import copy
from typing import Any, Dict, Iterator, Tuple
from bemani.backend.ddr import DDRFactory, DDRBase
from bemani.common import ValidatedDict, GameConstants, VersionConstants
from bemani.common import Profile, ValidatedDict, GameConstants, VersionConstants
from bemani.data import Attempt, Link, RemoteUser, Score, Song, UserID
from bemani.frontend.base import FrontendBase
@ -40,12 +40,12 @@ class DDRFrontend(FrontendBase):
def all_games(self) -> Iterator[Tuple[GameConstants, int, str]]:
yield from DDRFactory.all_games()
def update_name(self, profile: ValidatedDict, name: str) -> ValidatedDict:
def update_name(self, profile: Profile, name: str) -> Profile:
newprofile = copy.deepcopy(profile)
newprofile.replace_str('name', name)
return newprofile
def update_weight(self, profile: ValidatedDict, weight: int, enabled: bool) -> ValidatedDict:
def update_weight(self, profile: Profile, weight: int, enabled: bool) -> Profile:
newprofile = copy.deepcopy(profile)
if newprofile.get_int('version') in (VersionConstants.DDR_ACE, VersionConstants.DDR_A20):
if enabled:
@ -62,17 +62,17 @@ class DDRFrontend(FrontendBase):
del newprofile['weight']
return newprofile
def update_early_late(self, profile: ValidatedDict, display_early_late: bool) -> ValidatedDict:
def update_early_late(self, profile: Profile, display_early_late: bool) -> Profile:
newprofile = copy.deepcopy(profile)
newprofile.replace_int('early_late', 1 if display_early_late else 0)
return newprofile
def update_background_combo(self, profile: ValidatedDict, background_combo: bool) -> ValidatedDict:
def update_background_combo(self, profile: Profile, background_combo: bool) -> Profile:
newprofile = copy.deepcopy(profile)
newprofile.replace_int('combo', 1 if background_combo else 0)
return newprofile
def update_settings(self, profile: ValidatedDict, new_settings: Dict[str, Any]) -> ValidatedDict:
def update_settings(self, profile: Profile, new_settings: Dict[str, Any]) -> Profile:
newprofile = copy.deepcopy(profile)
if newprofile.get_int('version') in (VersionConstants.DDR_ACE, VersionConstants.DDR_A20):
newprofile.replace_int('arrowskin', new_settings['arrowskin'])
@ -84,7 +84,7 @@ class DDRFrontend(FrontendBase):
pass
return newprofile
def format_profile(self, profile: ValidatedDict, playstats: ValidatedDict) -> Dict[str, Any]:
def format_profile(self, profile: Profile, playstats: ValidatedDict) -> Dict[str, Any]:
formatted_profile = super().format_profile(profile, playstats)
if profile.get_int('version') in (VersionConstants.DDR_ACE, VersionConstants.DDR_A20):
formatted_profile.update({
@ -200,7 +200,7 @@ class DDRFrontend(FrontendBase):
new_song['difficulties'][new.chart] = new.data.get_int('difficulty', 20)
return new_song
def activate_rival(self, profile: ValidatedDict, position: int) -> ValidatedDict:
def activate_rival(self, profile: Profile, position: int) -> Profile:
newprofile = copy.deepcopy(profile)
if newprofile.get_int('version') == VersionConstants.DDR_X2:
# X2 only has one active rival
@ -219,7 +219,7 @@ class DDRFrontend(FrontendBase):
newprofile.replace_dict('last', lastdict)
return newprofile
def deactivate_rival(self, profile: ValidatedDict, position: int) -> ValidatedDict:
def deactivate_rival(self, profile: Profile, position: int) -> Profile:
newprofile = copy.deepcopy(profile)
if newprofile.get_int('version') == VersionConstants.DDR_X2:
# X2 only has one active rival
@ -239,11 +239,17 @@ class DDRFrontend(FrontendBase):
newprofile.replace_dict('last', lastdict)
return newprofile
def format_rival(self, link: Link, profile: ValidatedDict) -> Dict[str, Any]:
def format_rival(self, link: Link, profile: Profile) -> Dict[str, Any]:
pos = int(link.type[7:])
if profile.get_int('version') == VersionConstants.DDR_X2:
active = pos == (profile.get_dict('last').get_int('fri') - 1)
elif profile.get_int('version') in [VersionConstants.DDR_X3_VS_2NDMIX, VersionConstants.DDR_2013, VersionConstants.DDR_2014, VersionConstants.DDR_ACE, VersionConstants.DDR_A20]:
elif profile.get_int('version') in {
VersionConstants.DDR_X3_VS_2NDMIX,
VersionConstants.DDR_2013,
VersionConstants.DDR_2014,
VersionConstants.DDR_ACE,
VersionConstants.DDR_A20
}:
actives = [
profile.get_dict('last').get_int('rival1') - 1,
profile.get_dict('last').get_int('rival2') - 1,

View File

@ -4,7 +4,7 @@ from typing import Any, Dict, Iterator, Optional, Tuple, List
from flask_caching import Cache # type: ignore
from bemani.backend.iidx import IIDXFactory, IIDXBase
from bemani.common import ValidatedDict, GameConstants
from bemani.common import Profile, ValidatedDict, GameConstants
from bemani.data import Attempt, Data, Score, Song, UserID
from bemani.frontend.base import FrontendBase
@ -185,7 +185,7 @@ class IIDXFrontend(FrontendBase):
],
}
def format_profile(self, profile: ValidatedDict, playstats: ValidatedDict) -> Dict[str, Any]:
def format_profile(self, profile: Profile, playstats: ValidatedDict) -> Dict[str, Any]:
formatted_profile = super().format_profile(profile, playstats)
formatted_profile.update({
'arcade': "",

View File

@ -2,7 +2,7 @@
from typing import Any, Dict, Iterator, Tuple
from bemani.backend.jubeat import JubeatFactory, JubeatBase
from bemani.common import ValidatedDict, GameConstants, VersionConstants
from bemani.common import Profile, ValidatedDict, GameConstants, VersionConstants
from bemani.data import Attempt, Score, Song, UserID
from bemani.frontend.base import FrontendBase
@ -67,7 +67,7 @@ class JubeatFrontend(FrontendBase):
}.get(attempt.data.get_int('medal'), 'NO PLAY')
return formatted_attempt
def format_profile(self, profile: ValidatedDict, playstats: ValidatedDict) -> Dict[str, Any]:
def format_profile(self, profile: Profile, playstats: ValidatedDict) -> Dict[str, Any]:
formatted_profile = super().format_profile(profile, playstats)
formatted_profile['plays'] = playstats.get_int('total_plays')
return formatted_profile

View File

@ -4,7 +4,7 @@ from typing import Any, Dict, Iterator, Tuple
from flask_caching import Cache # type: ignore
from bemani.backend.museca import MusecaFactory, MusecaBase
from bemani.common import GameConstants, VersionConstants, DBConstants, ValidatedDict
from bemani.common import GameConstants, VersionConstants, DBConstants, Profile, ValidatedDict
from bemani.data import Attempt, Data, Score, Song, UserID
from bemani.frontend.base import FrontendBase
@ -74,7 +74,7 @@ class MusecaFrontend(FrontendBase):
formatted_attempt['medal'] = attempt.data.get_int('clear_type')
return formatted_attempt
def format_profile(self, profile: ValidatedDict, playstats: ValidatedDict) -> Dict[str, Any]:
def format_profile(self, profile: Profile, playstats: ValidatedDict) -> Dict[str, Any]:
formatted_profile = super().format_profile(profile, playstats)
formatted_profile['plays'] = playstats.get_int('total_plays')
return formatted_profile

View File

@ -2,7 +2,7 @@
from typing import Any, Dict, Iterator, Tuple
from bemani.backend.popn import PopnMusicFactory, PopnMusicBase
from bemani.common import ValidatedDict, GameConstants, VersionConstants
from bemani.common import Profile, ValidatedDict, GameConstants, VersionConstants
from bemani.data import Attempt, Score, Song, UserID
from bemani.frontend.base import FrontendBase
@ -73,7 +73,7 @@ class PopnMusicFrontend(FrontendBase):
}.get(attempt.data.get_int('medal'), 'No Play')
return formatted_attempt
def format_profile(self, profile: ValidatedDict, playstats: ValidatedDict) -> Dict[str, Any]:
def format_profile(self, profile: Profile, playstats: ValidatedDict) -> Dict[str, Any]:
formatted_profile = super().format_profile(profile, playstats)
formatted_profile['plays'] = playstats.get_int('total_plays')
return formatted_profile

View File

@ -4,7 +4,7 @@ from typing import Any, Dict, Iterator, Tuple
from flask_caching import Cache # type: ignore
from bemani.backend.reflec import ReflecBeatFactory, ReflecBeatBase
from bemani.common import GameConstants, ValidatedDict
from bemani.common import GameConstants, Profile, ValidatedDict
from bemani.data import Attempt, Data, Score, Song, UserID
from bemani.frontend.base import FrontendBase
@ -74,7 +74,7 @@ class ReflecBeatFrontend(FrontendBase):
formatted_attempt['medal'] = attempt.data.get_int('combo_type') * 1000 + attempt.data.get_int('clear_type')
return formatted_attempt
def format_profile(self, profile: ValidatedDict, playstats: ValidatedDict) -> Dict[str, Any]:
def format_profile(self, profile: Profile, playstats: ValidatedDict) -> Dict[str, Any]:
formatted_profile = super().format_profile(profile, playstats)
formatted_profile['plays'] = playstats.get_int('total_plays')
return formatted_profile

View File

@ -4,7 +4,7 @@ from typing import Any, Dict, Iterator, Tuple
from flask_caching import Cache # type: ignore
from bemani.backend.sdvx import SoundVoltexFactory, SoundVoltexBase
from bemani.common import GameConstants, ValidatedDict
from bemani.common import GameConstants, Profile, ValidatedDict
from bemani.data import Attempt, Data, Score, Song, UserID
from bemani.frontend.base import FrontendBase
@ -85,7 +85,7 @@ class SoundVoltexFrontend(FrontendBase):
formatted_attempt['medal'] = attempt.data.get_int('clear_type')
return formatted_attempt
def format_profile(self, profile: ValidatedDict, playstats: ValidatedDict) -> Dict[str, Any]:
def format_profile(self, profile: Profile, playstats: ValidatedDict) -> Dict[str, Any]:
formatted_profile = super().format_profile(profile, playstats)
formatted_profile['plays'] = playstats.get_int('total_plays')
return formatted_profile

View File

@ -3,7 +3,7 @@ import unittest
from unittest.mock import Mock
from bemani.backend.jubeat.prop import JubeatProp
from bemani.common import ValidatedDict
from bemani.common import Profile
from bemani.data.types import Achievement, UserID
@ -171,7 +171,7 @@ class TestJubeatProp(unittest.TestCase):
JubeatProp._get_league_scores(
data,
999,
[(UserID(1337), ValidatedDict())],
[(UserID(1337), Profile(JubeatProp.game, JubeatProp.version, "", 0))],
),
(
[(1337, 1368)],
@ -193,7 +193,7 @@ class TestJubeatProp(unittest.TestCase):
JubeatProp._get_league_scores(
data,
999,
[(UserID(1337), ValidatedDict())],
[(UserID(1337), Profile(JubeatProp.game, JubeatProp.version, "", 0))],
),
(
[],
@ -324,10 +324,16 @@ class TestJubeatProp(unittest.TestCase):
data.local.user = Mock()
# Test demoting a user at the bottom does nothing.
data.local.user.get_profile = Mock(return_value=ValidatedDict({
'league_class': 1,
'league_subclass': 5,
}))
data.local.user.get_profile = Mock(return_value=Profile(
JubeatProp.game,
JubeatProp.version,
"",
0,
{
'league_class': 1,
'league_subclass': 5,
},
))
JubeatProp._modify_profile(
data,
UserID(1337),
@ -336,10 +342,16 @@ class TestJubeatProp(unittest.TestCase):
self.assertFalse(data.local.user.put_profile.called)
# Test promoting a user at the top does nothing.
data.local.user.get_profile = Mock(return_value=ValidatedDict({
'league_class': 4,
'league_subclass': 1,
}))
data.local.user.get_profile = Mock(return_value=Profile(
JubeatProp.game,
JubeatProp.version,
"",
0,
{
'league_class': 4,
'league_subclass': 1,
},
))
JubeatProp._modify_profile(
data,
UserID(1337),
@ -348,11 +360,17 @@ class TestJubeatProp(unittest.TestCase):
self.assertFalse(data.local.user.put_profile.called)
# Test regular promotion updates profile properly
data.local.user.get_profile = Mock(return_value=ValidatedDict({
'league_class': 1,
'league_subclass': 5,
'league_is_checked': True,
}))
data.local.user.get_profile = Mock(return_value=Profile(
JubeatProp.game,
JubeatProp.version,
"",
0,
{
'league_class': 1,
'league_subclass': 5,
'league_is_checked': True,
},
))
JubeatProp._modify_profile(
data,
UserID(1337),
@ -375,11 +393,17 @@ class TestJubeatProp(unittest.TestCase):
data.local.user.put_profile.reset_mock()
# Test regular demote updates profile properly
data.local.user.get_profile = Mock(return_value=ValidatedDict({
'league_class': 1,
'league_subclass': 3,
'league_is_checked': True,
}))
data.local.user.get_profile = Mock(return_value=Profile(
JubeatProp.game,
JubeatProp.version,
"",
0,
{
'league_class': 1,
'league_subclass': 3,
'league_is_checked': True,
},
))
JubeatProp._modify_profile(
data,
UserID(1337),
@ -402,15 +426,21 @@ class TestJubeatProp(unittest.TestCase):
data.local.user.put_profile.reset_mock()
# Test demotion after not checking doesn't update old values
data.local.user.get_profile = Mock(return_value=ValidatedDict({
'league_class': 1,
'league_subclass': 4,
'league_is_checked': False,
'last': {
data.local.user.get_profile = Mock(return_value=Profile(
JubeatProp.game,
JubeatProp.version,
"",
0,
{
'league_class': 1,
'league_subclass': 3,
'league_subclass': 4,
'league_is_checked': False,
'last': {
'league_class': 1,
'league_subclass': 3,
},
},
}))
))
JubeatProp._modify_profile(
data,
UserID(1337),