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);
}
}
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);
}
}
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);
}
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();
}
}
}
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);
}
}
Aggregations