Compare commits
36 Commits
Author | SHA1 | Date |
---|---|---|
filoghost | 6f343c5fc0 | |
filoghost | 9dcf6035fe | |
filoghost | 0754e0ac33 | |
filoghost | ed3bbad1fb | |
filoghost | 667668f0f0 | |
filoghost | c14141679f | |
filoghost | 563df95561 | |
Spongecade | 3f067145b7 | |
rayanbzd | 9fd3bf2d0f | |
rayanbzd | 0b289b017b | |
filoghost | 07968520f0 | |
filoghost | 51fc2d0bd4 | |
filoghost | 5d22e2754d | |
Sascha Bartl | a3c82bfddf | |
filoghost | 2fa71ad3e0 | |
filoghost | 917db5ad94 | |
filoghost | 705abee6a3 | |
filoghost | 3727868dff | |
filoghost | fab8c9594d | |
filoghost | ef890acacd | |
filoghost | 2b5afc82af | |
filoghost | d057dd750c | |
filoghost | 27ebb9d2d8 | |
filoghost | 70779348af | |
filoghost | dd1f6f024d | |
filoghost | 5d2c97f194 | |
filoghost | 788cdc2c45 | |
filoghost | a5d9f58df3 | |
filoghost | 850beaebb8 | |
filoghost | 2f83fdcfdb | |
filoghost | 39e51328cc | |
filoghost | 017b0a2346 | |
filoghost | 80344c8503 | |
filoghost | 39f0a02412 | |
filoghost | 0e98b2f89a | |
filoghost | 0449fe65ca |
|
@ -1,16 +0,0 @@
|
|||
name: 💡 Suggestion
|
||||
description: "Suggest a new feature or an improvement."
|
||||
labels:
|
||||
- "Enhancement"
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |-
|
||||
Please suggest changes that would benefit as many users as possible, not just specific situations. Thank you for contributing to the project.
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Description"
|
||||
description: "Describe the new feature or improvement."
|
||||
validations:
|
||||
required: true
|
|
@ -1,42 +0,0 @@
|
|||
name: 📝 Help request
|
||||
description: "Ask a question."
|
||||
labels:
|
||||
- "Help"
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |-
|
||||
Please make sure you are using a recent version of the plugin.
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: "Confirmation"
|
||||
description: "Please confirm to have done the following checks before opening a new issue."
|
||||
options:
|
||||
- label: "I have read the [documentation](https://filoghost.me/docs/holographic-displays)."
|
||||
required: true
|
||||
- label: "I have read the [FAQ](https://filoghost.me/docs/holographic-displays/faq)."
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Description"
|
||||
description: "Describe your goal and what you have tried so far."
|
||||
placeholder: "What are you trying to achieve? What have you tried so far?"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
attributes:
|
||||
label: "Holographic Displays version"
|
||||
description: "Output of the command `/version HolographicDisplays`."
|
||||
placeholder: "HolographicDisplays version 2.4.8-SNAPSHOT-b174"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional information
|
||||
description: |-
|
||||
Relevant attachments such as **screenshots**, **server logs**, **configurations files** or any other additional information that might be useful.
|
||||
Text files can also be uploaded to [Pastebin](https://pastebin.com) and shared through the generated link.
|
|
@ -1,16 +0,0 @@
|
|||
name: 📚 Documentation improvement
|
||||
description: "Suggest a change or report an error to improve the official documentation."
|
||||
labels:
|
||||
- "Documentation"
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |-
|
||||
Suggest a change or report an error to improve the official documentation. Thank you for contributing to the project.
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: "Description"
|
||||
description: "Describe what should be improved and, if possible, _how_."
|
||||
validations:
|
||||
required: true
|
|
@ -17,9 +17,9 @@ Development Builds: https://ci.codemc.io/job/filoghost/job/HolographicDisplays
|
|||
|
||||
```xml
|
||||
<dependency>
|
||||
<groupId>com.gmail.filoghost.holographicdisplays</groupId>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-api</artifactId>
|
||||
<version>2.4.9</version>
|
||||
<version>3.0.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
```
|
||||
|
@ -32,7 +32,7 @@ maven {
|
|||
```
|
||||
|
||||
```groovy
|
||||
compileOnly 'com.gmail.filoghost.holographicdisplays:holographicdisplays-api:2.4.9'
|
||||
compileOnly 'me.filoghost.holographicdisplays:holographicdisplays-api:3.0.0'
|
||||
```
|
||||
|
||||
## License
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-parent</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-api</artifactId>
|
||||
|
|
|
@ -125,7 +125,6 @@
|
|||
|
||||
<!-- Miscellaneous -->
|
||||
<module name="ArrayTypeStyle"/>
|
||||
<module name="AvoidEscapedUnicodeCharacters"/>
|
||||
<module name="CommentsIndentation"/>
|
||||
<module name="Indentation">
|
||||
<property name="basicOffset" value="4"/>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-parent</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-common</artifactId>
|
||||
|
|
37
core/pom.xml
37
core/pom.xml
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-parent</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-core</artifactId>
|
||||
|
@ -74,16 +74,6 @@
|
|||
<artifactId>holographicdisplays-nms-v1_15_r1</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>holographicdisplays-nms-v1_16_r1</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>holographicdisplays-nms-v1_16_r2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>holographicdisplays-nms-v1_16_r3</artifactId>
|
||||
|
@ -109,6 +99,31 @@
|
|||
<artifactId>holographicdisplays-nms-v1_19_r1</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>holographicdisplays-nms-v1_19_r2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>holographicdisplays-nms-v1_19_r3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>holographicdisplays-nms-v1_20_r1</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>holographicdisplays-nms-v1_20_r2</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>holographicdisplays-nms-v1_20_r3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* Copyright (C) filoghost and contributors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
package me.filoghost.holographicdisplays.core;
|
||||
|
||||
public class CoreGlobalConfig {
|
||||
|
||||
public static double spaceBetweenLines;
|
||||
public static int maxViewRange;
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* Copyright (C) filoghost and contributors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
package me.filoghost.holographicdisplays.core;
|
||||
|
||||
import me.filoghost.fcommons.Preconditions;
|
||||
|
||||
public class CorePreconditions {
|
||||
|
||||
public static void checkMainThread() {
|
||||
Preconditions.checkMainThread("async operation is not supported");
|
||||
}
|
||||
|
||||
}
|
|
@ -16,7 +16,6 @@ import me.filoghost.holographicdisplays.core.api.current.DefaultHolographicDispl
|
|||
import me.filoghost.holographicdisplays.core.api.v2.V2HologramManager;
|
||||
import me.filoghost.holographicdisplays.core.api.v2.V2HologramsAPIProvider;
|
||||
import me.filoghost.holographicdisplays.core.base.BaseHologram;
|
||||
import me.filoghost.holographicdisplays.core.base.BaseHologramLines;
|
||||
import me.filoghost.holographicdisplays.core.listener.ChunkListener;
|
||||
import me.filoghost.holographicdisplays.core.listener.LineClickListener;
|
||||
import me.filoghost.holographicdisplays.core.listener.PlayerListener;
|
||||
|
@ -25,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;
|
||||
|
@ -41,13 +41,15 @@ public class HolographicDisplaysCore {
|
|||
try {
|
||||
nmsManager = NMSVersion.getCurrent().createNMSManager(errorCollector);
|
||||
} catch (UnknownVersionException e) {
|
||||
throw new PluginEnableException("Holographic Displays only supports Spigot from 1.8 to 1.18.2.");
|
||||
throw new PluginEnableException("Holographic Displays only supports Spigot from 1.8 to 1.20.");
|
||||
} catch (OutdatedVersionException e) {
|
||||
throw new PluginEnableException("Holographic Displays only supports " + e.getMinimumSupportedVersion() + " and above.");
|
||||
} catch (Throwable t) {
|
||||
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);
|
||||
|
@ -81,7 +83,7 @@ public class HolographicDisplaysCore {
|
|||
}
|
||||
|
||||
public void setSpaceBetweenHologramLines(double spaceBetweenLines) {
|
||||
BaseHologramLines.spaceBetweenLines = spaceBetweenLines;
|
||||
CoreGlobalConfig.spaceBetweenLines = spaceBetweenLines;
|
||||
for (BaseHologram hologram : apiHologramManager.getHolograms()) {
|
||||
hologram.getLines().updatePositions();
|
||||
}
|
||||
|
@ -90,6 +92,10 @@ public class HolographicDisplaysCore {
|
|||
}
|
||||
}
|
||||
|
||||
public void setMaxViewRange(int maxViewRange) {
|
||||
CoreGlobalConfig.maxViewRange = maxViewRange;
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
if (lineTrackerManager != null) {
|
||||
lineTrackerManager.resetViewersAndSendDestroyPackets();
|
||||
|
@ -100,6 +106,8 @@ public class HolographicDisplaysCore {
|
|||
nmsManager.uninjectPacketListener(player);
|
||||
}
|
||||
}
|
||||
|
||||
PacketSenderExecutor.stopGracefully();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,13 +32,18 @@ public enum NMSVersion {
|
|||
/* 1.13.1 - 1.13.2 */ v1_13_R2(errorCollector -> new me.filoghost.holographicdisplays.nms.v1_13_R2.VersionNMSManager(errorCollector)),
|
||||
/* 1.14 - 1.14.4 */ v1_14_R1(errorCollector -> new me.filoghost.holographicdisplays.nms.v1_14_R1.VersionNMSManager(errorCollector)),
|
||||
/* 1.15 - 1.15.2 */ v1_15_R1(errorCollector -> new me.filoghost.holographicdisplays.nms.v1_15_R1.VersionNMSManager(errorCollector)),
|
||||
/* 1.16 - 1.16.1 */ v1_16_R1(errorCollector -> new me.filoghost.holographicdisplays.nms.v1_16_R1.VersionNMSManager(errorCollector)),
|
||||
/* 1.16.2 - 1.16.3 */ v1_16_R2(errorCollector -> new me.filoghost.holographicdisplays.nms.v1_16_R2.VersionNMSManager(errorCollector)),
|
||||
/* 1.16 - 1.16.1 */ v1_16_R1(NMSManagerFactory.outdatedVersion("1.16.4")),
|
||||
/* 1.16.2 - 1.16.3 */ v1_16_R2(NMSManagerFactory.outdatedVersion("1.16.4")),
|
||||
/* 1.16.4 - 1.16.5 */ v1_16_R3(errorCollector -> new me.filoghost.holographicdisplays.nms.v1_16_R3.VersionNMSManager(errorCollector)),
|
||||
/* 1.17 */ v1_17_R1(errorCollector -> new me.filoghost.holographicdisplays.nms.v1_17_R1.VersionNMSManager(errorCollector)),
|
||||
/* 1.18 - 1.18.1 */ v1_18_R1(errorCollector -> new me.filoghost.holographicdisplays.nms.v1_18_R1.VersionNMSManager(errorCollector)),
|
||||
/* 1.18.2 */ v1_18_R2(errorCollector -> new me.filoghost.holographicdisplays.nms.v1_18_R2.VersionNMSManager(errorCollector)),
|
||||
/* 1.19 - ? */ v1_19_R1(errorCollector -> new me.filoghost.holographicdisplays.nms.v1_19_R1.VersionNMSManager(errorCollector)),
|
||||
/* 1.19 - 1.19.2 */ v1_19_R1(errorCollector -> new me.filoghost.holographicdisplays.nms.v1_19_R1.VersionNMSManager(errorCollector)),
|
||||
/* 1.19.3 */ v1_19_R2(errorCollector -> new me.filoghost.holographicdisplays.nms.v1_19_R2.VersionNMSManager(errorCollector)),
|
||||
/* 1.19.4 */ v1_19_R3(errorCollector -> new me.filoghost.holographicdisplays.nms.v1_19_R3.VersionNMSManager(errorCollector)),
|
||||
/* 1.20 - 1.20.1 */ v1_20_R1(errorCollector -> new me.filoghost.holographicdisplays.nms.v1_20_R1.VersionNMSManager(errorCollector)),
|
||||
/* 1.20.2 */ v1_20_R2(errorCollector -> new me.filoghost.holographicdisplays.nms.v1_20_R2.VersionNMSManager(errorCollector)),
|
||||
/* 1.20.3 - 1.20.4 */ v1_20_R3(errorCollector -> new me.filoghost.holographicdisplays.nms.v1_20_R3.VersionNMSManager(errorCollector)),
|
||||
/* Other versions */ UNKNOWN(NMSManagerFactory.unknownVersion());
|
||||
|
||||
private static final NMSVersion CURRENT_VERSION = detectCurrentVersion();
|
||||
|
|
|
@ -9,6 +9,7 @@ import me.filoghost.fcommons.Preconditions;
|
|||
import me.filoghost.holographicdisplays.api.Position;
|
||||
import me.filoghost.holographicdisplays.api.hologram.Hologram;
|
||||
import me.filoghost.holographicdisplays.api.hologram.PlaceholderSetting;
|
||||
import me.filoghost.holographicdisplays.core.CorePreconditions;
|
||||
import me.filoghost.holographicdisplays.core.base.BaseHologram;
|
||||
import me.filoghost.holographicdisplays.core.base.ImmutablePosition;
|
||||
import me.filoghost.holographicdisplays.core.tracking.LineTrackerManager;
|
||||
|
@ -30,7 +31,7 @@ class APIHologram extends BaseHologram implements Hologram {
|
|||
LineTrackerManager lineTrackerManager) {
|
||||
super(position, lineTrackerManager);
|
||||
Preconditions.notNull(plugin, "plugin");
|
||||
this.lines = new APIHologramLines(this);
|
||||
this.lines = new APIHologramLines(this, lineTrackerManager);
|
||||
this.plugin = plugin;
|
||||
this.hologramManager = hologramManager;
|
||||
this.placeholderSetting = PlaceholderSetting.DEFAULT;
|
||||
|
@ -53,6 +54,7 @@ class APIHologram extends BaseHologram implements Hologram {
|
|||
|
||||
@Override
|
||||
public void setPlaceholderSetting(@NotNull PlaceholderSetting placeholderSetting) {
|
||||
CorePreconditions.checkMainThread();
|
||||
Preconditions.notNull(placeholderSetting, "placeholderSetting");
|
||||
checkNotDeleted();
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import me.filoghost.holographicdisplays.api.hologram.line.HologramLine;
|
|||
import me.filoghost.holographicdisplays.api.hologram.line.ItemHologramLine;
|
||||
import me.filoghost.holographicdisplays.api.hologram.line.TextHologramLine;
|
||||
import me.filoghost.holographicdisplays.core.base.BaseHologramLines;
|
||||
import me.filoghost.holographicdisplays.core.tracking.LineTrackerManager;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
@ -19,8 +20,8 @@ class APIHologramLines extends BaseHologramLines<APIHologramLine> implements Hol
|
|||
|
||||
private final APIHologram hologram;
|
||||
|
||||
APIHologramLines(APIHologram hologram) {
|
||||
super(hologram);
|
||||
APIHologramLines(APIHologram hologram, LineTrackerManager lineTrackerManager) {
|
||||
super(hologram, lineTrackerManager);
|
||||
this.hologram = hologram;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ package me.filoghost.holographicdisplays.core.api.current;
|
|||
import me.filoghost.holographicdisplays.api.hologram.line.HologramLineClickListener;
|
||||
import me.filoghost.holographicdisplays.api.hologram.line.HologramLinePickupListener;
|
||||
import me.filoghost.holographicdisplays.api.hologram.line.ItemHologramLine;
|
||||
import me.filoghost.holographicdisplays.core.CorePreconditions;
|
||||
import me.filoghost.holographicdisplays.core.base.BaseItemHologramLine;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
@ -24,35 +25,39 @@ class APIItemHologramLine extends BaseItemHologramLine implements ItemHologramLi
|
|||
|
||||
@Override
|
||||
public @Nullable HologramLinePickupListener getPickupListener() {
|
||||
CorePreconditions.checkMainThread();
|
||||
return pickupListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPickupListener(@Nullable HologramLinePickupListener pickupListener) {
|
||||
CorePreconditions.checkMainThread();
|
||||
checkNotDeleted();
|
||||
|
||||
this.pickupListener = pickupListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable HologramLineClickListener getClickListener() {
|
||||
return clickListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPickupCallback() {
|
||||
return pickupListener != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void invokePickupCallback(Player player) {
|
||||
protected void invokeExternalPickupCallback(Player player) {
|
||||
if (pickupListener != null) {
|
||||
pickupListener.onPickup(new SimpleHologramLinePickupEvent(player));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable HologramLineClickListener getClickListener() {
|
||||
CorePreconditions.checkMainThread();
|
||||
return clickListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setClickListener(@Nullable HologramLineClickListener clickListener) {
|
||||
CorePreconditions.checkMainThread();
|
||||
checkNotDeleted();
|
||||
|
||||
this.clickListener = clickListener;
|
||||
|
@ -65,7 +70,7 @@ class APIItemHologramLine extends BaseItemHologramLine implements ItemHologramLi
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void invokeClickCallback(Player player) {
|
||||
protected void invokeExternalClickCallback(Player player) {
|
||||
if (clickListener != null) {
|
||||
clickListener.onClick(new SimpleHologramLineClickEvent(player));
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ package me.filoghost.holographicdisplays.core.api.current;
|
|||
import me.filoghost.holographicdisplays.api.hologram.PlaceholderSetting;
|
||||
import me.filoghost.holographicdisplays.api.hologram.line.HologramLineClickListener;
|
||||
import me.filoghost.holographicdisplays.api.hologram.line.TextHologramLine;
|
||||
import me.filoghost.holographicdisplays.core.CorePreconditions;
|
||||
import me.filoghost.holographicdisplays.core.base.BaseTextHologramLine;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
@ -30,6 +31,7 @@ class APITextHologramLine extends BaseTextHologramLine implements TextHologramLi
|
|||
|
||||
@Override
|
||||
public void setClickListener(@Nullable HologramLineClickListener clickListener) {
|
||||
CorePreconditions.checkMainThread();
|
||||
checkNotDeleted();
|
||||
|
||||
this.clickListener = clickListener;
|
||||
|
@ -47,7 +49,7 @@ class APITextHologramLine extends BaseTextHologramLine implements TextHologramLi
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void invokeClickCallback(Player player) {
|
||||
protected void invokeExternalClickCallback(Player player) {
|
||||
if (clickListener != null) {
|
||||
clickListener.onClick(new SimpleHologramLineClickEvent(player));
|
||||
}
|
||||
|
|
|
@ -17,26 +17,20 @@ import org.bukkit.block.Block;
|
|||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.WeakHashMap;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class DefaultHolographicDisplaysAPIProvider extends HolographicDisplaysAPIProvider {
|
||||
|
||||
private final Map<Plugin, HolographicDisplaysAPI> apiCache;
|
||||
private final Function<Plugin, HolographicDisplaysAPI> apiFactory;
|
||||
private final APIHologramManager apiHologramManager;
|
||||
private final PlaceholderRegistry placeholderRegistry;
|
||||
|
||||
public DefaultHolographicDisplaysAPIProvider(APIHologramManager apiHologramManager, PlaceholderRegistry placeholderRegistry) {
|
||||
this.apiCache = new WeakHashMap<>();
|
||||
this.apiFactory = plugin -> new DefaultHolographicDisplaysAPI(plugin, apiHologramManager, placeholderRegistry);
|
||||
this.apiHologramManager = apiHologramManager;
|
||||
this.placeholderRegistry = placeholderRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HolographicDisplaysAPI getHolographicDisplaysAPI(Plugin plugin) {
|
||||
Preconditions.notNull(plugin, "plugin");
|
||||
|
||||
// Optimization: avoid creating a new instance every time a plugin requests it, in case it never stores a reference
|
||||
return apiCache.computeIfAbsent(plugin, apiFactory);
|
||||
return new DefaultHolographicDisplaysAPI(plugin, apiHologramManager, placeholderRegistry);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -37,7 +37,7 @@ class V2Hologram extends BaseHologram implements Hologram {
|
|||
super(position, lineTrackerManager);
|
||||
this.plugin = plugin;
|
||||
this.hologramManager = hologramManager;
|
||||
this.lines = new BaseHologramLines<>(this);
|
||||
this.lines = new BaseHologramLines<>(this, lineTrackerManager);
|
||||
this.visibilityManager = new V2VisibilityManager(getVisibilitySettings());
|
||||
this.creationTimestamp = System.currentTimeMillis();
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ class V2ItemLine extends BaseItemHologramLine implements ItemLine, V2HologramLin
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void invokeClickCallback(Player player) {
|
||||
protected void invokeExternalClickCallback(Player player) {
|
||||
if (touchHandler != null) {
|
||||
touchHandler.onTouch(player);
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ class V2ItemLine extends BaseItemHologramLine implements ItemLine, V2HologramLin
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void invokePickupCallback(Player player) {
|
||||
protected void invokeExternalPickupCallback(Player player) {
|
||||
if (pickupHandler != null) {
|
||||
pickupHandler.onPickup(player);
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ class V2TextLine extends BaseTextHologramLine implements TextLine, V2HologramLin
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void invokeClickCallback(Player player) {
|
||||
protected void invokeExternalClickCallback(Player player) {
|
||||
if (touchHandler != null) {
|
||||
touchHandler.onTouch(player);
|
||||
}
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
package me.filoghost.holographicdisplays.core.base;
|
||||
|
||||
import me.filoghost.fcommons.logging.Log;
|
||||
import me.filoghost.holographicdisplays.common.PositionCoordinates;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public abstract class BaseClickableHologramLine extends BaseHologramLine {
|
||||
|
@ -17,30 +15,16 @@ public abstract class BaseClickableHologramLine extends BaseHologramLine {
|
|||
}
|
||||
|
||||
public void onClick(Player player) {
|
||||
if (hasClickCallback() && canInteract(player) && isInClickRange(player)) {
|
||||
try {
|
||||
invokeClickCallback(player);
|
||||
} catch (Throwable t) {
|
||||
Log.warning("The plugin " + getCreatorPlugin().getName() + " generated an exception"
|
||||
+ " when the player " + player.getName() + " clicked a hologram.", t);
|
||||
}
|
||||
try {
|
||||
invokeExternalClickCallback(player);
|
||||
} catch (Throwable t) {
|
||||
Log.warning("The plugin " + getCreatorPlugin().getName() + " generated an exception"
|
||||
+ " when the player " + player.getName() + " clicked a hologram.", t);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract boolean hasClickCallback();
|
||||
|
||||
protected abstract void invokeClickCallback(Player player);
|
||||
|
||||
private boolean isInClickRange(Player player) {
|
||||
Location playerLocation = player.getLocation();
|
||||
PositionCoordinates positionCoordinates = this.getCoordinates();
|
||||
|
||||
double xDiff = playerLocation.getX() - positionCoordinates.getX();
|
||||
double yDiff = playerLocation.getY() + 1.3 - positionCoordinates.getY(); // Use shoulder height
|
||||
double zDiff = playerLocation.getZ() - positionCoordinates.getZ();
|
||||
|
||||
double distanceSquared = (xDiff * xDiff) + (yDiff * yDiff) + (zDiff * zDiff);
|
||||
return distanceSquared < 5 * 5;
|
||||
}
|
||||
protected abstract void invokeExternalClickCallback(Player player);
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package me.filoghost.holographicdisplays.core.base;
|
||||
|
||||
import me.filoghost.fcommons.Preconditions;
|
||||
import me.filoghost.holographicdisplays.core.CorePreconditions;
|
||||
import me.filoghost.holographicdisplays.core.api.current.DefaultVisibilitySettings;
|
||||
import me.filoghost.holographicdisplays.core.tracking.LineTrackerManager;
|
||||
import org.bukkit.Chunk;
|
||||
|
@ -70,6 +71,7 @@ public abstract class BaseHologram extends BaseHologramComponent {
|
|||
}
|
||||
|
||||
public void setPosition(@NotNull ImmutablePosition position) {
|
||||
CorePreconditions.checkMainThread();
|
||||
Preconditions.notNull(position, "position");
|
||||
checkNotDeleted();
|
||||
|
||||
|
|
|
@ -8,9 +8,6 @@ package me.filoghost.holographicdisplays.core.base;
|
|||
import me.filoghost.fcommons.Preconditions;
|
||||
import me.filoghost.holographicdisplays.common.PositionCoordinates;
|
||||
import me.filoghost.holographicdisplays.core.api.current.DefaultVisibilitySettings;
|
||||
import me.filoghost.holographicdisplays.core.tracking.LineTracker;
|
||||
import me.filoghost.holographicdisplays.core.tracking.LineTrackerManager;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
@ -20,24 +17,30 @@ import org.jetbrains.annotations.Nullable;
|
|||
public abstract class BaseHologramLine extends BaseHologramComponent implements EditableHologramLine {
|
||||
|
||||
private final BaseHologram hologram;
|
||||
private final LineTracker<?> tracker;
|
||||
|
||||
private PositionCoordinates coordinates;
|
||||
|
||||
/**
|
||||
* Flag to indicate that the line has changed in some way and update packets might be necessary.
|
||||
*/
|
||||
private boolean changed;
|
||||
|
||||
protected BaseHologramLine(BaseHologram hologram) {
|
||||
Preconditions.notNull(hologram, "hologram");
|
||||
this.hologram = hologram;
|
||||
this.tracker = createTracker(hologram.getTrackerManager());
|
||||
setChanged(); // Force the initial refresh
|
||||
}
|
||||
|
||||
protected abstract LineTracker<?> createTracker(LineTrackerManager trackerManager);
|
||||
public boolean hasChanged() {
|
||||
return changed;
|
||||
}
|
||||
|
||||
public final void setChanged() {
|
||||
tracker.setLineChanged();
|
||||
changed = true;
|
||||
}
|
||||
|
||||
protected final boolean isViewer(Player player) {
|
||||
return tracker.isViewer(player);
|
||||
public void clearChanged() {
|
||||
changed = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -77,12 +80,4 @@ public abstract class BaseHologramLine extends BaseHologramComponent implements
|
|||
return hologram.getVisibilitySettings();
|
||||
}
|
||||
|
||||
protected boolean canInteract(Player player) {
|
||||
return !isDeleted()
|
||||
&& player.isOnline()
|
||||
&& player.getGameMode() != GameMode.SPECTATOR
|
||||
&& isViewer(player)
|
||||
&& isVisibleTo(player);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,6 +6,9 @@
|
|||
package me.filoghost.holographicdisplays.core.base;
|
||||
|
||||
import me.filoghost.holographicdisplays.api.Position;
|
||||
import me.filoghost.holographicdisplays.core.CoreGlobalConfig;
|
||||
import me.filoghost.holographicdisplays.core.CorePreconditions;
|
||||
import me.filoghost.holographicdisplays.core.tracking.LineTrackerManager;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
@ -15,46 +18,54 @@ import java.util.List;
|
|||
|
||||
public class BaseHologramLines<T extends EditableHologramLine> implements Iterable<T> {
|
||||
|
||||
public static double spaceBetweenLines;
|
||||
|
||||
private final BaseHologram hologram;
|
||||
private final LineTrackerManager lineTrackerManager;
|
||||
private final List<T> lines;
|
||||
private final List<T> unmodifiableLinesView;
|
||||
|
||||
public BaseHologramLines(BaseHologram hologram) {
|
||||
public BaseHologramLines(BaseHologram hologram, LineTrackerManager lineTrackerManager) {
|
||||
this.hologram = hologram;
|
||||
this.lineTrackerManager = lineTrackerManager;
|
||||
this.lines = new ArrayList<>();
|
||||
this.unmodifiableLinesView = Collections.unmodifiableList(lines);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
CorePreconditions.checkMainThread();
|
||||
return unmodifiableLinesView.iterator();
|
||||
}
|
||||
|
||||
public int size() {
|
||||
CorePreconditions.checkMainThread();
|
||||
return lines.size();
|
||||
}
|
||||
|
||||
public @NotNull T get(int index) {
|
||||
CorePreconditions.checkMainThread();
|
||||
return lines.get(index);
|
||||
}
|
||||
|
||||
public void add(T line) {
|
||||
CorePreconditions.checkMainThread();
|
||||
checkNotDeleted();
|
||||
|
||||
lines.add(line);
|
||||
lineTrackerManager.startTracking(line);
|
||||
updatePositions();
|
||||
}
|
||||
|
||||
public void insert(int beforeIndex, T line) {
|
||||
CorePreconditions.checkMainThread();
|
||||
checkNotDeleted();
|
||||
|
||||
lines.add(beforeIndex, line);
|
||||
lineTrackerManager.startTracking(line);
|
||||
updatePositions();
|
||||
}
|
||||
|
||||
public void remove(int index) {
|
||||
CorePreconditions.checkMainThread();
|
||||
checkNotDeleted();
|
||||
|
||||
lines.remove(index).setDeleted();
|
||||
|
@ -62,6 +73,7 @@ public class BaseHologramLines<T extends EditableHologramLine> implements Iterab
|
|||
}
|
||||
|
||||
public boolean remove(T line) {
|
||||
CorePreconditions.checkMainThread();
|
||||
checkNotDeleted();
|
||||
|
||||
boolean removed = lines.remove(line);
|
||||
|
@ -73,6 +85,7 @@ public class BaseHologramLines<T extends EditableHologramLine> implements Iterab
|
|||
}
|
||||
|
||||
public void clear() {
|
||||
CorePreconditions.checkMainThread();
|
||||
checkNotDeleted();
|
||||
|
||||
Iterator<T> iterator = lines.iterator();
|
||||
|
@ -98,7 +111,7 @@ public class BaseHologramLines<T extends EditableHologramLine> implements Iterab
|
|||
|
||||
currentLineY -= line.getHeight();
|
||||
if (i > 0) {
|
||||
currentLineY -= spaceBetweenLines;
|
||||
currentLineY -= CoreGlobalConfig.spaceBetweenLines;
|
||||
}
|
||||
|
||||
line.setCoordinates(hologramPosition.getX(), currentLineY, hologramPosition.getZ());
|
||||
|
@ -106,6 +119,8 @@ public class BaseHologramLines<T extends EditableHologramLine> implements Iterab
|
|||
}
|
||||
|
||||
public double getHeight() {
|
||||
CorePreconditions.checkMainThread();
|
||||
|
||||
if (lines.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -116,7 +131,7 @@ public class BaseHologramLines<T extends EditableHologramLine> implements Iterab
|
|||
height += line.getHeight();
|
||||
}
|
||||
|
||||
height += spaceBetweenLines * (lines.size() - 1);
|
||||
height += CoreGlobalConfig.spaceBetweenLines * (lines.size() - 1);
|
||||
return height;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
package me.filoghost.holographicdisplays.core.base;
|
||||
|
||||
import me.filoghost.fcommons.Preconditions;
|
||||
import me.filoghost.holographicdisplays.core.CorePreconditions;
|
||||
import org.bukkit.Chunk;
|
||||
import org.bukkit.World;
|
||||
|
||||
|
@ -21,7 +21,7 @@ public abstract class BaseHologramManager<H extends BaseHologram> {
|
|||
private final List<H> unmodifiableHologramsView = Collections.unmodifiableList(holograms);
|
||||
|
||||
protected void addHologram(H hologram) {
|
||||
Preconditions.checkMainThread("async hologram create");
|
||||
CorePreconditions.checkMainThread();
|
||||
|
||||
holograms.add(hologram);
|
||||
}
|
||||
|
@ -31,14 +31,14 @@ public abstract class BaseHologramManager<H extends BaseHologram> {
|
|||
}
|
||||
|
||||
public void deleteHologram(H hologram) {
|
||||
Preconditions.checkMainThread("async hologram delete");
|
||||
CorePreconditions.checkMainThread();
|
||||
|
||||
hologram.setDeleted();
|
||||
holograms.remove(hologram);
|
||||
}
|
||||
|
||||
public void deleteHologramsIf(Predicate<H> condition) {
|
||||
Preconditions.checkMainThread("async hologram delete");
|
||||
CorePreconditions.checkMainThread();
|
||||
|
||||
Iterator<H> iterator = holograms.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
|
@ -51,7 +51,7 @@ public abstract class BaseHologramManager<H extends BaseHologram> {
|
|||
}
|
||||
|
||||
public void deleteHolograms() {
|
||||
Preconditions.checkMainThread("async hologram delete");
|
||||
CorePreconditions.checkMainThread();
|
||||
|
||||
Iterator<H> iterator = holograms.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
|
|
|
@ -7,9 +7,8 @@ package me.filoghost.holographicdisplays.core.base;
|
|||
|
||||
import me.filoghost.fcommons.Preconditions;
|
||||
import me.filoghost.fcommons.logging.Log;
|
||||
import me.filoghost.holographicdisplays.core.CorePreconditions;
|
||||
import me.filoghost.holographicdisplays.nms.common.entity.ItemNMSPacketEntity;
|
||||
import me.filoghost.holographicdisplays.core.tracking.ItemLineTracker;
|
||||
import me.filoghost.holographicdisplays.core.tracking.LineTrackerManager;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
@ -23,31 +22,25 @@ public abstract class BaseItemHologramLine extends BaseClickableHologramLine {
|
|||
setItemStack(itemStack);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemLineTracker createTracker(LineTrackerManager trackerManager) {
|
||||
return trackerManager.startTracking(this);
|
||||
}
|
||||
|
||||
public void onPickup(Player player) {
|
||||
if (hasPickupCallback() && canInteract(player)) {
|
||||
try {
|
||||
invokePickupCallback(player);
|
||||
} catch (Throwable t) {
|
||||
Log.warning("The plugin " + getCreatorPlugin().getName() + " generated an exception"
|
||||
+ " when the player " + player.getName() + " picked up an item from a hologram.", t);
|
||||
}
|
||||
try {
|
||||
invokeExternalPickupCallback(player);
|
||||
} catch (Throwable t) {
|
||||
Log.warning("The plugin " + getCreatorPlugin().getName() + " generated an exception"
|
||||
+ " when the player " + player.getName() + " picked up an item from a hologram.", t);
|
||||
}
|
||||
}
|
||||
|
||||
public abstract boolean hasPickupCallback();
|
||||
|
||||
protected abstract void invokePickupCallback(Player player);
|
||||
protected abstract void invokeExternalPickupCallback(Player player);
|
||||
|
||||
public @Nullable ItemStack getItemStack() {
|
||||
return clone(itemStack);
|
||||
}
|
||||
|
||||
public void setItemStack(@Nullable ItemStack itemStack) {
|
||||
CorePreconditions.checkMainThread();
|
||||
checkNotDeleted();
|
||||
|
||||
if (itemStack != null) {
|
||||
|
|
|
@ -5,9 +5,8 @@
|
|||
*/
|
||||
package me.filoghost.holographicdisplays.core.base;
|
||||
|
||||
import me.filoghost.holographicdisplays.core.CorePreconditions;
|
||||
import me.filoghost.holographicdisplays.nms.common.entity.TextNMSPacketEntity;
|
||||
import me.filoghost.holographicdisplays.core.tracking.LineTrackerManager;
|
||||
import me.filoghost.holographicdisplays.core.tracking.TextLineTracker;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public abstract class BaseTextHologramLine extends BaseClickableHologramLine {
|
||||
|
@ -21,16 +20,12 @@ public abstract class BaseTextHologramLine extends BaseClickableHologramLine {
|
|||
|
||||
public abstract boolean isAllowPlaceholders();
|
||||
|
||||
@Override
|
||||
protected TextLineTracker createTracker(LineTrackerManager trackerManager) {
|
||||
return trackerManager.startTracking(this);
|
||||
}
|
||||
|
||||
public @Nullable String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(@Nullable String text) {
|
||||
CorePreconditions.checkMainThread();
|
||||
checkNotDeleted();
|
||||
|
||||
this.text = text;
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
*/
|
||||
package me.filoghost.holographicdisplays.core.listener;
|
||||
|
||||
import me.filoghost.holographicdisplays.core.tracking.ClickableLineTracker;
|
||||
import me.filoghost.holographicdisplays.nms.common.EntityID;
|
||||
import me.filoghost.holographicdisplays.nms.common.PacketListener;
|
||||
import me.filoghost.holographicdisplays.core.base.BaseClickableHologramLine;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.Collections;
|
||||
|
@ -17,22 +17,22 @@ import java.util.concurrent.ConcurrentMap;
|
|||
|
||||
public class LineClickListener implements PacketListener {
|
||||
|
||||
private final ConcurrentMap<Integer, BaseClickableHologramLine> linesByEntityID;
|
||||
private final ConcurrentMap<Integer, ClickableLineTracker<?>> lineTrackerByEntityID;
|
||||
|
||||
// It is necessary to queue async click events to process them from the main thread.
|
||||
// Use a set to avoid duplicate click events to the same line.
|
||||
private final Set<QueuedClickEvent> queuedClickEvents;
|
||||
|
||||
public LineClickListener() {
|
||||
linesByEntityID = new ConcurrentHashMap<>();
|
||||
lineTrackerByEntityID = new ConcurrentHashMap<>();
|
||||
queuedClickEvents = Collections.newSetFromMap(new ConcurrentHashMap<>());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onAsyncEntityInteract(Player player, int entityID) {
|
||||
BaseClickableHologramLine line = linesByEntityID.get(entityID);
|
||||
if (line != null) {
|
||||
queuedClickEvents.add(new QueuedClickEvent(player, line));
|
||||
ClickableLineTracker<?> lineTracker = lineTrackerByEntityID.get(entityID);
|
||||
if (lineTracker != null) {
|
||||
queuedClickEvents.add(new QueuedClickEvent(player, lineTracker));
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -41,19 +41,19 @@ public class LineClickListener implements PacketListener {
|
|||
|
||||
// This method is called from the main thread
|
||||
public void processQueuedClickEvents() {
|
||||
for (QueuedClickEvent queuedClickEvent : queuedClickEvents) {
|
||||
queuedClickEvent.line.onClick(queuedClickEvent.player);
|
||||
for (QueuedClickEvent event : queuedClickEvents) {
|
||||
event.lineTracker.onClientClick(event.player);
|
||||
}
|
||||
queuedClickEvents.clear();
|
||||
}
|
||||
|
||||
public void registerLine(EntityID clickableEntityID, BaseClickableHologramLine line) {
|
||||
linesByEntityID.put(clickableEntityID.getNumericID(), line);
|
||||
public void addLineTracker(EntityID clickableEntityID, ClickableLineTracker<?> lineTracker) {
|
||||
lineTrackerByEntityID.put(clickableEntityID.getNumericID(), lineTracker);
|
||||
}
|
||||
|
||||
public void unregisterLine(EntityID clickableEntityID) {
|
||||
public void removeLineTracker(EntityID clickableEntityID) {
|
||||
if (clickableEntityID.hasInitializedNumericID()) {
|
||||
linesByEntityID.remove(clickableEntityID.getNumericID());
|
||||
lineTrackerByEntityID.remove(clickableEntityID.getNumericID());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -61,11 +61,11 @@ public class LineClickListener implements PacketListener {
|
|||
private static class QueuedClickEvent {
|
||||
|
||||
private final Player player;
|
||||
private final BaseClickableHologramLine line;
|
||||
private final ClickableLineTracker<?> lineTracker;
|
||||
|
||||
QueuedClickEvent(Player player, BaseClickableHologramLine line) {
|
||||
QueuedClickEvent(Player player, ClickableLineTracker<?> lineTracker) {
|
||||
this.player = player;
|
||||
this.line = line;
|
||||
this.lineTracker = lineTracker;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -78,13 +78,13 @@ public class LineClickListener implements PacketListener {
|
|||
}
|
||||
|
||||
QueuedClickEvent other = (QueuedClickEvent) obj;
|
||||
return this.player.equals(other.player) && this.line.equals(other.line);
|
||||
return this.player.equals(other.player) && this.lineTracker.equals(other.lineTracker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = player.hashCode();
|
||||
result = 31 * result + line.hashCode();
|
||||
result = 31 * result + lineTracker.hashCode();
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,6 +123,22 @@ class Parser {
|
|||
}
|
||||
}
|
||||
|
||||
public static String addEscapes(String string) {
|
||||
StringBuilder output = new StringBuilder(string.length() + 16); // String gets longer with escapes
|
||||
|
||||
for (int i = 0; i < string.length(); i++) {
|
||||
char currentChar = string.charAt(i);
|
||||
|
||||
if (isSpecialCharacter(currentChar)) {
|
||||
output.append(ESCAPE_CHAR);
|
||||
}
|
||||
|
||||
output.append(currentChar);
|
||||
}
|
||||
|
||||
return output.toString();
|
||||
}
|
||||
|
||||
private static boolean isSpecialCharacter(char currentChar) {
|
||||
return currentChar == ESCAPE_CHAR
|
||||
|| currentChar == PLACEHOLDER_START_CHAR
|
||||
|
|
|
@ -27,6 +27,10 @@ public final class StringWithPlaceholders {
|
|||
return Parser.parse(string, true);
|
||||
}
|
||||
|
||||
public static String addEscapes(@NotNull String string) {
|
||||
return Parser.addEscapes(string);
|
||||
}
|
||||
|
||||
StringWithPlaceholders(@NotNull String string, @Nullable List<Part> parts) {
|
||||
this.string = string;
|
||||
this.parts = parts;
|
||||
|
@ -71,7 +75,7 @@ public final class StringWithPlaceholders {
|
|||
return replace(player, replaceFunction, StringReplaceFunction.NO_REPLACEMENTS);
|
||||
}
|
||||
|
||||
public @NotNull String replaceStrings(StringReplaceFunction replaceFunction) {
|
||||
public @NotNull String replaceOutsidePlaceholders(StringReplaceFunction replaceFunction) {
|
||||
return replace(null, PlaceholderReplaceFunction.NO_REPLACEMENTS, replaceFunction);
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
package me.filoghost.holographicdisplays.core.tick;
|
||||
|
||||
import me.filoghost.fcommons.logging.Log;
|
||||
import me.filoghost.holographicdisplays.core.CoreGlobalConfig;
|
||||
import me.filoghost.holographicdisplays.core.NMSVersion;
|
||||
import me.filoghost.holographicdisplays.core.listener.LineClickListener;
|
||||
import me.filoghost.holographicdisplays.core.placeholder.tracking.ActivePlaceholderTracker;
|
||||
import me.filoghost.holographicdisplays.core.tracking.LineTrackerManager;
|
||||
|
@ -56,7 +58,24 @@ public class TickingTask implements Runnable {
|
|||
}
|
||||
|
||||
public void onPlayerRespawn(Player player) {
|
||||
lineTrackerManager.removeViewer(player);
|
||||
switch (NMSVersion.getCurrent()) {
|
||||
case v1_8_R1:
|
||||
case v1_8_R2:
|
||||
case v1_8_R3:
|
||||
case v1_9_R1:
|
||||
case v1_9_R2:
|
||||
case v1_10_R1:
|
||||
case v1_11_R1:
|
||||
case v1_12_R1:
|
||||
case v1_13_R1:
|
||||
case v1_13_R2:
|
||||
case v1_14_R1:
|
||||
// For older versions, force spawn packets to be resent after the player respawns
|
||||
lineTrackerManager.removeViewer(player);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -75,6 +94,9 @@ public class TickingTask implements Runnable {
|
|||
|
||||
// Holograms need to disappear before chunks (code taken from Bukkit)
|
||||
int maxViewRange = (Bukkit.getViewDistance() - 1) * 16;
|
||||
if (maxViewRange > CoreGlobalConfig.maxViewRange) {
|
||||
maxViewRange = CoreGlobalConfig.maxViewRange;
|
||||
}
|
||||
|
||||
try {
|
||||
lineTrackerManager.update(onlinePlayers, movedPlayers, maxViewRange);
|
||||
|
|
|
@ -10,6 +10,8 @@ import me.filoghost.holographicdisplays.core.base.BaseClickableHologramLine;
|
|||
import me.filoghost.holographicdisplays.core.listener.LineClickListener;
|
||||
import me.filoghost.holographicdisplays.nms.common.NMSManager;
|
||||
import me.filoghost.holographicdisplays.nms.common.entity.ClickableNMSPacketEntity;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.MustBeInvokedByOverriders;
|
||||
|
||||
public abstract class ClickableLineTracker<T extends Viewer> extends LineTracker<T> {
|
||||
|
@ -27,14 +29,32 @@ public abstract class ClickableLineTracker<T extends Viewer> extends LineTracker
|
|||
this.lineClickListener = lineClickListener;
|
||||
}
|
||||
|
||||
public void onClientClick(Player player) {
|
||||
if (getLine().hasClickCallback() && canInteract(player) && isInClickRange(player)) {
|
||||
getLine().onClick(player);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isInClickRange(Player player) {
|
||||
Location playerLocation = player.getLocation();
|
||||
PositionCoordinates positionCoordinates = getLine().getCoordinates();
|
||||
|
||||
double xDiff = playerLocation.getX() - positionCoordinates.getX();
|
||||
double yDiff = playerLocation.getY() + 1.3 - positionCoordinates.getY(); // Use shoulder height
|
||||
double zDiff = playerLocation.getZ() - positionCoordinates.getZ();
|
||||
|
||||
double distanceSquared = (xDiff * xDiff) + (yDiff * yDiff) + (zDiff * zDiff);
|
||||
return distanceSquared < 5 * 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected abstract BaseClickableHologramLine getLine();
|
||||
public abstract BaseClickableHologramLine getLine();
|
||||
|
||||
@MustBeInvokedByOverriders
|
||||
@Override
|
||||
public void onRemoval() {
|
||||
super.onRemoval();
|
||||
lineClickListener.unregisterLine(clickableEntity.getID());
|
||||
lineClickListener.removeLineTracker(clickableEntity.getID());
|
||||
}
|
||||
|
||||
@MustBeInvokedByOverriders
|
||||
|
@ -47,9 +67,9 @@ public abstract class ClickableLineTracker<T extends Viewer> extends LineTracker
|
|||
this.spawnClickableEntity = spawnClickableEntity;
|
||||
this.spawnClickableEntityChanged = true;
|
||||
if (spawnClickableEntity) {
|
||||
lineClickListener.registerLine(clickableEntity.getID(), getLine());
|
||||
lineClickListener.addLineTracker(clickableEntity.getID(), this);
|
||||
} else {
|
||||
lineClickListener.unregisterLine(clickableEntity.getID());
|
||||
lineClickListener.removeLineTracker(clickableEntity.getID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +85,11 @@ public abstract class ClickableLineTracker<T extends Viewer> extends LineTracker
|
|||
@Override
|
||||
protected void sendSpawnPackets(Viewers<T> viewers) {
|
||||
if (spawnClickableEntity) {
|
||||
viewers.sendPackets(clickableEntity.newSpawnPackets(getClickableEntityPosition()));
|
||||
// Copy for async use
|
||||
PositionCoordinates clickableEntityPosition = getClickableEntityPosition();
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(clickableEntity.newSpawnPackets(clickableEntityPosition));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,7 +97,9 @@ public abstract class ClickableLineTracker<T extends Viewer> extends LineTracker
|
|||
@Override
|
||||
protected void sendDestroyPackets(Viewers<T> viewers) {
|
||||
if (spawnClickableEntity) {
|
||||
viewers.sendPackets(clickableEntity.newDestroyPackets());
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(clickableEntity.newDestroyPackets());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -84,9 +110,15 @@ public abstract class ClickableLineTracker<T extends Viewer> 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());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -95,7 +127,11 @@ public abstract class ClickableLineTracker<T extends Viewer> extends LineTracker
|
|||
@Override
|
||||
protected void sendPositionChangePackets(Viewers<T> viewers) {
|
||||
if (spawnClickableEntity) {
|
||||
viewers.sendPackets(clickableEntity.newTeleportPackets(getClickableEntityPosition()));
|
||||
// Copy for async use
|
||||
PositionCoordinates clickableEntityPosition = getClickableEntityPosition();
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(clickableEntity.newTeleportPackets(clickableEntityPosition));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,15 +5,16 @@
|
|||
*/
|
||||
package me.filoghost.holographicdisplays.core.tracking;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public class DelegateViewers<T extends Viewer> implements Viewers<T> {
|
||||
public class ImmutableViewers<T extends Viewer> implements Viewers<T> {
|
||||
|
||||
private final Collection<T> viewers;
|
||||
|
||||
public DelegateViewers(Collection<T> viewers) {
|
||||
this.viewers = viewers;
|
||||
public ImmutableViewers(Collection<T> viewers) {
|
||||
this.viewers = new ArrayList<>(viewers);
|
||||
}
|
||||
|
||||
@Override
|
|
@ -5,11 +5,14 @@
|
|||
*/
|
||||
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;
|
||||
import me.filoghost.holographicdisplays.nms.common.NMSManager;
|
||||
import me.filoghost.holographicdisplays.nms.common.entity.ItemNMSPacketEntity;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.jetbrains.annotations.MustBeInvokedByOverriders;
|
||||
|
||||
|
@ -48,13 +51,20 @@ public class ItemLineTracker extends ClickableLineTracker<Viewer> {
|
|||
|
||||
if (spawnItemEntity && hasViewers() && line.hasPickupCallback()) {
|
||||
for (Viewer viewer : getViewers()) {
|
||||
if (viewer.getLocation() != null && CollisionHelper.isInPickupRange(viewer.getLocation(), positionCoordinates)) {
|
||||
line.onPickup(viewer.getBukkitPlayer());
|
||||
}
|
||||
invokePickupIfNecessary(viewer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void invokePickupIfNecessary(Viewer viewer) {
|
||||
Location location = viewer.getLocation();
|
||||
Player player = viewer.getBukkitPlayer();
|
||||
|
||||
if (location != null && CollisionHelper.isInPickupRange(location, positionCoordinates) && canInteract(player)) {
|
||||
line.onPickup(player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean updatePlaceholders() {
|
||||
return false;
|
||||
|
@ -97,7 +107,12 @@ public class ItemLineTracker extends ClickableLineTracker<Viewer> {
|
|||
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));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -107,7 +122,9 @@ public class ItemLineTracker extends ClickableLineTracker<Viewer> {
|
|||
super.sendDestroyPackets(viewers);
|
||||
|
||||
if (spawnItemEntity) {
|
||||
viewers.sendPackets(itemEntity.newDestroyPackets());
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(itemEntity.newDestroyPackets());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -118,13 +135,24 @@ public class ItemLineTracker extends ClickableLineTracker<Viewer> {
|
|||
|
||||
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));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,7 +162,11 @@ public class ItemLineTracker extends ClickableLineTracker<Viewer> {
|
|||
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));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,35 +8,30 @@ package me.filoghost.holographicdisplays.core.tracking;
|
|||
import me.filoghost.holographicdisplays.common.PositionCoordinates;
|
||||
import me.filoghost.holographicdisplays.core.base.BaseHologramLine;
|
||||
import me.filoghost.holographicdisplays.core.tick.CachedPlayer;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
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<T extends Viewer> {
|
||||
|
||||
private final Map<Player, T> viewers;
|
||||
private final Viewers<T> iterableViewers;
|
||||
private final ConcurrentMap<Player, T> viewers;
|
||||
|
||||
private String positionWorldName;
|
||||
protected PositionCoordinates positionCoordinates;
|
||||
private boolean positionChanged;
|
||||
|
||||
/**
|
||||
* Flag to indicate that the line has changed in some way and there could be the need to send update packets.
|
||||
*/
|
||||
private boolean lineChanged;
|
||||
private boolean inLoadedChunk;
|
||||
private int lastVisibilitySettingsVersion;
|
||||
|
||||
protected LineTracker() {
|
||||
this.viewers = new HashMap<>();
|
||||
this.iterableViewers = new DelegateViewers<>(viewers.values());
|
||||
this.viewers = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
protected abstract BaseHologramLine getLine();
|
||||
|
@ -50,17 +45,13 @@ public abstract class LineTracker<T extends Viewer> {
|
|||
resetViewersAndSendDestroyPackets();
|
||||
}
|
||||
|
||||
public final void setLineChanged() {
|
||||
lineChanged = true;
|
||||
}
|
||||
|
||||
@MustBeInvokedByOverriders
|
||||
protected void update(List<CachedPlayer> onlinePlayers, List<CachedPlayer> movedPlayers, int maxViewRange) {
|
||||
boolean sendChangesPackets = false;
|
||||
|
||||
// First, detect the changes if the flag is on and set it off
|
||||
if (lineChanged) {
|
||||
lineChanged = false;
|
||||
if (getLine().hasChanged()) {
|
||||
getLine().clearChanged();
|
||||
detectChanges();
|
||||
sendChangesPackets = true;
|
||||
}
|
||||
|
@ -74,7 +65,7 @@ public abstract class LineTracker<T extends Viewer> {
|
|||
|
||||
// Then, send the changes (if any) to already tracked players
|
||||
if (sendChangesPackets && hasViewers()) {
|
||||
sendChangesPackets(iterableViewers);
|
||||
sendChangesPackets(new ImmutableViewers<>(viewers.values()));
|
||||
}
|
||||
|
||||
// Finally, add/remove viewers sending them the full spawn/destroy packets
|
||||
|
@ -189,7 +180,7 @@ public abstract class LineTracker<T extends Viewer> {
|
|||
return viewers.values();
|
||||
}
|
||||
|
||||
public final boolean isViewer(Player player) {
|
||||
protected final boolean isViewer(Player player) {
|
||||
return viewers.containsKey(player);
|
||||
}
|
||||
|
||||
|
@ -197,6 +188,14 @@ public abstract class LineTracker<T extends Viewer> {
|
|||
viewers.remove(player);
|
||||
}
|
||||
|
||||
protected boolean canInteract(Player player) {
|
||||
return !getLine().isDeleted()
|
||||
&& player.isOnline()
|
||||
&& player.getGameMode() != GameMode.SPECTATOR
|
||||
&& isViewer(player)
|
||||
&& getLine().isVisibleTo(player);
|
||||
}
|
||||
|
||||
@MustBeInvokedByOverriders
|
||||
protected void detectChanges() {
|
||||
PositionCoordinates positionCoordinates = getLine().getCoordinates();
|
||||
|
@ -222,7 +221,7 @@ public abstract class LineTracker<T extends Viewer> {
|
|||
return;
|
||||
}
|
||||
|
||||
sendDestroyPackets(iterableViewers);
|
||||
sendDestroyPackets(new ImmutableViewers<>(viewers.values()));
|
||||
viewers.clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ package me.filoghost.holographicdisplays.core.tracking;
|
|||
|
||||
import me.filoghost.holographicdisplays.core.base.BaseItemHologramLine;
|
||||
import me.filoghost.holographicdisplays.core.base.BaseTextHologramLine;
|
||||
import me.filoghost.holographicdisplays.core.base.EditableHologramLine;
|
||||
import me.filoghost.holographicdisplays.core.listener.LineClickListener;
|
||||
import me.filoghost.holographicdisplays.core.placeholder.tracking.ActivePlaceholderTracker;
|
||||
import me.filoghost.holographicdisplays.core.tick.CachedPlayer;
|
||||
|
@ -35,16 +36,14 @@ public class LineTrackerManager {
|
|||
this.lineTrackers = new LinkedList<>();
|
||||
}
|
||||
|
||||
public TextLineTracker startTracking(BaseTextHologramLine line) {
|
||||
TextLineTracker tracker = new TextLineTracker(line, nmsManager, lineClickListener, placeholderTracker);
|
||||
lineTrackers.add(tracker);
|
||||
return tracker;
|
||||
}
|
||||
|
||||
public ItemLineTracker startTracking(BaseItemHologramLine line) {
|
||||
ItemLineTracker tracker = new ItemLineTracker(line, nmsManager, lineClickListener);
|
||||
lineTrackers.add(tracker);
|
||||
return tracker;
|
||||
public <T extends EditableHologramLine> void startTracking(T line) {
|
||||
if (line instanceof BaseTextHologramLine) {
|
||||
lineTrackers.add(new TextLineTracker((BaseTextHologramLine) line, nmsManager, lineClickListener, placeholderTracker));
|
||||
} else if (line instanceof BaseItemHologramLine) {
|
||||
lineTrackers.add(new ItemLineTracker((BaseItemHologramLine) line, nmsManager, lineClickListener));
|
||||
} else {
|
||||
throw new UnsupportedOperationException("unsupported line class: " + line.getClass().getName());
|
||||
}
|
||||
}
|
||||
|
||||
public void update(List<CachedPlayer> onlinePlayers, List<CachedPlayer> movedPlayers, int maxViewRange) {
|
||||
|
|
|
@ -15,7 +15,7 @@ public class MutableViewers<T extends Viewer> implements Viewers<T> {
|
|||
private T viewer;
|
||||
private List<T> 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<T extends Viewer> implements Viewers<T> {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<? super T> action) {
|
||||
public synchronized void forEach(Consumer<? super T> action) {
|
||||
if (viewer != null) {
|
||||
action.accept(viewer);
|
||||
if (additionalViewers != null) {
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* 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.
|
||||
* Important note: this executor can only have one thread, as packets must be sent in a precise order.
|
||||
*/
|
||||
public class PacketSenderExecutor {
|
||||
|
||||
private static volatile BlockingQueue<Runnable> tasks;
|
||||
|
||||
private static final Runnable STOP_MARKER_TASK = () -> {};
|
||||
|
||||
public static void execute(Runnable task) {
|
||||
tasks.add(task);
|
||||
}
|
||||
|
||||
public static void start() {
|
||||
tasks = new LinkedBlockingQueue<>();
|
||||
Thread 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 async packets");
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public static void stopGracefully() {
|
||||
if (tasks != null) {
|
||||
tasks.add(STOP_MARKER_TASK);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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<TextLineViewer> {
|
|||
protected void sendSpawnPackets(Viewers<TextLineViewer> 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<TextLineViewer> viewers) {
|
||||
super.sendDestroyPackets(viewers);
|
||||
viewers.sendPackets(textEntity.newDestroyPackets());
|
||||
PacketSenderExecutor.execute(() -> {
|
||||
viewers.sendPackets(textEntity.newDestroyPackets());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -100,8 +108,11 @@ public class TextLineTracker extends ClickableLineTracker<TextLineViewer> {
|
|||
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<TextLineViewer> {
|
|||
@Override
|
||||
protected void sendPositionChangePackets(Viewers<TextLineViewer> 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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,8 @@ class StringWithPlaceholdersTest {
|
|||
Arguments.of(" {p} ", " # "),
|
||||
Arguments.of("{p} {p} {p}", "# # #"),
|
||||
Arguments.of("{{p}}", "{#}"), // Only the innermost placeholder should be replaced
|
||||
Arguments.of("{{p}", "{#"),
|
||||
Arguments.of("{p}}", "#}"),
|
||||
Arguments.of("{p abc", "{p abc"), // Placeholder without closing tag
|
||||
Arguments.of("abc p}", "abc p}") // Placeholder without opening tag
|
||||
);
|
||||
|
@ -46,7 +48,7 @@ class StringWithPlaceholdersTest {
|
|||
@MethodSource("replaceLiteralPartsTestArguments")
|
||||
void replaceLiteralParts(String input, String expectedOutput) {
|
||||
StringWithPlaceholders s = StringWithPlaceholders.of(input);
|
||||
assertThat(s.replaceStrings(literalPart -> "_")).isEqualTo(expectedOutput);
|
||||
assertThat(s.replaceOutsidePlaceholders(literalPart -> "_")).isEqualTo(expectedOutput);
|
||||
}
|
||||
|
||||
static Stream<Arguments> replaceLiteralPartsTestArguments() {
|
||||
|
@ -112,7 +114,7 @@ class StringWithPlaceholdersTest {
|
|||
@ParameterizedTest(name = "[{index}] {0} -> {0}")
|
||||
@MethodSource("escapesTestArguments")
|
||||
void preservingEscapes(String input) {
|
||||
String output = StringWithPlaceholders.withEscapes(input).replaceStrings(StringReplaceFunction.NO_REPLACEMENTS);
|
||||
String output = StringWithPlaceholders.withEscapes(input).replaceOutsidePlaceholders(StringReplaceFunction.NO_REPLACEMENTS);
|
||||
assertThat(output).isEqualTo(input);
|
||||
}
|
||||
|
||||
|
@ -133,4 +135,10 @@ class StringWithPlaceholdersTest {
|
|||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
void addEscapes() {
|
||||
String escaped = StringWithPlaceholders.addEscapes("} { \\");
|
||||
assertThat(escaped).isEqualTo("\\} \\{ \\\\");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-example</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-example-deathholograms</artifactId>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-parent</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-example</artifactId>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-example</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-example-powerups</artifactId>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-parent</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-legacy-api</artifactId>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-legacy-api</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-legacy-api-v1</artifactId>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-legacy-api</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-legacy-api-v2</artifactId>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-nms</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-nms-common</artifactId>
|
||||
|
|
87
nms/pom.xml
87
nms/pom.xml
|
@ -1,42 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-parent</artifactId>
|
||||
<version>3.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-nms</artifactId>
|
||||
<name>HolographicDisplays NMS</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>common</module>
|
||||
<module>v1_8_r3</module>
|
||||
<module>v1_9_r2</module>
|
||||
<module>v1_10_r1</module>
|
||||
<module>v1_11_r1</module>
|
||||
<module>v1_12_r1</module>
|
||||
<module>v1_13_r2</module>
|
||||
<module>v1_14_r1</module>
|
||||
<module>v1_15_r1</module>
|
||||
<module>v1_16_r1</module>
|
||||
<module>v1_16_r2</module>
|
||||
<module>v1_16_r3</module>
|
||||
<module>v1_17_r1</module>
|
||||
<module>v1_18_r1</module>
|
||||
<module>v1_18_r2</module>
|
||||
<module>v1_19_r1</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>me.filoghost.fcommons</groupId>
|
||||
<artifactId>fcommons</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-parent</artifactId>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-nms</artifactId>
|
||||
<name>HolographicDisplays NMS</name>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<modules>
|
||||
<module>common</module>
|
||||
<module>v1_8_r3</module>
|
||||
<module>v1_9_r2</module>
|
||||
<module>v1_10_r1</module>
|
||||
<module>v1_11_r1</module>
|
||||
<module>v1_12_r1</module>
|
||||
<module>v1_13_r2</module>
|
||||
<module>v1_14_r1</module>
|
||||
<module>v1_15_r1</module>
|
||||
<module>v1_16_r3</module>
|
||||
<module>v1_17_r1</module>
|
||||
<module>v1_18_r1</module>
|
||||
<module>v1_18_r2</module>
|
||||
<module>v1_19_r1</module>
|
||||
<module>v1_19_r2</module>
|
||||
<module>v1_19_r3</module>
|
||||
<module>v1_20_r1</module>
|
||||
<module>v1_20_r2</module>
|
||||
<module>v1_20_r3</module>
|
||||
</modules>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>me.filoghost.fcommons</groupId>
|
||||
<artifactId>fcommons</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-nms</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-nms-v1_10_r1</artifactId>
|
||||
|
|
|
@ -62,7 +62,7 @@ class EntityLivingSpawnNMSPacket extends VersionNMSPacket {
|
|||
// Entries are deserialized and saved into a field which is not used during the re-serialization, set as empty
|
||||
packetByteBuffer.writeDataWatcherEntriesEnd();
|
||||
|
||||
Packet<?> rawPacket = writeData(new PacketPlayOutSpawnEntityLiving(), packetByteBuffer);
|
||||
Packet<?> rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutSpawnEntityLiving());
|
||||
return new Builder(rawPacket, PacketByteBuffer.get());
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ class EntityMetadataNMSPacket extends VersionNMSPacket {
|
|||
private final Packet<?> rawPacket;
|
||||
|
||||
private EntityMetadataNMSPacket(PacketByteBuffer packetByteBuffer) {
|
||||
this.rawPacket = writeData(new PacketPlayOutEntityMetadata(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutEntityMetadata());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,7 +19,7 @@ class EntityMountNMSPacket extends VersionNMSPacket {
|
|||
packetByteBuffer.writeVarInt(vehicleEntityID.getNumericID());
|
||||
packetByteBuffer.writeVarIntArray(passengerEntityID.getNumericID());
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutMount(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutMount());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -42,7 +42,7 @@ class EntitySpawnNMSPacket extends VersionNMSPacket {
|
|||
packetByteBuffer.writeShort(0);
|
||||
packetByteBuffer.writeShort(0);
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutSpawnEntity(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutSpawnEntity());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -31,7 +31,7 @@ class EntityTeleportNMSPacket extends VersionNMSPacket {
|
|||
// On ground
|
||||
packetByteBuffer.writeBoolean(false);
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutEntityTeleport(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutEntityTeleport());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,25 +6,58 @@
|
|||
package me.filoghost.holographicdisplays.nms.v1_10_R1;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.server.v1_10_R1.Packet;
|
||||
import net.minecraft.server.v1_10_R1.PacketDataSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer extends PacketDataSerializer {
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> 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() {
|
||||
super(Unpooled.buffer());
|
||||
this.serializer = new PacketDataSerializer(Unpooled.buffer());
|
||||
}
|
||||
|
||||
int readableBytes() {
|
||||
return serializer.readableBytes();
|
||||
}
|
||||
|
||||
void readBytes(byte[] bytes) {
|
||||
serializer.readBytes(bytes);
|
||||
}
|
||||
|
||||
void writeBoolean(boolean flag) {
|
||||
serializer.writeBoolean(flag);
|
||||
}
|
||||
|
||||
void writeByte(int i) {
|
||||
serializer.writeByte(i);
|
||||
}
|
||||
|
||||
void writeShort(int i) {
|
||||
serializer.writeShort(i);
|
||||
}
|
||||
|
||||
void writeInt(int i) {
|
||||
serializer.writeInt(i);
|
||||
}
|
||||
|
||||
void writeDouble(double d) {
|
||||
serializer.writeDouble(d);
|
||||
}
|
||||
|
||||
void writeVarInt(int i) {
|
||||
super.d(i);
|
||||
serializer.d(i);
|
||||
}
|
||||
|
||||
void writeVarIntArray(int i1) {
|
||||
|
@ -33,17 +66,31 @@ class PacketByteBuffer extends PacketDataSerializer {
|
|||
}
|
||||
|
||||
void writeUUID(UUID uuid) {
|
||||
super.a(uuid);
|
||||
serializer.a(uuid);
|
||||
}
|
||||
|
||||
<T> void writeDataWatcherEntry(DataWatcherKey<T> key, T value) {
|
||||
writeByte(key.getIndex());
|
||||
serializer.writeByte(key.getIndex());
|
||||
writeVarInt(key.getSerializerTypeID());
|
||||
key.getSerializer().a(this, value);
|
||||
key.getSerializer().a(serializer, value);
|
||||
}
|
||||
|
||||
void writeDataWatcherEntriesEnd() {
|
||||
writeByte(0xFF);
|
||||
serializer.writeByte(0xFF);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
serializer.clear();
|
||||
}
|
||||
|
||||
<T extends Packet<?>> T writeDataTo(T packet) {
|
||||
try {
|
||||
packet.a(serializer);
|
||||
return packet;
|
||||
} catch (IOException e) {
|
||||
// Never thrown by the implementations
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ package me.filoghost.holographicdisplays.nms.v1_10_R1;
|
|||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.EventLoop;
|
||||
import me.filoghost.fcommons.logging.ErrorCollector;
|
||||
import me.filoghost.fcommons.logging.Log;
|
||||
import me.filoghost.fcommons.reflection.ReflectField;
|
||||
|
@ -115,8 +116,12 @@ public class VersionNMSManager implements NMSManager {
|
|||
PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection;
|
||||
NetworkManager networkManager = playerConnection.a();
|
||||
Channel channel = networkManager.channel;
|
||||
if (channel == null) {
|
||||
return;
|
||||
}
|
||||
EventLoop eventLoop = channel.eventLoop();
|
||||
|
||||
channel.eventLoop().execute(() -> {
|
||||
Runnable safeModifierTask = () -> {
|
||||
if (!player.isOnline()) {
|
||||
return;
|
||||
}
|
||||
|
@ -125,7 +130,13 @@ public class VersionNMSManager implements NMSManager {
|
|||
} catch (Exception e) {
|
||||
Log.warning(NMSErrors.EXCEPTION_MODIFYING_CHANNEL_PIPELINE, e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (eventLoop.inEventLoop()) {
|
||||
safeModifierTask.run();
|
||||
} else {
|
||||
eventLoop.execute(safeModifierTask);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@ import net.minecraft.server.v1_10_R1.Packet;
|
|||
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
abstract class VersionNMSPacket implements PacketGroup {
|
||||
|
||||
@Override
|
||||
|
@ -21,14 +19,4 @@ abstract class VersionNMSPacket implements PacketGroup {
|
|||
|
||||
abstract Packet<?> getRawPacket();
|
||||
|
||||
protected static <T extends Packet<?>> T writeData(T packet, PacketByteBuffer packetByteBuffer) {
|
||||
try {
|
||||
packet.a(packetByteBuffer);
|
||||
return packet;
|
||||
} catch (IOException e) {
|
||||
// Never thrown by the implementations
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-nms</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-nms-v1_11_r1</artifactId>
|
||||
|
|
|
@ -62,7 +62,7 @@ class EntityLivingSpawnNMSPacket extends VersionNMSPacket {
|
|||
// Entries are deserialized and saved into a field which is not used during the re-serialization, set as empty
|
||||
packetByteBuffer.writeDataWatcherEntriesEnd();
|
||||
|
||||
Packet<?> rawPacket = writeData(new PacketPlayOutSpawnEntityLiving(), packetByteBuffer);
|
||||
Packet<?> rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutSpawnEntityLiving());
|
||||
return new Builder(rawPacket, PacketByteBuffer.get());
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ class EntityMetadataNMSPacket extends VersionNMSPacket {
|
|||
private final Packet<?> rawPacket;
|
||||
|
||||
private EntityMetadataNMSPacket(PacketByteBuffer packetByteBuffer) {
|
||||
this.rawPacket = writeData(new PacketPlayOutEntityMetadata(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutEntityMetadata());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,7 +19,7 @@ class EntityMountNMSPacket extends VersionNMSPacket {
|
|||
packetByteBuffer.writeVarInt(vehicleEntityID.getNumericID());
|
||||
packetByteBuffer.writeVarIntArray(passengerEntityID.getNumericID());
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutMount(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutMount());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -42,7 +42,7 @@ class EntitySpawnNMSPacket extends VersionNMSPacket {
|
|||
packetByteBuffer.writeShort(0);
|
||||
packetByteBuffer.writeShort(0);
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutSpawnEntity(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutSpawnEntity());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -31,7 +31,7 @@ class EntityTeleportNMSPacket extends VersionNMSPacket {
|
|||
// On ground
|
||||
packetByteBuffer.writeBoolean(false);
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutEntityTeleport(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutEntityTeleport());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,25 +6,58 @@
|
|||
package me.filoghost.holographicdisplays.nms.v1_11_R1;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.server.v1_11_R1.Packet;
|
||||
import net.minecraft.server.v1_11_R1.PacketDataSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer extends PacketDataSerializer {
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> 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() {
|
||||
super(Unpooled.buffer());
|
||||
this.serializer = new PacketDataSerializer(Unpooled.buffer());
|
||||
}
|
||||
|
||||
int readableBytes() {
|
||||
return serializer.readableBytes();
|
||||
}
|
||||
|
||||
void readBytes(byte[] bytes) {
|
||||
serializer.readBytes(bytes);
|
||||
}
|
||||
|
||||
void writeBoolean(boolean flag) {
|
||||
serializer.writeBoolean(flag);
|
||||
}
|
||||
|
||||
void writeByte(int i) {
|
||||
serializer.writeByte(i);
|
||||
}
|
||||
|
||||
void writeShort(int i) {
|
||||
serializer.writeShort(i);
|
||||
}
|
||||
|
||||
void writeInt(int i) {
|
||||
serializer.writeInt(i);
|
||||
}
|
||||
|
||||
void writeDouble(double d) {
|
||||
serializer.writeDouble(d);
|
||||
}
|
||||
|
||||
void writeVarInt(int i) {
|
||||
super.d(i);
|
||||
serializer.d(i);
|
||||
}
|
||||
|
||||
void writeVarIntArray(int i1) {
|
||||
|
@ -33,17 +66,31 @@ class PacketByteBuffer extends PacketDataSerializer {
|
|||
}
|
||||
|
||||
void writeUUID(UUID uuid) {
|
||||
super.a(uuid);
|
||||
serializer.a(uuid);
|
||||
}
|
||||
|
||||
<T> void writeDataWatcherEntry(DataWatcherKey<T> key, T value) {
|
||||
writeByte(key.getIndex());
|
||||
serializer.writeByte(key.getIndex());
|
||||
writeVarInt(key.getSerializerTypeID());
|
||||
key.getSerializer().a(this, value);
|
||||
key.getSerializer().a(serializer, value);
|
||||
}
|
||||
|
||||
void writeDataWatcherEntriesEnd() {
|
||||
writeByte(0xFF);
|
||||
serializer.writeByte(0xFF);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
serializer.clear();
|
||||
}
|
||||
|
||||
<T extends Packet<?>> T writeDataTo(T packet) {
|
||||
try {
|
||||
packet.a(serializer);
|
||||
return packet;
|
||||
} catch (IOException e) {
|
||||
// Never thrown by the implementations
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ package me.filoghost.holographicdisplays.nms.v1_11_R1;
|
|||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.EventLoop;
|
||||
import me.filoghost.fcommons.logging.ErrorCollector;
|
||||
import me.filoghost.fcommons.logging.Log;
|
||||
import me.filoghost.fcommons.reflection.ReflectField;
|
||||
|
@ -115,8 +116,12 @@ public class VersionNMSManager implements NMSManager {
|
|||
PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection;
|
||||
NetworkManager networkManager = playerConnection.a();
|
||||
Channel channel = networkManager.channel;
|
||||
if (channel == null) {
|
||||
return;
|
||||
}
|
||||
EventLoop eventLoop = channel.eventLoop();
|
||||
|
||||
channel.eventLoop().execute(() -> {
|
||||
Runnable safeModifierTask = () -> {
|
||||
if (!player.isOnline()) {
|
||||
return;
|
||||
}
|
||||
|
@ -125,7 +130,13 @@ public class VersionNMSManager implements NMSManager {
|
|||
} catch (Exception e) {
|
||||
Log.warning(NMSErrors.EXCEPTION_MODIFYING_CHANNEL_PIPELINE, e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (eventLoop.inEventLoop()) {
|
||||
safeModifierTask.run();
|
||||
} else {
|
||||
eventLoop.execute(safeModifierTask);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@ import net.minecraft.server.v1_11_R1.Packet;
|
|||
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
abstract class VersionNMSPacket implements PacketGroup {
|
||||
|
||||
@Override
|
||||
|
@ -21,14 +19,4 @@ abstract class VersionNMSPacket implements PacketGroup {
|
|||
|
||||
abstract Packet<?> getRawPacket();
|
||||
|
||||
protected static <T extends Packet<?>> T writeData(T packet, PacketByteBuffer packetByteBuffer) {
|
||||
try {
|
||||
packet.a(packetByteBuffer);
|
||||
return packet;
|
||||
} catch (IOException e) {
|
||||
// Never thrown by the implementations
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-nms</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-nms-v1_12_r1</artifactId>
|
||||
|
|
|
@ -62,7 +62,7 @@ class EntityLivingSpawnNMSPacket extends VersionNMSPacket {
|
|||
// Entries are deserialized and saved into a field which is not used during the re-serialization, set as empty
|
||||
packetByteBuffer.writeDataWatcherEntriesEnd();
|
||||
|
||||
Packet<?> rawPacket = writeData(new PacketPlayOutSpawnEntityLiving(), packetByteBuffer);
|
||||
Packet<?> rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutSpawnEntityLiving());
|
||||
return new Builder(rawPacket, PacketByteBuffer.get());
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ class EntityMetadataNMSPacket extends VersionNMSPacket {
|
|||
private final Packet<?> rawPacket;
|
||||
|
||||
private EntityMetadataNMSPacket(PacketByteBuffer packetByteBuffer) {
|
||||
this.rawPacket = writeData(new PacketPlayOutEntityMetadata(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutEntityMetadata());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,7 +19,7 @@ class EntityMountNMSPacket extends VersionNMSPacket {
|
|||
packetByteBuffer.writeVarInt(vehicleEntityID.getNumericID());
|
||||
packetByteBuffer.writeVarIntArray(passengerEntityID.getNumericID());
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutMount(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutMount());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -42,7 +42,7 @@ class EntitySpawnNMSPacket extends VersionNMSPacket {
|
|||
packetByteBuffer.writeShort(0);
|
||||
packetByteBuffer.writeShort(0);
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutSpawnEntity(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutSpawnEntity());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -31,7 +31,7 @@ class EntityTeleportNMSPacket extends VersionNMSPacket {
|
|||
// On ground
|
||||
packetByteBuffer.writeBoolean(false);
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutEntityTeleport(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutEntityTeleport());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,25 +6,58 @@
|
|||
package me.filoghost.holographicdisplays.nms.v1_12_R1;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.server.v1_12_R1.Packet;
|
||||
import net.minecraft.server.v1_12_R1.PacketDataSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer extends PacketDataSerializer {
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> 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() {
|
||||
super(Unpooled.buffer());
|
||||
this.serializer = new PacketDataSerializer(Unpooled.buffer());
|
||||
}
|
||||
|
||||
int readableBytes() {
|
||||
return serializer.readableBytes();
|
||||
}
|
||||
|
||||
void readBytes(byte[] bytes) {
|
||||
serializer.readBytes(bytes);
|
||||
}
|
||||
|
||||
void writeBoolean(boolean flag) {
|
||||
serializer.writeBoolean(flag);
|
||||
}
|
||||
|
||||
void writeByte(int i) {
|
||||
serializer.writeByte(i);
|
||||
}
|
||||
|
||||
void writeShort(int i) {
|
||||
serializer.writeShort(i);
|
||||
}
|
||||
|
||||
void writeInt(int i) {
|
||||
serializer.writeInt(i);
|
||||
}
|
||||
|
||||
void writeDouble(double d) {
|
||||
serializer.writeDouble(d);
|
||||
}
|
||||
|
||||
void writeVarInt(int i) {
|
||||
super.d(i);
|
||||
serializer.d(i);
|
||||
}
|
||||
|
||||
void writeVarIntArray(int i1) {
|
||||
|
@ -33,17 +66,31 @@ class PacketByteBuffer extends PacketDataSerializer {
|
|||
}
|
||||
|
||||
void writeUUID(UUID uuid) {
|
||||
super.a(uuid);
|
||||
serializer.a(uuid);
|
||||
}
|
||||
|
||||
<T> void writeDataWatcherEntry(DataWatcherKey<T> key, T value) {
|
||||
writeByte(key.getIndex());
|
||||
serializer.writeByte(key.getIndex());
|
||||
writeVarInt(key.getSerializerTypeID());
|
||||
key.getSerializer().a(this, value);
|
||||
key.getSerializer().a(serializer, value);
|
||||
}
|
||||
|
||||
void writeDataWatcherEntriesEnd() {
|
||||
writeByte(0xFF);
|
||||
serializer.writeByte(0xFF);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
serializer.clear();
|
||||
}
|
||||
|
||||
<T extends Packet<?>> T writeDataTo(T packet) {
|
||||
try {
|
||||
packet.a(serializer);
|
||||
return packet;
|
||||
} catch (IOException e) {
|
||||
// Never thrown by the implementations
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ package me.filoghost.holographicdisplays.nms.v1_12_R1;
|
|||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.EventLoop;
|
||||
import me.filoghost.fcommons.logging.ErrorCollector;
|
||||
import me.filoghost.fcommons.logging.Log;
|
||||
import me.filoghost.fcommons.reflection.ReflectField;
|
||||
|
@ -115,8 +116,12 @@ public class VersionNMSManager implements NMSManager {
|
|||
PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection;
|
||||
NetworkManager networkManager = playerConnection.a();
|
||||
Channel channel = networkManager.channel;
|
||||
if (channel == null) {
|
||||
return;
|
||||
}
|
||||
EventLoop eventLoop = channel.eventLoop();
|
||||
|
||||
channel.eventLoop().execute(() -> {
|
||||
Runnable safeModifierTask = () -> {
|
||||
if (!player.isOnline()) {
|
||||
return;
|
||||
}
|
||||
|
@ -125,7 +130,13 @@ public class VersionNMSManager implements NMSManager {
|
|||
} catch (Exception e) {
|
||||
Log.warning(NMSErrors.EXCEPTION_MODIFYING_CHANNEL_PIPELINE, e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (eventLoop.inEventLoop()) {
|
||||
safeModifierTask.run();
|
||||
} else {
|
||||
eventLoop.execute(safeModifierTask);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@ import net.minecraft.server.v1_12_R1.Packet;
|
|||
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
abstract class VersionNMSPacket implements PacketGroup {
|
||||
|
||||
@Override
|
||||
|
@ -21,14 +19,4 @@ abstract class VersionNMSPacket implements PacketGroup {
|
|||
|
||||
abstract Packet<?> getRawPacket();
|
||||
|
||||
protected static <T extends Packet<?>> T writeData(T packet, PacketByteBuffer packetByteBuffer) {
|
||||
try {
|
||||
packet.a(packetByteBuffer);
|
||||
return packet;
|
||||
} catch (IOException e) {
|
||||
// Never thrown by the implementations
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-nms</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-nms-v1_13_r2</artifactId>
|
||||
|
|
|
@ -62,7 +62,7 @@ class EntityLivingSpawnNMSPacket extends VersionNMSPacket {
|
|||
// Entries are deserialized and saved into a field which is not used during the re-serialization, set as empty
|
||||
packetByteBuffer.writeDataWatcherEntriesEnd();
|
||||
|
||||
Packet<?> rawPacket = writeData(new PacketPlayOutSpawnEntityLiving(), packetByteBuffer);
|
||||
Packet<?> rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutSpawnEntityLiving());
|
||||
return new Builder(rawPacket, PacketByteBuffer.get());
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ class EntityMetadataNMSPacket extends VersionNMSPacket {
|
|||
private final Packet<?> rawPacket;
|
||||
|
||||
private EntityMetadataNMSPacket(PacketByteBuffer packetByteBuffer) {
|
||||
this.rawPacket = writeData(new PacketPlayOutEntityMetadata(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutEntityMetadata());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,7 +19,7 @@ class EntityMountNMSPacket extends VersionNMSPacket {
|
|||
packetByteBuffer.writeVarInt(vehicleEntityID.getNumericID());
|
||||
packetByteBuffer.writeVarIntArray(passengerEntityID.getNumericID());
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutMount(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutMount());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -42,7 +42,7 @@ class EntitySpawnNMSPacket extends VersionNMSPacket {
|
|||
packetByteBuffer.writeShort(0);
|
||||
packetByteBuffer.writeShort(0);
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutSpawnEntity(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutSpawnEntity());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -31,7 +31,7 @@ class EntityTeleportNMSPacket extends VersionNMSPacket {
|
|||
// On ground
|
||||
packetByteBuffer.writeBoolean(false);
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutEntityTeleport(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutEntityTeleport());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,25 +6,58 @@
|
|||
package me.filoghost.holographicdisplays.nms.v1_13_R2;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.server.v1_13_R2.Packet;
|
||||
import net.minecraft.server.v1_13_R2.PacketDataSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer extends PacketDataSerializer {
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> 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() {
|
||||
super(Unpooled.buffer());
|
||||
this.serializer = new PacketDataSerializer(Unpooled.buffer());
|
||||
}
|
||||
|
||||
int readableBytes() {
|
||||
return serializer.readableBytes();
|
||||
}
|
||||
|
||||
void readBytes(byte[] bytes) {
|
||||
serializer.readBytes(bytes);
|
||||
}
|
||||
|
||||
void writeBoolean(boolean flag) {
|
||||
serializer.writeBoolean(flag);
|
||||
}
|
||||
|
||||
void writeByte(int i) {
|
||||
serializer.writeByte(i);
|
||||
}
|
||||
|
||||
void writeShort(int i) {
|
||||
serializer.writeShort(i);
|
||||
}
|
||||
|
||||
void writeInt(int i) {
|
||||
serializer.writeInt(i);
|
||||
}
|
||||
|
||||
void writeDouble(double d) {
|
||||
serializer.writeDouble(d);
|
||||
}
|
||||
|
||||
void writeVarInt(int i) {
|
||||
super.d(i);
|
||||
serializer.d(i);
|
||||
}
|
||||
|
||||
void writeVarIntArray(int i1) {
|
||||
|
@ -33,17 +66,31 @@ class PacketByteBuffer extends PacketDataSerializer {
|
|||
}
|
||||
|
||||
void writeUUID(UUID uuid) {
|
||||
super.a(uuid);
|
||||
serializer.a(uuid);
|
||||
}
|
||||
|
||||
<T> void writeDataWatcherEntry(DataWatcherKey<T> key, T value) {
|
||||
writeByte(key.getIndex());
|
||||
serializer.writeByte(key.getIndex());
|
||||
writeVarInt(key.getSerializerTypeID());
|
||||
key.getSerializer().a(this, value);
|
||||
key.getSerializer().a(serializer, value);
|
||||
}
|
||||
|
||||
void writeDataWatcherEntriesEnd() {
|
||||
writeByte(0xFF);
|
||||
serializer.writeByte(0xFF);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
serializer.clear();
|
||||
}
|
||||
|
||||
<T extends Packet<?>> T writeDataTo(T packet) {
|
||||
try {
|
||||
packet.a(serializer);
|
||||
return packet;
|
||||
} catch (IOException e) {
|
||||
// Never thrown by the implementations
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ package me.filoghost.holographicdisplays.nms.v1_13_R2;
|
|||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.EventLoop;
|
||||
import me.filoghost.fcommons.logging.ErrorCollector;
|
||||
import me.filoghost.fcommons.logging.Log;
|
||||
import me.filoghost.fcommons.reflection.ReflectField;
|
||||
|
@ -115,8 +116,12 @@ public class VersionNMSManager implements NMSManager {
|
|||
PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection;
|
||||
NetworkManager networkManager = playerConnection.a();
|
||||
Channel channel = networkManager.channel;
|
||||
if (channel == null) {
|
||||
return;
|
||||
}
|
||||
EventLoop eventLoop = channel.eventLoop();
|
||||
|
||||
channel.eventLoop().execute(() -> {
|
||||
Runnable safeModifierTask = () -> {
|
||||
if (!player.isOnline()) {
|
||||
return;
|
||||
}
|
||||
|
@ -125,7 +130,13 @@ public class VersionNMSManager implements NMSManager {
|
|||
} catch (Exception e) {
|
||||
Log.warning(NMSErrors.EXCEPTION_MODIFYING_CHANNEL_PIPELINE, e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (eventLoop.inEventLoop()) {
|
||||
safeModifierTask.run();
|
||||
} else {
|
||||
eventLoop.execute(safeModifierTask);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@ import net.minecraft.server.v1_13_R2.Packet;
|
|||
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
abstract class VersionNMSPacket implements PacketGroup {
|
||||
|
||||
@Override
|
||||
|
@ -21,14 +19,4 @@ abstract class VersionNMSPacket implements PacketGroup {
|
|||
|
||||
abstract Packet<?> getRawPacket();
|
||||
|
||||
protected static <T extends Packet<?>> T writeData(T packet, PacketByteBuffer packetByteBuffer) {
|
||||
try {
|
||||
packet.a(packetByteBuffer);
|
||||
return packet;
|
||||
} catch (IOException e) {
|
||||
// Never thrown by the implementations
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-nms</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-nms-v1_14_r1</artifactId>
|
||||
|
|
|
@ -62,7 +62,7 @@ class EntityLivingSpawnNMSPacket extends VersionNMSPacket {
|
|||
// Entries are deserialized and saved into a field which is not used during the re-serialization, set as empty
|
||||
packetByteBuffer.writeDataWatcherEntriesEnd();
|
||||
|
||||
Packet<?> rawPacket = writeData(new PacketPlayOutSpawnEntityLiving(), packetByteBuffer);
|
||||
Packet<?> rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutSpawnEntityLiving());
|
||||
return new Builder(rawPacket, PacketByteBuffer.get());
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ class EntityMetadataNMSPacket extends VersionNMSPacket {
|
|||
private final Packet<?> rawPacket;
|
||||
|
||||
private EntityMetadataNMSPacket(PacketByteBuffer packetByteBuffer) {
|
||||
this.rawPacket = writeData(new PacketPlayOutEntityMetadata(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutEntityMetadata());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,7 +19,7 @@ class EntityMountNMSPacket extends VersionNMSPacket {
|
|||
packetByteBuffer.writeVarInt(vehicleEntityID.getNumericID());
|
||||
packetByteBuffer.writeVarIntArray(passengerEntityID.getNumericID());
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutMount(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutMount());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -42,7 +42,7 @@ class EntitySpawnNMSPacket extends VersionNMSPacket {
|
|||
packetByteBuffer.writeShort(0);
|
||||
packetByteBuffer.writeShort(0);
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutSpawnEntity(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutSpawnEntity());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -31,7 +31,7 @@ class EntityTeleportNMSPacket extends VersionNMSPacket {
|
|||
// On ground
|
||||
packetByteBuffer.writeBoolean(false);
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutEntityTeleport(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutEntityTeleport());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -6,25 +6,58 @@
|
|||
package me.filoghost.holographicdisplays.nms.v1_14_R1;
|
||||
|
||||
import io.netty.buffer.Unpooled;
|
||||
import net.minecraft.server.v1_14_R1.Packet;
|
||||
import net.minecraft.server.v1_14_R1.PacketDataSerializer;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
class PacketByteBuffer extends PacketDataSerializer {
|
||||
class PacketByteBuffer {
|
||||
|
||||
private static final PacketByteBuffer INSTANCE = new PacketByteBuffer();
|
||||
private static final ThreadLocal<PacketByteBuffer> 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() {
|
||||
super(Unpooled.buffer());
|
||||
this.serializer = new PacketDataSerializer(Unpooled.buffer());
|
||||
}
|
||||
|
||||
int readableBytes() {
|
||||
return serializer.readableBytes();
|
||||
}
|
||||
|
||||
void readBytes(byte[] bytes) {
|
||||
serializer.readBytes(bytes);
|
||||
}
|
||||
|
||||
void writeBoolean(boolean flag) {
|
||||
serializer.writeBoolean(flag);
|
||||
}
|
||||
|
||||
void writeByte(int i) {
|
||||
serializer.writeByte(i);
|
||||
}
|
||||
|
||||
void writeShort(int i) {
|
||||
serializer.writeShort(i);
|
||||
}
|
||||
|
||||
void writeInt(int i) {
|
||||
serializer.writeInt(i);
|
||||
}
|
||||
|
||||
void writeDouble(double d) {
|
||||
serializer.writeDouble(d);
|
||||
}
|
||||
|
||||
void writeVarInt(int i) {
|
||||
super.d(i);
|
||||
serializer.d(i);
|
||||
}
|
||||
|
||||
void writeVarIntArray(int i1) {
|
||||
|
@ -33,17 +66,31 @@ class PacketByteBuffer extends PacketDataSerializer {
|
|||
}
|
||||
|
||||
void writeUUID(UUID uuid) {
|
||||
super.a(uuid);
|
||||
serializer.a(uuid);
|
||||
}
|
||||
|
||||
<T> void writeDataWatcherEntry(DataWatcherKey<T> key, T value) {
|
||||
writeByte(key.getIndex());
|
||||
serializer.writeByte(key.getIndex());
|
||||
writeVarInt(key.getSerializerTypeID());
|
||||
key.getSerializer().a(this, value);
|
||||
key.getSerializer().a(serializer, value);
|
||||
}
|
||||
|
||||
void writeDataWatcherEntriesEnd() {
|
||||
writeByte(0xFF);
|
||||
serializer.writeByte(0xFF);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
serializer.clear();
|
||||
}
|
||||
|
||||
<T extends Packet<?>> T writeDataTo(T packet) {
|
||||
try {
|
||||
packet.a(serializer);
|
||||
return packet;
|
||||
} catch (IOException e) {
|
||||
// Never thrown by the implementations
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ package me.filoghost.holographicdisplays.nms.v1_14_R1;
|
|||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.EventLoop;
|
||||
import me.filoghost.fcommons.logging.ErrorCollector;
|
||||
import me.filoghost.fcommons.logging.Log;
|
||||
import me.filoghost.fcommons.reflection.ReflectField;
|
||||
|
@ -100,8 +101,12 @@ public class VersionNMSManager implements NMSManager {
|
|||
PlayerConnection playerConnection = ((CraftPlayer) player).getHandle().playerConnection;
|
||||
NetworkManager networkManager = playerConnection.a();
|
||||
Channel channel = networkManager.channel;
|
||||
if (channel == null) {
|
||||
return;
|
||||
}
|
||||
EventLoop eventLoop = channel.eventLoop();
|
||||
|
||||
channel.eventLoop().execute(() -> {
|
||||
Runnable safeModifierTask = () -> {
|
||||
if (!player.isOnline()) {
|
||||
return;
|
||||
}
|
||||
|
@ -110,7 +115,13 @@ public class VersionNMSManager implements NMSManager {
|
|||
} catch (Exception e) {
|
||||
Log.warning(NMSErrors.EXCEPTION_MODIFYING_CHANNEL_PIPELINE, e);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (eventLoop.inEventLoop()) {
|
||||
safeModifierTask.run();
|
||||
} else {
|
||||
eventLoop.execute(safeModifierTask);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,8 +10,6 @@ import net.minecraft.server.v1_14_R1.Packet;
|
|||
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
abstract class VersionNMSPacket implements PacketGroup {
|
||||
|
||||
@Override
|
||||
|
@ -21,14 +19,4 @@ abstract class VersionNMSPacket implements PacketGroup {
|
|||
|
||||
abstract Packet<?> getRawPacket();
|
||||
|
||||
protected static <T extends Packet<?>> T writeData(T packet, PacketByteBuffer packetByteBuffer) {
|
||||
try {
|
||||
packet.a(packetByteBuffer);
|
||||
return packet;
|
||||
} catch (IOException e) {
|
||||
// Never thrown by the implementations
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<parent>
|
||||
<groupId>me.filoghost.holographicdisplays</groupId>
|
||||
<artifactId>holographicdisplays-nms</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<version>3.0.5-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>holographicdisplays-nms-v1_15_r1</artifactId>
|
||||
|
|
|
@ -38,7 +38,7 @@ class EntityLivingSpawnNMSPacket extends VersionNMSPacket {
|
|||
packetByteBuffer.writeShort(0);
|
||||
packetByteBuffer.writeShort(0);
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutSpawnEntityLiving(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutSpawnEntityLiving());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -14,7 +14,7 @@ class EntityMetadataNMSPacket extends VersionNMSPacket {
|
|||
private final Packet<?> rawPacket;
|
||||
|
||||
private EntityMetadataNMSPacket(PacketByteBuffer packetByteBuffer) {
|
||||
this.rawPacket = writeData(new PacketPlayOutEntityMetadata(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutEntityMetadata());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,7 +19,7 @@ class EntityMountNMSPacket extends VersionNMSPacket {
|
|||
packetByteBuffer.writeVarInt(vehicleEntityID.getNumericID());
|
||||
packetByteBuffer.writeVarIntArray(passengerEntityID.getNumericID());
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutMount(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutMount());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -42,7 +42,7 @@ class EntitySpawnNMSPacket extends VersionNMSPacket {
|
|||
packetByteBuffer.writeShort(0);
|
||||
packetByteBuffer.writeShort(0);
|
||||
|
||||
this.rawPacket = writeData(new PacketPlayOutSpawnEntity(), packetByteBuffer);
|
||||
this.rawPacket = packetByteBuffer.writeDataTo(new PacketPlayOutSpawnEntity());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue