mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +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 UNSET_DAMAGE = -1;
|
||||||
public static final int MAX_DAMAGE = 10;
|
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;
|
private final World world;
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ public class BlockDestructionManager {
|
||||||
|
|
||||||
public void setBlockDestruction(BlockPos pos, int amount) {
|
public void setBlockDestruction(BlockPos pos, int amount) {
|
||||||
synchronized (locker) {
|
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() {
|
public void tick() {
|
||||||
synchronized (locker) {
|
synchronized (locker) {
|
||||||
destructions.long2ObjectEntrySet().removeIf(entry -> entry.getValue().tick());
|
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 {
|
private class Destruction {
|
||||||
BlockPos pos;
|
|
||||||
int amount = -1;
|
int amount = -1;
|
||||||
int age = 50;
|
int age = 50;
|
||||||
|
boolean dirty;
|
||||||
Destruction(BlockPos pos) {
|
|
||||||
this.pos = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean tick() {
|
boolean tick() {
|
||||||
if (age-- > 0) {
|
if (age-- > 0) {
|
||||||
|
@ -78,9 +86,7 @@ public class BlockDestructionManager {
|
||||||
void set(int amount) {
|
void set(int amount) {
|
||||||
this.age = 50;
|
this.age = 50;
|
||||||
this.amount = amount >= 0 && amount < MAX_DAMAGE ? amount : UNSET_DAMAGE;
|
this.amount = amount >= 0 && amount < MAX_DAMAGE ? amount : UNSET_DAMAGE;
|
||||||
if (world instanceof ServerWorld) {
|
this.dirty = true;
|
||||||
Channel.SERVER_BLOCK_DESTRUCTION.send(world, new MsgBlockDestruction(pos, this.amount));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,12 @@ public class ClientBlockDestructionManager {
|
||||||
|
|
||||||
private final Object locker = new Object();
|
private final Object locker = new Object();
|
||||||
|
|
||||||
public void setBlockDestruction(BlockPos pos, int amount) {
|
public void setBlockDestruction(long pos, int amount) {
|
||||||
synchronized (locker) {
|
synchronized (locker) {
|
||||||
if (amount <= 0 || amount > BlockDestructionManager.MAX_DAMAGE) {
|
if (amount <= 0 || amount > BlockDestructionManager.MAX_DAMAGE) {
|
||||||
destructions.remove(pos.asLong());
|
destructions.remove(pos);
|
||||||
} else {
|
} 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;
|
BlockBreakingInfo info;
|
||||||
|
|
||||||
Destruction(BlockPos pos) {
|
Destruction(long pos) {
|
||||||
this.info = new BlockBreakingInfo(0, pos);
|
this.info = new BlockBreakingInfo(0, BlockPos.fromLong(pos));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean tick() {
|
boolean tick() {
|
||||||
|
|
|
@ -2,35 +2,44 @@ package com.minelittlepony.unicopia.network;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.client.ClientBlockDestructionManager;
|
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.fabricmc.fabric.api.network.PacketContext;
|
||||||
import net.minecraft.network.PacketByteBuf;
|
import net.minecraft.network.PacketByteBuf;
|
||||||
import net.minecraft.util.math.BlockPos;
|
|
||||||
import net.minecraft.client.MinecraftClient;
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
|
||||||
public class MsgBlockDestruction implements Channel.Packet {
|
public class MsgBlockDestruction implements Channel.Packet {
|
||||||
|
|
||||||
private final BlockPos pos;
|
private final Long2ObjectMap<Integer> destructions;
|
||||||
|
|
||||||
private final int amount;
|
|
||||||
|
|
||||||
MsgBlockDestruction(PacketByteBuf buffer) {
|
MsgBlockDestruction(PacketByteBuf buffer) {
|
||||||
pos = buffer.readBlockPos();
|
destructions = new Long2ObjectOpenHashMap<>();
|
||||||
amount = buffer.readByte();
|
int size = buffer.readInt();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
destructions.put(buffer.readLong(), (Integer)buffer.readInt());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MsgBlockDestruction(BlockPos pos, int amount) {
|
public MsgBlockDestruction(Long2ObjectMap<Integer> destructions) {
|
||||||
this.pos = pos;
|
this.destructions = destructions;
|
||||||
this.amount = amount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toBuffer(PacketByteBuf buffer) {
|
public void toBuffer(PacketByteBuf buffer) {
|
||||||
buffer.writeBlockPos(pos);
|
buffer.writeInt(destructions.size());
|
||||||
buffer.writeByte(amount);
|
destructions.forEach((p, i) -> {
|
||||||
|
buffer.writeLong(p);
|
||||||
|
buffer.writeInt(i);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(PacketContext context) {
|
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