Fix network syncing of SERVER config. Enable COMMON Config. Fix network

login handling.

Signed-off-by: cpw <cpw+github@weeksfamily.ca>
This commit is contained in:
cpw 2019-02-15 21:45:28 -05:00
parent 36ccb3bbfe
commit 7f9e8d059b
No known key found for this signature in database
GPG key ID: 8EB3DF749553B1B7
11 changed files with 101 additions and 25 deletions

View file

@ -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 {

View file

@ -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
{

View file

@ -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);

View file

@ -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<Pair<String, FMLHandshakeMessages.S2CConfigData>> syncConfigs() {
final Map<String, byte[]> 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<NetworkEvent.Context> 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));
});
}
}
}

View file

@ -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<Void> 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.

View file

@ -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<NetworkEvent.Context> 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.

View file

@ -119,7 +119,6 @@ public class FMLHandshakeMessages
}
public static class S2CRegistry extends LoginIndexedMessage {
public S2CRegistry(final ResourceLocation key, final ForgeRegistry<? extends IForgeRegistryEntry<?>> 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;
}
}
}

View file

@ -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<String> FML_MARKER = AttributeKey.valueOf("fml:marker");
}

View file

@ -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);
}

View file

@ -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<LoginPayload> gatherLoginPayloads() {
static List<LoginPayload> gatherLoginPayloads(final NetworkDirection direction) {
if (direction!=NetworkDirection.LOGIN_TO_CLIENT) return Collections.emptyList();
List<LoginPayload> gatheredPayloads = new ArrayList<>();
instances.values().forEach(ni->ni.dispatchGatherLogin(gatheredPayloads));
return gatheredPayloads;

View file

@ -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;