Mirror von
https://github.com/Moulberry/AxiomPaperPlugin.git
synchronisiert 2024-11-17 05:40:06 +01:00
Partial ViaVersion support
Dieser Commit ist enthalten in:
Ursprung
ec99e2df42
Commit
ceca1afe68
@ -18,6 +18,7 @@ java {
|
|||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
maven("https://repo.viaversion.com")
|
||||||
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
|
maven("https://s01.oss.sonatype.org/content/repositories/snapshots/")
|
||||||
maven("https://jitpack.io")
|
maven("https://jitpack.io")
|
||||||
maven("https://repo.papermc.io/repository/maven-public/")
|
maven("https://repo.papermc.io/repository/maven-public/")
|
||||||
@ -31,6 +32,9 @@ dependencies {
|
|||||||
// Zstd Compression Library
|
// Zstd Compression Library
|
||||||
implementation("com.github.luben:zstd-jni:1.5.5-4")
|
implementation("com.github.luben:zstd-jni:1.5.5-4")
|
||||||
|
|
||||||
|
// ViaVersion support
|
||||||
|
compileOnly("com.viaversion:viaversion-api:4.9.4-SNAPSHOT")
|
||||||
|
|
||||||
// WorldGuard support
|
// WorldGuard support
|
||||||
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT")
|
compileOnly("com.sk89q.worldguard:worldguard-bukkit:7.1.0-SNAPSHOT")
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@ import org.bukkit.plugin.messaging.Messenger;
|
|||||||
import org.checkerframework.checker.nullness.qual.NonNull;
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@ -49,6 +50,7 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
|||||||
public final Set<UUID> activeAxiomPlayers = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
public final Set<UUID> activeAxiomPlayers = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||||
public final Map<UUID, RateLimiter> playerBlockBufferRateLimiters = new ConcurrentHashMap<>();
|
public final Map<UUID, RateLimiter> playerBlockBufferRateLimiters = new ConcurrentHashMap<>();
|
||||||
public final Map<UUID, Restrictions> playerRestrictions = new ConcurrentHashMap<>();
|
public final Map<UUID, Restrictions> playerRestrictions = new ConcurrentHashMap<>();
|
||||||
|
public final Map<UUID, IdMapper<BlockState>> playerBlockRegistry = new ConcurrentHashMap<>();
|
||||||
public Configuration configuration;
|
public Configuration configuration;
|
||||||
|
|
||||||
public IdMapper<BlockState> allowedBlockRegistry = null;
|
public IdMapper<BlockState> allowedBlockRegistry = null;
|
||||||
@ -265,6 +267,7 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
|||||||
activeAxiomPlayers.retainAll(stillActiveAxiomPlayers);
|
activeAxiomPlayers.retainAll(stillActiveAxiomPlayers);
|
||||||
playerBlockBufferRateLimiters.keySet().retainAll(stillActiveAxiomPlayers);
|
playerBlockBufferRateLimiters.keySet().retainAll(stillActiveAxiomPlayers);
|
||||||
playerRestrictions.keySet().retainAll(stillActiveAxiomPlayers);
|
playerRestrictions.keySet().retainAll(stillActiveAxiomPlayers);
|
||||||
|
playerBlockRegistry.keySet().retainAll(stillActiveAxiomPlayers);
|
||||||
}, 20, 20);
|
}, 20, 20);
|
||||||
|
|
||||||
boolean sendMarkers = configuration.getBoolean("send-markers");
|
boolean sendMarkers = configuration.getBoolean("send-markers");
|
||||||
@ -292,6 +295,14 @@ public class AxiomPaper extends JavaPlugin implements Listener {
|
|||||||
return this.playerBlockBufferRateLimiters.get(uuid);
|
return this.playerBlockBufferRateLimiters.get(uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasCustomBlockRegistry(UUID uuid) {
|
||||||
|
return this.playerBlockRegistry.containsKey(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdMapper<BlockState> getBlockRegistry(UUID uuid) {
|
||||||
|
return this.playerBlockRegistry.getOrDefault(uuid, this.allowedBlockRegistry);
|
||||||
|
}
|
||||||
|
|
||||||
private final WeakHashMap<World, ServerWorldPropertiesRegistry> worldProperties = new WeakHashMap<>();
|
private final WeakHashMap<World, ServerWorldPropertiesRegistry> worldProperties = new WeakHashMap<>();
|
||||||
|
|
||||||
public @Nullable ServerWorldPropertiesRegistry getWorldPropertiesIfPresent(World world) {
|
public @Nullable ServerWorldPropertiesRegistry getWorldPropertiesIfPresent(World world) {
|
||||||
|
@ -3,6 +3,7 @@ package com.moulberry.axiom;
|
|||||||
import com.mojang.brigadier.StringReader;
|
import com.mojang.brigadier.StringReader;
|
||||||
import com.mojang.datafixers.util.Either;
|
import com.mojang.datafixers.util.Either;
|
||||||
import com.moulberry.axiom.buffer.BlockBuffer;
|
import com.moulberry.axiom.buffer.BlockBuffer;
|
||||||
|
import com.viaversion.viaversion.api.data.Mappings;
|
||||||
import net.minecraft.commands.arguments.blocks.BlockPredicateArgument;
|
import net.minecraft.commands.arguments.blocks.BlockPredicateArgument;
|
||||||
import net.minecraft.commands.arguments.blocks.BlockStateParser;
|
import net.minecraft.commands.arguments.blocks.BlockStateParser;
|
||||||
import net.minecraft.core.IdMapper;
|
import net.minecraft.core.IdMapper;
|
||||||
|
@ -9,6 +9,7 @@ import it.unimi.dsi.fastutil.objects.ObjectSet;
|
|||||||
import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
|
import it.unimi.dsi.fastutil.shorts.Short2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.shorts.Short2ObjectOpenHashMap;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
|
import net.minecraft.core.IdMapper;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
@ -23,18 +24,16 @@ public class BlockBuffer {
|
|||||||
|
|
||||||
private final Long2ObjectMap<PalettedContainer<BlockState>> values;
|
private final Long2ObjectMap<PalettedContainer<BlockState>> values;
|
||||||
|
|
||||||
|
private IdMapper<BlockState> registry;
|
||||||
private PalettedContainer<BlockState> last = null;
|
private PalettedContainer<BlockState> last = null;
|
||||||
private long lastId = AxiomConstants.MIN_POSITION_LONG;
|
private long lastId = AxiomConstants.MIN_POSITION_LONG;
|
||||||
private final Long2ObjectMap<Short2ObjectMap<CompressedBlockEntity>> blockEntities = new Long2ObjectOpenHashMap<>();
|
private final Long2ObjectMap<Short2ObjectMap<CompressedBlockEntity>> blockEntities = new Long2ObjectOpenHashMap<>();
|
||||||
private long totalBlockEntities = 0;
|
private long totalBlockEntities = 0;
|
||||||
private long totalBlockEntityBytes = 0;
|
private long totalBlockEntityBytes = 0;
|
||||||
|
|
||||||
public BlockBuffer() {
|
public BlockBuffer(IdMapper<BlockState> registry) {
|
||||||
this.values = new Long2ObjectOpenHashMap<>();
|
this.values = new Long2ObjectOpenHashMap<>();
|
||||||
}
|
this.registry = registry;
|
||||||
|
|
||||||
public BlockBuffer(Long2ObjectMap<PalettedContainer<BlockState>> values) {
|
|
||||||
this.values = values;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(FriendlyByteBuf friendlyByteBuf) {
|
public void save(FriendlyByteBuf friendlyByteBuf) {
|
||||||
@ -57,8 +56,9 @@ public class BlockBuffer {
|
|||||||
friendlyByteBuf.writeLong(AxiomConstants.MIN_POSITION_LONG);
|
friendlyByteBuf.writeLong(AxiomConstants.MIN_POSITION_LONG);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockBuffer load(FriendlyByteBuf friendlyByteBuf, @Nullable RateLimiter rateLimiter, AtomicBoolean reachedRateLimit) {
|
public static BlockBuffer load(FriendlyByteBuf friendlyByteBuf, @Nullable RateLimiter rateLimiter, AtomicBoolean reachedRateLimit,
|
||||||
BlockBuffer buffer = new BlockBuffer();
|
IdMapper<BlockState> registry) {
|
||||||
|
BlockBuffer buffer = new BlockBuffer(registry);
|
||||||
|
|
||||||
long totalBlockEntities = 0;
|
long totalBlockEntities = 0;
|
||||||
long totalBlockEntityBytes = 0;
|
long totalBlockEntityBytes = 0;
|
||||||
@ -177,7 +177,7 @@ public class BlockBuffer {
|
|||||||
public PalettedContainer<BlockState> getOrCreateSection(long id) {
|
public PalettedContainer<BlockState> getOrCreateSection(long id) {
|
||||||
if (this.last == null || id != this.lastId) {
|
if (this.last == null || id != this.lastId) {
|
||||||
this.lastId = id;
|
this.lastId = id;
|
||||||
this.last = this.values.computeIfAbsent(id, k -> new PalettedContainer<>(AxiomPaper.PLUGIN.allowedBlockRegistry,
|
this.last = this.values.computeIfAbsent(id, k -> new PalettedContainer<>(this.registry,
|
||||||
EMPTY_STATE, PalettedContainer.Strategy.SECTION_STATES));
|
EMPTY_STATE, PalettedContainer.Strategy.SECTION_STATES));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,8 +62,7 @@ public class AxiomBigPayloadHandler extends ByteToMessageDecoder {
|
|||||||
} else if (identifier.equals(UPLOAD_BLUEPRINT)) {
|
} else if (identifier.equals(UPLOAD_BLUEPRINT)) {
|
||||||
ServerPlayer player = connection.getPlayer();
|
ServerPlayer player = connection.getPlayer();
|
||||||
if (AxiomPaper.PLUGIN.canUseAxiom(player.getBukkitEntity())) {
|
if (AxiomPaper.PLUGIN.canUseAxiom(player.getBukkitEntity())) {
|
||||||
player.getServer().execute(() -> uploadBlueprint.onReceive(player, buf));
|
uploadBlueprint.onReceive(player, buf);
|
||||||
|
|
||||||
success = true;
|
success = true;
|
||||||
in.skipBytes(in.readableBytes());
|
in.skipBytes(in.readableBytes());
|
||||||
return;
|
return;
|
||||||
@ -74,8 +73,15 @@ public class AxiomBigPayloadHandler extends ByteToMessageDecoder {
|
|||||||
byte[] bytes = new byte[buf.writerIndex() - buf.readerIndex()];
|
byte[] bytes = new byte[buf.writerIndex() - buf.readerIndex()];
|
||||||
buf.getBytes(buf.readerIndex(), bytes);
|
buf.getBytes(buf.readerIndex(), bytes);
|
||||||
|
|
||||||
player.getServer().execute(() -> requestChunkDataPacketListener.onPluginMessageReceived(
|
player.getServer().execute(() -> {
|
||||||
identifier.toString(), player.getBukkitEntity(), bytes));
|
try {
|
||||||
|
requestChunkDataPacketListener.onPluginMessageReceived(
|
||||||
|
identifier.toString(), player.getBukkitEntity(), bytes);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
player.getBukkitEntity().kick(net.kyori.adventure.text.Component.text(
|
||||||
|
"An error occured while requesting chunk data: " + t.getMessage()));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
success = true;
|
success = true;
|
||||||
in.skipBytes(in.readableBytes());
|
in.skipBytes(in.readableBytes());
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
package com.moulberry.axiom.packet;
|
package com.moulberry.axiom.packet;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.RateLimiter;
|
import com.google.common.util.concurrent.RateLimiter;
|
||||||
import com.moulberry.axiom.AxiomConstants;
|
import com.moulberry.axiom.*;
|
||||||
import com.moulberry.axiom.AxiomPaper;
|
|
||||||
import com.moulberry.axiom.View;
|
|
||||||
import com.moulberry.axiom.WorldExtension;
|
|
||||||
import com.moulberry.axiom.blueprint.ServerBlueprintManager;
|
import com.moulberry.axiom.blueprint.ServerBlueprintManager;
|
||||||
import com.moulberry.axiom.event.AxiomHandshakeEvent;
|
import com.moulberry.axiom.event.AxiomHandshakeEvent;
|
||||||
import com.moulberry.axiom.persistence.ItemStackDataType;
|
import com.moulberry.axiom.persistence.ItemStackDataType;
|
||||||
import com.moulberry.axiom.persistence.UUIDDataType;
|
import com.moulberry.axiom.persistence.UUIDDataType;
|
||||||
|
import com.moulberry.axiom.viaversion.ViaVersionHelper;
|
||||||
import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry;
|
import com.moulberry.axiom.world_properties.server.ServerWorldPropertiesRegistry;
|
||||||
|
import com.viaversion.viaversion.api.Via;
|
||||||
|
import com.viaversion.viaversion.api.data.*;
|
||||||
|
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
|
||||||
|
import com.viaversion.viaversion.libs.opennbt.tag.builtin.CompoundTag;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
@ -52,18 +54,52 @@ public class HelloPacketListener implements PluginMessageListener {
|
|||||||
|
|
||||||
int serverDataVersion = SharedConstants.getCurrentVersion().getDataVersion().getVersion();
|
int serverDataVersion = SharedConstants.getCurrentVersion().getDataVersion().getVersion();
|
||||||
if (dataVersion != serverDataVersion) {
|
if (dataVersion != serverDataVersion) {
|
||||||
Component text = Component.text("Axiom: Incompatible data version detected (client " + dataVersion +
|
if (!Bukkit.getPluginManager().isPluginEnabled("ViaVersion")) {
|
||||||
", server " + serverDataVersion + "), are you using ViaVersion?");
|
Component text = Component.text("Axiom: Incompatible data version detected (client " + dataVersion +
|
||||||
|
", server " + serverDataVersion + ")");
|
||||||
|
|
||||||
String incompatibleDataVersion = plugin.configuration.getString("incompatible-data-version");
|
String incompatibleDataVersion = plugin.configuration.getString("incompatible-data-version");
|
||||||
if (incompatibleDataVersion == null) incompatibleDataVersion = "kick";
|
if (incompatibleDataVersion == null) incompatibleDataVersion = "kick";
|
||||||
if (incompatibleDataVersion.equals("warn")) {
|
if (incompatibleDataVersion.equals("warn")) {
|
||||||
|
player.sendMessage(text.color(NamedTextColor.RED));
|
||||||
|
return;
|
||||||
|
} else if (!incompatibleDataVersion.equals("ignore")) {
|
||||||
|
player.kick(text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// int playerVersion = Via.getAPI().getPlayerVersion(player.getUniqueId());
|
||||||
|
// if (ProtocolVersion.isRegistered(playerVersion)) {
|
||||||
|
// ProtocolVersion version = ProtocolVersion.getProtocol(playerVersion);
|
||||||
|
// String name = version.getName().split("/")[0];
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// }
|
||||||
|
|
||||||
|
CompoundTag tag = MappingDataLoader.loadNBT("mappings-1.20.2to1.20.3.nbt");
|
||||||
|
|
||||||
|
if (tag == null) {
|
||||||
|
player.kick(Component.text("Axiom+ViaVersion: Failed to load mappings (1.20.2 <-> 1.20.3)"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mappings mappings = MappingDataLoader.loadMappings(tag, "blockstates");
|
||||||
|
|
||||||
|
if (mappings == null) {
|
||||||
|
player.kick(Component.text("Axiom+ViaVersion: Failed to load mapped blockstates (1.20.2 <-> 1.20.3"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.plugin.playerBlockRegistry.put(player.getUniqueId(), ViaVersionHelper.applyMappings(this.plugin.allowedBlockRegistry,
|
||||||
|
BiMappings.of(mappings).inverse()));
|
||||||
|
|
||||||
|
Component text = Component.text("Axiom: Warning, client and server versions don't match. " +
|
||||||
|
"Axiom will try to use ViaVersion conversions, but this process may cause problems");
|
||||||
player.sendMessage(text.color(NamedTextColor.RED));
|
player.sendMessage(text.color(NamedTextColor.RED));
|
||||||
return;
|
|
||||||
} else if (!incompatibleDataVersion.equals("ignore")) {
|
|
||||||
player.kick(text);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
// inverse.getNewIdOrDefault()
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (apiVersion != AxiomConstants.API_VERSION) {
|
if (apiVersion != AxiomConstants.API_VERSION) {
|
||||||
|
@ -5,6 +5,7 @@ import com.moulberry.axiom.AxiomPaper;
|
|||||||
import com.moulberry.axiom.VersionHelper;
|
import com.moulberry.axiom.VersionHelper;
|
||||||
import com.moulberry.axiom.buffer.CompressedBlockEntity;
|
import com.moulberry.axiom.buffer.CompressedBlockEntity;
|
||||||
import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration;
|
import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration;
|
||||||
|
import com.viaversion.viaversion.api.Via;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import it.unimi.dsi.fastutil.longs.*;
|
import it.unimi.dsi.fastutil.longs.*;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
@ -46,7 +47,7 @@ public class RequestChunkDataPacketListener implements PluginMessageListener {
|
|||||||
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message));
|
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message));
|
||||||
long id = friendlyByteBuf.readLong();
|
long id = friendlyByteBuf.readLong();
|
||||||
|
|
||||||
if (!this.plugin.canUseAxiom(bukkitPlayer)) {
|
if (!this.plugin.canUseAxiom(bukkitPlayer) || this.plugin.hasCustomBlockRegistry(bukkitPlayer.getUniqueId())) {
|
||||||
// We always send an 'empty' response in order to make the client happy
|
// We always send an 'empty' response in order to make the client happy
|
||||||
sendEmptyResponse(player, id);
|
sendEmptyResponse(player, id);
|
||||||
return;
|
return;
|
||||||
|
@ -85,7 +85,7 @@ public class SetBlockBufferPacketListener {
|
|||||||
byte type = friendlyByteBuf.readByte();
|
byte type = friendlyByteBuf.readByte();
|
||||||
if (type == 0) {
|
if (type == 0) {
|
||||||
AtomicBoolean reachedRateLimit = new AtomicBoolean(false);
|
AtomicBoolean reachedRateLimit = new AtomicBoolean(false);
|
||||||
BlockBuffer buffer = BlockBuffer.load(friendlyByteBuf, rateLimiter, reachedRateLimit);
|
BlockBuffer buffer = BlockBuffer.load(friendlyByteBuf, rateLimiter, reachedRateLimit, this.plugin.getBlockRegistry(player.getUUID()));
|
||||||
if (reachedRateLimit.get()) {
|
if (reachedRateLimit.get()) {
|
||||||
player.sendSystemMessage(Component.literal("[Axiom] Exceeded server rate-limit of " + (int)rateLimiter.getRate() + " sections per second")
|
player.sendSystemMessage(Component.literal("[Axiom] Exceeded server rate-limit of " + (int)rateLimiter.getRate() + " sections per second")
|
||||||
.withStyle(ChatFormatting.RED));
|
.withStyle(ChatFormatting.RED));
|
||||||
|
@ -7,6 +7,7 @@ import com.moulberry.axiom.integration.plotsquared.PlotSquaredIntegration;
|
|||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Holder;
|
import net.minecraft.core.Holder;
|
||||||
|
import net.minecraft.core.IdMapper;
|
||||||
import net.minecraft.core.SectionPos;
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.network.FriendlyByteBuf;
|
import net.minecraft.network.FriendlyByteBuf;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
@ -79,8 +80,9 @@ public class SetBlockPacketListener implements PluginMessageListener {
|
|||||||
// Read packet
|
// Read packet
|
||||||
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message));
|
FriendlyByteBuf friendlyByteBuf = new FriendlyByteBuf(Unpooled.wrappedBuffer(message));
|
||||||
IntFunction<Map<BlockPos, BlockState>> mapFunction = FriendlyByteBuf.limitValue(Maps::newLinkedHashMapWithExpectedSize, 512);
|
IntFunction<Map<BlockPos, BlockState>> mapFunction = FriendlyByteBuf.limitValue(Maps::newLinkedHashMapWithExpectedSize, 512);
|
||||||
|
IdMapper<BlockState> registry = this.plugin.getBlockRegistry(bukkitPlayer.getUniqueId());
|
||||||
Map<BlockPos, BlockState> blocks = friendlyByteBuf.readMap(mapFunction,
|
Map<BlockPos, BlockState> blocks = friendlyByteBuf.readMap(mapFunction,
|
||||||
FriendlyByteBuf::readBlockPos, buf -> buf.readById(this.plugin.allowedBlockRegistry));
|
FriendlyByteBuf::readBlockPos, buf -> buf.readById(registry));
|
||||||
boolean updateNeighbors = friendlyByteBuf.readBoolean();
|
boolean updateNeighbors = friendlyByteBuf.readBoolean();
|
||||||
|
|
||||||
int reason = friendlyByteBuf.readVarInt();
|
int reason = friendlyByteBuf.readVarInt();
|
||||||
@ -129,6 +131,10 @@ public class SetBlockPacketListener implements PluginMessageListener {
|
|||||||
BlockPos blockPos = entry.getKey();
|
BlockPos blockPos = entry.getKey();
|
||||||
BlockState blockState = entry.getValue();
|
BlockState blockState = entry.getValue();
|
||||||
|
|
||||||
|
if (blockState == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Disallow in unloaded chunks
|
// Disallow in unloaded chunks
|
||||||
if (!player.level().isLoaded(blockPos)) {
|
if (!player.level().isLoaded(blockPos)) {
|
||||||
continue;
|
continue;
|
||||||
@ -154,6 +160,10 @@ public class SetBlockPacketListener implements PluginMessageListener {
|
|||||||
BlockPos blockPos = entry.getKey();
|
BlockPos blockPos = entry.getKey();
|
||||||
BlockState blockState = entry.getValue();
|
BlockState blockState = entry.getValue();
|
||||||
|
|
||||||
|
if (blockState == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// Disallow in unloaded chunks
|
// Disallow in unloaded chunks
|
||||||
if (!player.level().isLoaded(blockPos)) {
|
if (!player.level().isLoaded(blockPos)) {
|
||||||
continue;
|
continue;
|
||||||
|
@ -47,25 +47,34 @@ public class UploadBlueprintPacketListener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Path path = this.plugin.blueprintFolder.resolve(relative);
|
String pathName = pathStr.substring(0, pathStr.length()-3);
|
||||||
|
|
||||||
// Write file
|
serverPlayer.getServer().execute(() -> {
|
||||||
try {
|
try {
|
||||||
Files.createDirectories(path.getParent());
|
Path path = this.plugin.blueprintFolder.resolve(relative);
|
||||||
} catch (IOException e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try (OutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(path))) {
|
|
||||||
BlueprintIo.writeRaw(outputStream, rawBlueprint);
|
|
||||||
} catch (IOException e) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update registry
|
// Write file
|
||||||
registry.blueprints().put("/" + pathStr.substring(0, pathStr.length()-3), rawBlueprint);
|
try {
|
||||||
|
Files.createDirectories(path.getParent());
|
||||||
|
} catch (IOException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try (OutputStream outputStream = new BufferedOutputStream(Files.newOutputStream(path))) {
|
||||||
|
BlueprintIo.writeRaw(outputStream, rawBlueprint);
|
||||||
|
} catch (IOException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Resend manifest
|
// Update registry
|
||||||
ServerBlueprintManager.sendManifest(serverPlayer.getServer().getPlayerList().getPlayers());
|
registry.blueprints().put("/" + pathName, rawBlueprint);
|
||||||
|
|
||||||
|
// Resend manifest
|
||||||
|
ServerBlueprintManager.sendManifest(serverPlayer.getServer().getPlayerList().getPlayers());
|
||||||
|
} catch (Throwable t) {
|
||||||
|
serverPlayer.getBukkitEntity().kick(net.kyori.adventure.text.Component.text(
|
||||||
|
"An error occured while uploading blueprint: " + t.getMessage()));
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,2 +1,42 @@
|
|||||||
package com.moulberry.axiom.viaversion;public class ViaVersionHelper {
|
package com.moulberry.axiom.viaversion;
|
||||||
|
|
||||||
|
import com.moulberry.axiom.buffer.BlockBuffer;
|
||||||
|
import com.viaversion.viaversion.api.data.BiMappings;
|
||||||
|
import com.viaversion.viaversion.api.data.Mappings;
|
||||||
|
import net.minecraft.core.IdMapper;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
|
public class ViaVersionHelper {
|
||||||
|
|
||||||
|
public static IdMapper<BlockState> applyMappings(IdMapper<BlockState> registry, BiMappings mappings) {
|
||||||
|
IdMapper<BlockState> newBlockRegistry = new IdMapper<>();
|
||||||
|
|
||||||
|
// Add empty mappings for non-existent blocks
|
||||||
|
int size = mappings.mappedSize();
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
newBlockRegistry.addMapping(BlockBuffer.EMPTY_STATE, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map blocks
|
||||||
|
for (int i = 0; i < registry.size(); i++) {
|
||||||
|
BlockState blockState = registry.byId(i);
|
||||||
|
|
||||||
|
if (blockState != null) {
|
||||||
|
int newId = mappings.getNewId(i);
|
||||||
|
if (newId >= 0) {
|
||||||
|
newBlockRegistry.addMapping(blockState, newId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure block -> id is correct for the empty state
|
||||||
|
int newEmptyStateId = mappings.getNewId(registry.getId(BlockBuffer.EMPTY_STATE));
|
||||||
|
if (newEmptyStateId >= 0) {
|
||||||
|
newBlockRegistry.addMapping(BlockBuffer.EMPTY_STATE, newEmptyStateId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newBlockRegistry;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ api-version: "$apiVersion"
|
|||||||
permissions:
|
permissions:
|
||||||
axiom.*:
|
axiom.*:
|
||||||
description: Allows use of all default Axiom features
|
description: Allows use of all default Axiom features
|
||||||
default: op
|
default: true # op
|
||||||
|
|
||||||
axiom.entity.*:
|
axiom.entity.*:
|
||||||
description: Allows use of all entity-related features (spawning, manipulating, deleting)
|
description: Allows use of all entity-related features (spawning, manipulating, deleting)
|
||||||
@ -22,7 +22,7 @@ permissions:
|
|||||||
|
|
||||||
axiom.allow_copying_other_plots:
|
axiom.allow_copying_other_plots:
|
||||||
description: This permission allows users to copy other user's plots
|
description: This permission allows users to copy other user's plots
|
||||||
default: true
|
default: false # true
|
||||||
axiom.can_import_blocks:
|
axiom.can_import_blocks:
|
||||||
description: Allows players to import schematics/blueprints into Axiom
|
description: Allows players to import schematics/blueprints into Axiom
|
||||||
default: true
|
default: true
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren