async def user_stats(args: List[str], player: 'Player', _): mode = GameModes(0) if len(args) < 1: nickname = player.name else: nickname = args[0] if len(args) > 1 and args[1].isdigit(): mode = GameModes(int(args[1])) if mode > 3: return "GameMode is incorrect" token = Context.players.get_token(name=nickname.lower()) if not token: return 'Player not online' mode_str = GameModes.resolve_to_str(mode) stats = token.stats[mode] acc = "{0:.2f}%".format(stats.accuracy) return (f"User: {nickname}\n" f"ID: {token.id}\n" "---------------------\n" f"Stats for {mode_str} #{stats.leaderboard_rank}\n" f"Ranked score: {new_utils.humanize(stats.ranked_score)}\n" f"Accuracy: {acc}\n" f"Play count: {new_utils.humanize(stats.total_plays)}\n" f"Total score: {new_utils.humanize(stats.total_score)}\n" f"PP count: {new_utils.humanize(stats.pp)}")
def update(self, **kwargs): self.action = Action(kwargs.get('action', 0)) self.action_text = kwargs.get('action_text', '') self.map_md5 = kwargs.get('map_md5', '') self.mode = GameModes(kwargs.get('mode', 0)) self.mods = Mods(kwargs.get('mods', 0)) self.map_id = kwargs.get('map_id', 0)
async def read_match(data: bytes) -> TypedReadMatch: buffer = KurisoBuffer(None) await buffer.write_to_buffer(data) await buffer.read_int_16( ) # skip 3 bytes for id and inProgress because default is False await buffer.read_byte() match_type = MatchTypes(await buffer.read_byte()) mods = Mods(await buffer.read_int_32()) name = await buffer.read_osu_string() password = await buffer.read_osu_string() beatmap_name = await buffer.read_osu_string() beatmap_id = await buffer.read_int_32() beatmap_md5 = await buffer.read_osu_string() slots = [Slot() for _ in range(0, 16)] # make slots for slot in slots: slot.status = SlotStatus(await buffer.read_byte()) for slot in slots: slot.team = SlotTeams(await buffer.read_byte()) for slot in slots: if slot.status.value & SlotStatus.HasPlayer: await buffer.read_int_32() host_id = await buffer.read_int_32() play_mode = GameModes(await buffer.read_byte()) scoring_type = MatchScoringTypes(await buffer.read_byte()) team_type = MatchTeamTypes(await buffer.read_byte()) is_freemod = await buffer.read_bool() match_freemod = MultiSpecialModes(int(is_freemod)) if is_freemod: for slot in slots: slot.mods = Mods(await buffer.read_int_32()) seed = await buffer.read_int_32() t_dict = { 'match_type': match_type, 'mods': mods, 'name': name, 'password': password, 'beatmap_name': beatmap_name, 'beatmap_id': beatmap_id, 'beatmap_md5': beatmap_md5, 'slots': slots, 'host_id': host_id, 'play_mode': play_mode, 'scoring_type': scoring_type, 'team_type': team_type, 'match_freemod': match_freemod, 'seed': seed } return t_dict
async def mp_map(args: List[str], player: 'Player', message: 'Message'): if not player.match: return 'You are not in any match' if not can_take_match(player, player.match, check_tourney_host=True): return 'You cant do anything with that match' if (len(args) < 2 or not args[1].isdigit()) or (len(args) == 3 and not args[2].isdigit()): return "Wrong syntax: !mp map <beatmapid> [<gamemode>]" beatmapID = int(args[1]) gameMode = int(args[2]) if len(args) == 3 else 0 if gameMode < 0 or gameMode > 3: return "Gamemode must be 0, 1, 2 or 3" beatmapData = await Context.mysql.fetch( "SELECT * FROM beatmaps WHERE beatmap_id = %s LIMIT 1", [beatmapID] ) if not beatmapData: return ("The beatmap you've selected couldn't be found in the database." "If the beatmap id is valid, please load the scoreboard first in " "order to cache it, then try again.") player.match.beatmap_id = beatmapID player.match.beatmap_name = beatmapData["song_name"] player.match.beatmap_md5 = beatmapData["beatmap_md5"] player.selected_game_mode = GameModes(gameMode) await player.match.unready_everyone() await player.match.update_match() return "Match map has been updated"
async def update_action(packet_data: bytes, p: 'Player'): resolved_data = await PacketResolver.read_new_presence(packet_data) if GameModes(resolved_data['mode']) != p.selected_game_mode: # okay, we have new gamemode here. We need to send userstats and new user panel p.selected_game_mode = GameModes(resolved_data['mode']) await p.update_stats(p.selected_game_mode) # in this case, we should send only new stats p.selected_game_mode = GameModes(resolved_data['mode']) p.pr_status.update(**resolved_data) data = await PacketBuilder.UserStats(p) + await PacketBuilder.UserPresence( p) p.enqueue(data) for spec in p.spectators: spec.enqueue(data) return True
async def update_action(packet_data: bytes, p: 'Player'): resolved_data = await PacketResolver.read_new_presence(packet_data) if GameModes(resolved_data['mode']) != p.selected_game_mode: # okay, we have new gamemode here. We need to send userstats and new user panel p.selected_game_mode = GameModes(resolved_data['mode']) await p.update_stats(p.selected_game_mode) # in this case, we should send only new stats p.selected_game_mode = GameModes(resolved_data['mode']) p.pr_status.update(**resolved_data) data = await PacketBuilder.UserStats(p) + await PacketBuilder.UserPresence( p) for user in Context.players.get_all_tokens(): if user.is_restricted: continue user.enqueue(data) return True
async def update_stats(self, selected_mode: GameModes = None) -> bool: for mode in GameModes if not selected_mode else [selected_mode]: res = await Context.mysql.fetch( 'select total_score_{0} as total_score, ranked_score_{0} as ranked_score, ' 'pp_{0} as pp, playcount_{0} as total_plays, avg_accuracy_{0} as accuracy, playtime_{0} as playtime ' 'from users_stats where id = %s'.format( GameModes.resolve_to_str(mode)), [self.id]) if not res: logger.elog( f"[Player/{self.name}] Can't parse stats for {GameModes.resolve_to_str(mode)}" ) return False res['leaderboard_rank'] = 0 self.stats[mode].update(**res) return True