コード例 #1
0
    def modify_emblem(self, player_mgr, emblem_style, emblem_color,
                      border_style, border_color, background_color):
        self.guild.emblem_style = emblem_style
        self.guild.emblem_color = emblem_color
        self.guild.border_style = border_style
        self.guild.border_color = border_color
        self.guild.background_color = background_color
        self.update_db_guild()

        GuildManager.send_emblem_result(
            player_mgr, GuildEmblemResult.ERR_GUILDEMBLEM_SUCCESS)

        query_packet = self.build_guild_query()
        MapManager.send_surrounding(query_packet,
                                    player_mgr,
                                    include_self=True)
コード例 #2
0
ファイル: UnitManager.py プロジェクト: Makkoni/alpha-core
    def receive_damage(self, amount, source=None):
        is_player = self.get_type() == ObjectTypes.TYPE_PLAYER

        new_health = self.health - amount
        if new_health <= 0:
            self.die(killer=source)
        else:
            self.set_health(new_health)

        # If unit is a creature and it's being attacked by another unit, automatically set combat target.
        if not self.combat_target and not is_player and source and source.get_type(
        ) != ObjectTypes.TYPE_GAMEOBJECT:
            self.attack(source)

        update_packet = self.generate_proper_update_packet(is_self=is_player)
        MapManager.send_surrounding(update_packet,
                                    self,
                                    include_self=is_player)
コード例 #3
0
    def respawn(self):
        super().respawn()

        self.set_health(self.max_health)
        self.set_mana(self.max_power_1)

        self.loot_manager.clear()
        self.set_lootable(False)

        if self.killed_by and self.killed_by.group_manager:
            self.killed_by.group_manager.clear_looters_for_victim(self)
        self.killed_by = None

        self.is_spawned = True
        self.respawn_timer = 0
        self.respawn_time = randint(self.creature_instance.spawntimesecsmin, self.creature_instance.spawntimesecsmax)

        MapManager.send_surrounding(self.generate_proper_update_packet(create=True), self, include_self=False)
コード例 #4
0
    def end_duel(self, duel_winner_flag, duel_complete_flag, winner):
        if not self.arbiter or self.duel_state == DuelState.DUEL_STATE_FINISHED or not self.players:
            return

        if self.duel_state == DuelState.DUEL_STATE_STARTED:
            duel_complete_flag = DuelComplete.DUEL_FINISHED

        # Set this first to prevent next tick to trigger.
        self.duel_state = DuelState.DUEL_STATE_FINISHED

        if duel_winner_flag == DuelWinner.DUEL_WINNER_KNOCKOUT:
            # TODO: Should trigger EMOTE BEG on loser?
            # TODO: Should root loser for 3 secs?
            pass

        # Send either the duel ended by natural means or if it was canceled/interrupted
        packet = PacketWriter.get_packet(OpCode.SMSG_DUEL_COMPLETE, pack('<B', duel_complete_flag))
        MapManager.send_surrounding(packet, self.arbiter)

        # Was not interrupted, broadcast duel result.
        if duel_complete_flag == DuelComplete.DUEL_FINISHED:
            winner_name_bytes = PacketWriter.string_to_bytes(winner.player.name)
            loser_name_bytes = PacketWriter.string_to_bytes(self.players[winner.guid].target.player.name)
            data = pack(f'<B{len(winner_name_bytes)}s{len(loser_name_bytes)}s', duel_winner_flag, winner_name_bytes,
                        loser_name_bytes)
            packet = PacketWriter.get_packet(OpCode.SMSG_DUEL_WINNER, data)
            MapManager.send_surrounding(packet, self.arbiter)

        packet = PacketWriter.get_packet(OpCode.SMSG_CANCEL_COMBAT)
        for entry in self.players.values():
            entry.player.enqueue_packet(packet)
            entry.player.leave_combat()
            self.build_update(entry.player)

            entry.player.spell_manager.remove_unit_from_all_cast_targets(entry.target.guid)
            entry.player.aura_manager.remove_harmful_auras_by_caster(entry.target.guid)

        # Clean up arbiter go and cleanup.
        MapManager.remove_object(self.arbiter)

        # Finally, flush this DualManager instance.
        self.flush()
コード例 #5
0
ファイル: CreatureManager.py プロジェクト: Makkoni/alpha-core
    def update(self):
        now = time.time()
        if now > self.last_tick > 0:
            elapsed = now - self.last_tick

            if self.is_alive:
                # Spell/aura updates
                self.spell_manager.update(now)
                self.aura_manager.update(elapsed)
                # Movement Updates
                self.movement_manager.update_pending_waypoints(elapsed)
                # Random Movement
                self._perform_random_movement(now)
                # Combat movement
                self._perform_combat_movement(now)
                # Attack update
                if self.combat_target and self.is_within_interactable_distance(
                        self.combat_target):
                    self.attack_update(elapsed)
            # Dead
            else:
                self.respawn_timer += elapsed
                if self.respawn_timer >= self.respawn_time:
                    self.respawn()
                # Destroy body when creature is about to respawn
                elif self.is_spawned and self.respawn_timer >= self.respawn_time * 0.8:
                    self.is_spawned = False
                    MapManager.send_surrounding(self.get_destroy_packet(),
                                                self,
                                                include_self=False)
        self.last_tick = now

        if self.dirty:
            MapManager.send_surrounding(
                self.generate_proper_update_packet(create=False),
                self,
                include_self=False)
            MapManager.update_object(self)
            self.reset_fields()

            self.set_dirty(is_dirty=False)
コード例 #6
0
    def update(self):
        now = time.time()
        if now > self.last_tick > 0:
            elapsed = now - self.last_tick

            if self.is_spawned:
                # Check "dirtiness" to determine if this game object should be updated yet or not.
                if self.dirty:
                    MapManager.send_surrounding(
                        self.generate_proper_update_packet(create=False),
                        self,
                        include_self=False)
                    MapManager.update_object(self)
                    if self.reset_fields_older_than(now):
                        self.set_dirty(is_dirty=False)
            # Not spawned.
            else:
                self.respawn_timer += elapsed
                if self.respawn_timer >= self.respawn_time and not self.is_summon:
                    self.respawn()

        self.last_tick = now
コード例 #7
0
ファイル: UnitManager.py プロジェクト: Fragrus/alpha-core
    def send_spell_cast_debug_info(self,
                                   damage_info,
                                   miss_reason,
                                   spell_id,
                                   healing=False,
                                   is_periodic=False):
        flags = SpellHitFlags.HIT_FLAG_HEALED if healing else SpellHitFlags.HIT_FLAG_DAMAGE
        if is_periodic:  # Periodic damage/healing does not show in combat log - only on character frame.
            flags |= SpellHitFlags.HIT_FLAG_PERIODIC

        if miss_reason != SpellMissReason.MISS_REASON_NONE:
            combat_log_data = pack('<i2Q2i', flags, damage_info.attacker.guid,
                                   damage_info.target.guid, spell_id,
                                   miss_reason)
            combat_log_opcode = OpCode.SMSG_ATTACKERSTATEUPDATEDEBUGINFOSPELLMISS
        else:

            combat_log_data = pack(
                '<I2Q2If3I', flags, damage_info.attacker.guid,
                damage_info.target.guid, spell_id, damage_info.total_damage,
                damage_info.damage, damage_info.damage_school_mask,
                damage_info.damage, damage_info.absorb)
            combat_log_opcode = OpCode.SMSG_ATTACKERSTATEUPDATEDEBUGINFOSPELL

        MapManager.send_surrounding(
            PacketWriter.get_packet(combat_log_opcode, combat_log_data),
            self,
            include_self=self.get_type() == ObjectTypes.TYPE_PLAYER)

        if not healing:
            damage_data = pack('<Q2i2IQ', damage_info.target.guid,
                               damage_info.total_damage, damage_info.damage,
                               miss_reason, spell_id,
                               damage_info.attacker.guid)
            MapManager.send_surrounding(
                PacketWriter.get_packet(OpCode.SMSG_DAMAGE_DONE, damage_data),
                self,
                include_self=self.get_type() == ObjectTypes.TYPE_PLAYER)
コード例 #8
0
ファイル: UnitManager.py プロジェクト: Makkoni/alpha-core
    def send_attack_state_update(self, damage_info):
        data = pack(
            '<I2QIBIf7I',
            damage_info.hit_info,
            damage_info.attacker.guid,
            damage_info.target.guid,
            damage_info.total_damage,
            1,  # Sub damage count
            damage_info.damage_school_mask,
            damage_info.total_damage,
            damage_info.damage,
            damage_info.absorb,
            damage_info.target_state,
            damage_info.resist,
            0,
            0,
            damage_info.blocked_amount)
        MapManager.send_surrounding(
            PacketWriter.get_packet(OpCode.SMSG_ATTACKERSTATEUPDATE, data),
            self,
            include_self=self.get_type() == ObjectTypes.TYPE_PLAYER)

        # Damage effects
        self.deal_damage(damage_info.target, damage_info.total_damage)
コード例 #9
0
    def handle_partial_interrupt(self):
        if not self.spell_entry.InterruptFlags & SpellInterruptFlags.SPELL_INTERRUPT_FLAG_PARTIAL:
            return

        # TODO Did pushback resistance exist?
        curr_time = time.time()
        remaining_cast_before_pushback = self.cast_end_timestamp - curr_time

        if self.is_channeled() and self.cast_state == SpellState.SPELL_STATE_ACTIVE:
            channel_length = self.duration_entry.Duration/1000  # /1000 for seconds.
            final_opcode = OpCode.MSG_CHANNEL_UPDATE
            pushback_length_sec = min(remaining_cast_before_pushback, channel_length * 0.25)
            for effect in self.get_effects():
                if remaining_cast_before_pushback <= pushback_length_sec:
                    # Applied aura duration is not timestamp based so it's stored in milliseconds.
                    # To avoid rounding issues, set to zero instead of subtracting if pushback leads to channel stop.
                    effect.applied_aura_duration = 0
                else:
                    effect.applied_aura_duration -= pushback_length_sec * 1000  # aura duration is stored as millis.
                effect.remove_old_periodic_effect_ticks()

            self.cast_end_timestamp -= pushback_length_sec
            data = pack('<I', int((remaining_cast_before_pushback - pushback_length_sec)*1000))  # *1000 for millis.

        elif self.cast_state == SpellState.SPELL_STATE_CASTING:
            final_opcode = OpCode.SMSG_SPELL_DELAYED
            cast_progress_seconds = self.get_base_cast_time()/1000 - remaining_cast_before_pushback  # base cast time in seconds.
            pushback_length_sec = min(cast_progress_seconds, 0.5)  # Push back 0.5s or to beginning of cast.

            self.cast_end_timestamp += pushback_length_sec
            data = pack('<QI', self.spell_caster.guid, int(pushback_length_sec * 1000))  # *1000 for millis.
        else:
            return

        MapManager.send_surrounding(PacketWriter.get_packet(final_opcode, data), self.spell_caster,
                                    include_self=self.spell_caster.get_type_id() == ObjectTypeIds.ID_PLAYER)
コード例 #10
0
ファイル: UnitManager.py プロジェクト: Makkoni/alpha-core
 def send_attack_start(self, victim_guid):
     data = pack('<2Q', self.guid, victim_guid)
     MapManager.send_surrounding(
         PacketWriter.get_packet(OpCode.SMSG_ATTACKSTART, data), self)
コード例 #11
0
    def handle_movement_status(world_session, socket,
                               reader: PacketReader) -> int:
        # Avoid handling malformed movement packets, or handling them while no player or player teleporting.
        if world_session.player_mgr and len(reader.data) >= 48:
            try:
                transport_guid, transport_x, transport_y, transport_z, transport_o, x, y, z, o, pitch, flags = \
                    unpack('<Q9fI', reader.data[:48])

                # Hacky way to prevent random teleports when colliding with elevators
                # Also acts as a rudimentary teleport cheat detection
                if not world_session.player_mgr.pending_taxi_destination and world_session.player_mgr.location.distance(
                        x=x, y=y, z=z) > 64:
                    Logger.anticheat(
                        f'Preventing coordinate desync from player {world_session.player_mgr.player.name} ({world_session.player_mgr.guid}).'
                    )
                    world_session.player_mgr.teleport(
                        world_session.player_mgr.map_,
                        world_session.player_mgr.location)

                    return 0

                # Send movement info to SpellManager until movement handling is merged to update system
                if flags & 0xF != 0:  # MoveFlags.MOVEFLAG_MOVE_MASK | MoveFlags.MOVEFLAG_STRAFE_MASK
                    world_session.player_mgr.spell_manager.flag_as_moved()

                world_session.player_mgr.transport_id = transport_guid

                world_session.player_mgr.transport.x = transport_x
                world_session.player_mgr.transport.y = transport_y
                world_session.player_mgr.transport.z = transport_z
                world_session.player_mgr.transport.o = transport_o

                world_session.player_mgr.location.x = x
                world_session.player_mgr.location.y = y
                world_session.player_mgr.location.z = z
                world_session.player_mgr.location.o = o

                world_session.player_mgr.pitch = pitch
                world_session.player_mgr.movement_flags = flags

                if flags & MoveFlags.MOVEFLAG_SPLINE_MOVER:
                    world_session.player_mgr.movement_spline = MovementManager.MovementSpline.from_bytes(
                        reader.data[48:])

                movement_data = pack(f'<Q{len(reader.data)}s',
                                     world_session.player_mgr.guid,
                                     reader.data)

                MapManager.send_surrounding(PacketWriter.get_packet(
                    OpCode(reader.opcode), movement_data),
                                            world_session.player_mgr,
                                            include_self=False)
                MapManager.update_object(world_session.player_mgr)
                world_session.player_mgr.sync_player()

                # Get up if you jump while not standing
                if reader.opcode == OpCode.MSG_MOVE_JUMP and \
                        world_session.player_mgr.stand_state != StandState.UNIT_DEAD and \
                        world_session.player_mgr.stand_state != StandState.UNIT_STANDING:
                    world_session.player_mgr.stand_state = StandState.UNIT_STANDING
                    world_session.player_mgr.set_dirty()

            except (AttributeError, error):
                Logger.error(
                    f'Error while handling {OpCode(reader.opcode).name}, skipping. Data: {reader.data}'
                )

        return 0
コード例 #12
0
 def send_update_surrounding(self):
     update_packet = UpdatePacketFactory.compress_if_needed(
         PacketWriter.get_packet(
             OpCode.SMSG_UPDATE_OBJECT,
             self.get_full_update_packet(is_self=False)))
     MapManager.send_surrounding(update_packet, self, include_self=False)
コード例 #13
0
 def send_custom_animation(self, animation):
     data = pack('<QI', self.guid, animation)
     packet = PacketWriter.get_packet(OpCode.SMSG_GAMEOBJECT_CUSTOM_ANIM, data)
     MapManager.send_surrounding(packet, self, include_self=False)
コード例 #14
0
ファイル: ObjectManager.py プロジェクト: Fragrus/alpha-core
 def send_create_packet_surroundings(self, **kwargs):
     update_packet = self.generate_proper_update_packet(False, True)
     MapManager.send_surrounding(update_packet, self, include_self=False)
コード例 #15
0
ファイル: MovementHandler.py プロジェクト: Fluglow/alpha-core
    def handle_movement_status(world_session, socket,
                               reader: PacketReader) -> int:
        # Avoid handling malformed movement packets, or handling them while no player or player teleporting.
        if world_session.player_mgr and len(reader.data) >= 48:
            try:
                transport_guid, transport_x, transport_y, transport_z, transport_o, x, y, z, o, pitch, flags = \
                    unpack('<Q9fI', reader.data[:48])

                # Hacky way to prevent random teleports when colliding with elevators
                # Also acts as a rudimentary teleport cheat detection
                if not world_session.player_mgr.pending_taxi_destination and \
                        world_session.player_mgr.location.distance(x=x, y=y, z=z) > 64:
                    Logger.anticheat(
                        f'Preventing coordinate desync from player {world_session.player_mgr.player.name} '
                        f'({world_session.player_mgr.guid}).')
                    world_session.player_mgr.teleport(
                        world_session.player_mgr.map_,
                        world_session.player_mgr.location,
                        is_instant=True)

                    return 0

                jumped = reader.opcode == OpCode.MSG_MOVE_JUMP

                # Movement and jump actions.
                if flags & (MoveFlags.MOVEFLAG_MOVE_MASK
                            | MoveFlags.MOVEFLAG_STRAFE_MASK) or jumped:
                    # Don't mark player as moved if only jumping.
                    if not jumped:
                        world_session.player_mgr.set_has_moved(True)

                    # Cancel looting if moved.
                    if world_session.player_mgr.loot_selection:
                        world_session.player_mgr.send_loot_release(
                            world_session.player_mgr.loot_selection)
                    world_session.player_mgr.spell_manager.check_spell_interrupts(
                        moved=True)
                    world_session.player_mgr.aura_manager.check_aura_interrupts(
                        moved=True)

                # Turn actions.
                if flags & MoveFlags.MOVEFLAG_TURN_MASK:
                    world_session.player_mgr.spell_manager.check_spell_interrupts(
                        turned=True)

                world_session.player_mgr.transport_id = transport_guid

                world_session.player_mgr.transport.x = transport_x
                world_session.player_mgr.transport.y = transport_y
                world_session.player_mgr.transport.z = transport_z
                world_session.player_mgr.transport.o = transport_o

                world_session.player_mgr.location.x = x
                world_session.player_mgr.location.y = y
                world_session.player_mgr.location.z = z
                world_session.player_mgr.location.o = o

                world_session.player_mgr.pitch = pitch
                world_session.player_mgr.movement_flags = flags

                if flags & MoveFlags.MOVEFLAG_SPLINE_MOVER:
                    world_session.player_mgr.movement_spline = MovementManager.MovementSpline.from_bytes(
                        reader.data[48:])

                # Broadcast player movement to surroundings.
                movement_data = pack(f'<Q{len(reader.data)}s',
                                     world_session.player_mgr.guid,
                                     reader.data)
                movement_packet = PacketWriter.get_packet(
                    OpCode(reader.opcode), movement_data)
                MapManager.send_surrounding(movement_packet,
                                            world_session.player_mgr,
                                            include_self=False)

                # Get up if you jump while not standing.
                if jumped and world_session.player_mgr.stand_state != StandState.UNIT_DEAD and \
                        world_session.player_mgr.stand_state != StandState.UNIT_STANDING:
                    world_session.player_mgr.set_stand_state(
                        StandState.UNIT_STANDING)

            except (AttributeError, error):
                Logger.error(
                    f'Error while handling {OpCode(reader.opcode).name}, skipping. Data: {reader.data}'
                )

        return 0