From 7f9e8d059b53e23b5dc2005bfd6249ed7cb9cfb9 Mon Sep 17 00:00:00 2001 From: cpw Date: Fri, 15 Feb 2019 21:45:28 -0500 Subject: [PATCH] Fix network syncing of SERVER config. Enable COMMON Config. Fix network login handling. Signed-off-by: cpw --- .../minecraftforge/common/ForgeConfig.java | 5 --- .../net/minecraftforge/common/ForgeMod.java | 6 ---- .../net/minecraftforge/fml/ModLoader.java | 1 + .../fml/config/ConfigTracker.java | 32 +++++++++++++++++-- .../minecraftforge/fml/config/ModConfig.java | 22 +++++++++++-- .../fml/network/FMLHandshakeHandler.java | 17 +++++++++- .../fml/network/FMLHandshakeMessages.java | 29 ++++++++++++++++- .../fml/network/FMLNetworking.java | 4 --- .../fml/network/NetworkHooks.java | 1 + .../fml/network/NetworkRegistry.java | 5 ++- .../fml/server/ServerLifecycleHooks.java | 4 +-- 11 files changed, 101 insertions(+), 25 deletions(-) diff --git a/src/main/java/net/minecraftforge/common/ForgeConfig.java b/src/main/java/net/minecraftforge/common/ForgeConfig.java index 5e58eab59..6f632ee08 100644 --- a/src/main/java/net/minecraftforge/common/ForgeConfig.java +++ b/src/main/java/net/minecraftforge/common/ForgeConfig.java @@ -22,8 +22,6 @@ package net.minecraftforge.common; import static net.minecraftforge.fml.Logging.CORE; import static net.minecraftforge.fml.loading.LogMarkers.FORGEMOD; -import com.electronwill.nightconfig.core.CommentedConfig; -import com.google.common.collect.Lists; import net.minecraftforge.eventbus.api.SubscribeEvent; import net.minecraftforge.fml.config.ModConfig; import org.apache.commons.lang3.tuple.Pair; @@ -33,9 +31,6 @@ import net.minecraftforge.common.ForgeConfigSpec.BooleanValue; import net.minecraftforge.common.ForgeConfigSpec.DoubleValue; import net.minecraftforge.common.ForgeConfigSpec.IntValue; -import javax.annotation.Nullable; -import java.util.List; - public class ForgeConfig { public static class Server { diff --git a/src/main/java/net/minecraftforge/common/ForgeMod.java b/src/main/java/net/minecraftforge/common/ForgeMod.java index ab6cc4c10..cadfc275f 100644 --- a/src/main/java/net/minecraftforge/common/ForgeMod.java +++ b/src/main/java/net/minecraftforge/common/ForgeMod.java @@ -32,13 +32,10 @@ import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent; import net.minecraftforge.fml.event.server.FMLServerStartingEvent; import net.minecraftforge.fml.event.server.FMLServerStoppingEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.fml.loading.FMLPaths; import net.minecraftforge.server.command.ForgeCommand; import net.minecraftforge.versions.forge.ForgeVersion; import net.minecraftforge.versions.mcp.MCPVersion; -import java.nio.file.Path; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -55,9 +52,6 @@ import net.minecraftforge.fml.common.gameevent.PlayerEvent; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; -import com.electronwill.nightconfig.core.file.CommentedFileConfig; -import com.electronwill.nightconfig.core.io.WritingMode; - @Mod("forge") public class ForgeMod implements WorldPersistenceHooks.WorldPersistenceHook { diff --git a/src/main/java/net/minecraftforge/fml/ModLoader.java b/src/main/java/net/minecraftforge/fml/ModLoader.java index 1b9d087c2..22dd27697 100644 --- a/src/main/java/net/minecraftforge/fml/ModLoader.java +++ b/src/main/java/net/minecraftforge/fml/ModLoader.java @@ -133,6 +133,7 @@ public class ModLoader CapabilityManager.INSTANCE.injectCapabilities(modList.getAllScanData()); GameData.fireRegistryEvents(rl->true, LifecycleEventProvider.LOAD_REGISTRIES, this::dispatchAndHandleError); DistExecutor.runWhenOn(Dist.CLIENT, ()->()-> ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.CLIENT, FMLPaths.CONFIGDIR.get())); + ConfigTracker.INSTANCE.loadConfigs(ModConfig.Type.COMMON, FMLPaths.CONFIGDIR.get()); dispatchAndHandleError(LifecycleEventProvider.SETUP); DistExecutor.runWhenOn(Dist.CLIENT, ModLoader::fireClientEvents); dispatchAndHandleError(LifecycleEventProvider.SIDED_SETUP); diff --git a/src/main/java/net/minecraftforge/fml/config/ConfigTracker.java b/src/main/java/net/minecraftforge/fml/config/ConfigTracker.java index bbe268858..47d0186ff 100644 --- a/src/main/java/net/minecraftforge/fml/config/ConfigTracker.java +++ b/src/main/java/net/minecraftforge/fml/config/ConfigTracker.java @@ -20,18 +20,31 @@ package net.minecraftforge.fml.config; import com.electronwill.nightconfig.core.file.CommentedFileConfig; +import com.electronwill.nightconfig.toml.TomlFormat; +import net.minecraft.client.Minecraft; +import net.minecraftforge.fml.network.FMLHandshakeMessages; +import net.minecraftforge.fml.network.NetworkEvent; +import org.apache.commons.lang3.tuple.Pair; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; +import java.io.ByteArrayInputStream; +import java.nio.file.Files; import java.nio.file.Path; import java.util.Collections; import java.util.EnumMap; import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentSkipListSet; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import static cpw.mods.modlauncher.api.LamdbaExceptionUtils.rethrowFunction; public class ConfigTracker { private static final Logger LOGGER = LogManager.getLogger(); @@ -44,6 +57,7 @@ public class ConfigTracker { this.fileMap = new ConcurrentHashMap<>(); this.configSets = new EnumMap<>(ModConfig.Type.class); this.configSets.put(ModConfig.Type.CLIENT, Collections.synchronizedSet(new LinkedHashSet<>())); + this.configSets.put(ModConfig.Type.COMMON, Collections.synchronizedSet(new LinkedHashSet<>())); // this.configSets.put(ModConfig.Type.PLAYER, new ConcurrentSkipListSet<>()); this.configSets.put(ModConfig.Type.SERVER, Collections.synchronizedSet(new LinkedHashSet<>())); } @@ -63,11 +77,25 @@ public class ConfigTracker { this.configSets.get(type).forEach(config -> openConfig(config, configBasePath)); } + public List> syncConfigs() { + final Map configData = configSets.get(ModConfig.Type.SERVER).stream().collect(Collectors.toMap(ModConfig::getFileName, rethrowFunction(mc -> Files.readAllBytes(mc.getFullPath())))); + return configData.entrySet().stream().map(e->Pair.of("Config "+e.getKey(), new FMLHandshakeMessages.S2CConfigData(e.getKey(), e.getValue()))).collect(Collectors.toList()); + } + private void openConfig(final ModConfig config, final Path configBasePath) { LOGGER.debug(CONFIG, "Loading config file type {} at {} for {}", config.getType(), config.getFileName(), config.getModId()); final CommentedFileConfig configData = config.getHandler().reader(configBasePath).apply(config); config.setConfigData(configData); config.fireEvent(new ModConfig.Loading(config)); - config.getConfigData().save(); + config.save(); + } + + public void receiveSyncedConfig(final FMLHandshakeMessages.S2CConfigData s2CConfigData, final Supplier contextSupplier) { + if (!Minecraft.getInstance().isIntegratedServerRunning()) { + Optional.ofNullable(fileMap.get(s2CConfigData.getFileName())).ifPresent(mc-> { + mc.setConfigData(TomlFormat.instance().createParser().parse(new ByteArrayInputStream(s2CConfigData.getBytes()))); + mc.fireEvent(new ModConfig.ConfigReloading(mc)); + }); + } } } diff --git a/src/main/java/net/minecraftforge/fml/config/ModConfig.java b/src/main/java/net/minecraftforge/fml/config/ModConfig.java index 3c4ef9e16..2e90cdd7e 100644 --- a/src/main/java/net/minecraftforge/fml/config/ModConfig.java +++ b/src/main/java/net/minecraftforge/fml/config/ModConfig.java @@ -19,12 +19,19 @@ package net.minecraftforge.fml.config; +import com.electronwill.nightconfig.core.CommentedConfig; import com.electronwill.nightconfig.core.file.CommentedFileConfig; import net.minecraftforge.common.ForgeConfigSpec; import net.minecraftforge.eventbus.api.Event; import net.minecraftforge.fml.ModContainer; import net.minecraftforge.fml.loading.StringUtils; +import java.nio.file.Path; +import java.util.concurrent.Callable; +import java.util.function.Consumer; + +import static cpw.mods.modlauncher.api.LamdbaExceptionUtils.uncheck; + public class ModConfig { private final Type type; @@ -32,7 +39,8 @@ public class ModConfig private final String fileName; private final ModContainer container; private final ConfigFileTypeHandler configHandler; - private CommentedFileConfig configData; + private CommentedConfig configData; + private Callable saveHandler; public ModConfig(final Type type, final ForgeConfigSpec spec, final ModContainer container, final String fileName) { this.type = type; @@ -71,11 +79,11 @@ public class ModConfig return container.getModId(); } - public CommentedFileConfig getConfigData() { + public CommentedConfig getConfigData() { return this.configData; } - void setConfigData(final CommentedFileConfig configData) { + void setConfigData(final CommentedConfig configData) { this.configData = configData; this.spec.setConfig(this.configData); } @@ -84,6 +92,14 @@ public class ModConfig this.container.dispatchConfigEvent(configEvent); } + public void save() { + ((CommentedFileConfig)this.configData).save(); + } + + public Path getFullPath() { + return ((CommentedFileConfig)this.configData).getNioPath(); + } + public enum Type { /** * Common mod config for configuration that needs to be loaded on both environments. diff --git a/src/main/java/net/minecraftforge/fml/network/FMLHandshakeHandler.java b/src/main/java/net/minecraftforge/fml/network/FMLHandshakeHandler.java index 1e13149fe..0c3992652 100644 --- a/src/main/java/net/minecraftforge/fml/network/FMLHandshakeHandler.java +++ b/src/main/java/net/minecraftforge/fml/network/FMLHandshakeHandler.java @@ -25,6 +25,7 @@ import net.minecraft.network.PacketBuffer; import net.minecraft.network.NetHandlerLoginServer; import net.minecraft.util.ResourceLocation; import net.minecraft.util.text.TextComponentString; +import net.minecraftforge.fml.config.ConfigTracker; import net.minecraftforge.fml.network.simple.SimpleChannel; import net.minecraftforge.fml.util.ThreeConsumer; import net.minecraftforge.registries.RegistryManager; @@ -108,6 +109,13 @@ public class FMLHandshakeHandler { buildLoginPacketList(RegistryManager::generateRegistryPackets). consumer(biConsumerFor(FMLHandshakeHandler::handleRegistryMessage)). add(); + channel.messageBuilder(FMLHandshakeMessages.S2CConfigData.class, 4). + loginIndex(FMLHandshakeMessages.LoginIndexedMessage::getLoginIndex, FMLHandshakeMessages.LoginIndexedMessage::setLoginIndex). + decoder(FMLHandshakeMessages.S2CConfigData::decode). + encoder(FMLHandshakeMessages.S2CConfigData::encode). + buildLoginPacketList(ConfigTracker.INSTANCE::syncConfigs). + consumer(biConsumerFor(FMLHandshakeHandler::handleConfigSync)). + add(); } /** @@ -172,7 +180,7 @@ public class FMLHandshakeHandler { { this.direction = side; this.manager = networkManager; - this.messageList = NetworkRegistry.gatherLoginPayloads(); + this.messageList = NetworkRegistry.gatherLoginPayloads(this.direction); LOGGER.debug(FMLHSMARKER, "Starting new modded network connection. Found {} messages to dispatch.", this.messageList.size()); } @@ -224,6 +232,13 @@ public class FMLHandshakeHandler { contextSupplier.get().setPacketHandled(true); } + private void handleConfigSync(final FMLHandshakeMessages.S2CConfigData msg, final Supplier contextSupplier) { + LOGGER.debug(FMLHSMARKER, "Received config sync from server"); + ConfigTracker.INSTANCE.receiveSyncedConfig(msg, contextSupplier); + contextSupplier.get().setPacketHandled(true); + final FMLHandshakeMessages.C2SAcknowledge reply = new FMLHandshakeMessages.C2SAcknowledge(); + channel.reply(reply, contextSupplier.get()); + } /** * FML will send packets, from Server to Client, from the messages queue until the queue is drained. Each message * will be indexed, and placed into the "pending acknowledgement" queue. diff --git a/src/main/java/net/minecraftforge/fml/network/FMLHandshakeMessages.java b/src/main/java/net/minecraftforge/fml/network/FMLHandshakeMessages.java index af851aa06..1c944b5db 100644 --- a/src/main/java/net/minecraftforge/fml/network/FMLHandshakeMessages.java +++ b/src/main/java/net/minecraftforge/fml/network/FMLHandshakeMessages.java @@ -119,7 +119,6 @@ public class FMLHandshakeMessages } public static class S2CRegistry extends LoginIndexedMessage { - public S2CRegistry(final ResourceLocation key, final ForgeRegistry> registry) { } @@ -133,4 +132,32 @@ public class FMLHandshakeMessages return new S2CRegistry(); } } + + + public static class S2CConfigData extends LoginIndexedMessage { + private final String fileName; + private final byte[] fileData; + + public S2CConfigData(final String configFileName, final byte[] configFileData) { + this.fileName = configFileName; + this.fileData = configFileData; + } + + void encode(final PacketBuffer buffer) { + buffer.writeString(this.fileName); + buffer.writeByteArray(this.fileData); + } + + public static S2CConfigData decode(final PacketBuffer buffer) { + return new S2CConfigData(buffer.readString(128), buffer.readByteArray()); + } + + public String getFileName() { + return fileName; + } + + public byte[] getBytes() { + return fileData; + } + } } diff --git a/src/main/java/net/minecraftforge/fml/network/FMLNetworking.java b/src/main/java/net/minecraftforge/fml/network/FMLNetworking.java index 9d8769d8a..539cb43e2 100644 --- a/src/main/java/net/minecraftforge/fml/network/FMLNetworking.java +++ b/src/main/java/net/minecraftforge/fml/network/FMLNetworking.java @@ -20,15 +20,11 @@ package net.minecraftforge.fml.network; import io.netty.util.AttributeKey; -import net.minecraft.network.NetworkManager; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; public class FMLNetworking { - private static final Logger LOGGER = LogManager.getLogger(); static final Marker NETWORK = MarkerManager.getMarker("FMLNETWORK"); static final AttributeKey FML_MARKER = AttributeKey.valueOf("fml:marker"); } diff --git a/src/main/java/net/minecraftforge/fml/network/NetworkHooks.java b/src/main/java/net/minecraftforge/fml/network/NetworkHooks.java index bc6685e0c..b85472727 100644 --- a/src/main/java/net/minecraftforge/fml/network/NetworkHooks.java +++ b/src/main/java/net/minecraftforge/fml/network/NetworkHooks.java @@ -79,6 +79,7 @@ public class NetworkHooks public static void registerClientLoginChannel(NetworkManager manager) { + if (manager == null) return; manager.channel().attr(FMLNetworking.FML_MARKER).set(NETVERSION); FMLHandshakeHandler.registerHandshake(manager, NetworkDirection.LOGIN_TO_SERVER); } diff --git a/src/main/java/net/minecraftforge/fml/network/NetworkRegistry.java b/src/main/java/net/minecraftforge/fml/network/NetworkRegistry.java index 41a60c497..321050342 100644 --- a/src/main/java/net/minecraftforge/fml/network/NetworkRegistry.java +++ b/src/main/java/net/minecraftforge/fml/network/NetworkRegistry.java @@ -33,6 +33,7 @@ import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -204,8 +205,10 @@ public class NetworkRegistry * Dispatches {@link net.minecraftforge.fml.network.NetworkEvent.GatherLoginPayloadsEvent} to each {@link NetworkInstance}. * * @return The {@link LoginPayload} list + * @param direction the network direction for the request - only gathers for LOGIN_TO_CLIENT */ - static List gatherLoginPayloads() { + static List gatherLoginPayloads(final NetworkDirection direction) { + if (direction!=NetworkDirection.LOGIN_TO_CLIENT) return Collections.emptyList(); List gatheredPayloads = new ArrayList<>(); instances.values().forEach(ni->ni.dispatchGatherLogin(gatheredPayloads)); return gatheredPayloads; diff --git a/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java b/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java index 021c001a0..0a0bbd38f 100644 --- a/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java +++ b/src/main/java/net/minecraftforge/fml/server/ServerLifecycleHooks.java @@ -36,7 +36,6 @@ import net.minecraftforge.fml.event.server.FMLServerStartingEvent; import net.minecraftforge.fml.event.server.FMLServerStartedEvent; import net.minecraftforge.fml.event.server.FMLServerStoppedEvent; import net.minecraftforge.fml.event.server.FMLServerStoppingEvent; -import net.minecraftforge.fml.loading.FMLPaths; import net.minecraftforge.fml.loading.FileUtils; import net.minecraftforge.fml.network.NetworkHooks; import net.minecraftforge.fml.packs.ResourcePackLoader; @@ -46,7 +45,6 @@ import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; import java.nio.file.Path; -import java.nio.file.Paths; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicBoolean; @@ -133,6 +131,8 @@ public class ServerLifecycleHooks return false; } + if (packet.getRequestedState() == EnumConnectionState.STATUS) return true; + NetworkHooks.registerServerLoginChannel(manager, packet); return true;