Incomplete

This commit is contained in:
s809
2023-08-21 22:08:35 +05:00
parent d9283e938b
commit 627bfbc007
17 changed files with 238 additions and 56 deletions
@@ -35,7 +35,8 @@ public abstract class AbstractPresetConfigEventHandler<TPresetEnum extends Enum<
public AbstractPresetConfigEventHandler()
{
configGui.addOnScreenChangeListener(() -> this.onConfigUiClosed());
if (configGui != null)
configGui.addOnScreenChangeListener(() -> this.onConfigUiClosed());
}
@@ -10,6 +10,7 @@ import com.seibel.distanthorizons.core.file.fullDatafile.FullDataMetaFile;
import com.seibel.distanthorizons.core.level.IDhLevel;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.pos.DhBlockPos2D;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.pos.DhLodPos;
import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.util.FullDataPointUtil;
@@ -23,6 +24,7 @@ import org.apache.logging.log4j.Logger;
import javax.annotation.CheckForNull;
import java.io.*;
import java.util.function.Consumer;
/**
* This data source contains every datapoint over its given {@link DhSectionPos}.
@@ -368,6 +370,27 @@ public class CompleteFullDataSource extends FullDataArrayAccessor implements IFu
}
}
public void splitIntoChunkSizedAccessors(Consumer<ChunkSizedFullDataAccessor> consumer)
{
LodUtil.assertTrue(sectionPos.sectionDetailLevel == DhSectionPos.SECTION_BLOCK_DETAIL_LEVEL, "Data source detail level must be at block detail level.");
sectionPos.forEachChildAtLevel(LodUtil.CHUNK_DETAIL_LEVEL, childPos -> {
ChunkSizedFullDataAccessor accessor = new ChunkSizedFullDataAccessor(new DhChunkPos(childPos.sectionX, childPos.sectionZ));
int detailLevelDifference = sectionPos.sectionDetailLevel - childPos.sectionDetailLevel;
int childRelativeX = childPos.sectionX - sectionPos.sectionX * BitShiftUtil.powerOfTwo(detailLevelDifference);
int childRelativeZ = childPos.sectionZ - sectionPos.sectionZ * BitShiftUtil.powerOfTwo(detailLevelDifference);
subView(
LodUtil.CHUNK_WIDTH,
childRelativeX * LodUtil.CHUNK_WIDTH,
childRelativeZ * LodUtil.CHUNK_WIDTH
).shadowCopyTo(accessor);
consumer.accept(accessor);
});
}
//=====================//
@@ -82,8 +82,6 @@ public class ChunkToLodBuilder implements AutoCloseable
}
else if (MC != null && !MC.playerExists())
{
// TODO handle server side properly
// MC hasn't finished loading (or is currently unloaded)
// can be uncommented if tasks aren't being cleared correctly
@@ -195,21 +195,7 @@ public class WorldRemoteGenerationQueue implements IWorldGenerationQueue, IDebug
if (chunkDataConsumer == null)
return entry.future.cancel(false);
sectionPos.forEachChildAtLevel(LodUtil.CHUNK_DETAIL_LEVEL, childPos -> {
ChunkSizedFullDataAccessor accessor = new ChunkSizedFullDataAccessor(new DhChunkPos(childPos.sectionX, childPos.sectionZ));
int detailLevelDifference = sectionPos.sectionDetailLevel - childPos.sectionDetailLevel;
int childRelativeX = childPos.sectionX - sectionPos.sectionX * BitShiftUtil.powerOfTwo(detailLevelDifference);
int childRelativeZ = childPos.sectionZ - sectionPos.sectionZ * BitShiftUtil.powerOfTwo(detailLevelDifference);
fullDataSource.subView(
LodUtil.CHUNK_WIDTH,
childRelativeX * LodUtil.CHUNK_WIDTH,
childRelativeZ * LodUtil.CHUNK_WIDTH
).shadowCopyTo(accessor);
chunkDataConsumer.accept(accessor);
});
fullDataSource.splitIntoChunkSizedAccessors(chunkDataConsumer);
}
catch (ChannelException | RateLimitedException e)
{
@@ -1,6 +1,7 @@
package com.seibel.distanthorizons.core.level;
import com.seibel.distanthorizons.core.dataObjects.fullData.accessor.ChunkSizedFullDataAccessor;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.CompleteFullDataSource;
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
import com.seibel.distanthorizons.core.file.fullDatafile.IFullDataSourceProvider;
import com.seibel.distanthorizons.core.file.fullDatafile.RemoteFullDataFileHandler;
@@ -8,22 +9,30 @@ import com.seibel.distanthorizons.core.file.structure.AbstractSaveStructure;
import com.seibel.distanthorizons.core.generation.WorldRemoteGenerationQueue;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.multiplayer.ClientNetworkState;
import com.seibel.distanthorizons.core.network.NetworkClient;
import com.seibel.distanthorizons.core.network.ScopedNetworkEventSource;
import com.seibel.distanthorizons.core.network.messages.FullDataSourceRequestMessage;
import com.seibel.distanthorizons.core.network.messages.FullDataSourceUpdateMessage;
import com.seibel.distanthorizons.core.pos.DhBlockPos;
import com.seibel.distanthorizons.core.pos.DhBlockPos2D;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.render.renderer.DebugRenderer;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.minecraft.IProfilerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IClientLevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.coreapi.util.BitShiftUtil;
import com.seibel.distanthorizons.coreapi.util.math.Mat4f;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.Nullable;
import javax.annotation.CheckForNull;
import java.awt.*;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
/** The level used when connected to a server */
@@ -47,6 +56,8 @@ public class DhClientLevel extends DhLevel implements IDhClientLevel
@CheckForNull
private final ClientNetworkState networkState;
@Nullable
private final ScopedNetworkEventSource<NetworkClient> eventSource;
public final WorldGenModule worldGenModule;
@@ -63,12 +74,41 @@ public class DhClientLevel extends DhLevel implements IDhClientLevel
this.networkState = networkState;
this.worldGenModule = new WorldGenModule(dataFileHandler, this);
if (networkState != null)
{
this.eventSource = new ScopedNetworkEventSource<>(networkState.getClient());
this.registerNetworkHandlers();
}
else
{
this.eventSource = null;
}
clientside = new ClientLevelModule(this);
clientside.startRenderer();
LOGGER.info("Started DHLevel for " + this.levelWrapper + " with saves at " + this.saveStructure);
}
private void registerNetworkHandlers()
{
assert this.eventSource != null;
this.eventSource.registerHandler(FullDataSourceUpdateMessage.class, msg ->
{
try
{
CompleteFullDataSource fullDataSource = msg.getFullDataSource(this);
if (fullDataSource == null) return;
fullDataSource.splitIntoChunkSizedAccessors(this::saveWrites);
}
catch (Exception e)
{
LOGGER.error("Error while updating full data source", e);
}
});
}
//==============//
// tick methods //
//==============//
@@ -25,7 +25,7 @@ public abstract class DhLevel implements IDhLevel
}
@Override
public void updateChunkAsync(IChunkWrapper chunk)
public CompletableFuture<ChunkSizedFullDataAccessor> updateChunkAsync(IChunkWrapper chunk)
{
CompletableFuture<ChunkSizedFullDataAccessor> future = this.chunkToLodBuilder.tryGenerateData(chunk);
if (future != null)
@@ -44,6 +44,7 @@ public abstract class DhLevel implements IDhLevel
new DhApiChunkModifiedEvent.EventParam(this.getLevelWrapper(), chunk.getChunkPos().x, chunk.getChunkPos().z));
});
}
return future;
}
@Override
@@ -6,6 +6,7 @@ import com.seibel.distanthorizons.core.dataObjects.fullData.accessor.ChunkSizedF
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.CompleteFullDataSource;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.interfaces.IFullDataSource;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.interfaces.IIncompleteFullDataSource;
import com.seibel.distanthorizons.core.file.fullDatafile.FullDataMetaFile;
import com.seibel.distanthorizons.core.file.fullDatafile.IFullDataSourceProvider;
import com.seibel.distanthorizons.core.file.structure.AbstractSaveStructure;
import com.seibel.distanthorizons.core.multiplayer.ServerPlayerState;
@@ -15,10 +16,12 @@ import com.seibel.distanthorizons.core.network.NetworkServer;
import com.seibel.distanthorizons.core.network.exceptions.RateLimitedException;
import com.seibel.distanthorizons.core.network.messages.*;
import com.seibel.distanthorizons.core.pos.DhBlockPos2D;
import com.seibel.distanthorizons.core.pos.DhChunkPos;
import com.seibel.distanthorizons.core.pos.DhLodPos;
import com.seibel.distanthorizons.core.pos.DhSectionPos;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.util.LodUtil;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IServerLevelWrapper;
@@ -26,9 +29,7 @@ import com.seibel.distanthorizons.coreapi.util.math.Vec3d;
import org.apache.logging.log4j.Logger;
import javax.annotation.CheckForNull;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.*;
public class DhServerLevel extends DhLevel implements IDhServerLevel
@@ -40,7 +41,7 @@ public class DhServerLevel extends DhLevel implements IDhServerLevel
private final RemotePlayerConnectionHandler remotePlayerConnectionHandler;
private final ScopedNetworkEventSource<NetworkServer> eventSource;
private final ConcurrentLinkedQueue<IServerPlayerWrapper> worldGenLoopingQueue = new ConcurrentLinkedQueue<>();
private final LinkedBlockingQueue<IServerPlayerWrapper> worldGenLoopingQueue = new LinkedBlockingQueue<>();
private final ConcurrentMap<DhSectionPos, IncompleteDataSourceEntry> incompleteDataSources = new ConcurrentHashMap<>();
private final ConcurrentMap<Long, IncompleteDataSourceEntry> fullDataRequests = new ConcurrentHashMap<>();
private final AppliedConfigState<Integer> rateLimitConfig = new AppliedConfigState<>(Config.Client.Advanced.Multiplayer.serverNetworkingRateLimit);
@@ -66,12 +67,16 @@ public class DhServerLevel extends DhLevel implements IDhServerLevel
// 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 ->
{
ServerPlayerState serverPlayerState = remotePlayerConnectionHandler.getConnectedPlayer(msg);
if (serverPlayerState == null) return;
if (serverPlayerState.serverPlayer.getLevel() != this.serverLevelWrapper)
return;
@@ -106,6 +111,8 @@ public class DhServerLevel extends DhLevel implements IDhServerLevel
this.eventSource.registerHandler(GenTaskPriorityRequestMessage.class, msg -> {
ServerPlayerState serverPlayerState = remotePlayerConnectionHandler.getConnectedPlayer(msg);
if (serverPlayerState == null) return;
if (serverPlayerState.serverPlayer.getLevel() != this.serverLevelWrapper)
return;
@@ -120,7 +127,9 @@ public class DhServerLevel extends DhLevel implements IDhServerLevel
if (entry == null) return;
FullDataSourceRequestMessage requestMessage = entry.requestMessages.remove(msg.futureId);
remotePlayerConnectionHandler.getConnectedPlayer(msg).pendingFullDataRequests.decrementAndGet();
ServerPlayerState serverPlayerState = remotePlayerConnectionHandler.getConnectedPlayer(msg);
if (serverPlayerState != null)
serverPlayerState.pendingFullDataRequests.decrementAndGet();
entry.requestCollectionSemaphore.acquireUninterruptibly(Short.MAX_VALUE);
if (entry.requestMessages.isEmpty())
@@ -135,18 +144,12 @@ public class DhServerLevel extends DhLevel implements IDhServerLevel
public void addPlayer(IServerPlayerWrapper serverPlayer)
{
synchronized (worldGenLoopingQueue)
{
this.worldGenLoopingQueue.add(serverPlayer);
}
this.worldGenLoopingQueue.add(serverPlayer);
}
public void removePlayer(IServerPlayerWrapper serverPlayer)
{
synchronized (worldGenLoopingQueue)
{
this.worldGenLoopingQueue.remove(serverPlayer);
}
boolean ignored = this.worldGenLoopingQueue.remove(serverPlayer);
}
public void serverTick()
@@ -189,6 +192,42 @@ public class DhServerLevel extends DhLevel implements IDhServerLevel
}
}
@Override
public CompletableFuture<ChunkSizedFullDataAccessor> updateChunkAsync(IChunkWrapper chunk)
{
DhSectionPos sectionPos = new DhSectionPos(chunk.getChunkPos()).convertToDetailLevel(DhSectionPos.SECTION_MINIMUM_DETAIL_LEVEL);
FullDataMetaFile metaFile = this.serverside.dataFileHandler.getFileIfExist(sectionPos);
int prevChecksum = metaFile != null ? metaFile.baseMetaData.checksum : 0;
CompletableFuture<ChunkSizedFullDataAccessor> future = super.updateChunkAsync(chunk);
if (future == null)
return null;
future.thenRun(() ->
{
if (metaFile == null || metaFile.baseMetaData.checksum == prevChecksum)
return;
this.serverside.dataFileHandler.read(sectionPos).thenAccept(fullDataSource ->
{
if (!(fullDataSource instanceof CompleteFullDataSource))
return;
CompleteFullDataSource completeSource = (CompleteFullDataSource) fullDataSource;
for (IServerPlayerWrapper serverPlayer : worldGenLoopingQueue)
{
ServerPlayerState serverPlayerState = remotePlayerConnectionHandler.getPlayer(serverPlayer);
if (serverPlayerState == null) continue;
if (chunk.getChunkPos().distance(new DhChunkPos(serverPlayer.getPosition())) <= serverPlayerState.config.renderDistance)
serverPlayerState.channelContext.writeAndFlush(new FullDataSourceUpdateMessage(completeSource, this));
}
});
});
return future;
}
@Override
public void saveWrites(ChunkSizedFullDataAccessor data)
{
@@ -1,9 +1,11 @@
package com.seibel.distanthorizons.core.level;
import com.seibel.distanthorizons.core.dataObjects.fullData.accessor.ChunkSizedFullDataAccessor;
import com.seibel.distanthorizons.core.file.fullDatafile.IFullDataSourceProvider;
import com.seibel.distanthorizons.core.file.structure.AbstractSaveStructure;
import com.seibel.distanthorizons.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
import org.jetbrains.annotations.Nullable;
import java.util.concurrent.CompletableFuture;
@@ -20,7 +22,8 @@ public interface IDhLevel extends AutoCloseable
*/
ILevelWrapper getLevelWrapper();
void updateChunkAsync(IChunkWrapper chunk);
@Nullable
CompletableFuture<ChunkSizedFullDataAccessor> updateChunkAsync(IChunkWrapper chunk);
IFullDataSourceProvider getFileHandler();
@@ -2,7 +2,6 @@ package com.seibel.distanthorizons.core.multiplayer;
import com.seibel.distanthorizons.core.config.Config;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.network.IClientRequestHandler;
import com.seibel.distanthorizons.core.network.ScopedNetworkEventSource;
import com.seibel.distanthorizons.core.network.NetworkClient;
import com.seibel.distanthorizons.core.network.messages.AckMessage;
@@ -10,6 +9,7 @@ import com.seibel.distanthorizons.core.network.messages.HelloMessage;
import com.seibel.distanthorizons.core.network.messages.PlayerUUIDMessage;
import com.seibel.distanthorizons.core.network.messages.RemotePlayerConfigMessage;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import java.io.Closeable;
import java.util.UUID;
@@ -26,7 +26,7 @@ public class ClientNetworkState implements Closeable
* Returns the client used by this instance. <p>
* If you need to subscribe to any packet events, create an instance of {@link ScopedNetworkEventSource} using the returned instance.
*/
public IClientRequestHandler getClient() { return this.client; }
public NetworkClient getClient() { return this.client; }
/**
* Constructs a new instance.
@@ -10,6 +10,7 @@ import com.seibel.distanthorizons.core.network.messages.PlayerUUIDMessage;
import com.seibel.distanthorizons.core.network.protocol.NetworkMessage;
import com.seibel.distanthorizons.core.wrapperInterfaces.misc.IServerPlayerWrapper;
import io.netty.channel.ChannelHandlerContext;
import org.jetbrains.annotations.Nullable;
import java.io.Closeable;
import java.util.HashMap;
@@ -69,11 +70,13 @@ public class RemotePlayerConnectionHandler implements Closeable
return playersByConnection.values();
}
@Nullable
public ServerPlayerState getConnectedPlayer(NetworkMessage msg)
{
return playersByConnection.get(msg.getChannelContext());
}
@Nullable
public ServerPlayerState getPlayer(IServerPlayerWrapper serverPlayer)
{
return playersByUUID.get(serverPlayer.getUUID());
@@ -1,19 +0,0 @@
package com.seibel.distanthorizons.core.network;
import com.seibel.distanthorizons.core.network.protocol.FutureTrackableNetworkMessage;
import java.util.concurrent.CompletableFuture;
public interface IClientRequestHandler
{
/** Indicates whether the client is initialized and not started connecting yet. */
boolean isInitialState();
/** Indicates whether the client is closed(-ing) and should not be used. */
boolean isClosed();
/** Indicates whether the connection is established and first message is sent. */
boolean isReady();
/** Sends a new request. */
<TResponse extends FutureTrackableNetworkMessage> CompletableFuture<TResponse> sendRequest(FutureTrackableNetworkMessage msg);
}
@@ -19,7 +19,7 @@ import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
public class NetworkClient extends NetworkEventSource implements IClientRequestHandler, AutoCloseable
public class NetworkClient extends NetworkEventSource implements AutoCloseable
{
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
@@ -5,8 +5,10 @@ import com.google.common.collect.Table;
import com.google.common.collect.Tables;
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
import com.seibel.distanthorizons.core.network.messages.CancelMessage;
import com.seibel.distanthorizons.core.network.messages.CloseEvent;
import com.seibel.distanthorizons.core.network.messages.ExceptionMessage;
import com.seibel.distanthorizons.core.network.protocol.FutureTrackableNetworkMessage;
import com.seibel.distanthorizons.core.network.protocol.MessageRegistry;
import com.seibel.distanthorizons.core.network.protocol.NetworkMessage;
import io.netty.channel.ChannelException;
import io.netty.channel.ChannelHandlerContext;
@@ -75,7 +77,13 @@ public abstract class NetworkEventSource
public <T extends NetworkMessage> void registerHandler(Class<T> handlerClass, Consumer<T> handlerImplementation)
{
this.handlers.computeIfAbsent(handlerClass, missingHandlerClass -> new HashSet<>())
this.handlers.computeIfAbsent(handlerClass, missingHandlerClass ->
{
// Will throw if the handler class is not found
if (handlerClass != CloseEvent.class)
MessageRegistry.INSTANCE.getMessageId(handlerClass);
return new HashSet<>();
})
.add((Consumer<NetworkMessage>) handlerImplementation);
}
@@ -71,5 +71,9 @@ public class FullDataSourceResponseMessage extends FutureTrackableNetworkMessage
{
return fullDataSourceLoader.loadData(pos, new DhDataInputStream(inputStream), level);
}
finally
{
dataBuffer.release();
}
}
}
@@ -0,0 +1,83 @@
package com.seibel.distanthorizons.core.network.messages;
import com.seibel.distanthorizons.core.dataObjects.fullData.loader.AbstractFullDataSourceLoader;
import com.seibel.distanthorizons.core.dataObjects.fullData.loader.CompleteFullDataSourceLoader;
import com.seibel.distanthorizons.core.dataObjects.fullData.sources.CompleteFullDataSource;
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.protocol.INetworkObject;
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 javax.annotation.Nullable;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
public class FullDataSourceUpdateMessage extends FutureTrackableNetworkMessage
{
private CompleteFullDataSource fullDataSource;
private DhServerLevel level;
private int levelHashCode;
private DhSectionPos sectionPos;
private CompleteFullDataSourceLoader fullDataSourceLoader;
private ByteBuf dataBuffer;
public FullDataSourceUpdateMessage() {}
public FullDataSourceUpdateMessage(CompleteFullDataSource fullDataSource, DhServerLevel level)
{
this.fullDataSource = fullDataSource;
this.level = level;
// TODO Multiverse support
this.levelHashCode = level.getLevelWrapper().getDimensionType().getDimensionName().hashCode();
}
@Override
public void encode0(ByteBuf out) throws IOException
{
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream())
{
DhDataOutputStream dhOutputStream = new DhDataOutputStream(outputStream);
fullDataSource.writeToStream(dhOutputStream, level);
dhOutputStream.flush();
out.writeInt(levelHashCode);
fullDataSource.getSectionPos().encode(out);
out.writeByte(fullDataSource.getBinaryDataFormatVersion());
out.writeInt(outputStream.size());
out.writeBytes(outputStream.toByteArray());
}
}
@Override
public void decode0(ByteBuf in)
{
levelHashCode = in.readInt();
sectionPos = INetworkObject.decodeStatic(DhSectionPos.zero(), in);
byte dataVersion = in.readByte();
this.fullDataSourceLoader = (CompleteFullDataSourceLoader) AbstractFullDataSourceLoader.getLoader(CompleteFullDataSource.TYPE_ID, dataVersion);
this.dataBuffer = in.readBytes(in.readInt());
}
@Nullable
public CompleteFullDataSource getFullDataSource(IDhLevel level) throws IOException, InterruptedException
{
// TODO Multiverse support
if (levelHashCode != level.getLevelWrapper().getDimensionType().getDimensionName().hashCode())
return null;
try (ByteBufInputStream inputStream = new ByteBufInputStream(dataBuffer))
{
return fullDataSourceLoader.loadData(sectionPos, new DhDataInputStream(inputStream), level);
}
finally
{
dataBuffer.release();
}
}
}
@@ -35,9 +35,10 @@ public class MessageRegistry
this.registerMessage(PlayerUUIDMessage.class, PlayerUUIDMessage::new);
this.registerMessage(RemotePlayerConfigMessage.class, RemotePlayerConfigMessage::new);
// Full data requests
// Full data requests & updates
this.registerMessage(FullDataSourceRequestMessage.class, FullDataSourceRequestMessage::new);
this.registerMessage(FullDataSourceResponseMessage.class, FullDataSourceResponseMessage::new);
this.registerMessage(FullDataSourceUpdateMessage.class, FullDataSourceUpdateMessage::new);
// Generation task prioritization
this.registerMessage(GenTaskPriorityRequestMessage.class, GenTaskPriorityRequestMessage::new);
@@ -19,6 +19,8 @@
package com.seibel.distanthorizons.core.pos;
import com.seibel.distanthorizons.coreapi.util.math.Vec3d;
import java.util.Objects;
public class DhChunkPos
@@ -48,6 +50,10 @@ public class DhChunkPos
// >> 4 is the Same as div 16
this(blockPos.x >> 4, blockPos.z >> 4);
}
public DhChunkPos(Vec3d pos)
{
this(((int)pos.x) >> 4, ((int)pos.z) >> 4);
}
public DhChunkPos(long packed) { this(getX(packed), getZ(packed)); }
@@ -72,6 +78,11 @@ public class DhChunkPos
public long getLong() { return toLong(x, z); }
public double distance(DhChunkPos other)
{
return Math.sqrt(Math.pow(x - other.x, 2) + Math.pow(z - other.z, 2));
}
@Override
public boolean equals(Object obj)
{