From e008eb8a13390e01d153220dd025c9584c5b562c Mon Sep 17 00:00:00 2001 From: s809 <43530948+s809@users.noreply.github.com> Date: Thu, 14 Mar 2024 21:46:23 +0500 Subject: [PATCH] Server side plugin networking Untested port for Forge --- .../api/internal/ClientPluginChannelApi.java | 8 +++- .../core/api/internal/ServerApi.java | 16 +++++--- .../server/RemotePlayerConnectionHandler.java | 40 ++++++++++++------- .../network/plugin/PluginChannelHandler.java | 9 +++-- .../network/plugin/PluginChannelMessage.java | 3 +- .../core/world/DhServerWorld.java | 11 +++-- 6 files changed, 58 insertions(+), 29 deletions(-) diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientPluginChannelApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientPluginChannelApi.java index 98192e6b4..1aee06fbf 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientPluginChannelApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ClientPluginChannelApi.java @@ -11,9 +11,11 @@ import com.seibel.distanthorizons.core.network.messages.plugin.PluginHelloMessag import com.seibel.distanthorizons.core.network.messages.plugin.ServerConnectInfoMessage; import com.seibel.distanthorizons.core.network.plugin.PluginChannelHandler; import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; +import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper; import io.netty.buffer.ByteBuf; import org.apache.logging.log4j.LogManager; +import org.jetbrains.annotations.Nullable; import java.util.function.Consumer; @@ -91,7 +93,11 @@ public class ClientPluginChannelApi implements AutoCloseable public void handlePacket(ByteBuf buffer) { - this.channelHandler.decodeAndHandle(buffer); + this.handlePacket(null, buffer); + } + public void handlePacket(@Nullable IServerPlayerWrapper serverPlayer, ByteBuf buffer) + { + this.channelHandler.decodeAndHandle(serverPlayer, buffer); } @Override diff --git a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ServerApi.java b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ServerApi.java index b3c60773a..f1163db28 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ServerApi.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/api/internal/ServerApi.java @@ -36,13 +36,9 @@ import com.seibel.distanthorizons.core.logging.DhLoggerBuilder; import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper; +import io.netty.buffer.ByteBuf; import org.apache.logging.log4j.Logger; -import java.util.ArrayList; -import java.util.LinkedList; -import java.util.List; -import java.util.concurrent.ThreadPoolExecutor; - /** * This holds the methods that should be called by the host mod loader (Fabric, * Forge, etc.). Specifically server events. @@ -182,4 +178,14 @@ public class ServerApi } } + public void pluginMessageReceived(IServerPlayerWrapper player, ByteBuf buffer) + { + IDhServerWorld serverWorld = SharedApi.getIDhServerWorld(); + if (serverWorld instanceof DhServerWorld) // TODO add support for DhClientServerWorld's (lan worlds) as well + { + LOGGER.debug("Player " + player.getUUID() + " sent plugin message: " + buffer.toString()); + ((DhServerWorld) serverWorld).handlePluginMessage(player, buffer); + } + } + } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/server/RemotePlayerConnectionHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/server/RemotePlayerConnectionHandler.java index 026186162..d35cb5f05 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/server/RemotePlayerConnectionHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/server/RemotePlayerConnectionHandler.java @@ -8,9 +8,9 @@ import com.seibel.distanthorizons.core.config.types.ConfigEntry; import com.seibel.distanthorizons.core.level.DhServerLevel; import com.seibel.distanthorizons.core.multiplayer.config.MultiplayerConfig; import com.seibel.distanthorizons.core.multiplayer.config.MultiplayerConfigChangeListener; +import com.seibel.distanthorizons.core.network.messages.plugin.PluginHelloMessage; import com.seibel.distanthorizons.core.network.netty.INettyConnection; import com.seibel.distanthorizons.core.network.netty.NettyServer; -import com.seibel.distanthorizons.core.network.ScopedNetworkEventSource; import com.seibel.distanthorizons.core.network.exceptions.InvalidLevelException; import com.seibel.distanthorizons.core.network.messages.netty.base.AckMessage; import com.seibel.distanthorizons.core.network.messages.netty.base.NettyCloseEvent; @@ -19,8 +19,10 @@ import com.seibel.distanthorizons.core.network.messages.netty.session.PlayerUUID import com.seibel.distanthorizons.core.network.messages.netty.session.RemotePlayerConfigMessage; import com.seibel.distanthorizons.core.network.netty.TrackableNettyMessage; import com.seibel.distanthorizons.core.network.netty.NettyMessage; +import com.seibel.distanthorizons.core.network.plugin.PluginChannelHandler; import com.seibel.distanthorizons.core.util.LodUtil; import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper; +import io.netty.buffer.ByteBuf; import org.jetbrains.annotations.Nullable; import java.io.Closeable; @@ -34,23 +36,20 @@ public class RemotePlayerConnectionHandler implements Closeable { private static final ConfigEntry GENERATE_MULTIPLE_DIMENSIONS_CONFIG = Config.Client.Advanced.Multiplayer.ServerNetworking.generateMultipleDimensions; - private final ScopedNetworkEventSource eventSource; + private final NettyServer server = new NettyServer(Config.Client.Advanced.Multiplayer.ServerNetworking.serverPort.get()); private final ConcurrentHashMap playersByUUID = new ConcurrentHashMap<>(); private final BiMap playersByConnection = Maps.synchronizedBiMap(HashBiMap.create()); - private final MultiplayerConfigChangeListener configChangeListener = new MultiplayerConfigChangeListener(this::onConfigChanged); - public NettyServer server() { return this.eventSource.parent; } + private final PluginChannelHandler pluginChannelHandler = new PluginChannelHandler(); + // TODO port change listener - public RemotePlayerConnectionHandler(NettyServer nettyServer) - { - this.eventSource = new ScopedNetworkEventSource<>(nettyServer); - this.registerNetworkHandlers(); - } + public NettyServer server() { return this.server; } - private void registerNetworkHandlers() + public RemotePlayerConnectionHandler() { - this.eventSource.registerHandler(PlayerUUIDMessage.class, playerUUIDMessage -> + //region Netty server + this.server.registerHandler(PlayerUUIDMessage.class, playerUUIDMessage -> { INettyConnection connection = playerUUIDMessage.getConnection(); ServerPlayerState serverPlayerState = this.playersByUUID.get(playerUUIDMessage.playerUUID); @@ -73,13 +72,13 @@ public class RemotePlayerConnectionHandler implements Closeable playerUUIDMessage.sendResponse(new AckMessage()); }); - this.eventSource.registerHandler(RemotePlayerConfigMessage.class, this.connectedPlayersOnly((remotePlayerConfigMessage, serverPlayerState) -> + this.server.registerHandler(RemotePlayerConfigMessage.class, this.connectedPlayersOnly((remotePlayerConfigMessage, serverPlayerState) -> { serverPlayerState.config.clientConfig = (MultiplayerConfig) remotePlayerConfigMessage.payload; serverPlayerState.connection.sendMessage(new RemotePlayerConfigMessage(serverPlayerState.config)); })); - this.eventSource.registerHandler(NettyCloseEvent.class, closeEvent -> + this.server.registerHandler(NettyCloseEvent.class, closeEvent -> { ServerPlayerState dhPlayer = this.playersByConnection.remove(closeEvent.getConnection()); if (dhPlayer != null) @@ -87,6 +86,19 @@ public class RemotePlayerConnectionHandler implements Closeable dhPlayer.connection = null; } }); + //endregion + + //region Plugin channel + this.pluginChannelHandler.registerHandler(PluginHelloMessage.class, msg -> { + // TODO tell to connect somewhere + int i = 0; + }); + //endregion + } + + public void handlePluginMessage(IServerPlayerWrapper player, ByteBuf buffer) + { + this.pluginChannelHandler.decodeAndHandle(player, buffer); } private void onConfigChanged() @@ -171,7 +183,7 @@ public class RemotePlayerConnectionHandler implements Closeable public void close() { this.configChangeListener.close(); - this.eventSource.close(); + this.pluginChannelHandler.close(); this.server().close(); } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/network/plugin/PluginChannelHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/network/plugin/PluginChannelHandler.java index a7c5705f3..b8c48a15d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/network/plugin/PluginChannelHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/network/plugin/PluginChannelHandler.java @@ -41,7 +41,7 @@ public class PluginChannelHandler extends NetworkEventSource messages = new ArrayList<>(); this.messageDecoder.decode(byteBuf, messages); - for (Object msg : messages) + for (Object msgObj : messages) { - this.handleMessage((PluginChannelMessage) msg); + PluginChannelMessage msg = (PluginChannelMessage) msgObj; + msg.serverPlayer = serverPlayer; + this.handleMessage(msg); } } catch (Throwable e) @@ -73,7 +75,6 @@ public class PluginChannelHandler extends NetworkEventSource levels; public final LocalSaveStructure saveStructure; + private final RemotePlayerConnectionHandler remotePlayerConnectionHandler; @@ -52,8 +52,7 @@ public class DhServerWorld extends AbstractDhWorld implements IDhServerWorld this.saveStructure = new LocalSaveStructure(); this.levels = new HashMap<>(); - NettyServer nettyServer = new NettyServer(Config.Client.Advanced.Multiplayer.ServerNetworking.serverPort.get()); - this.remotePlayerConnectionHandler = new RemotePlayerConnectionHandler(nettyServer); + this.remotePlayerConnectionHandler = new RemotePlayerConnectionHandler(); LOGGER.info("Started "+DhServerWorld.class.getSimpleName()+" of type "+this.environment); } @@ -79,6 +78,10 @@ public class DhServerWorld extends AbstractDhWorld implements IDhServerWorld this.getLevel(dest).addPlayer(player); this.getLevel(origin).removePlayer(player); } + public void handlePluginMessage(IServerPlayerWrapper player, ByteBuf buffer) + { + this.remotePlayerConnectionHandler.handlePluginMessage(player, buffer); + } @Override public DhServerLevel getOrLoadLevel(@NotNull ILevelWrapper wrapper)