perf: 重写部分代码

This commit is contained in:
2023-05-30 04:09:54 +08:00
parent 76c3f76329
commit cfa382b71c
20 changed files with 287 additions and 598 deletions

View File

@@ -25,6 +25,9 @@ subprojects {
dependencies {
// https://mvnrepository.com/artifact/org.jetbrains/annotations
compileOnly 'org.jetbrains:annotations:23.0.0'
// https://mvnrepository.com/artifact/org.projectlombok/lombok
compileOnly 'org.projectlombok:lombok:1.18.28'
annotationProcessor 'org.projectlombok:lombok:1.18.28'
}
java {

View File

@@ -10,7 +10,8 @@ dependencies {
api(project(":hamster-core-common")) { transitive = false }
shade(project(":hamster-core-common")) { transitive = false }
compileOnly('org.spigotmc:spigot-api:1.19.2-R0.1-SNAPSHOT') {
//noinspection VulnerableLibrariesLocal
compileOnly('org.spigotmc:spigot-api:1.19.4-R0.1-SNAPSHOT') {
exclude group: "com.google.code.gson"
}
@@ -21,6 +22,7 @@ dependencies {
// https://mvnrepository.com/artifact/com.google.code.gson/gson
//noinspection GradlePackageUpdate
//noinspection VulnerableLibrariesLocal
compileOnly 'com.google.code.gson:gson:2.8.0'
// https://mvnrepository.com/artifact/net.kyori/adventure-platform-bukkit
@@ -61,6 +63,7 @@ tasks.build.dependsOn(shadowJar)
tasks.register("oldJar", Jar) {
dependsOn("jar")
//noinspection GrDeprecatedAPIUsage
setClassifier("Old")
from([
tasks.jar.outputs.files.collect {

View File

@@ -10,10 +10,11 @@ import cn.hamster3.mc.plugin.core.bukkit.listener.CallbackListener;
import cn.hamster3.mc.plugin.core.bukkit.listener.DebugListener;
import cn.hamster3.mc.plugin.core.bukkit.page.handler.PageHandler;
import cn.hamster3.mc.plugin.core.bukkit.page.listener.PageListener;
import cn.hamster3.mc.plugin.core.bukkit.util.ItemStackAdapter;
import cn.hamster3.mc.plugin.core.common.constant.CoreConstantObjects;
import cn.hamster3.mc.plugin.core.bukkit.util.serializer.ItemStackAdapter;
import cn.hamster3.mc.plugin.core.bukkit.util.serializer.PotionEffectAdapter;
import cn.hamster3.mc.plugin.core.common.data.DisplayMessage;
import cn.hamster3.mc.plugin.core.common.misc.MessageTypeAdapter;
import cn.hamster3.mc.plugin.core.common.util.serializer.MessageTypeAdapter;
import cn.hamster3.mc.plugin.core.common.util.CoreUtils;
import com.google.gson.GsonBuilder;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.Bukkit;
@@ -22,6 +23,7 @@ import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.potion.PotionEffect;
import java.util.logging.Logger;
@@ -43,9 +45,10 @@ public class HamsterCorePlugin extends JavaPlugin {
saveDefaultConfig();
reloadConfig();
logger.info("已读取配置文件.");
CoreConstantObjects.GSON = new GsonBuilder()
CoreUtils.GSON = new GsonBuilder()
.registerTypeAdapter(DisplayMessage.class, MessageTypeAdapter.INSTANCE)
.registerTypeAdapter(ItemStack.class, ItemStackAdapter.INSTANCE)
.registerTypeAdapter(PotionEffect.class, PotionEffectAdapter.INSTANCE)
.create();
CoreBukkitAPI.init();
logger.info("已初始化 CoreBukkitAPI.");
@@ -83,9 +86,9 @@ public class HamsterCorePlugin extends JavaPlugin {
Logger logger = getLogger();
long start = System.currentTimeMillis();
logger.info("仓鼠核心正在关闭...");
CoreConstantObjects.WORKER_EXECUTOR.shutdownNow();
CoreUtils.WORKER_EXECUTOR.shutdownNow();
logger.info("已暂停 WORKER_EXECUTOR.");
CoreConstantObjects.SCHEDULED_EXECUTOR.shutdownNow();
CoreUtils.SCHEDULED_EXECUTOR.shutdownNow();
logger.info("已暂停 SCHEDULED_EXECUTOR.");
for (Player player : Bukkit.getOnlinePlayers()) {
InventoryView view = player.getOpenInventory();

View File

@@ -3,7 +3,6 @@ package cn.hamster3.mc.plugin.core.bukkit.command.lore;
import cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin;
import cn.hamster3.mc.plugin.core.bukkit.command.ParentCommand;
import cn.hamster3.mc.plugin.core.bukkit.command.lore.sub.*;
import cn.hamster3.mc.plugin.core.common.util.CoreUtils;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;
@@ -30,7 +29,9 @@ public final class ParentLoreCommand extends ParentCommand {
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, String[] args) {
CoreUtils.replaceColorCode(args);
for (int i = 0; i < args.length; i++) {
args[i] = args[i].replace("&", "§");
}
return super.onCommand(sender, command, label, args);
}
}

View File

@@ -47,8 +47,12 @@ public enum CoreMessage {
return;
}
for (CoreMessage value : values()) {
ConfigurationSection section = config.getConfigurationSection(value.name());
if (section == null) {
continue;
}
try {
value.message = BukkitUtils.getDisplayMessage(config.getConfigurationSection(value.name()));
value.message = BukkitUtils.getDisplayMessage(section);
} catch (Exception e) {
plugin.getLogger().warning("加载消息设置 " + value.name() + " 时遇到了一个异常: ");
e.printStackTrace();
@@ -65,16 +69,6 @@ public enum CoreMessage {
message.show(audience);
}
@SuppressWarnings("unused")
public void show(CommandSender sender, TextReplacementConfig replacement) {
if (message == null) {
sender.sendMessage(name());
return;
}
Audience audience = CoreBukkitAPI.getInstance().getAudienceProvider().sender(sender);
message.show(audience, replacement);
}
@SuppressWarnings("unused")
public void show(CommandSender sender, TextReplacementConfig... replacement) {
if (message == null) {

View File

@@ -1,26 +0,0 @@
package cn.hamster3.mc.plugin.core.bukkit.util;
import cn.hamster3.mc.plugin.core.bukkit.listener.CallbackListener;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.HumanEntity;
import java.util.concurrent.CompletableFuture;
@SuppressWarnings("unused")
public final class BukkitCallbackUtils {
private BukkitCallbackUtils() {
}
public static CompletableFuture<String> getPlayerChat(HumanEntity player) {
return CallbackListener.CHATS.computeIfAbsent(player.getUniqueId(), o -> new CompletableFuture<>());
}
public static CompletableFuture<Block> getPlayerClickedBlock(HumanEntity player) {
return CallbackListener.BLOCKS.computeIfAbsent(player.getUniqueId(), o -> new CompletableFuture<>());
}
public static CompletableFuture<Entity> getPlayerClickedEntity(HumanEntity player) {
return CallbackListener.ENTITIES.computeIfAbsent(player.getUniqueId(), o -> new CompletableFuture<>());
}
}

View File

@@ -1,108 +0,0 @@
package cn.hamster3.mc.plugin.core.bukkit.util;
import cn.hamster3.mc.plugin.core.bukkit.HamsterCorePlugin;
import com.comphenix.protocol.utility.StreamSerializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.bukkit.Bukkit;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.logging.Level;
@SuppressWarnings("unused")
public final class BukkitSerializeUtils {
private BukkitSerializeUtils() {
}
@Nullable
public static String serializeItemStack(@Nullable ItemStack stack) {
if (BukkitUtils.isEmptyItemStack(stack)) {
return null;
}
if (!Bukkit.getPluginManager().isPluginEnabled("ProtocolLib")) {
HamsterCorePlugin.getInstance().getLogger().warning("ProtocolLib 前置插件未启用, 无法序列化物品!");
return null;
}
try {
return StreamSerializer.getDefault().serializeItemStack(stack);
} catch (IOException e) {
HamsterCorePlugin.getInstance().getLogger().log(Level.WARNING, "序列化物品 " + stack + " 时出错!", e);
return null;
}
}
@Nullable
public static ItemStack deserializeItemStack(@Nullable String s) {
if (s == null) {
return null;
}
if (!Bukkit.getPluginManager().isPluginEnabled("ProtocolLib")) {
HamsterCorePlugin.getInstance().getLogger().warning("ProtocolLib 前置插件未启用, 无法反序列化物品!");
return null;
}
try {
return StreamSerializer.getDefault().deserializeItemStack(s);
} catch (Exception e) {
HamsterCorePlugin.getInstance().getLogger().log(Level.WARNING, "反序列化物品 " + s + " 时出错!", e);
return null;
}
}
@NotNull
public static ItemStack deserializeItemStack(@Nullable String s, @NotNull ItemStack defaultValue) {
if (s == null) {
return defaultValue;
}
if (!Bukkit.getPluginManager().isPluginEnabled("ProtocolLib")) {
HamsterCorePlugin.getInstance().getLogger().warning("ProtocolLib 前置插件未启用, 无法反序列化物品!");
return defaultValue;
}
try {
return StreamSerializer.getDefault().deserializeItemStack(s);
} catch (Exception e) {
HamsterCorePlugin.getInstance().getLogger().log(Level.WARNING, "反序列化物品 " + s + " 时出错!", e);
return defaultValue;
}
}
@Nullable
public static JsonObject serializePotionEffect(@Nullable PotionEffect effect) {
if (effect == null) {
return null;
}
try {
JsonObject object = new JsonObject();
object.addProperty("type", effect.getType().getName());
object.addProperty("duration", effect.getDuration());
object.addProperty("amplifier", effect.getAmplifier());
return object;
} catch (Exception e) {
HamsterCorePlugin.getInstance().getLogger().log(Level.WARNING, "序列化药水效果 " + effect + " 时出错!", e);
}
return null;
}
@Nullable
public static PotionEffect deserializePotionEffect(@Nullable JsonElement element) {
if (element == null || !element.isJsonObject()) {
return null;
}
JsonObject effectObject = element.getAsJsonObject();
try {
//noinspection ConstantConditions
return new PotionEffect(
PotionEffectType.getByName(effectObject.get("type").getAsString()),
effectObject.get("duration").getAsInt(),
effectObject.get("amplifier").getAsInt()
);
} catch (Exception e) {
HamsterCorePlugin.getInstance().getLogger().log(Level.WARNING, "反序列化药水效果 " + element + " 时出错!", e);
return null;
}
}
}

View File

@@ -1,17 +1,25 @@
package cn.hamster3.mc.plugin.core.bukkit.util;
import cn.hamster3.mc.plugin.core.bukkit.listener.CallbackListener;
import cn.hamster3.mc.plugin.core.common.data.DisplayMessage;
import com.comphenix.protocol.utility.StreamSerializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Entity;
import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.plugin.Plugin;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -22,6 +30,7 @@ import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
@SuppressWarnings("unused")
public final class BukkitUtils {
@@ -174,10 +183,8 @@ public final class BukkitUtils {
}
}
public static DisplayMessage getDisplayMessage(ConfigurationSection config) {
if (config == null) {
return null;
}
@NotNull
public static DisplayMessage getDisplayMessage(@NotNull ConfigurationSection config) {
DisplayMessage displayMessage = new DisplayMessage();
String message = config.getString("message");
if (message != null) {
@@ -185,14 +192,14 @@ public final class BukkitUtils {
}
String actionbar = config.getString("actionbar");
if (actionbar != null) {
displayMessage.setActionBar(actionbar);
displayMessage.setActionbar(actionbar);
}
String title = config.getString("title");
String subtitle = config.getString("subtitle");
if (title != null || subtitle != null) {
displayMessage.setTitle(
title == null ? "" : title,
subtitle == null ? "" : subtitle,
title,
subtitle,
config.getInt("fade-in", 10),
config.getInt("stay", 70),
config.getInt("fade-out", 20)
@@ -227,4 +234,75 @@ public final class BukkitUtils {
}
return YamlConfiguration.loadConfiguration(file);
}
@NotNull
public static String serializeItemStack(@Nullable ItemStack stack) {
if (!Bukkit.getPluginManager().isPluginEnabled("ProtocolLib")) {
throw new RuntimeException("ProtocolLib 前置插件未启用, 无法序列化物品!");
}
try {
return StreamSerializer.getDefault().serializeItemStack(stack);
} catch (IOException e) {
throw new RuntimeException("序列化物品时出现了一个异常!", e);
}
}
@NotNull
public static ItemStack deserializeItemStack(@NotNull String s) {
if (!Bukkit.getPluginManager().isPluginEnabled("ProtocolLib")) {
throw new RuntimeException("ProtocolLib 前置插件未启用, 无法反序列化物品!");
}
try {
return StreamSerializer.getDefault().deserializeItemStack(s);
} catch (IOException e) {
throw new RuntimeException("反序列化物品时出现了一个异常!", e);
}
}
@NotNull
public static ItemStack deserializeItemStack(@NotNull String s, @NotNull ItemStack defaultValue) {
if (!Bukkit.getPluginManager().isPluginEnabled("ProtocolLib")) {
return defaultValue;
}
try {
return StreamSerializer.getDefault().deserializeItemStack(s);
} catch (IOException e) {
return defaultValue;
}
}
@NotNull
public static JsonObject serializePotionEffect(@NotNull PotionEffect effect) {
JsonObject object = new JsonObject();
object.addProperty("type", effect.getType().getName());
object.addProperty("duration", effect.getDuration());
object.addProperty("amplifier", effect.getAmplifier());
return object;
}
@NotNull
public static PotionEffect deserializePotionEffect(@NotNull JsonElement element) {
JsonObject effectObject = element.getAsJsonObject();
//noinspection ConstantConditions
return new PotionEffect(
PotionEffectType.getByName(effectObject.get("type").getAsString()),
effectObject.get("duration").getAsInt(),
effectObject.get("amplifier").getAsInt()
);
}
@NotNull
public static CompletableFuture<String> getPlayerChat(HumanEntity player) {
return CallbackListener.CHATS.computeIfAbsent(player.getUniqueId(), o -> new CompletableFuture<>());
}
@NotNull
public static CompletableFuture<Block> getPlayerClickedBlock(HumanEntity player) {
return CallbackListener.BLOCKS.computeIfAbsent(player.getUniqueId(), o -> new CompletableFuture<>());
}
@NotNull
public static CompletableFuture<Entity> getPlayerClickedEntity(HumanEntity player) {
return CallbackListener.ENTITIES.computeIfAbsent(player.getUniqueId(), o -> new CompletableFuture<>());
}
}

View File

@@ -1,11 +1,12 @@
package cn.hamster3.mc.plugin.core.bukkit.util;
package cn.hamster3.mc.plugin.core.bukkit.util.serializer;
import cn.hamster3.mc.plugin.core.bukkit.util.BukkitUtils;
import com.google.gson.*;
import org.bukkit.inventory.ItemStack;
import java.lang.reflect.Type;
public class ItemStackAdapter implements JsonSerializer<ItemStack>, JsonDeserializer<ItemStack> {
public final class ItemStackAdapter implements JsonSerializer<ItemStack>, JsonDeserializer<ItemStack> {
public static final ItemStackAdapter INSTANCE = new ItemStackAdapter();
private ItemStackAdapter() {
@@ -16,15 +17,15 @@ public class ItemStackAdapter implements JsonSerializer<ItemStack>, JsonDeserial
if (json.isJsonNull()) {
return null;
}
return BukkitSerializeUtils.deserializeItemStack(json.getAsString());
return BukkitUtils.deserializeItemStack(json.getAsString());
}
@Override
public JsonElement serialize(ItemStack src, Type typeOfSrc, JsonSerializationContext context) {
String s = BukkitSerializeUtils.serializeItemStack(src);
if (s == null) {
if (src == null) {
return JsonNull.INSTANCE;
}
String s = BukkitUtils.serializeItemStack(src);
return new JsonPrimitive(s);
}
}

View File

@@ -0,0 +1,30 @@
package cn.hamster3.mc.plugin.core.bukkit.util.serializer;
import cn.hamster3.mc.plugin.core.bukkit.util.BukkitUtils;
import com.google.gson.*;
import org.bukkit.potion.PotionEffect;
import java.lang.reflect.Type;
public final class PotionEffectAdapter implements JsonSerializer<PotionEffect>, JsonDeserializer<PotionEffect> {
public static final PotionEffectAdapter INSTANCE = new PotionEffectAdapter();
private PotionEffectAdapter() {
}
@Override
public PotionEffect deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
if (json.isJsonNull()) {
return null;
}
return BukkitUtils.deserializePotionEffect(json);
}
@Override
public JsonElement serialize(PotionEffect src, Type typeOfSrc, JsonSerializationContext context) {
if (src == null) {
return JsonNull.INSTANCE;
}
return BukkitUtils.serializePotionEffect(src);
}
}

View File

@@ -11,6 +11,7 @@ dependencies {
shade(project(":hamster-core-common")) { transitive = false }
oldJar(project(":hamster-core-common")) { transitive = false }
//noinspection VulnerableLibrariesLocal
compileOnly 'net.md-5:bungeecord-api:1.19-R0.1-SNAPSHOT'
// https://mvnrepository.com/artifact/net.kyori/adventure-platform-bungeecord
@@ -38,7 +39,7 @@ processResources {
}
tasks.compileJava.dependsOn(":hamster-core-common:build")
tasks.create("shadowJar", Jar) {
tasks.register("shadowJar", Jar) {
dependsOn("jar")
from([
tasks.jar.outputs.files.collect {
@@ -52,8 +53,9 @@ tasks.create("shadowJar", Jar) {
}
tasks.build.dependsOn(shadowJar)
tasks.create("oldJar", Jar) {
tasks.register("oldJar", Jar) {
dependsOn("jar")
//noinspection GrDeprecatedAPIUsage
setClassifier("Old")
from([
tasks.jar.outputs.files.collect {

View File

@@ -1,7 +1,7 @@
package cn.hamster3.mc.plugin.core.bungee;
import cn.hamster3.mc.plugin.core.bungee.api.CoreBungeeAPI;
import cn.hamster3.mc.plugin.core.common.constant.CoreConstantObjects;
import cn.hamster3.mc.plugin.core.common.util.CoreUtils;
import net.kyori.adventure.platform.bungeecord.BungeeAudiences;
import net.md_5.bungee.api.plugin.Plugin;
@@ -43,9 +43,9 @@ public class HamsterCorePlugin extends Plugin {
Logger logger = getLogger();
long start = System.currentTimeMillis();
logger.info("仓鼠核心正在关闭...");
CoreConstantObjects.WORKER_EXECUTOR.shutdownNow();
CoreUtils.WORKER_EXECUTOR.shutdownNow();
logger.info("已暂停 WORKER_EXECUTOR.");
CoreConstantObjects.SCHEDULED_EXECUTOR.shutdownNow();
CoreUtils.SCHEDULED_EXECUTOR.shutdownNow();
logger.info("已暂停 SCHEDULED_EXECUTOR.");
long time = System.currentTimeMillis() - start;
logger.info("仓鼠核心已关闭,总计耗时 " + time + " ms.");

View File

@@ -3,6 +3,7 @@ setArchivesBaseName("HamsterCore-Common")
dependencies {
// https://mvnrepository.com/artifact/com.google.code.gson/gson
//noinspection GradlePackageUpdate
//noinspection VulnerableLibrariesLocal
compileOnly 'com.google.code.gson:gson:2.8.0'
// https://mvnrepository.com/artifact/com.squareup.okhttp3/okhttp

View File

@@ -1,20 +0,0 @@
package cn.hamster3.mc.plugin.core.common.constant;
import cn.hamster3.mc.plugin.core.common.util.CoreUtils;
import com.google.gson.Gson;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
@SuppressWarnings("unused")
public final class CoreConstantObjects {
public static final ExecutorService WORKER_EXECUTOR = CoreUtils.WORKER_EXECUTOR;
public static final ScheduledExecutorService SCHEDULED_EXECUTOR = CoreUtils.SCHEDULED_EXECUTOR;
public static Gson GSON = CoreUtils.GSON;
public static Gson GSON_HUMAN = CoreUtils.GSON_HUMAN;
private CoreConstantObjects() {
}
}

View File

@@ -1,8 +1,8 @@
package cn.hamster3.mc.plugin.core.common.data;
import cn.hamster3.mc.plugin.core.common.util.SerializeUtils;
import com.google.gson.JsonElement;
import cn.hamster3.mc.plugin.core.common.util.CoreUtils;
import com.google.gson.JsonObject;
import lombok.Data;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.sound.Sound;
@@ -14,7 +14,8 @@ import net.kyori.adventure.util.Ticks;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@SuppressWarnings("unused")
@SuppressWarnings({"unused", "UnusedReturnValue", "PatternValidation"})
@Data
public class DisplayMessage {
private Component message;
private Component actionbar;
@@ -27,40 +28,22 @@ public class DisplayMessage {
public DisplayMessage() {
}
public static DisplayMessage message(@NotNull String message) {
return new DisplayMessage().setMessage(message);
@NotNull
public static DisplayMessage fromJson(@NotNull JsonObject object) {
DisplayMessage displayMessage = new DisplayMessage();
if (object.has("message")) {
displayMessage.message = GsonComponentSerializer.gson().deserializeFromTree(object.get("message")).compact();
}
public static DisplayMessage message(@NotNull Component message) {
return new DisplayMessage().setMessage(message);
if (object.has("actionbar")) {
displayMessage.actionbar = GsonComponentSerializer.gson().deserializeFromTree(object.get("actionbar")).compact();
}
public static DisplayMessage actionbar(@NotNull String actionbar) {
return new DisplayMessage().setActionBar(actionbar);
if (object.has("title")) {
displayMessage.title = CoreUtils.deserializeTitle(object.getAsJsonObject("title"));
}
public static DisplayMessage actionbar(@NotNull Component actionbar) {
return new DisplayMessage().setActionBar(actionbar);
if (object.has("sound")) {
displayMessage.sound = CoreUtils.deserializeSound(object.getAsJsonObject("sound"));
}
public static DisplayMessage title(@Nullable String title, @Nullable String subtitle) {
return new DisplayMessage().setTitle(title, subtitle);
}
public static DisplayMessage title(@Nullable String title, @Nullable String subtitle, int fadeIn, int stay, int fadeOut) {
return new DisplayMessage().setTitle(title, subtitle, fadeIn, stay, fadeOut);
}
public static DisplayMessage sound(@NotNull String sound) {
return new DisplayMessage().setSound(sound);
}
public static DisplayMessage sound(@NotNull String sound, float volume, float pitch) {
return new DisplayMessage().setSound(sound, volume, pitch);
}
public static DisplayMessage sound(@NotNull Sound sound) {
return new DisplayMessage().setSound(sound);
return displayMessage;
}
public void show(@NotNull Audience audience) {
@@ -86,94 +69,15 @@ public class DisplayMessage {
copy().replace(replacements).show(audience);
}
public DisplayMessage replace(@NotNull TextReplacementConfig replacement) {
if (message != null) {
message = message.replaceText(replacement).compact();
}
if (actionbar != null) {
actionbar = actionbar.replaceText(replacement).compact();
}
if (title != null) {
title = Title.title(
title.title().replaceText(replacement).compact(),
title.subtitle().replaceText(replacement).compact(),
title.times()
);
}
return this;
}
public DisplayMessage replace(@NotNull TextReplacementConfig... replacements) {
if (message != null) {
for (TextReplacementConfig replacement : replacements) {
message = message.replaceText(replacement).compact();
}
}
if (actionbar != null) {
for (TextReplacementConfig replacement : replacements) {
actionbar = actionbar.replaceText(replacement).compact();
}
}
if (title != null) {
for (TextReplacementConfig replacement : replacements) {
title = Title.title(
title.title().replaceText(replacement).compact(),
title.subtitle().replaceText(replacement).compact(),
title.times()
);
}
}
@NotNull
public DisplayMessage setMessage(@NotNull String message) {
this.message = Component.text(message);
return this;
}
@NotNull
public JsonObject saveToJson() {
JsonObject object = new JsonObject();
if (message != null) {
object.add("message", GsonComponentSerializer.gson().serializeToTree(message));
}
if (actionbar != null) {
object.add("actionbar", GsonComponentSerializer.gson().serializeToTree(actionbar));
}
if (title != null) {
object.add("title", SerializeUtils.serializeTitle(title));
}
if (sound != null) {
object.add("sound", SerializeUtils.serializeSound(sound));
}
return object;
}
@NotNull
public DisplayMessage setMessage(@Nullable String message) {
this.message = message == null ? null : Component.text(message);
return this;
}
@NotNull
public DisplayMessage setMessage(@Nullable Component message) {
this.message = message == null ? null : message.compact();
return this;
}
@NotNull
public DisplayMessage setActionBar(@Nullable String actionbar) {
this.actionbar = actionbar == null ? null : Component.text(actionbar);
return this;
}
@NotNull
public DisplayMessage setActionBar(@Nullable Component actionbar) {
this.actionbar = actionbar == null ? null : actionbar.compact();
return this;
}
@NotNull
public DisplayMessage setTitle(@Nullable String title, @Nullable String subtitle) {
this.title = Title.title(
title == null ? Component.empty() : Component.text(title),
subtitle == null ? Component.empty() : Component.text(subtitle)
);
public DisplayMessage setActionbar(@NotNull String actionbar) {
this.actionbar = Component.text(actionbar);
return this;
}
@@ -192,108 +96,78 @@ public class DisplayMessage {
}
@NotNull
public DisplayMessage setTitle(@Nullable Component title, @Nullable Component subtitle) {
this.title = Title.title(
title == null ? Component.empty() : title.compact(),
subtitle == null ? Component.empty() : subtitle.compact()
);
return this;
}
@NotNull
public DisplayMessage setTitle(@Nullable Component title, @Nullable Component subtitle, int fadeIn, int stay, int fadeOut) {
this.title = Title.title(
title == null ? Component.empty() : title.compact(),
subtitle == null ? Component.empty() : subtitle.compact(),
Title.Times.times(
Ticks.duration(fadeIn),
Ticks.duration(stay),
Ticks.duration(fadeOut)
)
);
return this;
}
@NotNull
public DisplayMessage setTitle(@Nullable Title title) {
this.title = title;
return this;
}
@NotNull
@SuppressWarnings("PatternValidation")
public DisplayMessage setSound(@Nullable String sound) {
this.sound = sound == null ? null : Sound.sound(Key.key(sound), Sound.Source.MASTER, 1, 1);
return this;
}
@NotNull
@SuppressWarnings("PatternValidation")
public DisplayMessage setSound(@NotNull String namespace, @NotNull String path) {
this.sound = Sound.sound(Key.key(namespace, path), Sound.Source.MASTER, 1, 1);
return this;
}
@NotNull
@SuppressWarnings("PatternValidation")
public DisplayMessage setSound(@NotNull String sound, float volume, float pitch) {
this.sound = Sound.sound(Key.key(sound), Sound.Source.MASTER, volume, pitch);
return this;
}
@NotNull
@SuppressWarnings("PatternValidation")
public DisplayMessage setSound(@NotNull String namespace, @NotNull String value, float volume, float pitch) {
this.sound = Sound.sound(Key.key(namespace, value), Sound.Source.MASTER, volume, pitch);
return this;
}
@NotNull
@SuppressWarnings("PatternValidation")
public DisplayMessage setSound(@NotNull String namespace, @NotNull String value, @NotNull Sound.Source source, float volume, float pitch) {
this.sound = Sound.sound(Key.key(namespace, value), source, volume, pitch);
return this;
}
@NotNull
public DisplayMessage setSound(@Nullable Sound sound) {
this.sound = sound;
return this;
public DisplayMessage replace(@NotNull TextReplacementConfig... replacements) {
DisplayMessage copy = copy();
if (copy.message != null) {
for (TextReplacementConfig replacement : replacements) {
copy.message = copy.message.replaceText(replacement).compact();
}
}
if (copy.actionbar != null) {
for (TextReplacementConfig replacement : replacements) {
copy.actionbar = copy.actionbar.replaceText(replacement).compact();
}
}
if (copy.title != null) {
for (TextReplacementConfig replacement : replacements) {
copy.title = Title.title(
title.title().replaceText(replacement).compact(),
title.subtitle().replaceText(replacement).compact(),
title.times()
);
}
}
return copy;
}
@NotNull
public DisplayMessage fromJson(@NotNull JsonElement element) {
if (!element.isJsonObject()) {
message = Component.text(element.toString());
return this;
public JsonObject toJson() {
JsonObject object = new JsonObject();
if (message != null) {
object.add("message", GsonComponentSerializer.gson().serializeToTree(message));
}
JsonObject object = element.getAsJsonObject();
if (object.has("message")) {
message = GsonComponentSerializer.gson().deserializeFromTree(object.get("message")).compact();
if (actionbar != null) {
object.add("actionbar", GsonComponentSerializer.gson().serializeToTree(actionbar));
}
if (object.has("actionbar")) {
actionbar = GsonComponentSerializer.gson().deserializeFromTree(object.get("actionbar")).compact();
if (title != null) {
object.add("title", CoreUtils.serializeTitle(title));
}
if (object.has("title")) {
title = SerializeUtils.deserializeTitle(object.getAsJsonObject("title"));
if (sound != null) {
object.add("sound", CoreUtils.serializeSound(sound));
}
if (object.has("sound")) {
sound = SerializeUtils.deserializeSound(object.getAsJsonObject("sound"));
}
return this;
return object;
}
@NotNull
public DisplayMessage copy() {
return new DisplayMessage()
.setMessage(message)
.setActionBar(actionbar)
.setTitle(title)
.setSound(sound);
DisplayMessage copy = new DisplayMessage();
copy.message = message;
copy.actionbar = actionbar;
copy.title = title;
copy.sound = sound;
return copy;
}
@Override
public String toString() {
return saveToJson().toString();
return toJson().toString();
}
}

View File

@@ -1,6 +1,6 @@
package cn.hamster3.mc.plugin.core.common.thread;
import cn.hamster3.mc.plugin.core.common.constant.CoreConstantObjects;
import cn.hamster3.mc.plugin.core.common.util.CoreUtils;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
@@ -23,7 +23,7 @@ public abstract class CountdownThread implements Runnable {
}
public void start(long initialDelay) {
future = CoreConstantObjects.SCHEDULED_EXECUTOR.scheduleWithFixedDelay(this, initialDelay, interval, TimeUnit.MILLISECONDS);
future = CoreUtils.SCHEDULED_EXECUTOR.scheduleWithFixedDelay(this, initialDelay, interval, TimeUnit.MILLISECONDS);
}
@Override

View File

@@ -1,4 +1,4 @@
package cn.hamster3.mc.plugin.core.common.misc;
package cn.hamster3.mc.plugin.core.common.thread;
import org.jetbrains.annotations.NotNull;

View File

@@ -1,18 +1,21 @@
package cn.hamster3.mc.plugin.core.common.util;
import cn.hamster3.mc.plugin.core.common.data.DisplayMessage;
import cn.hamster3.mc.plugin.core.common.misc.MessageTypeAdapter;
import cn.hamster3.mc.plugin.core.common.misc.NamedThreadFactory;
import cn.hamster3.mc.plugin.core.common.util.serializer.MessageTypeAdapter;
import cn.hamster3.mc.plugin.core.common.thread.NamedThreadFactory;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.title.Title;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.time.Duration;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
@@ -72,135 +75,82 @@ public final class CoreUtils {
}
/**
* 替换颜色代码
* 将 adventure 中的 title 对象序列化为 json
*
* @param string 要替换的字符串
* @return 替换后的字符串
* @param title -
* @return -
*/
@Nullable
public static String replaceColorCode(@Nullable String string) {
if (string == null) return null;
return string.replace("&", "§");
@NotNull
public static JsonObject serializeTitle(@NotNull Title title) {
JsonObject object = new JsonObject();
object.add("title", GsonComponentSerializer.gson().serializeToTree(title.title()));
object.add("subtitle", GsonComponentSerializer.gson().serializeToTree(title.subtitle()));
Title.Times times = title.times();
if (times != null) {
object.add("times", serializeTitleTimes(times));
}
return object;
}
/**
* 替换颜色代码
* <p>
* 添加这个方法是因为 ConfigurationSection 中的 getString 方法有 @Nullable 注解
* <p>
* 导致 idea 会弹出某些警告,让人非常不爽
* 将 json 反序列化为 adventure 中的 title
*
* @param string 要替换的字符串
* @param defaultValue 若 string 为空则使用该字符串
* @return 替换后的字符串
* @param object -
* @return -
*/
@NotNull
public static String replaceColorCode(@Nullable String string, @NotNull String defaultValue) {
if (string == null) return defaultValue;
return string.replace("&", "§");
}
/**
* 替换颜色代码
*
* @param strings 要替换的字符串
* @return 替换后的字符串
*/
@NotNull
public static ArrayList<String> replaceColorCode(@Nullable Iterable<String> strings) {
ArrayList<String> list = new ArrayList<>();
if (strings == null) return list;
for (String s : strings) {
list.add(replaceColorCode(s));
}
return list;
}
/**
* 替换颜色代码
*
* @param strings 要替换的字符串
*/
public static void replaceColorCode(@NotNull String[] strings) {
for (int i = 0; i < strings.length; i++) {
strings[i] = strings[i].replace("&", "§");
public static Title deserializeTitle(@NotNull JsonObject object) {
if (object.has("times")) {
return Title.title(
GsonComponentSerializer.gson().deserializeFromTree(object.get("title")),
GsonComponentSerializer.gson().deserializeFromTree(object.get("subtitle")),
deserializeTitleTimes(object.getAsJsonObject("times"))
);
} else {
return Title.title(
GsonComponentSerializer.gson().deserializeFromTree(object.get("title")),
GsonComponentSerializer.gson().deserializeFromTree(object.get("subtitle"))
);
}
}
@NotNull
public static String[] replaceStringList(@NotNull String[] strings, @NotNull String key, @NotNull String value) {
for (int i = 0; i < strings.length; i++) {
strings[i] = strings[i].replace(key, value);
}
return strings;
public static JsonObject serializeTitleTimes(@NotNull Title.Times times) {
JsonObject object = new JsonObject();
object.addProperty("fadeIn", times.fadeIn().toMillis());
object.addProperty("stay", times.stay().toMillis());
object.addProperty("fadeOut", times.fadeOut().toMillis());
return object;
}
@NotNull
public static List<String> replaceStringList(@NotNull Iterable<String> strings, @NotNull String key, @NotNull String value) {
ArrayList<String> list = new ArrayList<>();
for (String s : strings) {
list.add(s.replace(key, value));
}
return list;
public static Title.Times deserializeTitleTimes(@NotNull JsonObject object) {
return Title.Times.times(
Duration.ofMillis(object.get("fadeIn").getAsLong()),
Duration.ofMillis(object.get("stay").getAsLong()),
Duration.ofMillis(object.get("fadeOut").getAsLong())
);
}
@NotNull
public static List<String> replaceStringList(@NotNull List<String> strings, @NotNull String key, @NotNull String value) {
strings.replaceAll(s -> s.replace(key, value));
return strings;
}
public static boolean startsWithIgnoreCase(@NotNull String string, @NotNull String prefix) {
return string.regionMatches(true, 0, prefix, 0, prefix.length());
}
public static boolean endsWithIgnoreCase(@NotNull String string, @NotNull String suffix) {
int strOffset = string.length() - suffix.length();
return string.regionMatches(true, strOffset, suffix, 0, suffix.length());
public static JsonObject serializeSound(@NotNull Sound sound) {
JsonObject object = new JsonObject();
object.addProperty("key", sound.name().asString());
object.addProperty("source", sound.source().name());
object.addProperty("volume", sound.volume());
object.addProperty("pitch", sound.pitch());
return object;
}
@NotNull
public static ArrayList<String> startsWith(@NotNull Iterable<String> strings, @NotNull String with) {
ArrayList<String> list = new ArrayList<>();
for (String string : strings) {
if (string.startsWith(with)) {
list.add(string);
}
}
return list;
}
@NotNull
public static ArrayList<String> endsWith(@NotNull Iterable<String> strings, @NotNull String with) {
ArrayList<String> list = new ArrayList<>();
for (String string : strings) {
if (string.endsWith(with)) {
list.add(string);
}
}
return list;
}
@NotNull
public static ArrayList<String> startsWithIgnoreCase(@NotNull Iterable<String> strings, @NotNull String start) {
ArrayList<String> list = new ArrayList<>();
for (String string : strings) {
if (startsWithIgnoreCase(string, start)) {
list.add(string);
}
}
return list;
}
@NotNull
public static ArrayList<String> endsWithIgnoreCase(@NotNull Iterable<String> strings, @NotNull String end) {
ArrayList<String> list = new ArrayList<>();
for (String string : strings) {
if (endsWithIgnoreCase(string, end)) {
list.add(string);
}
}
return list;
@SuppressWarnings("PatternValidation")
public static Sound deserializeSound(@NotNull JsonObject object) {
return Sound.sound(
Key.key(object.get("key").getAsString()),
Sound.Source.valueOf(object.get("source").getAsString()),
object.get("volume").getAsFloat(),
object.get("pitch").getAsFloat()
);
}
@SuppressWarnings("unchecked")

View File

@@ -1,97 +0,0 @@
package cn.hamster3.mc.plugin.core.common.util;
import com.google.gson.JsonObject;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.kyori.adventure.title.Title;
import org.jetbrains.annotations.NotNull;
import java.time.Duration;
/**
* 序列化相关工具
*/
public final class SerializeUtils {
private SerializeUtils() {
}
/**
* 将 adventure 中的 title 对象序列化为 json
*
* @param title -
* @return -
*/
@NotNull
public static JsonObject serializeTitle(@NotNull Title title) {
JsonObject object = new JsonObject();
object.add("title", GsonComponentSerializer.gson().serializeToTree(title.title()));
object.add("subtitle", GsonComponentSerializer.gson().serializeToTree(title.subtitle()));
Title.Times times = title.times();
if (times != null) {
object.add("times", serializeTitleTimes(times));
}
return object;
}
/**
* 将 json 反序列化为 adventure 中的 title
*
* @param object -
* @return -
*/
@NotNull
public static Title deserializeTitle(@NotNull JsonObject object) {
if (object.has("times")) {
return Title.title(
GsonComponentSerializer.gson().deserializeFromTree(object.get("title")),
GsonComponentSerializer.gson().deserializeFromTree(object.get("subtitle")),
deserializeTitleTimes(object.getAsJsonObject("times"))
);
} else {
return Title.title(
GsonComponentSerializer.gson().deserializeFromTree(object.get("title")),
GsonComponentSerializer.gson().deserializeFromTree(object.get("subtitle"))
);
}
}
@NotNull
public static JsonObject serializeTitleTimes(@NotNull Title.Times times) {
JsonObject object = new JsonObject();
object.addProperty("fadeIn", times.fadeIn().toMillis());
object.addProperty("stay", times.stay().toMillis());
object.addProperty("fadeOut", times.fadeOut().toMillis());
return object;
}
@NotNull
public static Title.Times deserializeTitleTimes(@NotNull JsonObject object) {
return Title.Times.times(
Duration.ofMillis(object.get("fadeIn").getAsLong()),
Duration.ofMillis(object.get("stay").getAsLong()),
Duration.ofMillis(object.get("fadeOut").getAsLong())
);
}
@NotNull
public static JsonObject serializeSound(@NotNull Sound sound) {
JsonObject object = new JsonObject();
object.addProperty("key", sound.name().asString());
object.addProperty("source", sound.source().name());
object.addProperty("volume", sound.volume());
object.addProperty("pitch", sound.pitch());
return object;
}
@NotNull
@SuppressWarnings("PatternValidation")
public static Sound deserializeSound(@NotNull JsonObject object) {
return Sound.sound(
Key.key(object.get("key").getAsString()),
Sound.Source.valueOf(object.get("source").getAsString()),
object.get("volume").getAsFloat(),
object.get("pitch").getAsFloat()
);
}
}

View File

@@ -1,4 +1,4 @@
package cn.hamster3.mc.plugin.core.common.misc;
package cn.hamster3.mc.plugin.core.common.util.serializer;
import cn.hamster3.mc.plugin.core.common.data.DisplayMessage;
import com.google.gson.*;
@@ -13,11 +13,11 @@ public class MessageTypeAdapter implements JsonSerializer<DisplayMessage>, JsonD
@Override
public DisplayMessage deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
return new DisplayMessage().fromJson(json);
return DisplayMessage.fromJson(json.getAsJsonObject());
}
@Override
public JsonElement serialize(DisplayMessage src, Type typeOfSrc, JsonSerializationContext context) {
return src.saveToJson();
return src.toJson();
}
}