You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Minecraft Forge 1.12.2
1 Velocity Serer
Multi paper backend servers
Introduction
Bukkit Server cannot send any message to client after server switching.
PlayerRegisterChannelEvent not called after server switching
Mininal Reproduction
Write one mod that reciving custom message and only System.out.println it
Write one bukkit plugin that register plugin message with one command to send plugin message
Startup 2 1.12.2 paper server
Login to velocity, and execute /server myserver2
Execute the /myplugin:sendpluginmessage, nothing printed in minecraft client
Analyzing
FML 1.12.2 will register and only register mod outgoing channels durning connection initialization. When server switching happen, Forge will not send registered channels again.
Velocity need to handle it and send it to backend manually.
/* * Minecraft Forge * Copyright (c) 2016-2020. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation version 2.1 * of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */packagenet.minecraftforge.fml.common.network.handshake;
importio.netty.channel.ChannelFutureListener;
importio.netty.channel.ChannelHandlerContext;
importjava.util.Map;
importjava.util.function.Consumer;
importcom.google.common.collect.Maps;
importcom.google.common.collect.Multimap;
importcom.google.common.util.concurrent.Futures;
importnet.minecraft.client.Minecraft;
importnet.minecraft.util.ResourceLocation;
importnet.minecraftforge.fml.common.FMLLog;
importnet.minecraftforge.fml.common.Loader;
importnet.minecraftforge.fml.common.network.NetworkRegistry;
importnet.minecraftforge.fml.common.network.handshake.FMLHandshakeMessage.ServerHello;
importnet.minecraftforge.fml.common.network.internal.FMLMessage;
importnet.minecraftforge.fml.common.network.internal.FMLNetworkHandler;
importnet.minecraftforge.fml.relauncher.Side;
importnet.minecraftforge.registries.ForgeRegistry;
importnet.minecraftforge.registries.GameData;
/** * Packet handshake sequence manager- client side (responding to remote server) * * Flow: * 1. Wait for server hello. (START). Move to HELLO state. * 2. Receive Server Hello. Send customchannel registration. Send Client Hello. Send our modlist. Move to WAITINGFORSERVERDATA state. * 3. Receive server modlist. Send ack if acceptable, else send nack and exit error. Receive server IDs. Move to COMPLETE state. Send ack. * * @author cpw * */enumFMLHandshakeClientStateimplementsIHandshakeState<FMLHandshakeClientState>
{
START
{
@Overridepublicvoidaccept(ChannelHandlerContextctx, FMLHandshakeMessagemsg, Consumer<? superFMLHandshakeClientState> cons)
{
cons.accept(HELLO);
NetworkDispatcherdispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
dispatcher.clientListenForServerHandshake();
}
},
HELLO
{
@Overridepublicvoidaccept(ChannelHandlerContextctx, FMLHandshakeMessagemsg, Consumer<? superFMLHandshakeClientState> cons)
{
booleanisVanilla = msg == null;
if (isVanilla)
{
cons.accept(DONE);
}
else
{
cons.accept(WAITINGSERVERDATA);
}
/////////////////////////////////////////////// HERE/////////////////////////////////////////////// write our custom packet registration, alwaysctx.writeAndFlush(FMLHandshakeMessage.makeCustomChannelRegistration(NetworkRegistry.INSTANCE.channelNamesFor(Side.CLIENT)));
if (isVanilla)
{
NetworkDispatcherdispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
dispatcher.abortClientHandshake("VANILLA");
// VANILLA loginreturn;
}
ServerHelloserverHelloPacket = (FMLHandshakeMessage.ServerHello)msg;
FMLLog.log.info("Server protocol version {}", Integer.toHexString(serverHelloPacket.protocolVersion()));
if (serverHelloPacket.protocolVersion() > 1)
{
// Server sent us an extra dimension for the logging in player - stash it for retrieval laterNetworkDispatcherdispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get();
dispatcher.setOverrideDimension(serverHelloPacket.overrideDim());
}
ctx.writeAndFlush(newFMLHandshakeMessage.ClientHello()).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
ctx.writeAndFlush(newFMLHandshakeMessage.ModList(Loader.instance().getActiveModList())).addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE);
}
},
Addition
PlayerRegsiterChannelEvent is triggered by REGISTER message from player.
sendPluginMessage is require channel was registered by player.
CraftPlayer.java
@OverridepublicvoidsendPluginMessage(Pluginsource, Stringchannel, byte[] message) {
StandardMessenger.validatePluginMessage(server.getMessenger(), source, channel, message);
if (getHandle().playerConnection == null) return;
if (channels.contains(channel)) {
PacketPlayOutCustomPayloadpacket = newPacketPlayOutCustomPayload(channel, newPacketDataSerializer(Unpooled.wrappedBuffer(message)));
getHandle().playerConnection.sendPacket(packet);
}
}
publicvoidaddChannel(Stringchannel) {
com.google.common.base.Preconditions.checkState(DISABLE_CHANNEL_LIMIT || channels.size() < 128, "Too many channels registered"); // Spigot // Paper - flag to disable channel limitif (channels.add(channel)) {
server.getPluginManager().callEvent(newPlayerRegisterChannelEvent(this, channel));
}
}
Base Environment
Introduction
Mininal Reproduction
/server myserver2
/myplugin:sendpluginmessage
, nothing printed in minecraft clientAnalyzing
FML 1.12.2 will register and only register mod outgoing channels durning connection initialization. When server switching happen, Forge will not send registered channels again.
Velocity need to handle it and send it to backend manually.
Addition
REGISTER
message from player.sendPluginMessage
is require channel was registered by player.CraftPlayer.java
Releated
#591
#1068
The text was updated successfully, but these errors were encountered: