Search in sources :

Example 1 with EntityTickContext

use of org.spongepowered.common.event.tracking.phase.tick.EntityTickContext in project SpongeCommon by SpongePowered.

the class TrackingUtil method tickRidingEntity.

public static void tickRidingEntity(net.minecraft.entity.Entity entity) {
    checkArgument(entity instanceof Entity, "Entity %s is not an instance of SpongeAPI's Entity!", entity);
    checkNotNull(entity, "Cannot capture on a null ticking entity!");
    final IMixinEntity mixinEntity = EntityUtil.toMixin(entity);
    if (!mixinEntity.shouldTick()) {
        return;
    }
    final Optional<User> notifierUser = mixinEntity.getNotifierUser();
    final Optional<User> creatorUser = mixinEntity.getCreatorUser();
    final EntityTickContext tickContext = TickPhase.Tick.ENTITY.createPhaseContext().source(entity).notifier(() -> notifierUser).owner(() -> creatorUser);
    try (final StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame();
        final EntityTickContext context = tickContext.buildAndSwitch();
        final Timing entityTiming = mixinEntity.getTimingsHandler().startTiming()) {
        Sponge.getCauseStackManager().pushCause(entity);
        notifierUser.ifPresent(notifier -> frame.addContext(EventContextKeys.NOTIFIER, notifier));
        creatorUser.ifPresent(notifier -> frame.addContext(EventContextKeys.OWNER, notifier));
        entity.updateRidden();
    } catch (Exception | NoClassDefFoundError e) {
        PhaseTracker.getInstance().printExceptionFromPhase(e, tickContext);
    }
}
Also used : IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) TileEntity(org.spongepowered.api.block.tileentity.TileEntity) IMixinTileEntity(org.spongepowered.common.interfaces.block.tile.IMixinTileEntity) Entity(org.spongepowered.api.entity.Entity) EntityTickContext(org.spongepowered.common.event.tracking.phase.tick.EntityTickContext) TileEntityTickContext(org.spongepowered.common.event.tracking.phase.tick.TileEntityTickContext) User(org.spongepowered.api.entity.living.player.User) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) Timing(co.aikar.timings.Timing)

Example 2 with EntityTickContext

use of org.spongepowered.common.event.tracking.phase.tick.EntityTickContext in project SpongeCommon by SpongePowered.

the class TrackingUtil method tickEntity.

public static void tickEntity(net.minecraft.entity.Entity entityIn) {
    checkArgument(entityIn instanceof Entity, "Entity %s is not an instance of SpongeAPI's Entity!", entityIn);
    checkNotNull(entityIn, "Cannot capture on a null ticking entity!");
    final IMixinEntity mixinEntity = EntityUtil.toMixin(entityIn);
    if (!mixinEntity.shouldTick()) {
        return;
    }
    final EntityTickContext tickContext = TickPhase.Tick.ENTITY.createPhaseContext().source(entityIn);
    try (final StackFrame frame = Sponge.getCauseStackManager().pushCauseFrame();
        final EntityTickContext context = tickContext;
        final Timing entityTiming = mixinEntity.getTimingsHandler().startTiming()) {
        mixinEntity.getNotifierUser().ifPresent(notifier -> {
            frame.addContext(EventContextKeys.NOTIFIER, notifier);
            context.notifier(notifier);
        });
        mixinEntity.getCreatorUser().ifPresent(owner -> {
            if (mixinEntity instanceof EntityFallingBlock) {
                frame.pushCause(owner);
            }
            frame.addContext(EventContextKeys.OWNER, owner);
            context.owner(owner);
        });
        context.buildAndSwitch();
        entityIn.onUpdate();
    } catch (Exception | NoClassDefFoundError e) {
        PhaseTracker.getInstance().printExceptionFromPhase(e, tickContext);
    }
}
Also used : IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) TileEntity(org.spongepowered.api.block.tileentity.TileEntity) IMixinTileEntity(org.spongepowered.common.interfaces.block.tile.IMixinTileEntity) Entity(org.spongepowered.api.entity.Entity) EntityTickContext(org.spongepowered.common.event.tracking.phase.tick.EntityTickContext) TileEntityTickContext(org.spongepowered.common.event.tracking.phase.tick.TileEntityTickContext) EntityFallingBlock(net.minecraft.entity.item.EntityFallingBlock) StackFrame(org.spongepowered.api.event.CauseStackManager.StackFrame) IMixinEntity(org.spongepowered.common.interfaces.entity.IMixinEntity) Timing(co.aikar.timings.Timing)

Example 3 with EntityTickContext

use of org.spongepowered.common.event.tracking.phase.tick.EntityTickContext in project SpongeCommon by SpongePowered.

the class TransactionSink method logSlotTransaction.

/**
 * Called with a created {@link SlotTransaction} that's been created and
 * possibly already recorded by {@link TrackedContainerBridge#bridge$detectAndSendChanges(boolean)}
 * performing transaction handling and submitting to be recorded through
 * here. The caveat with this system is that since it's reliant on having
 * the transactions created as a side effect of {@link AbstractContainerMenu#broadcastChanges()},
 * it's possible that certain transactions are "too late" or remain uncaptured
 * until the next tick.
 *
 * @param phaseContext The context
 * @param newTransaction The slot transaction in relation to the menu
 * @param abstractContainerMenu The container menu
 */
/*
     Non-Javadoc: Known areas where we are keeping transactions recorded:
     - commands - during CommandPhaseContext see below
     - place/use ServerPlayerGameModeMixin_Tracker#useItemOn
     - Dispenser equip PlayerEntityMixin_Inventory#setItemSlot
     - eating etc. LivingEntityMixin_Inventory#completeUsingItem
     - throw/use ServerGamePacketListenerImplMixin_Inventory#impl$onHandleUseItem
     - breaking blocks ServerPlayerGameModeMixin_Tracker#impl$onMineBlock
     - exp pickup with mending PlayerEntityMixin_Inventory#inventory$onTouch
     - attack PlayerMixin#attack
     - armor/shield damage LivingEntityMixin#bridge$damageEntity
     - elytra damage LivingEntityMixin#inventory$onElytraUse
     - consume arrow (BowItem#releaseUsing - shrink on stack) LivingEntityMixin#impl$onStopPlayerUsing
     - villager trade select ServerGamePacketListenerImplMixin_Inventory#impl$onHandleSelectTrade
     - close inventory adding back to inventory ServerPlayerEntityMixin_Inventory#impl$onCloseContainer
     - use on entity - ServerGamePacketListenerImplMixin_Inventory#impl$onInteractAt/impl$onInteractOn
     */
default void logSlotTransaction(final PhaseContext<@NonNull ?> phaseContext, final SlotTransaction newTransaction, final AbstractContainerMenu abstractContainerMenu) {
    // Inventory change during command
    if (abstractContainerMenu instanceof InventoryMenu) {
        if (phaseContext instanceof CommandPhaseContext) {
            this.logPlayerInventoryChange(((InventoryMenuAccessor) abstractContainerMenu).accessor$owner(), PlayerInventoryTransaction.EventCreator.STANDARD);
        }
        if (phaseContext instanceof UnwindingPhaseContext) {
            return;
        }
        if (phaseContext instanceof EntityTickContext) {
            // TODO remove warning when we got all cases covered
            SpongeCommon.logger().warn("Ignoring slot transaction on InventoryMenu during {}. {}\nNo Event will be fired for this", phaseContext.getClass().getSimpleName(), newTransaction);
            return;
        }
    }
    final ContainerSlotTransaction transaction = new ContainerSlotTransaction(abstractContainerMenu, newTransaction);
    this.logTransaction(transaction);
}
Also used : EntityTickContext(org.spongepowered.common.event.tracking.phase.tick.EntityTickContext) InventoryMenu(net.minecraft.world.inventory.InventoryMenu) CommandPhaseContext(org.spongepowered.common.event.tracking.phase.general.CommandPhaseContext) ContainerSlotTransaction(org.spongepowered.common.event.tracking.context.transaction.inventory.ContainerSlotTransaction) UnwindingPhaseContext(org.spongepowered.common.event.tracking.UnwindingPhaseContext)

Example 4 with EntityTickContext

use of org.spongepowered.common.event.tracking.phase.tick.EntityTickContext in project SpongeCommon by SpongePowered.

the class ServerScheduler method tick.

@Override
public void tick() {
    super.tick();
    for (final Player player : Sponge.server().onlinePlayers()) {
        try (final EntityTickContext context = TickPhase.Tick.ENTITY.createPhaseContext(PhaseTracker.SERVER).source(player)) {
            context.buildAndSwitch();
            // Detect Changes on PlayerInventories marked as dirty.
            ((PlayerInventoryBridge) ((net.minecraft.world.entity.player.Player) player).inventory).bridge$cleanupDirty();
        }
    }
}
Also used : EntityTickContext(org.spongepowered.common.event.tracking.phase.tick.EntityTickContext) Player(org.spongepowered.api.entity.living.player.Player) PlayerInventoryBridge(org.spongepowered.common.bridge.world.entity.player.PlayerInventoryBridge)

Example 5 with EntityTickContext

use of org.spongepowered.common.event.tracking.phase.tick.EntityTickContext in project SpongeCommon by SpongePowered.

the class TrackingUtil method tickEntity.

public static void tickEntity(final Consumer<net.minecraft.world.entity.Entity> consumer, final net.minecraft.world.entity.Entity entity) {
    checkArgument(entity instanceof Entity, "Entity %s is not an instance of SpongeAPI's Entity!", entity);
    checkNotNull(entity, "Cannot capture on a null ticking entity!");
    if (!((TrackableBridge) entity).bridge$shouldTick()) {
        return;
    }
    final EntityTickContext tickContext = TickPhase.Tick.ENTITY.createPhaseContext(PhaseTracker.SERVER).source(entity);
    try (final EntityTickContext context = tickContext;
        final Timing entityTiming = ((TimingBridge) entity.getType()).bridge$timings()) {
        if (entity instanceof CreatorTrackedBridge) {
            ((CreatorTrackedBridge) entity).tracker$getNotifierUUID().ifPresent(context::notifier);
            ((CreatorTrackedBridge) entity).tracker$getCreatorUUID().ifPresent(context::creator);
        }
        context.buildAndSwitch();
        entityTiming.startTiming();
        consumer.accept(entity);
        if (ShouldFire.MOVE_ENTITY_EVENT) {
            SpongeCommonEventFactory.callNaturalMoveEntityEvent(entity);
        }
        if (ShouldFire.ROTATE_ENTITY_EVENT) {
            SpongeCommonEventFactory.callNaturalRotateEntityEvent(entity);
        }
    } catch (final Exception e) {
        PhasePrinter.printExceptionFromPhase(PhaseTracker.getInstance().stack, e, tickContext);
    }
}
Also used : TickableBlockEntity(net.minecraft.world.level.block.entity.TickableBlockEntity) BlockEntity(org.spongepowered.api.block.entity.BlockEntity) Entity(org.spongepowered.api.entity.Entity) EntityTickContext(org.spongepowered.common.event.tracking.phase.tick.EntityTickContext) TileEntityTickContext(org.spongepowered.common.event.tracking.phase.tick.TileEntityTickContext) CreatorTrackedBridge(org.spongepowered.common.bridge.CreatorTrackedBridge) Timing(co.aikar.timings.Timing) TimingBridge(org.spongepowered.common.bridge.TimingBridge)

Aggregations

EntityTickContext (org.spongepowered.common.event.tracking.phase.tick.EntityTickContext)6 Timing (co.aikar.timings.Timing)4 Entity (org.spongepowered.api.entity.Entity)4 TileEntityTickContext (org.spongepowered.common.event.tracking.phase.tick.TileEntityTickContext)4 TickableBlockEntity (net.minecraft.world.level.block.entity.TickableBlockEntity)2 BlockEntity (org.spongepowered.api.block.entity.BlockEntity)2 TileEntity (org.spongepowered.api.block.tileentity.TileEntity)2 StackFrame (org.spongepowered.api.event.CauseStackManager.StackFrame)2 CreatorTrackedBridge (org.spongepowered.common.bridge.CreatorTrackedBridge)2 TimingBridge (org.spongepowered.common.bridge.TimingBridge)2 IMixinTileEntity (org.spongepowered.common.interfaces.block.tile.IMixinTileEntity)2 IMixinEntity (org.spongepowered.common.interfaces.entity.IMixinEntity)2 EntityFallingBlock (net.minecraft.entity.item.EntityFallingBlock)1 InventoryMenu (net.minecraft.world.inventory.InventoryMenu)1 Player (org.spongepowered.api.entity.living.player.Player)1 User (org.spongepowered.api.entity.living.player.User)1 PlayerInventoryBridge (org.spongepowered.common.bridge.world.entity.player.PlayerInventoryBridge)1 UnwindingPhaseContext (org.spongepowered.common.event.tracking.UnwindingPhaseContext)1 ContainerSlotTransaction (org.spongepowered.common.event.tracking.context.transaction.inventory.ContainerSlotTransaction)1 CommandPhaseContext (org.spongepowered.common.event.tracking.phase.general.CommandPhaseContext)1