Files
MinecraftForge/src/main/java/net/minecraftforge/server/ServerLifecycleHooks.java
T

186 lines
9.2 KiB
Java
Raw Normal View History

2018-06-21 15:37:32 -04:00
/*
* Copyright (c) Forge Development LLC and contributors
* SPDX-License-Identifier: LGPL-2.1-only
2018-06-21 15:37:32 -04:00
*/
2021-11-26 18:57:41 +00:00
package net.minecraftforge.server;
2018-06-21 15:37:32 -04:00
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
2022-06-07 15:31:26 -05:00
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;
2022-06-07 15:31:26 -05:00
import net.minecraft.core.Holder;
import net.minecraft.core.RegistryAccess;
2022-11-22 13:32:47 -06:00
import net.minecraft.core.registries.Registries;
import net.minecraft.gametest.framework.GameTestServer;
2023-09-10 20:27:15 -07:00
import net.minecraft.network.Connection;
import net.minecraft.network.ConnectionProtocol;
2022-06-07 15:31:26 -05:00
import net.minecraft.network.chat.Component;
2023-09-10 20:27:15 -07:00
import net.minecraft.network.protocol.handshake.ClientIntent;
import net.minecraft.network.protocol.handshake.ClientIntentionPacket;
import net.minecraft.network.protocol.login.ClientboundLoginDisconnectPacket;
2021-07-17 00:08:49 -05:00
import net.minecraft.world.level.storage.LevelResource;
import net.minecraftforge.common.world.StructureModifier;
import net.minecraftforge.fml.DistExecutor;
2021-11-26 18:57:41 +00:00
import net.minecraftforge.common.util.LogicalSidedProvider;
2022-06-07 15:31:26 -05:00
import net.minecraftforge.common.world.BiomeModifier;
2021-11-26 18:57:41 +00:00
import net.minecraftforge.network.ConnectionType;
2023-09-10 20:27:15 -07:00
import net.minecraftforge.network.NetworkContext;
2021-11-26 18:57:41 +00:00
import net.minecraftforge.network.NetworkRegistry;
import net.minecraftforge.registries.ForgeRegistries.Keys;
2021-12-20 19:34:57 +01:00
import net.minecraftforge.server.permission.PermissionAPI;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
2018-06-21 15:37:32 -04:00
import net.minecraft.server.MinecraftServer;
import net.minecraftforge.api.distmarker.Dist;
2018-06-21 15:37:32 -04:00
import net.minecraftforge.common.MinecraftForge;
2019-01-28 22:42:37 -05:00
import net.minecraftforge.fml.config.ConfigTracker;
import net.minecraftforge.fml.config.ModConfig;
2021-11-26 18:57:41 +00:00
import net.minecraftforge.event.server.ServerAboutToStartEvent;
import net.minecraftforge.event.server.ServerStartedEvent;
import net.minecraftforge.event.server.ServerStartingEvent;
import net.minecraftforge.event.server.ServerStoppedEvent;
import net.minecraftforge.event.server.ServerStoppingEvent;
2022-06-07 15:31:26 -05:00
import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.registries.GameData;
2022-11-22 13:32:47 -06:00
import org.jetbrains.annotations.ApiStatus;
2018-06-21 15:37:32 -04:00
2023-09-10 20:27:15 -07:00
@SuppressWarnings("deprecation")
@ApiStatus.Internal
public class ServerLifecycleHooks {
2018-08-27 13:10:07 -04:00
private static final Logger LOGGER = LogManager.getLogger();
2018-06-21 15:37:32 -04:00
private static final Marker SERVERHOOKS = MarkerManager.getMarker("SERVERHOOKS");
2021-07-17 00:08:49 -05:00
private static final LevelResource SERVERCONFIG = new LevelResource("serverconfig");
2023-09-10 20:27:15 -07:00
private static final AtomicBoolean allowLogins = new AtomicBoolean(false);
2018-06-21 15:37:32 -04:00
private static volatile CountDownLatch exitLatch = null;
private static MinecraftServer currentServer;
2023-09-10 20:27:15 -07:00
private static Path getServerConfigPath(final MinecraftServer server) {
final Path serverConfig = server.getWorldPath(SERVERCONFIG);
if (!Files.isDirectory(serverConfig)) {
try {
Files.createDirectories(serverConfig);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return serverConfig;
}
2023-09-10 20:27:15 -07:00
public static boolean handleServerAboutToStart(final MinecraftServer server) {
2018-06-21 15:37:32 -04:00
currentServer = server;
// on the dedi server we need to force the stuff to setup properly
2018-06-22 22:45:01 -04:00
LogicalSidedProvider.setServer(()->server);
ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.SERVER, getServerConfigPath(server));
runModifiers(server);
2021-11-26 18:57:41 +00:00
return !MinecraftForge.EVENT_BUS.post(new ServerAboutToStartEvent(server));
2018-06-21 15:37:32 -04:00
}
2023-09-10 20:27:15 -07:00
public static boolean handleServerStarting(final MinecraftServer server) {
DistExecutor.runWhenOn(Dist.DEDICATED_SERVER, ()->()->{
LanguageHook.loadLanguagesOnServer(server);
// GameTestServer requires the gametests to be registered earlier, so it is done in main and should not be done twice.
if (!(server instanceof GameTestServer))
net.minecraftforge.gametest.ForgeGameTestHooks.registerGametests();
});
2021-12-20 19:34:57 +01:00
PermissionAPI.initializePermissionAPI();
2021-11-26 18:57:41 +00:00
return !MinecraftForge.EVENT_BUS.post(new ServerStartingEvent(server));
2018-06-21 15:37:32 -04:00
}
2023-09-10 20:27:15 -07:00
public static void expectServerStopped() {
2018-06-21 15:37:32 -04:00
exitLatch = new CountDownLatch(1);
}
2023-09-10 20:27:15 -07:00
public static void handleServerStopped(final MinecraftServer server) {
if (!server.isDedicatedServer()) GameData.revertToFrozen();
2021-11-26 18:57:41 +00:00
MinecraftForge.EVENT_BUS.post(new ServerStoppedEvent(server));
2018-06-21 15:37:32 -04:00
currentServer = null;
2018-06-22 22:45:01 -04:00
LogicalSidedProvider.setServer(null);
2018-06-21 15:37:32 -04:00
CountDownLatch latch = exitLatch;
2023-09-10 20:27:15 -07:00
if (latch != null) {
2018-06-21 15:37:32 -04:00
latch.countDown();
exitLatch = null;
}
ConfigTracker.INSTANCE.unloadConfigs(ModConfig.Type.SERVER, getServerConfigPath(server));
2018-06-21 15:37:32 -04:00
}
2023-09-10 20:27:15 -07:00
public static MinecraftServer getCurrentServer() {
2018-06-21 15:37:32 -04:00
return currentServer;
}
2023-09-10 20:27:15 -07:00
private static void runModifiers(final MinecraftServer server) {
2022-06-07 15:31:26 -05:00
final RegistryAccess registries = server.registryAccess();
2022-06-07 15:31:26 -05:00
// The order of holders() is the order modifiers were loaded in.
final List<BiomeModifier> biomeModifiers = registries.registryOrThrow(ForgeRegistries.Keys.BIOME_MODIFIERS)
2022-06-07 15:31:26 -05:00
.holders()
.map(Holder::value)
.toList();
final List<StructureModifier> structureModifiers = registries.registryOrThrow(Keys.STRUCTURE_MODIFIERS)
.holders()
.map(Holder::value)
.toList();
2022-06-07 15:31:26 -05:00
// Apply sorted biome modifiers to each biome.
2022-11-22 13:32:47 -06:00
registries.registryOrThrow(Registries.BIOME).holders().forEach(biomeHolder ->
2023-09-10 20:27:15 -07:00
biomeHolder.value().modifiableBiomeInfo().applyBiomeModifiers(biomeHolder, biomeModifiers)
);
// Apply sorted structure modifiers to each structure.
2022-11-22 13:32:47 -06:00
registries.registryOrThrow(Registries.STRUCTURE).holders().forEach(structureHolder ->
2023-09-10 20:27:15 -07:00
structureHolder.value().modifiableStructureInfo().applyStructureModifiers(structureHolder, structureModifiers)
);
}
//==================================================================================================================================================================================
//==================================================================================================================================================================================
//==================================================================================================================================================================================
//==================================================================================================================================================================================
//==================================================================================================================================================================================
//==================================================================================================================================================================================
public static void handleServerStarted(final MinecraftServer server) {
MinecraftForge.EVENT_BUS.post(new ServerStartedEvent(server));
allowLogins.set(true);
}
public static void handleServerStopping(final MinecraftServer server) {
allowLogins.set(false);
MinecraftForge.EVENT_BUS.post(new ServerStoppingEvent(server));
}
public static boolean handleServerLogin(final ClientIntentionPacket packet, final Connection connection) {
var ctx = NetworkContext.get(connection);
ctx.processIntention(packet.hostName());
if (!allowLogins.get())
return rejectConnection(connection, ctx.getType(), "Server is still starting! Please wait before reconnecting.");
if (packet.nextProtocol() != ConnectionProtocol.LOGIN)
return true;
if (ctx.getType() == ConnectionType.MODDED && ctx.getNetVersion() != NetworkContext.NET_VERSION)
return rejectConnection(connection, ctx.getType(), "This modded server is not impl compatible with your modded client. Please verify your Forge version closely matches the server. Got net version " + ctx.getNetVersion() + " this server is net version " + NetworkContext.NET_VERSION);
if (ctx.getType() == ConnectionType.VANILLA && !NetworkRegistry.acceptsVanillaClientConnections())
return rejectConnection(connection, ctx.getType(), "This server has mods that require Forge to be installed on the client. Contact your server admin for more details.");
NetworkRegistry.onConnectionStart(connection);
return true;
}
private static boolean rejectConnection(final Connection connection, ConnectionType type, String message) {
connection.setClientboundProtocolAfterHandshake(ClientIntent.LOGIN);
LOGGER.info(SERVERHOOKS, "[{}] Disconnecting {} connection attempt: {}", connection.getLoggableAddress(true), type, message); // TODO: Respect logIP setting
var text = Component.literal(message);
connection.send(new ClientboundLoginDisconnectPacket(text));
connection.disconnect(text);
return false;
2022-06-07 15:31:26 -05:00
}
2018-06-21 15:37:32 -04:00
}