2025-11-24 22:52:51 +03:00

357 lines
13 KiB
Java

/*
* 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<SimpleGizmoCollector.GizmoInstance> latestTicksGizmos = new ArrayList<SimpleGizmoCollector.GizmoInstance>();
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<SimpleGizmoCollector.GizmoInstance> getPerTickGizmos() {
return this.latestTicksGizmos;
}
}