首页 > 解决方案 > 海绵我的世界服务器获取预留频道失败

问题描述

我正在寻找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]

我该如何解决它,只需使用 channel ?是否有保留 MC 频道消息的事件?

标签: javaminecraftspongeapi

解决方案


我尝试像 Sponge 一样注册频道,但没有检查导致问题。

为此,我像这样使用Java 反射

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
    }
});;

如果已经有错误,特别是反射失败时,建议你检查新版本,可能方法改变了她的参数或类被移动了。

你可以在他们的github上找到 Sponge 代码。


推荐阅读