/* * Decompiled with CFR 0.152. * * Could not load the following classes: * com.google.common.base.MoreObjects * com.google.common.collect.Lists * com.mojang.authlib.GameProfile * com.mojang.logging.LogUtils * org.jspecify.annotations.Nullable * org.slf4j.Logger */ package net.minecraft.client.server; import com.google.common.base.MoreObjects; import com.google.common.collect.Lists; import com.mojang.authlib.GameProfile; import com.mojang.logging.LogUtils; import java.io.IOException; import java.nio.file.Path; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.UUID; import java.util.function.BooleanSupplier; import net.minecraft.CrashReport; import net.minecraft.SharedConstants; import net.minecraft.SystemReport; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.components.toasts.SystemToast; import net.minecraft.client.server.IntegratedPlayerList; import net.minecraft.client.server.LanServerPinger; import net.minecraft.core.BlockPos; import net.minecraft.core.GlobalPos; import net.minecraft.core.HolderLookup; import net.minecraft.gizmos.Gizmos; import net.minecraft.gizmos.SimpleGizmoCollector; import net.minecraft.nbt.CompoundTag; import net.minecraft.server.MinecraftServer; import net.minecraft.server.Services; import net.minecraft.server.WorldStem; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.progress.LevelLoadListener; import net.minecraft.server.packs.repository.PackRepository; import net.minecraft.server.permissions.LevelBasedPermissionSet; import net.minecraft.server.players.NameAndId; import net.minecraft.stats.Stats; import net.minecraft.util.ModCheck; import net.minecraft.util.ProblemReporter; import net.minecraft.util.debugchart.LocalSampleLogger; import net.minecraft.util.profiling.Profiler; import net.minecraft.util.profiling.ProfilerFiller; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.GameType; import net.minecraft.world.level.chunk.storage.RegionStorageInfo; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.TagValueInput; import net.minecraft.world.level.storage.ValueInput; import org.jspecify.annotations.Nullable; import org.slf4j.Logger; public class IntegratedServer extends MinecraftServer { private static final Logger LOGGER = LogUtils.getLogger(); private static final int MIN_SIM_DISTANCE = 2; public static final int MAX_PLAYERS = 8; private final Minecraft minecraft; private boolean paused = true; private int publishedPort = -1; private @Nullable GameType publishedGameType; private @Nullable LanServerPinger lanPinger; private @Nullable UUID uuid; private int previousSimulationDistance = 0; private volatile List latestTicksGizmos = new ArrayList(); private final SimpleGizmoCollector gizmoCollector = new SimpleGizmoCollector(); public IntegratedServer(Thread serverThread, Minecraft minecraft, LevelStorageSource.LevelStorageAccess levelStorageAccess, PackRepository packRepository, WorldStem worldStem, Services services, LevelLoadListener levelLoadListener) { super(serverThread, levelStorageAccess, packRepository, worldStem, minecraft.getProxy(), minecraft.getFixerUpper(), services, levelLoadListener); this.setSingleplayerProfile(minecraft.getGameProfile()); this.setDemo(minecraft.isDemo()); this.setPlayerList(new IntegratedPlayerList(this, this.registries(), this.playerDataStorage)); this.minecraft = minecraft; } @Override protected boolean initServer() { LOGGER.info("Starting integrated minecraft server version {}", (Object)SharedConstants.getCurrentVersion().name()); this.setUsesAuthentication(true); this.initializeKeyPair(); this.loadLevel(); GameProfile host = this.getSingleplayerProfile(); String levelName = this.getWorldData().getLevelName(); this.setMotd((String)(host != null ? host.name() + " - " + levelName : levelName)); return true; } @Override public boolean isPaused() { return this.paused; } @Override protected void tickServer(BooleanSupplier haveTime) { int serverSimulationDistance; boolean wasPaused = this.paused; this.paused = Minecraft.getInstance().isPaused() || this.getPlayerList().getPlayers().isEmpty(); ProfilerFiller profiler = Profiler.get(); if (!wasPaused && this.paused) { profiler.push("autoSave"); LOGGER.info("Saving and pausing game..."); this.saveEverything(false, false, false); profiler.pop(); } if (this.paused) { this.tickPaused(); return; } if (wasPaused) { this.forceTimeSynchronization(); } try (Gizmos.TemporaryCollection ignored = Gizmos.withCollector(this.gizmoCollector);){ super.tickServer(haveTime); } this.latestTicksGizmos = this.gizmoCollector.drainGizmos(); int serverViewDistance = Math.max(2, this.minecraft.options.renderDistance().get()); if (serverViewDistance != this.getPlayerList().getViewDistance()) { LOGGER.info("Changing view distance to {}, from {}", (Object)serverViewDistance, (Object)this.getPlayerList().getViewDistance()); this.getPlayerList().setViewDistance(serverViewDistance); } if ((serverSimulationDistance = Math.max(2, this.minecraft.options.simulationDistance().get())) != this.previousSimulationDistance) { LOGGER.info("Changing simulation distance to {}, from {}", (Object)serverSimulationDistance, (Object)this.previousSimulationDistance); this.getPlayerList().setSimulationDistance(serverSimulationDistance); this.previousSimulationDistance = serverSimulationDistance; } } @Override protected LocalSampleLogger getTickTimeLogger() { return this.minecraft.getDebugOverlay().getTickTimeLogger(); } @Override public boolean isTickTimeLoggingEnabled() { return true; } private void tickPaused() { this.tickConnection(); for (ServerPlayer player : this.getPlayerList().getPlayers()) { player.awardStat(Stats.TOTAL_WORLD_TIME); } } @Override public boolean shouldRconBroadcast() { return true; } @Override public boolean shouldInformAdmins() { return true; } @Override public Path getServerDirectory() { return this.minecraft.gameDirectory.toPath(); } @Override public boolean isDedicatedServer() { return false; } @Override public int getRateLimitPacketsPerSecond() { return 0; } @Override public boolean useNativeTransport() { return this.minecraft.options.useNativeTransport(); } @Override protected void onServerCrash(CrashReport report) { this.minecraft.delayCrashRaw(report); } @Override public SystemReport fillServerSystemReport(SystemReport systemReport) { systemReport.setDetail("Type", "Integrated Server"); systemReport.setDetail("Is Modded", () -> this.getModdedStatus().fullDescription()); systemReport.setDetail("Launched Version", this.minecraft::getLaunchedVersion); return systemReport; } @Override public ModCheck getModdedStatus() { return Minecraft.checkModStatus().merge(super.getModdedStatus()); } @Override public boolean publishServer(@Nullable GameType gameMode, boolean allowCommands, int port) { try { this.minecraft.prepareForMultiplayer(); this.minecraft.getConnection().prepareKeyPair(); this.getConnection().startTcpServerListener(null, port); LOGGER.info("Started serving on {}", (Object)port); this.publishedPort = port; this.lanPinger = new LanServerPinger(this.getMotd(), "" + port); this.lanPinger.start(); this.publishedGameType = gameMode; this.getPlayerList().setAllowCommandsForAllPlayers(allowCommands); LevelBasedPermissionSet newProfilePermissions = this.getProfilePermissions(this.minecraft.player.nameAndId()); this.minecraft.player.setPermissions(newProfilePermissions); for (ServerPlayer player : this.getPlayerList().getPlayers()) { this.getCommands().sendCommands(player); } return true; } catch (IOException iOException) { return false; } } @Override public void stopServer() { super.stopServer(); if (this.lanPinger != null) { this.lanPinger.interrupt(); this.lanPinger = null; } } @Override public void halt(boolean wait) { this.executeBlocking(() -> { ArrayList players = Lists.newArrayList(this.getPlayerList().getPlayers()); for (ServerPlayer player : players) { if (player.getUUID().equals(this.uuid)) continue; this.getPlayerList().remove(player); } }); super.halt(wait); if (this.lanPinger != null) { this.lanPinger.interrupt(); this.lanPinger = null; } } @Override public boolean isPublished() { return this.publishedPort > -1; } @Override public int getPort() { return this.publishedPort; } @Override public void setDefaultGameType(GameType gameType) { super.setDefaultGameType(gameType); this.publishedGameType = null; } @Override public LevelBasedPermissionSet operatorUserPermissions() { return LevelBasedPermissionSet.GAMEMASTER; } @Override public LevelBasedPermissionSet getFunctionCompilationPermissions() { return LevelBasedPermissionSet.GAMEMASTER; } public void setUUID(UUID uuid) { this.uuid = uuid; } @Override public boolean isSingleplayerOwner(NameAndId nameAndId) { return this.getSingleplayerProfile() != null && nameAndId.name().equalsIgnoreCase(this.getSingleplayerProfile().name()); } @Override public int getScaledTrackingDistance(int baseRange) { return (int)(this.minecraft.options.entityDistanceScaling().get() * (double)baseRange); } @Override public boolean forceSynchronousWrites() { return this.minecraft.options.syncWrites; } @Override public @Nullable GameType getForcedGameType() { if (this.isPublished() && !this.isHardcore()) { return (GameType)MoreObjects.firstNonNull((Object)this.publishedGameType, (Object)this.worldData.getGameType()); } return null; } @Override protected GlobalPos selectLevelLoadFocusPos() { CompoundTag loadedPlayerTag = this.worldData.getLoadedPlayerTag(); if (loadedPlayerTag == null) { return super.selectLevelLoadFocusPos(); } try (ProblemReporter.ScopedCollector reporter = new ProblemReporter.ScopedCollector(LOGGER);){ ValueInput input = TagValueInput.create((ProblemReporter)reporter, (HolderLookup.Provider)this.registryAccess(), loadedPlayerTag); ServerPlayer.SavedPosition loadedPosition = input.read(ServerPlayer.SavedPosition.MAP_CODEC).orElse(ServerPlayer.SavedPosition.EMPTY); if (loadedPosition.dimension().isPresent() && loadedPosition.position().isPresent()) { GlobalPos globalPos = new GlobalPos(loadedPosition.dimension().get(), BlockPos.containing(loadedPosition.position().get())); return globalPos; } } return super.selectLevelLoadFocusPos(); } @Override public boolean saveEverything(boolean silent, boolean flush, boolean force) { boolean retval = super.saveEverything(silent, flush, force); this.warnOnLowDiskSpace(); return retval; } private void warnOnLowDiskSpace() { if (this.storageSource.checkForLowDiskSpace()) { this.minecraft.execute(() -> SystemToast.onLowDiskSpace(this.minecraft)); } } @Override public void reportChunkLoadFailure(Throwable throwable, RegionStorageInfo storageInfo, ChunkPos pos) { super.reportChunkLoadFailure(throwable, storageInfo, pos); this.warnOnLowDiskSpace(); this.minecraft.execute(() -> SystemToast.onChunkLoadFailure(this.minecraft, pos)); } @Override public void reportChunkSaveFailure(Throwable throwable, RegionStorageInfo storageInfo, ChunkPos pos) { super.reportChunkSaveFailure(throwable, storageInfo, pos); this.warnOnLowDiskSpace(); this.minecraft.execute(() -> SystemToast.onChunkSaveFailure(this.minecraft, pos)); } @Override public int getMaxPlayers() { return 8; } public Collection getPerTickGizmos() { return this.latestTicksGizmos; } }