mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 21:38:00 +01:00
Send destruction updates in batches to avoid network congestion
This commit is contained in:
parent
0bde55a0fb
commit
8e89edfb35
3 changed files with 42 additions and 27 deletions
|
@ -14,7 +14,7 @@ public class BlockDestructionManager {
|
|||
public static final int UNSET_DAMAGE = -1;
|
||||
public static final int MAX_DAMAGE = 10;
|
||||
|
||||
private final Destruction emptyDestruction = new Destruction(BlockPos.ORIGIN);
|
||||
private final Destruction emptyDestruction = new Destruction();
|
||||
|
||||
private final World world;
|
||||
|
||||
|
@ -36,7 +36,7 @@ public class BlockDestructionManager {
|
|||
|
||||
public void setBlockDestruction(BlockPos pos, int amount) {
|
||||
synchronized (locker) {
|
||||
destructions.computeIfAbsent(pos.asLong(), p -> new Destruction(pos)).set(amount);
|
||||
destructions.computeIfAbsent(pos.asLong(), p -> new Destruction()).set(amount);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -52,17 +52,25 @@ public class BlockDestructionManager {
|
|||
public void tick() {
|
||||
synchronized (locker) {
|
||||
destructions.long2ObjectEntrySet().removeIf(entry -> entry.getValue().tick());
|
||||
|
||||
if (world instanceof ServerWorld) {
|
||||
Long2ObjectMap<Integer> sent = new Long2ObjectOpenHashMap<>();
|
||||
destructions.forEach((p, item) -> {
|
||||
if (item.dirty) {
|
||||
sent.put(p.longValue(), (Integer)item.amount);
|
||||
}
|
||||
});
|
||||
if (!sent.isEmpty()) {
|
||||
Channel.SERVER_BLOCK_DESTRUCTION.send(world, new MsgBlockDestruction(sent));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class Destruction {
|
||||
BlockPos pos;
|
||||
int amount = -1;
|
||||
int age = 50;
|
||||
|
||||
Destruction(BlockPos pos) {
|
||||
this.pos = pos;
|
||||
}
|
||||
boolean dirty;
|
||||
|
||||
boolean tick() {
|
||||
if (age-- > 0) {
|
||||
|
@ -78,9 +86,7 @@ public class BlockDestructionManager {
|
|||
void set(int amount) {
|
||||
this.age = 50;
|
||||
this.amount = amount >= 0 && amount < MAX_DAMAGE ? amount : UNSET_DAMAGE;
|
||||
if (world instanceof ServerWorld) {
|
||||
Channel.SERVER_BLOCK_DESTRUCTION.send(world, new MsgBlockDestruction(pos, this.amount));
|
||||
}
|
||||
this.dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,12 +16,12 @@ public class ClientBlockDestructionManager {
|
|||
|
||||
private final Object locker = new Object();
|
||||
|
||||
public void setBlockDestruction(BlockPos pos, int amount) {
|
||||
public void setBlockDestruction(long pos, int amount) {
|
||||
synchronized (locker) {
|
||||
if (amount <= 0 || amount > BlockDestructionManager.MAX_DAMAGE) {
|
||||
destructions.remove(pos.asLong());
|
||||
destructions.remove(pos);
|
||||
} else {
|
||||
destructions.computeIfAbsent(pos.asLong(), p -> new Destruction(pos)).set(amount);
|
||||
destructions.computeIfAbsent(pos, p -> new Destruction(pos)).set(amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,8 +52,8 @@ public class ClientBlockDestructionManager {
|
|||
|
||||
BlockBreakingInfo info;
|
||||
|
||||
Destruction(BlockPos pos) {
|
||||
this.info = new BlockBreakingInfo(0, pos);
|
||||
Destruction(long pos) {
|
||||
this.info = new BlockBreakingInfo(0, BlockPos.fromLong(pos));
|
||||
}
|
||||
|
||||
boolean tick() {
|
||||
|
|
|
@ -2,35 +2,44 @@ package com.minelittlepony.unicopia.network;
|
|||
|
||||
import com.minelittlepony.unicopia.client.ClientBlockDestructionManager;
|
||||
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
|
||||
import net.fabricmc.fabric.api.network.PacketContext;
|
||||
import net.minecraft.network.PacketByteBuf;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
|
||||
public class MsgBlockDestruction implements Channel.Packet {
|
||||
|
||||
private final BlockPos pos;
|
||||
|
||||
private final int amount;
|
||||
private final Long2ObjectMap<Integer> destructions;
|
||||
|
||||
MsgBlockDestruction(PacketByteBuf buffer) {
|
||||
pos = buffer.readBlockPos();
|
||||
amount = buffer.readByte();
|
||||
destructions = new Long2ObjectOpenHashMap<>();
|
||||
int size = buffer.readInt();
|
||||
for (int i = 0; i < size; i++) {
|
||||
destructions.put(buffer.readLong(), (Integer)buffer.readInt());
|
||||
}
|
||||
}
|
||||
|
||||
public MsgBlockDestruction(BlockPos pos, int amount) {
|
||||
this.pos = pos;
|
||||
this.amount = amount;
|
||||
public MsgBlockDestruction(Long2ObjectMap<Integer> destructions) {
|
||||
this.destructions = destructions;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toBuffer(PacketByteBuf buffer) {
|
||||
buffer.writeBlockPos(pos);
|
||||
buffer.writeByte(amount);
|
||||
buffer.writeInt(destructions.size());
|
||||
destructions.forEach((p, i) -> {
|
||||
buffer.writeLong(p);
|
||||
buffer.writeInt(i);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(PacketContext context) {
|
||||
((ClientBlockDestructionManager.Source)MinecraftClient.getInstance().worldRenderer).getDestructionManager().setBlockDestruction(pos, amount);
|
||||
ClientBlockDestructionManager destr = ((ClientBlockDestructionManager.Source)MinecraftClient.getInstance().worldRenderer).getDestructionManager();
|
||||
|
||||
destructions.forEach((i, d) -> {
|
||||
destr.setBlockDestruction(i, d);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue