mirror of
https://github.com/LeavesMC/Leaves.git
synced 2025-12-21 15:59:33 +00:00
734 lines
34 KiB
Diff
734 lines
34 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: violetc <58360096+s-yh-china@users.noreply.github.com>
|
|
Date: Mon, 28 Nov 2022 15:34:15 +0800
|
|
Subject: [PATCH] PCA sync protocol
|
|
|
|
This patch is Powered by plusls-carpet-addition(https://github.com/plusls/plusls-carpet-addition)
|
|
|
|
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
index 2aeda591a182896f50edff099b042357f1347a39..adae87a679f8bd6d42d472b56cdc0a7806bc9910 100644
|
|
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
|
@@ -245,6 +245,7 @@ import org.bukkit.inventory.CraftingInventory;
|
|
import org.bukkit.inventory.EquipmentSlot;
|
|
import org.bukkit.inventory.InventoryView;
|
|
import org.bukkit.inventory.SmithingInventory;
|
|
+import top.leavesmc.leaves.util.ProtocolUtils;
|
|
// CraftBukkit end
|
|
|
|
public class ServerGamePacketListenerImpl implements ServerPlayerConnection, TickablePacketListener, ServerGamePacketListener {
|
|
@@ -3548,6 +3549,16 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
|
|
this.disconnect("Invalid payload UNREGISTER!", org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause
|
|
}
|
|
} else {
|
|
+ // Leaves start - leaves extra protocol
|
|
+ try {
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol && ProtocolUtils.isNamespacePacket(packet, top.leavesmc.leaves.protocol.PcaSyncProtocol.PROTOCOL_ID)) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.handlePacket(server, player, packet);
|
|
+ }
|
|
+ } catch (Exception ex) {
|
|
+ ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t dispatch custom payload", ex);
|
|
+ this.disconnect("Invalid custom payload!", org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD);
|
|
+ }
|
|
+ // Leaves end - leaves extra protocol
|
|
try {
|
|
byte[] data = new byte[packet.data.readableBytes()];
|
|
packet.data.readBytes(data);
|
|
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
|
index 3088709b9dc3f46ec34f3ad16a43883feb89af16..160b58c31ab420ebd7bdc57b87e4dbb1d28e0ef3 100644
|
|
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
|
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
|
@@ -356,6 +356,7 @@ public abstract class PlayerList {
|
|
bot1.render(playerconnection, true,player.getBukkitEntity().getWorld() == bot1.getBukkitEntity().getWorld())); // Leaves - render bot
|
|
}
|
|
// Leaves end - bot support
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.onJoin(player); // Leaves - pca
|
|
|
|
final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage();
|
|
|
|
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
|
|
index 79b6e241f425622fdc575b77d8dce7061c0ab783..57579e83cb2ba6ad82509e9e7b8fdda96b3553ce 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
|
|
@@ -376,6 +376,11 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
|
|
|
|
@Override
|
|
public void containerChanged(Container sender) {
|
|
+ // Leaves start - pca
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncEntityToClient(this);
|
|
+ }
|
|
+ // Leaves end - pca
|
|
boolean flag = this.isSaddled();
|
|
|
|
this.updateContainerEquipment();
|
|
diff --git a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
|
index 564908ce0a560c2190fb624e77d227d3b7031024..5304ee89ce843c9ca860d68091162a976daee0ea 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/npc/AbstractVillager.java
|
|
@@ -65,6 +65,15 @@ public abstract class AbstractVillager extends AgeableMob implements InventoryCa
|
|
super(type, world);
|
|
this.setPathfindingMalus(BlockPathTypes.DANGER_FIRE, 16.0F);
|
|
this.setPathfindingMalus(BlockPathTypes.DAMAGE_FIRE, -1.0F);
|
|
+ // Leaves start - pca
|
|
+ if (!this.level().isClientSide()) {
|
|
+ this.inventory.addListener(inventory -> {
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncEntityToClient(this);
|
|
+ }
|
|
+ });
|
|
+ }
|
|
+ // Leaves end - pca
|
|
}
|
|
|
|
@Override
|
|
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
|
|
index 272095d7a09ab41227d741172735f66fd2798ce1..f6acbef804a50c58f4298ebeae4fdbebaf129e1c 100644
|
|
--- a/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
|
|
+++ b/src/main/java/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java
|
|
@@ -129,7 +129,13 @@ public abstract class AbstractMinecartContainer extends AbstractMinecart impleme
|
|
}
|
|
|
|
@Override
|
|
- public void setChanged() {}
|
|
+ public void setChanged() {
|
|
+ // Leaves start - pca
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncEntityToClient(this);
|
|
+ }
|
|
+ // Leaves end - pca
|
|
+ }
|
|
|
|
@Override
|
|
public boolean stillValid(Player player) {
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
|
index 448fa4f4f200430d6ce3051763c7ceb697696146..6171f1ec26a822f89c126f64edf3e02a354239df 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java
|
|
@@ -569,6 +569,16 @@ public abstract class AbstractFurnaceBlockEntity extends BaseContainerBlockEntit
|
|
|
|
}
|
|
|
|
+ // Leaves start - pca
|
|
+ @Override
|
|
+ public void setChanged() {
|
|
+ super.setChanged();
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
|
+ }
|
|
+ }
|
|
+ // Leaves end - pca
|
|
+
|
|
@Override
|
|
public boolean stillValid(net.minecraft.world.entity.player.Player player) {
|
|
return Container.stillValidBlockEntity(this, player);
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
|
index 416aa989ebb18a8741cc9d605a1180ab830f6643..213bc3c11ff4ed9bc761e8153aa669d1e2301960 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/BarrelBlockEntity.java
|
|
@@ -131,6 +131,16 @@ public class BarrelBlockEntity extends RandomizableContainerBlockEntity {
|
|
this.items = list;
|
|
}
|
|
|
|
+ // Leaves start - pca
|
|
+ @Override
|
|
+ public void setChanged() {
|
|
+ super.setChanged();
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
|
+ }
|
|
+ }
|
|
+ // Leaves end - pca
|
|
+
|
|
@Override
|
|
protected Component getDefaultName() {
|
|
return Component.translatable("container.barrel");
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
|
|
index 41c9f074203915c31c1ae7a160ce509c13383f84..4c9e84dcd154a4306659ef41ab40127ea8452835 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
|
|
@@ -4,6 +4,7 @@ import com.google.common.collect.Lists;
|
|
import java.util.Arrays;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
+import java.util.Objects;
|
|
import javax.annotation.Nullable;
|
|
import net.minecraft.core.BlockPos;
|
|
import net.minecraft.core.Direction;
|
|
@@ -127,6 +128,11 @@ public class BeehiveBlockEntity extends BlockEntity {
|
|
super.setChanged();
|
|
}
|
|
|
|
+ // Leaves start - pca
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
|
+ }
|
|
+ // Leaves end - pca
|
|
return list;
|
|
}
|
|
|
|
@@ -188,6 +194,12 @@ public class BeehiveBlockEntity extends BlockEntity {
|
|
this.level.gameEvent(GameEvent.BLOCK_CHANGE, blockposition, GameEvent.Context.of(entity, this.getBlockState()));
|
|
}
|
|
|
|
+ // Leaves start - pca
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
|
+ }
|
|
+ // Leaves end - pca
|
|
+
|
|
entity.discard();
|
|
super.setChanged();
|
|
}
|
|
@@ -334,6 +346,11 @@ public class BeehiveBlockEntity extends BlockEntity {
|
|
if (BeehiveBlockEntity.releaseOccupant(world, pos, state, tileentitybeehive_hivebee, (List) null, tileentitybeehive_releasestatus, flowerPos)) {
|
|
flag = true;
|
|
iterator.remove();
|
|
+ // Leaves start - pca
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(Objects.requireNonNull(world.getBlockEntity(pos)));
|
|
+ }
|
|
+ // Leaves end - pca
|
|
// CraftBukkit start
|
|
} else {
|
|
tileentitybeehive_hivebee.exitTickCounter = tileentitybeehive_hivebee.minOccupationTicks / 2; // Not strictly Vanilla behaviour in cases where bees cannot spawn but still reasonable // Paper - use exitTickCounter to keep actual bee life
|
|
@@ -385,6 +402,11 @@ public class BeehiveBlockEntity extends BlockEntity {
|
|
this.maxBees = nbt.getInt("Bukkit.MaxEntities");
|
|
}
|
|
// CraftBukkit end
|
|
+ // Leaves start - pca
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
|
+ }
|
|
+ // Leaves end - pca
|
|
}
|
|
|
|
@Override
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
|
|
index c57efcb9a79337ec791e4e8f6671612f0a82b441..218fbc794b086c2c3c04a3d183a0d43dcb74c4c2 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
|
|
@@ -334,6 +334,16 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements
|
|
|
|
}
|
|
|
|
+ // Leaves start - pca
|
|
+ @Override
|
|
+ public void setChanged() {
|
|
+ super.setChanged();
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
|
+ }
|
|
+ }
|
|
+ // Leaves end - pca
|
|
+
|
|
@Override
|
|
public boolean stillValid(Player player) {
|
|
return Container.stillValidBlockEntity(this, player);
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
|
index a71414397bd45ee7bcacfeef0041d80dfa25f114..1d6c7a04b8246a60d80325e1615e50573b17a6bb 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
|
@@ -190,6 +190,16 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement
|
|
this.items = list;
|
|
}
|
|
|
|
+ // Leaves start - pca
|
|
+ @Override
|
|
+ public void setChanged() {
|
|
+ super.setChanged();
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
|
+ }
|
|
+ }
|
|
+ // Leaves end - pca
|
|
+
|
|
@Override
|
|
public float getOpenNess(float tickDelta) {
|
|
return this.chestLidController.getOpenness(tickDelta);
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/ComparatorBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ComparatorBlockEntity.java
|
|
index 9b2c162c362fcf6093a3bf6da715ae8f18176c82..84b877a712a883b868b139d29da7e09c9552a1e5 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/ComparatorBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/ComparatorBlockEntity.java
|
|
@@ -23,6 +23,16 @@ public class ComparatorBlockEntity extends BlockEntity {
|
|
this.output = nbt.getInt("OutputSignal");
|
|
}
|
|
|
|
+ // Leaves start - pca
|
|
+ @Override
|
|
+ public void setChanged() {
|
|
+ super.setChanged();
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
|
+ }
|
|
+ }
|
|
+ // Leaves end - pca
|
|
+
|
|
public int getOutputSignal() {
|
|
return this.output;
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java
|
|
index 881379681c39230a00b3a1f11cd87498984396c7..e01eb2025458cf311348c58a1530854053af78f4 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/DispenserBlockEntity.java
|
|
@@ -92,6 +92,16 @@ public class DispenserBlockEntity extends RandomizableContainerBlockEntity {
|
|
return -1;
|
|
}
|
|
|
|
+ // Leaves start - pca
|
|
+ @Override
|
|
+ public void setChanged() {
|
|
+ super.setChanged();
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
|
+ }
|
|
+ }
|
|
+ // Leaves end - pca
|
|
+
|
|
@Override
|
|
protected Component getDefaultName() {
|
|
return Component.translatable("container.dispenser");
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
|
index a8a26a0a37a08b6bbeb5a1fde417d6f448d3c79f..3eff0f2bd38b7b2a88183d5da51c6086b8aea340 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
|
|
@@ -129,6 +129,16 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
|
|
|
}
|
|
|
|
+ // Leaves start - pca
|
|
+ @Override
|
|
+ public void setChanged() {
|
|
+ super.setChanged();
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
|
+ }
|
|
+ }
|
|
+ // Leaves end - pca
|
|
+
|
|
@Override
|
|
protected Component getDefaultName() {
|
|
return Component.translatable("container.hopper");
|
|
@@ -169,6 +179,11 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
|
|
if (flag) {
|
|
blockEntity.setCooldown(world.spigotConfig.hopperTransfer); // Spigot
|
|
setChanged(world, pos, state);
|
|
+ // Leaves start - pca
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(blockEntity);
|
|
+ }
|
|
+ // Leaves end - pca
|
|
return true;
|
|
}
|
|
}
|
|
diff --git a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
|
|
index b7686fd63b7c5d88c3a12ec4ee9bc01a17f997e0..25a9c38c60d183bb65b14f4d7550ab98b431c218 100644
|
|
--- a/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
|
|
+++ b/src/main/java/net/minecraft/world/level/block/entity/ShulkerBoxBlockEntity.java
|
|
@@ -259,6 +259,16 @@ public class ShulkerBoxBlockEntity extends RandomizableContainerBlockEntity impl
|
|
this.itemStacks = list;
|
|
}
|
|
|
|
+ // Leaves start - pca
|
|
+ @Override
|
|
+ public void setChanged() {
|
|
+ super.setChanged();
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.syncBlockEntityToClient(this);
|
|
+ }
|
|
+ }
|
|
+ // Leaves end - pca
|
|
+
|
|
@Override
|
|
public int[] getSlotsForFace(Direction side) {
|
|
return ShulkerBoxBlockEntity.SLOTS;
|
|
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
index 7623ebe3bfc508183f67b84e1f1815697ed98ba8..c7f113730842f643b5c764d32e8c30d6df73648d 100644
|
|
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
|
@@ -462,6 +462,7 @@ public final class CraftServer implements Server {
|
|
MapPalette.setMapColorCache(new CraftMapColorCache(this.logger));
|
|
}
|
|
datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.init(); // Leaves - pca
|
|
}
|
|
|
|
public boolean getCommandBlockOverride(String command) {
|
|
@@ -1054,6 +1055,13 @@ public final class CraftServer implements Server {
|
|
org.spigotmc.SpigotConfig.init((File) console.options.valueOf("spigot-settings")); // Spigot
|
|
this.console.paperConfigurations.reloadConfigs(this.console);
|
|
top.leavesmc.leaves.LeavesConfig.init((File) console.options.valueOf("leaves-settings")); // Leaves - Server Config
|
|
+ // Leaves start - pca
|
|
+ if (top.leavesmc.leaves.LeavesConfig.pcaSyncProtocol) {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.enablePcaSyncProtocolGlobal();
|
|
+ } else {
|
|
+ top.leavesmc.leaves.protocol.PcaSyncProtocol.disablePcaSyncProtocolGlobal();
|
|
+ }
|
|
+ // Leaves end - pca
|
|
for (ServerLevel world : this.console.getAllLevels()) {
|
|
// world.serverLevelData.setDifficulty(config.difficulty); // Paper - per level difficulty
|
|
world.setSpawnSettings(world.serverLevelData.getDifficulty() != Difficulty.PEACEFUL && config.spawnMonsters, config.spawnAnimals); // Paper - per level difficulty (from MinecraftServer#setDifficulty(ServerLevel, Difficulty, boolean))
|
|
diff --git a/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java b/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java
|
|
new file mode 100644
|
|
index 0000000000000000000000000000000000000000..819c89946670cc41f390d1855cf7159aec6bb1b5
|
|
--- /dev/null
|
|
+++ b/src/main/java/top/leavesmc/leaves/protocol/PcaSyncProtocol.java
|
|
@@ -0,0 +1,357 @@
|
|
+package top.leavesmc.leaves.protocol;
|
|
+
|
|
+import io.netty.buffer.Unpooled;
|
|
+import net.minecraft.core.BlockPos;
|
|
+import net.minecraft.nbt.CompoundTag;
|
|
+import net.minecraft.network.FriendlyByteBuf;
|
|
+import net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket;
|
|
+import net.minecraft.resources.ResourceLocation;
|
|
+import net.minecraft.server.MinecraftServer;
|
|
+import net.minecraft.server.level.ServerLevel;
|
|
+import net.minecraft.server.level.ServerPlayer;
|
|
+import net.minecraft.world.entity.Entity;
|
|
+import net.minecraft.world.entity.player.Player;
|
|
+import net.minecraft.world.level.Level;
|
|
+import net.minecraft.world.level.block.ChestBlock;
|
|
+import net.minecraft.world.level.block.entity.BlockEntity;
|
|
+import net.minecraft.world.level.block.state.BlockState;
|
|
+import net.minecraft.world.level.block.state.properties.ChestType;
|
|
+import org.apache.commons.lang3.tuple.ImmutablePair;
|
|
+import org.apache.commons.lang3.tuple.MutablePair;
|
|
+import org.apache.commons.lang3.tuple.Pair;
|
|
+import org.apache.logging.log4j.util.TriConsumer;
|
|
+import org.jetbrains.annotations.Contract;
|
|
+import org.jetbrains.annotations.NotNull;
|
|
+import org.jetbrains.annotations.Nullable;
|
|
+import top.leavesmc.leaves.LeavesConfig;
|
|
+import top.leavesmc.leaves.LeavesLogger;
|
|
+import top.leavesmc.leaves.bot.ServerBot;
|
|
+import top.leavesmc.leaves.util.ProtocolUtils;
|
|
+
|
|
+import java.util.HashMap;
|
|
+import java.util.HashSet;
|
|
+import java.util.Map;
|
|
+import java.util.Set;
|
|
+import java.util.concurrent.locks.ReentrantLock;
|
|
+
|
|
+public class PcaSyncProtocol {
|
|
+
|
|
+ public static final String PROTOCOL_ID = "pca";
|
|
+
|
|
+ public static final ReentrantLock lock = new ReentrantLock(true);
|
|
+ public static final ReentrantLock pairLock = new ReentrantLock(true);
|
|
+
|
|
+ // send
|
|
+ private static final ResourceLocation ENABLE_PCA_SYNC_PROTOCOL = id("enable_pca_sync_protocol");
|
|
+ private static final ResourceLocation DISABLE_PCA_SYNC_PROTOCOL = id("disable_pca_sync_protocol");
|
|
+ private static final ResourceLocation UPDATE_ENTITY = id("update_entity");
|
|
+ private static final ResourceLocation UPDATE_BLOCK_ENTITY = id("update_block_entity");
|
|
+ // call
|
|
+ private static final ResourceLocation SYNC_BLOCK_ENTITY = id("sync_block_entity");
|
|
+ private static final ResourceLocation SYNC_ENTITY = id("sync_entity");
|
|
+ private static final ResourceLocation CANCEL_SYNC_BLOCK_ENTITY = id("cancel_sync_block_entity");
|
|
+ private static final ResourceLocation CANCEL_SYNC_ENTITY = id("cancel_sync_entity");
|
|
+ private static final Map<ServerPlayer, Pair<ResourceLocation, BlockPos>> playerWatchBlockPos = new HashMap<>();
|
|
+ private static final Map<ServerPlayer, Pair<ResourceLocation, Entity>> playerWatchEntity = new HashMap<>();
|
|
+ private static final Map<Pair<ResourceLocation, BlockPos>, Set<ServerPlayer>> blockPosWatchPlayerSet = new HashMap<>();
|
|
+ private static final Map<Pair<ResourceLocation, Entity>, Set<ServerPlayer>> entityWatchPlayerSet = new HashMap<>();
|
|
+ private static final MutablePair<ResourceLocation, Entity> ResourceLocationEntityPair = new MutablePair<>();
|
|
+ private static final MutablePair<ResourceLocation, BlockPos> ResourceLocationBlockPosPair = new MutablePair<>();
|
|
+
|
|
+ @Contract("_ -> new")
|
|
+ public static @NotNull ResourceLocation id(String path) {
|
|
+ return new ResourceLocation(PROTOCOL_ID, path);
|
|
+ }
|
|
+
|
|
+ public static void enablePcaSyncProtocol(@NotNull ServerPlayer player) {
|
|
+ FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
|
+ ProtocolUtils.sendPayloadPacket(player, ENABLE_PCA_SYNC_PROTOCOL, buf);
|
|
+ lock.lock();
|
|
+ lock.unlock();
|
|
+ }
|
|
+
|
|
+ public static void disablePcaSyncProtocol(@NotNull ServerPlayer player) {
|
|
+ FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
|
+ ProtocolUtils.sendPayloadPacket(player, DISABLE_PCA_SYNC_PROTOCOL, buf);
|
|
+ }
|
|
+
|
|
+ public static void updateEntity(@NotNull ServerPlayer player, @NotNull Entity entity) {
|
|
+ FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
|
+ buf.writeResourceLocation(entity.level().dimension().location());
|
|
+ buf.writeInt(entity.getId());
|
|
+ buf.writeNbt(entity.saveWithoutId(new CompoundTag()));
|
|
+ ProtocolUtils.sendPayloadPacket(player, UPDATE_ENTITY, buf);
|
|
+ }
|
|
+
|
|
+ public static void updateBlockEntity(@NotNull ServerPlayer player, @NotNull BlockEntity blockEntity) {
|
|
+ Level world = blockEntity.getLevel();
|
|
+
|
|
+ if (world == null) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
|
+ buf.writeResourceLocation(world.dimension().location());
|
|
+ buf.writeBlockPos(blockEntity.getBlockPos());
|
|
+ buf.writeNbt(blockEntity.saveWithId());
|
|
+ ProtocolUtils.sendPayloadPacket(player, UPDATE_BLOCK_ENTITY, buf);
|
|
+ }
|
|
+
|
|
+ private static final Map<ResourceLocation, TriConsumer<MinecraftServer, ServerPlayer, FriendlyByteBuf>> globalReceivers = new HashMap<>();
|
|
+
|
|
+ private static void registerGlobalReceiver(ResourceLocation identifier, TriConsumer<MinecraftServer, ServerPlayer, FriendlyByteBuf> consumer) {
|
|
+ globalReceivers.put(identifier, consumer);
|
|
+ }
|
|
+
|
|
+ public static void handlePacket(MinecraftServer server, ServerPlayer player, @NotNull ServerboundCustomPayloadPacket packet) {
|
|
+ globalReceivers.getOrDefault(
|
|
+ packet.identifier, ((server1, player1, buf) -> LeavesLogger.LOGGER.severe("NullPotion"))
|
|
+ ).accept(server, player, packet.data);
|
|
+ }
|
|
+
|
|
+ public static void init() {
|
|
+ registerGlobalReceiver(SYNC_BLOCK_ENTITY, PcaSyncProtocol::syncBlockEntityHandler);
|
|
+ registerGlobalReceiver(SYNC_ENTITY, PcaSyncProtocol::syncEntityHandler);
|
|
+ registerGlobalReceiver(CANCEL_SYNC_BLOCK_ENTITY, PcaSyncProtocol::cancelSyncBlockEntityHandler);
|
|
+ registerGlobalReceiver(CANCEL_SYNC_ENTITY, PcaSyncProtocol::cancelSyncEntityHandler);
|
|
+ }
|
|
+
|
|
+ public static void onJoin(ServerPlayer player) {
|
|
+ if (LeavesConfig.pcaSyncProtocol) {
|
|
+ enablePcaSyncProtocol(player);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static void cancelSyncBlockEntityHandler(MinecraftServer server, ServerPlayer player,
|
|
+ FriendlyByteBuf buf) {
|
|
+ if (!LeavesConfig.pcaSyncProtocol) {
|
|
+ return;
|
|
+ }
|
|
+ PcaSyncProtocol.clearPlayerWatchBlock(player);
|
|
+ }
|
|
+
|
|
+ private static void cancelSyncEntityHandler(MinecraftServer server, ServerPlayer player,
|
|
+ FriendlyByteBuf buf) {
|
|
+ if (!LeavesConfig.pcaSyncProtocol) {
|
|
+ return;
|
|
+ }
|
|
+ PcaSyncProtocol.clearPlayerWatchEntity(player);
|
|
+ }
|
|
+
|
|
+ private static void syncBlockEntityHandler(MinecraftServer server, ServerPlayer player,
|
|
+ FriendlyByteBuf buf) {
|
|
+ if (!LeavesConfig.pcaSyncProtocol) {
|
|
+ return;
|
|
+ }
|
|
+ BlockPos pos = buf.readBlockPos();
|
|
+ ServerLevel world = player.serverLevel();
|
|
+ BlockState blockState = world.getBlockState(pos);
|
|
+ clearPlayerWatchData(player);
|
|
+
|
|
+ BlockEntity blockEntityAdj = null;
|
|
+ if (blockState.getBlock() instanceof ChestBlock) {
|
|
+ if (blockState.getValue(ChestBlock.TYPE) != ChestType.SINGLE) {
|
|
+ BlockPos posAdj = pos.offset(ChestBlock.getConnectedDirection(blockState).getNormal());
|
|
+ // The method in World now checks that the caller is from the same thread...
|
|
+ blockEntityAdj = world.getChunk(posAdj).getBlockEntity(posAdj);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (blockEntityAdj != null) {
|
|
+ updateBlockEntity(player, blockEntityAdj);
|
|
+ }
|
|
+
|
|
+ // The method in World now checks that the caller is from the same thread...
|
|
+ BlockEntity blockEntity = world.getChunk(pos).getBlockEntity(pos);
|
|
+ if (blockEntity != null) {
|
|
+ updateBlockEntity(player, blockEntity);
|
|
+ }
|
|
+
|
|
+ Pair<ResourceLocation, BlockPos> pair = new ImmutablePair<>(player.level().dimension().location(), pos);
|
|
+ lock.lock();
|
|
+ playerWatchBlockPos.put(player, pair);
|
|
+ if (!blockPosWatchPlayerSet.containsKey(pair)) {
|
|
+ blockPosWatchPlayerSet.put(pair, new HashSet<>());
|
|
+ }
|
|
+ blockPosWatchPlayerSet.get(pair).add(player);
|
|
+ lock.unlock();
|
|
+ }
|
|
+
|
|
+ private static void syncEntityHandler(MinecraftServer server, ServerPlayer player,
|
|
+ FriendlyByteBuf buf) {
|
|
+ if (!LeavesConfig.pcaSyncProtocol) {
|
|
+ return;
|
|
+ }
|
|
+ int entityId = buf.readInt();
|
|
+ ServerLevel world = player.serverLevel();
|
|
+ Entity entity = world.getEntity(entityId);
|
|
+ if (entity != null) {
|
|
+ clearPlayerWatchData(player);
|
|
+ if (entity instanceof Player) {
|
|
+ if (LeavesConfig.pcaSyncPlayerEntity.equals("NOBODY")) {
|
|
+ return;
|
|
+ } else if (LeavesConfig.pcaSyncPlayerEntity.equals("BOT")) {
|
|
+ if (!(entity instanceof ServerBot)) {
|
|
+ return;
|
|
+ }
|
|
+ } else if (LeavesConfig.pcaSyncPlayerEntity.equals("OPS")) {
|
|
+ if (!(entity instanceof ServerBot) && server.getProfilePermissions(player.getGameProfile()) < 2) {
|
|
+ return;
|
|
+ }
|
|
+ } else if (LeavesConfig.pcaSyncPlayerEntity.equals("OPS_AND_SELF")) {
|
|
+ if (!(entity instanceof ServerBot) &&
|
|
+ server.getProfilePermissions(player.getGameProfile()) < 2 &&
|
|
+ entity != player) {
|
|
+ return;
|
|
+ }
|
|
+ } else if (!LeavesConfig.pcaSyncPlayerEntity.equals("EVERYONE")) {
|
|
+ // wtf????
|
|
+ LeavesLogger.LOGGER.warning("pcaSyncPlayerEntity wtf???");
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ updateEntity(player, entity);
|
|
+
|
|
+ Pair<ResourceLocation, Entity> pair = new ImmutablePair<>(entity.level().dimension().location(), entity);
|
|
+ lock.lock();
|
|
+ playerWatchEntity.put(player, pair);
|
|
+ if (!entityWatchPlayerSet.containsKey(pair)) {
|
|
+ entityWatchPlayerSet.put(pair, new HashSet<>());
|
|
+ }
|
|
+ entityWatchPlayerSet.get(pair).add(player);
|
|
+ lock.unlock();
|
|
+ }
|
|
+ }
|
|
+
|
|
+ private static MutablePair<ResourceLocation, Entity> getResourceLocationEntityPair(ResourceLocation ResourceLocation, Entity entity) {
|
|
+ pairLock.lock();
|
|
+ ResourceLocationEntityPair.setLeft(ResourceLocation);
|
|
+ ResourceLocationEntityPair.setRight(entity);
|
|
+ pairLock.unlock();
|
|
+ return ResourceLocationEntityPair;
|
|
+ }
|
|
+
|
|
+ private static MutablePair<ResourceLocation, BlockPos> getResourceLocationBlockPosPair(ResourceLocation ResourceLocation, BlockPos pos) {
|
|
+ pairLock.lock();
|
|
+ ResourceLocationBlockPosPair.setLeft(ResourceLocation);
|
|
+ ResourceLocationBlockPosPair.setRight(pos);
|
|
+ pairLock.unlock();
|
|
+ return ResourceLocationBlockPosPair;
|
|
+ }
|
|
+
|
|
+ private static @Nullable Set<ServerPlayer> getWatchPlayerList(@NotNull Entity entity) {
|
|
+ return entityWatchPlayerSet.get(getResourceLocationEntityPair(entity.level().dimension().location(), entity));
|
|
+ }
|
|
+
|
|
+ private static @Nullable Set<ServerPlayer> getWatchPlayerList(@NotNull Level world, @NotNull BlockPos blockPos) {
|
|
+ return blockPosWatchPlayerSet.get(getResourceLocationBlockPosPair(world.dimension().location(), blockPos));
|
|
+ }
|
|
+
|
|
+ public static boolean syncEntityToClient(@NotNull Entity entity) {
|
|
+ if (entity.level().isClientSide()) {
|
|
+ return false;
|
|
+ }
|
|
+ lock.lock();
|
|
+ Set<ServerPlayer> playerList = getWatchPlayerList(entity);
|
|
+ boolean ret = false;
|
|
+ if (playerList != null) {
|
|
+ for (ServerPlayer player : playerList) {
|
|
+ updateEntity(player, entity);
|
|
+ ret = true;
|
|
+ }
|
|
+ }
|
|
+ lock.unlock();
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ public static boolean syncBlockEntityToClient(@NotNull BlockEntity blockEntity) {
|
|
+ boolean ret = false;
|
|
+ Level world = blockEntity.getLevel();
|
|
+ BlockPos pos = blockEntity.getBlockPos();
|
|
+ if (world != null) {
|
|
+ if (world.isClientSide()) {
|
|
+ return false;
|
|
+ }
|
|
+ BlockState blockState = world.getBlockState(pos);
|
|
+ lock.lock();
|
|
+ Set<ServerPlayer> playerList = getWatchPlayerList(world, blockEntity.getBlockPos());
|
|
+
|
|
+ Set<ServerPlayer> playerListAdj = null;
|
|
+
|
|
+ if (blockState.getBlock() instanceof ChestBlock) {
|
|
+ if (blockState.getValue(ChestBlock.TYPE) != ChestType.SINGLE) {
|
|
+ BlockPos posAdj = pos.offset(ChestBlock.getConnectedDirection(blockState).getNormal());
|
|
+ playerListAdj = getWatchPlayerList(world, posAdj);
|
|
+ }
|
|
+ }
|
|
+ if (playerListAdj != null) {
|
|
+ if (playerList == null) {
|
|
+ playerList = playerListAdj;
|
|
+ } else {
|
|
+ playerList.addAll(playerListAdj);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (playerList != null) {
|
|
+ for (ServerPlayer player : playerList) {
|
|
+ updateBlockEntity(player, blockEntity);
|
|
+ ret = true;
|
|
+ }
|
|
+ }
|
|
+ lock.unlock();
|
|
+ }
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ private static void clearPlayerWatchEntity(ServerPlayer player) {
|
|
+ lock.lock();
|
|
+ Pair<ResourceLocation, Entity> pair = playerWatchEntity.get(player);
|
|
+ if (pair != null) {
|
|
+ Set<ServerPlayer> playerSet = entityWatchPlayerSet.get(pair);
|
|
+ playerSet.remove(player);
|
|
+ if (playerSet.isEmpty()) {
|
|
+ entityWatchPlayerSet.remove(pair);
|
|
+ }
|
|
+ playerWatchEntity.remove(player);
|
|
+ }
|
|
+ lock.unlock();
|
|
+ }
|
|
+
|
|
+ private static void clearPlayerWatchBlock(ServerPlayer player) {
|
|
+ lock.lock();
|
|
+ Pair<ResourceLocation, BlockPos> pair = playerWatchBlockPos.get(player);
|
|
+ if (pair != null) {
|
|
+ Set<ServerPlayer> playerSet = blockPosWatchPlayerSet.get(pair);
|
|
+ playerSet.remove(player);
|
|
+ if (playerSet.isEmpty()) {
|
|
+ blockPosWatchPlayerSet.remove(pair);
|
|
+ }
|
|
+ playerWatchBlockPos.remove(player);
|
|
+ }
|
|
+ lock.unlock();
|
|
+ }
|
|
+
|
|
+ public static void disablePcaSyncProtocolGlobal() {
|
|
+ lock.lock();
|
|
+ playerWatchBlockPos.clear();
|
|
+ playerWatchEntity.clear();
|
|
+ blockPosWatchPlayerSet.clear();
|
|
+ entityWatchPlayerSet.clear();
|
|
+ lock.unlock();
|
|
+ for (ServerPlayer player : MinecraftServer.getServer().getPlayerList().getPlayers()) {
|
|
+ disablePcaSyncProtocol(player);
|
|
+ }
|
|
+ }
|
|
+
|
|
+ public static void enablePcaSyncProtocolGlobal() {
|
|
+ for (ServerPlayer player : MinecraftServer.getServer().getPlayerList().getPlayers()) {
|
|
+ enablePcaSyncProtocol(player);
|
|
+ }
|
|
+ }
|
|
+
|
|
+
|
|
+ public static void clearPlayerWatchData(ServerPlayer player) {
|
|
+ PcaSyncProtocol.clearPlayerWatchBlock(player);
|
|
+ PcaSyncProtocol.clearPlayerWatchEntity(player);
|
|
+ }
|
|
+}
|