From 4b4c3cda3239b2758249af37f2cd122da565f3c2 Mon Sep 17 00:00:00 2001 From: LeoDog896 Date: Sat, 19 Jun 2021 18:12:56 -0400 Subject: [PATCH 01/39] Ensure proper error when extension.json is missing --- .../minestom/server/extensions/ExtensionManager.java | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/minestom/server/extensions/ExtensionManager.java b/src/main/java/net/minestom/server/extensions/ExtensionManager.java index 53ca4e7f7..a4ccc63bb 100644 --- a/src/main/java/net/minestom/server/extensions/ExtensionManager.java +++ b/src/main/java/net/minestom/server/extensions/ExtensionManager.java @@ -29,6 +29,7 @@ import java.net.URL; import java.nio.file.Path; import java.util.*; import java.util.stream.Collectors; +import java.util.zip.ZipEntry; import java.util.zip.ZipFile; public class ExtensionManager { @@ -379,8 +380,14 @@ public class ExtensionManager { */ @Nullable private DiscoveredExtension discoverFromJar(@NotNull File file) { - try (ZipFile f = new ZipFile(file); - InputStreamReader reader = new InputStreamReader(f.getInputStream(f.getEntry("extension.json")))) { + try (ZipFile f = new ZipFile(file);) { + + ZipEntry entry = f.getEntry("extension.json"); + + if (entry == null) + throw new IllegalStateException("Missing extension.json in extension " + file.getName() + "."); + + InputStreamReader reader = new InputStreamReader(f.getInputStream(entry)); // Initialize DiscoveredExtension from GSON. DiscoveredExtension extension = GSON.fromJson(reader, DiscoveredExtension.class); From a2f828986de5aa8f1ead9a1d7e0aea007687b5df Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 20 Jun 2021 17:40:37 +0200 Subject: [PATCH 02/39] Add RelativeLocation#fromView --- .../utils/location/RelativeBlockPosition.java | 13 +++++++ .../utils/location/RelativeLocation.java | 34 ++++++++++++------- .../server/utils/location/RelativeVec.java | 13 +++++++ 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/src/main/java/net/minestom/server/utils/location/RelativeBlockPosition.java b/src/main/java/net/minestom/server/utils/location/RelativeBlockPosition.java index b1b183e77..2a3ee592c 100644 --- a/src/main/java/net/minestom/server/utils/location/RelativeBlockPosition.java +++ b/src/main/java/net/minestom/server/utils/location/RelativeBlockPosition.java @@ -28,4 +28,17 @@ public class RelativeBlockPosition extends RelativeLocation { return new BlockPosition(x, y, z); } + + @Override + public BlockPosition fromView(@Nullable Position position) { + if (!relativeX && !relativeY && !relativeZ) { + return location.clone(); + } + final Position entityPosition = position != null ? position : new Position(); + + final int x = location.getX() + (relativeX ? (int) entityPosition.getYaw() : 0); + final int z = location.getZ() + (relativeZ ? (int) entityPosition.getPitch() : 0); + + return new BlockPosition(x, 0, z); + } } diff --git a/src/main/java/net/minestom/server/utils/location/RelativeLocation.java b/src/main/java/net/minestom/server/utils/location/RelativeLocation.java index fac09b12f..259406877 100644 --- a/src/main/java/net/minestom/server/utils/location/RelativeLocation.java +++ b/src/main/java/net/minestom/server/utils/location/RelativeLocation.java @@ -1,5 +1,6 @@ package net.minestom.server.utils.location; +import com.google.common.annotations.Beta; import net.minestom.server.entity.Entity; import net.minestom.server.utils.Position; import org.jetbrains.annotations.NotNull; @@ -22,19 +23,6 @@ public abstract class RelativeLocation { this.relativeZ = relativeZ; } - /** - * Gets the location based on the relative fields and {@code entity}. - * - * @param entity the entity to get the relative position from - * @return the location - */ - public T from(@Nullable Entity entity) { - - final Position entityPosition = entity != null ? entity.getPosition() : new Position(); - - return from(entityPosition); - } - /** * Gets the location based on the relative fields and {@code position}. * @@ -43,6 +31,26 @@ public abstract class RelativeLocation { */ public abstract T from(@Nullable Position position); + @Beta + public abstract T fromView(@Nullable Position position); + + /** + * Gets the location based on the relative fields and {@code entity}. + * + * @param entity the entity to get the relative position from + * @return the location + */ + public T from(@Nullable Entity entity) { + final Position entityPosition = entity != null ? entity.getPosition() : new Position(); + return from(entityPosition); + } + + @Beta + public T fromView(@Nullable Entity entity) { + final Position entityPosition = entity != null ? entity.getPosition() : new Position(); + return fromView(entityPosition); + } + /** * Gets if the 'x' field is relative. * diff --git a/src/main/java/net/minestom/server/utils/location/RelativeVec.java b/src/main/java/net/minestom/server/utils/location/RelativeVec.java index 42d948c84..df1c02ed9 100644 --- a/src/main/java/net/minestom/server/utils/location/RelativeVec.java +++ b/src/main/java/net/minestom/server/utils/location/RelativeVec.java @@ -28,4 +28,17 @@ public class RelativeVec extends RelativeLocation { return new Vector(x, y, z); } + + @Override + public Vector fromView(@Nullable Position position) { + if (!relativeX && !relativeY && !relativeZ) { + return location.clone(); + } + final Position entityPosition = position != null ? position : new Position(); + + final double x = location.getX() + (relativeX ? entityPosition.getYaw() : 0); + final double z = location.getZ() + (relativeZ ? entityPosition.getPitch() : 0); + + return new Vector(x, 0, z); + } } From f4f4a6386098565945ed1fd0dd3497f22cc46a06 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 20 Jun 2021 18:05:46 +0200 Subject: [PATCH 03/39] Replace deprecated serializer --- .../java/net/minestom/server/command/ConsoleSender.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/minestom/server/command/ConsoleSender.java b/src/main/java/net/minestom/server/command/ConsoleSender.java index 75bd72ad7..90d53f940 100644 --- a/src/main/java/net/minestom/server/command/ConsoleSender.java +++ b/src/main/java/net/minestom/server/command/ConsoleSender.java @@ -3,7 +3,7 @@ package net.minestom.server.command; import net.kyori.adventure.audience.MessageType; import net.kyori.adventure.identity.Identity; import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import net.minestom.server.permission.Permission; import org.jetbrains.annotations.NotNull; import org.slf4j.Logger; @@ -16,7 +16,7 @@ import java.util.concurrent.CopyOnWriteArraySet; * Represents the console when sending a command to the server. */ public class ConsoleSender implements CommandSender { - private static final PlainComponentSerializer PLAIN_SERIALIZER = PlainComponentSerializer.plain(); + private static final PlainTextComponentSerializer PLAIN_SERIALIZER = PlainTextComponentSerializer.plainText(); private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleSender.class); private final Set permissions = new CopyOnWriteArraySet<>(); @@ -27,7 +27,7 @@ public class ConsoleSender implements CommandSender { } @Override - public void sendMessage(@NotNull Identity source, @NotNull Component message, @NotNull MessageType type) { + public void sendMessage(@NotNull Identity source, @NotNull Component message, @NotNull MessageType type) { // we don't use the serializer here as we just need the plain text of the message this.sendMessage(PLAIN_SERIALIZER.serialize(message)); } From 1e9046d7929c24b680a7dcb1f1ebec953b73ab28 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 20 Jun 2021 20:59:53 +0200 Subject: [PATCH 04/39] Remove velocity compression library --- build.gradle | 6 ---- .../network/netty/codec/PacketCompressor.java | 33 +++++++++---------- .../minestom/server/utils/PacketUtils.java | 32 ++++++++++-------- 3 files changed, 35 insertions(+), 36 deletions(-) diff --git a/build.gradle b/build.gradle index 64eacd530..0a5100995 100644 --- a/build.gradle +++ b/build.gradle @@ -36,9 +36,6 @@ allprojects { name 'sponge' url 'https://repo.spongepowered.org/maven' } - maven { - url "https://repo.velocitypowered.com/snapshots/" - } } javadoc { options { @@ -153,9 +150,6 @@ dependencies { api "org.ow2.asm:asm-commons:${asmVersion}" api "org.spongepowered:mixin:${mixinVersion}" - // Compression - implementation "com.velocitypowered:velocity-native:1.1.0-SNAPSHOT" - // Path finding api 'com.github.MadMartian:hydrazine-path-finding:1.6.0' diff --git a/src/main/java/net/minestom/server/network/netty/codec/PacketCompressor.java b/src/main/java/net/minestom/server/network/netty/codec/PacketCompressor.java index 7f12b84a9..4ba5b0ef0 100644 --- a/src/main/java/net/minestom/server/network/netty/codec/PacketCompressor.java +++ b/src/main/java/net/minestom/server/network/netty/codec/PacketCompressor.java @@ -16,10 +16,8 @@ package net.minestom.server.network.netty.codec; -import com.velocitypowered.natives.compression.VelocityCompressor; -import com.velocitypowered.natives.util.MoreByteBufUtils; -import com.velocitypowered.natives.util.Natives; import io.netty.buffer.ByteBuf; +import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageCodec; import io.netty.handler.codec.DecoderException; @@ -27,6 +25,8 @@ import net.minestom.server.utils.PacketUtils; import net.minestom.server.utils.Utils; import java.util.List; +import java.util.zip.Deflater; +import java.util.zip.Inflater; public class PacketCompressor extends ByteToMessageCodec { @@ -34,7 +34,8 @@ public class PacketCompressor extends ByteToMessageCodec { private final int threshold; - private final VelocityCompressor compressor = Natives.compress.get().create(4); + private final Deflater deflater = new Deflater(); + private final Inflater inflater = new Inflater(); public PacketCompressor(int threshold) { this.threshold = threshold; @@ -42,7 +43,7 @@ public class PacketCompressor extends ByteToMessageCodec { @Override protected void encode(ChannelHandlerContext ctx, ByteBuf from, ByteBuf to) { - PacketUtils.compressBuffer(compressor, from, to); + PacketUtils.compressBuffer(deflater, from, to); } @Override @@ -61,19 +62,17 @@ public class PacketCompressor extends ByteToMessageCodec { throw new DecoderException("Badly compressed packet - size of " + claimedUncompressedSize + " is larger than protocol maximum of " + MAX_SIZE); } + // TODO optimize to do not initialize arrays each time - ByteBuf compatibleIn = MoreByteBufUtils.ensureCompatible(ctx.alloc(), compressor, in); - ByteBuf uncompressed = MoreByteBufUtils.preferredBuffer(ctx.alloc(), compressor, claimedUncompressedSize); - try { - compressor.inflate(compatibleIn, uncompressed, claimedUncompressedSize); - out.add(uncompressed); - in.clear(); - } catch (Exception e) { - uncompressed.release(); - throw e; - } finally { - compatibleIn.release(); - } + byte[] input = new byte[in.readableBytes()]; + in.readBytes(input); + + inflater.setInput(input); + byte[] output = new byte[claimedUncompressedSize]; + inflater.inflate(output); + inflater.reset(); + + out.add(Unpooled.wrappedBuffer(output)); } } } diff --git a/src/main/java/net/minestom/server/utils/PacketUtils.java b/src/main/java/net/minestom/server/utils/PacketUtils.java index ddf5eb29c..a0e4e7f5b 100644 --- a/src/main/java/net/minestom/server/utils/PacketUtils.java +++ b/src/main/java/net/minestom/server/utils/PacketUtils.java @@ -1,12 +1,9 @@ package net.minestom.server.utils; -import com.velocitypowered.natives.compression.VelocityCompressor; -import com.velocitypowered.natives.util.Natives; import io.netty.buffer.ByteBuf; import net.kyori.adventure.audience.Audience; import net.kyori.adventure.audience.ForwardingAudience; import net.minestom.server.MinecraftServer; -import net.minestom.server.adventure.AdventureSerializer; import net.minestom.server.adventure.MinestomAdventure; import net.minestom.server.adventure.audience.PacketGroupingAudience; import net.minestom.server.entity.Player; @@ -21,8 +18,9 @@ import net.minestom.server.utils.callback.validator.PlayerValidator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.nio.ByteBuffer; import java.util.Collection; -import java.util.zip.DataFormatException; +import java.util.zip.Deflater; /** * Utils class for packets. Including writing a {@link ServerPacket} into a {@link ByteBuf} @@ -31,7 +29,7 @@ import java.util.zip.DataFormatException; public final class PacketUtils { private static final PacketListenerManager PACKET_LISTENER_MANAGER = MinecraftServer.getPacketListenerManager(); - private static final ThreadLocal COMPRESSOR = ThreadLocal.withInitial(() -> Natives.compress.get().create(4)); + private static final ThreadLocal COMPRESSOR = ThreadLocal.withInitial(Deflater::new); private PacketUtils() { } @@ -189,27 +187,35 @@ public final class PacketUtils { *

* {@code packetBuffer} needs to be the packet content without any header (if you want to use it to write a Minecraft packet). * - * @param compressor the deflater for zlib compression + * @param deflater the deflater for zlib compression * @param packetBuffer the buffer containing all the packet fields * @param compressionTarget the buffer which will receive the compressed version of {@code packetBuffer} */ - public static void compressBuffer(@NotNull VelocityCompressor compressor, @NotNull ByteBuf packetBuffer, @NotNull ByteBuf compressionTarget) { + public static void compressBuffer(@NotNull Deflater deflater, @NotNull ByteBuf packetBuffer, @NotNull ByteBuf compressionTarget) { final int packetLength = packetBuffer.readableBytes(); final boolean compression = packetLength > MinecraftServer.getCompressionThreshold(); Utils.writeVarInt(compressionTarget, compression ? packetLength : 0); if (compression) { - compress(compressor, packetBuffer, compressionTarget); + compress(deflater, packetBuffer, compressionTarget); } else { compressionTarget.writeBytes(packetBuffer); } } - private static void compress(@NotNull VelocityCompressor compressor, @NotNull ByteBuf uncompressed, @NotNull ByteBuf compressed) { - try { - compressor.deflate(uncompressed, compressed); - } catch (DataFormatException e) { - e.printStackTrace(); + private static void compress(@NotNull Deflater deflater, @NotNull ByteBuf uncompressed, @NotNull ByteBuf compressed) { + deflater.setInput(uncompressed.nioBuffer()); + deflater.finish(); + + while (!deflater.finished()) { + ByteBuffer nioBuffer = compressed.nioBuffer(compressed.writerIndex(), compressed.writableBytes()); + compressed.writerIndex(deflater.deflate(nioBuffer) + compressed.writerIndex()); + + if (compressed.writableBytes() == 0) { + compressed.ensureWritable(8192); + } } + + deflater.reset(); } public static void writeFramedPacket(@NotNull ByteBuf buffer, From 4db3b9317de01750c043cb6d4812df19d1e6b662 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 20 Jun 2021 21:48:07 +0200 Subject: [PATCH 05/39] Replace google Beta annotation to jetbrains ApiStatus.Experimental --- .../java/net/minestom/server/acquirable/Acquirable.java | 3 +-- .../minestom/server/acquirable/AcquirableCollection.java | 4 ++-- .../java/net/minestom/server/command/builder/Command.java | 8 ++++---- .../server/command/builder/arguments/Argument.java | 6 +++--- .../server/command/builder/arguments/ArgumentCommand.java | 4 ++-- .../server/command/builder/arguments/ArgumentType.java | 4 ++-- .../server/command/builder/parser/ArgumentParser.java | 4 ++-- src/main/java/net/minestom/server/entity/Entity.java | 5 ++--- .../java/net/minestom/server/item/ItemStackBuilder.java | 4 ++-- src/main/java/net/minestom/server/tag/TagHandler.java | 4 ++-- .../minestom/server/utils/location/RelativeLocation.java | 6 +++--- 11 files changed, 25 insertions(+), 27 deletions(-) diff --git a/src/main/java/net/minestom/server/acquirable/Acquirable.java b/src/main/java/net/minestom/server/acquirable/Acquirable.java index 0781550de..b1f290e85 100644 --- a/src/main/java/net/minestom/server/acquirable/Acquirable.java +++ b/src/main/java/net/minestom/server/acquirable/Acquirable.java @@ -1,6 +1,5 @@ package net.minestom.server.acquirable; -import com.google.common.annotations.Beta; import net.minestom.server.entity.Entity; import net.minestom.server.thread.ThreadProvider; import net.minestom.server.thread.TickThread; @@ -14,7 +13,7 @@ import java.util.Optional; import java.util.function.Consumer; import java.util.stream.Stream; -@Beta +@ApiStatus.Experimental public interface Acquirable { /** diff --git a/src/main/java/net/minestom/server/acquirable/AcquirableCollection.java b/src/main/java/net/minestom/server/acquirable/AcquirableCollection.java index 225a725d4..0114d79e1 100644 --- a/src/main/java/net/minestom/server/acquirable/AcquirableCollection.java +++ b/src/main/java/net/minestom/server/acquirable/AcquirableCollection.java @@ -1,15 +1,15 @@ package net.minestom.server.acquirable; -import com.google.common.annotations.Beta; import net.minestom.server.thread.TickThread; import net.minestom.server.utils.async.AsyncUtils; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import java.util.*; import java.util.function.Consumer; import java.util.stream.Stream; -@Beta +@ApiStatus.Experimental public class AcquirableCollection implements Collection> { private final Collection> acquirableCollection; diff --git a/src/main/java/net/minestom/server/command/builder/Command.java b/src/main/java/net/minestom/server/command/builder/Command.java index d7907626d..d85681794 100644 --- a/src/main/java/net/minestom/server/command/builder/Command.java +++ b/src/main/java/net/minestom/server/command/builder/Command.java @@ -1,6 +1,5 @@ package net.minestom.server.command.builder; -import com.google.common.annotations.Beta; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import net.minestom.server.command.CommandSender; @@ -10,6 +9,7 @@ import net.minestom.server.command.builder.arguments.ArgumentType; import net.minestom.server.command.builder.arguments.ArgumentWord; import net.minestom.server.command.builder.condition.CommandCondition; import net.minestom.server.utils.StringUtils; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @@ -221,7 +221,7 @@ public class Command { * @param format the syntax format * @return the newly created {@link CommandSyntax syntaxes}. */ - @Beta + @ApiStatus.Experimental public @NotNull Collection addSyntax(@NotNull CommandExecutor executor, @NotNull String format) { return addSyntax(executor, ArgumentType.generate(format)); } @@ -302,7 +302,7 @@ public class Command { public void globalListener(@NotNull CommandSender sender, @NotNull CommandContext context, @NotNull String command) { } - @Beta + @ApiStatus.Experimental public @NotNull Set getSyntaxesStrings() { Set syntaxes = new HashSet<>(); @@ -320,7 +320,7 @@ public class Command { return syntaxes; } - @Beta + @ApiStatus.Experimental public @NotNull String getSyntaxesTree() { Node commandNode = new Node(); commandNode.names.addAll(Arrays.asList(getNames())); diff --git a/src/main/java/net/minestom/server/command/builder/arguments/Argument.java b/src/main/java/net/minestom/server/command/builder/arguments/Argument.java index 6f67e767a..df02b9ca3 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/Argument.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/Argument.java @@ -1,6 +1,5 @@ package net.minestom.server.command.builder.arguments; -import com.google.common.annotations.Beta; import net.minestom.server.command.builder.ArgumentCallback; import net.minestom.server.command.builder.Command; import net.minestom.server.command.builder.CommandExecutor; @@ -8,6 +7,7 @@ import net.minestom.server.command.builder.NodeMaker; import net.minestom.server.command.builder.exception.ArgumentSyntaxException; import net.minestom.server.command.builder.suggestion.SuggestionCallback; import net.minestom.server.network.packet.server.play.DeclareCommandsPacket; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -210,8 +210,8 @@ public abstract class Argument { /** * Gets the suggestion callback of the argument * - * @see #setSuggestionCallback * @return the suggestion callback of the argument, null if it doesn't exist + * @see #setSuggestionCallback */ @Nullable public SuggestionCallback getSuggestionCallback() { @@ -247,7 +247,7 @@ public abstract class Argument { * @param The type of output expected. * @return A new ArgumentMap that can get this complex object type. */ - @Beta + @ApiStatus.Experimental public @NotNull ArgumentMap map(@NotNull ArgumentMap.Mapper mapper) { return new ArgumentMap<>(this, mapper); } diff --git a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentCommand.java b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentCommand.java index 335be5300..7068ffedc 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentCommand.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentCommand.java @@ -1,6 +1,5 @@ package net.minestom.server.command.builder.arguments; -import com.google.common.annotations.Beta; import net.minestom.server.MinecraftServer; import net.minestom.server.command.builder.CommandDispatcher; import net.minestom.server.command.builder.CommandResult; @@ -8,6 +7,7 @@ import net.minestom.server.command.builder.NodeMaker; import net.minestom.server.command.builder.exception.ArgumentSyntaxException; import net.minestom.server.network.packet.server.play.DeclareCommandsPacket; import net.minestom.server.utils.StringUtils; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; public class ArgumentCommand extends Argument { @@ -69,7 +69,7 @@ public class ArgumentCommand extends Argument { return shortcut; } - @Beta + @ApiStatus.Experimental public ArgumentCommand setShortcut(@NotNull String shortcut) { this.shortcut = shortcut; return this; diff --git a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentType.java b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentType.java index 16eaf03f3..dc9ebc4e4 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/ArgumentType.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/ArgumentType.java @@ -1,6 +1,5 @@ package net.minestom.server.command.builder.arguments; -import com.google.common.annotations.Beta; import net.minestom.server.command.builder.arguments.minecraft.*; import net.minestom.server.command.builder.arguments.minecraft.registry.*; import net.minestom.server.command.builder.arguments.number.ArgumentDouble; @@ -11,6 +10,7 @@ import net.minestom.server.command.builder.arguments.relative.ArgumentRelativeBl import net.minestom.server.command.builder.arguments.relative.ArgumentRelativeVec2; import net.minestom.server.command.builder.arguments.relative.ArgumentRelativeVec3; import net.minestom.server.command.builder.parser.ArgumentParser; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; /** @@ -248,7 +248,7 @@ public class ArgumentType { *

* Note: this feature is in beta and is very likely to change depending on feedback. */ - @Beta + @ApiStatus.Experimental public static Argument[] generate(@NotNull String format) { return ArgumentParser.generate(format); } diff --git a/src/main/java/net/minestom/server/command/builder/parser/ArgumentParser.java b/src/main/java/net/minestom/server/command/builder/parser/ArgumentParser.java index 0c51c8aa5..39c246df1 100644 --- a/src/main/java/net/minestom/server/command/builder/parser/ArgumentParser.java +++ b/src/main/java/net/minestom/server/command/builder/parser/ArgumentParser.java @@ -1,6 +1,5 @@ package net.minestom.server.command.builder.parser; -import com.google.common.annotations.Beta; import net.minestom.server.command.builder.arguments.*; import net.minestom.server.command.builder.arguments.minecraft.*; import net.minestom.server.command.builder.arguments.minecraft.registry.*; @@ -12,6 +11,7 @@ import net.minestom.server.command.builder.arguments.relative.ArgumentRelativeVe import net.minestom.server.command.builder.arguments.relative.ArgumentRelativeVec3; import net.minestom.server.command.builder.exception.ArgumentSyntaxException; import net.minestom.server.utils.StringUtils; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -63,7 +63,7 @@ public class ArgumentParser { ARGUMENT_FUNCTION_MAP.put("relativevec2", ArgumentRelativeVec2::new); } - @Beta + @ApiStatus.Experimental public static @NotNull Argument[] generate(@NotNull String format) { List> result = new ArrayList<>(); diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index ad678cd0d..68966e023 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -1,6 +1,5 @@ package net.minestom.server.entity; -import com.google.common.annotations.Beta; import com.google.common.collect.Queues; import net.kyori.adventure.sound.Sound; import net.kyori.adventure.text.Component; @@ -1620,12 +1619,12 @@ public class Entity implements Viewable, Tickable, EventHandler, Da return Objects.requireNonNullElse(this.customSynchronizationCooldown, SYNCHRONIZATION_COOLDOWN); } - @Beta + @ApiStatus.Experimental public @NotNull Acquirable getAcquirable() { return (Acquirable) acquirable; } - @Beta + @ApiStatus.Experimental public @NotNull Acquirable getAcquirable(@NotNull Class clazz) { return (Acquirable) acquirable; } diff --git a/src/main/java/net/minestom/server/item/ItemStackBuilder.java b/src/main/java/net/minestom/server/item/ItemStackBuilder.java index 12b0b8a3a..75a2b42f7 100644 --- a/src/main/java/net/minestom/server/item/ItemStackBuilder.java +++ b/src/main/java/net/minestom/server/item/ItemStackBuilder.java @@ -1,8 +1,8 @@ package net.minestom.server.item; -import com.google.common.annotations.Beta; import net.kyori.adventure.text.Component; import net.minestom.server.item.metadata.*; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -100,7 +100,7 @@ public class ItemStackBuilder { return this; } - @Beta + @ApiStatus.Experimental @Contract(value = "_ -> this") public @NotNull ItemStackBuilder stackingRule(@Nullable StackingRule stackingRule) { this.stackingRule = stackingRule; diff --git a/src/main/java/net/minestom/server/tag/TagHandler.java b/src/main/java/net/minestom/server/tag/TagHandler.java index b53db14a1..fa0d7042b 100644 --- a/src/main/java/net/minestom/server/tag/TagHandler.java +++ b/src/main/java/net/minestom/server/tag/TagHandler.java @@ -1,10 +1,10 @@ package net.minestom.server.tag; -import com.google.common.annotations.Beta; +import org.jetbrains.annotations.ApiStatus; /** * Represents an element which can read and write {@link Tag tags}. */ -@Beta +@ApiStatus.Experimental public interface TagHandler extends TagReadable, TagWritable { } diff --git a/src/main/java/net/minestom/server/utils/location/RelativeLocation.java b/src/main/java/net/minestom/server/utils/location/RelativeLocation.java index 259406877..b2c2135fc 100644 --- a/src/main/java/net/minestom/server/utils/location/RelativeLocation.java +++ b/src/main/java/net/minestom/server/utils/location/RelativeLocation.java @@ -1,8 +1,8 @@ package net.minestom.server.utils.location; -import com.google.common.annotations.Beta; import net.minestom.server.entity.Entity; import net.minestom.server.utils.Position; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -31,7 +31,7 @@ public abstract class RelativeLocation { */ public abstract T from(@Nullable Position position); - @Beta + @ApiStatus.Experimental public abstract T fromView(@Nullable Position position); /** @@ -45,7 +45,7 @@ public abstract class RelativeLocation { return from(entityPosition); } - @Beta + @ApiStatus.Experimental public T fromView(@Nullable Entity entity) { final Position entityPosition = entity != null ? entity.getPosition() : new Position(); return fromView(entityPosition); From 0be2addbd8999b3fa61820ab0e07e7e476194614 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 20 Jun 2021 22:03:14 +0200 Subject: [PATCH 06/39] Remove most unnecessary uses of google common --- .../net/minestom/server/UpdateManager.java | 5 ++--- .../net/minestom/server/entity/Entity.java | 4 ++-- .../net/minestom/server/entity/Player.java | 4 ++-- .../server/entity/ai/goal/DoNothingGoal.java | 2 +- .../net/minestom/server/instance/Instance.java | 4 ++-- .../net/minestom/server/scoreboard/Team.java | 4 ++-- .../net/minestom/server/utils/MathUtils.java | 18 +++++++++--------- .../java/net/minestom/server/utils/Vector.java | 3 +-- 8 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/main/java/net/minestom/server/UpdateManager.java b/src/main/java/net/minestom/server/UpdateManager.java index 37fc0ae7e..419d0d8eb 100644 --- a/src/main/java/net/minestom/server/UpdateManager.java +++ b/src/main/java/net/minestom/server/UpdateManager.java @@ -1,6 +1,5 @@ package net.minestom.server; -import com.google.common.collect.Queues; import net.minestom.server.acquirable.Acquirable; import net.minestom.server.instance.Chunk; import net.minestom.server.instance.Instance; @@ -34,8 +33,8 @@ public final class UpdateManager { // TODO make configurable private ThreadProvider threadProvider = new SingleThreadProvider(); - private final Queue tickStartCallbacks = Queues.newConcurrentLinkedQueue(); - private final Queue tickEndCallbacks = Queues.newConcurrentLinkedQueue(); + private final Queue tickStartCallbacks = new ConcurrentLinkedQueue<>(); + private final Queue tickEndCallbacks = new ConcurrentLinkedQueue<>(); private final List> tickMonitors = new CopyOnWriteArrayList<>(); /** diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index 68966e023..ddd0a833a 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -1,6 +1,5 @@ package net.minestom.server.entity; -import com.google.common.collect.Queues; import net.kyori.adventure.sound.Sound; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.event.HoverEvent; @@ -53,6 +52,7 @@ import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; import java.util.concurrent.atomic.AtomicInteger; @@ -127,7 +127,7 @@ public class Entity implements Viewable, Tickable, EventHandler, Da private final List effects = new CopyOnWriteArrayList<>(); // list of scheduled tasks to be executed during the next entity tick - protected final Queue> nextTick = Queues.newConcurrentLinkedQueue(); + protected final Queue> nextTick = new ConcurrentLinkedQueue<>(); // Tick related private long ticks; diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index 48f36afbd..873decdb6 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -1,6 +1,5 @@ package net.minestom.server.entity; -import com.google.common.collect.Queues; import net.kyori.adventure.audience.MessageType; import net.kyori.adventure.bossbar.BossBar; import net.kyori.adventure.identity.Identified; @@ -87,6 +86,7 @@ import org.jetbrains.annotations.Nullable; import java.nio.charset.StandardCharsets; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.UnaryOperator; @@ -119,7 +119,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, private final AtomicInteger teleportId = new AtomicInteger(); private int receivedTeleportId; - private final Queue packets = Queues.newConcurrentLinkedQueue(); + private final Queue packets = new ConcurrentLinkedQueue<>(); private final boolean levelFlat; private final PlayerSettings settings; private float exp; diff --git a/src/main/java/net/minestom/server/entity/ai/goal/DoNothingGoal.java b/src/main/java/net/minestom/server/entity/ai/goal/DoNothingGoal.java index 05afd09c6..aed3f1b92 100644 --- a/src/main/java/net/minestom/server/entity/ai/goal/DoNothingGoal.java +++ b/src/main/java/net/minestom/server/entity/ai/goal/DoNothingGoal.java @@ -24,7 +24,7 @@ public class DoNothingGoal extends GoalSelector { public DoNothingGoal(EntityCreature entityCreature, long time, float chance) { super(entityCreature); this.time = time; - this.chance = MathUtils.clampFloat(chance, 0, 1); + this.chance = MathUtils.clamp(chance, 0, 1); } @Override diff --git a/src/main/java/net/minestom/server/instance/Instance.java b/src/main/java/net/minestom/server/instance/Instance.java index 0015a33a2..d0f9352b3 100644 --- a/src/main/java/net/minestom/server/instance/Instance.java +++ b/src/main/java/net/minestom/server/instance/Instance.java @@ -1,6 +1,5 @@ package net.minestom.server.instance; -import com.google.common.collect.Queues; import net.kyori.adventure.identity.Identity; import net.kyori.adventure.pointer.Pointers; import net.minestom.server.MinecraftServer; @@ -47,6 +46,7 @@ import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentLinkedQueue; import java.util.function.Consumer; /** @@ -98,7 +98,7 @@ public abstract class Instance implements BlockModifier, Tickable, EventHandler< protected UUID uniqueId; // list of scheduled tasks to be executed during the next instance tick - protected final Queue> nextTick = Queues.newConcurrentLinkedQueue(); + protected final Queue> nextTick = new ConcurrentLinkedQueue<>(); // instance custom data private Data data; diff --git a/src/main/java/net/minestom/server/scoreboard/Team.java b/src/main/java/net/minestom/server/scoreboard/Team.java index f316c44b8..aa6cc59fa 100644 --- a/src/main/java/net/minestom/server/scoreboard/Team.java +++ b/src/main/java/net/minestom/server/scoreboard/Team.java @@ -1,6 +1,5 @@ package net.minestom.server.scoreboard; -import com.google.common.collect.MapMaker; import net.kyori.adventure.identity.Identity; import net.kyori.adventure.pointer.Pointers; import net.kyori.adventure.text.Component; @@ -22,6 +21,7 @@ import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.Collections; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArraySet; /** @@ -72,7 +72,7 @@ public class Team implements PacketGroupingAudience { */ private Component suffix; - private final Set playerMembers = Collections.newSetFromMap(new MapMaker().weakKeys().makeMap()); + private final Set playerMembers = ConcurrentHashMap.newKeySet(); private boolean isPlayerMembersUpToDate; // Adventure diff --git a/src/main/java/net/minestom/server/utils/MathUtils.java b/src/main/java/net/minestom/server/utils/MathUtils.java index 788ec6a20..3012f80b1 100644 --- a/src/main/java/net/minestom/server/utils/MathUtils.java +++ b/src/main/java/net/minestom/server/utils/MathUtils.java @@ -47,10 +47,6 @@ public final class MathUtils { return Direction.HORIZONTAL[directionIndex]; } - public static float clampFloat(float t, float a, float b) { - return Math.max(a, Math.min(t, b)); - } - public static boolean isBetween(byte number, byte min, byte max) { return number >= min && number <= max; } @@ -84,11 +80,15 @@ public final class MathUtils { } public static int clamp(int value, int min, int max) { - if (value < min) { - return min; - } else { - return Math.min(value, max); - } + return Math.min(Math.max(value, min), max); + } + + public static float clamp(float value, float min, float max) { + return Math.min(Math.max(value, min), max); + } + + public static double clamp(double value, double min, double max) { + return Math.min(Math.max(value, min), max); } public static double mod(final double a, final double b) { diff --git a/src/main/java/net/minestom/server/utils/Vector.java b/src/main/java/net/minestom/server/utils/Vector.java index c77d69219..1833b8a7b 100644 --- a/src/main/java/net/minestom/server/utils/Vector.java +++ b/src/main/java/net/minestom/server/utils/Vector.java @@ -1,6 +1,5 @@ package net.minestom.server.utils; -import com.google.common.primitives.Doubles; import net.minestom.server.MinecraftServer; import net.minestom.server.utils.clone.PublicCloneable; import org.jetbrains.annotations.NotNull; @@ -167,7 +166,7 @@ public class Vector implements PublicCloneable { * @return angle in radians */ public float angle(@NotNull Vector other) { - double dot = Doubles.constrainToRange(dot(other) / (length() * other.length()), -1.0, 1.0); + double dot = MathUtils.clamp(dot(other) / (length() * other.length()), -1.0, 1.0); return (float) Math.acos(dot); } From 14afa0fbf4f6616f219442bf66eb529f44b4691d Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 20 Jun 2021 22:06:19 +0200 Subject: [PATCH 07/39] Less google --- .../minestom/server/extras/velocity/VelocityProxy.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/minestom/server/extras/velocity/VelocityProxy.java b/src/main/java/net/minestom/server/extras/velocity/VelocityProxy.java index 517c45459..f4a133243 100644 --- a/src/main/java/net/minestom/server/extras/velocity/VelocityProxy.java +++ b/src/main/java/net/minestom/server/extras/velocity/VelocityProxy.java @@ -1,7 +1,7 @@ package net.minestom.server.extras.velocity; -import com.google.common.net.InetAddresses; import io.netty.buffer.ByteBuf; +import net.minestom.server.MinecraftServer; import net.minestom.server.entity.PlayerSkin; import net.minestom.server.utils.binary.BinaryReader; import org.jetbrains.annotations.NotNull; @@ -9,6 +9,7 @@ import org.jetbrains.annotations.NotNull; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.net.InetAddress; +import java.net.UnknownHostException; import java.security.InvalidKeyException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; @@ -73,7 +74,12 @@ public final class VelocityProxy { } public static InetAddress readAddress(@NotNull BinaryReader reader) { - return InetAddresses.forString(reader.readSizedString()); + try { + return InetAddress.getByName(reader.readSizedString()); + } catch (UnknownHostException e) { + MinecraftServer.getExceptionManager().handleException(e); + return null; + } } public static PlayerSkin readSkin(@NotNull BinaryReader reader) { From c90bae063a44cb8e4aa800f0ec28f0e0c0b45837 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 20 Jun 2021 22:19:03 +0200 Subject: [PATCH 08/39] Update netty --- build.gradle | 9 ++++----- .../minestom/server/network/netty/NettyServer.java | 12 +----------- 2 files changed, 5 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index 0a5100995..c1286d6e6 100644 --- a/build.gradle +++ b/build.gradle @@ -108,11 +108,10 @@ dependencies { testCompileOnly "org.mockito:mockito-core:2.28.2" // Netty - api 'io.netty:netty-handler:4.1.63.Final' - api 'io.netty:netty-codec:4.1.63.Final' - api 'io.netty:netty-transport-native-epoll:4.1.63.Final:linux-x86_64' - api 'io.netty:netty-transport-native-kqueue:4.1.63.Final:osx-x86_64' - api 'io.netty.incubator:netty-incubator-transport-native-io_uring:0.0.5.Final:linux-x86_64' + api 'io.netty:netty-handler:4.1.65.Final' + api 'io.netty:netty-codec:4.1.65.Final' + api 'io.netty:netty-transport-native-epoll:4.1.65.Final:linux-x86_64' + api 'io.netty:netty-transport-native-kqueue:4.1.65.Final:osx-x86_64' // https://mvnrepository.com/artifact/it.unimi.dsi/fastutil api 'it.unimi.dsi:fastutil:8.5.4' diff --git a/src/main/java/net/minestom/server/network/netty/NettyServer.java b/src/main/java/net/minestom/server/network/netty/NettyServer.java index a3f77c388..c9adc82b9 100644 --- a/src/main/java/net/minestom/server/network/netty/NettyServer.java +++ b/src/main/java/net/minestom/server/network/netty/NettyServer.java @@ -13,9 +13,6 @@ import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.ServerSocketChannel; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; -import io.netty.incubator.channel.uring.IOUring; -import io.netty.incubator.channel.uring.IOUringEventLoopGroup; -import io.netty.incubator.channel.uring.IOUringServerSocketChannel; import net.minestom.server.MinecraftServer; import net.minestom.server.network.PacketProcessor; import net.minestom.server.network.netty.channel.ClientChannel; @@ -82,14 +79,7 @@ public final class NettyServer { // Find boss/worker event group { - if (IOUring.isAvailable()) { - boss = new IOUringEventLoopGroup(2); - worker = new IOUringEventLoopGroup(workerThreadCount); - - channel = IOUringServerSocketChannel.class; - - LOGGER.info("Using io_uring"); - } else if (Epoll.isAvailable()) { + if (Epoll.isAvailable()) { boss = new EpollEventLoopGroup(2); worker = new EpollEventLoopGroup(workerThreadCount); From e635e29a1691dff44896912874b281d3db72c4cc Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 20 Jun 2021 22:32:06 +0200 Subject: [PATCH 09/39] Replace guava cache to caffeine --- build.gradle | 2 ++ .../server/command/builder/CommandDispatcher.java | 6 +++--- .../net/minestom/server/utils/cache/TemporaryCache.java | 8 ++++---- .../minestom/server/utils/cache/TemporaryPacketCache.java | 6 ++++-- .../net/minestom/server/utils/mojang/MojangUtils.java | 8 ++++---- 5 files changed, 17 insertions(+), 13 deletions(-) diff --git a/build.gradle b/build.gradle index c1286d6e6..3879f18dd 100644 --- a/build.gradle +++ b/build.gradle @@ -138,6 +138,8 @@ dependencies { // https://search.maven.org/artifact/org.fusesource.jansi/jansi/2.3.2/jar implementation 'org.fusesource.jansi:jansi:2.3.2' + implementation 'com.github.ben-manes.caffeine:caffeine:3.0.2' + // Guava 21.0+ required for Mixin api 'com.google.guava:guava:30.1-jre' diff --git a/src/main/java/net/minestom/server/command/builder/CommandDispatcher.java b/src/main/java/net/minestom/server/command/builder/CommandDispatcher.java index dc930af34..efbd1595c 100644 --- a/src/main/java/net/minestom/server/command/builder/CommandDispatcher.java +++ b/src/main/java/net/minestom/server/command/builder/CommandDispatcher.java @@ -1,7 +1,7 @@ package net.minestom.server.command.builder; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; import it.unimi.dsi.fastutil.ints.Int2ObjectRBTreeMap; import net.minestom.server.command.CommandSender; import net.minestom.server.command.builder.arguments.Argument; @@ -25,7 +25,7 @@ public class CommandDispatcher { private final Map commandMap = new HashMap<>(); private final Set commands = new HashSet<>(); - private final Cache cache = CacheBuilder.newBuilder() + private final Cache cache = Caffeine.newBuilder() .expireAfterWrite(30, TimeUnit.SECONDS) .build(); diff --git a/src/main/java/net/minestom/server/utils/cache/TemporaryCache.java b/src/main/java/net/minestom/server/utils/cache/TemporaryCache.java index da2e64a23..beb1bff2b 100644 --- a/src/main/java/net/minestom/server/utils/cache/TemporaryCache.java +++ b/src/main/java/net/minestom/server/utils/cache/TemporaryCache.java @@ -1,8 +1,8 @@ package net.minestom.server.utils.cache; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; -import com.google.common.cache.RemovalListener; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; +import com.github.benmanes.caffeine.cache.RemovalListener; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -24,7 +24,7 @@ public class TemporaryCache { * @param duration the time before considering an object unused */ public TemporaryCache(long duration, TimeUnit timeUnit, RemovalListener removalListener) { - this.cache = CacheBuilder.newBuilder() + this.cache = Caffeine.newBuilder() .expireAfterWrite(duration, timeUnit) .removalListener(removalListener) .build(); diff --git a/src/main/java/net/minestom/server/utils/cache/TemporaryPacketCache.java b/src/main/java/net/minestom/server/utils/cache/TemporaryPacketCache.java index 6d6fe1d5e..7d805e904 100644 --- a/src/main/java/net/minestom/server/utils/cache/TemporaryPacketCache.java +++ b/src/main/java/net/minestom/server/utils/cache/TemporaryPacketCache.java @@ -6,8 +6,10 @@ import java.util.concurrent.TimeUnit; public class TemporaryPacketCache extends TemporaryCache { public TemporaryPacketCache(long duration, TimeUnit timeUnit) { - super(duration, timeUnit, notification -> { - final ByteBuf buffer = notification.getValue().getBuffer(); + super(duration, timeUnit, (key, value, cause) -> { + if (value == null) + return; + final ByteBuf buffer = value.getBuffer(); synchronized (buffer) { buffer.release(); } diff --git a/src/main/java/net/minestom/server/utils/mojang/MojangUtils.java b/src/main/java/net/minestom/server/utils/mojang/MojangUtils.java index 04e0df2d7..d019bdc1b 100644 --- a/src/main/java/net/minestom/server/utils/mojang/MojangUtils.java +++ b/src/main/java/net/minestom/server/utils/mojang/MojangUtils.java @@ -1,7 +1,7 @@ package net.minestom.server.utils.mojang; -import com.google.common.cache.Cache; -import com.google.common.cache.CacheBuilder; +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import net.minestom.server.MinecraftServer; @@ -17,12 +17,12 @@ import java.util.concurrent.TimeUnit; */ public final class MojangUtils { - private static final Cache UUID_CACHE = CacheBuilder.newBuilder() + private static final Cache UUID_CACHE = Caffeine.newBuilder() .expireAfterWrite(30, TimeUnit.SECONDS) .softValues() .build(); - private static final Cache USERNAME_CACHE = CacheBuilder.newBuilder() + private static final Cache USERNAME_CACHE = Caffeine.newBuilder() .expireAfterWrite(30, TimeUnit.SECONDS) .softValues() .build(); From 1f2dc0cd9fed757668c03ee52e01cbe465d526b9 Mon Sep 17 00:00:00 2001 From: TheMode Date: Mon, 21 Jun 2021 15:01:50 +0200 Subject: [PATCH 10/39] Add some inline packet initialization --- .../java/net/minestom/server/entity/Player.java | 4 +--- .../server/instance/InstanceContainer.java | 5 +---- .../server/listener/BlockPlacementListener.java | 5 +---- .../server/listener/PlayerDiggingListener.java | 9 +-------- .../play/AcknowledgePlayerDiggingPacket.java | 16 +++++++++++++--- .../packet/server/play/ActionBarPacket.java | 9 +++++---- .../packet/server/play/AttachEntityPacket.java | 15 ++++++++++++++- .../packet/server/play/BlockChangePacket.java | 7 ++++++- .../network/packet/server/play/CameraPacket.java | 13 ++++++++++++- .../packet/server/play/ChatMessagePacket.java | 10 ++++------ 10 files changed, 58 insertions(+), 35 deletions(-) diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index 873decdb6..0b875b1fd 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -1379,9 +1379,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, * @param entity the entity to spectate */ public void spectate(@NotNull Entity entity) { - CameraPacket cameraPacket = new CameraPacket(); - cameraPacket.cameraId = entity.getEntityId(); - playerConnection.sendPacket(cameraPacket); + playerConnection.sendPacket(new CameraPacket(entity)); } /** diff --git a/src/main/java/net/minestom/server/instance/InstanceContainer.java b/src/main/java/net/minestom/server/instance/InstanceContainer.java index aa3451643..d8a7d5fe2 100644 --- a/src/main/java/net/minestom/server/instance/InstanceContainer.java +++ b/src/main/java/net/minestom/server/instance/InstanceContainer.java @@ -750,10 +750,7 @@ public class InstanceContainer extends Instance { * @param blockStateId the new state of the block */ private void sendBlockChange(@NotNull Chunk chunk, @NotNull BlockPosition blockPosition, short blockStateId) { - BlockChangePacket blockChangePacket = new BlockChangePacket(); - blockChangePacket.blockPosition = blockPosition; - blockChangePacket.blockStateId = blockStateId; - chunk.sendPacketToViewers(blockChangePacket); + chunk.sendPacketToViewers(new BlockChangePacket(blockPosition, blockStateId)); } @Override diff --git a/src/main/java/net/minestom/server/listener/BlockPlacementListener.java b/src/main/java/net/minestom/server/listener/BlockPlacementListener.java index 79c2d4cd0..6d60411db 100644 --- a/src/main/java/net/minestom/server/listener/BlockPlacementListener.java +++ b/src/main/java/net/minestom/server/listener/BlockPlacementListener.java @@ -104,10 +104,7 @@ public class BlockPlacementListener { //Send a block change with AIR as block to keep the client in sync, //using refreshChunk results in the client not being in sync //after rapid invalid block placements - BlockChangePacket blockChangePacket = new BlockChangePacket(); - blockChangePacket.blockPosition = blockPosition; - blockChangePacket.blockStateId = Block.AIR.getBlockId(); - player.getPlayerConnection().sendPacket(blockChangePacket); + player.getPlayerConnection().sendPacket(new BlockChangePacket(blockPosition, Block.AIR.getBlockId())); } return; } diff --git a/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java b/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java index 3c04ee9e4..a92f6f59a 100644 --- a/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java +++ b/src/main/java/net/minestom/server/listener/PlayerDiggingListener.java @@ -263,13 +263,6 @@ public class PlayerDiggingListener { */ private static void sendAcknowledgePacket(@NotNull Player player, @NotNull BlockPosition blockPosition, int blockStateId, @NotNull ClientPlayerDiggingPacket.Status status, boolean success) { - AcknowledgePlayerDiggingPacket acknowledgePlayerDiggingPacket = new AcknowledgePlayerDiggingPacket(); - acknowledgePlayerDiggingPacket.blockPosition = blockPosition; - acknowledgePlayerDiggingPacket.blockStateId = blockStateId; - acknowledgePlayerDiggingPacket.status = status; - acknowledgePlayerDiggingPacket.successful = success; - - player.getPlayerConnection().sendPacket(acknowledgePlayerDiggingPacket); + player.getPlayerConnection().sendPacket(new AcknowledgePlayerDiggingPacket(blockPosition, blockStateId, status, success)); } - } diff --git a/src/main/java/net/minestom/server/network/packet/server/play/AcknowledgePlayerDiggingPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/AcknowledgePlayerDiggingPacket.java index da9cc6d82..36e25f056 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/AcknowledgePlayerDiggingPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/AcknowledgePlayerDiggingPacket.java @@ -10,12 +10,22 @@ import org.jetbrains.annotations.NotNull; public class AcknowledgePlayerDiggingPacket implements ServerPacket { - public BlockPosition blockPosition = new BlockPosition(0,0,0); + public BlockPosition blockPosition; public int blockStateId; - public ClientPlayerDiggingPacket.Status status = ClientPlayerDiggingPacket.Status.STARTED_DIGGING; + public ClientPlayerDiggingPacket.Status status; public boolean successful; - public AcknowledgePlayerDiggingPacket() {} + public AcknowledgePlayerDiggingPacket(@NotNull BlockPosition blockPosition, int blockStateId, + @NotNull ClientPlayerDiggingPacket.Status status, boolean success) { + this.blockPosition = blockPosition; + this.blockStateId = blockStateId; + this.status = status; + this.successful = success; + } + + public AcknowledgePlayerDiggingPacket() { + this(new BlockPosition(0, 0, 0), 0, ClientPlayerDiggingPacket.Status.STARTED_DIGGING, false); + } @Override public void write(@NotNull BinaryWriter writer) { diff --git a/src/main/java/net/minestom/server/network/packet/server/play/ActionBarPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/ActionBarPacket.java index e47f43d10..8c12cc9e6 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/ActionBarPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/ActionBarPacket.java @@ -9,13 +9,14 @@ import org.jetbrains.annotations.NotNull; public class ActionBarPacket implements ServerPacket { - public Component actionBarText = Component.empty(); + public Component actionBarText; - public ActionBarPacket() { + public ActionBarPacket(@NotNull Component actionBarText) { + this.actionBarText = actionBarText; } - public ActionBarPacket(Component actionBarText) { - this.actionBarText = actionBarText; + public ActionBarPacket() { + this(Component.empty()); } @Override diff --git a/src/main/java/net/minestom/server/network/packet/server/play/AttachEntityPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/AttachEntityPacket.java index 8f1aacce4..66b6a1234 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/AttachEntityPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/AttachEntityPacket.java @@ -1,17 +1,30 @@ package net.minestom.server.network.packet.server.play; +import net.minestom.server.entity.Entity; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.utils.binary.BinaryReader; import net.minestom.server.utils.binary.BinaryWriter; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class AttachEntityPacket implements ServerPacket { public int attachedEntityId; public int holdingEntityId; // Or -1 to detach - public AttachEntityPacket() {} + public AttachEntityPacket(int attachedEntityId, int holdingEntityId) { + this.attachedEntityId = attachedEntityId; + this.holdingEntityId = holdingEntityId; + } + + public AttachEntityPacket(@NotNull Entity attachedEntity, @Nullable Entity holdingEntity) { + this(attachedEntity.getEntityId(), holdingEntity != null ? holdingEntity.getEntityId() : -1); + } + + public AttachEntityPacket() { + this(0, 0); + } @Override public void write(@NotNull BinaryWriter writer) { diff --git a/src/main/java/net/minestom/server/network/packet/server/play/BlockChangePacket.java b/src/main/java/net/minestom/server/network/packet/server/play/BlockChangePacket.java index 50ffe2215..cb786e72b 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/BlockChangePacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/BlockChangePacket.java @@ -12,8 +12,13 @@ public class BlockChangePacket implements ServerPacket { public BlockPosition blockPosition; public int blockStateId; + public BlockChangePacket(BlockPosition blockPosition, int blockStateId) { + this.blockPosition = blockPosition; + this.blockStateId = blockStateId; + } + public BlockChangePacket() { - blockPosition = new BlockPosition(0,0,0); + this(new BlockPosition(0, 0, 0), 0); } @Override diff --git a/src/main/java/net/minestom/server/network/packet/server/play/CameraPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/CameraPacket.java index 980224da2..87de08693 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/CameraPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/CameraPacket.java @@ -1,5 +1,6 @@ package net.minestom.server.network.packet.server.play; +import net.minestom.server.entity.Entity; import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.ServerPacketIdentifier; import net.minestom.server.utils.binary.BinaryReader; @@ -10,7 +11,17 @@ public class CameraPacket implements ServerPacket { public int cameraId; - public CameraPacket() {} + public CameraPacket(int cameraId) { + this.cameraId = cameraId; + } + + public CameraPacket(@NotNull Entity camera) { + this(camera.getEntityId()); + } + + public CameraPacket() { + this(0); + } @Override public void write(@NotNull BinaryWriter writer) { diff --git a/src/main/java/net/minestom/server/network/packet/server/play/ChatMessagePacket.java b/src/main/java/net/minestom/server/network/packet/server/play/ChatMessagePacket.java index bd9599a41..85b57f270 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/ChatMessagePacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/ChatMessagePacket.java @@ -26,18 +26,16 @@ public class ChatMessagePacket implements ComponentHoldingServerPacket { public ChatPosition position; public UUID uuid; - public ChatMessagePacket() { - this.message = Component.empty(); - this.position = ChatPosition.SYSTEM_MESSAGE; - this.uuid = NULL_UUID; - } - public ChatMessagePacket(@NotNull Component message, @NotNull ChatPosition position, @Nullable UUID uuid) { this.message = message; this.position = position; this.uuid = Objects.requireNonNullElse(uuid, NULL_UUID); } + public ChatMessagePacket() { + this(Component.empty(), ChatPosition.SYSTEM_MESSAGE, NULL_UUID); + } + @Override public void write(@NotNull BinaryWriter writer) { writer.writeComponent(message); From a9086e83f2ab664f81b03d82e6edf9bb4c96bfe2 Mon Sep 17 00:00:00 2001 From: TheMode Date: Tue, 22 Jun 2021 02:51:04 +0200 Subject: [PATCH 11/39] Improve tag API --- .../net/minestom/server/item/ItemMeta.java | 5 --- .../net/minestom/server/item/ItemStack.java | 5 --- .../java/net/minestom/server/tag/Tag.java | 42 +++++++++++++------ .../net/minestom/server/tag/TagReadable.java | 9 ++-- .../minestom/server/tag/TagSerializer.java | 8 ++-- .../net/minestom/server/tag/TagWritable.java | 4 ++ 6 files changed, 41 insertions(+), 32 deletions(-) diff --git a/src/main/java/net/minestom/server/item/ItemMeta.java b/src/main/java/net/minestom/server/item/ItemMeta.java index 2128a180a..862e9709e 100644 --- a/src/main/java/net/minestom/server/item/ItemMeta.java +++ b/src/main/java/net/minestom/server/item/ItemMeta.java @@ -117,11 +117,6 @@ public class ItemMeta implements TagReadable, Writeable { return tag.read(nbt); } - @Override - public boolean hasTag(@NotNull Tag tag) { - return nbt.containsKey(tag.getKey()); - } - public @NotNull NBTCompound toNBT() { return nbt.deepClone(); } diff --git a/src/main/java/net/minestom/server/item/ItemStack.java b/src/main/java/net/minestom/server/item/ItemStack.java index b5d6a0a80..a67d350f3 100644 --- a/src/main/java/net/minestom/server/item/ItemStack.java +++ b/src/main/java/net/minestom/server/item/ItemStack.java @@ -203,11 +203,6 @@ public final class ItemStack implements TagReadable, HoverEventSource tag) { - return meta.hasTag(tag); - } - @Override public @NotNull HoverEvent asHoverEvent(@NotNull UnaryOperator op) { return HoverEvent.showItem(op.apply(HoverEvent.ShowItem.of(this.material, diff --git a/src/main/java/net/minestom/server/tag/Tag.java b/src/main/java/net/minestom/server/tag/Tag.java index 63e054446..80652cbac 100644 --- a/src/main/java/net/minestom/server/tag/Tag.java +++ b/src/main/java/net/minestom/server/tag/Tag.java @@ -21,6 +21,8 @@ import java.util.function.Supplier; @ApiStatus.NonExtendable public class Tag { + private static final String EMPTY_KEY = ""; + private final String key; private final Function readFunction; private final BiConsumer writeConsumer; @@ -60,7 +62,7 @@ public class Tag { @Contract(value = "_, _ -> new", pure = true) public Tag map(@NotNull Function readMap, @NotNull Function writeMap) { - return new Tag(key, + return new Tag<>(key, // Read nbtCompound -> { final var old = readFunction.apply(nbtCompound); @@ -85,22 +87,26 @@ public class Tag { } public @Nullable T read(@NotNull NBTCompound nbtCompound) { - if (nbtCompound.containsKey(key)) { - return readFunction.apply(nbtCompound); - } else { + T result = readFunction.apply(nbtCompound); + if (result == null) { final var supplier = defaultValue; - return supplier != null ? supplier.get() : null; + result = supplier != null ? supplier.get() : null; } + return result; } public void write(@NotNull NBTCompound nbtCompound, @Nullable T value) { - if (value != null) { + if (value != null || key.equals(EMPTY_KEY)) { this.writeConsumer.accept(nbtCompound, value); } else { nbtCompound.removeTag(key); } } + public void writeUnsafe(@NotNull NBTCompound nbtCompound, @Nullable Object value) { + write(nbtCompound, (T) value); + } + public static @NotNull Tag Byte(@NotNull String key) { return new Tag<>(key, nbtCompound -> nbtCompound.getByte(key), @@ -149,17 +155,15 @@ public class Tag { (nbtCompound, value) -> nbtCompound.setString(key, value)); } - public static @NotNull Tag NBT(@NotNull String key) { + public static @NotNull Tag NBT(@NotNull String key) { return new Tag<>(key, nbt -> { - var currentNBT = nbt.get(key); - + final var currentNBT = nbt.get(key); // Avoid a NPE when cloning a null variable. if (currentNBT == null) { return null; } - - return currentNBT.deepClone(); + return (T) currentNBT.deepClone(); }, ((nbt, value) -> nbt.set(key, value.deepClone()))); } @@ -176,7 +180,15 @@ public class Tag { (nbtCompound, value) -> nbtCompound.setLongArray(key, value)); } - public static @NotNull Tag Custom(@NotNull String key, @NotNull TagSerializer serializer) { + /** + * Create a wrapper around a compound. + * + * @param key the tag key + * @param serializer the tag serializer + * @param the tag type + * @return the created tag + */ + public static @NotNull Tag Structure(@NotNull String key, @NotNull TagSerializer serializer) { return new Tag<>(key, nbtCompound -> { final var compound = nbtCompound.getCompound(key); @@ -194,4 +206,10 @@ public class Tag { serializer.write(TagWritable.fromCompound(compound), value); }); } + + public static @NotNull Tag View(@NotNull TagSerializer serializer) { + return new Tag<>(EMPTY_KEY, + nbtCompound -> serializer.read(TagReadable.fromCompound(nbtCompound)), + (nbtCompound, value) -> serializer.write(TagWritable.fromCompound(nbtCompound), value)); + } } diff --git a/src/main/java/net/minestom/server/tag/TagReadable.java b/src/main/java/net/minestom/server/tag/TagReadable.java index 18deb2f02..06a4a9cd2 100644 --- a/src/main/java/net/minestom/server/tag/TagReadable.java +++ b/src/main/java/net/minestom/server/tag/TagReadable.java @@ -24,7 +24,9 @@ public interface TagReadable { * @param tag the tag to check * @return true if the tag is present, false otherwise */ - boolean hasTag(@NotNull Tag tag); + default boolean hasTag(@NotNull Tag tag) { + return getTag(tag) != null; + } /** * Converts an nbt compound to a tag reader. @@ -38,11 +40,6 @@ public interface TagReadable { public @Nullable T getTag(@NotNull Tag tag) { return tag.read(compound); } - - @Override - public boolean hasTag(@NotNull Tag tag) { - return compound.containsKey(tag.getKey()); - } }; } } diff --git a/src/main/java/net/minestom/server/tag/TagSerializer.java b/src/main/java/net/minestom/server/tag/TagSerializer.java index 03318bfdf..36f0f08c2 100644 --- a/src/main/java/net/minestom/server/tag/TagSerializer.java +++ b/src/main/java/net/minestom/server/tag/TagSerializer.java @@ -4,7 +4,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** - * Interface used to create custom types compatible with {@link Tag#Custom(String, TagSerializer)}. + * Interface used to create custom {@link Tag tags}. * * @param the type to serialize */ @@ -14,7 +14,7 @@ public interface TagSerializer { * Reads the custom tag from a {@link TagReadable}. * * @param reader the reader - * @return the deserialized value + * @return the deserialized value, null if invalid */ @Nullable T read(@NotNull TagReadable reader); @@ -22,7 +22,7 @@ public interface TagSerializer { * Writes the custom tag to a {@link TagWritable}. * * @param writer the writer - * @param value the value to serialize + * @param value the value to serialize, null to remove */ - void write(@NotNull TagWritable writer, @NotNull T value); + void write(@NotNull TagWritable writer, @Nullable T value); } diff --git a/src/main/java/net/minestom/server/tag/TagWritable.java b/src/main/java/net/minestom/server/tag/TagWritable.java index fe0c2962b..3630615f5 100644 --- a/src/main/java/net/minestom/server/tag/TagWritable.java +++ b/src/main/java/net/minestom/server/tag/TagWritable.java @@ -18,6 +18,10 @@ public interface TagWritable { */ void setTag(@NotNull Tag tag, @Nullable T value); + default void removeTag(@NotNull Tag tag) { + setTag(tag, null); + } + /** * Converts an nbt compound to a tag writer. * From b5c7106f9b338de53f8ea4f6d664104efb14af2a Mon Sep 17 00:00:00 2001 From: TheMode Date: Tue, 22 Jun 2021 02:56:00 +0200 Subject: [PATCH 12/39] Use the tag api inside Entity, deprecate DataContainer --- .../net/minestom/server/data/DataContainer.java | 3 +++ .../java/net/minestom/server/entity/Entity.java | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/main/java/net/minestom/server/data/DataContainer.java b/src/main/java/net/minestom/server/data/DataContainer.java index e5dbddbde..050712399 100644 --- a/src/main/java/net/minestom/server/data/DataContainer.java +++ b/src/main/java/net/minestom/server/data/DataContainer.java @@ -6,7 +6,10 @@ import org.jetbrains.annotations.Nullable; * Represents an element which can have a {@link Data} attached to it. *

* The data will always be optional and can therefore be null. + * + * @deprecated switch to the Tag API instead */ +@Deprecated public interface DataContainer { /** diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index ddd0a833a..eec74abf0 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -33,6 +33,8 @@ import net.minestom.server.permission.PermissionHandler; import net.minestom.server.potion.Potion; import net.minestom.server.potion.PotionEffect; import net.minestom.server.potion.TimedPotion; +import net.minestom.server.tag.Tag; +import net.minestom.server.tag.TagHandler; import net.minestom.server.thread.ThreadProvider; import net.minestom.server.utils.BlockPosition; import net.minestom.server.utils.Position; @@ -49,6 +51,7 @@ import net.minestom.server.utils.validate.Check; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -64,7 +67,7 @@ import java.util.function.UnaryOperator; *

* To create your own entity you probably want to extends {@link LivingEntity} or {@link EntityCreature} instead. */ -public class Entity implements Viewable, Tickable, EventHandler, DataContainer, PermissionHandler, HoverEventSource, Sound.Emitter { +public class Entity implements Viewable, Tickable, EventHandler, DataContainer, TagHandler, PermissionHandler, HoverEventSource, Sound.Emitter { private static final Map ENTITY_BY_ID = new ConcurrentHashMap<>(); private static final Map ENTITY_BY_UUID = new ConcurrentHashMap<>(); @@ -102,6 +105,7 @@ public class Entity implements Viewable, Tickable, EventHandler, Da protected final Set viewers = ConcurrentHashMap.newKeySet(); private final Set unmodifiableViewers = Collections.unmodifiableSet(viewers); private Data data; + private final NBTCompound nbtCompound = new NBTCompound(); private final Set permissions = new CopyOnWriteArraySet<>(); protected UUID uuid; @@ -1629,6 +1633,16 @@ public class Entity implements Viewable, Tickable, EventHandler, Da return (Acquirable) acquirable; } + @Override + public @Nullable T getTag(@NotNull Tag tag) { + return tag.read(nbtCompound); + } + + @Override + public void setTag(@NotNull Tag tag, @Nullable T value) { + tag.write(nbtCompound, value); + } + public enum Pose { STANDING, FALL_FLYING, From 43c2b48b68f5b520b41aeaa65374954c8e78bb46 Mon Sep 17 00:00:00 2001 From: TheMode Date: Tue, 22 Jun 2021 03:05:22 +0200 Subject: [PATCH 13/39] Add backward compatible method --- src/main/java/net/minestom/server/tag/Tag.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/net/minestom/server/tag/Tag.java b/src/main/java/net/minestom/server/tag/Tag.java index 80652cbac..641952cbe 100644 --- a/src/main/java/net/minestom/server/tag/Tag.java +++ b/src/main/java/net/minestom/server/tag/Tag.java @@ -212,4 +212,12 @@ public class Tag { nbtCompound -> serializer.read(TagReadable.fromCompound(nbtCompound)), (nbtCompound, value) -> serializer.write(TagWritable.fromCompound(nbtCompound), value)); } + + /** + * @deprecated use {@link #Structure(String, TagSerializer)} instead + */ + @Deprecated + public static @NotNull Tag Custom(@NotNull String key, @NotNull TagSerializer serializer) { + return Structure(key, serializer); + } } From 0f02be4b2b60c7e27b1a46361f0dc7eebc862526 Mon Sep 17 00:00:00 2001 From: TheMode Date: Tue, 22 Jun 2021 13:30:47 +0200 Subject: [PATCH 14/39] Add tag api to CommandSender --- .../net/minestom/server/command/CommandSender.java | 8 ++++---- .../net/minestom/server/command/ConsoleSender.java | 14 ++++++++++++++ .../net/minestom/server/command/ServerSender.java | 14 ++++++++++++++ 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/minestom/server/command/CommandSender.java b/src/main/java/net/minestom/server/command/CommandSender.java index 627621c8c..398e019f7 100644 --- a/src/main/java/net/minestom/server/command/CommandSender.java +++ b/src/main/java/net/minestom/server/command/CommandSender.java @@ -5,6 +5,7 @@ import net.kyori.adventure.text.Component; import net.minestom.server.chat.JsonMessage; import net.minestom.server.entity.Player; import net.minestom.server.permission.PermissionHandler; +import net.minestom.server.tag.TagHandler; import org.jetbrains.annotations.NotNull; /** @@ -12,7 +13,7 @@ import org.jetbrains.annotations.NotNull; *

* Main implementations are {@link Player} and {@link ConsoleSender}. */ -public interface CommandSender extends PermissionHandler, Audience { +public interface CommandSender extends PermissionHandler, Audience, TagHandler { /** * Sends a raw string message. @@ -28,7 +29,7 @@ public interface CommandSender extends PermissionHandler, Audience { * * @param messages the messages to send */ - default void sendMessage(@NotNull String @NotNull[] messages) { + default void sendMessage(@NotNull String @NotNull [] messages) { for (String message : messages) { sendMessage(message); } @@ -39,9 +40,8 @@ public interface CommandSender extends PermissionHandler, Audience { * If this is not a {@link Player}, only the content of the message will be sent as a string. * * @param text The {@link JsonMessage} to send. - * * @deprecated Use {@link #sendMessage(Component)} - * */ + */ @Deprecated default void sendMessage(@NotNull JsonMessage text) { this.sendMessage(text.asComponent()); diff --git a/src/main/java/net/minestom/server/command/ConsoleSender.java b/src/main/java/net/minestom/server/command/ConsoleSender.java index 90d53f940..35e03861d 100644 --- a/src/main/java/net/minestom/server/command/ConsoleSender.java +++ b/src/main/java/net/minestom/server/command/ConsoleSender.java @@ -5,7 +5,10 @@ import net.kyori.adventure.identity.Identity; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; import net.minestom.server.permission.Permission; +import net.minestom.server.tag.Tag; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,6 +23,7 @@ public class ConsoleSender implements CommandSender { private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleSender.class); private final Set permissions = new CopyOnWriteArraySet<>(); + private final NBTCompound nbtCompound = new NBTCompound(); @Override public void sendMessage(@NotNull String message) { @@ -47,4 +51,14 @@ public class ConsoleSender implements CommandSender { public ConsoleSender asConsole() { return this; } + + @Override + public @Nullable T getTag(@NotNull Tag tag) { + return tag.read(nbtCompound); + } + + @Override + public void setTag(@NotNull Tag tag, @Nullable T value) { + tag.write(nbtCompound, value); + } } diff --git a/src/main/java/net/minestom/server/command/ServerSender.java b/src/main/java/net/minestom/server/command/ServerSender.java index 663c57d7d..22c95a524 100644 --- a/src/main/java/net/minestom/server/command/ServerSender.java +++ b/src/main/java/net/minestom/server/command/ServerSender.java @@ -3,7 +3,10 @@ package net.minestom.server.command; import net.minestom.server.command.builder.CommandContext; import net.kyori.adventure.audience.Audience; import net.minestom.server.permission.Permission; +import net.minestom.server.tag.Tag; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; import java.util.Collections; import java.util.HashSet; @@ -19,10 +22,21 @@ import java.util.Set; public class ServerSender implements CommandSender { private final Set permissions = Collections.unmodifiableSet(new HashSet<>()); + private final NBTCompound nbtCompound = new NBTCompound(); @NotNull @Override public Set getAllPermissions() { return permissions; } + + @Override + public @Nullable T getTag(@NotNull Tag tag) { + return tag.read(nbtCompound); + } + + @Override + public void setTag(@NotNull Tag tag, @Nullable T value) { + tag.write(nbtCompound, value); + } } From 804f11c87ba934a27037c1495d8505b703f9a7c8 Mon Sep 17 00:00:00 2001 From: TheMode Date: Wed, 23 Jun 2021 02:20:51 +0200 Subject: [PATCH 15/39] Potentially fix explosion packet --- .../server/network/packet/server/play/ExplosionPacket.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/minestom/server/network/packet/server/play/ExplosionPacket.java b/src/main/java/net/minestom/server/network/packet/server/play/ExplosionPacket.java index fbf32107c..acd4fee22 100644 --- a/src/main/java/net/minestom/server/network/packet/server/play/ExplosionPacket.java +++ b/src/main/java/net/minestom/server/network/packet/server/play/ExplosionPacket.java @@ -13,7 +13,8 @@ public class ExplosionPacket implements ServerPacket { public byte[] records = new byte[0]; public float playerMotionX, playerMotionY, playerMotionZ; - public ExplosionPacket() {} + public ExplosionPacket() { + } @Override public void write(@NotNull BinaryWriter writer) { @@ -21,7 +22,7 @@ public class ExplosionPacket implements ServerPacket { writer.writeFloat(y); writer.writeFloat(z); writer.writeFloat(radius); - writer.writeInt(records.length/3); // each record is 3 bytes long + writer.writeVarInt(records.length / 3); // each record is 3 bytes long for (byte record : records) writer.writeByte(record); writer.writeFloat(playerMotionX); From 6526a2658a75d787cf9356b355240b03e6b26905 Mon Sep 17 00:00:00 2001 From: TheMode Date: Fri, 25 Jun 2021 06:45:02 +0200 Subject: [PATCH 16/39] Replace netty to jdk thread local random --- .../java/net/minestom/server/attribute/AttributeModifier.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/minestom/server/attribute/AttributeModifier.java b/src/main/java/net/minestom/server/attribute/AttributeModifier.java index 9ea5aab56..3cdd9be0f 100644 --- a/src/main/java/net/minestom/server/attribute/AttributeModifier.java +++ b/src/main/java/net/minestom/server/attribute/AttributeModifier.java @@ -1,10 +1,10 @@ package net.minestom.server.attribute; -import io.netty.util.internal.ThreadLocalRandom; import net.minestom.server.utils.UniqueIdUtils; import org.jetbrains.annotations.NotNull; import java.util.UUID; +import java.util.concurrent.ThreadLocalRandom; /** * Represent an attribute modifier. From d84964d55b07784a543180b52ce815daeffd73ee Mon Sep 17 00:00:00 2001 From: BuildTools Date: Fri, 25 Jun 2021 20:32:13 +0800 Subject: [PATCH 17/39] Add sendGroupedPacket convenience method to PacketGroupingAudience --- .../server/adventure/audience/PacketGroupingAudience.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/main/java/net/minestom/server/adventure/audience/PacketGroupingAudience.java b/src/main/java/net/minestom/server/adventure/audience/PacketGroupingAudience.java index cd18eeec1..9f4c4dc0f 100644 --- a/src/main/java/net/minestom/server/adventure/audience/PacketGroupingAudience.java +++ b/src/main/java/net/minestom/server/adventure/audience/PacketGroupingAudience.java @@ -14,6 +14,7 @@ import net.minestom.server.adventure.AdventurePacketConvertor; import net.minestom.server.entity.Player; import net.minestom.server.message.ChatPosition; import net.minestom.server.message.Messenger; +import net.minestom.server.network.packet.server.ServerPacket; import net.minestom.server.network.packet.server.play.*; import net.minestom.server.utils.PacketUtils; import org.jetbrains.annotations.NotNull; @@ -44,6 +45,10 @@ public interface PacketGroupingAudience extends ForwardingAudience { */ @NotNull Collection getPlayers(); + default void sendGroupedPacket(ServerPacket packet) { + PacketUtils.sendGroupedPacket(this.getPlayers(), packet); + } + @Override default void sendMessage(@NotNull Identity source, @NotNull Component message, @NotNull MessageType type) { Messenger.sendMessage(this.getPlayers(), message, ChatPosition.fromMessageType(type), source.uuid()); From 07a2b37f3582c63ed8bbccc3216090683b94e64e Mon Sep 17 00:00:00 2001 From: BuildTools Date: Fri, 25 Jun 2021 20:34:19 +0800 Subject: [PATCH 18/39] Add Javadoc --- .../server/adventure/audience/PacketGroupingAudience.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/net/minestom/server/adventure/audience/PacketGroupingAudience.java b/src/main/java/net/minestom/server/adventure/audience/PacketGroupingAudience.java index 9f4c4dc0f..9e20b2567 100644 --- a/src/main/java/net/minestom/server/adventure/audience/PacketGroupingAudience.java +++ b/src/main/java/net/minestom/server/adventure/audience/PacketGroupingAudience.java @@ -45,6 +45,10 @@ public interface PacketGroupingAudience extends ForwardingAudience { */ @NotNull Collection getPlayers(); + /** + * Broadcast a ServerPacket to all players of this audience + * @param packet the packet to broadcast + */ default void sendGroupedPacket(ServerPacket packet) { PacketUtils.sendGroupedPacket(this.getPlayers(), packet); } From e69c02f46d597e73b6455a00f04bd7333775b7ec Mon Sep 17 00:00:00 2001 From: BuildTools Date: Fri, 25 Jun 2021 20:41:54 +0800 Subject: [PATCH 19/39] Change other usages of PacketUtils#sendGroupedPacket to use new convenience method --- .../audience/PacketGroupingAudience.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/net/minestom/server/adventure/audience/PacketGroupingAudience.java b/src/main/java/net/minestom/server/adventure/audience/PacketGroupingAudience.java index 9e20b2567..40775bf96 100644 --- a/src/main/java/net/minestom/server/adventure/audience/PacketGroupingAudience.java +++ b/src/main/java/net/minestom/server/adventure/audience/PacketGroupingAudience.java @@ -60,28 +60,28 @@ public interface PacketGroupingAudience extends ForwardingAudience { @Override default void sendActionBar(@NotNull Component message) { - PacketUtils.sendGroupedPacket(this.getPlayers(), new ActionBarPacket(message)); + sendGroupedPacket(new ActionBarPacket(message)); } @Override default void sendPlayerListHeaderAndFooter(@NotNull Component header, @NotNull Component footer) { - PacketUtils.sendGroupedPacket(this.getPlayers(), new PlayerListHeaderAndFooterPacket(header, footer)); + sendGroupedPacket(new PlayerListHeaderAndFooterPacket(header, footer)); } @Override default void showTitle(@NotNull Title title) { - PacketUtils.sendGroupedPacket(this.getPlayers(), new SetTitleTextPacket(title.title())); - PacketUtils.sendGroupedPacket(this.getPlayers(), new SetTitleSubTitlePacket(title.subtitle())); + sendGroupedPacket(new SetTitleTextPacket(title.title())); + sendGroupedPacket(new SetTitleSubTitlePacket(title.subtitle())); } @Override default void clearTitle() { - PacketUtils.sendGroupedPacket(this.getPlayers(), new ClearTitlesPacket()); + sendGroupedPacket(new ClearTitlesPacket()); } @Override default void resetTitle() { - PacketUtils.sendGroupedPacket(this.getPlayers(), new ClearTitlesPacket(true)); + sendGroupedPacket(new ClearTitlesPacket(true)); } @Override @@ -96,13 +96,13 @@ public interface PacketGroupingAudience extends ForwardingAudience { @Override default void playSound(@NotNull Sound sound, double x, double y, double z) { - PacketUtils.sendGroupedPacket(this.getPlayers(), AdventurePacketConvertor.createSoundPacket(sound, x, y, z)); + sendGroupedPacket(AdventurePacketConvertor.createSoundPacket(sound, x, y, z)); } @Override default void playSound(@NotNull Sound sound, Sound.@NotNull Emitter emitter) { if (emitter != Sound.Emitter.self()) { - PacketUtils.sendGroupedPacket(this.getPlayers(), AdventurePacketConvertor.createSoundPacket(sound, emitter)); + sendGroupedPacket(AdventurePacketConvertor.createSoundPacket(sound, emitter)); } else { // if we're playing on self, we need to delegate to each audience member for (Audience audience : this.audiences()) { @@ -113,7 +113,7 @@ public interface PacketGroupingAudience extends ForwardingAudience { @Override default void stopSound(@NotNull SoundStop stop) { - PacketUtils.sendGroupedPacket(this.getPlayers(), AdventurePacketConvertor.createSoundStopPacket(stop)); + sendGroupedPacket(AdventurePacketConvertor.createSoundStopPacket(stop)); } From 76bec5425406ec0d2804a1e8a0b2e6ac2f0ff465 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sat, 26 Jun 2021 00:31:04 +0200 Subject: [PATCH 20/39] Add more TagHandler implementations --- .../minestom/server/data/DataContainer.java | 8 ++++--- .../server/entity/damage/DamageType.java | 21 ++++++++++++++++++- .../net/minestom/server/instance/Chunk.java | 16 +++++++++++++- .../minestom/server/instance/Instance.java | 21 ++++++++++++++++++- .../server/inventory/AbstractInventory.java | 21 ++++++++++++++++++- 5 files changed, 80 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/minestom/server/data/DataContainer.java b/src/main/java/net/minestom/server/data/DataContainer.java index 050712399..772c86f6d 100644 --- a/src/main/java/net/minestom/server/data/DataContainer.java +++ b/src/main/java/net/minestom/server/data/DataContainer.java @@ -19,9 +19,10 @@ public interface DataContainer { * meaning that this will be null if no data has been defined. * * @return the {@link Data} of this container, can be null + * @deprecated use the tag API https://wiki.minestom.com/feature/tags */ - @Nullable - Data getData(); + @Deprecated + @Nullable Data getData(); /** * Sets the {@link Data} of this container. @@ -30,7 +31,8 @@ public interface DataContainer { * on your use-case. * * @param data the new {@link Data} of this container, null to remove it + * @deprecated use the tag API https://wiki.minestom.com/feature/tags */ + @Deprecated void setData(@Nullable Data data); - } \ No newline at end of file diff --git a/src/main/java/net/minestom/server/entity/damage/DamageType.java b/src/main/java/net/minestom/server/entity/damage/DamageType.java index e1850622a..f311059f8 100644 --- a/src/main/java/net/minestom/server/entity/damage/DamageType.java +++ b/src/main/java/net/minestom/server/entity/damage/DamageType.java @@ -8,8 +8,11 @@ import net.minestom.server.entity.Entity; import net.minestom.server.entity.LivingEntity; import net.minestom.server.entity.Player; import net.minestom.server.sound.SoundEvent; +import net.minestom.server.tag.Tag; +import net.minestom.server.tag.TagHandler; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; /** * Represents a type of damage, required when calling {@link LivingEntity#damage(DamageType, float)} @@ -19,7 +22,7 @@ import org.jetbrains.annotations.Nullable; * Be aware that this class implements {@link DataContainer} * so you can add your own data to an already existing damage type without any wrapper. */ -public class DamageType implements DataContainer { +public class DamageType implements TagHandler, DataContainer { public static final DamageType VOID = new DamageType("attack.outOfWorld"); public static final DamageType GRAVITY = new DamageType("attack.fall"); @@ -30,6 +33,8 @@ public class DamageType implements DataContainer { } }; private final String identifier; + private final Object nbtLock = new Object(); + private final NBTCompound nbt = new NBTCompound(); private Data data; /** @@ -159,4 +164,18 @@ public class DamageType implements DataContainer { public void setData(Data data) { this.data = data; } + + @Override + public @Nullable T getTag(@NotNull Tag tag) { + synchronized (nbtLock) { + return tag.read(nbt); + } + } + + @Override + public void setTag(@NotNull Tag tag, @Nullable T value) { + synchronized (nbtLock) { + tag.write(nbt, value); + } + } } diff --git a/src/main/java/net/minestom/server/instance/Chunk.java b/src/main/java/net/minestom/server/instance/Chunk.java index 18bb9d98c..7d0b0c1cf 100644 --- a/src/main/java/net/minestom/server/instance/Chunk.java +++ b/src/main/java/net/minestom/server/instance/Chunk.java @@ -16,6 +16,8 @@ import net.minestom.server.instance.block.CustomBlock; import net.minestom.server.network.packet.server.play.ChunkDataPacket; import net.minestom.server.network.packet.server.play.UpdateLightPacket; import net.minestom.server.network.player.PlayerConnection; +import net.minestom.server.tag.Tag; +import net.minestom.server.tag.TagHandler; import net.minestom.server.utils.PacketUtils; import net.minestom.server.utils.Position; import net.minestom.server.utils.binary.BinaryReader; @@ -27,6 +29,7 @@ import net.minestom.server.world.biomes.Biome; import net.minestom.server.world.biomes.BiomeManager; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -47,7 +50,7 @@ import java.util.concurrent.ConcurrentHashMap; * You generally want to avoid storing references of this object as this could lead to a huge memory leak, * you should store the chunk coordinates instead. */ -public abstract class Chunk implements Viewable, Tickable, DataContainer { +public abstract class Chunk implements Viewable, Tickable, TagHandler, DataContainer { protected static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager(); protected static final BiomeManager BIOME_MANAGER = MinecraftServer.getBiomeManager(); @@ -75,6 +78,7 @@ public abstract class Chunk implements Viewable, Tickable, DataContainer { protected PFColumnarSpace columnarSpace; // Data + private final NBTCompound nbt = new NBTCompound(); protected Data data; public Chunk(@NotNull Instance instance, @Nullable Biome[] biomes, int chunkX, int chunkZ, boolean shouldGenerate) { @@ -480,6 +484,16 @@ public abstract class Chunk implements Viewable, Tickable, DataContainer { return unmodifiableViewers; } + @Override + public @Nullable T getTag(@NotNull Tag tag) { + return tag.read(nbt); + } + + @Override + public void setTag(@NotNull Tag tag, @Nullable T value) { + tag.write(nbt, value); + } + @Nullable @Override public Data getData() { diff --git a/src/main/java/net/minestom/server/instance/Instance.java b/src/main/java/net/minestom/server/instance/Instance.java index d0f9352b3..cae571ff2 100644 --- a/src/main/java/net/minestom/server/instance/Instance.java +++ b/src/main/java/net/minestom/server/instance/Instance.java @@ -28,6 +28,8 @@ import net.minestom.server.instance.block.CustomBlock; import net.minestom.server.network.packet.server.play.BlockActionPacket; import net.minestom.server.network.packet.server.play.TimeUpdatePacket; import net.minestom.server.storage.StorageLocation; +import net.minestom.server.tag.Tag; +import net.minestom.server.tag.TagHandler; import net.minestom.server.thread.ThreadProvider; import net.minestom.server.utils.BlockPosition; import net.minestom.server.utils.PacketUtils; @@ -43,6 +45,7 @@ import net.minestom.server.world.DimensionType; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; import java.util.*; import java.util.concurrent.ConcurrentHashMap; @@ -60,7 +63,7 @@ import java.util.function.Consumer; * you need to be sure to signal the {@link UpdateManager} of the changes using * {@link UpdateManager#signalChunkLoad(Chunk)} and {@link UpdateManager#signalChunkUnload(Chunk)}. */ -public abstract class Instance implements BlockModifier, Tickable, EventHandler, DataContainer, PacketGroupingAudience { +public abstract class Instance implements BlockModifier, Tickable, TagHandler, PacketGroupingAudience, EventHandler, DataContainer { protected static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager(); protected static final UpdateManager UPDATE_MANAGER = MinecraftServer.getUpdateManager(); @@ -101,6 +104,8 @@ public abstract class Instance implements BlockModifier, Tickable, EventHandler< protected final Queue> nextTick = new ConcurrentLinkedQueue<>(); // instance custom data + private final Object nbtLock = new Object(); + private final NBTCompound nbt = new NBTCompound(); private Data data; // the explosion supplier @@ -1061,6 +1066,20 @@ public abstract class Instance implements BlockModifier, Tickable, EventHandler< this.worldBorder.update(); } + @Override + public @Nullable T getTag(@NotNull Tag tag) { + synchronized (nbtLock) { + return tag.read(nbt); + } + } + + @Override + public void setTag(@NotNull Tag tag, @Nullable T value) { + synchronized (nbtLock) { + tag.write(nbt, value); + } + } + /** * Creates an explosion at the given position with the given strength. * The algorithm used to compute damages is provided by {@link #getExplosionSupplier()}. diff --git a/src/main/java/net/minestom/server/inventory/AbstractInventory.java b/src/main/java/net/minestom/server/inventory/AbstractInventory.java index b4cc7a641..bb5112dde 100644 --- a/src/main/java/net/minestom/server/inventory/AbstractInventory.java +++ b/src/main/java/net/minestom/server/inventory/AbstractInventory.java @@ -5,10 +5,13 @@ import net.minestom.server.data.DataContainer; import net.minestom.server.inventory.click.InventoryClickProcessor; import net.minestom.server.inventory.condition.InventoryCondition; import net.minestom.server.item.ItemStack; +import net.minestom.server.tag.Tag; +import net.minestom.server.tag.TagHandler; import net.minestom.server.utils.MathUtils; import net.minestom.server.utils.validate.Check; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jglrxavpok.hephaistos.nbt.NBTCompound; import java.util.ArrayList; import java.util.Arrays; @@ -19,7 +22,7 @@ import java.util.function.UnaryOperator; /** * Represents an inventory where items can be modified/retrieved. */ -public abstract class AbstractInventory implements InventoryClickHandler, DataContainer { +public abstract class AbstractInventory implements InventoryClickHandler, TagHandler, DataContainer { private final int size; protected final ItemStack[] itemStacks; @@ -29,6 +32,8 @@ public abstract class AbstractInventory implements InventoryClickHandler, DataCo // the click processor which process all the clicks in the inventory protected final InventoryClickProcessor clickProcessor = new InventoryClickProcessor(); + private final Object nbtLock = new Object(); + private final NBTCompound nbt = new NBTCompound(); private Data data; protected AbstractInventory(int size) { @@ -210,6 +215,20 @@ public abstract class AbstractInventory implements InventoryClickHandler, DataCo } } + @Override + public @Nullable T getTag(@NotNull Tag tag) { + synchronized (nbtLock) { + return tag.read(nbt); + } + } + + @Override + public void setTag(@NotNull Tag tag, @Nullable T value) { + synchronized (nbtLock) { + tag.write(nbt, value); + } + } + @Override public @Nullable Data getData() { return data; From bf446257308cf87d671c9244e14eea959682699c Mon Sep 17 00:00:00 2001 From: TheMode Date: Sat, 26 Jun 2021 05:08:33 +0200 Subject: [PATCH 21/39] Add experimental tags --- .../net/minestom/server/item/ItemMeta.java | 7 +--- .../java/net/minestom/server/tag/Tag.java | 41 +++++++++++++++---- 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/main/java/net/minestom/server/item/ItemMeta.java b/src/main/java/net/minestom/server/item/ItemMeta.java index 862e9709e..443e15bb3 100644 --- a/src/main/java/net/minestom/server/item/ItemMeta.java +++ b/src/main/java/net/minestom/server/item/ItemMeta.java @@ -164,12 +164,7 @@ public class ItemMeta implements TagReadable, Writeable { @Deprecated @Contract(pure = true) public T getOrDefault(@NotNull Tag tag, @Nullable T defaultValue) { - var key = tag.getKey(); - if (nbt.containsKey(key)) { - return tag.read(toNBT()); - } else { - return defaultValue; - } + return tag.defaultValue(defaultValue).read(toNBT()); } /** diff --git a/src/main/java/net/minestom/server/tag/Tag.java b/src/main/java/net/minestom/server/tag/Tag.java index 641952cbe..5af525a88 100644 --- a/src/main/java/net/minestom/server/tag/Tag.java +++ b/src/main/java/net/minestom/server/tag/Tag.java @@ -7,6 +7,7 @@ import org.jetbrains.annotations.Nullable; import org.jglrxavpok.hephaistos.nbt.NBT; import org.jglrxavpok.hephaistos.nbt.NBTCompound; +import java.util.Objects; import java.util.function.BiConsumer; import java.util.function.Function; import java.util.function.Supplier; @@ -21,7 +22,21 @@ import java.util.function.Supplier; @ApiStatus.NonExtendable public class Tag { - private static final String EMPTY_KEY = ""; + /** + * Reads the snbt of the tags holder. + *

+ * Writing is not supported. + */ + @ApiStatus.Experimental + public static final Tag SNBT = new Tag<>(null, NBTCompound::toSNBT, null, null); + + /** + * Reads the complete tag holder compound. + *

+ * Writing is not supported. + */ + @ApiStatus.Experimental + public static final Tag NBT = new Tag<>(null, NBTCompound::deepClone, null, null); private final String key; private final Function readFunction; @@ -29,23 +44,31 @@ public class Tag { private final Supplier defaultValue; - protected Tag(@NotNull String key, + protected Tag(@Nullable String key, @NotNull Function readFunction, - @NotNull BiConsumer writeConsumer, + @Nullable BiConsumer writeConsumer, @Nullable Supplier defaultValue) { this.key = key; this.readFunction = readFunction; - this.writeConsumer = writeConsumer; + this.writeConsumer = Objects.requireNonNullElse(writeConsumer, (compound, t) -> { + }); this.defaultValue = defaultValue; } - protected Tag(@NotNull String key, + protected Tag(@Nullable String key, @NotNull Function readFunction, - @NotNull BiConsumer writeConsumer) { + @Nullable BiConsumer writeConsumer) { this(key, readFunction, writeConsumer, null); } - public @NotNull String getKey() { + /** + * Returns the key used to navigate inside the holder nbt. + *

+ * Can be null if unused (e.g. {@link #View(TagSerializer)}, {@link #SNBT} and {@link #NBT}). + * + * @return the tag key + */ + public @Nullable String getKey() { return key; } @@ -96,7 +119,7 @@ public class Tag { } public void write(@NotNull NBTCompound nbtCompound, @Nullable T value) { - if (value != null || key.equals(EMPTY_KEY)) { + if (key == null || value != null) { this.writeConsumer.accept(nbtCompound, value); } else { nbtCompound.removeTag(key); @@ -208,7 +231,7 @@ public class Tag { } public static @NotNull Tag View(@NotNull TagSerializer serializer) { - return new Tag<>(EMPTY_KEY, + return new Tag<>(null, nbtCompound -> serializer.read(TagReadable.fromCompound(nbtCompound)), (nbtCompound, value) -> serializer.write(TagWritable.fromCompound(nbtCompound), value)); } From 5ddfff22f2a14f6188a0d96b16d6458070bf2606 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sat, 26 Jun 2021 19:44:35 +0200 Subject: [PATCH 22/39] Add Tag#NBT write support --- src/main/java/net/minestom/server/tag/Tag.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/minestom/server/tag/Tag.java b/src/main/java/net/minestom/server/tag/Tag.java index 5af525a88..fcea2241d 100644 --- a/src/main/java/net/minestom/server/tag/Tag.java +++ b/src/main/java/net/minestom/server/tag/Tag.java @@ -33,10 +33,13 @@ public class Tag { /** * Reads the complete tag holder compound. *

- * Writing is not supported. + * Writing will override all tags. Proceed with caution. */ @ApiStatus.Experimental - public static final Tag NBT = new Tag<>(null, NBTCompound::deepClone, null, null); + public static final Tag NBT = new Tag<>(null, NBTCompound::deepClone, (original, updated) -> { + original.clear(); + updated.getKeys().forEach(s -> original.set(s, Objects.requireNonNull(updated.get(s)))); + }, null); private final String key; private final Function readFunction; From fbf8ddefcec2e71f156ca23b4a3154346f13c968 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sat, 26 Jun 2021 19:52:35 +0200 Subject: [PATCH 23/39] Add Tag#SNBT write support --- .../java/net/minestom/server/tag/Tag.java | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/minestom/server/tag/Tag.java b/src/main/java/net/minestom/server/tag/Tag.java index fcea2241d..7b03a175b 100644 --- a/src/main/java/net/minestom/server/tag/Tag.java +++ b/src/main/java/net/minestom/server/tag/Tag.java @@ -6,7 +6,10 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jglrxavpok.hephaistos.nbt.NBT; import org.jglrxavpok.hephaistos.nbt.NBTCompound; +import org.jglrxavpok.hephaistos.nbt.NBTException; +import org.jglrxavpok.hephaistos.nbt.SNBTParser; +import java.io.StringReader; import java.util.Objects; import java.util.function.BiConsumer; import java.util.function.Function; @@ -23,15 +26,27 @@ import java.util.function.Supplier; public class Tag { /** - * Reads the snbt of the tags holder. + * Handles the snbt of the tag holder. *

- * Writing is not supported. + * Writing will override all tags. Proceed with caution. */ @ApiStatus.Experimental - public static final Tag SNBT = new Tag<>(null, NBTCompound::toSNBT, null, null); + public static final Tag SNBT = new Tag<>(null, NBTCompound::toSNBT, (original, snbt) -> { + try { + final var updated = new SNBTParser(new StringReader(snbt)).parse(); + if (!(updated instanceof NBTCompound)) + throw new IllegalArgumentException("'" + snbt + "' is not a compound!"); + NBTCompound updatedCompound = (NBTCompound) updated; + original.clear(); + updatedCompound.getKeys().forEach(s -> + original.set(s, Objects.requireNonNull(updatedCompound.get(s)))); + } catch (NBTException e) { + e.printStackTrace(); + } + }, null); /** - * Reads the complete tag holder compound. + * Handles the complete tag holder compound. *

* Writing will override all tags. Proceed with caution. */ From edaec0cb6ddb3110cb3e83b77b50379f16a4fe98 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 27 Jun 2021 05:44:24 +0200 Subject: [PATCH 24/39] Fix double click inside player inventory --- .../java/net/minestom/server/inventory/PlayerInventory.java | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/main/java/net/minestom/server/inventory/PlayerInventory.java b/src/main/java/net/minestom/server/inventory/PlayerInventory.java index 34d88ef63..18c558d52 100644 --- a/src/main/java/net/minestom/server/inventory/PlayerInventory.java +++ b/src/main/java/net/minestom/server/inventory/PlayerInventory.java @@ -403,16 +403,11 @@ public class PlayerInventory extends AbstractInventory implements EquipmentHandl public boolean doubleClick(@NotNull Player player, int slot) { final ItemStack cursor = getCursorItem(); final InventoryClickResult clickResult = clickProcessor.doubleClick(this, null, player, slot, cursor); - if (clickResult == null) return false; - if (clickResult.doRefresh()) update(); - - setItemStack(slot, OFFSET, clickResult.getClicked()); setCursorItem(clickResult.getCursor()); - return !clickResult.isCancel(); } } From e772aace7149e15a49f6873573fc1a7294846865 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 27 Jun 2021 17:36:37 +0200 Subject: [PATCH 25/39] Initial reusable meta builder --- .../net/minestom/server/item/ItemMeta.java | 2 +- .../minestom/server/item/ItemMetaBuilder.java | 104 ++++++++++++------ .../server/item/ItemStackBuilder.java | 7 +- .../server/item/metadata/CompassMeta.java | 34 +++--- .../server/item/metadata/CrossbowMeta.java | 6 +- .../item/metadata/EnchantedBookMeta.java | 6 +- .../item/metadata/FireworkEffectMeta.java | 2 +- .../server/item/metadata/MapMeta.java | 26 +++-- .../server/item/metadata/PotionMeta.java | 6 +- .../item/metadata/WritableBookMeta.java | 9 +- .../server/item/metadata/WrittenBookMeta.java | 12 +- 11 files changed, 127 insertions(+), 87 deletions(-) diff --git a/src/main/java/net/minestom/server/item/ItemMeta.java b/src/main/java/net/minestom/server/item/ItemMeta.java index 443e15bb3..a634d73ca 100644 --- a/src/main/java/net/minestom/server/item/ItemMeta.java +++ b/src/main/java/net/minestom/server/item/ItemMeta.java @@ -51,7 +51,7 @@ public class ItemMeta implements TagReadable, Writeable { this.canDestroy = new HashSet<>(metaBuilder.canDestroy); this.canPlaceOn = new HashSet<>(metaBuilder.canPlaceOn); - this.nbt = metaBuilder.nbt; + this.nbt = metaBuilder.nbt(); this.emptyBuilder = metaBuilder.getSupplier().get(); } diff --git a/src/main/java/net/minestom/server/item/ItemMetaBuilder.java b/src/main/java/net/minestom/server/item/ItemMetaBuilder.java index b6858ff8c..6274e4905 100644 --- a/src/main/java/net/minestom/server/item/ItemMetaBuilder.java +++ b/src/main/java/net/minestom/server/item/ItemMetaBuilder.java @@ -2,7 +2,6 @@ package net.minestom.server.item; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; -import net.minestom.server.adventure.AdventureSerializer; import net.minestom.server.instance.block.Block; import net.minestom.server.item.attribute.ItemAttribute; import net.minestom.server.tag.Tag; @@ -15,12 +14,17 @@ import org.jetbrains.annotations.Nullable; import org.jglrxavpok.hephaistos.nbt.*; import java.util.*; +import java.util.concurrent.atomic.AtomicReferenceFieldUpdater; import java.util.function.Consumer; import java.util.function.Supplier; public abstract class ItemMetaBuilder implements TagWritable { - protected NBTCompound nbt = new NBTCompound(); + private static final AtomicReferenceFieldUpdater NBT_UPDATER = + AtomicReferenceFieldUpdater.newUpdater(ItemMetaBuilder.class, NBTCompound.class, "nbt"); + + protected volatile boolean built = false; + private volatile NBTCompound nbt = new NBTCompound(); protected int damage; protected boolean unbreakable; @@ -36,21 +40,21 @@ public abstract class ItemMetaBuilder implements TagWritable { @Contract("_ -> this") public @NotNull ItemMetaBuilder damage(int damage) { this.damage = damage; - this.nbt.setInt("Damage", damage); + mutateNbt(compound -> compound.setInt("Damage", damage)); return this; } @Contract("_ -> this") public @NotNull ItemMetaBuilder unbreakable(boolean unbreakable) { this.unbreakable = unbreakable; - this.nbt.setByte("Unbreakable", (byte) (unbreakable ? 1 : 0)); + mutateNbt(compound -> compound.setByte("Unbreakable", (byte) (unbreakable ? 1 : 0))); return this; } @Contract("_ -> this") public @NotNull ItemMetaBuilder hideFlag(int hideFlag) { this.hideFlag = hideFlag; - this.nbt.setInt("HideFlags", hideFlag); + mutateNbt(compound -> compound.setInt("HideFlags", hideFlag)); return this; } @@ -79,7 +83,7 @@ public abstract class ItemMetaBuilder implements TagWritable { @Contract("_ -> this") public @NotNull ItemMetaBuilder lore(@NotNull List<@NotNull Component> lore) { - this.lore = lore; + this.lore = new ArrayList<>(lore); handleCompound("display", nbtCompound -> { final NBTList loreNBT = new NBTList<>(NBTTypes.TAG_String); for (Component line : lore) { @@ -98,7 +102,7 @@ public abstract class ItemMetaBuilder implements TagWritable { @Contract("_ -> this") public @NotNull ItemMetaBuilder enchantments(@NotNull Map enchantments) { - this.enchantmentMap = enchantments; + this.enchantmentMap = new HashMap<>(enchantments); handleMap(enchantmentMap, "Enchantments", nbt, () -> { NBTUtils.writeEnchant(nbt, "Enchantments", enchantmentMap); return nbt.get("Enchantments"); @@ -108,21 +112,21 @@ public abstract class ItemMetaBuilder implements TagWritable { @Contract("_, _ -> this") public @NotNull ItemMetaBuilder enchantment(@NotNull Enchantment enchantment, short level) { - this.enchantmentMap.put(enchantment, level); + this.enchantmentMap = Map.of(enchantment, level); enchantments(enchantmentMap); return this; } @Contract("-> this") public @NotNull ItemMetaBuilder clearEnchantment() { - this.enchantmentMap.clear(); + this.enchantmentMap = Collections.emptyMap(); enchantments(enchantmentMap); return this; } @Contract("_ -> this") public @NotNull ItemMetaBuilder attributes(@NotNull List<@NotNull ItemAttribute> attributes) { - this.attributes = attributes; + this.attributes = new ArrayList<>(attributes); handleCollection(attributes, "AttributeModifiers", nbt, () -> { NBTList attributesNBT = new NBTList<>(NBTTypes.TAG_Compound); @@ -153,7 +157,7 @@ public abstract class ItemMetaBuilder implements TagWritable { @Contract("_ -> this") public @NotNull ItemMetaBuilder canPlaceOn(@NotNull Set<@NotNull Block> blocks) { - this.canPlaceOn = blocks; + this.canPlaceOn = new HashSet<>(blocks); handleCollection(canPlaceOn, "CanPlaceOn", nbt, () -> { NBTList list = new NBTList<>(NBTTypes.TAG_String); canPlaceOn.forEach(block -> list.add(new NBTString(block.getName()))); @@ -170,7 +174,7 @@ public abstract class ItemMetaBuilder implements TagWritable { @Contract("_ -> this") public @NotNull ItemMetaBuilder canDestroy(@NotNull Set<@NotNull Block> blocks) { - this.canDestroy = blocks; + this.canDestroy = new HashSet<>(blocks); handleCollection(canDestroy, "CanDestroy", nbt, () -> { NBTList list = new NBTList<>(NBTTypes.TAG_String); canDestroy.forEach(block -> list.add(new NBTString(block.getName()))); @@ -187,7 +191,7 @@ public abstract class ItemMetaBuilder implements TagWritable { @Override public void setTag(@NotNull Tag tag, @Nullable T value) { - tag.write(nbt, value); + mutateNbt(compound -> tag.write(compound, value)); } public @NotNull ItemMetaBuilder set(@NotNull Tag tag, @Nullable T value) { @@ -202,30 +206,51 @@ public abstract class ItemMetaBuilder implements TagWritable { protected abstract @NotNull Supplier<@NotNull ItemMetaBuilder> getSupplier(); + protected void mutateNbt(Consumer consumer) { + if (built) { + built = false; + final var currentNbt = nbt; + NBT_UPDATER.compareAndSet(this, currentNbt, currentNbt.deepClone()); + } + synchronized (this) { + consumer.accept(nbt); + } + } + + protected synchronized NBTCompound nbt() { + return nbt; + } + + protected @NotNull ItemMeta generate() { + this.built = true; + return build(); + } + protected void handleCompound(@NotNull String key, @NotNull Consumer<@NotNull NBTCompound> consumer) { - NBTCompound compound = null; - boolean newNbt = false; - if (nbt.containsKey(key)) { - NBT dNbt = nbt.get(key); - if (dNbt instanceof NBTCompound) { - compound = (NBTCompound) dNbt; - } - } else { - compound = new NBTCompound(); - newNbt = true; - } - - if (compound != null) { - consumer.accept(compound); - - if (newNbt && compound.getSize() > 0) { - this.nbt.set(key, compound); - } else if (!newNbt && compound.getSize() == 0) { - this.nbt.removeTag(key); + mutateNbt(nbt -> { + NBTCompound compound = null; + boolean newNbt = false; + if (nbt.containsKey(key)) { + NBT dNbt = nbt.get(key); + if (dNbt instanceof NBTCompound) { + compound = (NBTCompound) dNbt; + } + } else { + compound = new NBTCompound(); + newNbt = true; } - } + if (compound != null) { + consumer.accept(compound); + + if (newNbt && compound.getSize() > 0) { + this.nbt.set(key, compound); + } else if (!newNbt && compound.getSize() == 0) { + this.nbt.removeTag(key); + } + } + }); } protected void handleNullable(@Nullable Object value, @@ -239,6 +264,12 @@ public abstract class ItemMetaBuilder implements TagWritable { } } + protected void handleNullable(@Nullable Object value, + @NotNull String key, + @NotNull Supplier<@NotNull NBT> supplier) { + mutateNbt(compound -> handleNullable(value, key, compound, supplier)); + } + protected void handleCollection(@NotNull Collection objects, @NotNull String key, @NotNull NBTCompound nbtCompound, @@ -250,6 +281,12 @@ public abstract class ItemMetaBuilder implements TagWritable { } } + protected void handleCollection(@NotNull Collection objects, + @NotNull String key, + @NotNull Supplier<@NotNull NBT> supplier) { + mutateNbt(compound -> handleCollection(objects, key, compound, supplier)); + } + protected void handleMap(@NotNull Map objects, @NotNull String key, @NotNull NBTCompound nbtCompound, @@ -271,5 +308,4 @@ public abstract class ItemMetaBuilder implements TagWritable { public interface Provider { } - } diff --git a/src/main/java/net/minestom/server/item/ItemStackBuilder.java b/src/main/java/net/minestom/server/item/ItemStackBuilder.java index 75a2b42f7..168f8d43a 100644 --- a/src/main/java/net/minestom/server/item/ItemStackBuilder.java +++ b/src/main/java/net/minestom/server/item/ItemStackBuilder.java @@ -109,9 +109,9 @@ public class ItemStackBuilder { @Contract(value = "-> new", pure = true) public @NotNull ItemStack build() { - if (amount > 0) - return new ItemStack(material, amount, metaBuilder.build(), stackingRule); - return ItemStack.AIR; + if (amount < 1) + return ItemStack.AIR; + return new ItemStack(material, amount, metaBuilder.generate(), stackingRule); } private static final class DefaultMeta extends ItemMetaBuilder { @@ -130,5 +130,4 @@ public class ItemStackBuilder { return DefaultMeta::new; } } - } diff --git a/src/main/java/net/minestom/server/item/metadata/CompassMeta.java b/src/main/java/net/minestom/server/item/metadata/CompassMeta.java index a046f0597..2393fbe90 100644 --- a/src/main/java/net/minestom/server/item/metadata/CompassMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/CompassMeta.java @@ -45,18 +45,20 @@ public class CompassMeta extends ItemMeta implements ItemMetaBuilder.Provider compound.setByte("LodestoneTracked", (byte) (lodestoneTracked ? 1 : 0))); return this; } public Builder lodestoneDimension(@Nullable String lodestoneDimension) { this.lodestoneDimension = lodestoneDimension; - if (lodestoneDimension != null) { - this.nbt.setString("LodestoneDimension", lodestoneDimension); - } else { - this.nbt.removeTag("LodestoneDimension"); - } + mutateNbt(compound -> { + if (lodestoneDimension != null) { + compound.setString("LodestoneDimension", lodestoneDimension); + } else { + compound.removeTag("LodestoneDimension"); + } + }); return this; } @@ -64,15 +66,17 @@ public class CompassMeta extends ItemMeta implements ItemMetaBuilder.Provider { + if (lodestonePosition != null) { + NBTCompound posCompound = new NBTCompound(); + posCompound.setInt("X", (int) lodestonePosition.getX()); + posCompound.setInt("Y", (int) lodestonePosition.getY()); + posCompound.setInt("Z", (int) lodestonePosition.getZ()); + compound.set("LodestonePos", posCompound); + } else { + compound.removeTag("LodestonePos"); + } + }); return this; } diff --git a/src/main/java/net/minestom/server/item/metadata/CrossbowMeta.java b/src/main/java/net/minestom/server/item/metadata/CrossbowMeta.java index c08236ecf..5aa7d45f3 100644 --- a/src/main/java/net/minestom/server/item/metadata/CrossbowMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/CrossbowMeta.java @@ -97,7 +97,7 @@ public class CrossbowMeta extends ItemMeta implements ItemMetaBuilder.Provider compound.set("ChargedProjectiles", chargedProjectiles)); return this; } @@ -123,7 +123,7 @@ public class CrossbowMeta extends ItemMeta implements ItemMetaBuilder.Provider compound.set("ChargedProjectiles", chargedProjectiles)); return this; } @@ -135,7 +135,7 @@ public class CrossbowMeta extends ItemMeta implements ItemMetaBuilder.Provider compound.setByte("Charged", (byte) (charged ? 1 : 0))); return this; } diff --git a/src/main/java/net/minestom/server/item/metadata/EnchantedBookMeta.java b/src/main/java/net/minestom/server/item/metadata/EnchantedBookMeta.java index 3f5c218ab..bed14c215 100644 --- a/src/main/java/net/minestom/server/item/metadata/EnchantedBookMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/EnchantedBookMeta.java @@ -35,13 +35,13 @@ public class EnchantedBookMeta extends ItemMeta implements ItemMetaBuilder.Provi private Map enchantments = new HashMap<>(); - public @NotNull Builder enchantments(Map enchantments) { + public @NotNull Builder enchantments(@NotNull Map enchantments) { this.enchantments = enchantments; - NBTUtils.writeEnchant(nbt, "StoredEnchantments", enchantments); + mutateNbt(compound -> NBTUtils.writeEnchant(compound, "StoredEnchantments", enchantments)); return this; } - public @NotNull Builder enchantment(Enchantment enchantment, short level) { + public @NotNull Builder enchantment(@NotNull Enchantment enchantment, short level) { this.enchantments.put(enchantment, level); enchantments(enchantments); return this; diff --git a/src/main/java/net/minestom/server/item/metadata/FireworkEffectMeta.java b/src/main/java/net/minestom/server/item/metadata/FireworkEffectMeta.java index 1af345b36..373dfcb3d 100644 --- a/src/main/java/net/minestom/server/item/metadata/FireworkEffectMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/FireworkEffectMeta.java @@ -28,7 +28,7 @@ public class FireworkEffectMeta extends ItemMeta implements ItemMetaBuilder.Prov public Builder effect(@Nullable FireworkEffect fireworkEffect) { this.fireworkEffect = fireworkEffect; - this.nbt.set("Explosion", this.fireworkEffect.asCompound()); + mutateNbt(compound -> compound.set("Explosion", this.fireworkEffect.asCompound())); return this; } diff --git a/src/main/java/net/minestom/server/item/metadata/MapMeta.java b/src/main/java/net/minestom/server/item/metadata/MapMeta.java index d720714a0..a3e86d19d 100644 --- a/src/main/java/net/minestom/server/item/metadata/MapMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/MapMeta.java @@ -91,18 +91,18 @@ public class MapMeta extends ItemMeta implements ItemMetaBuilder.Provider compound.setInt("map", mapId)); return this; } public Builder mapScaleDirection(int value) { this.mapScaleDirection = value; - this.nbt.setInt("map_scale_direction", value); + mutateNbt(compound -> compound.setInt("map_scale_direction", value)); return this; } public Builder decorations(List value) { - this.decorations = value; + this.decorations = new ArrayList<>(value); NBTList decorationsList = new NBTList<>(NBTTypes.TAG_Compound); for (MapDecoration decoration : decorations) { @@ -115,7 +115,7 @@ public class MapMeta extends ItemMeta implements ItemMetaBuilder.Provider compound.set("Decorations", decorationsList)); return this; } @@ -123,14 +123,16 @@ public class MapMeta extends ItemMeta implements ItemMetaBuilder.Provider { + NBTCompound displayCompound; + if (nbt.containsKey("display")) { + displayCompound = nbt.getCompound("display"); + } else { + displayCompound = new NBTCompound(); + nbt.set("display", displayCompound); + } + displayCompound.setInt("MapColor", mapColor.asRGB()); + }); return this; } diff --git a/src/main/java/net/minestom/server/item/metadata/PotionMeta.java b/src/main/java/net/minestom/server/item/metadata/PotionMeta.java index a764b7cfa..e7ee9ad7d 100644 --- a/src/main/java/net/minestom/server/item/metadata/PotionMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/PotionMeta.java @@ -52,7 +52,7 @@ public class PotionMeta extends ItemMeta implements ItemMetaBuilder.Provider compound.setString("Potion", potionType.getNamespaceID().asString())); return this; } @@ -71,14 +71,14 @@ public class PotionMeta extends ItemMeta implements ItemMetaBuilder.Provider compound.set("CustomPotionEffects", potionList)); return this; } public Builder color(@NotNull Color color) { this.color = color; - this.nbt.setInt("CustomPotionColor", color.asRGB()); + mutateNbt(compound -> compound.setInt("CustomPotionColor", color.asRGB())); return this; } diff --git a/src/main/java/net/minestom/server/item/metadata/WritableBookMeta.java b/src/main/java/net/minestom/server/item/metadata/WritableBookMeta.java index f108845ec..761d5261a 100644 --- a/src/main/java/net/minestom/server/item/metadata/WritableBookMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/WritableBookMeta.java @@ -2,7 +2,6 @@ package net.minestom.server.item.metadata; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer; -import net.minestom.server.adventure.AdventureSerializer; import net.minestom.server.item.ItemMeta; import net.minestom.server.item.ItemMetaBuilder; import org.jetbrains.annotations.NotNull; @@ -53,22 +52,22 @@ public class WritableBookMeta extends ItemMeta implements ItemMetaBuilder.Provid public Builder author(@Nullable String author) { this.author = author; - handleNullable(author, "author", nbt, + handleNullable(author, "author", () -> new NBTString(Objects.requireNonNull(author))); return this; } public Builder title(@Nullable String title) { this.title = title; - handleNullable(title, "title", nbt, + handleNullable(title, "title", () -> new NBTString(Objects.requireNonNull(title))); return this; } public Builder pages(@NotNull List<@NotNull Component> pages) { - this.pages = pages; + this.pages = new ArrayList<>(pages); - handleCollection(pages, "pages", nbt, () -> { + handleCollection(pages, "pages", () -> { NBTList list = new NBTList<>(NBTTypes.TAG_String); for (Component page : pages) { list.add(new NBTString(GsonComponentSerializer.gson().serialize(page))); diff --git a/src/main/java/net/minestom/server/item/metadata/WrittenBookMeta.java b/src/main/java/net/minestom/server/item/metadata/WrittenBookMeta.java index 3ce191ae4..86e79a7f5 100644 --- a/src/main/java/net/minestom/server/item/metadata/WrittenBookMeta.java +++ b/src/main/java/net/minestom/server/item/metadata/WrittenBookMeta.java @@ -86,35 +86,35 @@ public class WrittenBookMeta extends ItemMeta implements ItemMetaBuilder.Provide public Builder resolved(boolean resolved) { this.resolved = resolved; - this.nbt.setByte("resolved", (byte) (resolved ? 1 : 0)); + mutateNbt(compound -> compound.setByte("resolved", (byte) (resolved ? 1 : 0))); return this; } public Builder generation(@Nullable WrittenBookGeneration generation) { this.generation = generation; - handleNullable(generation, "generation", nbt, + handleNullable(generation, "generation", () -> new NBTInt(Objects.requireNonNull(generation).ordinal())); return this; } public Builder author(@Nullable String author) { this.author = author; - handleNullable(author, "author", nbt, + handleNullable(author, "author", () -> new NBTString(Objects.requireNonNull(author))); return this; } public Builder title(@Nullable String title) { this.title = title; - handleNullable(title, "title", nbt, + handleNullable(title, "title", () -> new NBTString(Objects.requireNonNull(title))); return this; } public Builder pages(@NotNull List<@NotNull Component> pages) { - this.pages = pages; + this.pages = new ArrayList<>(pages); - handleCollection(pages, "pages", nbt, () -> { + handleCollection(pages, "pages", () -> { NBTList list = new NBTList<>(NBTTypes.TAG_String); for (Component page : pages) { list.add(new NBTString(GsonComponentSerializer.gson().serialize(page))); From 018a9263ee8ab7c27f92bb8c0466d1704b74a348 Mon Sep 17 00:00:00 2001 From: TheMode Date: Sun, 27 Jun 2021 17:41:07 +0200 Subject: [PATCH 26/39] Remove all direct volatile reads --- .../minestom/server/item/ItemMetaBuilder.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/main/java/net/minestom/server/item/ItemMetaBuilder.java b/src/main/java/net/minestom/server/item/ItemMetaBuilder.java index 6274e4905..8f6eed47a 100644 --- a/src/main/java/net/minestom/server/item/ItemMetaBuilder.java +++ b/src/main/java/net/minestom/server/item/ItemMetaBuilder.java @@ -103,7 +103,7 @@ public abstract class ItemMetaBuilder implements TagWritable { @Contract("_ -> this") public @NotNull ItemMetaBuilder enchantments(@NotNull Map enchantments) { this.enchantmentMap = new HashMap<>(enchantments); - handleMap(enchantmentMap, "Enchantments", nbt, () -> { + handleMap(enchantmentMap, "Enchantments", () -> { NBTUtils.writeEnchant(nbt, "Enchantments", enchantmentMap); return nbt.get("Enchantments"); }); @@ -128,7 +128,7 @@ public abstract class ItemMetaBuilder implements TagWritable { public @NotNull ItemMetaBuilder attributes(@NotNull List<@NotNull ItemAttribute> attributes) { this.attributes = new ArrayList<>(attributes); - handleCollection(attributes, "AttributeModifiers", nbt, () -> { + handleCollection(attributes, "AttributeModifiers", () -> { NBTList attributesNBT = new NBTList<>(NBTTypes.TAG_Compound); for (ItemAttribute itemAttribute : attributes) { final UUID uuid = itemAttribute.getUuid(); @@ -151,17 +151,16 @@ public abstract class ItemMetaBuilder implements TagWritable { @Contract("_ -> this") public @NotNull ItemMetaBuilder customModelData(int customModelData) { this.customModelData = customModelData; - this.nbt.setInt("CustomModelData", customModelData); + mutateNbt(compound -> compound.setInt("CustomModelData", customModelData)); return this; } @Contract("_ -> this") public @NotNull ItemMetaBuilder canPlaceOn(@NotNull Set<@NotNull Block> blocks) { this.canPlaceOn = new HashSet<>(blocks); - handleCollection(canPlaceOn, "CanPlaceOn", nbt, () -> { + handleCollection(canPlaceOn, "CanPlaceOn", () -> { NBTList list = new NBTList<>(NBTTypes.TAG_String); canPlaceOn.forEach(block -> list.add(new NBTString(block.getName()))); - nbt.set("CanPlaceOn", list); return list; }); return this; @@ -175,10 +174,9 @@ public abstract class ItemMetaBuilder implements TagWritable { @Contract("_ -> this") public @NotNull ItemMetaBuilder canDestroy(@NotNull Set<@NotNull Block> blocks) { this.canDestroy = new HashSet<>(blocks); - handleCollection(canDestroy, "CanDestroy", nbt, () -> { + handleCollection(canDestroy, "CanDestroy", () -> { NBTList list = new NBTList<>(NBTTypes.TAG_String); canDestroy.forEach(block -> list.add(new NBTString(block.getName()))); - nbt.set("CanDestroy", list); return list; }); return this; @@ -298,6 +296,12 @@ public abstract class ItemMetaBuilder implements TagWritable { } } + protected void handleMap(@NotNull Map objects, + @NotNull String key, + @NotNull Supplier<@NotNull NBT> supplier) { + mutateNbt(compound -> handleMap(objects, key, compound, supplier)); + } + @Contract(value = "_, _ -> new", pure = true) public static @NotNull ItemMetaBuilder fromNBT(@NotNull ItemMetaBuilder src, @NotNull NBTCompound nbtCompound) { ItemMetaBuilder dest = src.getSupplier().get(); From b900d0e73d7e6877109650c4b69611d945582303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9meth=20Noel?= Date: Sun, 27 Jun 2021 22:29:25 +0200 Subject: [PATCH 27/39] Introduced Entity#initializeDefaultGravity method --- .../net/minestom/server/entity/Entity.java | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index eec74abf0..6460eb556 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -162,6 +162,8 @@ public class Entity implements Viewable, Tickable, EventHandler, Da Entity.ENTITY_BY_UUID.put(uuid, this); this.eventNode = EventNode.value("entity-" + uuid, EventFilter.ENTITY, this::equals); + + initializeDefaultGravity(); } public Entity(@NotNull EntityType entityType) { @@ -1643,6 +1645,94 @@ public class Entity implements Viewable, Tickable, EventHandler, Da tag.write(nbtCompound, value); } + /** + * Sets the Entity's {@link gravityAcceleration} and {@link gravityDragPerTick} fields to + * the default values according to Motion of entities + */ + @SuppressWarnings("JavadocReference") + public void initializeDefaultGravity() { + // TODO Add support for these values in the data generator + // Acceleration + switch (entityType) { + // 0 + case ITEM_FRAME: + this.gravityAcceleration = 0; + break; + // 0.03 + case EGG: + case FISHING_BOBBER: + case EXPERIENCE_BOTTLE: + case ENDER_PEARL: + case POTION: + case SNOWBALL: + this.gravityAcceleration = 0.03; + break; + // 0.04 + case BOAT: + case TNT: + case FALLING_BLOCK: + case ITEM: + case MINECART: + this.gravityAcceleration = 0.04; + break; + // 0.05 + case ARROW: + case SPECTRAL_ARROW: + case TRIDENT: + this.gravityAcceleration = 0.05; + break; + // 0.06 + case LLAMA_SPIT: + this.gravityAcceleration = 0.06; + break; + // 0.1 + case FIREBALL: + case WITHER_SKULL: + case DRAGON_FIREBALL: + this.gravityAcceleration = 0.1; + break; + // 0.08 + default: + this.gravityAcceleration = 0.08; + break; + } + + // Drag + switch (entityType) { + // 0 + case BOAT: + this.gravityDragPerTick = 0; + break; + // 0.01 + case LLAMA_SPIT: + case ENDER_PEARL: + case POTION: + case SNOWBALL: + case EGG: + case TRIDENT: + case SPECTRAL_ARROW: + case ARROW: + this.gravityDragPerTick = 0.01; + break; + // 0.05 + case MINECART: + this.gravityDragPerTick = 0.05; + break; + // 0.08 + case FISHING_BOBBER: + this.gravityDragPerTick = 0.08; + break; + // 0.02 + default: + this.gravityDragPerTick = 0.02; + break; + } + + // Values are in blocks/tick, convert them to blocks/second + gravityAcceleration *= MinecraftServer.TICK_PER_SECOND; + gravityDragPerTick *= MinecraftServer.TICK_PER_SECOND; + } + public enum Pose { STANDING, FALL_FLYING, From e66fc2d200b6b69cfae404dfcd765d349c4b5f8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9meth=20Noel?= Date: Sun, 27 Jun 2021 22:32:56 +0200 Subject: [PATCH 28/39] Removed usages of Entity#setGravity --- src/main/java/net/minestom/server/entity/EntityProjectile.java | 1 - src/main/java/net/minestom/server/entity/ExperienceOrb.java | 1 - src/main/java/net/minestom/server/entity/ItemEntity.java | 1 - src/main/java/net/minestom/server/entity/LivingEntity.java | 2 -- 4 files changed, 5 deletions(-) diff --git a/src/main/java/net/minestom/server/entity/EntityProjectile.java b/src/main/java/net/minestom/server/entity/EntityProjectile.java index 712c3983b..f00fd5576 100644 --- a/src/main/java/net/minestom/server/entity/EntityProjectile.java +++ b/src/main/java/net/minestom/server/entity/EntityProjectile.java @@ -47,7 +47,6 @@ public class EntityProjectile extends Entity { if (getEntityMeta() instanceof ProjectileMeta) { ((ProjectileMeta) getEntityMeta()).setShooter(this.shooter); } - setGravity(0.02f, 0.04f, 1.96f); } @Nullable diff --git a/src/main/java/net/minestom/server/entity/ExperienceOrb.java b/src/main/java/net/minestom/server/entity/ExperienceOrb.java index 379b647ac..4566bf8c9 100644 --- a/src/main/java/net/minestom/server/entity/ExperienceOrb.java +++ b/src/main/java/net/minestom/server/entity/ExperienceOrb.java @@ -17,7 +17,6 @@ public class ExperienceOrb extends Entity { public ExperienceOrb(short experienceCount, @NotNull Position spawnPosition) { super(EntityType.EXPERIENCE_ORB, spawnPosition); - setGravity(0.02f, 0.04f, 1.96f); setBoundingBox(0.5f, 0.5f, 0.5f); //todo vanilla sets random velocity here? this.experienceCount = experienceCount; diff --git a/src/main/java/net/minestom/server/entity/ItemEntity.java b/src/main/java/net/minestom/server/entity/ItemEntity.java index 8fdb5e69b..275348262 100644 --- a/src/main/java/net/minestom/server/entity/ItemEntity.java +++ b/src/main/java/net/minestom/server/entity/ItemEntity.java @@ -43,7 +43,6 @@ public class ItemEntity extends Entity { public ItemEntity(@NotNull ItemStack itemStack, @NotNull Position spawnPosition) { super(EntityType.ITEM, spawnPosition); setItemStack(itemStack); - setGravity(0.02f, 0.04f, 1.96f); setBoundingBox(0.25f, 0.25f, 0.25f); } diff --git a/src/main/java/net/minestom/server/entity/LivingEntity.java b/src/main/java/net/minestom/server/entity/LivingEntity.java index 674acfc68..37fcf82c1 100644 --- a/src/main/java/net/minestom/server/entity/LivingEntity.java +++ b/src/main/java/net/minestom/server/entity/LivingEntity.java @@ -90,7 +90,6 @@ public class LivingEntity extends Entity implements EquipmentHandler { */ public LivingEntity(@NotNull EntityType entityType, @NotNull UUID uuid) { this(entityType, uuid, new Position()); - setGravity(0.02f, 0.08f, 3.92f); initEquipments(); } @@ -104,7 +103,6 @@ public class LivingEntity extends Entity implements EquipmentHandler { @Deprecated public LivingEntity(@NotNull EntityType entityType, @NotNull UUID uuid, @NotNull Position spawnPosition) { super(entityType, uuid, spawnPosition); - setGravity(0.02f, 0.08f, 3.92f); initEquipments(); } From adf0e0688821061dfb022b4168cc018359ea4e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9meth=20Noel?= Date: Sun, 27 Jun 2021 22:44:04 +0200 Subject: [PATCH 29/39] Changed gravity calculation --- src/main/java/net/minestom/server/entity/Entity.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index 6460eb556..049413cc2 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -529,9 +529,7 @@ public class Entity implements Viewable, Tickable, EventHandler, Da Vector newVelocityOut = new Vector(); // Gravity force - final double gravityY = !hasNoGravity() ? Math.min( - gravityDragPerTick + (gravityAcceleration * (double) gravityTickCount), - gravityTerminalVelocity) : 0; + final double gravityY = hasNoGravity() ? 0 : gravityAcceleration; final Vector deltaPos = new Vector( getVelocity().getX() / tps, @@ -596,6 +594,8 @@ public class Entity implements Viewable, Tickable, EventHandler, Da this.velocity.setX(velocity.getX() * drag); this.velocity.setZ(velocity.getZ() * drag); + if (!hasNoGravity()) + this.velocity.setY(velocity.getY() * (1-gravityDragPerTick)); if (velocity.equals(new Vector())) { this.velocity.zero(); From 811531da70594d277eb616f23ef8f6a3d6849ad2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9meth=20Noel?= Date: Sun, 27 Jun 2021 22:45:05 +0200 Subject: [PATCH 30/39] Remove unit conversion --- src/main/java/net/minestom/server/entity/Entity.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index 049413cc2..427aa8d1c 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -1727,10 +1727,6 @@ public class Entity implements Viewable, Tickable, EventHandler, Da this.gravityDragPerTick = 0.02; break; } - - // Values are in blocks/tick, convert them to blocks/second - gravityAcceleration *= MinecraftServer.TICK_PER_SECOND; - gravityDragPerTick *= MinecraftServer.TICK_PER_SECOND; } public enum Pose { From 17aa606037765bf6c0280de048e71e9d21f7ba49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9meth=20Noel?= Date: Sun, 27 Jun 2021 22:48:58 +0200 Subject: [PATCH 31/39] Added javadoc to gravity related fields --- src/main/java/net/minestom/server/entity/Entity.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index 427aa8d1c..1890a1cc8 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -95,7 +95,17 @@ public class Entity implements Viewable, Tickable, EventHandler, Da protected Vector velocity = new Vector(); // Movement in block per second protected boolean hasPhysics = true; + /** + * The amount of drag applied on the Y axle. + *

+ * Unit: 1/tick + */ protected double gravityDragPerTick; + /** + * Acceleration on the Y axle due to gravity + *

+ * Unit: blocks/tick + */ protected double gravityAcceleration; protected double gravityTerminalVelocity; protected int gravityTickCount; // Number of tick where gravity tick was applied From 6c60c4d0fc86621f1c60c7213fcd461b91097886 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9meth=20Noel?= Date: Sun, 27 Jun 2021 23:05:54 +0200 Subject: [PATCH 32/39] Implement knockback --- .../java/net/minestom/server/entity/Entity.java | 16 ++++++++++++++++ .../net/minestom/server/entity/LivingEntity.java | 14 ++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index 1890a1cc8..dcc0f5960 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -1739,6 +1739,22 @@ public class Entity implements Viewable, Tickable, EventHandler, Da } } + /** + * Applies knockback to the entity + * + * @param strength the strength of the knockback, 0.4 is the vanilla value for a bare hand hit + * @param x knockback on x axle, for default knockback use the following formula

sin(attacker.yaw * (pi/180))
+ * @param z knockback on z axle, for default knockback use the following formula
-cos(attacker.yaw * (pi/180))
+ */ + public void takeKnockback(final float strength, final double x, final double z) { + if (strength > 0) { + final Vector velocityModifier = new Vector(x, 0d, z).normalize().multiply(strength); + this.velocity.setX(velocity.getX() / 2d - velocityModifier.getX()); + this.velocity.setY(onGround ? Math.min(.4d, velocity.getY() / 2d + strength) : velocity.getY()); + this.velocity.setZ(velocity.getZ() / 2d - velocityModifier.getZ()); + } + } + public enum Pose { STANDING, FALL_FLYING, diff --git a/src/main/java/net/minestom/server/entity/LivingEntity.java b/src/main/java/net/minestom/server/entity/LivingEntity.java index 37fcf82c1..f1fd8642e 100644 --- a/src/main/java/net/minestom/server/entity/LivingEntity.java +++ b/src/main/java/net/minestom/server/entity/LivingEntity.java @@ -779,4 +779,18 @@ public class LivingEntity extends Entity implements EquipmentHandler { return null; } + /** + * Applies knockback + *

+ * Note: The strength is reduced based on knockback resistance + * + * @param strength the strength of the knockback, 0.4 is the vanilla value for a bare hand hit + * @param x knockback on x axle, for default knockback use the following formula

sin(attacker.yaw * (pi/180))
+ * @param z knockback on z axle, for default knockback use the following formula
-cos(attacker.yaw * (pi/180))
+ */ + @Override + public void takeKnockback(float strength, final double x, final double z) { + strength *= 1 - getAttributeValue(Attribute.KNOCKBACK_RESISTANCE); + super.takeKnockback(strength, x, z); + } } From 1afd4b4328a950bedf5a482a125d5efdb7ca396b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9meth=20Noel?= Date: Sun, 27 Jun 2021 23:09:23 +0200 Subject: [PATCH 33/39] Use knockback method --- src/test/java/demo/PlayerInit.java | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/test/java/demo/PlayerInit.java b/src/test/java/demo/PlayerInit.java index 485347368..9048b56a9 100644 --- a/src/test/java/demo/PlayerInit.java +++ b/src/test/java/demo/PlayerInit.java @@ -50,16 +50,12 @@ public class PlayerInit { .addListener(EntityAttackEvent.class, event -> { final Entity source = event.getEntity(); final Entity entity = event.getTarget(); + + entity.takeKnockback(0.4f, Math.sin(source.getPosition().getYaw() * 0.017453292), -Math.cos(source.getPosition().getYaw() * 0.017453292)); + if (entity instanceof Player) { Player target = (Player) entity; - Vector velocity = source.getPosition().clone().getDirection().multiply(4); - velocity.setY(3.5f); - target.setVelocity(velocity); target.damage(DamageType.fromEntity(source), 5); - } else { - Vector velocity = source.getPosition().clone().getDirection().multiply(3); - velocity.setY(3f); - entity.setVelocity(velocity); } if (source instanceof Player) { From 1ea526aa89e782da7f9e7446334cce7fd543cd5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9meth=20Noel?= Date: Sun, 27 Jun 2021 23:29:28 +0200 Subject: [PATCH 34/39] Fix gravity acceleration --- src/main/java/net/minestom/server/entity/Entity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index dcc0f5960..584975bc1 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -543,7 +543,7 @@ public class Entity implements Viewable, Tickable, EventHandler, Da final Vector deltaPos = new Vector( getVelocity().getX() / tps, - (getVelocity().getY() - gravityY) / tps, + getVelocity().getY() / tps - gravityY, getVelocity().getZ() / tps ); From 13779aabdecc6ed5bb9a06e1a88483772fb7af01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9meth=20Noel?= Date: Mon, 28 Jun 2021 19:23:36 +0200 Subject: [PATCH 35/39] Fix knockback --- src/main/java/net/minestom/server/entity/Entity.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index 584975bc1..ce590466f 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -1748,9 +1748,10 @@ public class Entity implements Viewable, Tickable, EventHandler, Da */ public void takeKnockback(final float strength, final double x, final double z) { if (strength > 0) { - final Vector velocityModifier = new Vector(x, 0d, z).normalize().multiply(strength); + //TODO check possible side effects of unnatural TPS (other than 20TPS) + final Vector velocityModifier = new Vector(x, 0d, z).normalize().multiply(strength * MinecraftServer.TICK_PER_SECOND / 2); this.velocity.setX(velocity.getX() / 2d - velocityModifier.getX()); - this.velocity.setY(onGround ? Math.min(.4d, velocity.getY() / 2d + strength) : velocity.getY()); + this.velocity.setY(onGround ? Math.min(.4d, velocity.getY() / 2d + strength) * MinecraftServer.TICK_PER_SECOND : velocity.getY()); this.velocity.setZ(velocity.getZ() / 2d - velocityModifier.getZ()); } } From 796d296f0d763a6811d7d35417d346aef43bfd15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9meth=20Noel?= Date: Mon, 28 Jun 2021 19:24:53 +0200 Subject: [PATCH 36/39] Removed terminal velocity --- .../java/net/minestom/server/entity/Entity.java | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index ce590466f..a328b03f0 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -107,7 +107,6 @@ public class Entity implements Viewable, Tickable, EventHandler, Da * Unit: blocks/tick */ protected double gravityAcceleration; - protected double gravityTerminalVelocity; protected int gravityTickCount; // Number of tick where gravity tick was applied private boolean autoViewable; @@ -997,15 +996,6 @@ public class Entity implements Viewable, Tickable, EventHandler, Da return gravityAcceleration; } - /** - * Gets the maximum gravity velocity. - * - * @return the maximum gravity velocity in block - */ - public double getGravityTerminalVelocity() { - return gravityTerminalVelocity; - } - /** * Gets the number of tick this entity has been applied gravity. * @@ -1020,13 +1010,11 @@ public class Entity implements Viewable, Tickable, EventHandler, Da * * @param gravityDragPerTick the gravity drag per tick in block * @param gravityAcceleration the gravity acceleration in block - * @param gravityTerminalVelocity the gravity terminal velocity (maximum) in block * @see Entities motion */ - public void setGravity(double gravityDragPerTick, double gravityAcceleration, double gravityTerminalVelocity) { + public void setGravity(double gravityDragPerTick, double gravityAcceleration) { this.gravityDragPerTick = gravityDragPerTick; this.gravityAcceleration = gravityAcceleration; - this.gravityTerminalVelocity = gravityTerminalVelocity; } /** From f6425d9fb2d60fc13e6005c017a5ad16c879bc32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?N=C3=A9meth=20Noel?= Date: Mon, 28 Jun 2021 21:58:59 +0200 Subject: [PATCH 37/39] Reduce the visibility of Entity#initializeDefaultGravity --- src/main/java/net/minestom/server/entity/Entity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index a328b03f0..3878aa7f9 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -1648,7 +1648,7 @@ public class Entity implements Viewable, Tickable, EventHandler, Da * the default values according to Motion of entities */ @SuppressWarnings("JavadocReference") - public void initializeDefaultGravity() { + private void initializeDefaultGravity() { // TODO Add support for these values in the data generator // Acceleration switch (entityType) { From 790e99bce3a94c1c4492eba3d949e305e63cf274 Mon Sep 17 00:00:00 2001 From: TheMode Date: Mon, 28 Jun 2021 23:27:12 +0200 Subject: [PATCH 38/39] Simplify synchronization --- src/main/java/net/minestom/server/item/ItemMetaBuilder.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/net/minestom/server/item/ItemMetaBuilder.java b/src/main/java/net/minestom/server/item/ItemMetaBuilder.java index 8f6eed47a..5c6a4c1cd 100644 --- a/src/main/java/net/minestom/server/item/ItemMetaBuilder.java +++ b/src/main/java/net/minestom/server/item/ItemMetaBuilder.java @@ -204,15 +204,13 @@ public abstract class ItemMetaBuilder implements TagWritable { protected abstract @NotNull Supplier<@NotNull ItemMetaBuilder> getSupplier(); - protected void mutateNbt(Consumer consumer) { + protected synchronized void mutateNbt(Consumer consumer) { if (built) { built = false; final var currentNbt = nbt; NBT_UPDATER.compareAndSet(this, currentNbt, currentNbt.deepClone()); } - synchronized (this) { - consumer.accept(nbt); - } + consumer.accept(nbt); } protected synchronized NBTCompound nbt() { From 5dfecce5d5b79e742331d84e4959361106b038aa Mon Sep 17 00:00:00 2001 From: TheMode Date: Mon, 28 Jun 2021 23:31:01 +0200 Subject: [PATCH 39/39] Cleanup --- .../minestom/server/item/ItemMetaBuilder.java | 59 +++++++------------ 1 file changed, 22 insertions(+), 37 deletions(-) diff --git a/src/main/java/net/minestom/server/item/ItemMetaBuilder.java b/src/main/java/net/minestom/server/item/ItemMetaBuilder.java index 5c6a4c1cd..8ec7551b7 100644 --- a/src/main/java/net/minestom/server/item/ItemMetaBuilder.java +++ b/src/main/java/net/minestom/server/item/ItemMetaBuilder.java @@ -112,7 +112,7 @@ public abstract class ItemMetaBuilder implements TagWritable { @Contract("_, _ -> this") public @NotNull ItemMetaBuilder enchantment(@NotNull Enchantment enchantment, short level) { - this.enchantmentMap = Map.of(enchantment, level); + this.enchantmentMap.put(enchantment, level); enchantments(enchantmentMap); return this; } @@ -251,53 +251,38 @@ public abstract class ItemMetaBuilder implements TagWritable { protected void handleNullable(@Nullable Object value, @NotNull String key, - @NotNull NBTCompound nbtCompound, @NotNull Supplier<@NotNull NBT> supplier) { - if (value != null) { - nbtCompound.set(key, supplier.get()); - } else { - nbtCompound.removeTag(key); - } - } - - protected void handleNullable(@Nullable Object value, - @NotNull String key, - @NotNull Supplier<@NotNull NBT> supplier) { - mutateNbt(compound -> handleNullable(value, key, compound, supplier)); - } - - protected void handleCollection(@NotNull Collection objects, - @NotNull String key, - @NotNull NBTCompound nbtCompound, - @NotNull Supplier<@NotNull NBT> supplier) { - if (!objects.isEmpty()) { - nbtCompound.set(key, supplier.get()); - } else { - nbtCompound.removeTag(key); - } + mutateNbt(compound -> { + if (value != null) { + compound.set(key, supplier.get()); + } else { + compound.removeTag(key); + } + }); } protected void handleCollection(@NotNull Collection objects, @NotNull String key, @NotNull Supplier<@NotNull NBT> supplier) { - mutateNbt(compound -> handleCollection(objects, key, compound, supplier)); - } - - protected void handleMap(@NotNull Map objects, - @NotNull String key, - @NotNull NBTCompound nbtCompound, - @NotNull Supplier<@NotNull NBT> supplier) { - if (!objects.isEmpty()) { - nbtCompound.set(key, supplier.get()); - } else { - nbtCompound.removeTag(key); - } + mutateNbt(compound -> { + if (!objects.isEmpty()) { + compound.set(key, supplier.get()); + } else { + compound.removeTag(key); + } + }); } protected void handleMap(@NotNull Map objects, @NotNull String key, @NotNull Supplier<@NotNull NBT> supplier) { - mutateNbt(compound -> handleMap(objects, key, compound, supplier)); + mutateNbt(compound -> { + if (!objects.isEmpty()) { + compound.set(key, supplier.get()); + } else { + compound.removeTag(key); + } + }); } @Contract(value = "_, _ -> new", pure = true)