ProtocolLib

3M Downloads

ChannelInboundHandlerAdapter not marked as sharable

Camotoy opened this issue ยท 0 comments

commented

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:

  1. Compile the inject branch of my Geyser fork.
  2. 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.