9
0
mirror of https://github.com/Xiao-MoMi/Custom-Nameplates.git synced 2025-12-19 15:09:23 +00:00
This commit is contained in:
XiaoMoMi
2025-06-30 02:05:35 +08:00
parent 3cbf4698ed
commit 2ebb781721
20 changed files with 66 additions and 197 deletions

View File

@@ -15,6 +15,7 @@ dependencies {
compileOnly("net.kyori:adventure-text-serializer-gson:${rootProject.properties["adventure_bundle_version"]}")
compileOnly("net.kyori:adventure-text-minimessage:${rootProject.properties["adventure_bundle_version"]}")
compileOnly("net.kyori:adventure-text-serializer-gson:${rootProject.properties["adventure_bundle_version"]}")
compileOnly("net.kyori:adventure-text-serializer-json-legacy-impl:${rootProject.properties["adventure_bundle_version"]}")
// YAML
implementation(files("libs/boosted-yaml-${rootProject.properties["boosted_yaml_version"]}.jar"))
// Cache

View File

@@ -23,6 +23,8 @@ import net.kyori.adventure.key.Key;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.text.serializer.json.JSONOptions;
import net.kyori.adventure.text.serializer.json.legacyimpl.NBTLegacyHoverEventSerializer;
import net.momirealms.customnameplates.api.ConfigManager;
import net.momirealms.customnameplates.api.CustomNameplates;
@@ -52,7 +54,19 @@ public class AdventureHelper {
private AdventureHelper() {
this.miniMessage = MiniMessage.builder().build();
this.miniMessageStrict = MiniMessage.builder().strict(true).build();
this.gsonComponentSerializer = GsonComponentSerializer.builder().build();
GsonComponentSerializer.Builder builder = GsonComponentSerializer.builder();
if (!VersionHelper.isVersionNewerThan1_20_5()) {
builder.legacyHoverEventSerializer(NBTLegacyHoverEventSerializer.get());
builder.editOptions((b) -> b.value(JSONOptions.EMIT_HOVER_SHOW_ENTITY_ID_AS_INT_ARRAY, false));
}
if (!VersionHelper.isVersionNewerThan1_21_5()) {
builder.editOptions((b) -> {
b.value(JSONOptions.EMIT_CLICK_EVENT_TYPE, JSONOptions.ClickEventValueMode.CAMEL_CASE);
b.value(JSONOptions.EMIT_HOVER_EVENT_TYPE, JSONOptions.HoverEventValueMode.CAMEL_CASE);
b.value(JSONOptions.EMIT_HOVER_SHOW_ENTITY_KEY_AS_TYPE_AND_UUID_AS_ID, true);
});
}
this.gsonComponentSerializer = builder.build();
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(1, r -> {
Thread thread = Executors.defaultThreadFactory().newThread(r);

View File

@@ -19,18 +19,12 @@ package net.momirealms.customnameplates.api.network;
import net.momirealms.customnameplates.common.event.Cancellable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
/**
* Represents a packet event, which can be cancelled and supports delayed tasks that are executed later.
*/
public class PacketEvent implements Cancellable {
private boolean cancelled;
private List<Runnable> delayedTasks = null;
private final Object packet;
/**
@@ -51,27 +45,6 @@ public class PacketEvent implements Cancellable {
return packet;
}
/**
* Adds a task to be executed later, after the event has been processed.
*
* @param task the task to be added
*/
public void addDelayedTask(Runnable task) {
if (delayedTasks == null) {
delayedTasks = new ArrayList<>();
}
delayedTasks.add(task);
}
/**
* Returns the list of delayed tasks to be executed.
*
* @return a list of tasks, or an empty list if no tasks are added
*/
public List<Runnable> getDelayedTasks() {
return Optional.ofNullable(delayedTasks).orElse(Collections.emptyList());
}
/**
* Checks if the event has been cancelled.
*

View File

@@ -33,6 +33,7 @@ import net.momirealms.customnameplates.api.feature.image.Animation;
import net.momirealms.customnameplates.api.feature.image.Image;
import net.momirealms.customnameplates.api.feature.nameplate.Nameplate;
import net.momirealms.customnameplates.api.feature.pack.ResourcePackManager;
import net.momirealms.customnameplates.api.helper.AdventureHelper;
import net.momirealms.customnameplates.api.util.CharacterUtils;
import net.momirealms.customnameplates.api.util.ZipUtils;
import org.apache.commons.io.FileUtils;
@@ -72,46 +73,16 @@ public class ResourcePackManagerImpl implements ResourcePackManager {
if (ConfigManager.enableShader()) {
if (ConfigManager.minPackVersion() >= 21.4f) {
this.generateShaders("ResourcePack" + File.separator + "overlay_1_21_4" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, true);
try {
FileUtils.copyDirectory(
new File(plugin.getDataFolder(), "ResourcePack" + File.separator + "overlay_1_21_4"),
new File(plugin.getDataFolder(), "ResourcePack")
);
FileUtils.deleteDirectory(new File(plugin.getDataFolder(), "ResourcePack" + File.separator + "overlay_1_21_4"));
} catch (IOException e) {
throw new RuntimeException(e);
}
// do nothing
} else if (ConfigManager.minPackVersion() >= 21.2f) {
this.generateShaders("ResourcePack" + File.separator + "overlay_1_21_2" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, true);
try {
FileUtils.copyDirectory(
new File(plugin.getDataFolder(), "ResourcePack" + File.separator + "overlay_1_21_2"),
new File(plugin.getDataFolder(), "ResourcePack")
);
FileUtils.deleteDirectory(new File(plugin.getDataFolder(), "ResourcePack" + File.separator + "overlay_1_21_2"));
} catch (IOException e) {
throw new RuntimeException(e);
}
this.generateShaders("ResourcePack" + File.separator + "overlay_1_21_4" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, true);
} else if (ConfigManager.minPackVersion() >= 20.5f) {
this.generateShaders("ResourcePack" + File.separator + "overlay_1_20_5" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, true);
try {
FileUtils.copyDirectory(
new File(plugin.getDataFolder(), "ResourcePack" + File.separator + "overlay_1_20_5"),
new File(plugin.getDataFolder(), "ResourcePack")
);
FileUtils.deleteDirectory(new File(plugin.getDataFolder(), "ResourcePack" + File.separator + "overlay_1_20_5"));
} catch (IOException e) {
throw new RuntimeException(e);
}
this.generateShaders("ResourcePack" + File.separator + "overlay_1_21_2" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, true);
this.generateShaders("ResourcePack" + File.separator + "overlay_1_21_4" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, true);
} else {
this.generateShaders("ResourcePack" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, false);
this.generateShaders("ResourcePack" + File.separator + "overlay_1_20_2" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, false);
this.generateShaders("ResourcePack" + File.separator + "overlay_1_20_5" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, true);
this.generateShaders("ResourcePack" + File.separator + "overlay_1_21_2" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, true);
this.generateShaders("ResourcePack" + File.separator + "overlay_1_21_4" + File.separator + "assets" + File.separator + "minecraft" + File.separator + "shaders" + File.separator + "core" + File.separator, true);
}
}

View File

@@ -1,24 +0,0 @@
#version 150
#moj_import <minecraft:fog.glsl>
uniform sampler2D Sampler0;
uniform vec4 ColorModulator;
uniform float FogStart;
uniform float FogEnd;
uniform vec4 FogColor;
in float vertexDistance;
in vec4 vertexColor;
in vec2 texCoord0;
out vec4 fragColor;
void main() {
vec4 color = texture(Sampler0, texCoord0) * vertexColor * ColorModulator;
if (color.a < 0.1) {
discard;
}
fragColor = linear_fog(color, vertexDistance, FogStart, FogEnd, FogColor);
}

View File

@@ -1,17 +0,0 @@
{
"vertex": "minecraft:core/rendertype_text",
"fragment": "minecraft:core/rendertype_text",
"samplers": [
{ "name": "Sampler0" },
{ "name": "Sampler2" }
],
"uniforms": [
{ "name": "ModelViewMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
{ "name": "ProjMat", "type": "matrix4x4", "count": 16, "values": [ 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0 ] },
{ "name": "ColorModulator", "type": "float", "count": 4, "values": [ 1.0, 1.0, 1.0, 1.0 ] },
{ "name": "FogStart", "type": "float", "count": 1, "values": [ 0.0 ] },
{ "name": "FogEnd", "type": "float", "count": 1, "values": [ 1.0 ] },
{ "name": "FogColor", "type": "float", "count": 4, "values": [ 0.0, 0.0, 0.0, 0.0 ] },
{ "name": "FogShape", "type": "int", "count": 1, "values": [ 0 ] }
]
}

View File

@@ -1,26 +0,0 @@
#version 150
#moj_import <minecraft:fog.glsl>
in vec3 Position;
in vec4 Color;
in vec2 UV0;
in ivec2 UV2;
uniform sampler2D Sampler2;
uniform mat4 ModelViewMat;
uniform mat4 ProjMat;
uniform int FogShape;
out float vertexDistance;
out vec4 vertexColor;
out vec2 texCoord0;
void main() {
gl_Position = ProjMat * ModelViewMat * vec4(Position, 1.0);
vertexDistance = fog_distance(Position, FogShape);
vertexColor = Color * texelFetch(Sampler2, UV2 / 16, 0);
texCoord0 = UV0;
}

View File

@@ -9,6 +9,13 @@
},
"overlays": {
"entries": [
{
"formats": {
"min_inclusive": 13,
"max_inclusive": 31
},
"directory": "overlay_1_20_2"
},
{
"formats": {
"min_inclusive": 32,
@@ -22,13 +29,6 @@
"max_inclusive": 45
},
"directory": "overlay_1_21_2"
},
{
"formats": {
"min_inclusive": 46,
"max_inclusive": 99
},
"directory": "overlay_1_21_4"
}
]
}

View File

@@ -9,19 +9,19 @@
},
"overlays": {
"entries": [
{
"formats": {
"min_inclusive": 32,
"max_inclusive": 41
},
"directory": "overlay_1_20_5"
},
{
"formats": {
"min_inclusive": 42,
"max_inclusive": 45
},
"directory": "overlay_1_21_2"
},
{
"formats": {
"min_inclusive": 46,
"max_inclusive": 99
},
"directory": "overlay_1_21_4"
}
]
}

View File

@@ -11,10 +11,10 @@
"entries": [
{
"formats": {
"min_inclusive": 46,
"max_inclusive": 99
"min_inclusive": 42,
"max_inclusive": 45
},
"directory": "overlay_1_21_4"
"directory": "overlay_1_21_2"
}
]
}

View File

@@ -46,7 +46,7 @@ integrations:
resource-pack:
disable-generation-on-start: false # Allow resource pack generation at server start
supported-version:
# You can specify a version like 1.20.1, 1.21.4 or use SERVER_VERSION
# You can specify a version like 1.20.2, 1.21.4 or use SERVER_VERSION
min: "SERVER_VERSION"
namespace: "nameplates" # Namespace for the resource pack
font: "default" # Default font used
@@ -57,6 +57,8 @@ resource-pack:
images: 'font/images/' # Path for other images
bubbles: 'font/bubbles/' # Path for bubble text images
space-split: 'font/base/' # Path for base font images
# Using shader is dangerous and might conflict with other plugin
# It's recommended to disable shaders on a 1.21.4+ server
shader:
enable: true # Enable shader generation
hide-scoreboard-number: false # Hiding of scoreboard numbers

View File

@@ -1,6 +1,6 @@
# Project settings
# Rule: [major update].[feature update].[bug fix]
project_version=3.0.28
project_version=3.0.29
config_version=38
project_group=net.momirealms
@@ -18,7 +18,7 @@ asm_commons_version=9.8
jar_relocator_version=1.7
h2_driver_version=2.3.232
sqlite_driver_version=3.49.1.0
adventure_bundle_version=4.21.0
adventure_bundle_version=4.23.0
adventure_platform_version=4.4.0
cloud_core_version=2.0.0
cloud_services_version=2.0.0

View File

@@ -27,6 +27,7 @@ dependencies {
implementation("net.kyori:adventure-text-serializer-gson:${rootProject.properties["adventure_bundle_version"]}") {
exclude("com.google.code.gson", "gson")
}
implementation("net.kyori:adventure-text-serializer-json-legacy-impl:${rootProject.properties["adventure_bundle_version"]}")
// BStats
compileOnly("org.bstats:bstats-bukkit:${rootProject.properties["bstats_version"]}")

View File

@@ -297,11 +297,6 @@ public class BukkitNetworkManager implements PacketSender, PipelineInjector {
plugin.getPlatform().onPacketSend(player, event);
if (event.cancelled()) return;
super.write(context, packet, channelPromise);
channelPromise.addListener((p) -> {
for (Runnable task : event.getDelayedTasks()) {
task.run();
}
});
} catch (Throwable e) {
plugin.getPluginLogger().severe("An error occurred when reading packets", e);
super.write(context, packet, channelPromise);

View File

@@ -482,37 +482,21 @@ public class BukkitPlatform implements Platform {
@Override
public Object jsonToMinecraftComponent(String json) {
if (VersionHelper.isVersionNewerThan1_20_5()) {
try {
return Reflections.method$Component$Serializer$fromJson.invoke(null, json, Reflections.instance$MinecraftRegistry);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
} else {
try {
return Reflections.method$CraftChatMessage$fromJSON.invoke(null, json);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
}
@Override
public String minecraftComponentToJson(Object component) {
if (VersionHelper.isVersionNewerThan1_20_5()) {
try {
return (String) Reflections.method$Component$Serializer$toJson.invoke(null, component, Reflections.instance$MinecraftRegistry);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
} else {
try {
return (String) Reflections.method$CraftChatMessage$toJSON.invoke(null, component);
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
}
@Override
public Placeholder registerPlatformPlaceholder(String id) {

View File

@@ -28,6 +28,8 @@ package net.momirealms.customnameplates.bukkit;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import net.kyori.adventure.text.Component;
import net.momirealms.customnameplates.api.helper.AdventureHelper;
import net.momirealms.customnameplates.bukkit.util.Reflections;
import net.momirealms.customnameplates.common.sender.Sender;
import net.momirealms.customnameplates.common.sender.SenderFactory;
import net.momirealms.customnameplates.common.util.Tristate;
@@ -69,8 +71,14 @@ public class BukkitSenderFactory extends SenderFactory<BukkitCustomNameplates, C
@Override
protected void sendMessage(CommandSender sender, Component message) {
// we can safely send async for players and the console - otherwise, send it sync
if (sender instanceof Player || sender instanceof ConsoleCommandSender || sender instanceof RemoteConsoleCommandSender) {
if (sender instanceof Player player) {
try {
Object packet = Reflections.constructor$ClientboundSystemChatPacket.newInstance(getPlugin().getPlatform().jsonToMinecraftComponent(AdventureHelper.gson().serialize(message)), false);
getPlugin().getPacketSender().sendPacket(getPlugin().getPlayer(player.getUniqueId()), packet);
} catch (ReflectiveOperationException e) {
getPlugin().getPluginLogger().warn("Failed to send message to player " + sender.getName(), e);
}
} else if (sender instanceof ConsoleCommandSender || sender instanceof RemoteConsoleCommandSender) {
getAudience(sender).sendMessage(message);
} else {
getPlugin().getScheduler().executeSync(() -> getAudience(sender).sendMessage(message));

View File

@@ -124,6 +124,12 @@ public class Reflections {
clazz$ClientboundSystemChatPacket, String.class, 0
);
public static final Constructor<?> constructor$ClientboundSystemChatPacket = requireNonNull(
ReflectionUtils.getConstructor(
clazz$ClientboundSystemChatPacket, clazz$Component, boolean.class
)
);
public static final Class<?> clazz$CraftChatMessage = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleCBClass("util.CraftChatMessage")
@@ -317,30 +323,11 @@ public class Reflections {
}
}
public static final Class<?> clazz$Component$Serializer = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("network.chat.Component$Serializer"),
BukkitReflectionUtils.assembleMCClass("network.chat.IChatBaseComponent$ChatSerializer")
)
);
public static final Class<?> clazz$HolderLookup$Provider = ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("core.HolderLookup$Provider"),
BukkitReflectionUtils.assembleMCClass(VersionHelper.isVersionNewerThan1_20_5() ? "core.HolderLookup$a" : "core.HolderLookup$b")
);
public static final Method method$Component$Serializer$fromJson = ReflectionUtils.getMethod(
clazz$Component$Serializer,
new String[] { "fromJson", "a" },
String.class, clazz$HolderLookup$Provider
);
public static final Method method$Component$Serializer$toJson = ReflectionUtils.getMethod(
clazz$Component$Serializer,
new String[] { "toJson", "a" },
clazz$Component, clazz$HolderLookup$Provider
);
public static final Class<?> clazz$ClientboundBundlePacket = requireNonNull(
ReflectionUtils.getClazz(
BukkitReflectionUtils.assembleMCClass("network.protocol.game.ClientboundBundlePacket")