use of org.spongepowered.api.world.server.ServerWorld in project SpongeCommon by SpongePowered.
the class ServerPlayerMixin method impl$onReturnSleep.
@Inject(method = "startSleepInBed", at = @At(value = "RETURN"), cancellable = true)
private void impl$onReturnSleep(final BlockPos param0, final CallbackInfoReturnable<Either<Player.BedSleepingProblem, Unit>> cir) {
final Either<Player.BedSleepingProblem, Unit> returnValue = cir.getReturnValue();
if (returnValue.left().isPresent()) {
switch(returnValue.left().get()) {
case NOT_POSSIBLE_HERE:
case TOO_FAR_AWAY:
case NOT_POSSIBLE_NOW:
case OBSTRUCTED:
case NOT_SAFE:
final Cause currentCause = Sponge.server().causeStackManager().currentCause();
final BlockSnapshot snapshot = ((ServerWorld) this.level).createSnapshot(param0.getX(), param0.getY(), param0.getZ());
if (Sponge.eventManager().post(SpongeEventFactory.createSleepingEventFailed(currentCause, snapshot, (Living) this))) {
final Either<Player.BedSleepingProblem, Unit> var5 = super.shadow$startSleepInBed(param0).ifRight((param0x) -> {
this.shadow$awardStat(Stats.SLEEP_IN_BED);
CriteriaTriggers.SLEPT_IN_BED.trigger((net.minecraft.server.level.ServerPlayer) (Object) this);
});
((ServerLevel) this.level).updateSleepingPlayerList();
cir.setReturnValue(var5);
}
break;
case // ignore
OTHER_PROBLEM:
break;
}
}
}
use of org.spongepowered.api.world.server.ServerWorld in project SpongeCommon by SpongePowered.
the class TeleportCommandMixin method performTeleport.
/**
* @author Zidane
* @reason Have the teleport command respect our events
*/
@Overwrite
private static void performTeleport(CommandSourceStack source, Entity entityIn, ServerLevel worldIn, double x, double y, double z, Set<ClientboundPlayerPositionPacket.RelativeArgument> relativeList, float yaw, float pitch, @Nullable TeleportCommand.LookAt facing) {
double actualX = x;
double actualY = y;
double actualZ = z;
double actualYaw = yaw;
double actualPitch = pitch;
if (!(entityIn instanceof ServerPlayer)) {
actualYaw = Mth.wrapDegrees(yaw);
actualPitch = Mth.wrapDegrees(pitch);
actualPitch = Mth.clamp(actualPitch, -90.0F, 90.0F);
}
if (worldIn == entityIn.level) {
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND);
if (ShouldFire.MOVE_ENTITY_EVENT) {
final MoveEntityEvent posEvent = SpongeEventFactory.createMoveEntityEvent(frame.currentCause(), (org.spongepowered.api.entity.Entity) entityIn, VecHelper.toVector3d(entityIn.position()), new Vector3d(x, y, z), new Vector3d(x, y, z));
if (SpongeCommon.post(posEvent)) {
return;
}
actualX = posEvent.destinationPosition().x();
actualY = posEvent.destinationPosition().y();
actualZ = posEvent.destinationPosition().z();
}
if (ShouldFire.ROTATE_ENTITY_EVENT) {
final RotateEntityEvent rotateEvent = SpongeEventFactory.createRotateEntityEvent(frame.currentCause(), (org.spongepowered.api.entity.Entity) entityIn, new Vector3d(actualPitch, actualYaw, 0), new Vector3d(pitch, yaw, 0));
SpongeCommon.post(rotateEvent);
actualYaw = rotateEvent.isCancelled() ? entityIn.yRot : rotateEvent.toRotation().y();
actualPitch = rotateEvent.isCancelled() ? entityIn.xRot : rotateEvent.toRotation().x();
}
if (entityIn instanceof ServerPlayer) {
ChunkPos chunkpos = new ChunkPos(new BlockPos(actualX, actualY, actualZ));
worldIn.getChunkSource().addRegionTicket(TicketType.POST_TELEPORT, chunkpos, 1, entityIn.getId());
entityIn.stopRiding();
if (((ServerPlayer) entityIn).isSleeping()) {
((ServerPlayer) entityIn).stopSleepInBed(true, true);
}
((ServerPlayer) entityIn).connection.teleport(actualX, actualY, actualZ, (float) actualYaw, (float) actualPitch, relativeList);
} else {
entityIn.moveTo(actualX, actualY, actualZ, (float) actualYaw, (float) actualPitch);
}
entityIn.setYHeadRot((float) actualYaw);
}
} else {
if (entityIn instanceof ServerPlayer) {
// To ensure mod code is caught, handling the world change for players happens in teleport
// Teleport will create a frame but we want to ensure it'll be the command movement type
// TODO check if this is still correct
PhaseTracker.getCauseStackManager().addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND);
((ServerPlayer) entityIn).teleportTo(worldIn, x, y, z, yaw, pitch);
PhaseTracker.getCauseStackManager().removeContext(EventContextKeys.MOVEMENT_TYPE);
} else {
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
frame.addContext(EventContextKeys.MOVEMENT_TYPE, MovementTypes.COMMAND);
final ServerLevel fromWorld = (ServerLevel) entityIn.getCommandSenderWorld();
final ChangeEntityWorldEvent.Pre preEvent = PlatformHooks.INSTANCE.getEventHooks().callChangeEntityWorldEventPre(entityIn, worldIn);
if (SpongeCommon.post(preEvent)) {
return;
}
final ChangeEntityWorldEvent.Reposition posEvent = SpongeEventFactory.createChangeEntityWorldEventReposition(frame.currentCause(), (org.spongepowered.api.entity.Entity) entityIn, (org.spongepowered.api.world.server.ServerWorld) entityIn.getCommandSenderWorld(), VecHelper.toVector3d(entityIn.position()), new Vector3d(x, y, z), preEvent.originalDestinationWorld(), new Vector3d(x, y, z), preEvent.destinationWorld());
if (SpongeCommon.post(posEvent)) {
return;
}
entityIn.unRide();
final Entity result = entityIn.getType().create(worldIn);
if (result == null) {
return;
}
if (ShouldFire.ROTATE_ENTITY_EVENT) {
final RotateEntityEvent rotateEvent = SpongeEventFactory.createRotateEntityEvent(frame.currentCause(), (org.spongepowered.api.entity.Entity) entityIn, new Vector3d(entityIn.xRot, entityIn.yRot, 0), new Vector3d(actualPitch, actualYaw, 0));
if (!SpongeCommon.post(rotateEvent)) {
actualYaw = Mth.wrapDegrees(rotateEvent.toRotation().y());
actualPitch = Mth.wrapDegrees(rotateEvent.toRotation().x());
actualPitch = Mth.clamp(actualPitch, -90.0F, 90.0F);
} else {
actualYaw = entityIn.yRot;
actualPitch = entityIn.xRot;
}
}
result.restoreFrom(entityIn);
result.moveTo(posEvent.destinationPosition().x(), posEvent.destinationPosition().y(), posEvent.destinationPosition().z(), (float) actualYaw, (float) actualPitch);
result.setYHeadRot((float) actualYaw);
worldIn.addFromAnotherDimension(result);
entityIn.removed = true;
Sponge.eventManager().post(SpongeEventFactory.createChangeEntityWorldEventPost(PhaseTracker.getCauseStackManager().currentCause(), (org.spongepowered.api.entity.Entity) result, (ServerWorld) fromWorld, preEvent.originalDestinationWorld(), preEvent.destinationWorld()));
}
}
}
if (facing != null) {
facing.perform(source, entityIn);
}
if (!(entityIn instanceof LivingEntity) || !((LivingEntity) entityIn).isFallFlying()) {
entityIn.setDeltaMovement(entityIn.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D));
entityIn.setOnGround(true);
}
if (entityIn instanceof PathfinderMob) {
((PathfinderMob) entityIn).getNavigation().stop();
}
}
use of org.spongepowered.api.world.server.ServerWorld in project SpongeCommon by SpongePowered.
the class SpongeCommonEventFactory method handleCollideImpactEvent.
public static boolean handleCollideImpactEvent(final net.minecraft.world.entity.Entity projectile, @Nullable final ProjectileSource projectileSource, final HitResult movingObjectPosition) {
final HitResult.Type movingObjectType = movingObjectPosition.getType();
try (final CauseStackManager.StackFrame frame = PhaseTracker.getCauseStackManager().pushCauseFrame()) {
frame.pushCause(projectile);
frame.addContext(EventContextKeys.PROJECTILE_SOURCE, projectileSource == null ? UnknownProjectileSource.UNKNOWN : projectileSource);
final Optional<UUID> creator = PhaseTracker.getInstance().getPhaseContext().getCreator();
creator.ifPresent(user -> frame.addContext(EventContextKeys.CREATOR, user));
final ServerLocation impactPoint = ServerLocation.of((ServerWorld) projectile.level, VecHelper.toVector3d(movingObjectPosition.getLocation()));
boolean cancelled = false;
if (movingObjectType == HitResult.Type.BLOCK) {
final BlockHitResult blockMovingObjectPosition = (BlockHitResult) movingObjectPosition;
final BlockPos blockPos = blockMovingObjectPosition.getBlockPos();
if (blockPos.getY() <= 0) {
return false;
}
final BlockSnapshot targetBlock = ((ServerWorld) projectile.level).createSnapshot(blockPos.getX(), blockPos.getY(), blockPos.getZ());
final Direction side = DirectionFacingProvider.INSTANCE.getKey(blockMovingObjectPosition.getDirection()).get();
final CollideBlockEvent.Impact event = SpongeEventFactory.createCollideBlockEventImpact(frame.currentCause(), impactPoint, targetBlock.state(), targetBlock.location().get(), side);
cancelled = SpongeCommon.post(event);
// Track impact block if event is not cancelled
if (!cancelled && creator.isPresent()) {
final BlockPos targetPos = VecHelper.toBlockPos(impactPoint.blockPosition());
final LevelChunkBridge spongeChunk = (LevelChunkBridge) projectile.level.getChunkAt(targetPos);
spongeChunk.bridge$addTrackedBlockPosition((Block) targetBlock.state().type(), targetPos, creator.get(), PlayerTracker.Type.NOTIFIER);
}
} else if (movingObjectType == HitResult.Type.ENTITY) {
// entity
final EntityHitResult entityMovingObjectPosition = (EntityHitResult) movingObjectPosition;
final ArrayList<Entity> entityList = new ArrayList<>();
entityList.add((Entity) entityMovingObjectPosition.getEntity());
final CollideEntityEvent.Impact event = SpongeEventFactory.createCollideEntityEventImpact(frame.currentCause(), entityList, impactPoint);
cancelled = SpongeCommon.post(event);
}
return cancelled;
}
}
use of org.spongepowered.api.world.server.ServerWorld in project SpongeCommon by SpongePowered.
the class BlockTransactionType method consumeEventsAndMarker.
@Override
protected void consumeEventsAndMarker(PhaseContext<@NonNull ?> context, final Collection<? extends ChangeBlockEvent.All> changeBlockEvents) {
final Multimap<ResourceKey, ChangeBlockEvent.All> eventsByWorld = LinkedListMultimap.create();
changeBlockEvents.forEach(event -> eventsByWorld.put(event.world().key(), event));
eventsByWorld.asMap().forEach((key, events) -> {
final Optional<ServerWorld> serverWorld = ((SpongeServer) SpongeCommon.server()).worldManager().world(key);
if (!serverWorld.isPresent()) {
return;
}
final ListMultimap<BlockPos, SpongeBlockSnapshot> positions = LinkedListMultimap.create();
// Gather transactions that were valid
events.stream().filter(event -> !event.isCancelled()).flatMap(event -> event.transactions().stream()).filter(BlockTransaction::isValid).forEach(transactions -> {
// Then "put" the most recent transactions such that we have a complete rebuild of
// each position according to what originally existed and then
// the ultimate final block on that position
final SpongeBlockSnapshot original = (SpongeBlockSnapshot) transactions.original();
positions.put(original.getBlockPos(), original);
positions.put(original.getBlockPos(), (SpongeBlockSnapshot) transactions.finalReplacement());
});
// just return.
if (positions.isEmpty()) {
return;
}
final ImmutableList<BlockTransactionReceipt> transactions = positions.asMap().values().stream().map(spongeBlockSnapshots -> {
final List<SpongeBlockSnapshot> snapshots = new ArrayList<>(spongeBlockSnapshots);
if (snapshots.isEmpty() || snapshots.size() < 2) {
// Error case
return Optional.<BlockTransactionReceipt>empty();
}
final SpongeBlockSnapshot original = snapshots.get(0);
final SpongeBlockSnapshot result = snapshots.get(snapshots.size() - 1);
final Operation operation = context.getBlockOperation(original, result);
final BlockTransactionReceipt eventTransaction = new BlockTransactionReceipt(original, result, operation);
context.postBlockTransactionApplication(original.blockChange, eventTransaction);
return Optional.of(eventTransaction);
}).filter(Optional::isPresent).map(Optional::get).collect(ImmutableList.toImmutableList());
final Cause cause = PhaseTracker.getInstance().currentCause();
SpongeCommon.post(SpongeEventFactory.createChangeBlockEventPost(cause, transactions, serverWorld.get()));
});
}
use of org.spongepowered.api.world.server.ServerWorld in project SpongeCommon by SpongePowered.
the class SpongeContextCalculator method accumulateContexts.
@Override
public void accumulateContexts(final Cause causes, final Consumer<Context> accumulator) {
final ServerLocation /* @Nullable */
location = causes.context().get(EventContextKeys.LOCATION).orElse(null);
if (location != null) {
final ServerWorld world = location.worldIfAvailable().orElse(null);
if (world != null) {
accumulator.accept(world.context());
accumulator.accept(world.worldType().context());
}
}
causes.first(RemoteConnection.class).ifPresent(connection -> {
// TODO(zml): Wrong way to get a connection, add API?
this.remoteIpCache.get(connection).forEach(accumulator);
this.localIpCache.get(connection).forEach(accumulator);
accumulator.accept(new Context(Context.LOCAL_PORT_KEY, String.valueOf(connection.virtualHost().getPort())));
accumulator.accept(new Context(Context.LOCAL_HOST_KEY, connection.virtualHost().getHostName()));
});
}
Aggregations