Search in sources :

Example 16 with ServerPlayer

use of org.spongepowered.api.entity.living.player.server.ServerPlayer in project SpongeCommon by SpongePowered.

the class SpongeScoreCriterionProgress method set.

@Override
public Optional<Instant> set(final int score) {
    checkState(score >= 0 && score <= this.goal(), "Score cannot be negative or greater than the goal.");
    int lastScore = this.score();
    if (lastScore == score) {
        return this.get();
    }
    final CriterionEvent.Score.Change event;
    final Cause cause = PhaseTracker.getCauseStackManager().currentCause();
    final Advancement advancement = this.progress.advancement();
    final ServerPlayer player = ((PlayerAdvancementsBridge) ((AdvancementProgressBridge) this.progress).bridge$getPlayerAdvancements()).bridge$getPlayer();
    if (lastScore == this.goal()) {
        event = SpongeEventFactory.createCriterionEventScoreRevoke(cause, advancement, this.criterion(), player, lastScore, score);
    } else if (score == this.goal()) {
        event = SpongeEventFactory.createCriterionEventScoreGrant(cause, advancement, this.criterion(), player, Instant.now(), lastScore, score);
    } else {
        event = SpongeEventFactory.createCriterionEventScoreChange(cause, advancement, this.criterion(), player, lastScore, score);
    }
    if (SpongeCommon.post(event)) {
        return this.get();
    }
    SpongeScoreCriterion.BYPASS_EVENT = true;
    // This is the only case a instant will be returned
    if (score == this.goal()) {
        Instant instant = null;
        for (final AdvancementCriterion criterion : this.criterion.internalCriteria) {
            final org.spongepowered.api.advancement.criteria.CriterionProgress progress = this.progress.get(criterion).get();
            if (!progress.achieved()) {
                instant = progress.grant();
            }
        }
        this.score = score;
        return Optional.of(instant == null ? Instant.now() : instant);
    }
    for (final AdvancementCriterion criterion : this.criterion.internalCriteria) {
        final org.spongepowered.api.advancement.criteria.CriterionProgress progress = this.progress.get(criterion).get();
        // We don't have enough score, grant more criteria
        if (lastScore < score && !progress.achieved()) {
            progress.grant();
            lastScore++;
        // We have too much score, revoke more criteria
        } else if (lastScore > score && progress.achieved()) {
            progress.revoke();
            lastScore--;
        }
        // We reached the target score
        if (lastScore == score) {
            break;
        }
    }
    this.score = score;
    SpongeScoreCriterion.BYPASS_EVENT = false;
    return Optional.empty();
}
Also used : PlayerAdvancementsBridge(org.spongepowered.common.bridge.server.PlayerAdvancementsBridge) Instant(java.time.Instant) ScoreAdvancementCriterion(org.spongepowered.api.advancement.criteria.ScoreAdvancementCriterion) AdvancementCriterion(org.spongepowered.api.advancement.criteria.AdvancementCriterion) Cause(org.spongepowered.api.event.Cause) ServerPlayer(org.spongepowered.api.entity.living.player.server.ServerPlayer) Advancement(org.spongepowered.api.advancement.Advancement)

Example 17 with ServerPlayer

use of org.spongepowered.api.entity.living.player.server.ServerPlayer in project SpongeCommon by SpongePowered.

the class SpongePacketHandler method init.

public static void init(final SpongeChannelManager registry) {
    SpongePacketHandler.channel = registry.createChannel(ResourceKey.sponge("default"), PacketChannel.class);
    SpongePacketHandler.channel.registerTransactional(RequestBlockTrackerDataPacket.class, TrackerDataResponsePacket.class, 0).setRequestHandler(EngineConnectionTypes.SERVER_PLAYER, (requestPacket, connection, response) -> {
        final ServerPlayer player = connection.player();
        if (!player.hasPermission("sponge.debug.block-tracking")) {
            return;
        }
        final net.minecraft.server.level.ServerPlayer sender = (net.minecraft.server.level.ServerPlayer) player;
        final BlockPos pos = new BlockPos(requestPacket.x, requestPacket.y, requestPacket.z);
        if (!sender.level.hasChunkAt(pos)) {
            return;
        }
        final LevelChunkBridge levelChunkBridge = (LevelChunkBridge) sender.level.getChunkAt(pos);
        final Optional<UUID> owner = levelChunkBridge.bridge$getBlockCreatorUUID(pos);
        final Optional<UUID> notifier = levelChunkBridge.bridge$getBlockNotifierUUID(pos);
        response.success(SpongePacketHandler.createTrackerDataResponse(owner, notifier));
    });
    SpongePacketHandler.channel.registerTransactional(RequestEntityTrackerDataPacket.class, TrackerDataResponsePacket.class, 1).setRequestHandler(EngineConnectionTypes.SERVER_PLAYER, (requestPacket, connection, response) -> {
        final ServerPlayer player = connection.player();
        if (!player.hasPermission("sponge.debug.entity-tracking")) {
            return;
        }
        final net.minecraft.server.level.ServerPlayer sender = (net.minecraft.server.level.ServerPlayer) player;
        final Entity entity = sender.level.getEntity(requestPacket.entityId);
        if (!(entity instanceof CreatorTrackedBridge)) {
            return;
        }
        final CreatorTrackedBridge creatorTrackedBridge = (CreatorTrackedBridge) entity;
        final Optional<UUID> owner = creatorTrackedBridge.tracker$getCreatorUUID();
        final Optional<UUID> notifier = creatorTrackedBridge.tracker$getNotifierUUID();
        response.success(SpongePacketHandler.createTrackerDataResponse(owner, notifier));
    });
    SpongePacketHandler.channel.register(ChangeViewerEnvironmentPacket.class, 3).addHandler(ClientSideConnection.class, (packet, connection) -> {
        final ClientLevel world = Minecraft.getInstance().level;
        if (world == null) {
            return;
        }
        final DimensionType dimensionType = SpongeCommon.server().registryAccess().dimensionTypes().get(packet.dimensionLogic);
        ((LevelBridge) world).bridge$adjustDimensionLogic(dimensionType);
    });
}
Also used : Entity(net.minecraft.world.entity.Entity) DimensionType(net.minecraft.world.level.dimension.DimensionType) CreatorTrackedBridge(org.spongepowered.common.bridge.CreatorTrackedBridge) ClientLevel(net.minecraft.client.multiplayer.ClientLevel) PacketChannel(org.spongepowered.api.network.channel.packet.PacketChannel) LevelBridge(org.spongepowered.common.bridge.world.level.LevelBridge) ServerPlayer(org.spongepowered.api.entity.living.player.server.ServerPlayer) BlockPos(net.minecraft.core.BlockPos) LevelChunkBridge(org.spongepowered.common.bridge.world.level.chunk.LevelChunkBridge) UUID(java.util.UUID)

Example 18 with ServerPlayer

use of org.spongepowered.api.entity.living.player.server.ServerPlayer in project SpongeCommon by SpongePowered.

the class MinecraftServerMixin_API method shutdown.

@Override
public void shutdown(final Component kickMessage) {
    Objects.requireNonNull(kickMessage, "kickMessage");
    for (final ServerPlayer player : this.onlinePlayers()) {
        player.kick(kickMessage);
    }
    this.shadow$halt(false);
}
Also used : ServerPlayer(org.spongepowered.api.entity.living.player.server.ServerPlayer)

Example 19 with ServerPlayer

use of org.spongepowered.api.entity.living.player.server.ServerPlayer in project SpongeCommon by SpongePowered.

the class ServerGamePacketListenerImplMixin method impl$callMoveEntityEvent.

/**
 * Effectively, hooking into the following code block:
 * <pre>
 *       if (isMovePlayerPacketInvalid(packetIn)) {
 *          this.disconnect(new TranslationTextComponent("multiplayer.disconnect.invalid_player_movement"));
 *       } else {
 *          ServerWorld serverworld = this.server.world(this.player.dimension);
 *          if (!this.player.queuedEndExit) { // <---- Here is where we're injecting
 *             if (this.networkTickCount == 0) {
 *                this.captureCurrentPosition();
 *             }
 * </pre>
 * we can effectively short circuit the method to handle movement code where
 * returning {@code true} will escape the packet being processed further entirely and
 * {@code false} will allow the remaining processing of the method run.
 *
 * @param packetIn The movement packet
 */
@Inject(method = "handleMovePlayer", at = @At(value = "FIELD", opcode = Opcodes.GETFIELD, target = "Lnet/minecraft/server/network/ServerGamePacketListenerImpl;awaitingPositionFromClient:Lnet/minecraft/world/phys/Vec3;"), slice = @Slice(from = @At(value = "FIELD", target = "Lnet/minecraft/server/level/ServerPlayer;wonGame:Z"), to = @At(value = "FIELD", target = "Lnet/minecraft/server/network/ServerGamePacketListenerImpl;tickCount:I", ordinal = 1)), cancellable = true)
private void impl$callMoveEntityEvent(final ServerboundMovePlayerPacket packetIn, final CallbackInfo ci) {
    // If the movement is modified we pretend that the player has queuedEndExit = true
    // so that vanilla wont process that packet further
    final ServerboundMovePlayerPacketAccessor packetInAccessor = (ServerboundMovePlayerPacketAccessor) packetIn;
    // We don't fire an event to avoid confusing plugins.
    if (!packetInAccessor.accessor$hasPos() && !packetInAccessor.accessor$hasRot()) {
        return;
    }
    final boolean goodMovementPacket = this.receivedMovePacketCount - this.knownMovePacketCount <= 5;
    final boolean fireMoveEvent = goodMovementPacket && packetInAccessor.accessor$hasPos() && ShouldFire.MOVE_ENTITY_EVENT;
    final boolean fireRotationEvent = goodMovementPacket && packetInAccessor.accessor$hasRot() && ShouldFire.ROTATE_ENTITY_EVENT;
    final ServerPlayer player = (ServerPlayer) this.player;
    final Vector3d fromRotation = new Vector3d(this.player.yRot, this.player.xRot, 0);
    // Use the position of the last movement with an event or the current player position if never called
    // We need this because we ignore very small position changes as to not spam as many move events.
    final Vector3d fromPosition = player.position();
    Vector3d toPosition = new Vector3d(packetIn.getX(this.player.getX()), packetIn.getY(this.player.getY()), packetIn.getZ(this.player.getZ()));
    Vector3d toRotation = new Vector3d(packetIn.getYRot(this.player.yRot), packetIn.getXRot(this.player.xRot), 0);
    final boolean significantRotation = fromRotation.distanceSquared(toRotation) > (.15f * .15f);
    final Vector3d originalToPosition = toPosition;
    boolean cancelMovement = false;
    boolean cancelRotation = false;
    // Call move & rotate event as needed...
    if (fireMoveEvent) {
        final MoveEntityEvent event = SpongeEventFactory.createMoveEntityEvent(PhaseTracker.getCauseStackManager().currentCause(), (ServerPlayer) this.player, fromPosition, toPosition, toPosition);
        if (SpongeCommon.post(event)) {
            cancelMovement = true;
        } else {
            toPosition = event.destinationPosition();
        }
    }
    if (significantRotation && fireRotationEvent) {
        final RotateEntityEvent event = SpongeEventFactory.createRotateEntityEvent(PhaseTracker.getCauseStackManager().currentCause(), (ServerPlayer) this.player, fromRotation, toRotation);
        if (SpongeCommon.post(event)) {
            cancelRotation = true;
            toRotation = fromRotation;
        } else {
            toRotation = event.toRotation();
        }
    }
    // player position and update the player's relation in the chunk manager.
    if (cancelMovement) {
        if (fromPosition.distanceSquared(toPosition) > 0) {
            // Set the location, as if the player was teleporting
            this.awaitingTeleportTime = this.tickCount;
            this.shadow$teleport(fromPosition.x(), fromPosition.y(), fromPosition.z(), (float) toRotation.x(), (float) toRotation.y());
        } else {
            // If this is only rotation do not teleport back
            this.player.absMoveTo(fromPosition.x(), fromPosition.y(), fromPosition.z(), (float) toRotation.x(), (float) toRotation.y());
        }
        ci.cancel();
        return;
    }
    // Handle event results
    if (!toPosition.equals(originalToPosition)) {
        // Check if we have to say it's a "teleport" vs a standard move
        final double d4 = packetIn.getX(this.player.getX());
        final double d5 = packetIn.getY(this.player.getY());
        final double d6 = packetIn.getZ(this.player.getZ());
        final double d7 = d4 - this.firstGoodX;
        final double d8 = d5 - this.firstGoodY;
        final double d9 = d6 - this.firstGoodZ;
        final double d10 = this.player.getDeltaMovement().lengthSqr();
        final double d11 = d7 * d7 + d8 * d8 + d9 * d9;
        final float f2 = this.player.isFallFlying() ? 300.0F : 100.0F;
        final int i = this.receivedMovePacketCount - this.knownMovePacketCount;
        if (d11 - d10 > (double) (f2 * (float) i) && !this.shadow$isSingleplayerOwner()) {
            // At this point, we need to set the target position so the teleport code forces it
            this.awaitingPositionFromClient = VecHelper.toVanillaVector3d(toPosition);
            ((EntityAccessor) this.player).invoker$setRot((float) toRotation.x(), (float) toRotation.y());
            // And reset the position update so the force set is done.
            this.awaitingTeleportTime = this.tickCount - Constants.Networking.MAGIC_TRIGGER_TELEPORT_CONFIRM_DIFF;
        } else {
            // otherwise, set the data back onto the packet
            packetInAccessor.accessor$hasPos(true);
            packetInAccessor.accessor$x(toPosition.x());
            packetInAccessor.accessor$y(toPosition.y());
            packetInAccessor.accessor$z(toPosition.z());
        }
    }
}
Also used : EntityAccessor(org.spongepowered.common.accessor.world.entity.EntityAccessor) ServerboundMovePlayerPacketAccessor(org.spongepowered.common.accessor.network.protocol.game.ServerboundMovePlayerPacketAccessor) MoveEntityEvent(org.spongepowered.api.event.entity.MoveEntityEvent) Vector3d(org.spongepowered.math.vector.Vector3d) ServerPlayer(org.spongepowered.api.entity.living.player.server.ServerPlayer) RotateEntityEvent(org.spongepowered.api.event.entity.RotateEntityEvent) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 20 with ServerPlayer

use of org.spongepowered.api.entity.living.player.server.ServerPlayer in project SpongeCommon by SpongePowered.

the class PlayerListMixin method impl$onInitPlayer_join.

@Inject(method = "placeNewPlayer", at = @At(value = "RETURN"))
private void impl$onInitPlayer_join(final Connection networkManager, final net.minecraft.server.level.ServerPlayer mcPlayer, final CallbackInfo ci) {
    final ServerPlayer player = (ServerPlayer) mcPlayer;
    final ServerSideConnection connection = player.connection();
    final Cause cause = Cause.of(EventContext.empty(), connection, player);
    final Audience audience = Audiences.onlinePlayers();
    final Component joinComponent = SpongeAdventure.asAdventure(((ServerPlayerBridge) mcPlayer).bridge$getConnectionMessageToSend());
    final ServerSideConnectionEvent.Join event = SpongeEventFactory.createServerSideConnectionEventJoin(cause, audience, Optional.of(audience), joinComponent, joinComponent, connection, player, false);
    SpongeCommon.post(event);
    if (!event.isMessageCancelled()) {
        event.audience().ifPresent(audience1 -> audience1.sendMessage(Identity.nil(), event.message()));
    }
    ((ServerPlayerBridge) mcPlayer).bridge$setConnectionMessageToSend(null);
    final PhaseContext<?> context = PhaseTracker.SERVER.getPhaseContext();
    PhaseTracker.SERVER.pushCause(event);
    final TransactionalCaptureSupplier transactor = context.getTransactor();
    transactor.logPlayerInventoryChange(mcPlayer, PlayerInventoryTransaction.EventCreator.STANDARD);
    try (EffectTransactor ignored = BroadcastInventoryChangesEffect.transact(transactor)) {
        // in case plugins modified it
        mcPlayer.inventoryMenu.broadcastChanges();
    }
}
Also used : TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) Audience(net.kyori.adventure.audience.Audience) ServerPlayer(org.spongepowered.api.entity.living.player.server.ServerPlayer) Cause(org.spongepowered.api.event.Cause) ServerSideConnection(org.spongepowered.api.network.ServerSideConnection) ServerSideConnectionEvent(org.spongepowered.api.event.network.ServerSideConnectionEvent) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor) TranslatableComponent(net.minecraft.network.chat.TranslatableComponent) TextComponent(net.minecraft.network.chat.TextComponent) MutableComponent(net.minecraft.network.chat.MutableComponent) Component(net.kyori.adventure.text.Component) ServerPlayerBridge(org.spongepowered.common.bridge.server.level.ServerPlayerBridge) Inject(org.spongepowered.asm.mixin.injection.Inject)

Aggregations

ServerPlayer (org.spongepowered.api.entity.living.player.server.ServerPlayer)32 Component (net.kyori.adventure.text.Component)13 Cause (org.spongepowered.api.event.Cause)9 Listener (org.spongepowered.api.event.Listener)8 Sponge (org.spongepowered.api.Sponge)7 Inject (org.spongepowered.asm.mixin.injection.Inject)7 TypeToken (io.leangen.geantyref.TypeToken)6 RegistryTypes (org.spongepowered.api.registry.RegistryTypes)6 Inject (com.google.inject.Inject)5 UUID (java.util.UUID)5 Identity (net.kyori.adventure.identity.Identity)5 NamedTextColor (net.kyori.adventure.text.format.NamedTextColor)5 BlockPos (net.minecraft.core.BlockPos)5 AdvancementCriterion (org.spongepowered.api.advancement.criteria.AdvancementCriterion)5 CommandResult (org.spongepowered.api.command.CommandResult)5 CommandException (org.spongepowered.api.command.exception.CommandException)5 CommandContext (org.spongepowered.api.command.parameter.CommandContext)5 Map (java.util.Map)4 Command (org.spongepowered.api.command.Command)4 Parameter (org.spongepowered.api.command.parameter.Parameter)4