geforkt von Mirrors/AxiomPaperPlugin
Merge pull request '1.20.1' (#4) from Mirrors/AxiomPaperPlugin:1.20.1 into master
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful
Reviewed-on: #4
Dieser Commit ist enthalten in:
Commit
db7d852705
@ -1,14 +1,14 @@
|
||||
plugins {
|
||||
`java-library`
|
||||
id("io.papermc.paperweight.userdev") version "1.5.5"
|
||||
id("xyz.jpenilla.run-paper") version "2.1.0" // Adds runServer and runMojangMappedServer tasks for testing
|
||||
id("io.papermc.paperweight.userdev") version "1.5.8"
|
||||
id("xyz.jpenilla.run-paper") version "2.2.0" // Adds runServer and runMojangMappedServer tasks for testing
|
||||
|
||||
// Shades and relocates dependencies into our plugin jar. See https://imperceptiblethoughts.com/shadow/introduction/
|
||||
id("com.github.johnrengelman.shadow") version "8.1.1"
|
||||
}
|
||||
|
||||
group = "com.moulberry.axiom"
|
||||
version = "1.2.1"
|
||||
version = "1.5.1"
|
||||
description = "Serverside component for Axiom on Paper"
|
||||
|
||||
java {
|
||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
|
||||
networkTimeout=10000
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
@ -12,7 +12,7 @@ public class AxiomConstants {
|
||||
}
|
||||
}
|
||||
|
||||
public static final int API_VERSION = 6;
|
||||
public static final int API_VERSION = 7;
|
||||
public static final NamespacedKey ACTIVE_HOTBAR_INDEX = new NamespacedKey("axiom", "active_hotbar_index");
|
||||
public static final NamespacedKey HOTBAR_DATA = new NamespacedKey("axiom", "hotbar_data");
|
||||
|
||||
|
@ -2,10 +2,7 @@ package com.moulberry.axiom;
|
||||
|
||||
import com.moulberry.axiom.buffer.CompressedBlockEntity;
|
||||
import com.moulberry.axiom.event.AxiomCreateWorldPropertiesEvent;
|
||||
import com.moulberry.axiom.event.AxiomTimeChangeEvent;
|
||||
import com.moulberry.axiom.packet.*;
|
||||
import com.moulberry.axiom.world_properties.WorldPropertyCategory;
|
||||
import com.moulberry.axiom.world_properties.WorldPropertyWidgetType;
|
||||
import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry;
|
||||
import com.moulberry.axiom.world_properties.server.ServerWorldProperty;
|
||||
import io.netty.buffer.Unpooled;
|
||||
@ -22,13 +19,11 @@ import net.minecraft.network.protocol.Packet;
|
||||
import net.minecraft.network.protocol.PacketFlow;
|
||||
import net.minecraft.network.protocol.game.ServerboundCustomPayloadPacket;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import org.bukkit.*;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerChangedWorldEvent;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.plugin.messaging.Messenger;
|
||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
@ -56,7 +51,7 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:enable");
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:initialize_hotbars");
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:set_editor_views");
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:block_entities");
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:response_chunk_data");
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:register_world_properties");
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:set_world_property");
|
||||
msg.registerOutgoingPluginChannel(this, "axiom:ack_world_properties");
|
||||
@ -71,7 +66,7 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
||||
msg.registerIncomingPluginChannel(this, "axiom:switch_active_hotbar", new SwitchActiveHotbarPacketListener());
|
||||
msg.registerIncomingPluginChannel(this, "axiom:teleport", new TeleportPacketListener());
|
||||
msg.registerIncomingPluginChannel(this, "axiom:set_editor_views", new SetEditorViewsPacketListener());
|
||||
msg.registerIncomingPluginChannel(this, "axiom:request_block_entity", new RequestBlockEntityPacketListener(this));
|
||||
msg.registerIncomingPluginChannel(this, "axiom:request_chunk_data", new RequestChunkDataPacketListener(this));
|
||||
|
||||
SetBlockBufferPacketListener setBlockBufferPacketListener = new SetBlockBufferPacketListener(this);
|
||||
|
||||
@ -104,7 +99,9 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
||||
if (!player.hasPermission("axiom.*")) {
|
||||
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||
buf.writeBoolean(false);
|
||||
player.sendPluginMessage(this, "axiom:enable", buf.accessByteBufWithCorrectSize());
|
||||
byte[] bytes = new byte[buf.writerIndex()];
|
||||
buf.getBytes(0, bytes);
|
||||
player.sendPluginMessage(this, "axiom:enable", bytes);
|
||||
} else {
|
||||
newActiveAxiomPlayers.add(player.getUniqueId());
|
||||
}
|
||||
@ -130,9 +127,12 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onFailMove(PlayerFailMoveEvent event) {
|
||||
if (event.getPlayer().hasPermission("axiom.*") &&
|
||||
event.getFailReason() == PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY) {
|
||||
event.setAllowed(true);
|
||||
if (event.getPlayer().hasPermission("axiom.*")) {
|
||||
if (event.getFailReason() == PlayerFailMoveEvent.FailReason.MOVED_TOO_QUICKLY) {
|
||||
event.setAllowed(true); // Support for arcball camera
|
||||
} else if (event.getPlayer().isFlying()) {
|
||||
event.setAllowed(true); // Support for noclip
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,22 +149,6 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onJoin(PlayerJoinEvent event) {
|
||||
Player player = event.getPlayer();
|
||||
Bukkit.getScheduler().scheduleSyncDelayedTask(this, () -> {
|
||||
World world = player.getWorld();
|
||||
|
||||
ServerWorldPropertiesRegistry properties = getWorldProperties(world);
|
||||
|
||||
if (properties == null) {
|
||||
player.sendPluginMessage(this, "axiom:register_world_properties", new byte[]{0});
|
||||
} else {
|
||||
properties.registerFor(this, player);
|
||||
}
|
||||
}, 20); // Why does this need to be delayed?
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onGameRuleChanged(WorldGameRuleChangeEvent event) {
|
||||
if (event.getGameRule() == GameRule.DO_WEATHER_CYCLE) {
|
||||
|
@ -47,7 +47,7 @@ public class RegionProtectionWorldGuard {
|
||||
// Don't do any protection if player has bypass
|
||||
if (platform.getSessionManager().hasBypass(worldGuardPlayer, worldEditWorld)) {
|
||||
// todo: enable bypass
|
||||
// return null;
|
||||
return null;
|
||||
}
|
||||
|
||||
RegionManager regionManager = regionContainer.get(worldEditWorld);
|
||||
@ -108,7 +108,7 @@ public class RegionProtectionWorldGuard {
|
||||
// }
|
||||
}
|
||||
|
||||
System.out.println("returning default");
|
||||
// System.out.println("returning default");
|
||||
StateFlag.State fallback = Flags.BUILD.getDefault();
|
||||
return fallback == StateFlag.State.DENY ? SectionProtection.DENY : SectionProtection.ALLOW;
|
||||
}
|
||||
@ -117,7 +117,7 @@ public class RegionProtectionWorldGuard {
|
||||
for (Map.Entry<ProtectedRegion, StateFlag.State> entry : consideredValues.entrySet()) {
|
||||
ProtectedRegion region = entry.getKey();
|
||||
if (entry.getValue() == StateFlag.State.DENY) {
|
||||
System.out.println("found region with deny!");
|
||||
// System.out.println("found region with deny!");
|
||||
if (region instanceof GlobalProtectedRegion) {
|
||||
return SectionProtection.DENY;
|
||||
} else if (region instanceof ProtectedCuboidRegion && doesRegionCompletelyContainSection(region, cx, cy, cz)) {
|
||||
@ -128,7 +128,7 @@ public class RegionProtectionWorldGuard {
|
||||
}
|
||||
|
||||
if (hasPartialDeny) {
|
||||
System.out.println("returning check!");
|
||||
// System.out.println("returning check!");
|
||||
return new SectionProtection() {
|
||||
@Override
|
||||
public SectionState getSectionState() {
|
||||
@ -143,7 +143,7 @@ public class RegionProtectionWorldGuard {
|
||||
// return complex thing
|
||||
}
|
||||
|
||||
System.out.println("returning allow!");
|
||||
// System.out.println("returning allow!");
|
||||
return SectionProtection.ALLOW;
|
||||
}
|
||||
|
||||
|
@ -6,11 +6,14 @@ import com.moulberry.axiom.View;
|
||||
import com.moulberry.axiom.event.AxiomHandshakeEvent;
|
||||
import com.moulberry.axiom.persistence.ItemStackDataType;
|
||||
import com.moulberry.axiom.persistence.UUIDDataType;
|
||||
import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minecraft.SharedConstants;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.inventory.CraftItemStack;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -40,8 +43,14 @@ public class HelloPacketListener implements PluginMessageListener {
|
||||
|
||||
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message));
|
||||
int apiVersion = friendlyByteBuf.readVarInt();
|
||||
int dataVersion = friendlyByteBuf.readVarInt();
|
||||
friendlyByteBuf.readNbt(); // Discard
|
||||
|
||||
if (dataVersion != SharedConstants.getCurrentVersion().getDataVersion().getVersion()) {
|
||||
player.kick(Component.text("Axiom: Incompatible data version detected, are you using ViaVersion?"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (apiVersion != AxiomConstants.API_VERSION) {
|
||||
player.kick(Component.text("Unsupported Axiom API Version. Server supports " + AxiomConstants.API_VERSION +
|
||||
", while client is " + apiVersion));
|
||||
@ -66,7 +75,10 @@ public class HelloPacketListener implements PluginMessageListener {
|
||||
buf.writeVarInt(5); // Maximum Reach
|
||||
buf.writeVarInt(16); // Max editor views
|
||||
buf.writeBoolean(true); // Editable Views
|
||||
player.sendPluginMessage(this.plugin, "axiom:enable", buf.accessByteBufWithCorrectSize());
|
||||
|
||||
byte[] enableBytes = new byte[buf.writerIndex()];
|
||||
buf.getBytes(0, enableBytes);
|
||||
player.sendPluginMessage(this.plugin, "axiom:enable", enableBytes);
|
||||
|
||||
// Initialize Hotbars
|
||||
PersistentDataContainer container = player.getPersistentDataContainer();
|
||||
@ -84,7 +96,10 @@ public class HelloPacketListener implements PluginMessageListener {
|
||||
buf.writeItem(CraftItemStack.asNMSCopy(stack));
|
||||
}
|
||||
}
|
||||
player.sendPluginMessage(this.plugin, "axiom:initialize_hotbars", buf.accessByteBufWithCorrectSize());
|
||||
|
||||
byte[] bytes = new byte[buf.writerIndex()];
|
||||
buf.getBytes(0, bytes);
|
||||
player.sendPluginMessage(this.plugin, "axiom:initialize_hotbars", bytes);
|
||||
}
|
||||
|
||||
// Initialize Views
|
||||
@ -99,7 +114,19 @@ public class HelloPacketListener implements PluginMessageListener {
|
||||
View.load(view).write(buf);
|
||||
}
|
||||
|
||||
player.sendPluginMessage(this.plugin, "axiom:set_editor_views", buf.accessByteBufWithCorrectSize());
|
||||
byte[] bytes = new byte[buf.writerIndex()];
|
||||
buf.getBytes(0, bytes);
|
||||
player.sendPluginMessage(this.plugin, "axiom:set_editor_views", bytes);
|
||||
}
|
||||
|
||||
// Register world properties
|
||||
World world = player.getWorld();
|
||||
ServerWorldPropertiesRegistry properties = plugin.getWorldProperties(world);
|
||||
|
||||
if (properties == null) {
|
||||
player.sendPluginMessage(plugin, "axiom:register_world_properties", new byte[]{0});
|
||||
} else {
|
||||
properties.registerFor(plugin, player);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,90 +0,0 @@
|
||||
package com.moulberry.axiom.packet;
|
||||
|
||||
import com.moulberry.axiom.AxiomPaper;
|
||||
import com.moulberry.axiom.buffer.CompressedBlockEntity;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import it.unimi.dsi.fastutil.longs.*;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class RequestBlockEntityPacketListener implements PluginMessageListener {
|
||||
|
||||
private final AxiomPaper plugin;
|
||||
|
||||
public RequestBlockEntityPacketListener(AxiomPaper plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player bukkitPlayer, @NotNull byte[] message) {
|
||||
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message));
|
||||
long id = friendlyByteBuf.readLong();
|
||||
|
||||
if (!bukkitPlayer.hasPermission("axiom.*")) {
|
||||
// We always send an 'empty' response in order to make the client happy
|
||||
sendEmptyResponse(bukkitPlayer, id);
|
||||
return;
|
||||
}
|
||||
|
||||
ServerPlayer player = ((CraftPlayer)bukkitPlayer).getHandle();
|
||||
MinecraftServer server = player.getServer();
|
||||
if (server == null) {
|
||||
sendEmptyResponse(bukkitPlayer, id);
|
||||
return;
|
||||
}
|
||||
|
||||
ResourceKey<Level> worldKey = friendlyByteBuf.readResourceKey(Registries.DIMENSION);
|
||||
ServerLevel level = server.getLevel(worldKey);
|
||||
if (level == null) {
|
||||
sendEmptyResponse(bukkitPlayer, id);
|
||||
return;
|
||||
}
|
||||
|
||||
Long2ObjectMap<CompressedBlockEntity> map = new Long2ObjectOpenHashMap<>();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
|
||||
|
||||
// Save and compress block entities
|
||||
int count = friendlyByteBuf.readVarInt();
|
||||
for (int i = 0; i < count; i++) {
|
||||
long pos = friendlyByteBuf.readLong();
|
||||
BlockEntity blockEntity = level.getBlockEntity(mutableBlockPos.set(pos));
|
||||
if (blockEntity != null) {
|
||||
CompoundTag tag = blockEntity.saveWithoutMetadata();
|
||||
map.put(pos, CompressedBlockEntity.compress(tag, baos));
|
||||
}
|
||||
}
|
||||
|
||||
// Send response packet
|
||||
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer(16));
|
||||
buf.writeLong(id);
|
||||
buf.writeVarInt(map.size());
|
||||
for (Long2ObjectMap.Entry<CompressedBlockEntity> entry : map.long2ObjectEntrySet()) {
|
||||
buf.writeLong(entry.getLongKey());
|
||||
entry.getValue().write(buf);
|
||||
}
|
||||
bukkitPlayer.sendPluginMessage(this.plugin, "axiom:block_entities", buf.accessByteBufWithCorrectSize());
|
||||
}
|
||||
|
||||
private void sendEmptyResponse(Player player, long id) {
|
||||
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer(16));
|
||||
buf.writeLong(id);
|
||||
buf.writeByte(0); // no block entities
|
||||
player.sendPluginMessage(this.plugin, "axiom:block_entities", buf.accessByteBufWithCorrectSize());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,263 @@
|
||||
package com.moulberry.axiom.packet;
|
||||
|
||||
import com.moulberry.axiom.AxiomConstants;
|
||||
import com.moulberry.axiom.AxiomPaper;
|
||||
import com.moulberry.axiom.buffer.CompressedBlockEntity;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import it.unimi.dsi.fastutil.longs.*;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.protocol.game.ClientboundCustomPayloadPacket;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
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.level.Level;
|
||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import net.minecraft.world.level.chunk.LevelChunkSection;
|
||||
import net.minecraft.world.level.chunk.PalettedContainer;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
public class RequestChunkDataPacketListener implements PluginMessageListener {
|
||||
|
||||
private static final ResourceLocation RESPONSE_ID = new ResourceLocation("axiom:response_chunk_data");
|
||||
|
||||
private final AxiomPaper plugin;
|
||||
|
||||
public RequestChunkDataPacketListener(AxiomPaper plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player bukkitPlayer, @NotNull byte[] message) {
|
||||
ServerPlayer player = ((CraftPlayer)bukkitPlayer).getHandle();
|
||||
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message));
|
||||
long id = friendlyByteBuf.readLong();
|
||||
|
||||
if (!bukkitPlayer.hasPermission("axiom.*")) {
|
||||
// We always send an 'empty' response in order to make the client happy
|
||||
sendEmptyResponse(player, id);
|
||||
return;
|
||||
}
|
||||
|
||||
MinecraftServer server = player.getServer();
|
||||
if (server == null) {
|
||||
sendEmptyResponse(player, id);
|
||||
return;
|
||||
}
|
||||
|
||||
ResourceKey<Level> worldKey = friendlyByteBuf.readResourceKey(Registries.DIMENSION);
|
||||
ServerLevel level = server.getLevel(worldKey);
|
||||
if (level == null) {
|
||||
sendEmptyResponse(player, id);
|
||||
return;
|
||||
}
|
||||
|
||||
boolean sendBlockEntitiesInChunks= friendlyByteBuf.readBoolean();
|
||||
|
||||
Long2ObjectMap<CompressedBlockEntity> blockEntityMap = new Long2ObjectOpenHashMap<>();
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
BlockPos.MutableBlockPos mutableBlockPos = new BlockPos.MutableBlockPos();
|
||||
|
||||
// Save and compress block entities
|
||||
int count = friendlyByteBuf.readVarInt();
|
||||
for (int i = 0; i < count; i++) {
|
||||
long pos = friendlyByteBuf.readLong();
|
||||
BlockEntity blockEntity = level.getBlockEntity(mutableBlockPos.set(pos));
|
||||
if (blockEntity != null) {
|
||||
CompoundTag tag = blockEntity.saveWithoutMetadata();
|
||||
blockEntityMap.put(pos, CompressedBlockEntity.compress(tag, baos));
|
||||
}
|
||||
}
|
||||
|
||||
int playerSectionX = player.getBlockX() >> 4;
|
||||
int playerSectionZ = player.getBlockZ() >> 4;
|
||||
|
||||
Long2ObjectMap<PalettedContainer<BlockState>> sections = new Long2ObjectOpenHashMap<>();
|
||||
count = friendlyByteBuf.readVarInt();
|
||||
for (int i = 0; i < count; i++) {
|
||||
long pos = friendlyByteBuf.readLong();
|
||||
|
||||
int sx = BlockPos.getX(pos);
|
||||
int sy = BlockPos.getY(pos);
|
||||
int sz = BlockPos.getZ(pos);
|
||||
|
||||
int distance = Math.abs(playerSectionX - sx) + Math.abs(playerSectionZ - sz);
|
||||
if (distance > 128) continue;
|
||||
|
||||
LevelChunk chunk = level.getChunk(sx, sz);
|
||||
int sectionIndex = chunk.getSectionIndexFromSectionY(sy);
|
||||
if (sectionIndex < 0 || sectionIndex >= chunk.getSectionsCount()) continue;
|
||||
LevelChunkSection section = chunk.getSection(sectionIndex);
|
||||
|
||||
if (section.hasOnlyAir()) {
|
||||
sections.put(pos, null);
|
||||
} else {
|
||||
PalettedContainer<BlockState> container = section.getStates();
|
||||
sections.put(pos, container);
|
||||
|
||||
if (sendBlockEntitiesInChunks && section.maybeHas(BlockState::hasBlockEntity)) {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
BlockState blockState = container.get(x, y, z);
|
||||
if (blockState.hasBlockEntity()) {
|
||||
mutableBlockPos.set(sx*16 + x, sy*16 + y, sz*16 + z);
|
||||
BlockEntity blockEntity = chunk.getBlockEntity(mutableBlockPos, LevelChunk.EntityCreationType.CHECK);
|
||||
if (blockEntity != null) {
|
||||
CompoundTag tag = blockEntity.saveWithoutMetadata();
|
||||
blockEntityMap.put(mutableBlockPos.asLong(), CompressedBlockEntity.compress(tag, baos));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Send response packet
|
||||
|
||||
boolean firstPart = true;
|
||||
int maxSize = 0x100000 - 64; // Leeway of 64 bytes
|
||||
|
||||
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||
buf.writeLong(id);
|
||||
|
||||
for (Long2ObjectMap.Entry<CompressedBlockEntity> entry : blockEntityMap.long2ObjectEntrySet()) {
|
||||
int beforeWriterIndex = buf.writerIndex();
|
||||
|
||||
buf.writeLong(entry.getLongKey());
|
||||
entry.getValue().write(buf);
|
||||
|
||||
if (buf.writerIndex() >= maxSize) {
|
||||
if (firstPart) {
|
||||
// Finish and send current packet
|
||||
buf.writeLong(AxiomConstants.MIN_POSITION_LONG);
|
||||
buf.writeLong(AxiomConstants.MIN_POSITION_LONG);
|
||||
buf.writeBoolean(false);
|
||||
byte[] bytes = new byte[buf.writerIndex()];
|
||||
buf.getBytes(0, bytes);
|
||||
player.connection.send(new ClientboundCustomPayloadPacket(RESPONSE_ID, buf));
|
||||
|
||||
// Continuation packet
|
||||
buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||
buf.writeLong(id);
|
||||
} else {
|
||||
// Copy extra bytes
|
||||
int copiedSize = buf.writerIndex() - beforeWriterIndex;
|
||||
byte[] copied = new byte[copiedSize];
|
||||
buf.getBytes(beforeWriterIndex, copied);
|
||||
|
||||
// Discard extra bytes
|
||||
buf.writerIndex(beforeWriterIndex);
|
||||
|
||||
// Finish and send current packet
|
||||
buf.writeLong(AxiomConstants.MIN_POSITION_LONG);
|
||||
buf.writeLong(AxiomConstants.MIN_POSITION_LONG);
|
||||
buf.writeBoolean(false);
|
||||
byte[] bytes = new byte[buf.writerIndex()];
|
||||
buf.getBytes(0, bytes);
|
||||
player.connection.send(new ClientboundCustomPayloadPacket(RESPONSE_ID, buf));
|
||||
|
||||
// Continuation packet
|
||||
buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||
buf.writeLong(id);
|
||||
|
||||
// Write start of new packet
|
||||
buf.writeBytes(copied);
|
||||
firstPart = true;
|
||||
}
|
||||
} else {
|
||||
firstPart = false;
|
||||
}
|
||||
}
|
||||
|
||||
buf.writeLong(AxiomConstants.MIN_POSITION_LONG);
|
||||
|
||||
for (Long2ObjectMap.Entry<PalettedContainer<BlockState>> entry : sections.long2ObjectEntrySet()) {
|
||||
int beforeWriterIndex = buf.writerIndex();
|
||||
|
||||
buf.writeLong(entry.getLongKey());
|
||||
var container = entry.getValue();
|
||||
if (container == null) {
|
||||
buf.writeBoolean(false);
|
||||
} else {
|
||||
buf.writeBoolean(true);
|
||||
entry.getValue().write(buf);
|
||||
}
|
||||
|
||||
if (buf.writerIndex() >= maxSize) {
|
||||
if (firstPart) {
|
||||
// Finish and send current packet
|
||||
buf.writeLong(AxiomConstants.MIN_POSITION_LONG);
|
||||
buf.writeBoolean(false);
|
||||
byte[] bytes = new byte[buf.writerIndex()];
|
||||
buf.getBytes(0, bytes);
|
||||
player.connection.send(new ClientboundCustomPayloadPacket(RESPONSE_ID, buf));
|
||||
|
||||
// Continuation packet
|
||||
buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||
buf.writeLong(id);
|
||||
buf.writeLong(AxiomConstants.MIN_POSITION_LONG);
|
||||
} else {
|
||||
// Copy extra bytes
|
||||
int copiedSize = buf.writerIndex() - beforeWriterIndex;
|
||||
byte[] copied = new byte[copiedSize];
|
||||
buf.getBytes(beforeWriterIndex, copied);
|
||||
|
||||
// Discard extra bytes
|
||||
buf.writerIndex(beforeWriterIndex);
|
||||
|
||||
// Finish and send current packet
|
||||
buf.writeLong(AxiomConstants.MIN_POSITION_LONG);
|
||||
buf.writeBoolean(false);
|
||||
byte[] bytes = new byte[buf.writerIndex()];
|
||||
buf.getBytes(0, bytes);
|
||||
player.connection.send(new ClientboundCustomPayloadPacket(RESPONSE_ID, buf));
|
||||
|
||||
// Continuation packet
|
||||
buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||
buf.writeLong(id);
|
||||
buf.writeLong(AxiomConstants.MIN_POSITION_LONG);
|
||||
|
||||
// Write start of new packet
|
||||
buf.writeBytes(copied);
|
||||
firstPart = true;
|
||||
}
|
||||
} else {
|
||||
firstPart = false;
|
||||
}
|
||||
}
|
||||
|
||||
buf.writeLong(AxiomConstants.MIN_POSITION_LONG);
|
||||
buf.writeBoolean(true);
|
||||
byte[] bytes = new byte[buf.writerIndex()];
|
||||
buf.getBytes(0, bytes);
|
||||
player.connection.send(new ClientboundCustomPayloadPacket(RESPONSE_ID, buf));
|
||||
}
|
||||
|
||||
private void sendEmptyResponse(ServerPlayer player, long id) {
|
||||
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer(16));
|
||||
buf.writeLong(id);
|
||||
buf.writeLong(AxiomConstants.MIN_POSITION_LONG); // no block entities
|
||||
buf.writeLong(AxiomConstants.MIN_POSITION_LONG); // no chunks
|
||||
buf.writeBoolean(true); // finished
|
||||
|
||||
byte[] bytes = new byte[buf.writerIndex()];
|
||||
buf.getBytes(0, bytes);
|
||||
player.connection.send(new ClientboundCustomPayloadPacket(RESPONSE_ID, buf));
|
||||
}
|
||||
|
||||
}
|
@ -35,6 +35,8 @@ import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.entity.ai.village.poi.PoiType;
|
||||
import net.minecraft.world.entity.ai.village.poi.PoiTypes;
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.level.biome.Biome;
|
||||
@ -50,12 +52,6 @@ import net.minecraft.world.level.chunk.PalettedContainer;
|
||||
import net.minecraft.world.level.levelgen.Heightmap;
|
||||
import net.minecraft.world.level.lighting.LightEngine;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import xyz.jpenilla.reflectionremapper.ReflectionRemapper;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -118,7 +114,7 @@ public class SetBlockBufferPacketListener {
|
||||
Bukkit.getPluginManager().callEvent(modifyWorldEvent);
|
||||
if (modifyWorldEvent.isCancelled()) return;
|
||||
|
||||
RegionProtection regionProtection = new RegionProtection(player.getBukkitEntity(), world.getWorld());
|
||||
// RegionProtection regionProtection = new RegionProtection(player.getBukkitEntity(), world.getWorld());
|
||||
|
||||
// Allowed, apply buffer
|
||||
BlockPos.MutableBlockPos blockPos = new BlockPos.MutableBlockPos();
|
||||
@ -137,7 +133,7 @@ public class SetBlockBufferPacketListener {
|
||||
continue;
|
||||
}
|
||||
|
||||
SectionProtection sectionProtection = regionProtection.getSection(cx, cy, cz);
|
||||
// SectionProtection sectionProtection = regionProtection.getSection(cx, cy, cz);
|
||||
// switch (sectionProtection.getSectionState()) {
|
||||
// case ALLOW -> sectionProtection = null;
|
||||
// case DENY -> {
|
||||
@ -169,99 +165,105 @@ public class SetBlockBufferPacketListener {
|
||||
|
||||
Short2ObjectMap<CompressedBlockEntity> blockEntityChunkMap = buffer.getBlockEntityChunkMap(entry.getLongKey());
|
||||
|
||||
sectionStates.acquire();
|
||||
try {
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
BlockState blockState = container.get(x, y, z);
|
||||
if (blockState == emptyState) continue;
|
||||
for (int x = 0; x < 16; x++) {
|
||||
for (int y = 0; y < 16; y++) {
|
||||
for (int z = 0; z < 16; z++) {
|
||||
BlockState blockState = container.get(x, y, z);
|
||||
if (blockState == emptyState) continue;
|
||||
|
||||
switch (sectionProtection.getSectionState()) {
|
||||
case ALLOW -> {}
|
||||
case DENY -> blockState = Blocks.REDSTONE_BLOCK.defaultBlockState();
|
||||
case CHECK -> blockState = Blocks.DIAMOND_BLOCK.defaultBlockState();
|
||||
}
|
||||
// switch (sectionProtection.getSectionState()) {
|
||||
// case ALLOW -> {}
|
||||
// case DENY -> blockState = Blocks.REDSTONE_BLOCK.defaultBlockState();
|
||||
// case CHECK -> blockState = Blocks.DIAMOND_BLOCK.defaultBlockState();
|
||||
// }
|
||||
|
||||
int bx = cx*16 + x;
|
||||
int by = cy*16 + y;
|
||||
int bz = cz*16 + z;
|
||||
int bx = cx*16 + x;
|
||||
int by = cy*16 + y;
|
||||
int bz = cz*16 + z;
|
||||
|
||||
// if (!regionProtection.canBuild(bx, by, bz)) {
|
||||
// continue;
|
||||
// }
|
||||
// if (!regionProtection.canBuild(bx, by, bz)) {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
blockPos.set(bx, by, bz);
|
||||
blockPos.set(bx, by, bz);
|
||||
|
||||
if (hasOnlyAir && blockState.isAir()) {
|
||||
continue;
|
||||
}
|
||||
if (hasOnlyAir && blockState.isAir()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
BlockState old = section.setBlockState(x, y, z, blockState, false);
|
||||
if (blockState != old) {
|
||||
Block block = blockState.getBlock();
|
||||
motionBlocking.update(x, by, z, blockState);
|
||||
motionBlockingNoLeaves.update(x, by, z, blockState);
|
||||
oceanFloor.update(x, by, z, blockState);
|
||||
worldSurface.update(x, by, z, blockState);
|
||||
BlockState old = section.setBlockState(x, y, z, blockState, true);
|
||||
if (blockState != old) {
|
||||
Block block = blockState.getBlock();
|
||||
motionBlocking.update(x, by, z, blockState);
|
||||
motionBlockingNoLeaves.update(x, by, z, blockState);
|
||||
oceanFloor.update(x, by, z, blockState);
|
||||
worldSurface.update(x, by, z, blockState);
|
||||
|
||||
if (false) { // Full update
|
||||
old.onRemove(world, blockPos, blockState, false);
|
||||
if (false) { // Full update
|
||||
old.onRemove(world, blockPos, blockState, false);
|
||||
|
||||
if (sectionStates.get(x, y, z).is(block)) {
|
||||
blockState.onPlace(world, blockPos, old, false);
|
||||
}
|
||||
if (sectionStates.get(x, y, z).is(block)) {
|
||||
blockState.onPlace(world, blockPos, old, false);
|
||||
}
|
||||
}
|
||||
|
||||
if (blockState.hasBlockEntity()) {
|
||||
BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK);
|
||||
if (blockState.hasBlockEntity()) {
|
||||
BlockEntity blockEntity = chunk.getBlockEntity(blockPos, LevelChunk.EntityCreationType.CHECK);
|
||||
|
||||
if (blockEntity == null) {
|
||||
// There isn't a block entity here, create it!
|
||||
blockEntity = ((EntityBlock)block).newBlockEntity(blockPos, blockState);
|
||||
if (blockEntity != null) {
|
||||
chunk.addAndRegisterBlockEntity(blockEntity);
|
||||
}
|
||||
} else if (blockEntity.getType().isValid(blockState)) {
|
||||
// Block entity is here and the type is correct
|
||||
blockEntity.setBlockState(blockState);
|
||||
|
||||
try {
|
||||
this.updateBlockEntityTicker.invoke(chunk, blockEntity);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else {
|
||||
// Block entity type isn't correct, we need to recreate it
|
||||
chunk.removeBlockEntity(blockPos);
|
||||
|
||||
blockEntity = ((EntityBlock)block).newBlockEntity(blockPos, blockState);
|
||||
if (blockEntity != null) {
|
||||
chunk.addAndRegisterBlockEntity(blockEntity);
|
||||
}
|
||||
if (blockEntity == null) {
|
||||
// There isn't a block entity here, create it!
|
||||
blockEntity = ((EntityBlock)block).newBlockEntity(blockPos, blockState);
|
||||
if (blockEntity != null) {
|
||||
chunk.addAndRegisterBlockEntity(blockEntity);
|
||||
}
|
||||
if (blockEntity != null && blockEntityChunkMap != null) {
|
||||
int key = x | (y << 4) | (z << 8);
|
||||
CompressedBlockEntity savedBlockEntity = blockEntityChunkMap.get((short) key);
|
||||
if (savedBlockEntity != null) {
|
||||
blockEntity.load(savedBlockEntity.decompress());
|
||||
}
|
||||
} else if (blockEntity.getType().isValid(blockState)) {
|
||||
// Block entity is here and the type is correct
|
||||
blockEntity.setBlockState(blockState);
|
||||
|
||||
try {
|
||||
this.updateBlockEntityTicker.invoke(chunk, blockEntity);
|
||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} else if (old.hasBlockEntity()) {
|
||||
} else {
|
||||
// Block entity type isn't correct, we need to recreate it
|
||||
chunk.removeBlockEntity(blockPos);
|
||||
}
|
||||
|
||||
world.getChunkSource().blockChanged(blockPos); // todo: maybe simply resend chunk instead of this?
|
||||
|
||||
if (LightEngine.hasDifferentLightProperties(chunk, blockPos, old, blockState)) {
|
||||
lightEngine.checkBlock(blockPos);
|
||||
blockEntity = ((EntityBlock)block).newBlockEntity(blockPos, blockState);
|
||||
if (blockEntity != null) {
|
||||
chunk.addAndRegisterBlockEntity(blockEntity);
|
||||
}
|
||||
}
|
||||
if (blockEntity != null && blockEntityChunkMap != null) {
|
||||
int key = x | (y << 4) | (z << 8);
|
||||
CompressedBlockEntity savedBlockEntity = blockEntityChunkMap.get((short) key);
|
||||
if (savedBlockEntity != null) {
|
||||
blockEntity.load(savedBlockEntity.decompress());
|
||||
}
|
||||
}
|
||||
} else if (old.hasBlockEntity()) {
|
||||
chunk.removeBlockEntity(blockPos);
|
||||
}
|
||||
|
||||
// Mark block changed
|
||||
world.getChunkSource().blockChanged(blockPos); // todo: maybe simply resend chunk instead of this?
|
||||
|
||||
// Update Light
|
||||
if (LightEngine.hasDifferentLightProperties(chunk, blockPos, old, blockState)) {
|
||||
chunk.getSkyLightSources().update(chunk, x, by, z);
|
||||
lightEngine.checkBlock(blockPos);
|
||||
}
|
||||
|
||||
// Update Poi
|
||||
Optional<Holder<PoiType>> newPoi = PoiTypes.forState(blockState);
|
||||
Optional<Holder<PoiType>> oldPoi = PoiTypes.forState(old);
|
||||
if (!Objects.equals(oldPoi, newPoi)) {
|
||||
if (oldPoi.isPresent()) world.getPoiManager().remove(blockPos);
|
||||
if (newPoi.isPresent()) world.getPoiManager().add(blockPos, newPoi.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
sectionStates.release();
|
||||
}
|
||||
|
||||
boolean nowHasOnlyAir = section.hasOnlyAir();
|
||||
|
@ -4,11 +4,14 @@ import com.moulberry.axiom.AxiomPaper;
|
||||
import com.moulberry.axiom.event.AxiomModifyWorldEvent;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Holder;
|
||||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.server.level.ServerPlayer;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.ai.village.poi.PoiType;
|
||||
import net.minecraft.world.entity.ai.village.poi.PoiTypes;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.block.EntityBlock;
|
||||
@ -33,7 +36,8 @@ import xyz.jpenilla.reflectionremapper.ReflectionRemapper;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
public class SetBlockPacketListener implements PluginMessageListener {
|
||||
|
||||
@ -142,7 +146,7 @@ public class SetBlockPacketListener implements PluginMessageListener {
|
||||
}
|
||||
}
|
||||
|
||||
BlockState old = section.setBlockState(x, y, z, blockState, false);
|
||||
BlockState old = section.setBlockState(x, y, z, blockState, true);
|
||||
if (blockState != old) {
|
||||
Block block = blockState.getBlock();
|
||||
motionBlocking.update(x, by, z, blockState);
|
||||
@ -182,10 +186,22 @@ public class SetBlockPacketListener implements PluginMessageListener {
|
||||
chunk.removeBlockEntity(blockPos);
|
||||
}
|
||||
|
||||
// Mark block changed
|
||||
level.getChunkSource().blockChanged(blockPos);
|
||||
|
||||
// Update Light
|
||||
if (LightEngine.hasDifferentLightProperties(chunk, blockPos, old, blockState)) {
|
||||
chunk.getSkyLightSources().update(chunk, x, by, z);
|
||||
level.getChunkSource().getLightEngine().checkBlock(blockPos);
|
||||
}
|
||||
|
||||
// Update Poi
|
||||
Optional<Holder<PoiType>> newPoi = PoiTypes.forState(blockState);
|
||||
Optional<Holder<PoiType>> oldPoi = PoiTypes.forState(old);
|
||||
if (!Objects.equals(oldPoi, newPoi)) {
|
||||
if (oldPoi.isPresent()) level.getPoiManager().remove(blockPos);
|
||||
if (newPoi.isPresent()) level.getPoiManager().add(blockPos, newPoi.get());
|
||||
}
|
||||
}
|
||||
|
||||
boolean nowHasOnlyAir = section.hasOnlyAir();
|
||||
|
@ -1,12 +1,9 @@
|
||||
package com.moulberry.axiom.packet;
|
||||
|
||||
import com.moulberry.axiom.event.AxiomFlySpeedChangeEvent;
|
||||
import com.moulberry.axiom.event.AxiomGameModeChangeEvent;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.world.level.GameType;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||
|
@ -1,27 +1,15 @@
|
||||
package com.moulberry.axiom.packet;
|
||||
|
||||
import com.moulberry.axiom.AxiomPaper;
|
||||
import com.moulberry.axiom.event.AxiomTimeChangeEvent;
|
||||
import com.moulberry.axiom.world_properties.WorldPropertyCategory;
|
||||
import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry;
|
||||
import com.moulberry.axiom.world_properties.server.ServerWorldProperty;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.core.registries.Registries;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceKey;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.world.level.GameRules;
|
||||
import net.minecraft.world.level.Level;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.v1_20_R1.CraftWorld;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.messaging.PluginMessageListener;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class SetWorldPropertyListener implements PluginMessageListener {
|
||||
|
||||
@Override
|
||||
@ -46,8 +34,10 @@ public class SetWorldPropertyListener implements PluginMessageListener {
|
||||
|
||||
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer());
|
||||
buf.writeVarInt(updateId);
|
||||
player.sendPluginMessage(AxiomPaper.PLUGIN, "axiom:ack_world_properties",
|
||||
buf.accessByteBufWithCorrectSize());
|
||||
|
||||
byte[] bytes = new byte[buf.writerIndex()];
|
||||
buf.getBytes(0, bytes);
|
||||
player.sendPluginMessage(AxiomPaper.PLUGIN, "axiom:ack_world_properties", bytes);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -42,7 +42,10 @@ public abstract class WorldPropertyDataType<T> {
|
||||
public byte[] serialize(Integer value) {
|
||||
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer(8));
|
||||
buf.writeVarInt(value);
|
||||
return buf.accessByteBufWithCorrectSize();
|
||||
|
||||
byte[] bytes = new byte[buf.writerIndex()];
|
||||
buf.getBytes(0, bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -79,7 +82,10 @@ public abstract class WorldPropertyDataType<T> {
|
||||
public byte[] serialize(Item value) {
|
||||
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer(8));
|
||||
buf.writeId(BuiltInRegistries.ITEM, value);
|
||||
return buf.accessByteBufWithCorrectSize();
|
||||
|
||||
byte[] bytes = new byte[buf.writerIndex()];
|
||||
buf.getBytes(0, bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -99,7 +105,10 @@ public abstract class WorldPropertyDataType<T> {
|
||||
public byte[] serialize(Block value) {
|
||||
FriendlyByteBuf buf = new FriendlyByteBuf(Unpooled.buffer(8));
|
||||
buf.writeId(BuiltInRegistries.BLOCK, value);
|
||||
return buf.accessByteBufWithCorrectSize();
|
||||
|
||||
byte[] bytes = new byte[buf.writerIndex()];
|
||||
buf.getBytes(0, bytes);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -53,8 +53,9 @@ public class ServerWorldPropertiesRegistry {
|
||||
buf.writeCollection(entry.getValue(), (buffer, p) -> p.write(buffer));
|
||||
}
|
||||
|
||||
bukkitPlayer.sendPluginMessage(plugin, "axiom:register_world_properties",
|
||||
buf.accessByteBufWithCorrectSize());
|
||||
byte[] bytes = new byte[buf.writerIndex()];
|
||||
buf.getBytes(0, bytes);
|
||||
bukkitPlayer.sendPluginMessage(plugin, "axiom:register_world_properties", bytes);
|
||||
}
|
||||
|
||||
public void registerDefault(World world) {
|
||||
|
@ -61,7 +61,8 @@ public class ServerWorldProperty<T> {
|
||||
buf.writeVarInt(this.widget.dataType().getTypeId());
|
||||
buf.writeByteArray(this.widget.dataType().serialize(this.value));
|
||||
|
||||
byte[] message = buf.accessByteBufWithCorrectSize();
|
||||
byte[] message = new byte[buf.writerIndex()];
|
||||
buf.getBytes(0, message);
|
||||
for (Player player : world.getPlayers()) {
|
||||
if (AxiomPaper.PLUGIN.activeAxiomPlayers.contains(player.getUniqueId())) {
|
||||
player.sendPluginMessage(AxiomPaper.PLUGIN, "axiom:set_world_property", message);
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren