Move context levels to requests

This commit is contained in:
s809
2023-09-21 10:16:34 +05:00
parent 08704aad2c
commit d325a69e3f
8 changed files with 102 additions and 72 deletions
@@ -164,7 +164,7 @@ public class WorldRemoteGenerationQueue implements IWorldGenerationQueue, IDebug
DhSectionPos sectionPos = mapEntry.getKey();
WorldGenQueueEntry entry = mapEntry.getValue();
CompletableFuture<FullDataSourceResponseMessage> request = this.networkState.getClient().sendRequest(new FullDataSourceRequestMessage(sectionPos), FullDataSourceResponseMessage.class);
CompletableFuture<FullDataSourceResponseMessage> request = this.networkState.getClient().sendRequest(new FullDataSourceRequestMessage(level.getLevelWrapper(), sectionPos), FullDataSourceResponseMessage.class);
entry.request = request;
request.handleAsync((response, throwable) ->
{
@@ -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<DhSectionPos> changedPosList = new HashSet<>();
for (Map.Entry<DhSectionPos, Integer> 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 ->
{
@@ -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 <T extends NetworkMessage> Consumer<T> connectedPlayersOnly(BiConsumer<T, ServerPlayerState> next)
{
return msg ->
{
ServerPlayerState serverPlayerState = getConnectedPlayer(msg);
if (serverPlayerState != null)
next.accept(msg, serverPlayerState);
};
}
public <T extends NetworkMessage> Consumer<T> currentLevelOnly(DhServerLevel level, BiConsumer<T, ServerPlayerState> 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<ServerPlayerState> getConnectedPlayers()
{
return playersByConnection.values();
@@ -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;
}
}
@@ -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
);
}
}
@@ -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);
}
}
@@ -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<DhSectionPos, Integer> 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(
@@ -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))
{