Skip to content

Commit

Permalink
sync from sakura-ryoko/litematica
Browse files Browse the repository at this point in the history
  • Loading branch information
TexBlock committed Jul 24, 2024
1 parent fda1e67 commit 9b736b5
Show file tree
Hide file tree
Showing 43 changed files with 3,283 additions and 2,615 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
## Change
- update mafglib version
- `neonetwork` -> `badpackets`
- sync from `sakura-ryoko/litematica`
4 changes: 2 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ mappings_patch="1.21+build.4"
neoforge="21.0.60-beta"

# Mod properties
version="0.1.7"
version="0.1.8"
maven-group="org.thinkingstudio.forgematica"
archives-name="Forgematica"

Expand All @@ -18,7 +18,7 @@ id-modrinth="dCKRaeBC"
id-curseforge="912441"

# Mod dependencies
mafglib="0.1.16-mc1.21"
mafglib="0.1.17-mc1.21"
badpackets="neo-0.8.1"

# Libraries
Expand Down
270 changes: 136 additions & 134 deletions src/main/java/fi/dy/masa/litematica/config/Configs.java

Large diffs are not rendered by default.

150 changes: 77 additions & 73 deletions src/main/java/fi/dy/masa/litematica/config/Hotkeys.java

Large diffs are not rendered by default.

163 changes: 101 additions & 62 deletions src/main/java/fi/dy/masa/litematica/data/EntitiesDataStorage.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
import net.minecraft.nbt.NbtList;
import net.minecraft.registry.Registries;
import net.minecraft.util.Identifier;
import net.minecraft.util.Util;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import fi.dy.masa.malilib.interfaces.IClientTickHandler;
Expand All @@ -33,6 +35,7 @@
import fi.dy.masa.litematica.network.ServuxLitematicaHandler;
import fi.dy.masa.litematica.network.ServuxLitematicaPacket;
import fi.dy.masa.litematica.util.EntityUtils;
import fi.dy.masa.litematica.util.WorldUtils;

public class EntitiesDataStorage implements IClientTickHandler
{
Expand All @@ -49,15 +52,18 @@ public static EntitiesDataStorage getInstance()
private boolean servuxServer = false;
private boolean hasInValidServux = false;
private String servuxVersion;
private final long chunkTimeoutMs = 5000;
// Wait 5 seconds for loaded Client Chunks to receive Entity Data

private long serverTickTime = 0;
// Requests to be executed
private Set<BlockPos> pendingBlockEntitiesQueue = new LinkedHashSet<>();
private Set<Integer> pendingEntitiesQueue = new LinkedHashSet<>();
private Set<ChunkPos> pendingChunks = new LinkedHashSet<>();
private Set<ChunkPos> completedChunks = new LinkedHashSet<>();
private final Set<BlockPos> pendingBlockEntitiesQueue = new LinkedHashSet<>();
private final Set<Integer> pendingEntitiesQueue = new LinkedHashSet<>();
private final Set<ChunkPos> pendingChunks = new LinkedHashSet<>();
private final Set<ChunkPos> completedChunks = new LinkedHashSet<>();
private final Map<ChunkPos, Long> pendingChunkTimeout = new HashMap<>();
// To save vanilla query packet transaction
private Map<Integer, Either<BlockPos, Integer>> transactionToBlockPosOrEntityId = new HashMap<>();
private final Map<Integer, Either<BlockPos, Integer>> transactionToBlockPosOrEntityId = new HashMap<>();

@Nullable
public World getWorld()
Expand All @@ -72,23 +78,38 @@ private EntitiesDataStorage()
@Override
public void onClientTick(MinecraftClient mc)
{
uptimeTicks++;
if (System.currentTimeMillis() - serverTickTime > 50)
this.uptimeTicks++;
if (System.currentTimeMillis() - this.serverTickTime > 50)
{
// In this block, we do something every server tick

if (Configs.Generic.ENTITY_DATA_SYNC.getBooleanValue() == false)
{
serverTickTime = System.currentTimeMillis();
this.serverTickTime = System.currentTimeMillis();

if (DataManager.getInstance().hasIntegratedServer() == false && this.hasServuxServer())
{
this.servuxServer = false;
HANDLER.unregisterPlayReceiver();
}
return;
}
else if (DataManager.getInstance().hasIntegratedServer() == false &&
this.hasServuxServer() == false &&
this.hasInValidServux == false &&
this.getWorld() != null)
{
// Make sure we're Play Registered, and request Metadata
HANDLER.registerPlayReceiver(ServuxLitematicaPacket.Payload.ID, HANDLER::receivePlayPayload);
this.requestMetadata();
}

// 5 queries / server tick
for (int i = 0; i < Configs.Generic.SERVER_NBT_REQUEST_RATE.getIntegerValue(); i++)
{
if (!pendingBlockEntitiesQueue.isEmpty())
if (!this.pendingBlockEntitiesQueue.isEmpty())
{
var iter = pendingBlockEntitiesQueue.iterator();
var iter = this.pendingBlockEntitiesQueue.iterator();
BlockPos pos = iter.next();
iter.remove();
if (this.hasServuxServer())
Expand All @@ -100,9 +121,9 @@ public void onClientTick(MinecraftClient mc)
requestQueryBlockEntity(pos);
}
}
if (!pendingEntitiesQueue.isEmpty())
if (!this.pendingEntitiesQueue.isEmpty())
{
var iter = pendingEntitiesQueue.iterator();
var iter = this.pendingEntitiesQueue.iterator();
int entityId = iter.next();
iter.remove();
if (this.hasServuxServer())
Expand All @@ -115,7 +136,7 @@ public void onClientTick(MinecraftClient mc)
}
}
}
serverTickTime = System.currentTimeMillis();
this.serverTickTime = System.currentTimeMillis();
}
}

Expand Down Expand Up @@ -244,13 +265,13 @@ public void requestBlockEntity(World world, BlockPos pos)
{
if (world.getBlockState(pos).getBlock() instanceof BlockEntityProvider)
{
pendingBlockEntitiesQueue.add(pos);
this.pendingBlockEntitiesQueue.add(pos);
}
}

public void requestEntity(int entityId)
{
pendingEntitiesQueue.add(entityId);
this.pendingEntitiesQueue.add(entityId);
}

private void requestQueryBlockEntity(BlockPos pos)
Expand All @@ -268,7 +289,7 @@ private void requestQueryBlockEntity(BlockPos pos)
{
handleBlockEntityData(pos, nbtCompound, null);
});
transactionToBlockPosOrEntityId.put(((IMixinDataQueryHandler) handler.getDataQueryHandler()).currentTransactionId(), Either.left(pos));
this.transactionToBlockPosOrEntityId.put(((IMixinDataQueryHandler) handler.getDataQueryHandler()).currentTransactionId(), Either.left(pos));
}
}

Expand All @@ -279,15 +300,15 @@ private void requestQueryEntityData(int entityId)
return;
}

ClientPlayNetworkHandler handler = this.getVanillaHandler();
ClientPlayNetworkHandler handler = getVanillaHandler();

if (handler != null)
{
handler.getDataQueryHandler().queryEntityNbt(entityId, nbtCompound ->
{
handleEntityData(entityId, nbtCompound);
});
transactionToBlockPosOrEntityId.put(((IMixinDataQueryHandler) handler.getDataQueryHandler()).currentTransactionId(), Either.right(entityId));
this.transactionToBlockPosOrEntityId.put(((IMixinDataQueryHandler) handler.getDataQueryHandler()).currentTransactionId(), Either.right(entityId));
}
}

Expand Down Expand Up @@ -321,22 +342,14 @@ public void requestServuxBulkEntityData(ChunkPos chunkPos, int minY, int maxY)

NbtCompound req = new NbtCompound();

if (this.completedChunks.contains(chunkPos))
{
this.completedChunks.remove(chunkPos);
}

this.completedChunks.remove(chunkPos);
this.pendingChunks.add(chunkPos);
this.pendingChunkTimeout.put(chunkPos, Util.getMeasuringTimeMs());

if (minY < -60)
{
minY = -60;
}
if (maxY > 319)
{
maxY = 319;
}
minY = MathHelper.clamp(minY, -60, 319);
maxY = MathHelper.clamp(maxY, -60, 319);

req.putString("Task", "BulkEntityRequest");
req.putInt("minY", minY);
req.putInt("maxY", maxY);

Expand All @@ -347,7 +360,7 @@ public void requestServuxBulkEntityData(ChunkPos chunkPos, int minY, int maxY)
@Nullable
public BlockEntity handleBlockEntityData(BlockPos pos, NbtCompound nbt, @Nullable Identifier type)
{
pendingBlockEntitiesQueue.remove(pos);
this.pendingBlockEntitiesQueue.remove(pos);
if (nbt == null || this.getWorld() == null) return null;

BlockEntity blockEntity = this.getWorld().getBlockEntity(pos);
Expand Down Expand Up @@ -375,7 +388,7 @@ public BlockEntity handleBlockEntityData(BlockPos pos, NbtCompound nbt, @Nullabl
@Nullable
public Entity handleEntityData(int entityId, NbtCompound nbt)
{
pendingEntitiesQueue.remove(entityId);
this.pendingEntitiesQueue.remove(entityId);
if (nbt == null || this.getWorld() == null) return null;
Entity entity = this.getWorld().getEntityById(entityId);
if (entity != null)
Expand All @@ -391,41 +404,45 @@ public void handleBulkEntityData(int transactionId, @Nullable NbtCompound nbt)
{
return;
}
NbtList tileList = nbt.contains("TileEntities") ? nbt.getList("TileEntities", Constants.NBT.TAG_COMPOUND) : new NbtList();
NbtList entityList = nbt.contains("Entities") ? nbt.getList("Entities", Constants.NBT.TAG_COMPOUND) : new NbtList();
ChunkPos chunkPos = new ChunkPos(nbt.getInt("chunkX"), nbt.getInt("chunkZ"));

for (int i = 0; i < tileList.size(); ++i)
// TODO --> Split out the task this way (I should have done this under sakura.12, etc),
// So we need to check if the "Task" is not included for now... (Wait for the updates to bake in)
if ((nbt.contains("Task") && nbt.getString("Task").equals("BulkEntityReply")) ||
nbt.contains("Task") == false)
{
NbtCompound te = tileList.getCompound(i);
BlockPos pos = NBTUtils.readBlockPos(te);
Identifier type = Identifier.of(te.getString("id"));
NbtList tileList = nbt.contains("TileEntities") ? nbt.getList("TileEntities", Constants.NBT.TAG_COMPOUND) : new NbtList();
NbtList entityList = nbt.contains("Entities") ? nbt.getList("Entities", Constants.NBT.TAG_COMPOUND) : new NbtList();
ChunkPos chunkPos = new ChunkPos(nbt.getInt("chunkX"), nbt.getInt("chunkZ"));

handleBlockEntityData(pos, te, type);
}
for (int i = 0; i < tileList.size(); ++i)
{
NbtCompound te = tileList.getCompound(i);
BlockPos pos = NBTUtils.readBlockPos(te);
Identifier type = Identifier.of(te.getString("id"));

for (int i = 0; i < entityList.size(); ++i)
{
NbtCompound ent = entityList.getCompound(i);
Vec3d pos = NBTUtils.readEntityPositionFromTag(ent);
int entityId = ent.getInt("entityId");
handleBlockEntityData(pos, te, type);
}

handleEntityData(entityId, ent);
}
for (int i = 0; i < entityList.size(); ++i)
{
NbtCompound ent = entityList.getCompound(i);
Vec3d pos = NBTUtils.readEntityPositionFromTag(ent);
int entityId = ent.getInt("entityId");

if (this.pendingChunks.contains(chunkPos))
{
this.pendingChunks.remove(chunkPos);
}
handleEntityData(entityId, ent);
}

this.completedChunks.add(chunkPos);
this.pendingChunks.remove(chunkPos);
this.pendingChunkTimeout.remove(chunkPos);
this.completedChunks.add(chunkPos);

Litematica.debugLog("EntitiesDataStorage#handleBulkEntityData(): [ChunkPos {}] received TE: [{}], and E: [{}] entiries from Servux", chunkPos.toString(), tileList.size(), entityList.size());
Litematica.debugLog("EntitiesDataStorage#handleBulkEntityData(): [ChunkPos {}] received TE: [{}], and E: [{}] entiries from Servux", chunkPos.toString(), tileList.size(), entityList.size());
}
}

public void handleVanillaQueryNbt(int transactionId, NbtCompound nbt)
{
Either<BlockPos, Integer> either = transactionToBlockPosOrEntityId.remove(transactionId);
Either<BlockPos, Integer> either = this.transactionToBlockPosOrEntityId.remove(transactionId);
if (either != null)
{
either.ifLeft(pos -> handleBlockEntityData(pos, nbt, null))
Expand All @@ -439,22 +456,44 @@ public boolean hasPendingChunk(ChunkPos pos)
{
return this.pendingChunks.contains(pos);
}
else

return false;
}

private void checkForPendingChunkTimeout(ChunkPos pos)
{
if (this.hasServuxServer() && this.hasPendingChunk(pos))
{
return false;
long now = Util.getMeasuringTimeMs();

// Take no action when ChunkPos is not loaded by the ClientWorld.
if (WorldUtils.isClientChunkLoaded(mc.world, pos.x, pos.z) == false)
{
this.pendingChunkTimeout.replace(pos, now);
return;
}

long duration = now - this.pendingChunkTimeout.get(pos);

if (duration > this.chunkTimeoutMs)
{
//Litematica.debugLog("EntitiesDataStorage#checkForPendingChunkTimeout(): [ChunkPos {}] has timed out waiting for data, marking complete without Receiving Entity Data.", pos.toString());
this.pendingChunkTimeout.remove(pos);
this.pendingChunks.remove(pos);
this.completedChunks.add(pos);
}
}
}

public boolean hasCompletedChunk(ChunkPos pos)
{
if (this.hasServuxServer())
{
this.checkForPendingChunkTimeout(pos);
return this.completedChunks.contains(pos);
}
else
{
return true;
}

return true;
}

public void markCompletedChunkDirty(ChunkPos pos)
Expand Down
Loading

0 comments on commit 9b736b5

Please sign in to comment.