def handle(world_session, socket, reader): if world_session.player_mgr.is_alive and len(reader.data) >= 12: emote_text_id, guid = unpack('<IQ', reader.data) emote = DbcDatabaseManager.emote_text_get_by_id(emote_text_id) if emote: data = pack('<QI', world_session.player_mgr.guid, emote_text_id) target = GridManager.get_surrounding_unit_by_guid( world_session.player_mgr, guid, include_players=True) if not target: data += pack('<B', 0) elif target.get_type() == ObjectTypes.TYPE_PLAYER: player_name_bytes = PacketWriter.string_to_bytes( target.player.name) data += pack('<%us' % len(player_name_bytes), player_name_bytes) elif target.get_type( ) == ObjectTypes.TYPE_UNIT and target.creature_template: unit_name_bytes = PacketWriter.string_to_bytes( target.creature_template.name) data += pack('<%us' % len(unit_name_bytes), unit_name_bytes) else: data += pack('<B', 0) GridManager.send_surrounding_in_range( PacketWriter.get_packet(OpCode.SMSG_TEXT_EMOTE, data), world_session.player_mgr, config.World.Chat.ChatRange.emote_range) # Perform visual emote action if needed emote_id = emote.EmoteID state = StandState.UNIT_STANDING needs_broadcast = True if emote_text_id == Emotes.SIT: if not world_session.player_mgr.is_sitting: state = StandState.UNIT_SITTING world_session.player_mgr.stand_state = state elif emote_text_id == Emotes.STAND: world_session.player_mgr.stand_state = state elif emote_text_id == Emotes.SLEEP: if world_session.player_mgr.stand_state != StandState.UNIT_SLEEPING: state = StandState.UNIT_SLEEPING world_session.player_mgr.stand_state = state elif emote_text_id == Emotes.KNEEL: if world_session.player_mgr.stand_state != StandState.UNIT_KNEEL: state = StandState.UNIT_KNEEL world_session.player_mgr.stand_state = state else: needs_broadcast = False world_session.player_mgr.play_emote(emote_id) if needs_broadcast: world_session.player_mgr.flagged_for_update = True return 0
def handle(world_session, socket, reader): if len(reader.data) >= 8: # Avoid handling empty packet guid, quest_entry = unpack('<QL', reader.data[:12]) # quest giver is an npc or an item quest_giver = GridManager.get_surrounding_unit_by_guid( world_session.player_mgr, guid ) or world_session.player_mgr.inventory.get_item_info_by_guid( guid)[3].item_template if not quest_giver: Logger.error( "Error in CMSG_QUESTGIVER_QUERY_QUEST, could not find quest giver with guid of: %u" % guid) return 0 quest_giver_is_related = world_session.player_mgr.quest_manager.check_quest_giver_npc_is_related( quest_giver.entry, quest_entry) or quest_giver.start_quest == quest_entry if not quest_giver_is_related: Logger.error( "Error in CMSG_QUESTGIVER_QUERY_QUEST, quest giver %u was not related to quest %u" % (quest_giver.entry, quest_entry)) return 0 quest = WorldDatabaseManager.quest_get_by_entry(quest_entry) if not quest: Logger.error( "Error in CMSG_QUESTGIVER_QUERY_QUEST, could not find quest with an entry of: %u" % quest_entry) return 0 world_session.player_mgr.quest_manager.send_quest_giver_quest_details( quest, guid, True) return 0
def handle(world_session, socket, reader): if len(reader.data ) >= 8: # Avoid handling empty quest giver status packet quest_giver_guid = unpack('<Q', reader.data[:8])[0] quest_giver = GridManager.get_surrounding_unit_by_guid( world_session.player_mgr, quest_giver_guid) quest_giver_status = QuestGiverStatus.QUEST_GIVER_NONE if not quest_giver: Logger.error( "Error in CMSG_QUESTGIVER_STATUS_QUERY, could not find quest giver with guid of: %u" % quest_giver_guid) return 0 if world_session.player_mgr: if quest_giver.get_type() == ObjectTypes.TYPE_UNIT: quest_giver_status = world_session.player_mgr.quest_manager.get_dialog_status( quest_giver) elif quest_giver.get_type() == ObjectTypes.TYPE_GAMEOBJECT: # TODO: Proper handling for game object, check if this is needed quest_giver_status = QuestGiverStatus.QUEST_GIVER_NONE else: Logger.error( "Error in CMSG_QUESTGIVER_STATUS_QUERY, quest giver was an unexpected type of: %u" % quest_giver.object_type) world_session.player_mgr.quest_manager.send_quest_giver_status( quest_giver_guid, quest_giver_status) return 0
def handle_cast_attempt(self, spell_id, caster, target_guid, target_mask): spell = DbcDatabaseManager.SpellHolder.spell_get_by_id(spell_id) if not spell: return spell_target = GridManager.get_surrounding_unit_by_guid(caster, target_guid, include_players=True) if target_guid and target_guid != caster.guid else caster self.start_spell_cast(spell, caster, spell_target, target_mask)
def handle(world_session, socket, reader): if len(reader.data ) >= 8: # Avoid handling empty quest giver status packet quest_giver_guid = unpack('<Q', reader.data[:8])[0] quest_giver = None # NPC if quest_giver_guid & HighGuid.HIGHGUID_UNIT: quest_giver = GridManager.get_surrounding_unit_by_guid( world_session.player_mgr, quest_giver_guid) # Gameobject elif quest_giver_guid & HighGuid.HIGHGUID_GAMEOBJECT: quest_giver = GridManager.get_surrounding_gameobject_by_guid( world_session.player_mgr, quest_giver_guid) if not quest_giver: return 0 quest_giver_status = QuestGiverStatus.QUEST_GIVER_NONE if world_session.player_mgr: if quest_giver.get_type() == ObjectTypes.TYPE_UNIT: quest_giver_status = world_session.player_mgr.quest_manager.get_dialog_status( quest_giver) elif quest_giver.get_type() == ObjectTypes.TYPE_GAMEOBJECT: # TODO: Proper handling for game object quest_giver_status = QuestGiverStatus.QUEST_GIVER_NONE else: Logger.error( f'Error in CMSG_QUESTGIVER_STATUS_QUERY, quest giver was an unexpected type of: {quest_giver.object_type}' ) world_session.player_mgr.quest_manager.send_quest_giver_status( quest_giver_guid, quest_giver_status) return 0
def handle(world_session, socket, reader): if len(reader.data) >= 8: # Avoid handling empty debug AI state packet guid = unpack('<Q', reader.data[:8])[0] world_object = GridManager.get_surrounding_unit_by_guid( world_session.player_mgr, guid, include_players=True) # If no Unit or Player, try to get a Gameobject. if not world_object: world_object = GridManager.get_surrounding_gameobject_by_guid( world_session.player_mgr, guid) # Still no object with that Guid? Return. if not world_object: return 0 messages = world_object.get_debug_messages() data = pack('<QI', guid, len(messages)) for message in messages: message_bytes = PacketWriter.string_to_bytes( message[:127]) # Max length is 128 (127 + null byte). data += pack(f'<{len(message_bytes)}s', message_bytes) world_session.enqueue_packet( PacketWriter.get_packet(OpCode.SMSG_DEBUG_AISTATE, data)) return 0
def handle(world_session, socket, reader): if len(reader.data) >= 8: # Avoid handling empty ping packet npc_guid = unpack('<Q', reader.data[:8])[0] if npc_guid > 0: vendor = GridManager.get_surrounding_unit_by_guid(world_session.player_mgr, npc_guid) if vendor: vendor.send_inventory_list(world_session) return 0
def handle(world_session, socket, reader): if len(reader.data) >= 8: # Avoid handling empty attack swing packet # TODO: Finish implementing this enemy_guid = unpack('<Q', reader.data[:8])[0] enemy = GridManager.get_surrounding_unit_by_guid( world_session.player_mgr, enemy_guid, include_players=True) data = pack('<2Q', world_session.player_mgr.guid, enemy_guid) socket.sendall( PacketWriter.get_packet(OpCode.SMSG_ATTACKSTART, data)) return 0
def handle(world_session, socket, reader): if len(reader.data) >= 12: # Avoid handling empty quest giver accept quest packet quest_giver_guid, quest_id = unpack ('<QI', reader.data[:12]) quest_giver = GridManager.get_surrounding_unit_by_guid(world_session.player_mgr, quest_giver_guid) if not quest_giver: Logger.error(f'Error in CMSG_QUESTGIVER_ACCEPT_QUEST, could not find quest giver with guid of: {quest_giver_guid}') return 0 if world_session.player_mgr.is_enemy_to(quest_giver): return 0 world_session.player_mgr.quest_manager.handle_add_quest(quest_id, quest_giver_guid) return 0
def creature_info(world_session, args): creature = GridManager.get_surrounding_unit_by_guid( world_session.player_mgr, world_session.player_mgr.current_selection) if creature: return 0, '[%s] - Guid: %u, Entry: %u, Display ID: %u, X: %f, Y: %f, Z: %f, O: %f, Map: %u' % ( creature.creature_template.name, creature.guid & ~HighGuid.HIGHGUID_UNIT, creature.creature_template.entry, creature.display_id, creature.location.x, creature.location.y, creature.location.z, creature.location.o, creature.map_) return -1, 'error retrieving creature info.'
def handle(world_session, socket, reader): if len(reader.data) >= 8: # Avoid handling empty attack swing packet # TODO: Finish implementing this enemy_guid = unpack('<Q', reader.data[:8])[0] enemy = GridManager.get_surrounding_unit_by_guid( world_session.player_mgr, enemy_guid, include_players=True) if not enemy or not enemy.is_alive: AttackSwingHandler.handle_stop(world_session, socket, reader) return 0 world_session.player_mgr.attack(enemy) return 0
def _target_or_self(world_session, only_players=False): if world_session.player_mgr.current_selection \ and world_session.player_mgr.current_selection != world_session.player_mgr.guid: if only_players: unit = GridManager.get_surrounding_player_by_guid(world_session.player_mgr, world_session.player_mgr.current_selection) else: unit = GridManager.get_surrounding_unit_by_guid(world_session.player_mgr, world_session.player_mgr.current_selection, include_players=True) if unit: return unit return world_session.player_mgr
def handle(world_session, socket, reader): if len(reader.data ) >= 8: # Avoid handling empty quest giver query quest packet guid, quest_entry = unpack('<QL', reader.data[:12]) # NPC if guid & HighGuid.HIGHGUID_UNIT: quest_giver = GridManager.get_surrounding_unit_by_guid( world_session.player_mgr, guid) if not quest_giver: return 0 quest_giver_is_related = world_session.player_mgr.quest_manager.check_quest_giver_npc_is_related( quest_giver.entry, quest_entry) if not quest_giver_is_related: return 0 # Gameobject elif guid & HighGuid.HIGHGUID_GAMEOBJECT: quest_giver = GridManager.get_surrounding_gameobject_by_guid( world_session, guid) if not quest_giver: return 0 # Item elif guid & HighGuid.HIGHGUID_ITEM: item_info = world_session.player_mgr.inventory.get_item_info_by_guid( guid) if not item_info[3]: return 0 quest_giver = item_info[3].item_template quest_giver_is_related = quest_giver.start_quest == quest_entry if not quest_giver_is_related: return 0 else: Logger.error( f'Error in CMSG_QUESTGIVER_QUERY_QUEST, unknown quest giver type.' ) return 0 quest = WorldDatabaseManager.QuestTemplateHolder.quest_get_by_entry( quest_entry) if not quest: Logger.error( f'Error in CMSG_QUESTGIVER_QUERY_QUEST, could not find quest with an entry of: {quest_entry}' ) return 0 world_session.player_mgr.quest_manager.send_quest_giver_quest_details( quest, guid, True) return 0
def creature_info(world_session, args): creature = GridManager.get_surrounding_unit_by_guid( world_session.player_mgr, world_session.player_mgr.current_selection) if creature: return 0, f'[{creature.creature_template.name}] - Guid: {creature.guid & ~HighGuid.HIGHGUID_UNIT}, ' \ f'Entry: {creature.creature_template.entry}, ' \ f'Display ID: {creature.current_display_id}, ' \ f'X: {creature.location.x}, ' \ f'Y: {creature.location.y}, ' \ f'Z: {creature.location.z}, ' \ f'O: {creature.location.o}, ' \ f'Map: {creature.map_}' return -1, 'error retrieving creature info.'
def handle(world_session, socket, reader): if len(reader.data) >= 8: # Avoid handling empty quest giver hello packet guid = unpack('<Q', reader.data[:8])[0] quest_giver = GridManager.get_surrounding_unit_by_guid(world_session.player_mgr, guid) if not quest_giver: Logger.error("Error in CMSG_QUESTGIVER_HELLO, could not find quest giver with guid of: %u" % guid) return 0 if world_session.player_mgr.is_enemy_to(quest_giver): return 0 # TODO: Stop the npc if it's moving # TODO: Remove feign death from player (if it even exists in 0.5.3) # TODO: If the gossip menu is already open, do nothing world_session.player_mgr.quest_manager.prepare_quest_giver_gossip_menu(quest_giver, guid) return 0
def send_loot_release(self, guid): self.unit_flags &= ~UnitFlags.UNIT_FLAG_LOOTING self.set_uint32(UnitFields.UNIT_FIELD_FLAGS, self.unit_flags) data = pack('<QB', guid, 1) # Must be 1 otherwise client keeps the loot window open self.session.request.sendall( PacketWriter.get_packet(OpCode.SMSG_LOOT_RELEASE_RESPONSE, data)) # If this release comes from the loot owner, set killed_by to None to allow FFA loot. enemy = GridManager.get_surrounding_unit_by_guid(self, guid, include_players=False) if enemy and enemy.killed_by and enemy.killed_by == self: enemy.killed_by = None self.set_dirty()
def handle(world_session, socket, reader): if len(reader.data) >= 13: # Avoid handling empty buy item packet vendor_guid, item, count = unpack('<QIB', reader.data[:13]) if 0 < vendor_guid == world_session.player_mgr.current_selection: if count <= 0: count = 1 vendor_npc = GridManager.get_surrounding_unit_by_guid( world_session.player_mgr, vendor_guid) vendor_data, session = WorldDatabaseManager.creature_get_vendor_data_by_item( vendor_npc.entry, item) if vendor_data: item_template = vendor_data.item_template session.close() total_cost = item_template.buy_price * count if world_session.player_mgr.coinage < total_cost: world_session.player_mgr.inventory.send_buy_error( BuyResults.BUY_ERR_NOT_ENOUGH_MONEY, item, vendor_guid) return 0 if 0 < vendor_data.maxcount < count: # I should be checking here for current count too world_session.player_mgr.inventory.send_buy_error( BuyResults.BUY_ERR_ITEM_SOLD_OUT, item, vendor_guid) return 0 if world_session.player_mgr.inventory.add_item( item_template=item_template, count=count, handle_error=False): world_session.player_mgr.mod_money(total_cost * -1) #vendor_npc.send_inventory_list(world_session) else: world_session.player_mgr.inventory.send_buy_error( BuyResults.BUY_ERR_CANT_CARRY_MORE, item, vendor_guid) else: world_session.player_mgr.inventory.send_buy_error( BuyResults.BUY_ERR_CANT_FIND_ITEM, item, vendor_guid) return 0
def handle(world_session, socket, reader): if len(reader.data ) >= 12: # Avoid handling empty creature query packet entry, guid = unpack('<IQ', reader.data[:12]) if guid > 0: creature_mgr = GridManager.get_surrounding_unit_by_guid( world_session.player_mgr, guid) if not creature_mgr: creature_spawn, session = WorldDatabaseManager.creature_spawn_get_by_guid( guid) if creature_spawn and creature_spawn.creature_template.entry == entry: creature_mgr = CreatureManager( creature_template=creature_spawn.creature_template) session.close() if creature_mgr: socket.sendall(creature_mgr.query_details()) return 0
def handle(world_session, socket, reader): if len(reader.data) >= 8: # Avoid handling empty loot packet loot_target_guid = unpack('<Q', reader.data[:8])[0] player = world_session.player_mgr enemy = GridManager.get_surrounding_unit_by_guid( world_session.player_mgr, loot_target_guid, include_players=False) if player and enemy: # Only set flag if player was able to loot, else the player would be kneeling forever. if player.send_loot(enemy): player.unit_flags |= UnitFlags.UNIT_FLAG_LOOTING player.set_uint32(UnitFields.UNIT_FIELD_FLAGS, player.unit_flags) player.set_dirty() return 0
def handle(world_session, socket, reader): # CGPlayer_C::GetQuestReward if len( reader.data ) >= 16: # Avoid handling empty quest fiver choose reward packet quest_giver_guid, quest_id, item_choice = unpack( '<Q2I', reader.data[:16]) quest_giver = GridManager.get_surrounding_unit_by_guid( world_session.player_mgr, quest_giver_guid) if not quest_giver: Logger.error( f'Error in CMSG_QUESTGIVER_COMPLETE_QUEST, could not find quest giver with guid of: {quest_giver_guid}' ) return 0 if world_session.player_mgr.is_enemy_to(quest_giver): return 0 world_session.player_mgr.quest_manager.handle_choose_reward( quest_giver_guid, quest_id, item_choice) return 0
def loot_money(self): if self.current_selection > 0: enemy = GridManager.get_surrounding_unit_by_guid( self, self.current_selection) if enemy and enemy.loot_manager.has_money(): if self.group_manager: self.group_manager.reward_group_money(self, enemy) else: self.session.request.sendall( PacketWriter.get_packet(OpCode.SMSG_LOOT_CLEAR_MONEY)) data = pack('<I', enemy.loot_manager.current_money) self.session.request.sendall( PacketWriter.get_packet(OpCode.SMSG_LOOT_MONEY_NOTIFY, data)) self.mod_money(enemy.loot_manager.current_money) enemy.loot_manager.clear_money() if not enemy.loot_manager.has_items(): self.send_loot_release(enemy.guid) enemy.set_lootable(False)
def handle(world_session, socket, reader): if len(reader.data) >= 8: # Avoid handling empty set selection packet questgiver_guid = unpack('<Q', reader.data[:8])[0] questgiver_npc = GridManager.get_surrounding_unit_by_guid( world_session.player_mgr, questgiver_guid) # Terminate method if questgiver could not be found if not questgiver_npc: Logger.error( "Error in OpCode CMSG_QUESTGIVER_STATUS_QUERY, could not find questgiver with guid of: %s" % (questgiver_guid)) return 0 if world_session.player_mgr: # Get the status for this questgiver questgiver_status = ObjectCodes.QuestGiverStatuses.QUEST_GIVER_NONE questgiver_status = world_session.player_mgr.quests.get_dialog_status( questgiver_npc, questgiver_status) # Construct the packet and send it off world_session.player_mgr.quests.send_quest_status( questgiver_guid, questgiver_status) return 0
def loot_item(self, slot): if self.current_selection > 0: enemy = GridManager.get_surrounding_unit_by_guid( self, self.current_selection, include_players=False) if enemy and enemy.loot_manager.has_loot(): loot = enemy.loot_manager.get_loot_in_slot(slot) if not loot or not loot.item: self.send_loot_release(enemy.guid) return if self.inventory.add_item( item_template=loot.item.item_template, count=loot.quantity, looted=True): enemy.loot_manager.do_loot(slot) data = pack('<B', slot) GridManager.send_surrounding( PacketWriter.get_packet(OpCode.SMSG_LOOT_REMOVED, data), self) if enemy and not enemy.loot_manager.has_loot(): enemy.set_lootable(False)