package net.minecraft.network.protocol.game;

import net.minecraft.network.PacketListener;
import java.util.Iterator;
import java.io.IOException;
import net.minecraft.core.Registry;
import com.google.common.collect.Sets;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.core.RegistryAccess;
import net.minecraft.world.level.Level;
import net.minecraft.resources.ResourceKey;
import java.util.Set;
import net.minecraft.world.level.GameType;
import net.minecraft.network.protocol.Packet;

public class ClientboundLoginPacket implements Packet<ClientGamePacketListener> {
    private int playerId;
    private long seed;
    private boolean hardcore;
    private GameType gameType;
    private GameType previousGameType;
    private Set<ResourceKey<Level>> levels;
    private RegistryAccess.RegistryHolder registryHolder;
    private ResourceKey<DimensionType> dimensionType;
    private ResourceKey<Level> dimension;
    private int maxPlayers;
    private int chunkRadius;
    private boolean reducedDebugInfo;
    private boolean showDeathScreen;
    private boolean isDebug;
    private boolean isFlat;
    
    public ClientboundLoginPacket() {
    }
    
    public ClientboundLoginPacket(final int integer1, final GameType bpy2, final GameType bpy3, final long long4, final boolean boolean5, final Set<ResourceKey<Level>> set, final RegistryAccess.RegistryHolder a, final ResourceKey<DimensionType> ug8, final ResourceKey<Level> ug9, final int integer10, final int integer11, final boolean boolean12, final boolean boolean13, final boolean boolean14, final boolean boolean15) {
        this.playerId = integer1;
        this.levels = set;
        this.registryHolder = a;
        this.dimensionType = ug8;
        this.dimension = ug9;
        this.seed = long4;
        this.gameType = bpy2;
        this.previousGameType = bpy3;
        this.maxPlayers = integer10;
        this.hardcore = boolean5;
        this.chunkRadius = integer11;
        this.reducedDebugInfo = boolean12;
        this.showDeathScreen = boolean13;
        this.isDebug = boolean14;
        this.isFlat = boolean15;
    }
    
    @Override
    public void read(final FriendlyByteBuf mg) throws IOException {
        this.playerId = mg.readInt();
        int integer3 = mg.readUnsignedByte();
        this.hardcore = ((integer3 & 0x8) == 0x8);
        integer3 &= 0xFFFFFFF7;
        this.gameType = GameType.byId(integer3);
        this.previousGameType = GameType.byId(mg.readUnsignedByte());
        final int integer4 = mg.readVarInt();
        this.levels = Sets.newHashSet();
        for (int integer5 = 0; integer5 < integer4; ++integer5) {
            this.levels.add(ResourceKey.<Level>create(Registry.DIMENSION_REGISTRY, mg.readResourceLocation()));
        }
        this.registryHolder = mg.<RegistryAccess.RegistryHolder>readWithCodec(RegistryAccess.RegistryHolder.CODEC);
        this.dimensionType = ResourceKey.<DimensionType>create(Registry.DIMENSION_TYPE_REGISTRY, mg.readResourceLocation());
        this.dimension = ResourceKey.<Level>create(Registry.DIMENSION_REGISTRY, mg.readResourceLocation());
        this.seed = mg.readLong();
        this.maxPlayers = mg.readUnsignedByte();
        this.chunkRadius = mg.readVarInt();
        this.reducedDebugInfo = mg.readBoolean();
        this.showDeathScreen = mg.readBoolean();
        this.isDebug = mg.readBoolean();
        this.isFlat = mg.readBoolean();
    }
    
    @Override
    public void write(final FriendlyByteBuf mg) throws IOException {
        mg.writeInt(this.playerId);
        int integer3 = this.gameType.getId();
        if (this.hardcore) {
            integer3 |= 0x8;
        }
        mg.writeByte(integer3);
        mg.writeByte(this.previousGameType.getId());
        mg.writeVarInt(this.levels.size());
        for (final ResourceKey<Level> ug5 : this.levels) {
            mg.writeResourceLocation(ug5.location());
        }
        mg.<RegistryAccess.RegistryHolder>writeWithCodec(RegistryAccess.RegistryHolder.CODEC, this.registryHolder);
        mg.writeResourceLocation(this.dimensionType.location());
        mg.writeResourceLocation(this.dimension.location());
        mg.writeLong(this.seed);
        mg.writeByte(this.maxPlayers);
        mg.writeVarInt(this.chunkRadius);
        mg.writeBoolean(this.reducedDebugInfo);
        mg.writeBoolean(this.showDeathScreen);
        mg.writeBoolean(this.isDebug);
        mg.writeBoolean(this.isFlat);
    }
    
    @Override
    public void handle(final ClientGamePacketListener nl) {
        nl.handleLogin(this);
    }
    
    public int getPlayerId() {
        return this.playerId;
    }
    
    public long getSeed() {
        return this.seed;
    }
    
    public boolean isHardcore() {
        return this.hardcore;
    }
    
    public GameType getGameType() {
        return this.gameType;
    }
    
    public GameType getPreviousGameType() {
        return this.previousGameType;
    }
    
    public Set<ResourceKey<Level>> levels() {
        return this.levels;
    }
    
    public RegistryAccess registryAccess() {
        return this.registryHolder;
    }
    
    public ResourceKey<DimensionType> getDimensionType() {
        return this.dimensionType;
    }
    
    public ResourceKey<Level> getDimension() {
        return this.dimension;
    }
    
    public int getChunkRadius() {
        return this.chunkRadius;
    }
    
    public boolean isReducedDebugInfo() {
        return this.reducedDebugInfo;
    }
    
    public boolean shouldShowDeathScreen() {
        return this.showDeathScreen;
    }
    
    public boolean isDebug() {
        return this.isDebug;
    }
    
    public boolean isFlat() {
        return this.isFlat;
    }
}
