package net.minecraft.server.players;

import org.apache.logging.log4j.LogManager;
import net.minecraft.network.protocol.game.ClientboundSetChunkCacheRadiusPacket;
import net.minecraft.network.protocol.game.ClientboundChatPacket;
import net.minecraft.network.chat.ChatType;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.network.protocol.game.ClientboundSetTimePacket;
import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
import java.util.Collection;
import net.minecraft.world.scores.Team;
import java.util.Optional;
import net.minecraft.core.BlockPos;
import net.minecraft.network.protocol.game.ClientboundSetExperiencePacket;
import net.minecraft.network.protocol.game.ClientboundSetSpawnPositionPacket;
import net.minecraft.network.protocol.game.ClientboundRespawnPacket;
import net.minecraft.network.protocol.game.ClientboundGameEventPacket;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.level.LevelReader;
import net.minecraft.server.level.ServerPlayerGameMode;
import net.minecraft.server.level.DemoMode;
import java.net.SocketAddress;
import net.minecraft.stats.Stats;
import javax.annotation.Nullable;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.network.protocol.game.ClientboundSetBorderPacket;
import net.minecraft.world.level.border.WorldBorder;
import net.minecraft.world.level.border.BorderChangeListener;
import net.minecraft.world.scores.Objective;
import java.util.Set;
import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket;
import net.minecraft.world.scores.PlayerTeam;
import com.google.common.collect.Sets;
import net.minecraft.server.ServerScoreboard;
import java.util.Iterator;
import net.minecraft.network.chat.Component;
import net.minecraft.nbt.CompoundTag;
import com.mojang.authlib.GameProfile;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoPacket;
import net.minecraft.ChatFormatting;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.network.protocol.game.ClientboundUpdateTagsPacket;
import net.minecraft.network.protocol.game.ClientboundUpdateRecipesPacket;
import net.minecraft.network.protocol.game.ClientboundSetCarriedItemPacket;
import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket;
import net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket;
import net.minecraft.network.FriendlyByteBuf;
import io.netty.buffer.Unpooled;
import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundLoginPacket;
import net.minecraft.world.level.storage.LevelData;
import net.minecraft.world.level.GameRules;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.world.level.LevelAccessor;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import net.minecraft.network.Connection;
import com.google.common.collect.Maps;
import com.google.common.collect.Lists;
import net.minecraft.world.level.GameType;
import net.minecraft.world.level.storage.PlayerIO;
import net.minecraft.server.PlayerAdvancements;
import net.minecraft.stats.ServerStatsCounter;
import java.util.UUID;
import java.util.Map;
import net.minecraft.server.level.ServerPlayer;
import java.util.List;
import net.minecraft.server.MinecraftServer;
import java.text.SimpleDateFormat;
import org.apache.logging.log4j.Logger;
import java.io.File;

public abstract class PlayerList {
    public static final File USERBANLIST_FILE;
    public static final File IPBANLIST_FILE;
    public static final File OPLIST_FILE;
    public static final File WHITELIST_FILE;
    private static final Logger LOGGER;
    private static final SimpleDateFormat BAN_DATE_FORMAT;
    private final MinecraftServer server;
    private final List<ServerPlayer> players;
    private final Map<UUID, ServerPlayer> playersByUUID;
    private final UserBanList bans;
    private final IpBanList ipBans;
    private final ServerOpList ops;
    private final UserWhiteList whitelist;
    private final Map<UUID, ServerStatsCounter> stats;
    private final Map<UUID, PlayerAdvancements> advancements;
    private PlayerIO playerIo;
    private boolean doWhiteList;
    protected final int maxPlayers;
    private int viewDistance;
    private GameType overrideGameMode;
    private boolean allowCheatsForAllPlayers;
    private int sendAllPlayerInfoIn;
    
    public PlayerList(final MinecraftServer minecraftServer, final int integer) {
        this.players = Lists.newArrayList();
        this.playersByUUID = Maps.newHashMap();
        this.bans = new UserBanList(PlayerList.USERBANLIST_FILE);
        this.ipBans = new IpBanList(PlayerList.IPBANLIST_FILE);
        this.ops = new ServerOpList(PlayerList.OPLIST_FILE);
        this.whitelist = new UserWhiteList(PlayerList.WHITELIST_FILE);
        this.stats = Maps.newHashMap();
        this.advancements = Maps.newHashMap();
        this.server = minecraftServer;
        this.maxPlayers = integer;
        this.getBans().setEnabled(true);
        this.getIpBans().setEnabled(true);
    }
    
    public void placeNewPlayer(final Connection kt, final ServerPlayer xe) {
        final GameProfile gameProfile4 = xe.getGameProfile();
        final GameProfileCache zk5 = this.server.getProfileCache();
        final GameProfile gameProfile5 = zk5.get(gameProfile4.getId());
        final String string7 = (gameProfile5 == null) ? gameProfile4.getName() : gameProfile5.getName();
        zk5.add(gameProfile4);
        final CompoundTag jt8 = this.load(xe);
        final ServerLevel xd9 = this.server.getLevel(xe.dimension);
        xe.setLevel(xd9);
        xe.gameMode.setLevel((ServerLevel)xe.level);
        String string8 = "local";
        if (kt.getRemoteAddress() != null) {
            string8 = kt.getRemoteAddress().toString();
        }
        PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ({}, {}, {})", xe.getName().getString(), string8, xe.getId(), xe.getX(), xe.getY(), xe.getZ());
        final LevelData crm11 = xd9.getLevelData();
        this.updatePlayerGameMode(xe, null, xd9);
        final ServerGamePacketListenerImpl xv12 = new ServerGamePacketListenerImpl(this.server, kt, xe);
        final GameRules bjs13 = xd9.getGameRules();
        final boolean boolean14 = bjs13.getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN);
        final boolean boolean15 = bjs13.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO);
        xv12.send(new ClientboundLoginPacket(xe.getId(), xe.gameMode.getGameModeForPlayer(), LevelData.obfuscateSeed(crm11.getSeed()), crm11.isHardcore(), xd9.dimension.getType(), this.getMaxPlayers(), crm11.getGeneratorType(), this.viewDistance, boolean15, !boolean14));
        xv12.send(new ClientboundCustomPayloadPacket(ClientboundCustomPayloadPacket.BRAND, new FriendlyByteBuf(Unpooled.buffer()).writeUtf(this.getServer().getServerModName())));
        xv12.send(new ClientboundChangeDifficultyPacket(crm11.getDifficulty(), crm11.isDifficultyLocked()));
        xv12.send(new ClientboundPlayerAbilitiesPacket(xe.abilities));
        xv12.send(new ClientboundSetCarriedItemPacket(xe.inventory.selected));
        xv12.send(new ClientboundUpdateRecipesPacket(this.server.getRecipeManager().getRecipes()));
        xv12.send(new ClientboundUpdateTagsPacket(this.server.getTags()));
        this.sendPlayerPermissionLevel(xe);
        xe.getStats().markAllDirty();
        xe.getRecipeBook().sendInitialRecipeBook(xe);
        this.updateEntireScoreboard(xd9.getScoreboard(), xe);
        this.server.invalidateStatus();
        Component lf16;
        if (xe.getGameProfile().getName().equalsIgnoreCase(string7)) {
            lf16 = new TranslatableComponent("multiplayer.player.joined", new Object[] { xe.getDisplayName() });
        }
        else {
            lf16 = new TranslatableComponent("multiplayer.player.joined.renamed", new Object[] { xe.getDisplayName(), string7 });
        }
        this.broadcastMessage(lf16.withStyle(ChatFormatting.YELLOW));
        xv12.teleport(xe.getX(), xe.getY(), xe.getZ(), xe.yRot, xe.xRot);
        this.players.add(xe);
        this.playersByUUID.put(xe.getUUID(), xe);
        this.broadcastAll(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, new ServerPlayer[] { xe }));
        for (int integer17 = 0; integer17 < this.players.size(); ++integer17) {
            xe.connection.send(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.ADD_PLAYER, new ServerPlayer[] { this.players.get(integer17) }));
        }
        xd9.addNewPlayer(xe);
        this.server.getCustomBossEvents().onPlayerConnect(xe);
        this.sendLevelInfo(xe, xd9);
        if (!this.server.getResourcePack().isEmpty()) {
            xe.sendTexturePack(this.server.getResourcePack(), this.server.getResourcePackHash());
        }
        for (final MobEffectInstance akk18 : xe.getActiveEffects()) {
            xv12.send(new ClientboundUpdateMobEffectPacket(xe.getId(), akk18));
        }
        if (jt8 != null && jt8.contains("RootVehicle", 10)) {
            final CompoundTag jt9 = jt8.getCompound("RootVehicle");
            final Entity akq2 = EntityType.loadEntityRecursive(jt9.getCompound("Entity"), (Level)xd9, akq -> {
                if (!xd9.addWithUUID(akq)) {
                    return null;
                }
                else {
                    return akq;
                }
            });
            if (akq2 != null) {
                final UUID uUID19 = jt9.getUUID("Attach");
                if (akq2.getUUID().equals(uUID19)) {
                    xe.startRiding(akq2, true);
                }
                else {
                    for (final Entity akq3 : akq2.getIndirectPassengers()) {
                        if (akq3.getUUID().equals(uUID19)) {
                            xe.startRiding(akq3, true);
                            break;
                        }
                    }
                }
                if (!xe.isPassenger()) {
                    PlayerList.LOGGER.warn("Couldn't reattach entity to player");
                    xd9.despawn(akq2);
                    for (final Entity akq3 : akq2.getIndirectPassengers()) {
                        xd9.despawn(akq3);
                    }
                }
            }
        }
        xe.initMenu();
    }
    
    protected void updateEntireScoreboard(final ServerScoreboard ta, final ServerPlayer xe) {
        final Set<Objective> set4 = Sets.newHashSet();
        for (final PlayerTeam cwj6 : ta.getPlayerTeams()) {
            xe.connection.send(new ClientboundSetPlayerTeamPacket(cwj6, 0));
        }
        for (int integer5 = 0; integer5 < 19; ++integer5) {
            final Objective cwi6 = ta.getDisplayObjective(integer5);
            if (cwi6 != null && !set4.contains(cwi6)) {
                final List<Packet<?>> list7 = ta.getStartTrackingPackets(cwi6);
                for (final Packet<?> lt9 : list7) {
                    xe.connection.send(lt9);
                }
                set4.add(cwi6);
            }
        }
    }
    
    public void setLevel(final ServerLevel xd) {
        this.playerIo = xd.getLevelStorage();
        xd.getWorldBorder().addListener(new BorderChangeListener() {
            @Override
            public void onBorderSizeSet(final WorldBorder bzw, final double double2) {
                PlayerList.this.broadcastAll(new ClientboundSetBorderPacket(bzw, ClientboundSetBorderPacket.Type.SET_SIZE));
            }
            
            @Override
            public void onBorderSizeLerping(final WorldBorder bzw, final double double2, final double double3, final long long4) {
                PlayerList.this.broadcastAll(new ClientboundSetBorderPacket(bzw, ClientboundSetBorderPacket.Type.LERP_SIZE));
            }
            
            @Override
            public void onBorderCenterSet(final WorldBorder bzw, final double double2, final double double3) {
                PlayerList.this.broadcastAll(new ClientboundSetBorderPacket(bzw, ClientboundSetBorderPacket.Type.SET_CENTER));
            }
            
            @Override
            public void onBorderSetWarningTime(final WorldBorder bzw, final int integer) {
                PlayerList.this.broadcastAll(new ClientboundSetBorderPacket(bzw, ClientboundSetBorderPacket.Type.SET_WARNING_TIME));
            }
            
            @Override
            public void onBorderSetWarningBlocks(final WorldBorder bzw, final int integer) {
                PlayerList.this.broadcastAll(new ClientboundSetBorderPacket(bzw, ClientboundSetBorderPacket.Type.SET_WARNING_BLOCKS));
            }
            
            @Override
            public void onBorderSetDamagePerBlock(final WorldBorder bzw, final double double2) {
            }
            
            @Override
            public void onBorderSetDamageSafeZOne(final WorldBorder bzw, final double double2) {
            }
        });
    }
    
    @Nullable
    public CompoundTag load(final ServerPlayer xe) {
        final CompoundTag jt3 = this.server.getLevel(DimensionType.OVERWORLD).getLevelData().getLoadedPlayerTag();
        CompoundTag jt4;
        if (xe.getName().getString().equals(this.server.getSingleplayerName()) && jt3 != null) {
            jt4 = jt3;
            xe.load(jt4);
            PlayerList.LOGGER.debug("loading single player");
        }
        else {
            jt4 = this.playerIo.load(xe);
        }
        return jt4;
    }
    
    protected void save(final ServerPlayer xe) {
        this.playerIo.save(xe);
        final ServerStatsCounter aan3 = this.stats.get(xe.getUUID());
        if (aan3 != null) {
            aan3.save();
        }
        final PlayerAdvancements sv4 = this.advancements.get(xe.getUUID());
        if (sv4 != null) {
            sv4.save();
        }
    }
    
    public void remove(final ServerPlayer xe) {
        final ServerLevel xd3 = xe.getLevel();
        xe.awardStat(Stats.LEAVE_GAME);
        this.save(xe);
        if (xe.isPassenger()) {
            final Entity akq4 = xe.getRootVehicle();
            if (akq4.hasOnePlayerPassenger()) {
                PlayerList.LOGGER.debug("Removing player mount");
                xe.stopRiding();
                xd3.despawn(akq4);
                for (final Entity akq5 : akq4.getIndirectPassengers()) {
                    xd3.despawn(akq5);
                }
                xd3.getChunk(xe.xChunk, xe.zChunk).markUnsaved();
            }
        }
        xe.unRide();
        xd3.removePlayerImmediately(xe);
        xe.getAdvancements().stopListening();
        this.players.remove(xe);
        this.server.getCustomBossEvents().onPlayerDisconnect(xe);
        final UUID uUID4 = xe.getUUID();
        final ServerPlayer xe2 = this.playersByUUID.get(uUID4);
        if (xe2 == xe) {
            this.playersByUUID.remove(uUID4);
            this.stats.remove(uUID4);
            this.advancements.remove(uUID4);
        }
        this.broadcastAll(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.REMOVE_PLAYER, new ServerPlayer[] { xe }));
    }
    
    @Nullable
    public Component canPlayerLogin(final SocketAddress socketAddress, final GameProfile gameProfile) {
        if (this.bans.isBanned(gameProfile)) {
            final UserBanListEntry zu4 = this.bans.get(gameProfile);
            final Component lf5 = new TranslatableComponent("multiplayer.disconnect.banned.reason", new Object[] { zu4.getReason() });
            if (zu4.getExpires() != null) {
                lf5.append(new TranslatableComponent("multiplayer.disconnect.banned.expiration", new Object[] { PlayerList.BAN_DATE_FORMAT.format(zu4.getExpires()) }));
            }
            return lf5;
        }
        if (!this.isWhiteListed(gameProfile)) {
            return new TranslatableComponent("multiplayer.disconnect.not_whitelisted", new Object[0]);
        }
        if (this.ipBans.isBanned(socketAddress)) {
            final IpBanListEntry zm4 = this.ipBans.get(socketAddress);
            final Component lf5 = new TranslatableComponent("multiplayer.disconnect.banned_ip.reason", new Object[] { zm4.getReason() });
            if (zm4.getExpires() != null) {
                lf5.append(new TranslatableComponent("multiplayer.disconnect.banned_ip.expiration", new Object[] { PlayerList.BAN_DATE_FORMAT.format(zm4.getExpires()) }));
            }
            return lf5;
        }
        if (this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameProfile)) {
            return new TranslatableComponent("multiplayer.disconnect.server_full", new Object[0]);
        }
        return null;
    }
    
    public ServerPlayer getPlayerForLogin(final GameProfile gameProfile) {
        final UUID uUID3 = Player.createPlayerUUID(gameProfile);
        final List<ServerPlayer> list4 = Lists.newArrayList();
        for (int integer5 = 0; integer5 < this.players.size(); ++integer5) {
            final ServerPlayer xe6 = this.players.get(integer5);
            if (xe6.getUUID().equals(uUID3)) {
                list4.add(xe6);
            }
        }
        final ServerPlayer xe7 = this.playersByUUID.get(gameProfile.getId());
        if (xe7 != null && !list4.contains(xe7)) {
            list4.add(xe7);
        }
        for (final ServerPlayer xe8 : list4) {
            xe8.connection.disconnect(new TranslatableComponent("multiplayer.disconnect.duplicate_login", new Object[0]));
        }
        ServerPlayerGameMode xf6;
        if (this.server.isDemo()) {
            xf6 = new DemoMode(this.server.getLevel(DimensionType.OVERWORLD));
        }
        else {
            xf6 = new ServerPlayerGameMode(this.server.getLevel(DimensionType.OVERWORLD));
        }
        return new ServerPlayer(this.server, this.server.getLevel(DimensionType.OVERWORLD), gameProfile, xf6);
    }
    
    public ServerPlayer respawn(final ServerPlayer xe, final DimensionType cbi, final boolean boolean3) {
        this.players.remove(xe);
        xe.getLevel().removePlayerImmediately(xe);
        final BlockPos fk5 = xe.getRespawnPosition();
        final boolean boolean4 = xe.isRespawnForced();
        xe.dimension = cbi;
        ServerPlayerGameMode xf7;
        if (this.server.isDemo()) {
            xf7 = new DemoMode(this.server.getLevel(xe.dimension));
        }
        else {
            xf7 = new ServerPlayerGameMode(this.server.getLevel(xe.dimension));
        }
        final ServerPlayer xe2 = new ServerPlayer(this.server, this.server.getLevel(xe.dimension), xe.getGameProfile(), xf7);
        xe2.connection = xe.connection;
        xe2.restoreFrom(xe, boolean3);
        xe2.setId(xe.getId());
        xe2.setMainArm(xe.getMainArm());
        for (final String string10 : xe.getTags()) {
            xe2.addTag(string10);
        }
        final ServerLevel xd9 = this.server.getLevel(xe.dimension);
        this.updatePlayerGameMode(xe2, xe, xd9);
        if (fk5 != null) {
            final Optional<Vec3> optional10 = Player.checkBedValidRespawnPosition(this.server.getLevel(xe.dimension), fk5, boolean4);
            if (optional10.isPresent()) {
                final Vec3 cvl11 = optional10.get();
                xe2.moveTo(cvl11.x, cvl11.y, cvl11.z, 0.0f, 0.0f);
                xe2.setRespawnPosition(fk5, boolean4, false);
            }
            else {
                xe2.connection.send(new ClientboundGameEventPacket(0, 0.0f));
            }
        }
        while (!xd9.noCollision(xe2) && xe2.getY() < 256.0) {
            xe2.setPos(xe2.getX(), xe2.getY() + 1.0, xe2.getZ());
        }
        final LevelData crm10 = xe2.level.getLevelData();
        xe2.connection.send(new ClientboundRespawnPacket(xe2.dimension, LevelData.obfuscateSeed(crm10.getSeed()), crm10.getGeneratorType(), xe2.gameMode.getGameModeForPlayer()));
        final BlockPos fk6 = xd9.getSharedSpawnPos();
        xe2.connection.teleport(xe2.getX(), xe2.getY(), xe2.getZ(), xe2.yRot, xe2.xRot);
        xe2.connection.send(new ClientboundSetSpawnPositionPacket(fk6));
        xe2.connection.send(new ClientboundChangeDifficultyPacket(crm10.getDifficulty(), crm10.isDifficultyLocked()));
        xe2.connection.send(new ClientboundSetExperiencePacket(xe2.experienceProgress, xe2.totalExperience, xe2.experienceLevel));
        this.sendLevelInfo(xe2, xd9);
        this.sendPlayerPermissionLevel(xe2);
        xd9.addRespawnedPlayer(xe2);
        this.players.add(xe2);
        this.playersByUUID.put(xe2.getUUID(), xe2);
        xe2.initMenu();
        xe2.setHealth(xe2.getHealth());
        return xe2;
    }
    
    public void sendPlayerPermissionLevel(final ServerPlayer xe) {
        final GameProfile gameProfile3 = xe.getGameProfile();
        final int integer4 = this.server.getProfilePermissions(gameProfile3);
        this.sendPlayerPermissionLevel(xe, integer4);
    }
    
    public void tick() {
        if (++this.sendAllPlayerInfoIn > 600) {
            this.broadcastAll(new ClientboundPlayerInfoPacket(ClientboundPlayerInfoPacket.Action.UPDATE_LATENCY, this.players));
            this.sendAllPlayerInfoIn = 0;
        }
    }
    
    public void broadcastAll(final Packet<?> lt) {
        for (int integer3 = 0; integer3 < this.players.size(); ++integer3) {
            this.players.get(integer3).connection.send(lt);
        }
    }
    
    public void broadcastAll(final Packet<?> lt, final DimensionType cbi) {
        for (int integer4 = 0; integer4 < this.players.size(); ++integer4) {
            final ServerPlayer xe5 = this.players.get(integer4);
            if (xe5.dimension == cbi) {
                xe5.connection.send(lt);
            }
        }
    }
    
    public void broadcastToTeam(final Player ayj, final Component lf) {
        final Team cwn4 = ayj.getTeam();
        if (cwn4 == null) {
            return;
        }
        final Collection<String> collection5 = cwn4.getPlayers();
        for (final String string7 : collection5) {
            final ServerPlayer xe8 = this.getPlayerByName(string7);
            if (xe8 != null) {
                if (xe8 == ayj) {
                    continue;
                }
                xe8.sendMessage(lf);
            }
        }
    }
    
    public void broadcastToAllExceptTeam(final Player ayj, final Component lf) {
        final Team cwn4 = ayj.getTeam();
        if (cwn4 == null) {
            this.broadcastMessage(lf);
            return;
        }
        for (int integer5 = 0; integer5 < this.players.size(); ++integer5) {
            final ServerPlayer xe6 = this.players.get(integer5);
            if (xe6.getTeam() != cwn4) {
                xe6.sendMessage(lf);
            }
        }
    }
    
    public String[] getPlayerNamesArray() {
        final String[] arr2 = new String[this.players.size()];
        for (int integer3 = 0; integer3 < this.players.size(); ++integer3) {
            arr2[integer3] = this.players.get(integer3).getGameProfile().getName();
        }
        return arr2;
    }
    
    public UserBanList getBans() {
        return this.bans;
    }
    
    public IpBanList getIpBans() {
        return this.ipBans;
    }
    
    public void op(final GameProfile gameProfile) {
        ((StoredUserList<K, ServerOpListEntry>)this.ops).add(new ServerOpListEntry(gameProfile, this.server.getOperatorUserPermissionLevel(), this.ops.canBypassPlayerLimit(gameProfile)));
        final ServerPlayer xe3 = this.getPlayer(gameProfile.getId());
        if (xe3 != null) {
            this.sendPlayerPermissionLevel(xe3);
        }
    }
    
    public void deop(final GameProfile gameProfile) {
        ((StoredUserList<GameProfile, V>)this.ops).remove(gameProfile);
        final ServerPlayer xe3 = this.getPlayer(gameProfile.getId());
        if (xe3 != null) {
            this.sendPlayerPermissionLevel(xe3);
        }
    }
    
    private void sendPlayerPermissionLevel(final ServerPlayer xe, final int integer) {
        if (xe.connection != null) {
            byte byte4;
            if (integer <= 0) {
                byte4 = 24;
            }
            else if (integer >= 4) {
                byte4 = 28;
            }
            else {
                byte4 = (byte)(24 + integer);
            }
            xe.connection.send(new ClientboundEntityEventPacket(xe, byte4));
        }
        this.server.getCommands().sendCommands(xe);
    }
    
    public boolean isWhiteListed(final GameProfile gameProfile) {
        return !this.doWhiteList || ((StoredUserList<GameProfile, V>)this.ops).contains(gameProfile) || ((StoredUserList<GameProfile, V>)this.whitelist).contains(gameProfile);
    }
    
    public boolean isOp(final GameProfile gameProfile) {
        return ((StoredUserList<GameProfile, V>)this.ops).contains(gameProfile) || (this.server.isSingleplayerOwner(gameProfile) && this.server.getLevel(DimensionType.OVERWORLD).getLevelData().getAllowCommands()) || this.allowCheatsForAllPlayers;
    }
    
    @Nullable
    public ServerPlayer getPlayerByName(final String string) {
        for (final ServerPlayer xe4 : this.players) {
            if (xe4.getGameProfile().getName().equalsIgnoreCase(string)) {
                return xe4;
            }
        }
        return null;
    }
    
    public void broadcast(@Nullable final Player ayj, final double double2, final double double3, final double double4, final double double5, final DimensionType cbi, final Packet<?> lt) {
        for (int integer13 = 0; integer13 < this.players.size(); ++integer13) {
            final ServerPlayer xe14 = this.players.get(integer13);
            if (xe14 != ayj) {
                if (xe14.dimension == cbi) {
                    final double double6 = double2 - xe14.getX();
                    final double double7 = double3 - xe14.getY();
                    final double double8 = double4 - xe14.getZ();
                    if (double6 * double6 + double7 * double7 + double8 * double8 < double5 * double5) {
                        xe14.connection.send(lt);
                    }
                }
            }
        }
    }
    
    public void saveAll() {
        for (int integer2 = 0; integer2 < this.players.size(); ++integer2) {
            this.save(this.players.get(integer2));
        }
    }
    
    public UserWhiteList getWhiteList() {
        return this.whitelist;
    }
    
    public String[] getWhiteListNames() {
        return this.whitelist.getUserList();
    }
    
    public ServerOpList getOps() {
        return this.ops;
    }
    
    public String[] getOpNames() {
        return this.ops.getUserList();
    }
    
    public void reloadWhiteList() {
    }
    
    public void sendLevelInfo(final ServerPlayer xe, final ServerLevel xd) {
        final WorldBorder bzw4 = this.server.getLevel(DimensionType.OVERWORLD).getWorldBorder();
        xe.connection.send(new ClientboundSetBorderPacket(bzw4, ClientboundSetBorderPacket.Type.INITIALIZE));
        xe.connection.send(new ClientboundSetTimePacket(xd.getGameTime(), xd.getDayTime(), xd.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)));
        final BlockPos fk5 = xd.getSharedSpawnPos();
        xe.connection.send(new ClientboundSetSpawnPositionPacket(fk5));
        if (xd.isRaining()) {
            xe.connection.send(new ClientboundGameEventPacket(1, 0.0f));
            xe.connection.send(new ClientboundGameEventPacket(7, xd.getRainLevel(1.0f)));
            xe.connection.send(new ClientboundGameEventPacket(8, xd.getThunderLevel(1.0f)));
        }
    }
    
    public void sendAllPlayerInfo(final ServerPlayer xe) {
        xe.refreshContainer(xe.inventoryMenu);
        xe.resetSentInfo();
        xe.connection.send(new ClientboundSetCarriedItemPacket(xe.inventory.selected));
    }
    
    public int getPlayerCount() {
        return this.players.size();
    }
    
    public int getMaxPlayers() {
        return this.maxPlayers;
    }
    
    public boolean isUsingWhitelist() {
        return this.doWhiteList;
    }
    
    public void setUsingWhiteList(final boolean boolean1) {
        this.doWhiteList = boolean1;
    }
    
    public List<ServerPlayer> getPlayersWithAddress(final String string) {
        final List<ServerPlayer> list3 = Lists.newArrayList();
        for (final ServerPlayer xe5 : this.players) {
            if (xe5.getIpAddress().equals(string)) {
                list3.add(xe5);
            }
        }
        return list3;
    }
    
    public int getViewDistance() {
        return this.viewDistance;
    }
    
    public MinecraftServer getServer() {
        return this.server;
    }
    
    public CompoundTag getSingleplayerData() {
        return null;
    }
    
    public void setOverrideGameMode(final GameType bjt) {
        this.overrideGameMode = bjt;
    }
    
    private void updatePlayerGameMode(final ServerPlayer xe1, final ServerPlayer xe2, final LevelAccessor bjx) {
        if (xe2 != null) {
            xe1.gameMode.setGameModeForPlayer(xe2.gameMode.getGameModeForPlayer());
        }
        else if (this.overrideGameMode != null) {
            xe1.gameMode.setGameModeForPlayer(this.overrideGameMode);
        }
        xe1.gameMode.updateGameMode(bjx.getLevelData().getGameType());
    }
    
    public void setAllowCheatsForAllPlayers(final boolean boolean1) {
        this.allowCheatsForAllPlayers = boolean1;
    }
    
    public void removeAll() {
        for (int integer2 = 0; integer2 < this.players.size(); ++integer2) {
            this.players.get(integer2).connection.disconnect(new TranslatableComponent("multiplayer.disconnect.server_shutdown", new Object[0]));
        }
    }
    
    public void broadcastMessage(final Component lf, final boolean boolean2) {
        this.server.sendMessage(lf);
        final ChatType ld4 = boolean2 ? ChatType.SYSTEM : ChatType.CHAT;
        this.broadcastAll(new ClientboundChatPacket(lf, ld4));
    }
    
    public void broadcastMessage(final Component lf) {
        this.broadcastMessage(lf, true);
    }
    
    public ServerStatsCounter getPlayerStats(final Player ayj) {
        final UUID uUID3 = ayj.getUUID();
        ServerStatsCounter aan4 = (uUID3 == null) ? null : this.stats.get(uUID3);
        if (aan4 == null) {
            final File file5 = new File(this.server.getLevel(DimensionType.OVERWORLD).getLevelStorage().getFolder(), "stats");
            final File file6 = new File(file5, uUID3 + ".json");
            if (!file6.exists()) {
                final File file7 = new File(file5, ayj.getName().getString() + ".json");
                if (file7.exists() && file7.isFile()) {
                    file7.renameTo(file6);
                }
            }
            aan4 = new ServerStatsCounter(this.server, file6);
            this.stats.put(uUID3, aan4);
        }
        return aan4;
    }
    
    public PlayerAdvancements getPlayerAdvancements(final ServerPlayer xe) {
        final UUID uUID3 = xe.getUUID();
        PlayerAdvancements sv4 = this.advancements.get(uUID3);
        if (sv4 == null) {
            final File file5 = new File(this.server.getLevel(DimensionType.OVERWORLD).getLevelStorage().getFolder(), "advancements");
            final File file6 = new File(file5, uUID3 + ".json");
            sv4 = new PlayerAdvancements(this.server, file6, xe);
            this.advancements.put(uUID3, sv4);
        }
        sv4.setPlayer(xe);
        return sv4;
    }
    
    public void setViewDistance(final int integer) {
        this.viewDistance = integer;
        this.broadcastAll(new ClientboundSetChunkCacheRadiusPacket(integer));
        for (final ServerLevel xd4 : this.server.getAllLevels()) {
            if (xd4 != null) {
                xd4.getChunkSource().setViewDistance(integer);
            }
        }
    }
    
    public List<ServerPlayer> getPlayers() {
        return this.players;
    }
    
    @Nullable
    public ServerPlayer getPlayer(final UUID uUID) {
        return this.playersByUUID.get(uUID);
    }
    
    public boolean canBypassPlayerLimit(final GameProfile gameProfile) {
        return false;
    }
    
    public void reloadResources() {
        for (final PlayerAdvancements sv3 : this.advancements.values()) {
            sv3.reload();
        }
        this.broadcastAll(new ClientboundUpdateTagsPacket(this.server.getTags()));
        final ClientboundUpdateRecipesPacket ph2 = new ClientboundUpdateRecipesPacket(this.server.getRecipeManager().getRecipes());
        for (final ServerPlayer xe4 : this.players) {
            xe4.connection.send(ph2);
            xe4.getRecipeBook().sendInitialRecipeBook(xe4);
        }
    }
    
    public boolean isAllowCheatsForAllPlayers() {
        return this.allowCheatsForAllPlayers;
    }
    
    static {
        USERBANLIST_FILE = new File("banned-players.json");
        IPBANLIST_FILE = new File("banned-ips.json");
        OPLIST_FILE = new File("ops.json");
        WHITELIST_FILE = new File("whitelist.json");
        LOGGER = LogManager.getLogger();
        BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");
    }
}
