Workaround for modded attributes on vanilla entities logging warnings on vanilla clients
Switch to a handler-based approach per packet class, simplify patch, add some docs Add license header and docs Switch to a network handler based approach Switch to a network handler based approach revert build gradle change Simplify Packet patch Add license header to IForgePacket Revert ForgeHooks changes Less hacky and more generic way to filter packets for vanilla connections _Actually_ Order SAS. It's early Order SAS simplify vanilla connection check Remove unneeded import change
This commit is contained in:
parent
5a7facc20f
commit
acd18455c2
5 changed files with 124 additions and 3 deletions
|
@ -27,7 +27,8 @@ public enum ConnectionType
|
|||
|
||||
private final Function<String, Integer> versionExtractor;
|
||||
|
||||
ConnectionType(Function<String, Integer> versionExtractor) {
|
||||
ConnectionType(Function<String, Integer> versionExtractor)
|
||||
{
|
||||
this.versionExtractor = versionExtractor;
|
||||
}
|
||||
|
||||
|
@ -36,7 +37,14 @@ public enum ConnectionType
|
|||
return vers.startsWith(FMLNetworkConstants.FMLNETMARKER) ? MODDED : VANILLA;
|
||||
}
|
||||
|
||||
public int getFMLVersionNumber(final String fmlVersion) {
|
||||
public int getFMLVersionNumber(final String fmlVersion)
|
||||
{
|
||||
return versionExtractor.apply(fmlVersion);
|
||||
}
|
||||
|
||||
public boolean isVanilla()
|
||||
{
|
||||
return this == VANILLA;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -27,6 +27,8 @@ import java.util.function.Consumer;
|
|||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import net.minecraft.tags.ITagCollection;
|
||||
import net.minecraft.tags.ITagCollectionSupplier;
|
||||
import net.minecraft.util.text.StringTextComponent;
|
||||
|
@ -62,7 +64,17 @@ public class NetworkHooks
|
|||
|
||||
public static ConnectionType getConnectionType(final Supplier<NetworkManager> connection)
|
||||
{
|
||||
return ConnectionType.forVersionFlag(connection.get().channel().attr(FMLNetworkConstants.FML_NETVERSION).get());
|
||||
return getConnectionType(connection.get().channel());
|
||||
}
|
||||
|
||||
public static ConnectionType getConnectionType(ChannelHandlerContext context)
|
||||
{
|
||||
return getConnectionType(context.channel());
|
||||
}
|
||||
|
||||
private static ConnectionType getConnectionType(Channel channel)
|
||||
{
|
||||
return ConnectionType.forVersionFlag(channel.attr(FMLNetworkConstants.FML_NETVERSION).get());
|
||||
}
|
||||
|
||||
public static IPacket<?> getEntitySpawningPacket(Entity entity)
|
||||
|
|
|
@ -68,6 +68,7 @@ import net.minecraftforge.fml.loading.moddiscovery.ModFile;
|
|||
import net.minecraftforge.fml.packs.ModFileResourcePack;
|
||||
import net.minecraftforge.fml.packs.ResourcePackLoader;
|
||||
import net.minecraftforge.forgespi.language.IModInfo;
|
||||
import net.minecraftforge.network.VanillaConnectionNetworkFilter;
|
||||
import net.minecraftforge.registries.GameData;
|
||||
|
||||
public class ServerLifecycleHooks
|
||||
|
@ -168,6 +169,7 @@ public class ServerLifecycleHooks
|
|||
if (packet.getRequestedState() == ProtocolType.STATUS) return true;
|
||||
|
||||
NetworkHooks.registerServerLoginChannel(manager, packet);
|
||||
VanillaConnectionNetworkFilter.injectIfNecessary(manager);
|
||||
return true;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Minecraft Forge
|
||||
* Copyright (c) 2016-2020.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation version 2.1
|
||||
* of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
package net.minecraftforge.network;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.handler.codec.MessageToMessageEncoder;
|
||||
import net.minecraft.network.IPacket;
|
||||
import net.minecraft.network.NetworkManager;
|
||||
import net.minecraft.network.play.server.SEntityPropertiesPacket;
|
||||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.fml.network.NetworkHooks;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
|
||||
/**
|
||||
* A filter for network packets, used to filter/modify parts of vanilla network messages that
|
||||
* will cause errors or warnings on vanilla clients, for example entity attributes that are added by Forge or mods.
|
||||
*/
|
||||
public class VanillaConnectionNetworkFilter extends MessageToMessageEncoder<IPacket<?>>
|
||||
{
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
private static final Map<Class<? extends IPacket<?>>, Function<IPacket<?>, ? extends IPacket<?>>> handlers = ImmutableMap.<Class<? extends IPacket<?>>, Function<IPacket<?>, ? extends IPacket<?>>>builder()
|
||||
.put(handler(SEntityPropertiesPacket.class, VanillaConnectionNetworkFilter::filterEntityProperties))
|
||||
.build();
|
||||
|
||||
|
||||
public static void injectIfNecessary(NetworkManager manager)
|
||||
{
|
||||
if (NetworkHooks.isVanillaConnection(manager))
|
||||
{
|
||||
manager.channel().pipeline().addBefore("packet_handler", "forge:vanilla_filter", new VanillaConnectionNetworkFilter());
|
||||
LOGGER.debug("Injected into {}", manager);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper function for building the handler map.
|
||||
*/
|
||||
@Nonnull
|
||||
private static <T extends IPacket<?>> Map.Entry<Class<? extends IPacket<?>>, Function<IPacket<?>, ? extends IPacket<?>>> handler(Class<T> cls, Function<T, ? extends IPacket<?>> function)
|
||||
{
|
||||
return new AbstractMap.SimpleEntry<>(cls, function.compose(cls::cast));
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter for SEntityPropertiesPacket. Filters out any entity attributes that are not in the "minecraft" namespace.
|
||||
* A vanilla client would ignore these with an error log.
|
||||
*/
|
||||
@Nonnull
|
||||
private static SEntityPropertiesPacket filterEntityProperties(SEntityPropertiesPacket msg)
|
||||
{
|
||||
SEntityPropertiesPacket newPacket = new SEntityPropertiesPacket();
|
||||
msg.getSnapshots().stream()
|
||||
.filter(snapshot -> {
|
||||
ResourceLocation key = ForgeRegistries.ATTRIBUTES.getKey(snapshot.func_240834_a_());
|
||||
return key != null && key.getNamespace().equals("minecraft");
|
||||
})
|
||||
.forEach(snapshot -> newPacket.getSnapshots().add(snapshot));
|
||||
return newPacket;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void encode(ChannelHandlerContext ctx, IPacket<?> msg, List<Object> out)
|
||||
{
|
||||
Function<IPacket<?>, ? extends IPacket<?>> function = handlers.getOrDefault(msg.getClass(), Function.identity());
|
||||
out.add(function.apply(msg));
|
||||
}
|
||||
}
|
|
@ -74,6 +74,7 @@ net/minecraft/item/crafting/IRecipe func_193358_e()Ljava/lang/String; # getGroup
|
|||
net/minecraft/item/crafting/SingleItemRecipe func_193358_e()Ljava/lang/String;
|
||||
net/minecraft/nbt/CompressedStreamTools func_74797_a(Ljava/io/File;)Lnet/minecraft/nbt/CompoundNBT; # read
|
||||
net/minecraft/nbt/CompressedStreamTools func_74795_b(Lnet/minecraft/nbt/CompoundNBT;Ljava/io/File;)V # write
|
||||
net/minecraft/network/play/server/SEntityPropertiesPacket func_149441_d()Ljava/util/List; # getSnapshots
|
||||
net/minecraft/potion/Effect func_220303_e()Lnet/minecraft/potion/EffectType; # getEffectType
|
||||
net/minecraft/potion/Effect func_111186_k()Ljava/util/Map; # getAttributeModifierMap
|
||||
net/minecraft/potion/Effect func_188408_i()Z # isBeneficial
|
||||
|
|
Loading…
Reference in a new issue