海绵我的世界服务器获取预留通道失败

Failed to get reserved channel on sponge minecraft server

我正在寻找在海绵 Minecraft 服务器上使用 MC|Brand 频道。

当我尝试使用时:

Sponge.getChannelRegistrar().getOrCreateRaw(plugin, channel).addListener((data, connection, side) -> {
    if(side == Type.CLIENT) {
        // do something
    }
});

我遇到了这个问题:

org.spongepowered.api.network.ChannelRegistrationException: Reserved channels cannot be registered by plugins
        at org.spongepowered.server.network.VanillaChannelRegistrar.validateChannel(VanillaChannelRegistrar.java:71) ~[VanillaChannelRegistrar.class:1.12.2-7.3.0]
        at org.spongepowered.server.network.VanillaChannelRegistrar.createRawChannel(VanillaChannelRegistrar.java:104) ~[VanillaChannelRegistrar.class:1.12.2-7.3.0]
        at org.spongepowered.api.network.ChannelRegistrar.getOrCreateRaw(ChannelRegistrar.java:122) ~[ChannelRegistrar.class:1.12.2-7.3.0]

我怎样才能修复它,只使用频道?是否有预留MC频道消息事件?

我尝试完全按照 Sponge 的方式注册频道,但没有检查导致问题。

为此,我使用 Java Reflection :

RawDataChannel spongeChannel = null; // declare channel
try {
    // firstly, try default channel registration to go faster
    spongeChannel = Sponge.getChannelRegistrar().getOrCreateRaw(plugin, channel);
} catch (ChannelRegistrationException e) { // error -> can't register
    try {
        // load class
        Class<?> vanillaRawChannelClass = Class.forName("org.spongepowered.server.network.VanillaRawDataChannel");
        Class<?> vanillaChannelRegistrarClass = Class.forName("org.spongepowered.server.network.VanillaChannelRegistrar");
        Class<?> vanillaBindingClass = Class.forName("org.spongepowered.server.network.VanillaChannelBinding");
        // get constructor of raw channel
        Constructor<?> rawChannelConstructor = vanillaRawChannelClass.getConstructor(ChannelRegistrar.class, String.class, PluginContainer.class);
        spongeChannel = (RawDataChannel) rawChannelConstructor.newInstance(Sponge.getChannelRegistrar(), channel, plugin.getContainer()); // new channel instance
        // now register channel
        Method registerChannel = vanillaChannelRegistrarClass.getDeclaredMethod("registerChannel", vanillaBindingClass); // get the method to register
        registerChannel.setAccessible(true); // it's a private method, so set as accessible
        registerChannel.invoke(Sponge.getChannelRegistrar(), spongeChannel); // run channel registration
    } catch (Exception exc) {
        exc.printStackTrace(); // reflection failed
    }
}
if(spongeChannel == null) // channel not registered
    return;
// my channel is now registered, by one of both available method. That's perfect
spongeChannel.addListener((data, connection, side) -> { // my listener
    if(side == Type.CLIENT) {
        // do something
    }
});;

如果已经有错误,特别是反射失败的时候,建议你检查新版本,可能是method改了参数或者class被移动了

您可以在 github.

上找到 Sponge 代码