Downloads already visited chunks

This commit is contained in:
s809
2023-07-23 23:48:42 +05:00
parent d7ef6c8a72
commit 10e2873497
6 changed files with 71 additions and 22 deletions
@@ -2,6 +2,7 @@ package com.seibel.distanthorizons.core.file.fullDatafile;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.interfaces.IFullDataSource;
import com.seibel.distanthorizons.core.file.structure.AbstractSaveStructure;
import com.seibel.distanthorizons.core.level.DhClientLevel;
import com.seibel.distanthorizons.core.level.IDhLevel;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.network.NetworkClient;
@@ -25,17 +26,35 @@ public class RemoteFullDataFileHandler extends FullDataFileHandler
@Override
public CompletableFuture<IFullDataSource> read(DhSectionPos pos) {
// TODO: LOD data file updating is probably incomplete
return super.read(pos).thenCompose((fullDataSource) -> {
CompletableFuture<FullDataSourceResponseMessage> responseFuture = networkClient.<FullDataSourceResponseMessage>sendRequest(new FullDataSourceRequestMessage(pos))
.exceptionally(throwable -> {
LOGGER.error(throwable);
return null;
});
responseFuture.thenAccept(response -> LOGGER.info("ChunkResponseMessage "+pos));
return super.read(pos).thenCompose(fullDataSource -> {
if (fullDataSource == null)
return null;
if (!fullDataSource.isEmpty())
return CompletableFuture.completedFuture(fullDataSource);
FullDataMetaFile metaFile = this.getLoadOrMakeFile(pos, true);
return onDataFileUpdate(fullDataSource, metaFile, iFullDataSource -> {}, iFullDataSource -> true);
return networkClient.<FullDataSourceResponseMessage>sendRequest(new FullDataSourceRequestMessage(pos))
.handle((response, throwable) -> {
try
{
if (throwable != null)
throw throwable;
LOGGER.info("FullDataSourceResponseMessage " + pos);
return response.getFullDataSource(metaFile, pos, level);
}
catch (Exception e)
{
LOGGER.error(e);
return null;
}
catch (Throwable e)
{
LOGGER.error(e.toString());
return null;
}
});
});
}
@@ -1,10 +1,14 @@
package com.seibel.distanthorizons.core.network.messages;
import com.google.common.collect.MapMaker;
import com.seibel.distanthorizons.core.level.DhClientLevel;
import com.seibel.distanthorizons.core.network.protocol.FutureTrackableNetworkMessage;
import com.seibel.distanthorizons.core.network.protocol.INetworkObject;
import com.seibel.distanthorizons.core.pos.DhSectionPos;
import io.netty.buffer.ByteBuf;
import java.util.concurrent.ConcurrentMap;
public class FullDataSourceRequestMessage extends FutureTrackableNetworkMessage
{
public DhSectionPos dhSectionPos;
@@ -1,16 +1,26 @@
package com.seibel.distanthorizons.core.network.messages;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.HighDetailIncompleteFullDataSource;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.interfaces.IFullDataSource;
import com.seibel.distanthorizons.core.file.fullDatafile.FullDataMetaFile;
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.pos.DhSectionPos;
import com.seibel.distanthorizons.core.util.objects.dataStreams.DhDataInputStream;
import com.seibel.distanthorizons.core.util.objects.dataStreams.DhDataOutputStream;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class FullDataSourceResponseMessage extends FutureTrackableNetworkMessage
{
public IFullDataSource fullDataSource;
public DhServerLevel level;
private IFullDataSource fullDataSource;
private DhServerLevel level;
private ByteBufInputStream inputStream;
public FullDataSourceResponseMessage() {}
public FullDataSourceResponseMessage(IFullDataSource fullDataSource, DhServerLevel level)
@@ -22,13 +32,28 @@ public class FullDataSourceResponseMessage extends FutureTrackableNetworkMessage
@Override
public void encode0(ByteBuf out) throws IOException
{
//fullDataSource.writeToStream(new DhDataOutputStream(new ByteBufOutputStream(out)), level);
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream())
{
DhDataOutputStream dhOutputStream = new DhDataOutputStream(outputStream);
fullDataSource.writeToStream(dhOutputStream, level);
dhOutputStream.flush();
out.writeInt(outputStream.size());
out.writeBytes(outputStream.toByteArray());
}
}
@Override
public void decode0(ByteBuf in)
{
//DhSectionPos sectionPos = INetworkObject.decode(new DhSectionPos((byte) 0, (byte) 0, (byte) 0), in);
//fullDataSource = HighDetailIncompleteFullDataSource.createEmpty(sectionPos);
inputStream = new ByteBufInputStream(in.readBytes(in.readInt()));
}
public IFullDataSource getFullDataSource(FullDataMetaFile metaFile, DhSectionPos pos, IDhLevel level) throws IOException, InterruptedException
{
IFullDataSource fullDataSource = HighDetailIncompleteFullDataSource.createEmpty(pos);
fullDataSource.populateFromStream(metaFile, new DhDataInputStream(inputStream), level);
inputStream.close();
return fullDataSource;
}
}
@@ -1,16 +1,17 @@
package com.seibel.distanthorizons.core.network.protocol;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
public abstract class FutureTrackableNetworkMessage implements INetworkMessage
{
private static int lastId = 0;
public int futureId = lastId++;
public static FutureTrackableNetworkMessage makeResponse(FutureTrackableNetworkMessage requestMessage, FutureTrackableNetworkMessage responseMessage)
public static void sendResponse(ChannelHandlerContext ctx, FutureTrackableNetworkMessage requestMessage, FutureTrackableNetworkMessage responseMessage)
{
responseMessage.futureId = requestMessage.futureId;
return responseMessage;
ctx.writeAndFlush(responseMessage);
}
@Override public final void encode(ByteBuf out)
@@ -21,12 +21,12 @@ public class NetworkChannelInitializer extends ChannelInitializer<SocketChannel>
ChannelPipeline pipeline = socketChannel.pipeline();
// Encoder
pipeline.addLast(new LengthFieldPrepender(Short.BYTES));
pipeline.addLast(new LengthFieldPrepender(Integer.BYTES));
pipeline.addLast(new MessageEncoder());
pipeline.addLast(new NetworkOutboundExceptionRouter());
// Decoder
pipeline.addLast(new LengthFieldBasedFrameDecoder(Short.MAX_VALUE, 0, Short.BYTES, 0, Short.BYTES));
pipeline.addLast(new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 0, Integer.BYTES, 0, Integer.BYTES));
pipeline.addLast(new MessageDecoder());
// Handler
@@ -90,11 +90,11 @@ public class DhServerWorld extends AbstractDhWorld implements IDhServerWorld
this.networkServer.registerHandler(FullDataSourceRequestMessage.class, (msg, ctx) ->
{
if (msg.dhSectionPos == null) {
LOGGER.warn("RequestChunksMessage received with null msg.dhSectionPos");
LOGGER.warn("FullDataSourceRequestMessage received with null msg.dhSectionPos");
return;
}
LOGGER.info("RequestChunksMessage received at pos ({}, {}) with detail level {}", msg.dhSectionPos.sectionX, msg.dhSectionPos.sectionZ, msg.dhSectionPos.sectionDetailLevel);
LOGGER.info("FullDataSourceRequestMessage received at pos ({}, {}) with detail level {}", msg.dhSectionPos.sectionX, msg.dhSectionPos.sectionZ, msg.dhSectionPos.sectionDetailLevel);
// hasReceivedChunkRequest should be false somewhere ???
// to avoid sending updates until client says at least something about its state
@@ -102,11 +102,11 @@ public class DhServerWorld extends AbstractDhWorld implements IDhServerWorld
DhServerLevel level = this.getLevel(playersByConnection.get(ctx).serverPlayer.getLevel());
// TODO: Add level to packet
level.serverside.worldGenTick(new DhBlockPos2D(msg.dhSectionPos.sectionX, msg.dhSectionPos.sectionZ));
//level.serverside.worldGenTick(new DhBlockPos2D(msg.dhSectionPos.sectionX, msg.dhSectionPos.sectionZ));
level.serverside.dataFileHandler.read(msg.dhSectionPos).thenAccept(fullDataSource -> {
// Send chunk response message back
ctx.writeAndFlush(FutureTrackableNetworkMessage.makeResponse(msg, new FullDataSourceResponseMessage(fullDataSource, level)));
FutureTrackableNetworkMessage.sendResponse(ctx, msg, new FullDataSourceResponseMessage(fullDataSource, level));
});
});
}