use of org.spongepowered.api.world.server.ServerLocation in project SpongeCommon by SpongePowered.
the class DamageEventUtil method generateCauseFor.
/**
* This applies various contexts based on the type of {@link DamageSource}, whether
* it's provided by sponge or vanilla. This is not stack neutral, which is why it requires
* a {@link CauseStackManager.StackFrame} reference to push onto the stack.
*/
public static void generateCauseFor(final DamageSource damageSource, final CauseStackManager.StackFrame frame) {
if (damageSource instanceof EntityDamageSource) {
final net.minecraft.world.entity.Entity source = damageSource.getEntity();
if (!(source instanceof Player) && source instanceof CreatorTrackedBridge) {
final CreatorTrackedBridge creatorBridge = (CreatorTrackedBridge) source;
creatorBridge.tracker$getCreatorUUID().ifPresent(creator -> frame.addContext(EventContextKeys.CREATOR, creator));
creatorBridge.tracker$getNotifierUUID().ifPresent(notifier -> frame.addContext(EventContextKeys.NOTIFIER, notifier));
}
} else if (damageSource instanceof BlockDamageSource) {
final ServerLocation location = ((BlockDamageSource) damageSource).location();
final BlockPos blockPos = VecHelper.toBlockPos(location);
final LevelChunkBridge chunkBridge = (LevelChunkBridge) ((net.minecraft.world.level.Level) location.world()).getChunkAt(blockPos);
chunkBridge.bridge$getBlockCreatorUUID(blockPos).ifPresent(creator -> frame.addContext(EventContextKeys.CREATOR, creator));
chunkBridge.bridge$getBlockNotifierUUID(blockPos).ifPresent(notifier -> frame.addContext(EventContextKeys.NOTIFIER, notifier));
}
frame.pushCause(damageSource);
}
use of org.spongepowered.api.world.server.ServerLocation 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()));
});
}
use of org.spongepowered.api.world.server.ServerLocation in project SpongeCommon by SpongePowered.
the class CommandSourceStackMixin method impl$updateCauseOnWithWorld.
/*
* A note on why we're doing this with the cause manually.
*
* When the object is first constructed, we get the cause from the stack manager. However, as the command processor
* works through the nodes, this entire source may get replaced. We want to keep some of the changes in sync,
* but the original cause may have gone by the time the source changes. Really, this command source is the analogue
* of our Cause, NOT our CauseStackManager, so we just need to do `Cause.with(...)` along with their select `with*(...)`
* methods.
*/
@Inject(method = "withLevel", at = @At("RETURN"))
private void impl$updateCauseOnWithWorld(final ServerLevel serverWorld, final CallbackInfoReturnable<CommandSourceStack> cir) {
if (cir.getReturnValue() != (Object) this) {
final ServerLocation location = this.impl$cause.context().get(EventContextKeys.LOCATION).map(x -> ServerLocation.of((org.spongepowered.api.world.server.ServerWorld) serverWorld, x.position())).orElseGet(() -> ServerLocation.of((org.spongepowered.api.world.server.ServerWorld) serverWorld, VecHelper.toVector3d(cir.getReturnValue().getPosition())));
((CommandSourceStackBridge) cir.getReturnValue()).bridge$setCause(this.impl$applyToCause(EventContextKeys.LOCATION, location));
}
}
use of org.spongepowered.api.world.server.ServerLocation in project SpongeCommon by SpongePowered.
the class PlayerListMixin method impl$onInitPlayer_getWorld.
@Redirect(method = "placeNewPlayer", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;getLevel(Lnet/minecraft/resources/ResourceKey;)Lnet/minecraft/server/level/ServerLevel;"))
private net.minecraft.server.level.ServerLevel impl$onInitPlayer_getWorld(final MinecraftServer minecraftServer, final ResourceKey<Level> dimension, final Connection networkManager, final net.minecraft.server.level.ServerPlayer mcPlayer) {
@Nullable final net.minecraft.network.chat.Component kickReason = ((ConnectionBridge) networkManager).bridge$getKickReason();
final Component disconnectMessage;
if (kickReason != null) {
disconnectMessage = SpongeAdventure.asAdventure(kickReason);
} else {
disconnectMessage = Component.text("You are not allowed to log in to this server.");
}
net.minecraft.server.level.ServerLevel mcWorld = minecraftServer.getLevel(dimension);
if (mcWorld == null) {
SpongeCommon.logger().warn("The player '{}' was located in a world that isn't loaded or doesn't exist. This is not safe so " + "the player will be moved to the spawn of the default world.", mcPlayer.getGameProfile().getName());
mcWorld = minecraftServer.overworld();
final BlockPos spawnPoint = mcWorld.getSharedSpawnPos();
mcPlayer.setPos(spawnPoint.getX() + 0.5, spawnPoint.getY() + 0.5, spawnPoint.getZ() + 0.5);
}
mcPlayer.setLevel(mcWorld);
final ServerPlayer player = (ServerPlayer) mcPlayer;
final ServerLocation location = player.serverLocation();
final Vector3d rotation = player.rotation();
// player.connection() cannot be used here, because it's still be null at this point
final ServerSideConnection connection = (ServerSideConnection) networkManager.getPacketListener();
// The user is not yet in the player list, so we need to make special provision.
final User user = SpongeUserView.createLoginEventUser(player);
final Cause cause = Cause.of(EventContext.empty(), connection, user);
final ServerSideConnectionEvent.Login event = SpongeEventFactory.createServerSideConnectionEventLogin(cause, disconnectMessage, disconnectMessage, location, location, rotation, rotation, connection, user);
if (kickReason != null) {
event.setCancelled(true);
}
if (SpongeCommon.post(event)) {
this.impl$disconnectClient(networkManager, event.message(), player.profile());
return null;
}
final ServerLocation toLocation = event.toLocation();
final Vector3d toRotation = event.toRotation();
mcPlayer.absMoveTo(toLocation.x(), toLocation.y(), toLocation.z(), (float) toRotation.y(), (float) toRotation.x());
return (net.minecraft.server.level.ServerLevel) toLocation.world();
}
use of org.spongepowered.api.world.server.ServerLocation in project SpongeCommon by SpongePowered.
the class LivingEntityMixin method impl$callFinishSleepingEvent.
// End implementation of UseItemStackEvent
@Inject(method = "stopSleeping", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/LivingEntity;clearSleepingPos()V"))
private void impl$callFinishSleepingEvent(final CallbackInfo ci) {
if (this.level.isClientSide) {
return;
}
final Optional<BlockPos> sleepingPos = this.shadow$getSleepingPos();
if (!sleepingPos.isPresent()) {
return;
}
final BlockSnapshot snapshot = ((ServerWorld) this.level).createSnapshot(sleepingPos.get().getX(), sleepingPos.get().getY(), sleepingPos.get().getZ());
final Cause currentCause = Sponge.server().causeStackManager().currentCause();
final ServerLocation loc = ServerLocation.of((ServerWorld) this.level, VecHelper.toVector3d(this.shadow$position()));
final Vector3d rot = ((Living) this).rotation();
final SleepingEvent.Finish event = SpongeEventFactory.createSleepingEventFinish(currentCause, loc, loc, rot, rot, snapshot, (Living) this);
Sponge.eventManager().post(event);
this.shadow$clearSleepingPos();
if (event.toLocation().world() != this.level) {
throw new UnsupportedOperationException("World change is not supported here.");
}
this.shadow$setPos(event.toLocation().x(), event.toLocation().y(), event.toLocation().z());
((Living) this).setRotation(event.toRotation());
}
Aggregations