317 lines
10 KiB
Java
317 lines
10 KiB
Java
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.UUID;
|
|
import java.util.function.BooleanSupplier;
|
|
import javax.annotation.Nullable;
|
|
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.server.MinecraftServer;
|
|
import net.minecraft.server.Services;
|
|
import net.minecraft.server.WorldStem;
|
|
import net.minecraft.server.level.ServerPlayer;
|
|
import net.minecraft.server.level.progress.ChunkProgressListenerFactory;
|
|
import net.minecraft.server.packs.repository.PackRepository;
|
|
import net.minecraft.stats.Stats;
|
|
import net.minecraft.util.ModCheck;
|
|
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.minecraftforge.api.distmarker.Dist;
|
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
|
import org.slf4j.Logger;
|
|
|
|
@OnlyIn(Dist.CLIENT)
|
|
public class IntegratedServer extends MinecraftServer {
|
|
private static final Logger LOGGER = LogUtils.getLogger();
|
|
private static final int MIN_SIM_DISTANCE = 2;
|
|
private final Minecraft minecraft;
|
|
private boolean paused = true;
|
|
private int publishedPort = -1;
|
|
@Nullable
|
|
private GameType publishedGameType;
|
|
@Nullable
|
|
private LanServerPinger lanPinger;
|
|
@Nullable
|
|
private UUID uuid;
|
|
private int previousSimulationDistance = 0;
|
|
|
|
public IntegratedServer(
|
|
Thread p_235248_,
|
|
Minecraft p_235249_,
|
|
LevelStorageSource.LevelStorageAccess p_235250_,
|
|
PackRepository p_235251_,
|
|
WorldStem p_235252_,
|
|
Services p_235253_,
|
|
ChunkProgressListenerFactory p_235254_
|
|
) {
|
|
super(p_235248_, p_235250_, p_235251_, p_235252_, p_235249_.getProxy(), p_235249_.getFixerUpper(), p_235253_, p_235254_);
|
|
this.setSingleplayerProfile(p_235249_.getGameProfile());
|
|
this.setDemo(p_235249_.isDemo());
|
|
this.setPlayerList(new IntegratedPlayerList(this, this.registries(), this.playerDataStorage));
|
|
this.minecraft = p_235249_;
|
|
}
|
|
|
|
@Override
|
|
public boolean initServer() {
|
|
LOGGER.info("Starting integrated minecraft server version {}", SharedConstants.getCurrentVersion().getName());
|
|
this.setUsesAuthentication(true);
|
|
this.setPvpAllowed(true);
|
|
this.setFlightAllowed(true);
|
|
this.initializeKeyPair();
|
|
this.loadLevel();
|
|
GameProfile gameprofile = this.getSingleplayerProfile();
|
|
String s = this.getWorldData().getLevelName();
|
|
this.setMotd(gameprofile != null ? gameprofile.getName() + " - " + s : s);
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean isPaused() {
|
|
return this.paused;
|
|
}
|
|
|
|
@Override
|
|
public void tickServer(BooleanSupplier p_120049_) {
|
|
boolean flag = this.paused;
|
|
this.paused = Minecraft.getInstance().isPaused();
|
|
ProfilerFiller profilerfiller = Profiler.get();
|
|
if (!flag && this.paused) {
|
|
profilerfiller.push("autoSave");
|
|
LOGGER.info("Saving and pausing game...");
|
|
this.saveEverything(false, false, false);
|
|
profilerfiller.pop();
|
|
}
|
|
|
|
boolean flag1 = Minecraft.getInstance().getConnection() != null;
|
|
if (flag1 && this.paused) {
|
|
this.tickPaused();
|
|
} else {
|
|
if (flag && !this.paused) {
|
|
this.forceTimeSynchronization();
|
|
}
|
|
|
|
super.tickServer(p_120049_);
|
|
int i = Math.max(2, this.minecraft.options.renderDistance().get());
|
|
if (i != this.getPlayerList().getViewDistance()) {
|
|
LOGGER.info("Changing view distance to {}, from {}", i, this.getPlayerList().getViewDistance());
|
|
this.getPlayerList().setViewDistance(i);
|
|
}
|
|
|
|
int j = Math.max(2, this.minecraft.options.simulationDistance().get());
|
|
if (j != this.previousSimulationDistance) {
|
|
LOGGER.info("Changing simulation distance to {}, from {}", j, this.previousSimulationDistance);
|
|
this.getPlayerList().setSimulationDistance(j);
|
|
this.previousSimulationDistance = j;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected LocalSampleLogger getTickTimeLogger() {
|
|
return this.minecraft.getDebugOverlay().getTickTimeLogger();
|
|
}
|
|
|
|
@Override
|
|
public boolean isTickTimeLoggingEnabled() {
|
|
return true;
|
|
}
|
|
|
|
private void tickPaused() {
|
|
for (ServerPlayer serverplayer : this.getPlayerList().getPlayers()) {
|
|
serverplayer.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 isEpollEnabled() {
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public void onServerCrash(CrashReport p_120051_) {
|
|
this.minecraft.delayCrashRaw(p_120051_);
|
|
}
|
|
|
|
@Override
|
|
public SystemReport fillServerSystemReport(SystemReport p_174970_) {
|
|
p_174970_.setDetail("Type", "Integrated Server (map_client.txt)");
|
|
p_174970_.setDetail("Is Modded", () -> this.getModdedStatus().fullDescription());
|
|
p_174970_.setDetail("Launched Version", this.minecraft::getLaunchedVersion);
|
|
return p_174970_;
|
|
}
|
|
|
|
@Override
|
|
public ModCheck getModdedStatus() {
|
|
return Minecraft.checkModStatus().merge(super.getModdedStatus());
|
|
}
|
|
|
|
@Override
|
|
public boolean publishServer(@Nullable GameType p_120041_, boolean p_120042_, int p_120043_) {
|
|
try {
|
|
this.minecraft.prepareForMultiplayer();
|
|
this.minecraft.getConnection().prepareKeyPair();
|
|
this.getConnection().startTcpServerListener(null, p_120043_);
|
|
LOGGER.info("Started serving on {}", p_120043_);
|
|
this.publishedPort = p_120043_;
|
|
this.lanPinger = new LanServerPinger(this.getMotd(), p_120043_ + "");
|
|
this.lanPinger.start();
|
|
this.publishedGameType = p_120041_;
|
|
this.getPlayerList().setAllowCommandsForAllPlayers(p_120042_);
|
|
int i = this.getProfilePermissions(this.minecraft.player.getGameProfile());
|
|
this.minecraft.player.setPermissionLevel(i);
|
|
|
|
for (ServerPlayer serverplayer : this.getPlayerList().getPlayers()) {
|
|
this.getCommands().sendCommands(serverplayer);
|
|
}
|
|
|
|
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 p_120053_) {
|
|
this.executeBlocking(() -> {
|
|
for (ServerPlayer serverplayer : Lists.newArrayList(this.getPlayerList().getPlayers())) {
|
|
if (!serverplayer.getUUID().equals(this.uuid)) {
|
|
this.getPlayerList().remove(serverplayer);
|
|
}
|
|
}
|
|
});
|
|
super.halt(p_120053_);
|
|
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 p_120039_) {
|
|
super.setDefaultGameType(p_120039_);
|
|
this.publishedGameType = null;
|
|
}
|
|
|
|
@Override
|
|
public boolean isCommandBlockEnabled() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public int getOperatorUserPermissionLevel() {
|
|
return 2;
|
|
}
|
|
|
|
@Override
|
|
public int getFunctionCompilationLevel() {
|
|
return 2;
|
|
}
|
|
|
|
public void setUUID(UUID p_120047_) {
|
|
this.uuid = p_120047_;
|
|
}
|
|
|
|
@Override
|
|
public boolean isSingleplayerOwner(GameProfile p_120045_) {
|
|
return this.getSingleplayerProfile() != null && p_120045_.getName().equalsIgnoreCase(this.getSingleplayerProfile().getName());
|
|
}
|
|
|
|
@Override
|
|
public int getScaledTrackingDistance(int p_120056_) {
|
|
return (int)(this.minecraft.options.entityDistanceScaling().get() * p_120056_);
|
|
}
|
|
|
|
@Override
|
|
public boolean forceSynchronousWrites() {
|
|
return this.minecraft.options.syncWrites;
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
public GameType getForcedGameType() {
|
|
return this.isPublished() && !this.isHardcore() ? MoreObjects.firstNonNull(this.publishedGameType, this.worldData.getGameType()) : null;
|
|
}
|
|
|
|
@Override
|
|
public boolean saveEverything(boolean p_329604_, boolean p_328766_, boolean p_334434_) {
|
|
boolean flag = super.saveEverything(p_329604_, p_328766_, p_334434_);
|
|
this.warnOnLowDiskSpace();
|
|
return flag;
|
|
}
|
|
|
|
private void warnOnLowDiskSpace() {
|
|
if (this.storageSource.checkForLowDiskSpace()) {
|
|
this.minecraft.execute(() -> SystemToast.onLowDiskSpace(this.minecraft));
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void reportChunkLoadFailure(Throwable p_344018_, RegionStorageInfo p_345415_, ChunkPos p_335057_) {
|
|
super.reportChunkLoadFailure(p_344018_, p_345415_, p_335057_);
|
|
this.warnOnLowDiskSpace();
|
|
this.minecraft.execute(() -> SystemToast.onChunkLoadFailure(this.minecraft, p_335057_));
|
|
}
|
|
|
|
@Override
|
|
public void reportChunkSaveFailure(Throwable p_345295_, RegionStorageInfo p_345019_, ChunkPos p_328809_) {
|
|
super.reportChunkSaveFailure(p_345295_, p_345019_, p_328809_);
|
|
this.warnOnLowDiskSpace();
|
|
this.minecraft.execute(() -> SystemToast.onChunkSaveFailure(this.minecraft, p_328809_));
|
|
}
|
|
} |