Code/net/minecraft/server/players/PlayerList.java

862 lines
37 KiB
Java
Raw Normal View History

2025-07-01 06:20:03 +00:00
package net.minecraft.server.players;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.mojang.authlib.GameProfile;
import com.mojang.logging.LogUtils;
import com.mojang.serialization.Dynamic;
import java.io.File;
import java.net.SocketAddress;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.function.Function;
import java.util.function.Predicate;
import javax.annotation.Nullable;
import net.minecraft.ChatFormatting;
import net.minecraft.FileUtil;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.core.BlockPos;
import net.minecraft.core.LayeredRegistryAccess;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.NbtOps;
import net.minecraft.network.Connection;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.chat.ChatType;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.network.chat.OutgoingChatMessage;
import net.minecraft.network.chat.PlayerChatMessage;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.common.ClientboundUpdateTagsPacket;
import net.minecraft.network.protocol.game.ClientboundChangeDifficultyPacket;
import net.minecraft.network.protocol.game.ClientboundEntityEventPacket;
import net.minecraft.network.protocol.game.ClientboundGameEventPacket;
import net.minecraft.network.protocol.game.ClientboundInitializeBorderPacket;
import net.minecraft.network.protocol.game.ClientboundLoginPacket;
import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoRemovePacket;
import net.minecraft.network.protocol.game.ClientboundPlayerInfoUpdatePacket;
import net.minecraft.network.protocol.game.ClientboundRespawnPacket;
import net.minecraft.network.protocol.game.ClientboundSetBorderCenterPacket;
import net.minecraft.network.protocol.game.ClientboundSetBorderLerpSizePacket;
import net.minecraft.network.protocol.game.ClientboundSetBorderSizePacket;
import net.minecraft.network.protocol.game.ClientboundSetBorderWarningDelayPacket;
import net.minecraft.network.protocol.game.ClientboundSetBorderWarningDistancePacket;
import net.minecraft.network.protocol.game.ClientboundSetChunkCacheRadiusPacket;
import net.minecraft.network.protocol.game.ClientboundSetDefaultSpawnPositionPacket;
import net.minecraft.network.protocol.game.ClientboundSetExperiencePacket;
import net.minecraft.network.protocol.game.ClientboundSetHeldSlotPacket;
import net.minecraft.network.protocol.game.ClientboundSetPlayerTeamPacket;
import net.minecraft.network.protocol.game.ClientboundSetSimulationDistancePacket;
import net.minecraft.network.protocol.game.ClientboundSetTimePacket;
import net.minecraft.network.protocol.game.ClientboundSoundPacket;
import net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket;
import net.minecraft.network.protocol.game.ClientboundUpdateRecipesPacket;
import net.minecraft.network.protocol.game.GameProtocols;
import net.minecraft.network.protocol.status.ServerStatus;
import net.minecraft.resources.ResourceKey;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.PlayerAdvancements;
import net.minecraft.server.RegistryLayer;
import net.minecraft.server.ServerScoreboard;
import net.minecraft.server.level.ClientInformation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.CommonListenerCookie;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.stats.ServerStatsCounter;
import net.minecraft.stats.Stats;
import net.minecraft.tags.TagNetworkSerialization;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.ThrownEnderpearl;
import net.minecraft.world.item.crafting.RecipeManager;
import net.minecraft.world.level.GameRules;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.Blocks;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.border.BorderChangeListener;
import net.minecraft.world.level.border.WorldBorder;
import net.minecraft.world.level.dimension.DimensionType;
import net.minecraft.world.level.portal.TeleportTransition;
import net.minecraft.world.level.storage.LevelData;
import net.minecraft.world.level.storage.LevelResource;
import net.minecraft.world.level.storage.PlayerDataStorage;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.scores.DisplaySlot;
import net.minecraft.world.scores.Objective;
import net.minecraft.world.scores.PlayerTeam;
import net.minecraft.world.scores.Team;
import org.slf4j.Logger;
public abstract class PlayerList {
public static final File USERBANLIST_FILE = new File("banned-players.json");
public static final File IPBANLIST_FILE = new File("banned-ips.json");
public static final File OPLIST_FILE = new File("ops.json");
public static final File WHITELIST_FILE = new File("whitelist.json");
public static final Component CHAT_FILTERED_FULL = Component.translatable("chat.filtered_full");
public static final Component DUPLICATE_LOGIN_DISCONNECT_MESSAGE = Component.translatable("multiplayer.disconnect.duplicate_login");
private static final Logger LOGGER = LogUtils.getLogger();
private static final int SEND_PLAYER_INFO_INTERVAL = 600;
private static final SimpleDateFormat BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");
private final MinecraftServer server;
private final List<ServerPlayer> players = Lists.newArrayList();
private final Map<UUID, ServerPlayer> playersByUUID = Maps.newHashMap();
private final UserBanList bans = new UserBanList(USERBANLIST_FILE);
private final IpBanList ipBans = new IpBanList(IPBANLIST_FILE);
private final ServerOpList ops = new ServerOpList(OPLIST_FILE);
private final UserWhiteList whitelist = new UserWhiteList(WHITELIST_FILE);
private final Map<UUID, ServerStatsCounter> stats = Maps.newHashMap();
private final Map<UUID, PlayerAdvancements> advancements = Maps.newHashMap();
private final PlayerDataStorage playerIo;
private boolean doWhiteList;
private final LayeredRegistryAccess<RegistryLayer> registries;
protected final int maxPlayers;
private int viewDistance;
private int simulationDistance;
private boolean allowCommandsForAllPlayers;
private static final boolean ALLOW_LOGOUTIVATOR = false;
private int sendAllPlayerInfoIn;
public PlayerList(MinecraftServer p_203842_, LayeredRegistryAccess<RegistryLayer> p_251844_, PlayerDataStorage p_203844_, int p_203845_) {
this.server = p_203842_;
this.registries = p_251844_;
this.maxPlayers = p_203845_;
this.playerIo = p_203844_;
}
public void placeNewPlayer(Connection p_11262_, ServerPlayer p_11263_, CommonListenerCookie p_297215_) {
GameProfile gameprofile = p_11263_.getGameProfile();
GameProfileCache gameprofilecache = this.server.getProfileCache();
String s;
if (gameprofilecache != null) {
Optional<GameProfile> optional = gameprofilecache.get(gameprofile.getId());
s = optional.map(GameProfile::getName).orElse(gameprofile.getName());
gameprofilecache.add(gameprofile);
} else {
s = gameprofile.getName();
}
Optional<CompoundTag> optional1 = this.load(p_11263_);
ResourceKey<Level> resourcekey = optional1.<ResourceKey<Level>>flatMap(
p_326481_ -> DimensionType.parseLegacy(new Dynamic<>(NbtOps.INSTANCE, p_326481_.get("Dimension"))).resultOrPartial(LOGGER::error)
)
.orElse(Level.OVERWORLD);
ServerLevel serverlevel = this.server.getLevel(resourcekey);
ServerLevel serverlevel1;
if (serverlevel == null) {
LOGGER.warn("Unknown respawn dimension {}, defaulting to overworld", resourcekey);
serverlevel1 = this.server.overworld();
} else {
serverlevel1 = serverlevel;
}
p_11263_.setServerLevel(serverlevel1);
String s1 = p_11262_.getLoggableAddress(this.server.logIPs());
LOGGER.info(
"{}[{}] logged in with entity id {} at ({}, {}, {})",
p_11263_.getName().getString(),
s1,
p_11263_.getId(),
p_11263_.getX(),
p_11263_.getY(),
p_11263_.getZ()
);
LevelData leveldata = serverlevel1.getLevelData();
p_11263_.loadGameTypes(optional1.orElse(null));
ServerGamePacketListenerImpl servergamepacketlistenerimpl = new ServerGamePacketListenerImpl(this.server, p_11262_, p_11263_, p_297215_);
p_11262_.setupInboundProtocol(
GameProtocols.SERVERBOUND_TEMPLATE.bind(RegistryFriendlyByteBuf.decorator(this.server.registryAccess()), servergamepacketlistenerimpl),
servergamepacketlistenerimpl
);
GameRules gamerules = serverlevel1.getGameRules();
boolean flag = gamerules.getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN);
boolean flag1 = gamerules.getBoolean(GameRules.RULE_REDUCEDDEBUGINFO);
boolean flag2 = gamerules.getBoolean(GameRules.RULE_LIMITED_CRAFTING);
servergamepacketlistenerimpl.send(
new ClientboundLoginPacket(
p_11263_.getId(),
leveldata.isHardcore(),
this.server.levelKeys(),
this.getMaxPlayers(),
this.viewDistance,
this.simulationDistance,
flag1,
!flag,
flag2,
p_11263_.createCommonSpawnInfo(serverlevel1),
this.server.enforceSecureProfile()
)
);
servergamepacketlistenerimpl.send(new ClientboundChangeDifficultyPacket(leveldata.getDifficulty(), leveldata.isDifficultyLocked()));
servergamepacketlistenerimpl.send(new ClientboundPlayerAbilitiesPacket(p_11263_.getAbilities()));
servergamepacketlistenerimpl.send(new ClientboundSetHeldSlotPacket(p_11263_.getInventory().getSelectedSlot()));
RecipeManager recipemanager = this.server.getRecipeManager();
servergamepacketlistenerimpl.send(new ClientboundUpdateRecipesPacket(recipemanager.getSynchronizedItemProperties(), recipemanager.getSynchronizedStonecutterRecipes()));
this.sendPlayerPermissionLevel(p_11263_);
p_11263_.getStats().markAllDirty();
p_11263_.getRecipeBook().sendInitialRecipeBook(p_11263_);
this.updateEntireScoreboard(serverlevel1.getScoreboard(), p_11263_);
this.server.invalidateStatus();
MutableComponent mutablecomponent;
if (p_11263_.getGameProfile().getName().equalsIgnoreCase(s)) {
mutablecomponent = Component.translatable("multiplayer.player.joined", p_11263_.getDisplayName());
} else {
mutablecomponent = Component.translatable("multiplayer.player.joined.renamed", p_11263_.getDisplayName(), s);
}
this.broadcastSystemMessage(mutablecomponent.withStyle(ChatFormatting.YELLOW), false);
servergamepacketlistenerimpl.teleport(p_11263_.getX(), p_11263_.getY(), p_11263_.getZ(), p_11263_.getYRot(), p_11263_.getXRot());
ServerStatus serverstatus = this.server.getStatus();
if (serverstatus != null && !p_297215_.transferred()) {
p_11263_.sendServerStatus(serverstatus);
}
p_11263_.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players));
this.players.add(p_11263_);
this.playersByUUID.put(p_11263_.getUUID(), p_11263_);
this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(p_11263_)));
this.sendLevelInfo(p_11263_, serverlevel1);
serverlevel1.addNewPlayer(p_11263_);
this.server.getCustomBossEvents().onPlayerConnect(p_11263_);
this.sendActivePlayerEffects(p_11263_);
optional1.ifPresent(p_390188_ -> {
p_11263_.loadAndSpawnEnderPearls(p_390188_);
p_11263_.loadAndSpawnParentVehicle(p_390188_);
});
p_11263_.initInventoryMenu();
}
protected void updateEntireScoreboard(ServerScoreboard p_11274_, ServerPlayer p_11275_) {
Set<Objective> set = Sets.newHashSet();
for (PlayerTeam playerteam : p_11274_.getPlayerTeams()) {
p_11275_.connection.send(ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(playerteam, true));
}
for (DisplaySlot displayslot : DisplaySlot.values()) {
Objective objective = p_11274_.getDisplayObjective(displayslot);
if (objective != null && !set.contains(objective)) {
for (Packet<?> packet : p_11274_.getStartTrackingPackets(objective)) {
p_11275_.connection.send(packet);
}
set.add(objective);
}
}
}
public void addWorldborderListener(ServerLevel p_184210_) {
p_184210_.getWorldBorder().addListener(new BorderChangeListener() {
@Override
public void onBorderSizeSet(WorldBorder p_11321_, double p_11322_) {
PlayerList.this.broadcastAll(new ClientboundSetBorderSizePacket(p_11321_));
}
@Override
public void onBorderSizeLerping(WorldBorder p_11328_, double p_11329_, double p_11330_, long p_11331_) {
PlayerList.this.broadcastAll(new ClientboundSetBorderLerpSizePacket(p_11328_));
}
@Override
public void onBorderCenterSet(WorldBorder p_11324_, double p_11325_, double p_11326_) {
PlayerList.this.broadcastAll(new ClientboundSetBorderCenterPacket(p_11324_));
}
@Override
public void onBorderSetWarningTime(WorldBorder p_11333_, int p_11334_) {
PlayerList.this.broadcastAll(new ClientboundSetBorderWarningDelayPacket(p_11333_));
}
@Override
public void onBorderSetWarningBlocks(WorldBorder p_11339_, int p_11340_) {
PlayerList.this.broadcastAll(new ClientboundSetBorderWarningDistancePacket(p_11339_));
}
@Override
public void onBorderSetDamagePerBlock(WorldBorder p_11336_, double p_11337_) {
}
@Override
public void onBorderSetDamageSafeZOne(WorldBorder p_11342_, double p_11343_) {
}
});
}
public Optional<CompoundTag> load(ServerPlayer p_11225_) {
CompoundTag compoundtag = this.server.getWorldData().getLoadedPlayerTag();
Optional<CompoundTag> optional;
if (this.server.isSingleplayerOwner(p_11225_.getGameProfile()) && compoundtag != null) {
optional = Optional.of(compoundtag);
p_11225_.load(compoundtag);
LOGGER.debug("loading single player");
} else {
optional = this.playerIo.load(p_11225_);
}
return optional;
}
protected void save(ServerPlayer p_11277_) {
this.playerIo.save(p_11277_);
ServerStatsCounter serverstatscounter = this.stats.get(p_11277_.getUUID());
if (serverstatscounter != null) {
serverstatscounter.save();
}
PlayerAdvancements playeradvancements = this.advancements.get(p_11277_.getUUID());
if (playeradvancements != null) {
playeradvancements.save();
}
}
public void remove(ServerPlayer p_11287_) {
ServerLevel serverlevel = p_11287_.serverLevel();
p_11287_.awardStat(Stats.LEAVE_GAME);
this.save(p_11287_);
if (p_11287_.isPassenger()) {
Entity entity = p_11287_.getRootVehicle();
if (entity.hasExactlyOnePlayerPassenger()) {
LOGGER.debug("Removing player mount");
p_11287_.stopRiding();
entity.getPassengersAndSelf().forEach(p_215620_ -> p_215620_.setRemoved(Entity.RemovalReason.UNLOADED_WITH_PLAYER));
}
}
p_11287_.unRide();
for (ThrownEnderpearl thrownenderpearl : p_11287_.getEnderPearls()) {
thrownenderpearl.setRemoved(Entity.RemovalReason.UNLOADED_WITH_PLAYER);
}
serverlevel.removePlayerImmediately(p_11287_, Entity.RemovalReason.UNLOADED_WITH_PLAYER);
p_11287_.getAdvancements().stopListening();
this.players.remove(p_11287_);
this.server.getCustomBossEvents().onPlayerDisconnect(p_11287_);
UUID uuid = p_11287_.getUUID();
ServerPlayer serverplayer = this.playersByUUID.get(uuid);
if (serverplayer == p_11287_) {
this.playersByUUID.remove(uuid);
this.stats.remove(uuid);
this.advancements.remove(uuid);
}
this.broadcastAll(new ClientboundPlayerInfoRemovePacket(List.of(p_11287_.getUUID())));
}
@Nullable
public Component canPlayerLogin(SocketAddress p_11257_, GameProfile p_11258_) {
if (this.bans.isBanned(p_11258_)) {
UserBanListEntry userbanlistentry = this.bans.get(p_11258_);
MutableComponent mutablecomponent1 = Component.translatable("multiplayer.disconnect.banned.reason", userbanlistentry.getReason());
if (userbanlistentry.getExpires() != null) {
mutablecomponent1.append(Component.translatable("multiplayer.disconnect.banned.expiration", BAN_DATE_FORMAT.format(userbanlistentry.getExpires())));
}
return mutablecomponent1;
} else if (!this.isWhiteListed(p_11258_)) {
return Component.translatable("multiplayer.disconnect.not_whitelisted");
} else if (this.ipBans.isBanned(p_11257_)) {
IpBanListEntry ipbanlistentry = this.ipBans.get(p_11257_);
MutableComponent mutablecomponent = Component.translatable("multiplayer.disconnect.banned_ip.reason", ipbanlistentry.getReason());
if (ipbanlistentry.getExpires() != null) {
mutablecomponent.append(Component.translatable("multiplayer.disconnect.banned_ip.expiration", BAN_DATE_FORMAT.format(ipbanlistentry.getExpires())));
}
return mutablecomponent;
} else {
return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(p_11258_) ? Component.translatable("multiplayer.disconnect.server_full") : null;
}
}
public ServerPlayer getPlayerForLogin(GameProfile p_215625_, ClientInformation p_300548_) {
return new ServerPlayer(this.server, this.server.overworld(), p_215625_, p_300548_);
}
public boolean disconnectAllPlayersWithProfile(GameProfile p_299278_) {
UUID uuid = p_299278_.getId();
Set<ServerPlayer> set = Sets.newIdentityHashSet();
for (ServerPlayer serverplayer : this.players) {
if (serverplayer.getUUID().equals(uuid)) {
set.add(serverplayer);
}
}
ServerPlayer serverplayer2 = this.playersByUUID.get(p_299278_.getId());
if (serverplayer2 != null) {
set.add(serverplayer2);
}
for (ServerPlayer serverplayer1 : set) {
serverplayer1.connection.disconnect(DUPLICATE_LOGIN_DISCONNECT_MESSAGE);
}
return !set.isEmpty();
}
public ServerPlayer respawn(ServerPlayer p_11237_, boolean p_11238_, Entity.RemovalReason p_344452_) {
this.players.remove(p_11237_);
p_11237_.serverLevel().removePlayerImmediately(p_11237_, p_344452_);
TeleportTransition teleporttransition = p_11237_.findRespawnPositionAndUseSpawnBlock(!p_11238_, TeleportTransition.DO_NOTHING);
ServerLevel serverlevel = teleporttransition.newLevel();
ServerPlayer serverplayer = new ServerPlayer(this.server, serverlevel, p_11237_.getGameProfile(), p_11237_.clientInformation());
serverplayer.connection = p_11237_.connection;
serverplayer.restoreFrom(p_11237_, p_11238_);
serverplayer.setId(p_11237_.getId());
serverplayer.setMainArm(p_11237_.getMainArm());
if (!teleporttransition.missingRespawnBlock()) {
serverplayer.copyRespawnPosition(p_11237_);
}
for (String s : p_11237_.getTags()) {
serverplayer.addTag(s);
}
Vec3 vec3 = teleporttransition.position();
serverplayer.snapTo(vec3.x, vec3.y, vec3.z, teleporttransition.yRot(), teleporttransition.xRot());
if (teleporttransition.missingRespawnBlock()) {
serverplayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0F));
}
byte b0 = (byte)(p_11238_ ? 1 : 0);
ServerLevel serverlevel1 = serverplayer.serverLevel();
LevelData leveldata = serverlevel1.getLevelData();
serverplayer.connection.send(new ClientboundRespawnPacket(serverplayer.createCommonSpawnInfo(serverlevel1), b0));
serverplayer.connection
.teleport(serverplayer.getX(), serverplayer.getY(), serverplayer.getZ(), serverplayer.getYRot(), serverplayer.getXRot());
serverplayer.connection.send(new ClientboundSetDefaultSpawnPositionPacket(serverlevel.getSharedSpawnPos(), serverlevel.getSharedSpawnAngle()));
serverplayer.connection.send(new ClientboundChangeDifficultyPacket(leveldata.getDifficulty(), leveldata.isDifficultyLocked()));
serverplayer.connection.send(new ClientboundSetExperiencePacket(serverplayer.experienceProgress, serverplayer.totalExperience, serverplayer.experienceLevel));
this.sendActivePlayerEffects(serverplayer);
this.sendLevelInfo(serverplayer, serverlevel);
this.sendPlayerPermissionLevel(serverplayer);
serverlevel.addRespawnedPlayer(serverplayer);
this.players.add(serverplayer);
this.playersByUUID.put(serverplayer.getUUID(), serverplayer);
serverplayer.initInventoryMenu();
serverplayer.setHealth(serverplayer.getHealth());
ServerPlayer.RespawnConfig serverplayer$respawnconfig = serverplayer.getRespawnConfig();
if (!p_11238_ && serverplayer$respawnconfig != null) {
ServerLevel serverlevel2 = this.server.getLevel(serverplayer$respawnconfig.dimension());
if (serverlevel2 != null) {
BlockPos blockpos = serverplayer$respawnconfig.pos();
BlockState blockstate = serverlevel2.getBlockState(blockpos);
if (blockstate.is(Blocks.RESPAWN_ANCHOR)) {
serverplayer.connection
.send(
new ClientboundSoundPacket(
SoundEvents.RESPAWN_ANCHOR_DEPLETE,
SoundSource.BLOCKS,
blockpos.getX(),
blockpos.getY(),
blockpos.getZ(),
1.0F,
1.0F,
serverlevel.getRandom().nextLong()
)
);
}
}
}
return serverplayer;
}
public void sendActivePlayerEffects(ServerPlayer p_344496_) {
this.sendActiveEffects(p_344496_, p_344496_.connection);
}
public void sendActiveEffects(LivingEntity p_344934_, ServerGamePacketListenerImpl p_343169_) {
for (MobEffectInstance mobeffectinstance : p_344934_.getActiveEffects()) {
p_343169_.send(new ClientboundUpdateMobEffectPacket(p_344934_.getId(), mobeffectinstance, false));
}
}
public void sendPlayerPermissionLevel(ServerPlayer p_11290_) {
GameProfile gameprofile = p_11290_.getGameProfile();
int i = this.server.getProfilePermissions(gameprofile);
this.sendPlayerPermissionLevel(p_11290_, i);
}
public void tick() {
if (++this.sendAllPlayerInfoIn > 600) {
this.broadcastAll(new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_LATENCY), this.players));
this.sendAllPlayerInfoIn = 0;
}
}
public void broadcastAll(Packet<?> p_11269_) {
for (ServerPlayer serverplayer : this.players) {
serverplayer.connection.send(p_11269_);
}
}
public void broadcastAll(Packet<?> p_11271_, ResourceKey<Level> p_11272_) {
for (ServerPlayer serverplayer : this.players) {
if (serverplayer.level().dimension() == p_11272_) {
serverplayer.connection.send(p_11271_);
}
}
}
public void broadcastSystemToTeam(Player p_215622_, Component p_215623_) {
Team team = p_215622_.getTeam();
if (team != null) {
for (String s : team.getPlayers()) {
ServerPlayer serverplayer = this.getPlayerByName(s);
if (serverplayer != null && serverplayer != p_215622_) {
serverplayer.sendSystemMessage(p_215623_);
}
}
}
}
public void broadcastSystemToAllExceptTeam(Player p_215650_, Component p_215651_) {
Team team = p_215650_.getTeam();
if (team == null) {
this.broadcastSystemMessage(p_215651_, false);
} else {
for (int i = 0; i < this.players.size(); i++) {
ServerPlayer serverplayer = this.players.get(i);
if (serverplayer.getTeam() != team) {
serverplayer.sendSystemMessage(p_215651_);
}
}
}
}
public String[] getPlayerNamesArray() {
String[] astring = new String[this.players.size()];
for (int i = 0; i < this.players.size(); i++) {
astring[i] = this.players.get(i).getGameProfile().getName();
}
return astring;
}
public UserBanList getBans() {
return this.bans;
}
public IpBanList getIpBans() {
return this.ipBans;
}
public void op(GameProfile p_11254_) {
this.ops.add(new ServerOpListEntry(p_11254_, this.server.getOperatorUserPermissionLevel(), this.ops.canBypassPlayerLimit(p_11254_)));
ServerPlayer serverplayer = this.getPlayer(p_11254_.getId());
if (serverplayer != null) {
this.sendPlayerPermissionLevel(serverplayer);
}
}
public void deop(GameProfile p_11281_) {
this.ops.remove(p_11281_);
ServerPlayer serverplayer = this.getPlayer(p_11281_.getId());
if (serverplayer != null) {
this.sendPlayerPermissionLevel(serverplayer);
}
}
private void sendPlayerPermissionLevel(ServerPlayer p_11227_, int p_11228_) {
if (p_11227_.connection != null) {
byte b0;
if (p_11228_ <= 0) {
b0 = 24;
} else if (p_11228_ >= 4) {
b0 = 28;
} else {
b0 = (byte)(24 + p_11228_);
}
p_11227_.connection.send(new ClientboundEntityEventPacket(p_11227_, b0));
}
this.server.getCommands().sendCommands(p_11227_);
}
public boolean isWhiteListed(GameProfile p_11294_) {
return !this.doWhiteList || this.ops.contains(p_11294_) || this.whitelist.contains(p_11294_);
}
public boolean isOp(GameProfile p_11304_) {
return this.ops.contains(p_11304_) || this.server.isSingleplayerOwner(p_11304_) && this.server.getWorldData().isAllowCommands() || this.allowCommandsForAllPlayers;
}
@Nullable
public ServerPlayer getPlayerByName(String p_11256_) {
int i = this.players.size();
for (int j = 0; j < i; j++) {
ServerPlayer serverplayer = this.players.get(j);
if (serverplayer.getGameProfile().getName().equalsIgnoreCase(p_11256_)) {
return serverplayer;
}
}
return null;
}
public void broadcast(
@Nullable Player p_11242_, double p_11243_, double p_11244_, double p_11245_, double p_11246_, ResourceKey<Level> p_11247_, Packet<?> p_11248_
) {
for (int i = 0; i < this.players.size(); i++) {
ServerPlayer serverplayer = this.players.get(i);
if (serverplayer != p_11242_ && serverplayer.level().dimension() == p_11247_) {
double d0 = p_11243_ - serverplayer.getX();
double d1 = p_11244_ - serverplayer.getY();
double d2 = p_11245_ - serverplayer.getZ();
if (d0 * d0 + d1 * d1 + d2 * d2 < p_11246_ * p_11246_) {
serverplayer.connection.send(p_11248_);
}
}
}
}
public void saveAll() {
for (int i = 0; i < this.players.size(); i++) {
this.save(this.players.get(i));
}
}
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(ServerPlayer p_11230_, ServerLevel p_11231_) {
WorldBorder worldborder = this.server.overworld().getWorldBorder();
p_11230_.connection.send(new ClientboundInitializeBorderPacket(worldborder));
p_11230_.connection.send(new ClientboundSetTimePacket(p_11231_.getGameTime(), p_11231_.getDayTime(), p_11231_.getGameRules().getBoolean(GameRules.RULE_DAYLIGHT)));
p_11230_.connection.send(new ClientboundSetDefaultSpawnPositionPacket(p_11231_.getSharedSpawnPos(), p_11231_.getSharedSpawnAngle()));
if (p_11231_.isRaining()) {
p_11230_.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.START_RAINING, 0.0F));
p_11230_.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.RAIN_LEVEL_CHANGE, p_11231_.getRainLevel(1.0F)));
p_11230_.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.THUNDER_LEVEL_CHANGE, p_11231_.getThunderLevel(1.0F)));
}
p_11230_.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F));
this.server.tickRateManager().updateJoiningPlayer(p_11230_);
}
public void sendAllPlayerInfo(ServerPlayer p_11293_) {
p_11293_.inventoryMenu.sendAllDataToRemote();
p_11293_.resetSentInfo();
p_11293_.connection.send(new ClientboundSetHeldSlotPacket(p_11293_.getInventory().getSelectedSlot()));
}
public int getPlayerCount() {
return this.players.size();
}
public int getMaxPlayers() {
return this.maxPlayers;
}
public boolean isUsingWhitelist() {
return this.doWhiteList;
}
public void setUsingWhiteList(boolean p_11276_) {
this.doWhiteList = p_11276_;
}
public List<ServerPlayer> getPlayersWithAddress(String p_11283_) {
List<ServerPlayer> list = Lists.newArrayList();
for (ServerPlayer serverplayer : this.players) {
if (serverplayer.getIpAddress().equals(p_11283_)) {
list.add(serverplayer);
}
}
return list;
}
public int getViewDistance() {
return this.viewDistance;
}
public int getSimulationDistance() {
return this.simulationDistance;
}
public MinecraftServer getServer() {
return this.server;
}
@Nullable
public CompoundTag getSingleplayerData() {
return null;
}
public void setAllowCommandsForAllPlayers(boolean p_335066_) {
this.allowCommandsForAllPlayers = p_335066_;
}
public void removeAll() {
for (int i = 0; i < this.players.size(); i++) {
this.players.get(i).connection.disconnect(Component.translatable("multiplayer.disconnect.server_shutdown"));
}
}
public void broadcastSystemMessage(Component p_240618_, boolean p_240644_) {
this.broadcastSystemMessage(p_240618_, p_215639_ -> p_240618_, p_240644_);
}
public void broadcastSystemMessage(Component p_240526_, Function<ServerPlayer, Component> p_240594_, boolean p_240648_) {
this.server.sendSystemMessage(p_240526_);
for (ServerPlayer serverplayer : this.players) {
Component component = p_240594_.apply(serverplayer);
if (component != null) {
serverplayer.sendSystemMessage(component, p_240648_);
}
}
}
public void broadcastChatMessage(PlayerChatMessage p_243229_, CommandSourceStack p_243254_, ChatType.Bound p_243255_) {
this.broadcastChatMessage(p_243229_, p_243254_::shouldFilterMessageTo, p_243254_.getPlayer(), p_243255_);
}
public void broadcastChatMessage(PlayerChatMessage p_243264_, ServerPlayer p_243234_, ChatType.Bound p_243204_) {
this.broadcastChatMessage(p_243264_, p_243234_::shouldFilterMessageTo, p_243234_, p_243204_);
}
private void broadcastChatMessage(PlayerChatMessage p_249952_, Predicate<ServerPlayer> p_250784_, @Nullable ServerPlayer p_249623_, ChatType.Bound p_250276_) {
boolean flag = this.verifyChatTrusted(p_249952_);
this.server.logChatMessage(p_249952_.decoratedContent(), p_250276_, flag ? null : "Not Secure");
OutgoingChatMessage outgoingchatmessage = OutgoingChatMessage.create(p_249952_);
boolean flag1 = false;
for (ServerPlayer serverplayer : this.players) {
boolean flag2 = p_250784_.test(serverplayer);
serverplayer.sendChatMessage(outgoingchatmessage, flag2, p_250276_);
flag1 |= flag2 && p_249952_.isFullyFiltered();
}
if (flag1 && p_249623_ != null) {
p_249623_.sendSystemMessage(CHAT_FILTERED_FULL);
}
}
private boolean verifyChatTrusted(PlayerChatMessage p_251384_) {
return p_251384_.hasSignature() && !p_251384_.hasExpiredServer(Instant.now());
}
public ServerStatsCounter getPlayerStats(Player p_11240_) {
UUID uuid = p_11240_.getUUID();
ServerStatsCounter serverstatscounter = this.stats.get(uuid);
if (serverstatscounter == null) {
File file1 = this.server.getWorldPath(LevelResource.PLAYER_STATS_DIR).toFile();
File file2 = new File(file1, uuid + ".json");
if (!file2.exists()) {
File file3 = new File(file1, p_11240_.getName().getString() + ".json");
Path path = file3.toPath();
if (FileUtil.isPathNormalized(path) && FileUtil.isPathPortable(path) && path.startsWith(file1.getPath()) && file3.isFile()) {
file3.renameTo(file2);
}
}
serverstatscounter = new ServerStatsCounter(this.server, file2);
this.stats.put(uuid, serverstatscounter);
}
return serverstatscounter;
}
public PlayerAdvancements getPlayerAdvancements(ServerPlayer p_11297_) {
UUID uuid = p_11297_.getUUID();
PlayerAdvancements playeradvancements = this.advancements.get(uuid);
if (playeradvancements == null) {
Path path = this.server.getWorldPath(LevelResource.PLAYER_ADVANCEMENTS_DIR).resolve(uuid + ".json");
playeradvancements = new PlayerAdvancements(this.server.getFixerUpper(), this, this.server.getAdvancements(), path, p_11297_);
this.advancements.put(uuid, playeradvancements);
}
playeradvancements.setPlayer(p_11297_);
return playeradvancements;
}
public void setViewDistance(int p_11218_) {
this.viewDistance = p_11218_;
this.broadcastAll(new ClientboundSetChunkCacheRadiusPacket(p_11218_));
for (ServerLevel serverlevel : this.server.getAllLevels()) {
if (serverlevel != null) {
serverlevel.getChunkSource().setViewDistance(p_11218_);
}
}
}
public void setSimulationDistance(int p_184212_) {
this.simulationDistance = p_184212_;
this.broadcastAll(new ClientboundSetSimulationDistancePacket(p_184212_));
for (ServerLevel serverlevel : this.server.getAllLevels()) {
if (serverlevel != null) {
serverlevel.getChunkSource().setSimulationDistance(p_184212_);
}
}
}
public List<ServerPlayer> getPlayers() {
return this.players;
}
@Nullable
public ServerPlayer getPlayer(UUID p_11260_) {
return this.playersByUUID.get(p_11260_);
}
public boolean canBypassPlayerLimit(GameProfile p_11298_) {
return false;
}
public void reloadResources() {
for (PlayerAdvancements playeradvancements : this.advancements.values()) {
playeradvancements.reload(this.server.getAdvancements());
}
this.broadcastAll(new ClientboundUpdateTagsPacket(TagNetworkSerialization.serializeTagsToNetwork(this.registries)));
RecipeManager recipemanager = this.server.getRecipeManager();
ClientboundUpdateRecipesPacket clientboundupdaterecipespacket = new ClientboundUpdateRecipesPacket(recipemanager.getSynchronizedItemProperties(), recipemanager.getSynchronizedStonecutterRecipes());
for (ServerPlayer serverplayer : this.players) {
serverplayer.connection.send(clientboundupdaterecipespacket);
serverplayer.getRecipeBook().sendInitialRecipeBook(serverplayer);
}
}
public boolean isAllowCommandsForAllPlayers() {
return this.allowCommandsForAllPlayers;
}
}