ChannelInboundHandlerAdapter not marked as sharable
Camotoy opened this issue ยท 0 comments
I'm part of the Geyser team. I've been working on a method for Geyser to use a local Netty channel to join the Java server, instead of initializing a TCP connection from the plugin to the server. Our current code can be found here: https://github.com/Camotoy/Geyser/blob/inject/bootstrap/spigot/src/main/java/org/geysermc/platform/spigot/GeyserSpigotInjector.java
Describe the bug
In order to add the necessary pipeline injections that ProtocolLib adds, we need to add ourselves to the listeningChannels
list in ServerConnection
. ProtocolLib correctly bootstraps our ChannelFuture
object until it reaches this ChannelHandler
: https://github.com/dmulloy2/ProtocolLib/blob/master/src/main/java/com/comphenix/protocol/injector/netty/ProtocolInjector.java#L180, at which point our method fails:
[18:34:29 WARN]: io.netty.channel.ChannelPipelineException: com.comphenix.protocol.injector.netty.ProtocolInjector$3 is not a @Sharable handler, so can't be added or removed multiple times.
[18:34:29 WARN]: at io.netty.channel.DefaultChannelPipeline.checkMultiplicity(DefaultChannelPipeline.java:600)
[18:34:29 WARN]: at io.netty.channel.DefaultChannelPipeline.addFirst(DefaultChannelPipeline.java:159)
[18:34:29 WARN]: at io.netty.channel.DefaultChannelPipeline.addFirst(DefaultChannelPipeline.java:358)
[18:34:29 WARN]: at io.netty.channel.DefaultChannelPipeline.addFirst(DefaultChannelPipeline.java:339)
[18:34:29 WARN]: at com.comphenix.protocol.injector.netty.BootstrapList.processBootstrap(BootstrapList.java:105)
[18:34:29 WARN]: at com.comphenix.protocol.injector.netty.BootstrapList.processElement(BootstrapList.java:85)
[18:34:29 WARN]: at com.comphenix.protocol.injector.netty.BootstrapList.add(BootstrapList.java:52)
[18:34:29 WARN]: at org.geysermc.platform.spigot.GeyserSpigotInjector.initializeLocalChannel0(GeyserSpigotInjector.java:148)
[18:34:29 WARN]: at org.geysermc.connector.common.GeyserInjector.initializeLocalChannel(GeyserInjector.java:65)
[18:34:29 WARN]: at org.geysermc.platform.spigot.GeyserSpigotPlugin.onEnable(GeyserSpigotPlugin.java:171)
[18:34:29 WARN]: at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:263)
[18:34:29 WARN]: at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:364)
[18:34:29 WARN]: at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:483)
[18:34:29 WARN]: at org.bukkit.craftbukkit.v1_16_R3.CraftServer.enablePlugin(CraftServer.java:504)
[18:34:29 WARN]: at org.bukkit.craftbukkit.v1_16_R3.CraftServer.enablePlugins(CraftServer.java:418)
[18:34:29 WARN]: at net.minecraft.server.v1_16_R3.MinecraftServer.loadWorld(MinecraftServer.java:592)
[18:34:29 WARN]: at net.minecraft.server.v1_16_R3.DedicatedServer.init(DedicatedServer.java:281)
[18:34:29 WARN]: at net.minecraft.server.v1_16_R3.MinecraftServer.w(MinecraftServer.java:1066)
[18:34:29 WARN]: at net.minecraft.server.v1_16_R3.MinecraftServer.lambda$a$0(MinecraftServer.java:290)
[18:34:29 WARN]: at net.minecraft.server.v1_16_R3.MinecraftServer$$Lambda$3074/000000002D2AB480.run(Unknown Source)
[18:34:29 WARN]: at java.lang.Thread.run(Thread.java:821)
To Reproduce
Steps to reproduce the behavior:
- Compile the
inject
branch of my Geyser fork. - Run the Spigot plugin alongside ProtocolLib.
Proposed behavior
The only blocking thing here on ProtocolLib's end is the lack of the ChannelInboundHandlerAdapter not being marked as sharable. While this does appear to be an easy change, and I would be happy to PR it, I am still new to this level of Netty work so I'm not sure if there's a reason it shouldn't be.
Version Info
https://ci.dmulloy2.net/job/ProtocolLib/501/
ProtocolLib Dump
Timestamp: 05/22/21 18:40:38
ProtocolLib Version: ProtocolLib v4.6.1-SNAPSHOT-b501
Bukkit Version: 1.16.5-R0.1-SNAPSHOT
Server Version: git-Paper-691 (MC: 1.16.5)
Java Version: 1.8.0_252
ProtocolLib: com.comphenix.protocol.ProtocolLib@e7472ec9[
statistics=com.comphenix.protocol.metrics.Statistics@4c9ff161
backgroundCompiler=com.comphenix.protocol.reflect.compiler.BackgroundCompiler@4fe3f9ab
packetTask=2
tickCounter=7368
unhookTask=com.comphenix.protocol.injector.DelayedSingleTask@627cc6bf
configExpectedMod=1
updater=com.comphenix.protocol.updater.SpigotUpdater@7864704
redirectHandler=com.comphenix.protocol.ProtocolLib$2@16104a4
commandProtocol=com.comphenix.protocol.CommandProtocol@673eec8
commandPacket=com.comphenix.protocol.CommandPacket@3185fc9f
commandFilter=com.comphenix.protocol.CommandFilter@c599ecb9
packetLogging=com.comphenix.protocol.PacketLogging@61039919
skipDisable=false
isEnabled=true
loader=org.bukkit.plugin.java.JavaPluginLoader@a0603c85
server=CraftServer{serverName=Paper,serverVersion=git-Paper-691,minecraftVersion=1.16.5}
file=plugins/ProtocolLib.jar
description=org.bukkit.plugin.PluginDescriptionFile@ba02d157
dataFolder=plugins/ProtocolLib
classLoader=PluginClassLoader{plugin=ProtocolLib v4.6.1-SNAPSHOT-b501, pluginEnabled=true, url=plugins/ProtocolLib.jar}
naggable=true
newConfig=YamlConfiguration[path='', root='YamlConfiguration']
configFile=plugins/ProtocolLib/config.yml
logger=com.destroystokyo.paper.utils.PaperPluginLogger@c3da4c42
]
Manager: com.comphenix.protocol.injector.PacketFilterManager@20033c45[
unhookTask=com.comphenix.protocol.injector.DelayedSingleTask@627cc6bf
packetListeners=[]
packetInjector=com.comphenix.protocol.injector.netty.ProtocolInjector$5@124775e
playerInjection=com.comphenix.protocol.injector.netty.ProtocolInjector$4@89457810
inputBufferedPackets=[]
recievedListeners=com.comphenix.protocol.injector.SortedPacketListenerList@cfed715c
sendingListeners=com.comphenix.protocol.injector.SortedPacketListenerList@67d8647f
hasClosed=false
classLoader=PluginClassLoader{plugin=ProtocolLib v4.6.1-SNAPSHOT-b501, pluginEnabled=true, url=plugins/ProtocolLib.jar}
reporter=com.comphenix.protocol.ProtocolLib$1@876c7c32
server=CraftServer{serverName=Paper,serverVersion=git-Paper-691,minecraftVersion=1.16.5}
library=ProtocolLib v4.6.1-SNAPSHOT-b501
asyncFilterManager=com.comphenix.protocol.async.AsyncFilterManager@11ce1879
knowsServerPackets=true
knowsClientPackets=true
phaseLoginCount=0
phasePlayingCount=0
packetCreation=false
nettyInjector=com.comphenix.protocol.injector.netty.ProtocolInjector@a8a41c03
pluginVerifier=com.comphenix.protocol.injector.PluginVerifier@13dd1c69
hasRecycleDistance=true
minecraftVersion=(MC: 1.16.5)
debug=false
]
No listeners
Additional context
This isn't necessary for ProtocolLib to do - and worst case Geyser can check for ProtocolLib and not implement "direct injection" - but, as ProtocolLib is a popular plugin, I would be rather grateful.
Additionally, if there is a different, better way to solve this issue, I am all ears.