0

I'm looking for using MC|Brand channel on a sponge minecraft server.

When i'm trying to use :

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

I'm getting this issue:

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]

How can I fix it, just by using channel ? Is there an event for reserved MC channel message ?

Elikill58
  • 4,050
  • 24
  • 23
  • 45

1 Answers1

0

I tried to register the channel exactly as Sponge does, but without the check that create the issue.

To do it, I use Java Reflection like that :

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

If there already have an error, specially when the reflection failed, I suggest you to check for new version, maybe method have change her parameter or class have been moved.

You can find Sponge code on their github.

Elikill58
  • 4,050
  • 24
  • 23
  • 45