From 0754e0ac330e8cb8ee480d5add68db8061372dde Mon Sep 17 00:00:00 2001 From: filoghost Date: Mon, 19 Feb 2024 23:11:34 +0100 Subject: [PATCH] Experimental and potentially unstable: async packet sending --- .../core/HolographicDisplaysCore.java | 5 ++ .../core/tracking/ClickableLineTracker.java | 26 +++++-- .../core/tracking/ItemLineTracker.java | 35 ++++++++-- .../core/tracking/LineTracker.java | 8 +-- .../core/tracking/MutableViewers.java | 4 +- .../core/tracking/PacketSenderExecutor.java | 69 +++++++++++++++++++ .../core/tracking/TextLineTracker.java | 27 ++++++-- .../core/tracking/TextLineViewer.java | 41 ++++++----- .../nms/v1_10_R1/PacketByteBuffer.java | 7 +- .../nms/v1_11_R1/PacketByteBuffer.java | 7 +- .../nms/v1_12_R1/PacketByteBuffer.java | 7 +- .../nms/v1_13_R2/PacketByteBuffer.java | 7 +- .../nms/v1_14_R1/PacketByteBuffer.java | 7 +- .../nms/v1_15_R1/PacketByteBuffer.java | 7 +- .../nms/v1_16_R3/PacketByteBuffer.java | 7 +- .../nms/v1_17_R1/PacketByteBuffer.java | 7 +- .../nms/v1_18_R1/PacketByteBuffer.java | 7 +- .../nms/v1_18_R2/PacketByteBuffer.java | 7 +- .../nms/v1_19_R1/PacketByteBuffer.java | 7 +- .../nms/v1_19_R2/PacketByteBuffer.java | 7 +- .../nms/v1_19_R3/PacketByteBuffer.java | 7 +- .../nms/v1_20_R1/PacketByteBuffer.java | 7 +- .../nms/v1_20_R2/PacketByteBuffer.java | 7 +- .../nms/v1_20_R3/PacketByteBuffer.java | 7 +- .../nms/v1_8_R3/PacketByteBuffer.java | 7 +- .../nms/v1_9_R2/PacketByteBuffer.java | 7 +- 26 files changed, 248 insertions(+), 93 deletions(-) create mode 100644 core/src/main/java/me/filoghost/holographicdisplays/core/tracking/PacketSenderExecutor.java diff --git a/core/src/main/java/me/filoghost/holographicdisplays/core/HolographicDisplaysCore.java b/core/src/main/java/me/filoghost/holographicdisplays/core/HolographicDisplaysCore.java index 485c4dab..ac5d6339 100644 --- a/core/src/main/java/me/filoghost/holographicdisplays/core/HolographicDisplaysCore.java +++ b/core/src/main/java/me/filoghost/holographicdisplays/core/HolographicDisplaysCore.java @@ -24,6 +24,7 @@ import me.filoghost.holographicdisplays.core.placeholder.tracking.ActivePlacehol import me.filoghost.holographicdisplays.core.tick.TickClock; import me.filoghost.holographicdisplays.core.tick.TickingTask; import me.filoghost.holographicdisplays.core.tracking.LineTrackerManager; +import me.filoghost.holographicdisplays.core.tracking.PacketSenderExecutor; import me.filoghost.holographicdisplays.nms.common.NMSManager; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -47,6 +48,8 @@ public class HolographicDisplaysCore { throw new PluginEnableException(t, "Couldn't initialize the NMS manager."); } + PacketSenderExecutor.start(); + PlaceholderRegistry placeholderRegistry = new PlaceholderRegistry(); TickClock tickClock = new TickClock(); ActivePlaceholderTracker placeholderTracker = new ActivePlaceholderTracker(placeholderRegistry, tickClock); @@ -103,6 +106,8 @@ public class HolographicDisplaysCore { nmsManager.uninjectPacketListener(player); } } + + PacketSenderExecutor.stopGracefully(); } } diff --git a/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/ClickableLineTracker.java b/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/ClickableLineTracker.java index 4773ffb4..d2a06016 100644 --- a/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/ClickableLineTracker.java +++ b/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/ClickableLineTracker.java @@ -85,7 +85,11 @@ public abstract class ClickableLineTracker extends LineTracker @Override protected void sendSpawnPackets(Viewers viewers) { if (spawnClickableEntity) { - viewers.sendPackets(clickableEntity.newSpawnPackets(getClickableEntityPosition())); + // Copy for async use + PositionCoordinates clickableEntityPosition = getClickableEntityPosition(); + PacketSenderExecutor.execute(() -> { + viewers.sendPackets(clickableEntity.newSpawnPackets(clickableEntityPosition)); + }); } } @@ -93,7 +97,9 @@ public abstract class ClickableLineTracker extends LineTracker @Override protected void sendDestroyPackets(Viewers viewers) { if (spawnClickableEntity) { - viewers.sendPackets(clickableEntity.newDestroyPackets()); + PacketSenderExecutor.execute(() -> { + viewers.sendPackets(clickableEntity.newDestroyPackets()); + }); } } @@ -104,9 +110,15 @@ public abstract class ClickableLineTracker extends LineTracker if (spawnClickableEntityChanged) { if (spawnClickableEntity) { - viewers.sendPackets(clickableEntity.newSpawnPackets(getClickableEntityPosition())); + // Copy for async use + PositionCoordinates clickableEntityPosition = getClickableEntityPosition(); + PacketSenderExecutor.execute(() -> { + viewers.sendPackets(clickableEntity.newSpawnPackets(clickableEntityPosition)); + }); } else { - viewers.sendPackets(clickableEntity.newDestroyPackets()); + PacketSenderExecutor.execute(() -> { + viewers.sendPackets(clickableEntity.newDestroyPackets()); + }); } } } @@ -115,7 +127,11 @@ public abstract class ClickableLineTracker extends LineTracker @Override protected void sendPositionChangePackets(Viewers viewers) { if (spawnClickableEntity) { - viewers.sendPackets(clickableEntity.newTeleportPackets(getClickableEntityPosition())); + // Copy for async use + PositionCoordinates clickableEntityPosition = getClickableEntityPosition(); + PacketSenderExecutor.execute(() -> { + viewers.sendPackets(clickableEntity.newTeleportPackets(clickableEntityPosition)); + }); } } diff --git a/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/ItemLineTracker.java b/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/ItemLineTracker.java index 79feff59..7f553f1a 100644 --- a/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/ItemLineTracker.java +++ b/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/ItemLineTracker.java @@ -5,6 +5,7 @@ */ package me.filoghost.holographicdisplays.core.tracking; +import me.filoghost.holographicdisplays.common.PositionCoordinates; import me.filoghost.holographicdisplays.core.base.BaseItemHologramLine; import me.filoghost.holographicdisplays.core.listener.LineClickListener; import me.filoghost.holographicdisplays.core.tick.CachedPlayer; @@ -106,7 +107,12 @@ public class ItemLineTracker extends ClickableLineTracker { super.sendSpawnPackets(viewers); if (spawnItemEntity) { - viewers.sendPackets(itemEntity.newSpawnPackets(positionCoordinates, itemStack)); + // Copy for async use + PositionCoordinates positionCoordinates = this.positionCoordinates; + ItemStack itemStack = this.itemStack; + PacketSenderExecutor.execute(() -> { + viewers.sendPackets(itemEntity.newSpawnPackets(positionCoordinates, itemStack)); + }); } } @@ -116,7 +122,9 @@ public class ItemLineTracker extends ClickableLineTracker { super.sendDestroyPackets(viewers); if (spawnItemEntity) { - viewers.sendPackets(itemEntity.newDestroyPackets()); + PacketSenderExecutor.execute(() -> { + viewers.sendPackets(itemEntity.newDestroyPackets()); + }); } } @@ -127,13 +135,24 @@ public class ItemLineTracker extends ClickableLineTracker { if (spawnItemEntityChanged) { if (spawnItemEntity) { - viewers.sendPackets(itemEntity.newSpawnPackets(positionCoordinates, itemStack)); + // Copy for async use + PositionCoordinates positionCoordinates = this.positionCoordinates; + ItemStack itemStack = this.itemStack; + PacketSenderExecutor.execute(() -> { + viewers.sendPackets(itemEntity.newSpawnPackets(positionCoordinates, itemStack)); + }); } else { - viewers.sendPackets(itemEntity.newDestroyPackets()); + PacketSenderExecutor.execute(() -> { + viewers.sendPackets(itemEntity.newDestroyPackets()); + }); } } else if (itemStackChanged) { // Only send item changes if full spawn/destroy packets were not sent - viewers.sendPackets(itemEntity.newChangePackets(itemStack)); + // Copy for async use + ItemStack itemStack = this.itemStack; + PacketSenderExecutor.execute(() -> { + viewers.sendPackets(itemEntity.newChangePackets(itemStack)); + }); } } @@ -143,7 +162,11 @@ public class ItemLineTracker extends ClickableLineTracker { super.sendPositionChangePackets(viewers); if (spawnItemEntity) { - viewers.sendPackets(itemEntity.newTeleportPackets(positionCoordinates)); + // Copy for async use + PositionCoordinates positionCoordinates = this.positionCoordinates; + PacketSenderExecutor.execute(() -> { + viewers.sendPackets(itemEntity.newTeleportPackets(positionCoordinates)); + }); } } diff --git a/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/LineTracker.java b/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/LineTracker.java index 3c8c8af8..5ac3e470 100644 --- a/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/LineTracker.java +++ b/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/LineTracker.java @@ -14,14 +14,14 @@ import org.bukkit.entity.Player; import org.jetbrains.annotations.MustBeInvokedByOverriders; import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Objects; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; public abstract class LineTracker { - private final Map viewers; + private final ConcurrentMap viewers; private final Viewers iterableViewers; private String positionWorldName; @@ -32,7 +32,7 @@ public abstract class LineTracker { private int lastVisibilitySettingsVersion; protected LineTracker() { - this.viewers = new HashMap<>(); + this.viewers = new ConcurrentHashMap<>(); this.iterableViewers = new DelegateViewers<>(viewers.values()); } diff --git a/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/MutableViewers.java b/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/MutableViewers.java index a730dc90..1511da7d 100644 --- a/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/MutableViewers.java +++ b/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/MutableViewers.java @@ -15,7 +15,7 @@ public class MutableViewers implements Viewers { private T viewer; private List additionalViewers; - public void add(T viewer) { + public synchronized void add(T viewer) { if (this.viewer == null) { this.viewer = viewer; } else { @@ -27,7 +27,7 @@ public class MutableViewers implements Viewers { } @Override - public void forEach(Consumer action) { + public synchronized void forEach(Consumer action) { if (viewer != null) { action.accept(viewer); if (additionalViewers != null) { diff --git a/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/PacketSenderExecutor.java b/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/PacketSenderExecutor.java new file mode 100644 index 00000000..27061055 --- /dev/null +++ b/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/PacketSenderExecutor.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) filoghost and contributors + * + * SPDX-License-Identifier: GPL-3.0-or-later + */ +package me.filoghost.holographicdisplays.core.tracking; + +import me.filoghost.fcommons.logging.Log; + +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; + +/** + * This is a quick but ugly helper class for creating and sending packets async. + * Static classes like this should be avoided. + */ +public class PacketSenderExecutor { + + private static volatile BlockingQueue tasks; + private static volatile Thread thread; + + private static final Runnable STOP_MARKER_TASK = () -> {}; + + static { + tasks = new LinkedBlockingQueue<>(); + thread = new Thread(() -> { + while (true) { + try { + Runnable task = tasks.take(); + task.run(); + } catch (Throwable t) { + Log.severe("Error in packet sender task", t); + } + } + }); + thread.setName("Holographic Displays async packets"); + thread.start(); + } + + public static void execute(Runnable task) { + tasks.add(task); + } + + public static void start() { + tasks = new LinkedBlockingQueue<>(); + thread = new Thread(() -> { + while (true) { + try { + Runnable task = tasks.take(); + if (task == STOP_MARKER_TASK) { + return; + } + task.run(); + } catch (Throwable t) { + Log.severe("Error in packet sender task", t); + } + } + }); + thread.setName("Holographic Displays packet sender"); + thread.start(); + } + + public static void stopGracefully() { + if (tasks != null) { + tasks.add(STOP_MARKER_TASK); + } + } + +} diff --git a/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/TextLineTracker.java b/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/TextLineTracker.java index 323383cf..0b0093e3 100644 --- a/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/TextLineTracker.java +++ b/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/TextLineTracker.java @@ -5,6 +5,7 @@ */ package me.filoghost.holographicdisplays.core.tracking; +import me.filoghost.holographicdisplays.common.PositionCoordinates; import me.filoghost.holographicdisplays.core.base.BaseTextHologramLine; import me.filoghost.holographicdisplays.core.listener.LineClickListener; import me.filoghost.holographicdisplays.core.placeholder.tracking.ActivePlaceholderTracker; @@ -84,15 +85,22 @@ public class TextLineTracker extends ClickableLineTracker { protected void sendSpawnPackets(Viewers viewers) { super.sendSpawnPackets(viewers); - IndividualTextPacketGroup spawnPackets = textEntity.newSpawnPackets(positionCoordinates); - viewers.forEach(viewer -> viewer.sendTextPackets(spawnPackets)); + // Copy for async use + PositionCoordinates positionCoordinates = this.positionCoordinates; + viewers.forEach(TextLineViewer::updateNextTextToSend); + PacketSenderExecutor.execute(() -> { + IndividualTextPacketGroup spawnPackets = textEntity.newSpawnPackets(positionCoordinates); + viewers.forEach(viewer -> viewer.sendTextPackets(spawnPackets)); + }); } @MustBeInvokedByOverriders @Override protected void sendDestroyPackets(Viewers viewers) { super.sendDestroyPackets(viewers); - viewers.sendPackets(textEntity.newDestroyPackets()); + PacketSenderExecutor.execute(() -> { + viewers.sendPackets(textEntity.newDestroyPackets()); + }); } @Override @@ -100,8 +108,11 @@ public class TextLineTracker extends ClickableLineTracker { super.sendChangesPackets(viewers); if (displayTextChanged) { - IndividualTextPacketGroup changePackets = textEntity.newChangePackets(); - viewers.forEach(viewer -> viewer.sendTextPacketsIfNecessary(changePackets)); + viewers.forEach(TextLineViewer::updateNextTextToSend); + PacketSenderExecutor.execute(() -> { + IndividualTextPacketGroup changePackets = textEntity.newChangePackets(); + viewers.forEach(viewer -> viewer.sendTextPacketsIfNecessary(changePackets)); + }); } } @@ -109,7 +120,11 @@ public class TextLineTracker extends ClickableLineTracker { @Override protected void sendPositionChangePackets(Viewers viewers) { super.sendPositionChangePackets(viewers); - viewers.sendPackets(textEntity.newTeleportPackets(positionCoordinates)); + // Copy for async use + PositionCoordinates positionCoordinates = this.positionCoordinates; + PacketSenderExecutor.execute(() -> { + viewers.sendPackets(textEntity.newTeleportPackets(positionCoordinates)); + }); } @Override diff --git a/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/TextLineViewer.java b/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/TextLineViewer.java index 960fc55e..db6f5ba2 100644 --- a/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/TextLineViewer.java +++ b/core/src/main/java/me/filoghost/holographicdisplays/core/tracking/TextLineViewer.java @@ -5,9 +5,8 @@ */ package me.filoghost.holographicdisplays.core.tracking; -import me.filoghost.holographicdisplays.nms.common.IndividualTextPacketGroup; import me.filoghost.holographicdisplays.core.tick.CachedPlayer; -import org.jetbrains.annotations.Nullable; +import me.filoghost.holographicdisplays.nms.common.IndividualTextPacketGroup; import java.util.Objects; @@ -15,8 +14,10 @@ class TextLineViewer extends Viewer { private final DisplayText displayText; + // Access to these variables must be synchronized, they are accessed from multiple threads private String individualText; private String lastSentText; + private String nextTextToSend; TextLineViewer(CachedPlayer player, DisplayText displayText) { super(player); @@ -24,39 +25,47 @@ class TextLineViewer extends Viewer { } public void sendTextPackets(IndividualTextPacketGroup packets) { - String text = getOrComputeText(); - this.lastSentText = text; + String text; + synchronized (this) { + text = nextTextToSend; + this.lastSentText = text; + } sendIndividualPackets(packets, text); } public void sendTextPacketsIfNecessary(IndividualTextPacketGroup packets) { - String text = getOrComputeText(); - if (Objects.equals(lastSentText, text)) { - return; // Avoid sending unnecessary packets + String text; + synchronized (this) { + text = nextTextToSend; + if (Objects.equals(lastSentText, text)) { + return; // Avoid sending unnecessary packets + } + this.lastSentText = text; } - this.lastSentText = text; sendIndividualPackets(packets, text); } - private @Nullable String getOrComputeText() { + public synchronized void updateNextTextToSend() { if (displayText.containsIndividualPlaceholders()) { if (individualText == null) { individualText = displayText.computeIndividualText(this); } - return individualText; + nextTextToSend = individualText; } else { individualText = null; - return displayText.getGlobalText(); + nextTextToSend = displayText.getGlobalText(); } } public boolean updateIndividualText() { String individualText = displayText.computeIndividualText(this); - if (!Objects.equals(this.individualText, individualText)) { - this.individualText = individualText; - return true; - } else { - return false; + synchronized (this) { + if (!Objects.equals(this.individualText, individualText)) { + this.individualText = individualText; + return true; + } else { + return false; + } } } diff --git a/nms/v1_10_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_10_R1/PacketByteBuffer.java b/nms/v1_10_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_10_R1/PacketByteBuffer.java index 246681ab..0fb684dd 100644 --- a/nms/v1_10_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_10_R1/PacketByteBuffer.java +++ b/nms/v1_10_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_10_R1/PacketByteBuffer.java @@ -14,13 +14,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() { diff --git a/nms/v1_11_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_11_R1/PacketByteBuffer.java b/nms/v1_11_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_11_R1/PacketByteBuffer.java index 3a6aa0eb..d1d1d040 100644 --- a/nms/v1_11_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_11_R1/PacketByteBuffer.java +++ b/nms/v1_11_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_11_R1/PacketByteBuffer.java @@ -14,13 +14,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() { diff --git a/nms/v1_12_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_12_R1/PacketByteBuffer.java b/nms/v1_12_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_12_R1/PacketByteBuffer.java index 0eb7eb0d..05460475 100644 --- a/nms/v1_12_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_12_R1/PacketByteBuffer.java +++ b/nms/v1_12_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_12_R1/PacketByteBuffer.java @@ -14,13 +14,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() { diff --git a/nms/v1_13_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_13_R2/PacketByteBuffer.java b/nms/v1_13_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_13_R2/PacketByteBuffer.java index b80d88eb..3c33614a 100644 --- a/nms/v1_13_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_13_R2/PacketByteBuffer.java +++ b/nms/v1_13_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_13_R2/PacketByteBuffer.java @@ -14,13 +14,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() { diff --git a/nms/v1_14_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_14_R1/PacketByteBuffer.java b/nms/v1_14_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_14_R1/PacketByteBuffer.java index 348473cb..7cac05e2 100644 --- a/nms/v1_14_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_14_R1/PacketByteBuffer.java +++ b/nms/v1_14_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_14_R1/PacketByteBuffer.java @@ -14,13 +14,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() { diff --git a/nms/v1_15_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_15_R1/PacketByteBuffer.java b/nms/v1_15_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_15_R1/PacketByteBuffer.java index a49ff050..17a16f73 100644 --- a/nms/v1_15_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_15_R1/PacketByteBuffer.java +++ b/nms/v1_15_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_15_R1/PacketByteBuffer.java @@ -14,13 +14,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() { diff --git a/nms/v1_16_r3/src/main/java/me/filoghost/holographicdisplays/nms/v1_16_R3/PacketByteBuffer.java b/nms/v1_16_r3/src/main/java/me/filoghost/holographicdisplays/nms/v1_16_R3/PacketByteBuffer.java index d7c9d01c..7ebd9ae2 100644 --- a/nms/v1_16_r3/src/main/java/me/filoghost/holographicdisplays/nms/v1_16_R3/PacketByteBuffer.java +++ b/nms/v1_16_r3/src/main/java/me/filoghost/holographicdisplays/nms/v1_16_R3/PacketByteBuffer.java @@ -14,13 +14,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } void writeBoolean(boolean flag) { diff --git a/nms/v1_17_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_17_R1/PacketByteBuffer.java b/nms/v1_17_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_17_R1/PacketByteBuffer.java index 3937c0de..d37c5686 100644 --- a/nms/v1_17_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_17_R1/PacketByteBuffer.java +++ b/nms/v1_17_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_17_R1/PacketByteBuffer.java @@ -12,13 +12,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() { diff --git a/nms/v1_18_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_18_R1/PacketByteBuffer.java b/nms/v1_18_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_18_R1/PacketByteBuffer.java index 756a018c..661c8659 100644 --- a/nms/v1_18_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_18_R1/PacketByteBuffer.java +++ b/nms/v1_18_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_18_R1/PacketByteBuffer.java @@ -12,13 +12,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() { diff --git a/nms/v1_18_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_18_R2/PacketByteBuffer.java b/nms/v1_18_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_18_R2/PacketByteBuffer.java index 47641c29..573c46fb 100644 --- a/nms/v1_18_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_18_R2/PacketByteBuffer.java +++ b/nms/v1_18_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_18_R2/PacketByteBuffer.java @@ -12,13 +12,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() { diff --git a/nms/v1_19_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_19_R1/PacketByteBuffer.java b/nms/v1_19_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_19_R1/PacketByteBuffer.java index a7cd14c4..c3bf6a7e 100644 --- a/nms/v1_19_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_19_R1/PacketByteBuffer.java +++ b/nms/v1_19_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_19_R1/PacketByteBuffer.java @@ -12,13 +12,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() { diff --git a/nms/v1_19_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_19_R2/PacketByteBuffer.java b/nms/v1_19_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_19_R2/PacketByteBuffer.java index a554a794..9fbbf810 100644 --- a/nms/v1_19_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_19_R2/PacketByteBuffer.java +++ b/nms/v1_19_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_19_R2/PacketByteBuffer.java @@ -12,13 +12,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() { diff --git a/nms/v1_19_r3/src/main/java/me/filoghost/holographicdisplays/nms/v1_19_R3/PacketByteBuffer.java b/nms/v1_19_r3/src/main/java/me/filoghost/holographicdisplays/nms/v1_19_R3/PacketByteBuffer.java index 74b3ab41..89cf3825 100644 --- a/nms/v1_19_r3/src/main/java/me/filoghost/holographicdisplays/nms/v1_19_R3/PacketByteBuffer.java +++ b/nms/v1_19_r3/src/main/java/me/filoghost/holographicdisplays/nms/v1_19_R3/PacketByteBuffer.java @@ -12,13 +12,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() { diff --git a/nms/v1_20_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_20_R1/PacketByteBuffer.java b/nms/v1_20_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_20_R1/PacketByteBuffer.java index 93cdca7b..e3712153 100644 --- a/nms/v1_20_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_20_R1/PacketByteBuffer.java +++ b/nms/v1_20_r1/src/main/java/me/filoghost/holographicdisplays/nms/v1_20_R1/PacketByteBuffer.java @@ -12,13 +12,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() { diff --git a/nms/v1_20_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_20_R2/PacketByteBuffer.java b/nms/v1_20_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_20_R2/PacketByteBuffer.java index 541582db..967e71b5 100644 --- a/nms/v1_20_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_20_R2/PacketByteBuffer.java +++ b/nms/v1_20_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_20_R2/PacketByteBuffer.java @@ -12,13 +12,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() { diff --git a/nms/v1_20_r3/src/main/java/me/filoghost/holographicdisplays/nms/v1_20_R3/PacketByteBuffer.java b/nms/v1_20_r3/src/main/java/me/filoghost/holographicdisplays/nms/v1_20_R3/PacketByteBuffer.java index 68284077..67b3dfd2 100644 --- a/nms/v1_20_r3/src/main/java/me/filoghost/holographicdisplays/nms/v1_20_R3/PacketByteBuffer.java +++ b/nms/v1_20_r3/src/main/java/me/filoghost/holographicdisplays/nms/v1_20_R3/PacketByteBuffer.java @@ -12,13 +12,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() { diff --git a/nms/v1_8_r3/src/main/java/me/filoghost/holographicdisplays/nms/v1_8_R3/PacketByteBuffer.java b/nms/v1_8_r3/src/main/java/me/filoghost/holographicdisplays/nms/v1_8_R3/PacketByteBuffer.java index 83841763..58c69ddc 100644 --- a/nms/v1_8_r3/src/main/java/me/filoghost/holographicdisplays/nms/v1_8_R3/PacketByteBuffer.java +++ b/nms/v1_8_r3/src/main/java/me/filoghost/holographicdisplays/nms/v1_8_R3/PacketByteBuffer.java @@ -14,13 +14,14 @@ import java.io.IOException; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() { diff --git a/nms/v1_9_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_9_R2/PacketByteBuffer.java b/nms/v1_9_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_9_R2/PacketByteBuffer.java index e7d8bb6c..27886a51 100644 --- a/nms/v1_9_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_9_R2/PacketByteBuffer.java +++ b/nms/v1_9_r2/src/main/java/me/filoghost/holographicdisplays/nms/v1_9_R2/PacketByteBuffer.java @@ -14,13 +14,14 @@ import java.util.UUID; class PacketByteBuffer { - private static final PacketByteBuffer INSTANCE = new PacketByteBuffer(); + private static final ThreadLocal LOCAL_INSTANCE = ThreadLocal.withInitial(PacketByteBuffer::new); private final PacketDataSerializer serializer; static PacketByteBuffer get() { - INSTANCE.clear(); - return INSTANCE; + PacketByteBuffer instance = LOCAL_INSTANCE.get(); + instance.clear(); + return instance; } private PacketByteBuffer() {