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.get_int('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.get_int('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')