1
0
mirror of synced 2024-11-24 14:30:11 +01:00
bemaniutils/bemani/backend/museca/common.py

203 lines
6.8 KiB
Python

from bemani.backend.museca.base import MusecaBase
from bemani.common import ID
from bemani.protocol import Node
class MusecaGameShopHandler(MusecaBase):
def handle_game_3_shop_request(self, request: Node) -> Node:
self.update_machine_name(request.child_value('shopname'))
# Respond with number of milliseconds until next request
game = Node.void('game_3')
game.add_child(Node.u32('nxt_time', 1000 * 5 * 60))
return game
class MusecaGameHiscoreHandler(MusecaBase):
def handle_game_3_hiscore_request(self, request: Node) -> Node:
# Grab location for local scores
locid = ID.parse_machine_id(request.child_value('locid'))
# Start the response packet
game = Node.void('game_3')
# First, grab hit chart
playcounts = self.data.local.music.get_hit_chart(self.game, self.version, 1024)
hitchart = Node.void('hitchart')
game.add_child(hitchart)
for (songid, count) in playcounts:
info = Node.void('info')
hitchart.add_child(info)
info.add_child(Node.u32('id', songid))
info.add_child(Node.u32('cnt', count))
# Now, grab user records
records = self.data.remote.music.get_all_records(self.game, self.version)
users = {
uid: prof for (uid, prof) in
self.get_any_profiles([r[0] for r in records])
}
hiscore_allover = Node.void('hiscore_allover')
game.add_child(hiscore_allover)
# Output records
for (userid, score) in records:
info = Node.void('info')
if userid not in users:
raise Exception('Logic error, could not find profile for user!')
profile = users[userid]
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.extid)))
info.add_child(Node.u32('score', score.points))
# Add to global scores
hiscore_allover.add_child(info)
# Now, grab local records
area_users = [
uid for (uid, prof) in self.data.local.user.get_all_profiles(self.game, self.version)
if prof.get_int('loc', -1) == locid
]
records = self.data.local.music.get_all_records(self.game, self.version, userlist=area_users)
missing_players = [
uid for (uid, _) in records
if uid not in users
]
for (uid, prof) in self.get_any_profiles(missing_players):
users[uid] = prof
hiscore_location = Node.void('hiscore_location')
game.add_child(hiscore_location)
# Output records
for (userid, score) in records:
info = Node.void('info')
if userid not in users:
raise Exception('Logic error, could not find profile for user!')
profile = users[userid]
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.extid)))
info.add_child(Node.u32('score', score.points))
# Add to global scores
hiscore_location.add_child(info)
# Now, grab clear rates
clear_rate = Node.void('clear_rate')
game.add_child(clear_rate)
clears = self.get_clear_rates()
for songid in clears:
for chart in clears[songid]:
if clears[songid][chart]['total'] > 0:
rate = float(clears[songid][chart]['clears']) / float(clears[songid][chart]['total'])
dnode = Node.void('d')
clear_rate.add_child(dnode)
dnode.add_child(Node.u32('id', songid))
dnode.add_child(Node.u32('type', chart))
dnode.add_child(Node.s16('cr', int(rate * 10000)))
return game
class MusecaGameFrozenHandler(MusecaBase):
def handle_game_3_frozen_request(self, request: Node) -> Node:
game = Node.void('game_3')
game.add_child(Node.u8('result', 0))
return game
class MusecaGameNewHandler(MusecaBase):
def handle_game_3_new_request(self, request: Node) -> Node:
refid = request.child_value('refid')
name = request.child_value('name')
loc = ID.parse_machine_id(request.child_value('locid'))
self.new_profile_by_refid(refid, name, loc)
root = Node.void('game_3')
return root
class MusecaGameSaveMusicHandler(MusecaBase):
def handle_game_3_save_m_request(self, request: Node) -> Node:
refid = request.child_value('refid')
if refid is not None:
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
else:
userid = None
# Doesn't matter if userid is None here, that's an anonymous score
musicid = request.child_value('music_id')
chart = request.child_value('music_type')
points = request.child_value('score')
combo = request.child_value('max_chain')
clear_type = self.game_to_db_clear_type(request.child_value('clear_type'))
grade = self.game_to_db_grade(request.child_value('score_grade'))
stats = {
'btn_rate': request.child_value('btn_rate'),
'long_rate': request.child_value('long_rate'),
'vol_rate': request.child_value('vol_rate'),
'critical': request.child_value('critical'),
'near': request.child_value('near'),
'error': request.child_value('error'),
}
# Save the score
self.update_score(
userid,
musicid,
chart,
points,
clear_type,
grade,
combo,
stats,
)
# Return a blank response
return Node.void('game_3')
class MusecaGamePlayEndHandler(MusecaBase):
def handle_game_3_play_e_request(self, request: Node) -> Node:
return Node.void('game_3')
class MusecaGameSaveHandler(MusecaBase):
def handle_game_3_save_request(self, request: Node) -> Node:
refid = request.child_value('refid')
if refid is not None:
userid = self.data.remote.user.from_refid(self.game, self.version, refid)
else:
userid = None
if userid is not None:
oldprofile = self.get_profile(userid)
newprofile = self.unformat_profile(userid, request, oldprofile)
else:
newprofile = None
if userid is not None and newprofile is not None:
self.put_profile(userid, newprofile)
return Node.void('game_3')