From d325a69e3f725b24d00ddffebf17c146877c424e Mon Sep 17 00:00:00 2001 From: s809 <43530948+s809@users.noreply.github.com> Date: Thu, 21 Sep 2023 10:16:34 +0500 Subject: [PATCH] Move context levels to requests --- .../WorldRemoteGenerationQueue.java | 2 +- .../core/level/DhServerLevel.java | 49 +++---------------- .../RemotePlayerConnectionHandler.java | 28 +++++++++++ .../messages/base/ILevelRelatedMessage.java | 41 ++++++++++++++++ .../FullDataSourceRequestMessage.java | 21 +++++--- .../FullDataSourceResponseMessage.java | 14 +----- .../FullDataChangeSummaryRequestMessage.java | 9 ++-- .../updates/FullDataPartialUpdateMessage.java | 10 ++-- 8 files changed, 102 insertions(+), 72 deletions(-) create mode 100644 core/src/main/java/com/seibel/distanthorizons/core/network/messages/base/ILevelRelatedMessage.java diff --git a/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldRemoteGenerationQueue.java b/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldRemoteGenerationQueue.java index cb1fb2c55..fdb7a3d12 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldRemoteGenerationQueue.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/generation/WorldRemoteGenerationQueue.java @@ -164,7 +164,7 @@ public class WorldRemoteGenerationQueue implements IWorldGenerationQueue, IDebug DhSectionPos sectionPos = mapEntry.getKey(); WorldGenQueueEntry entry = mapEntry.getValue(); - CompletableFuture request = this.networkState.getClient().sendRequest(new FullDataSourceRequestMessage(sectionPos), FullDataSourceResponseMessage.class); + CompletableFuture request = this.networkState.getClient().sendRequest(new FullDataSourceRequestMessage(level.getLevelWrapper(), sectionPos), FullDataSourceResponseMessage.class); entry.request = request; request.handleAsync((response, throwable) -> { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java b/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java index eba0de788..bc75fdd5e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/level/DhServerLevel.java @@ -92,28 +92,12 @@ public class DhServerLevel extends DhLevel implements IDhServerLevel private void registerNetworkHandlers() { - // TODO implement transparent message handling restriction by level - // workaround: -// ServerPlayerState serverPlayerState = remotePlayerConnectionHandler.getConnectedPlayer(msg); -// if (serverPlayerState == null) return; -// -// if (serverPlayerState.serverPlayer.getLevel() != this.serverLevelWrapper) -// return; - - this.eventSource.registerHandler(FullDataSourceRequestMessage.class, msg -> + this.eventSource.registerHandler(FullDataSourceRequestMessage.class, remotePlayerConnectionHandler.currentLevelOnly(this, (msg, serverPlayerState) -> { - ServerPlayerState serverPlayerState = remotePlayerConnectionHandler.getConnectedPlayer(msg); - if (serverPlayerState == null) return; - - if (serverPlayerState.serverPlayer.getLevel() != this.serverLevelWrapper) - return; - - LOGGER.debug("FullDataSourceRequestMessage received at pos ({}, {}) with detail level {}", msg.dhSectionPos.getX(), msg.dhSectionPos.getZ(), msg.dhSectionPos.getDetailLevel()); - if (serverPlayerState.pendingFullDataRequests.incrementAndGet() > rateLimitConfig.get()) { serverPlayerState.pendingFullDataRequests.decrementAndGet(); - msg.sendResponse(new RateLimitedException("Max concurrent requests: "+rateLimitConfig.get())); + msg.sendResponse(new RateLimitedException("Max concurrent requests: " + rateLimitConfig.get())); return; } @@ -135,34 +119,17 @@ public class DhServerLevel extends DhLevel implements IDhServerLevel break; } } - }); + })); - this.eventSource.registerHandler(GenTaskPriorityRequestMessage.class, msg -> { - ServerPlayerState serverPlayerState = remotePlayerConnectionHandler.getConnectedPlayer(msg); - if (serverPlayerState == null) return; - - if (serverPlayerState.serverPlayer.getLevel() != this.serverLevelWrapper) - return; - + this.eventSource.registerHandler(GenTaskPriorityRequestMessage.class, remotePlayerConnectionHandler.currentLevelOnly(this, (msg, serverPlayerState) -> + { msg.sendResponse(new GenTaskPriorityResponseMessage( this.serverside.dataFileHandler.getLoadStates(msg.posList) )); - }); + })); - this.eventSource.registerHandler(FullDataChangeSummaryRequestMessage.class, msg -> + this.eventSource.registerHandler(FullDataChangeSummaryRequestMessage.class, remotePlayerConnectionHandler.currentLevelOnly(this, (msg, serverPlayerState) -> { - ServerPlayerState serverPlayerState = remotePlayerConnectionHandler.getConnectedPlayer(msg); - if (serverPlayerState == null) return; - - if (serverPlayerState.serverPlayer.getLevel() != this.serverLevelWrapper) - return; - - if (!msg.isLevelValid(this.serverLevelWrapper)) - { - msg.sendResponse(new InvalidLevelException("Invalid level")); - return; - } - // Load files and check checksums HashSet changedPosList = new HashSet<>(); for (Map.Entry entry : msg.checksums.entrySet()) @@ -179,7 +146,7 @@ public class DhServerLevel extends DhLevel implements IDhServerLevel } msg.sendResponse(new FullDataChangeSummaryResponseMessage(changedPosList)); - }); + })); this.eventSource.registerHandler(CancelMessage.class, msg -> { diff --git a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/RemotePlayerConnectionHandler.java b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/RemotePlayerConnectionHandler.java index d5f0bc14d..09a0b11db 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/RemotePlayerConnectionHandler.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/multiplayer/RemotePlayerConnectionHandler.java @@ -2,8 +2,10 @@ package com.seibel.distanthorizons.core.multiplayer; import com.google.common.collect.BiMap; import com.google.common.collect.HashBiMap; +import com.seibel.distanthorizons.core.level.DhServerLevel; import com.seibel.distanthorizons.core.network.ScopedNetworkEventSource; import com.seibel.distanthorizons.core.network.NetworkServer; +import com.seibel.distanthorizons.core.network.messages.base.ILevelRelatedMessage; import com.seibel.distanthorizons.core.network.messages.base.AckMessage; import com.seibel.distanthorizons.core.network.messages.base.CloseEvent; import com.seibel.distanthorizons.core.network.messages.session.PlayerUUIDMessage; @@ -15,6 +17,8 @@ import org.jetbrains.annotations.Nullable; import java.io.Closeable; import java.util.HashMap; import java.util.UUID; +import java.util.function.BiConsumer; +import java.util.function.Consumer; public class RemotePlayerConnectionHandler implements Closeable { @@ -65,6 +69,30 @@ public class RemotePlayerConnectionHandler implements Closeable }); } + public Consumer connectedPlayersOnly(BiConsumer next) + { + return msg -> + { + ServerPlayerState serverPlayerState = getConnectedPlayer(msg); + if (serverPlayerState != null) + next.accept(msg, serverPlayerState); + }; + } + + public Consumer currentLevelOnly(DhServerLevel level, BiConsumer next) + { + return connectedPlayersOnly((msg, serverPlayerState) -> + { + if (serverPlayerState.serverPlayer.getLevel() != level.getLevelWrapper()) + return; + + if (msg instanceof ILevelRelatedMessage && ((ILevelRelatedMessage) msg).sendExceptionIfLevelInvalid(level.getLevelWrapper())) + return; + + next.accept(msg, serverPlayerState); + }); + } + public Iterable getConnectedPlayers() { return playersByConnection.values(); diff --git a/core/src/main/java/com/seibel/distanthorizons/core/network/messages/base/ILevelRelatedMessage.java b/core/src/main/java/com/seibel/distanthorizons/core/network/messages/base/ILevelRelatedMessage.java new file mode 100644 index 000000000..8ba15e42d --- /dev/null +++ b/core/src/main/java/com/seibel/distanthorizons/core/network/messages/base/ILevelRelatedMessage.java @@ -0,0 +1,41 @@ +package com.seibel.distanthorizons.core.network.messages.base; + +import com.seibel.distanthorizons.core.network.exceptions.InvalidLevelException; +import com.seibel.distanthorizons.core.network.protocol.FutureTrackableNetworkMessage; +import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; + +public interface ILevelRelatedMessage +{ + int getLevelHashCode(); + + /** + * Returns true if level does not match the given level. + * + * @param levelWrapper Level wrapper to check against. + * @return Whether the level is invalid. + */ + default boolean isLevelInvalid(ILevelWrapper levelWrapper) + { + return levelWrapper.getDimensionType().getDimensionName().hashCode() != getLevelHashCode(); + } + + /** + * Same as {@link #isLevelInvalid}. + * If current message implements {@link FutureTrackableNetworkMessage}, additionally sends an exception response if given wrapper does not match. + * + * @param levelWrapper Level wrapper to check against. + * @return Whether the level is invalid. + */ + default boolean sendExceptionIfLevelInvalid(ILevelWrapper levelWrapper) + { + if (isLevelInvalid(levelWrapper)) + { + if (this instanceof FutureTrackableNetworkMessage) + ((FutureTrackableNetworkMessage) this).sendResponse(new InvalidLevelException("Invalid level")); + return true; + } + + return false; + } + +} diff --git a/core/src/main/java/com/seibel/distanthorizons/core/network/messages/fullData/generation/FullDataSourceRequestMessage.java b/core/src/main/java/com/seibel/distanthorizons/core/network/messages/fullData/generation/FullDataSourceRequestMessage.java index 65f88874a..315981a5b 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/network/messages/fullData/generation/FullDataSourceRequestMessage.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/network/messages/fullData/generation/FullDataSourceRequestMessage.java @@ -19,40 +19,49 @@ package com.seibel.distanthorizons.core.network.messages.fullData.generation; +import com.seibel.distanthorizons.core.network.messages.base.ILevelRelatedMessage; import com.seibel.distanthorizons.core.network.protocol.FutureTrackableNetworkMessage; import com.seibel.distanthorizons.core.network.protocol.INetworkObject; import com.seibel.distanthorizons.core.pos.DhSectionPos; +import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; import io.netty.buffer.ByteBuf; -import javax.annotation.Nullable; - -public class FullDataSourceRequestMessage extends FutureTrackableNetworkMessage +public class FullDataSourceRequestMessage extends FutureTrackableNetworkMessage implements ILevelRelatedMessage { public DhSectionPos dhSectionPos; - + private int levelHashCode; + @Override public int getLevelHashCode() { return levelHashCode; } + public FullDataSourceRequestMessage() {} - public FullDataSourceRequestMessage(DhSectionPos dhSectionPos) + public FullDataSourceRequestMessage(ILevelWrapper levelWrapper, DhSectionPos dhSectionPos) { + // TODO Multiverse support + this.levelHashCode = levelWrapper.getDimensionType().getDimensionName().hashCode(); this.dhSectionPos = dhSectionPos; } @Override public void encode0(ByteBuf out) { + out.writeInt(levelHashCode); dhSectionPos.encode(out); } @Override public void decode0(ByteBuf in) { + levelHashCode = in.readInt(); dhSectionPos = INetworkObject.decodeStatic(DhSectionPos.zero(), in); } @Override public String toString() { - return super.toString("dhSectionPos=" + dhSectionPos); + return super.toString( + "dhSectionPos=" + dhSectionPos + + ", levelHashCode=" + levelHashCode + ); } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/network/messages/fullData/generation/FullDataSourceResponseMessage.java b/core/src/main/java/com/seibel/distanthorizons/core/network/messages/fullData/generation/FullDataSourceResponseMessage.java index 3326cc16d..930e1ea2d 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/network/messages/fullData/generation/FullDataSourceResponseMessage.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/network/messages/fullData/generation/FullDataSourceResponseMessage.java @@ -40,7 +40,6 @@ public class FullDataSourceResponseMessage extends FutureTrackableNetworkMessage private CompleteFullDataSource fullDataSource; private DhServerLevel level; - private int levelHashCode; private CompleteFullDataSourceLoader fullDataSourceLoader; private ByteBuf dataBuffer; @@ -49,9 +48,6 @@ public class FullDataSourceResponseMessage extends FutureTrackableNetworkMessage { this.fullDataSource = fullDataSource; this.level = level; - - // TODO Multiverse support - this.levelHashCode = level.getLevelWrapper().getDimensionType().getDimensionName().hashCode(); } @Override @@ -63,7 +59,6 @@ public class FullDataSourceResponseMessage extends FutureTrackableNetworkMessage fullDataSource.writeToStream(dhOutputStream, level); dhOutputStream.flush(); - out.writeInt(levelHashCode); out.writeByte(fullDataSource.getBinaryDataFormatVersion()); out.writeInt(outputStream.size()); out.writeBytes(outputStream.toByteArray()); @@ -73,7 +68,6 @@ public class FullDataSourceResponseMessage extends FutureTrackableNetworkMessage @Override public void decode0(ByteBuf in) { - levelHashCode = in.readInt(); byte dataVersion = in.readByte(); this.fullDataSourceLoader = (CompleteFullDataSourceLoader) AbstractFullDataSourceLoader.getLoader(CompleteFullDataSource.TYPE_ID, dataVersion); this.dataBuffer = in.readBytes(in.readInt()); @@ -82,9 +76,6 @@ public class FullDataSourceResponseMessage extends FutureTrackableNetworkMessage @Nullable public CompleteFullDataSource getFullDataSource(DhSectionPos pos, IDhLevel level) throws IOException, InterruptedException { - // TODO Multiverse support - if (levelHashCode != level.getLevelWrapper().getDimensionType().getDimensionName().hashCode()) - return null; try (ByteBufInputStream inputStream = new ByteBufInputStream(dataBuffer)) { @@ -98,10 +89,7 @@ public class FullDataSourceResponseMessage extends FutureTrackableNetworkMessage @Override public String toString() { - return super.toString( - "levelHashCode=" + levelHashCode + - ", dataBuffer=" + dataBuffer - ); + return super.toString("dataBuffer=" + dataBuffer); } } diff --git a/core/src/main/java/com/seibel/distanthorizons/core/network/messages/fullData/updates/FullDataChangeSummaryRequestMessage.java b/core/src/main/java/com/seibel/distanthorizons/core/network/messages/fullData/updates/FullDataChangeSummaryRequestMessage.java index 090ec4fec..9116525ca 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/network/messages/fullData/updates/FullDataChangeSummaryRequestMessage.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/network/messages/fullData/updates/FullDataChangeSummaryRequestMessage.java @@ -19,6 +19,7 @@ package com.seibel.distanthorizons.core.network.messages.fullData.updates; +import com.seibel.distanthorizons.core.network.messages.base.ILevelRelatedMessage; import com.seibel.distanthorizons.core.network.protocol.FutureTrackableNetworkMessage; import com.seibel.distanthorizons.core.pos.DhSectionPos; import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper; @@ -27,10 +28,11 @@ import io.netty.buffer.ByteBuf; import java.util.HashMap; import java.util.Map; -public class FullDataChangeSummaryRequestMessage extends FutureTrackableNetworkMessage +public class FullDataChangeSummaryRequestMessage extends FutureTrackableNetworkMessage implements ILevelRelatedMessage { public Map checksums = new HashMap<>(); public int levelHashCode; + @Override public int getLevelHashCode() { return levelHashCode; } public FullDataChangeSummaryRequestMessage() { } @@ -56,11 +58,6 @@ public class FullDataChangeSummaryRequestMessage extends FutureTrackableNetworkM decodeMap(in, checksums, DhSectionPos::zero, () -> 0); } - public boolean isLevelValid(ILevelWrapper levelWrapper) - { - return levelWrapper.getDimensionType().getDimensionName().hashCode() == levelHashCode; - } - @Override public String toString() { return super.toString( diff --git a/core/src/main/java/com/seibel/distanthorizons/core/network/messages/fullData/updates/FullDataPartialUpdateMessage.java b/core/src/main/java/com/seibel/distanthorizons/core/network/messages/fullData/updates/FullDataPartialUpdateMessage.java index 1524b3f26..a2d70154e 100644 --- a/core/src/main/java/com/seibel/distanthorizons/core/network/messages/fullData/updates/FullDataPartialUpdateMessage.java +++ b/core/src/main/java/com/seibel/distanthorizons/core/network/messages/fullData/updates/FullDataPartialUpdateMessage.java @@ -22,7 +22,7 @@ package com.seibel.distanthorizons.core.network.messages.fullData.updates; import com.seibel.distanthorizons.core.dataObjects.fullData.accessor.ChunkSizedFullDataAccessor; import com.seibel.distanthorizons.core.level.DhServerLevel; import com.seibel.distanthorizons.core.level.IDhLevel; -import com.seibel.distanthorizons.core.network.protocol.FutureTrackableNetworkMessage; +import com.seibel.distanthorizons.core.network.messages.base.ILevelRelatedMessage; import com.seibel.distanthorizons.core.network.protocol.NetworkMessage; import com.seibel.distanthorizons.core.pos.DhChunkPos; import com.seibel.distanthorizons.core.util.objects.dataStreams.DhDataInputStream; @@ -34,12 +34,14 @@ import javax.annotation.Nullable; import java.io.ByteArrayOutputStream; import java.io.IOException; -public class FullDataPartialUpdateMessage extends NetworkMessage +public class FullDataPartialUpdateMessage extends NetworkMessage implements ILevelRelatedMessage { private ChunkSizedFullDataAccessor fullDataAccessor; private DhServerLevel level; private int levelHashCode; + @Override public int getLevelHashCode() { return levelHashCode; } + private DhChunkPos chunkPos; private ByteBuf dataBuffer; @@ -90,9 +92,7 @@ public class FullDataPartialUpdateMessage extends NetworkMessage @Nullable public ChunkSizedFullDataAccessor getFullDataSource(IDhLevel level) throws IOException, InterruptedException { - // TODO Multiverse support - if (levelHashCode != level.getLevelWrapper().getDimensionType().getDimensionName().hashCode()) - return null; + if (isLevelInvalid(level.getLevelWrapper())) return null; try (ByteBufInputStream inputStream = new ByteBufInputStream(dataBuffer)) {