Search in sources :

Example 1 with PlayerList

use of net.minecraft.server.players.PlayerList in project SpongeCommon by SpongePowered.

the class ServerPlayerMixin method impl$postPortalForceChangeTasks.

@Override
protected final void impl$postPortalForceChangeTasks(final Entity entity, final net.minecraft.server.level.ServerLevel targetWorld, final boolean isNetherPortal) {
    // Standard vanilla processing
    this.gameMode.setLevel(targetWorld);
    this.connection.send(new ClientboundPlayerAbilitiesPacket(this.abilities));
    final PlayerList playerlist = this.server.getPlayerList();
    playerlist.sendLevelInfo((net.minecraft.server.level.ServerPlayer) (Object) this, targetWorld);
    playerlist.sendAllPlayerInfo((net.minecraft.server.level.ServerPlayer) (Object) this);
    // Sponge Start: teleport here after all data is sent to avoid any potential "stuttering" due to slow packets.
    final net.minecraft.world.phys.Vec3 finalPos = this.shadow$position();
    this.shadow$moveTo(finalPos.x, finalPos.y, finalPos.z);
    for (final MobEffectInstance effectinstance : this.shadow$getActiveEffects()) {
        this.connection.send(new ClientboundUpdateMobEffectPacket(this.shadow$getId(), effectinstance));
    }
    if (isNetherPortal) {
        // Sponge: only play the sound if we've got a vanilla teleporter that reports a nether portal
        this.connection.send(new ClientboundLevelEventPacket(1032, BlockPos.ZERO, 0, false));
    }
    // Sponge: end if
    this.lastSentExp = -1;
    this.lastSentHealth = -1.0F;
    this.lastSentFood = -1;
}
Also used : ClientboundPlayerAbilitiesPacket(net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket) PlayerList(net.minecraft.server.players.PlayerList) ClientboundLevelEventPacket(net.minecraft.network.protocol.game.ClientboundLevelEventPacket) MobEffectInstance(net.minecraft.world.effect.MobEffectInstance) ClientboundUpdateMobEffectPacket(net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket)

Example 2 with PlayerList

use of net.minecraft.server.players.PlayerList in project SpongeCommon by SpongePowered.

the class ServerLoginPacketListenerImplMixin method handleAcceptedLogin.

/**
 * @author morph - April 27th, 2021
 * @author dualspiral - July 17th, 2021
 *
 * @reason support async ban/whitelist service and user->player syncing.
 */
@Overwrite
public void handleAcceptedLogin() {
    if (!this.gameProfile.isComplete()) {
        this.gameProfile = this.shadow$createFakeProfile(this.gameProfile);
    }
    // Sponge start - avoid #tick calling handleAcceptedLogin more than once.
    if (this.impl$accepted) {
        return;
    }
    this.impl$accepted = true;
    final PlayerList playerList = this.server.getPlayerList();
    // Sponge end
    // Sponge start - completable future
    ((PlayerListBridge) playerList).bridge$canPlayerLogin(this.connection.getRemoteAddress(), this.gameProfile).handle((componentOpt, throwable) -> {
        if (throwable != null) {
            // An error occurred during login checks so we ask to abort.
            ((ConnectionBridge) this.connection).bridge$setKickReason(new TextComponent("An error occurred checking ban/whitelist status."));
            SpongeCommon.logger().error("An error occurred when checking the ban/whitelist status of {}.", this.gameProfile.getId().toString());
            SpongeCommon.logger().error(throwable);
        } else if (componentOpt != null) {
            // We handle this later
            ((ConnectionBridge) this.connection).bridge$setKickReason(componentOpt);
        }
        try {
            ((SpongeServer) SpongeCommon.server()).userManager().handlePlayerLogin(this.gameProfile);
        } catch (final IOException e) {
            throw new CompletionException(e);
        }
        return null;
    }).handleAsync((ignored, throwable) -> {
        if (throwable != null) {
            // We're just going to disconnect here, because something went horribly wrong.
            if (throwable instanceof CompletionException) {
                throw (CompletionException) throwable;
            } else {
                throw new CompletionException(throwable);
            }
        }
        // Sponge end
        this.state = ServerLoginPacketListenerImpl.State.ACCEPTED;
        if (this.server.getCompressionThreshold() >= 0 && !this.connection.isMemoryConnection()) {
            this.connection.send(new ClientboundLoginCompressionPacket(this.server.getCompressionThreshold()), (param0) -> this.connection.setupCompression(this.server.getCompressionThreshold()));
        }
        this.connection.send(new ClientboundGameProfilePacket(this.gameProfile));
        final ServerPlayer var1 = this.server.getPlayerList().getPlayer(this.gameProfile.getId());
        if (var1 != null) {
            this.state = ServerLoginPacketListenerImpl.State.DELAY_ACCEPT;
            this.delayedAcceptPlayer = this.server.getPlayerList().getPlayerForLogin(this.gameProfile);
        } else {
            // Sponge start - Also send the channel registrations using the minecraft channel, for compatibility
            final ServerSideConnection connection = (ServerSideConnection) this;
            ((SpongeChannelManager) Sponge.channelManager()).sendChannelRegistrations(connection);
            try {
                this.server.getPlayerList().placeNewPlayer(this.connection, this.server.getPlayerList().getPlayerForLogin(this.gameProfile));
                // invalidate just to be sure there is no user cached for the online player anymore
                Sponge.server().userManager().removeFromCache(this.gameProfile.getId());
            } catch (final Exception e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }, SpongeCommon.server()).exceptionally(throwable -> {
        // If a throwable exists, we're just going to disconnect the user, better than leaving them in limbo.
        if (throwable != null) {
            this.impl$disconnectError(throwable, this.state == ServerLoginPacketListenerImpl.State.ACCEPTED || this.state == ServerLoginPacketListenerImpl.State.READY_TO_ACCEPT);
        }
        return null;
    // Sponge End
    });
}
Also used : TextComponent(net.minecraft.network.chat.TextComponent) ServerSideConnection(org.spongepowered.api.network.ServerSideConnection) ConnectionBridge(org.spongepowered.common.bridge.network.ConnectionBridge) ServerSideConnectionEvent(org.spongepowered.api.event.network.ServerSideConnectionEvent) Inject(org.spongepowered.asm.mixin.injection.Inject) SpongeServer(org.spongepowered.common.SpongeServer) Connection(net.minecraft.network.Connection) Overwrite(org.spongepowered.asm.mixin.Overwrite) SpongeAdventure(org.spongepowered.common.adventure.SpongeAdventure) EventContext(org.spongepowered.api.event.EventContext) PlayerList(net.minecraft.server.players.PlayerList) ClientboundLoginCompressionPacket(net.minecraft.network.protocol.login.ClientboundLoginCompressionPacket) ServerPlayer(net.minecraft.server.level.ServerPlayer) CallbackInfo(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) MinecraftServer(net.minecraft.server.MinecraftServer) Mixin(org.spongepowered.asm.mixin.Mixin) Component(net.kyori.adventure.text.Component) ConnectionHolderBridge(org.spongepowered.common.bridge.network.ConnectionHolderBridge) PlayerListBridge(org.spongepowered.common.bridge.server.players.PlayerListBridge) At(org.spongepowered.asm.mixin.injection.At) Opcodes(org.objectweb.asm.Opcodes) ServerLoginPacketListenerImplBridge(org.spongepowered.common.bridge.server.network.ServerLoginPacketListenerImplBridge) ClientboundGameProfilePacket(net.minecraft.network.protocol.login.ClientboundGameProfilePacket) ServerLoginPacketListenerImpl(net.minecraft.server.network.ServerLoginPacketListenerImpl) Redirect(org.spongepowered.asm.mixin.injection.Redirect) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) Sponge(org.spongepowered.api.Sponge) SpongeChannelManager(org.spongepowered.common.network.channel.SpongeChannelManager) IOException(java.io.IOException) CompletionException(java.util.concurrent.CompletionException) SpongeCommon(org.spongepowered.common.SpongeCommon) Final(org.spongepowered.asm.mixin.Final) ClientboundDisconnectPacket(net.minecraft.network.protocol.game.ClientboundDisconnectPacket) Cause(org.spongepowered.api.event.Cause) TextComponent(net.minecraft.network.chat.TextComponent) Shadow(org.spongepowered.asm.mixin.Shadow) ClientboundLoginCompressionPacket(net.minecraft.network.protocol.login.ClientboundLoginCompressionPacket) PlayerList(net.minecraft.server.players.PlayerList) ConnectionBridge(org.spongepowered.common.bridge.network.ConnectionBridge) CompletionException(java.util.concurrent.CompletionException) ServerPlayer(net.minecraft.server.level.ServerPlayer) ServerSideConnection(org.spongepowered.api.network.ServerSideConnection) IOException(java.io.IOException) IOException(java.io.IOException) CompletionException(java.util.concurrent.CompletionException) ClientboundGameProfilePacket(net.minecraft.network.protocol.login.ClientboundGameProfilePacket) Overwrite(org.spongepowered.asm.mixin.Overwrite)

Example 3 with PlayerList

use of net.minecraft.server.players.PlayerList in project SpongeCommon by SpongePowered.

the class ServerGamePacketListenerImplMixin_Vanilla method vanilla$onProcessChatMessage.

@Inject(method = "handleChat(Ljava/lang/String;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/players/PlayerList;broadcastMessage(Lnet/minecraft/network/chat/Component;Lnet/minecraft/network/chat/ChatType;Ljava/util/UUID;)V"), cancellable = true, locals = LocalCapture.CAPTURE_FAILHARD)
private void vanilla$onProcessChatMessage(String var1, CallbackInfo ci, net.minecraft.network.chat.Component component) {
    ChatFormatter.formatChatComponent((net.minecraft.network.chat.TranslatableComponent) component);
    final ServerPlayer player = (ServerPlayer) this.player;
    final PlayerChatFormatter chatFormatter = player.chatFormatter();
    final TextComponent rawMessage = Component.text(var1);
    try (CauseStackManager.StackFrame frame = PhaseTracker.SERVER.pushCauseFrame()) {
        frame.pushCause(this.player);
        final Audience audience = (Audience) this.server;
        final PlayerChatEvent event = SpongeEventFactory.createPlayerChatEvent(frame.currentCause(), audience, Optional.of(audience), chatFormatter, Optional.of(chatFormatter), rawMessage, rawMessage);
        if (SpongeCommon.post(event)) {
            ci.cancel();
        } else {
            event.chatFormatter().ifPresent(formatter -> event.audience().map(SpongeAdventure::unpackAudiences).ifPresent(targets -> {
                for (Audience target : targets) {
                    formatter.format(player, target, event.message(), event.originalMessage()).ifPresent(formattedMessage -> target.sendMessage(player, formattedMessage));
                }
            }));
        }
    }
}
Also used : TextComponent(net.kyori.adventure.text.TextComponent) Inventory(org.spongepowered.api.item.inventory.Inventory) NonNull(org.checkerframework.checker.nullness.qual.NonNull) RecipeBookMenu(net.minecraft.world.inventory.RecipeBookMenu) Inject(org.spongepowered.asm.mixin.injection.Inject) SpongeAdventure(org.spongepowered.common.adventure.SpongeAdventure) EffectTransactor(org.spongepowered.common.event.tracking.context.transaction.EffectTransactor) PlayerList(net.minecraft.server.players.PlayerList) CallbackInfo(org.spongepowered.asm.mixin.injection.callback.CallbackInfo) MinecraftServer(net.minecraft.server.MinecraftServer) Mixin(org.spongepowered.asm.mixin.Mixin) Component(net.kyori.adventure.text.Component) ServerboundCustomPayloadPacket(net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket) CauseStackManager(org.spongepowered.api.event.CauseStackManager) TransactionalCaptureSupplier(org.spongepowered.common.event.tracking.context.transaction.TransactionalCaptureSupplier) ServerGamePacketListener(net.minecraft.network.protocol.game.ServerGamePacketListener) LocalCapture(org.spongepowered.asm.mixin.injection.callback.LocalCapture) At(org.spongepowered.asm.mixin.injection.At) TextComponent(net.kyori.adventure.text.TextComponent) Redirect(org.spongepowered.asm.mixin.injection.Redirect) SpongeEventFactory(org.spongepowered.api.event.SpongeEventFactory) EngineConnection(org.spongepowered.api.network.EngineConnection) Sponge(org.spongepowered.api.Sponge) PlayerChatEvent(org.spongepowered.api.event.message.PlayerChatEvent) SpongeChannelManager(org.spongepowered.common.network.channel.SpongeChannelManager) Group(org.spongepowered.asm.mixin.injection.Group) ChatType(net.minecraft.network.chat.ChatType) SpongeCommon(org.spongepowered.common.SpongeCommon) PhaseTracker(org.spongepowered.common.event.tracking.PhaseTracker) UUID(java.util.UUID) Final(org.spongepowered.asm.mixin.Final) QueryTypes(org.spongepowered.api.item.inventory.query.QueryTypes) ServerGamePacketListenerImpl(net.minecraft.server.network.ServerGamePacketListenerImpl) PlayerChatFormatter(org.spongepowered.api.entity.living.player.PlayerChatFormatter) Audience(net.kyori.adventure.audience.Audience) Recipe(net.minecraft.world.item.crafting.Recipe) PhaseContext(org.spongepowered.common.event.tracking.PhaseContext) CraftingInventory(org.spongepowered.api.item.inventory.crafting.CraftingInventory) ServerboundCustomPayloadPacketAccessor(org.spongepowered.common.accessor.network.protocol.game.ServerboundCustomPayloadPacketAccessor) ChatFormatter(org.spongepowered.vanilla.chat.ChatFormatter) Shadow(org.spongepowered.asm.mixin.Shadow) Optional(java.util.Optional) ServerPlayer(org.spongepowered.api.entity.living.player.server.ServerPlayer) PlayerChatEvent(org.spongepowered.api.event.message.PlayerChatEvent) Audience(net.kyori.adventure.audience.Audience) CauseStackManager(org.spongepowered.api.event.CauseStackManager) ServerPlayer(org.spongepowered.api.entity.living.player.server.ServerPlayer) SpongeAdventure(org.spongepowered.common.adventure.SpongeAdventure) PlayerChatFormatter(org.spongepowered.api.entity.living.player.PlayerChatFormatter) Inject(org.spongepowered.asm.mixin.injection.Inject)

Example 4 with PlayerList

use of net.minecraft.server.players.PlayerList in project SpongeCommon by SpongePowered.

the class EntityUtil method performPostChangePlayerWorldLogic.

public static void performPostChangePlayerWorldLogic(final ServerPlayer player, final ServerLevel fromWorld, final ServerLevel originalToWorld, final ServerLevel toWorld, final boolean isPortal) {
    // Sponge Start - Send any platform dimension data
    ((ServerPlayerBridge) player).bridge$sendDimensionData(player.connection.connection, toWorld.dimensionType(), toWorld.dimension());
    // Sponge End
    final LevelData worldinfo = toWorld.getLevelData();
    // We send dimension change for portals before loading chunks
    if (!isPortal) {
        // Sponge Start - Allow the platform to handle how dimension changes are sent down
        ((ServerPlayerBridge) player).bridge$sendChangeDimension(toWorld.dimensionType(), toWorld.dimension(), BiomeManager.obfuscateSeed(toWorld.getSeed()), player.gameMode.getGameModeForPlayer(), player.gameMode.getPreviousGameModeForPlayer(), toWorld.isDebug(), toWorld.isFlat(), true);
    }
    // Sponge End
    player.connection.send(new ClientboundChangeDifficultyPacket(worldinfo.getDifficulty(), worldinfo.isDifficultyLocked()));
    final PlayerList playerlist = player.getServer().getPlayerList();
    playerlist.sendPlayerPermissionLevel(player);
    // Sponge Start - Have the platform handle removing the entity from the world. Move this to after the event call so
    // that we do not remove the player from the world unless we really have teleported..
    ((PlatformServerLevelBridge) fromWorld).bridge$removeEntity(player, true);
    ((PlatformEntityBridge) player).bridge$revive();
    // Sponge End
    player.setLevel(toWorld);
    toWorld.addDuringPortalTeleport(player);
    if (isPortal) {
        ((ServerPlayerAccessor) player).invoker$triggerDimensionChangeTriggers(toWorld);
    }
    player.gameMode.setLevel(toWorld);
    player.connection.send(new ClientboundPlayerAbilitiesPacket(player.abilities));
    playerlist.sendLevelInfo(player, toWorld);
    playerlist.sendAllPlayerInfo(player);
    for (final MobEffectInstance effectinstance : player.getActiveEffects()) {
        player.connection.send(new ClientboundUpdateMobEffectPacket(player.getId(), effectinstance));
    }
    if (isPortal) {
        player.connection.send(new ClientboundLevelEventPacket(1032, BlockPos.ZERO, 0, false));
    }
    ((ServerLevelBridge) fromWorld).bridge$getBossBarManager().onPlayerDisconnect(player);
    ((ServerLevelBridge) toWorld).bridge$getBossBarManager().onPlayerDisconnect(player);
    ((ServerPlayerAccessor) player).accessor$lastSentExp(-1);
    ((ServerPlayerAccessor) player).accessor$lastSentHealth(-1.0f);
    ((ServerPlayerAccessor) player).accessor$lastSentFood(-1);
    if (!isPortal) {
        player.connection.teleport(player.getX(), player.getY(), player.getZ(), player.yRot, player.xRot);
        player.connection.resetPosition();
    }
    if (player.containerMenu != player.inventoryMenu) {
        player.closeContainer();
    }
    // Sponge Start - Call event
    Sponge.eventManager().post(SpongeEventFactory.createChangeEntityWorldEventPost(PhaseTracker.getCauseStackManager().currentCause(), (org.spongepowered.api.entity.Entity) player, (ServerWorld) fromWorld, (ServerWorld) originalToWorld, (ServerWorld) toWorld));
// Sponge End
}
Also used : Entity(net.minecraft.world.entity.Entity) ItemEntity(net.minecraft.world.entity.item.ItemEntity) PlatformServerLevelBridge(org.spongepowered.common.bridge.world.level.PlatformServerLevelBridge) PlayerList(net.minecraft.server.players.PlayerList) ClientboundLevelEventPacket(net.minecraft.network.protocol.game.ClientboundLevelEventPacket) MobEffectInstance(net.minecraft.world.effect.MobEffectInstance) ClientboundChangeDifficultyPacket(net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket) ClientboundUpdateMobEffectPacket(net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket) PlatformEntityBridge(org.spongepowered.common.bridge.world.entity.PlatformEntityBridge) ServerPlayerBridge(org.spongepowered.common.bridge.server.level.ServerPlayerBridge) ServerWorld(org.spongepowered.api.world.server.ServerWorld) ClientboundPlayerAbilitiesPacket(net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket) ServerPlayerAccessor(org.spongepowered.common.accessor.server.level.ServerPlayerAccessor) LevelData(net.minecraft.world.level.storage.LevelData)

Example 5 with PlayerList

use of net.minecraft.server.players.PlayerList in project SpongeCommon by SpongePowered.

the class ServerPlayerMixin method impl$prepareForPortalTeleport.

@Override
protected final void impl$prepareForPortalTeleport(final ServerLevel currentWorld, final ServerLevel targetWorld) {
    final LevelData levelData = targetWorld.getLevelData();
    this.connection.send(new ClientboundRespawnPacket(targetWorld.dimensionType(), targetWorld.dimension(), BiomeManager.obfuscateSeed(targetWorld.getSeed()), this.gameMode.getGameModeForPlayer(), this.gameMode.getPreviousGameModeForPlayer(), targetWorld.isDebug(), targetWorld.isFlat(), true));
    this.connection.send(new ClientboundChangeDifficultyPacket(levelData.getDifficulty(), levelData.isDifficultyLocked()));
    final PlayerList playerlist = this.server.getPlayerList();
    playerlist.sendPlayerPermissionLevel((net.minecraft.server.level.ServerPlayer) (Object) this);
    currentWorld.removePlayerImmediately((net.minecraft.server.level.ServerPlayer) (Object) this);
    this.removed = false;
}
Also used : PlayerList(net.minecraft.server.players.PlayerList) ClientboundRespawnPacket(net.minecraft.network.protocol.game.ClientboundRespawnPacket) ClientboundChangeDifficultyPacket(net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket) LevelData(net.minecraft.world.level.storage.LevelData)

Aggregations

PlayerList (net.minecraft.server.players.PlayerList)5 Component (net.kyori.adventure.text.Component)2 ClientboundChangeDifficultyPacket (net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket)2 ClientboundLevelEventPacket (net.minecraft.network.protocol.game.ClientboundLevelEventPacket)2 ClientboundPlayerAbilitiesPacket (net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket)2 ClientboundUpdateMobEffectPacket (net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket)2 MinecraftServer (net.minecraft.server.MinecraftServer)2 MobEffectInstance (net.minecraft.world.effect.MobEffectInstance)2 Sponge (org.spongepowered.api.Sponge)2 SpongeEventFactory (org.spongepowered.api.event.SpongeEventFactory)2 Final (org.spongepowered.asm.mixin.Final)2 Mixin (org.spongepowered.asm.mixin.Mixin)2 Shadow (org.spongepowered.asm.mixin.Shadow)2 At (org.spongepowered.asm.mixin.injection.At)2 Inject (org.spongepowered.asm.mixin.injection.Inject)2 Redirect (org.spongepowered.asm.mixin.injection.Redirect)2 CallbackInfo (org.spongepowered.asm.mixin.injection.callback.CallbackInfo)2 SpongeCommon (org.spongepowered.common.SpongeCommon)2 SpongeAdventure (org.spongepowered.common.adventure.SpongeAdventure)2 SpongeChannelManager (org.spongepowered.common.network.channel.SpongeChannelManager)2