def leave_party(self, player_guid, force_disband=False, is_kicked=False): disband = player_guid == self.group.leader_guid or len( self.members) == 2 or force_disband was_formed = self.is_party_formed() # Group was disbanded before even existing. if disband and player_guid == self.group.leader_guid and len( self.members) == 0: leader_player = WorldSessionStateHandler.find_player_by_guid( self.group.leader_guid) if leader_player: leader_player.group_manager = None leader_player.has_pending_invite = False else: for member in list(self.members.values()): # Avoid mutability. if disband or member.guid == player_guid: member_player = WorldSessionStateHandler.find_player_by_guid( member.guid) if member_player: member_player.has_pending_group_invite = False member_player.group_manager = None member_player.group_status = WhoPartyStatus.WHO_PARTY_STATUS_NOT_IN_PARTY if member.guid == self.group.leader_guid: GroupManager._remove_leader_flag(member) if not disband: self._set_previous_looter(member.guid) RealmDatabaseManager.group_remove_member(member) self.members.pop(member.guid) if was_formed and member_player and disband and not is_kicked and member.guid != player_guid: disband_packet = PacketWriter.get_packet( OpCode.SMSG_GROUP_DESTROYED) member_player.enqueue_packet(disband_packet) elif was_formed and member_player and disband and member.guid != player_guid: disband_packet = PacketWriter.get_packet( OpCode.SMSG_GROUP_DESTROYED) member_player.enqueue_packet(disband_packet) elif was_formed and member_player and not is_kicked: GroupManager.send_group_operation_result( member_player, PartyOperations.PARTY_OP_LEAVE, member_player.player.name, PartyResults.ERR_PARTY_RESULT_OK) if member_player and is_kicked and member.guid == player_guid: # 'You have been removed from the group.' message packet = PacketWriter.get_packet( OpCode.SMSG_GROUP_UNINVITE) member_player.enqueue_packet(packet) if disband: self.flush() else: self.send_update()
def disconnect(self): try: if self.player_mgr: self.player_mgr.logout() except AttributeError: pass self.keep_alive = False WorldSessionStateHandler.remove(self) try: self.request.shutdown(socket.SHUT_RDWR) self.request.close() except OSError: pass
def remove_member(self, player_guid): member = self.members[player_guid] guild_master = self.guild_master data = pack('<2B', GuildEvents.GUILD_EVENT_REMOVED, 2) target_name_bytes = PacketWriter.string_to_bytes(member.character.name) data += pack( f'<{len(target_name_bytes)}s', target_name_bytes ) remover_name_bytes = PacketWriter.string_to_bytes(guild_master.character.name) data += pack( f'<{len(remover_name_bytes)}s', remover_name_bytes ) packet = PacketWriter.get_packet(OpCode.SMSG_GUILD_EVENT, data) self.send_message_to_guild(packet, GuildChatMessageTypes.G_MSGTYPE_ALL) # Pop it at the end, so he gets the above message. RealmDatabaseManager.guild_remove_member(member) player_mgr = WorldSessionStateHandler.find_player_by_guid(player_guid) self.members.pop(player_guid) if player_mgr: self.build_update(player_mgr, unset=True) player_mgr.guild_manager = None player_mgr.set_dirty()
def handle(world_session, socket, reader): if len(reader.data) >= 16: # Avoid handling empty petition offer packet. petition_item_guid, target_player_guid = unpack('<2Q', reader.data[:16]) target_player_mgr = WorldSessionStateHandler.find_player_by_guid(target_player_guid) if petition_item_guid > 0: if not target_player_mgr: GuildManager.send_guild_command_result(world_session.player_mgr, GuildTypeCommand.GUILD_INVITE_S, 'Player', GuildCommandResults.GUILD_PLAYER_NOT_FOUND) elif target_player_mgr.guild_manager: GuildManager.send_guild_command_result(world_session.player_mgr, GuildTypeCommand.GUILD_INVITE_S, target_player_mgr.player.name, GuildCommandResults.GUILD_ALREADY_IN_GUILD) if target_player_mgr.team != world_session.player_mgr.team: GuildManager.send_guild_command_result(world_session.player_mgr, GuildTypeCommand.GUILD_INVITE_S, '', GuildCommandResults.GUILD_NOT_ALLIED) else: petition = PetitionManager.get_petition(petition_item_guid) if petition: packet = PetitionManager.build_signatures_packet(petition) target_player_mgr.enqueue_packet(packet) else: PetitionManager.send_petition_sign_result(world_session.player_mgr, PetitionError.PETITION_UNKNOWN_ERROR) return 0
def handle(world_session, socket, reader): target_name = PacketReader.read_string(reader.data, 0).strip() target_player_mgr = WorldSessionStateHandler.find_player_by_name( target_name) player_mgr = world_session.player_mgr if not player_mgr.guild_manager: GuildManager.send_guild_command_result( player_mgr, GuildTypeCommand.GUILD_INVITE_S, '', GuildCommandResults.GUILD_PLAYER_NOT_IN_GUILD) if not target_player_mgr: GuildManager.send_guild_command_result( player_mgr, GuildTypeCommand.GUILD_INVITE_S, target_name, GuildCommandResults.GUILD_PLAYER_NOT_FOUND) elif player_mgr != player_mgr.guild_manager.guild_master: GuildManager.send_guild_command_result( player_mgr, GuildTypeCommand.GUILD_FOUNDER_S, '', GuildCommandResults.GUILD_PERMISSIONS) elif not target_player_mgr.guild_manager or not player_mgr.guild_manager.is_member( target_player_mgr): GuildManager.send_guild_command_result( player_mgr, GuildTypeCommand.GUILD_INVITE_S, target_name, GuildCommandResults.GUILD_PLAYER_NOT_IN_GUILD) else: player_mgr.guild_manager.set_guild_master(target_player_mgr) return 0
def handle(world_session, socket, reader): target_name = PacketReader.read_string(reader.data, 0).strip() target_player_mgr = WorldSessionStateHandler.find_player_by_name( target_name) friend_result = None if not target_player_mgr: friend_result = FriendResults.FRIEND_NOT_FOUND elif world_session.player_mgr.team != target_player_mgr.team: friend_result = FriendResults.FRIEND_ENEMY elif world_session.player_mgr.guid == target_player_mgr.guid: friend_result = FriendResults.FRIEND_SELF elif world_session.player_mgr.friends_manager.has_friend( target_player_mgr): friend_result = FriendResults.FRIEND_ALREADY if not friend_result: world_session.player_mgr.friends_manager.add_friend( target_player_mgr) else: data = pack('<B', friend_result) world_session.player_mgr.session.request.sendall( PacketWriter.get_packet(OpCode.SMSG_FRIEND_STATUS, data)) return 0
def handle(world_session, socket, reader): target_name = PacketReader.read_string(reader.data, 0).strip() target_player_mgr = WorldSessionStateHandler.find_player_by_name( target_name) player_mgr = world_session.player_mgr if not player_mgr.guild_manager: GuildManager.send_guild_command_result( player_mgr, GuildTypeCommand.GUILD_INVITE_S, '', GuildCommandResults.GUILD_PLAYER_NOT_IN_GUILD) # TODO I guess not only GM should be able to promote? elif player_mgr != player_mgr.guild_manager.guild_master: GuildManager.send_guild_command_result( player_mgr, GuildTypeCommand.GUILD_INVITE_S, '', GuildCommandResults.GUILD_PERMISSIONS) elif not target_player_mgr: GuildManager.send_guild_command_result( player_mgr, GuildTypeCommand.GUILD_INVITE_S, target_name, GuildCommandResults.GUILD_PLAYER_NOT_FOUND) elif not player_mgr.guild_manager.is_member(target_player_mgr): GuildManager.send_guild_command_result( player_mgr, GuildTypeCommand.GUILD_INVITE_S, target_name, GuildCommandResults.GUILD_PLAYER_NOT_IN_GUILD) elif not player_mgr.guild_manager.promote_rank(target_player_mgr): GuildManager.send_guild_command_result( player_mgr, GuildTypeCommand.GUILD_INVITE_S, '', GuildCommandResults.GUILD_INTERNAL) return 0
def create_guild(player_mgr, guild_name, petition=None): if not TextChecker.valid_text(guild_name, is_guild=True): GuildManager.send_guild_command_result(player_mgr, GuildTypeCommand.GUILD_CREATE_S, '', GuildCommandResults.GUILD_NAME_INVALID) return False if guild_name in GuildManager.GUILDS or not petition and RealmDatabaseManager.guild_petition_get_by_name(guild_name): GuildManager.send_guild_command_result(player_mgr, GuildTypeCommand.GUILD_CREATE_S, guild_name, GuildCommandResults.GUILD_NAME_EXISTS) return False if player_mgr.guild_manager: GuildManager.send_guild_command_result(player_mgr, GuildTypeCommand.GUILD_CREATE_S, '', GuildCommandResults.GUILD_ALREADY_IN_GUILD) return False guild = GuildManager._create_guild("", guild_name, -1, -1, -1, -1, -1, player_mgr.guid) player_mgr.guild_manager = GuildManager(guild) player_mgr.guild_manager.add_new_member(player_mgr, is_guild_master=True) if petition: for member_signer in petition.characters: member = WorldSessionStateHandler.find_player_by_guid(member_signer.guid) if member: player_mgr.guild_manager.add_new_member(member, False) else: offline_member = RealmDatabaseManager.character_get_by_guid(member_signer.guid) if offline_member: player_mgr.guild_manager.add_new_offline_member(offline_member) return True
def _build_party_member_stats(group_member): player_mgr = WorldSessionStateHandler.find_player_by_guid( group_member.guid) character = None # If player is offline, build stats based on db information. if not player_mgr or not player_mgr.online: player_mgr = None character = RealmDatabaseManager.character_get_by_guid( group_member.guid) data = pack( '<Q2IB6I3f', player_mgr.guid if player_mgr else character.guid, player_mgr.health if player_mgr else 0, player_mgr.max_health if player_mgr else 0, player_mgr.power_type if player_mgr else 0, player_mgr.get_power_type_value() if player_mgr else 0, player_mgr.get_max_power_value() if player_mgr else 0, player_mgr.level if player_mgr else character.level, player_mgr.map_ if player_mgr else character.map, # Client expects an AreaNumber from AreaTable, not a zone id. MapManager.get_area_number_by_zone_id( player_mgr.zone if player_mgr else character.zone), player_mgr.class_ if player_mgr else character.class_, player_mgr.location.x if player_mgr else character.position_x, player_mgr.location.y if player_mgr else character.position_y, player_mgr.location.z if player_mgr else character.position_z, ) return PacketWriter.get_packet(OpCode.SMSG_PARTY_MEMBER_STATS, data)
def _remove_leader_flag(member): player_mgr = WorldSessionStateHandler.find_player_by_guid(member.guid) if player_mgr: player_mgr.player.extra_flags &= ~PlayerFlags.PLAYER_FLAGS_GROUP_LEADER player_mgr.player_bytes_2 = unpack('<I', pack('<4B', player_mgr.player.extra_flags, player_mgr.player.facialhair, player_mgr.player.bankslots, 0))[0] player_mgr.set_uint32(PlayerFields.PLAYER_BYTES_2, player_mgr.player_bytes_2) player_mgr.set_dirty()
def send_update(self): for member in list(self.members.keys()): player_mgr = WorldSessionStateHandler.find_player_by_guid(member) if player_mgr: player_mgr.enqueue_packet(self._build_group_list(player_mgr)) self.send_party_members_stats()
def summon(world_session, args): player_name = args is_online = True player = WorldSessionStateHandler.find_player_by_name(player_name) if player: player.teleport(world_session.player_mgr.map_, world_session.player_mgr.location) else: is_online = False player = RealmDatabaseManager.character_get_by_name(player_name) if player: if not is_online: player.map = world_session.player_mgr.map_ player.zone = world_session.player_mgr.zone player.position_x = world_session.player_mgr.location.x player.position_y = world_session.player_mgr.location.y player.position_z = world_session.player_mgr.location.z RealmDatabaseManager.character_update(player) else: return -1, 'player not found.' return 0, 'Summoned player %s (%s).' % ( player_name.capitalize(), 'Online' if is_online else 'Offline')
def send_packet_to_members(self, packet, ignore=None, source=None, use_ignore=False, exclude=None, surrounding_only=False): if surrounding_only and source: surrounding_players = MapManager.get_surrounding_players( source).values() members = [ self.members[player.guid] for player in surrounding_players if player.guid in self.members ] else: members = self.members.values() for member in members: if exclude and member.guid == exclude.guid: continue player_mgr = WorldSessionStateHandler.find_player_by_guid( member.guid) if not player_mgr or not player_mgr.online: continue if ignore and player_mgr.guid in ignore: continue if use_ignore and source and player_mgr.friends_manager.has_ignore( source.guid): continue player_mgr.enqueue_packet(packet)
def set_guild_master(self, player_guid): member = self.members[player_guid] previous_gm = self.guild_master member.rank = int(GuildRank.GUILDRANK_GUILD_MASTER) previous_gm.rank = int(GuildRank.GUILDRANK_OFFICER) if previous_gm: data = pack('<2B', GuildEvents.GUILD_EVENT_LEADER_CHANGED, 2) name_bytes = PacketWriter.string_to_bytes( previous_gm.character.name) data += pack(f'<{len(name_bytes)}s', name_bytes) name_bytes = PacketWriter.string_to_bytes(member.character.name) data += pack(f'<{len(name_bytes)}s', name_bytes) packet = PacketWriter.get_packet(OpCode.SMSG_GUILD_EVENT, data) self.send_message_to_guild(packet, GuildChatMessageTypes.G_MSGTYPE_ALL) self.update_db_guild_members() player_mgr = WorldSessionStateHandler.find_player_by_guid(player_guid) if player_mgr: player_mgr.set_uint32(PlayerFields.PLAYER_GUILDRANK, member.rank) player_mgr.set_dirty()
def goplayer(world_session, args): player_name = args is_online = True player = WorldSessionStateHandler.find_player_by_name(player_name) player_location = None map_ = 0 if player: player_location = player.location map_ = player.map_ else: is_online = False player = RealmDatabaseManager.character_get_by_name(player_name) if player: if not is_online: player_location = Vector(float(player.position_x), float(player.position_y), float(player.position_z)) map_ = player.map else: return -1, 'player not found.' world_session.player_mgr.teleport(int(map_), player_location) return 0, 'Teleported to player %s (%s).' % ( player_name.capitalize(), 'Online' if is_online else 'Offline')
def _remove_leader_flag(member): player_mgr = WorldSessionStateHandler.find_player_by_guid(member.guid) if player_mgr: player_mgr.player.extra_flags &= ~PlayerFlags.PLAYER_FLAGS_GROUP_LEADER player_mgr.player_bytes_2 = player_mgr.get_player_bytes_2() player_mgr.set_uint32(PlayerFields.PLAYER_BYTES_2, player_mgr.player_bytes_2)
def demote_rank(self, player_guid): member = self.members[player_guid] if member.rank == GuildRank.GUILDRANK_GUILD_MASTER: return False if member.rank == GuildRank.GUILDRANK_INITIATE: # Use initiate as lowest for now return False else: member.rank += 1 data = pack('<2B', GuildEvents.GUILD_EVENT_DEMOTION, 2) target_name_bytes = PacketWriter.string_to_bytes(member.character.name) data += pack(f'<{len(target_name_bytes)}s', target_name_bytes) rank_name = GuildRank(member.rank).name.split('_')[1].capitalize() rank_name_bytes = PacketWriter.string_to_bytes(rank_name) data += pack(f'<{len(rank_name_bytes)}s', rank_name_bytes) packet = PacketWriter.get_packet(OpCode.SMSG_GUILD_EVENT, data) self.send_message_to_guild(packet, GuildChatMessageTypes.G_MSGTYPE_ALL) player_mgr = WorldSessionStateHandler.find_player_by_guid(member.guid) if player_mgr: player_mgr.set_uint32(PlayerFields.PLAYER_GUILDRANK, member.rank) player_mgr.set_dirty() self.update_db_guild_members() return True
def handle(world_session, socket, reader): target_name = PacketReader.read_string(reader.data, 0).strip() online_player = WorldSessionStateHandler.find_player_by_name( target_name) offline_player = None friend_result_error = None # Try to pull the character from DB. if not online_player: offline_player = RealmDatabaseManager.character_get_by_name( target_name) target_guid = online_player.guid if online_player else offline_player.guid if offline_player else None target_team = online_player.team if online_player else PlayerManager.get_team_for_race( offline_player.race) if offline_player else None if not online_player and not offline_player: friend_result_error = FriendResults.FRIEND_NOT_FOUND elif world_session.player_mgr.team != target_team: friend_result_error = FriendResults.FRIEND_ENEMY elif world_session.player_mgr.guid == target_guid: friend_result_error = FriendResults.FRIEND_SELF elif world_session.player_mgr.friends_manager.has_friend(target_guid): friend_result_error = FriendResults.FRIEND_ALREADY if not friend_result_error: world_session.player_mgr.friends_manager.add_friend(target_guid) else: data = pack('<B', friend_result_error) world_session.enqueue_packet( PacketWriter.get_packet(OpCode.SMSG_FRIEND_STATUS, data)) return 0
def handle(world_session, socket, reader): chat_type, lang = unpack('<2I', reader.data[:8]) message = '' guid = 0 chat_flags = 0 # Return if no player if not world_session.player_mgr: return 0 # Override language to universal for GMs if world_session.player_mgr.is_gm: lang = Languages.LANG_UNIVERSAL # Say, Yell, Emote if chat_type == ChatMsgs.CHAT_MSG_SAY \ or chat_type == ChatMsgs.CHAT_MSG_EMOTE \ or chat_type == ChatMsgs.CHAT_MSG_YELL: message = PacketReader.read_string(reader.data, 8) guid = world_session.player_mgr.guid chat_flags = world_session.player_mgr.chat_flags # Only send message if it's not a command if not ChatHandler.check_if_command(world_session, message): ChatManager.send_chat_message( world_session, guid, chat_flags, message, chat_type, lang, ChatHandler.get_range_by_type(chat_type)) # Whisper elif chat_type == ChatMsgs.CHAT_MSG_WHISPER: target_name = PacketReader.read_string(reader.data, 8).strip() target_player_mgr = WorldSessionStateHandler.find_player_by_name( target_name) if not target_player_mgr: ChatManager.send_system_message( world_session, 'No player named \'%s\' is currently playing.' % target_name.capitalize()) return 0 message = PacketReader.read_string(reader.data, 8 + len(target_name) + 1) if not ChatHandler.check_if_command(world_session, message): # Always whisper in universal language when speaking with a GM if target_player_mgr.is_gm: lang = Languages.LANG_UNIVERSAL ChatManager.send_whisper(world_session.player_mgr, target_player_mgr, message, lang) return 0 # Party elif chat_type == ChatMsgs.CHAT_MSG_PARTY: message = PacketReader.read_string(reader.data, 8) ChatManager.send_party(world_session.player_mgr, message, lang) return 0 # Guild elif chat_type == ChatMsgs.CHAT_MSG_GUILD: # TODO: Implement return 0 return 0
def send_update_to_friends(self): have_me_as_friend = RealmDatabaseManager.character_get_friends_of( self.owner.guid) for friend in have_me_as_friend: player_mgr = WorldSessionStateHandler.find_player_by_guid( friend.guid) if player_mgr: player_mgr.friends_manager.send_friends()
def send_offline_notification(self): sessions = WorldSessionStateHandler.get_world_sessions() for session in sessions: if session and session.player_mgr: if session.player_mgr.friends_manager.has_friend(self.owner): data = pack('<BQB', FriendResults.FRIEND_OFFLINE, self.owner.guid, 0) packet = PacketWriter.get_packet(OpCode.SMSG_FRIEND_STATUS, data) session.player_mgr.session.request.sendall(packet)
def ann(world_session, args): ann = str(args) for session in WorldSessionStateHandler.get_world_sessions(): if session.player_mgr and session.player_mgr.is_online: ChatManager.send_system_message(session, '[SERVER] %s' % ann) return 0, ''
def send_offline_notification(self): have_me_as_friend = RealmDatabaseManager.character_get_friends_of(self.owner.guid) for friend in have_me_as_friend: player_mgr = WorldSessionStateHandler.find_player_by_guid(friend.guid) if player_mgr and not player_mgr.friends_manager.has_ignore(self.owner.guid): data = pack('<BQB', FriendResults.FRIEND_OFFLINE, self.owner.guid, 0) packet = PacketWriter.get_packet(OpCode.SMSG_FRIEND_STATUS, data) player_mgr.session.enqueue_packet(packet) player_mgr.friends_manager.send_friends()
def handle_permanent_enchant(casting_spell, effect, caster, target, is_temporary=False): if caster.get_type_id() != ObjectTypeIds.ID_PLAYER: return # Calculate slot, duration and charges. enchantment_slot = EnchantmentSlots.PermanentSlot if not is_temporary else EnchantmentSlots.TemporarySlot duration = 0 charges = 0 if is_temporary: # Temporary enchantments from professions (enchanting) have a duration of 1h while others have 30min. duration = 30 * 60 if not casting_spell.spell_entry.CastUI else 60 * 60 charges = int( WorldDatabaseManager.spell_enchant_charges_get_by_spell( casting_spell.spell_entry.ID)) owner_player = WorldSessionStateHandler.find_player_by_guid( target.get_owner_guid()) if not owner_player: return # If this enchantment is being applied on a trade, update trade status with proposed enchant. # Enchant will be applied after trade is accepted. if owner_player != caster: if caster.trade_data and caster.trade_data.other_player and caster.trade_data.other_player.trade_data: # Get the trade slot for the item being enchanted. trade_slot = caster.trade_data.other_player.trade_data.get_slot_by_item( target) # Update proposed enchantment on caster. caster.trade_data.set_proposed_enchant( trade_slot, casting_spell.spell_entry.ID, enchantment_slot, effect.misc_value, duration, charges) # Update proposed enchantment on receiver. caster.trade_data.other_player.trade_data.set_proposed_enchant( trade_slot, casting_spell.spell_entry.ID, enchantment_slot, effect.misc_value, duration, charges) # Update trade status, this will propagate to both players. caster.trade_data.update_trade_status() return # Apply permanent enchantment. owner_player.enchantment_manager.set_item_enchantment( target, enchantment_slot, effect.misc_value, duration, charges) caster.skill_manager.handle_profession_skill_gain_chance( casting_spell.spell_entry.ID) # Save item. target.save()
def _target_or_self(world_session): if world_session.player_mgr.current_selection \ and world_session.player_mgr.current_selection != world_session.player_mgr.guid: player_mgr = WorldSessionStateHandler.find_player_by_guid( world_session.player_mgr.current_selection) if player_mgr: return player_mgr return world_session.player_mgr
def send_invite_decline(self, player_name): player_mgr = WorldSessionStateHandler.find_player_by_guid( self.group.leader_guid) if player_mgr: name_bytes = PacketWriter.string_to_bytes(player_name) data = pack(f'<{len(name_bytes)}s', name_bytes) packet = PacketWriter.get_packet(OpCode.SMSG_GROUP_DECLINE, data) player_mgr.enqueue_packet(packet)
def send_friends(self): data = pack('<B', len(self.friends)) for friend in self.friends: player_mgr = WorldSessionStateHandler.find_player_by_guid(friend) if player_mgr: data += pack('<QB3I', player_mgr.guid, 1, player_mgr.zone, player_mgr.level, player_mgr.player.class_) packet = PacketWriter.get_packet(OpCode.SMSG_FRIEND_LIST, data) self.owner.session.request.sendall(packet)
def send_ignores(self): data = pack('<B', len(self.ignores)) for ignore in self.ignores.values(): player_mgr = WorldSessionStateHandler.find_player_by_guid(ignore) if player_mgr: data += pack('<Q', player_mgr.guid) packet = PacketWriter.get_packet(OpCode.SMSG_IGNORE_LIST, data) self.owner.session.request.sendall(packet)
def worldoff(world_session, args): # Prevent more sockets to be opened WorldManager.WORLD_ON = False # Kick all players for session in WorldSessionStateHandler.get_world_sessions(): if session.player_mgr and session.player_mgr.is_online: session.keep_alive = False return 0, ''
def send_update(self): leader_name_bytes = PacketWriter.string_to_bytes( self.members[self.group.leader_guid].character.name) leader = WorldSessionStateHandler.find_player_by_guid( self.group.leader_guid) # Header data = pack( f'<I{len(leader_name_bytes)}sQB', len(self.members), leader_name_bytes, self.group.leader_guid, 1 if leader and leader.online else 0 # If party leader is online or not ) # Fill all group members. for member in self.members.values(): if member.guid == self.group.leader_guid: continue player_mgr = WorldSessionStateHandler.find_player_by_guid( member.guid) member_name_bytes = PacketWriter.string_to_bytes( member.character.name) data += pack( f'<{len(member_name_bytes)}sQB', member_name_bytes, member.guid, 1 if player_mgr and player_mgr.online else 0, # If member is online or not ) data += pack( '<BQ', self.group.loot_method, self.group.loot_master # Master Looter guid ) packet = PacketWriter.get_packet(OpCode.SMSG_GROUP_LIST, data) self.send_packet_to_members(packet) self.send_party_members_stats()