mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-12 16:27:47 +00:00
Handle differing network versions for FML gracefully?
Signed-off-by: cpw <cpw+github@weeksfamily.ca>
This commit is contained in:
8 files changed
+52
-37
No files matched your search
@@ -19,23 +19,23 @@
|
||||
|
||||
package net.minecraftforge.fml.network;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
|
||||
public enum ConnectionType
|
||||
{
|
||||
MODDED(NetworkHooks.NETVERSION), VANILLA(NetworkHooks.NOVERSION);
|
||||
MODDED(s->Integer.valueOf(s.substring(FMLNetworkConstants.FMLNETMARKER.length()))), VANILLA(s->0);
|
||||
|
||||
private final String versionString;
|
||||
private final Function<String, Integer> versionExtractor;
|
||||
|
||||
ConnectionType(String versionString)
|
||||
{
|
||||
this.versionString = versionString;
|
||||
ConnectionType(Function<String, Integer> versionExtractor) {
|
||||
this.versionExtractor = versionExtractor;
|
||||
}
|
||||
|
||||
public static ConnectionType forVersionFlag(String vers)
|
||||
{
|
||||
return Arrays.stream(values()).filter(ct->Objects.equals(ct.versionString, vers)).
|
||||
findFirst().orElse(ConnectionType.VANILLA);
|
||||
return vers.startsWith(FMLNetworkConstants.FMLNETMARKER) ? MODDED : VANILLA;
|
||||
}
|
||||
|
||||
public int getFMLVersionNumber(final String fmlVersion) {
|
||||
return versionExtractor.apply(fmlVersion);
|
||||
}
|
||||
}
|
||||
@@ -72,7 +72,7 @@ import static net.minecraftforge.registries.ForgeRegistry.REGISTRIES;
|
||||
* final login phase will commence.
|
||||
*/
|
||||
public class FMLHandshakeHandler {
|
||||
static final Marker FMLHSMARKER = MarkerManager.getMarker("FMLHANDSHAKE").setParents(FMLNetworking.NETWORK);
|
||||
static final Marker FMLHSMARKER = MarkerManager.getMarker("FMLHANDSHAKE").setParents(FMLNetworkConstants.NETWORK);
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
static final ResourceLocation FML_HANDSHAKE_RESOURCE = new ResourceLocation("fml:handshake");
|
||||
private static final AttributeKey<FMLHandshakeHandler> FML_HANDSHAKE_HANDLER_ATTRIBUTE_KEY = AttributeKey.newInstance("fml:handshake");
|
||||
@@ -83,7 +83,7 @@ public class FMLHandshakeHandler {
|
||||
channel = NetworkRegistry.ChannelBuilder.named(FML_HANDSHAKE_RESOURCE).
|
||||
clientAcceptedVersions(a -> true).
|
||||
serverAcceptedVersions(a -> true).
|
||||
networkProtocolVersion(() -> NetworkHooks.NETVERSION).
|
||||
networkProtocolVersion(() -> FMLNetworkConstants.NETVERSION).
|
||||
simpleChannel();
|
||||
channel.messageBuilder(FMLHandshakeMessages.C2SAcknowledge.class, 99).
|
||||
loginIndex(FMLHandshakeMessages.LoginIndexedMessage::getLoginIndex, FMLHandshakeMessages.LoginIndexedMessage::setLoginIndex).
|
||||
@@ -208,7 +208,7 @@ public class FMLHandshakeHandler {
|
||||
channel.reply(reply, c.get());
|
||||
LOGGER.debug(FMLHSMARKER, "Accepted server connection");
|
||||
// Set the modded marker on the channel so we know we got packets
|
||||
c.get().getNetworkManager().channel().attr(FMLNetworking.FML_MARKER).set(NetworkHooks.NETVERSION);
|
||||
c.get().getNetworkManager().channel().attr(FMLNetworkConstants.FML_MARKER).set(FMLNetworkConstants.NETVERSION);
|
||||
this.registriesToReceive = new HashSet<>(serverModList.getRegistries());
|
||||
LOGGER.debug(REGISTRIES, "Expecting {} registries: {}", ()->this.registriesToReceive.size(), ()->this.registriesToReceive);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public class FMLLoginWrapper {
|
||||
wrapperChannel = NetworkRegistry.ChannelBuilder.named(FMLLoginWrapper.WRAPPER).
|
||||
clientAcceptedVersions(a->true).
|
||||
serverAcceptedVersions(a->true).
|
||||
networkProtocolVersion(()->NetworkHooks.NETVERSION)
|
||||
networkProtocolVersion(()-> FMLNetworkConstants.NETVERSION)
|
||||
.eventNetworkChannel();
|
||||
wrapperChannel.addListener(this::wrapperReceived);
|
||||
}
|
||||
|
||||
+8
-1
@@ -23,8 +23,15 @@ import io.netty.util.AttributeKey;
|
||||
import org.apache.logging.log4j.Marker;
|
||||
import org.apache.logging.log4j.MarkerManager;
|
||||
|
||||
public class FMLNetworking
|
||||
/**
|
||||
* Constants related to networking
|
||||
*/
|
||||
public class FMLNetworkConstants
|
||||
{
|
||||
public static final String FMLNETMARKER = "FML";
|
||||
public static final int FMLNETVERSION = 1;
|
||||
public static final String NETVERSION = FMLNETMARKER + FMLNETVERSION;
|
||||
public static final String NOVERSION = "NONE";
|
||||
static final Marker NETWORK = MarkerManager.getMarker("FMLNETWORK");
|
||||
static final AttributeKey<String> FML_MARKER = AttributeKey.valueOf("fml:marker");
|
||||
}
|
||||
@@ -28,7 +28,7 @@ public class FMLPlayHandler
|
||||
.named(new ResourceLocation("fml", "play"))
|
||||
.clientAcceptedVersions(a -> true)
|
||||
.serverAcceptedVersions(a -> true)
|
||||
.networkProtocolVersion(() -> NetworkHooks.NETVERSION)
|
||||
.networkProtocolVersion(() -> FMLNetworkConstants.NETVERSION)
|
||||
.simpleChannel();
|
||||
static
|
||||
{
|
||||
|
||||
@@ -44,22 +44,15 @@ import java.util.function.Supplier;
|
||||
public class NetworkHooks
|
||||
{
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final String NETVERSION = "FML1";
|
||||
public static final String NOVERSION = "NONE";
|
||||
|
||||
public static String getFMLVersion(final String ip)
|
||||
{
|
||||
return ip.contains("\0") ? Objects.equals(ip.split("\0")[1], NETVERSION) ? NETVERSION : ip.split("\0")[1] : NOVERSION;
|
||||
}
|
||||
|
||||
public static boolean accepts(final CPacketHandshake packet)
|
||||
{
|
||||
return Objects.equals(packet.getFMLVersion(), NETVERSION) || NetworkRegistry.acceptsVanillaClientConnections();
|
||||
return ip.contains("\0") ? Objects.equals(ip.split("\0")[1], FMLNetworkConstants.NETVERSION) ? FMLNetworkConstants.NETVERSION : ip.split("\0")[1] : FMLNetworkConstants.NOVERSION;
|
||||
}
|
||||
|
||||
public static ConnectionType getConnectionType(final Supplier<NetworkManager> connection)
|
||||
{
|
||||
return ConnectionType.forVersionFlag(connection.get().channel().attr(FMLNetworking.FML_MARKER).get());
|
||||
return ConnectionType.forVersionFlag(connection.get().channel().attr(FMLNetworkConstants.FML_MARKER).get());
|
||||
}
|
||||
|
||||
public static Packet<?> getEntitySpawningPacket(Entity entity)
|
||||
@@ -78,14 +71,14 @@ public class NetworkHooks
|
||||
|
||||
public static void registerServerLoginChannel(NetworkManager manager, CPacketHandshake packet)
|
||||
{
|
||||
manager.channel().attr(FMLNetworking.FML_MARKER).set(packet.getFMLVersion());
|
||||
manager.channel().attr(FMLNetworkConstants.FML_MARKER).set(packet.getFMLVersion());
|
||||
FMLHandshakeHandler.registerHandshake(manager, NetworkDirection.LOGIN_TO_CLIENT);
|
||||
}
|
||||
|
||||
public static void registerClientLoginChannel(NetworkManager manager)
|
||||
{
|
||||
if (manager == null || manager.channel() == null) return;
|
||||
manager.channel().attr(FMLNetworking.FML_MARKER).set(NOVERSION);
|
||||
manager.channel().attr(FMLNetworkConstants.FML_MARKER).set(FMLNetworkConstants.NOVERSION);
|
||||
FMLHandshakeHandler.registerHandshake(manager, NetworkDirection.LOGIN_TO_SERVER);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ public class NetworkRegistry
|
||||
return listRejectedVanillaMods(NetworkInstance::tryClientVersionOnServer);
|
||||
}
|
||||
|
||||
static boolean acceptsVanillaClientConnections() {
|
||||
public static boolean acceptsVanillaClientConnections() {
|
||||
return instances.isEmpty() || getNonVanillaNetworkMods().isEmpty();
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,10 @@ 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.FileUtils;
|
||||
import net.minecraftforge.fml.network.ConnectionType;
|
||||
import net.minecraftforge.fml.network.FMLNetworkConstants;
|
||||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
import net.minecraftforge.fml.network.NetworkRegistry;
|
||||
import net.minecraftforge.fml.packs.ResourcePackLoader;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
@@ -120,15 +123,19 @@ public class ServerLifecycleHooks
|
||||
return false;
|
||||
}
|
||||
|
||||
if (packet.getRequestedState() == EnumConnectionState.LOGIN && !NetworkHooks.accepts(packet))
|
||||
{
|
||||
manager.setConnectionState(EnumConnectionState.LOGIN);
|
||||
TextComponentString text = new TextComponentString("This server has mods that require Forge to be installed on the client. Contact your server admin for more details.");
|
||||
List<String> modNames = net.minecraftforge.fml.network.NetworkRegistry.getNonVanillaNetworkMods();
|
||||
LOGGER.info(SERVERHOOKS,"Disconnecting vanilla connection attempt. Required mods {}", modNames);
|
||||
manager.sendPacket(new SPacketDisconnectLogin(text));
|
||||
manager.closeChannel(text);
|
||||
return false;
|
||||
if (packet.getRequestedState() == EnumConnectionState.LOGIN) {
|
||||
final ConnectionType connectionType = ConnectionType.forVersionFlag(packet.getFMLVersion());
|
||||
final int versionNumber = connectionType.getFMLVersionNumber(packet.getFMLVersion());
|
||||
|
||||
if (connectionType == ConnectionType.MODDED && versionNumber != FMLNetworkConstants.FMLNETVERSION) {
|
||||
rejectConnection(manager, connectionType, "This modded server is not network compatible with your modded client. Please verify your Forge version closely matches the server. Got net version "+ versionNumber + " this server is net version "+FMLNetworkConstants.FMLNETVERSION);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (connectionType == ConnectionType.VANILLA && !NetworkRegistry.acceptsVanillaClientConnections()) {
|
||||
rejectConnection(manager, connectionType, "This server has mods that require Forge to be installed on the client. Contact your server admin for more details.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (packet.getRequestedState() == EnumConnectionState.STATUS) return true;
|
||||
@@ -138,6 +145,14 @@ public class ServerLifecycleHooks
|
||||
|
||||
}
|
||||
|
||||
private static void rejectConnection(final NetworkManager manager, ConnectionType type, String message) {
|
||||
manager.setConnectionState(EnumConnectionState.LOGIN);
|
||||
LOGGER.info(SERVERHOOKS, "Disconnecting {} connection attempt: ", type, message);
|
||||
TextComponentString text = new TextComponentString(message);
|
||||
manager.sendPacket(new SPacketDisconnectLogin(text));
|
||||
manager.closeChannel(text);
|
||||
}
|
||||
|
||||
public static void handleExit(int retVal)
|
||||
{
|
||||
/*
|
||||
|
||||
Reference in new issue
Block a user