From f24b660b35527fe7df235b0e4572cd1287b0cdb7 Mon Sep 17 00:00:00 2001 From: StarWishsama Date: Sun, 8 Dec 2024 17:00:03 +0800 Subject: [PATCH] fix(uni): retrieve data only from main thread (#979) --- .../norain/slimefun4/utils/ClassUtil.java | 16 ---------- .../city/norain/slimefun4/utils/TaskUtil.java | 29 +++++++++++++++++++ .../controller/BlockDataController.java | 4 +++ .../storage/util/StorageCacheUtils.java | 11 +++++-- .../slimefun4/api/ErrorReport.java | 4 +-- .../items/androids/ProgrammableAndroid.java | 4 ++- 6 files changed, 46 insertions(+), 22 deletions(-) delete mode 100644 src/main/java/city/norain/slimefun4/utils/ClassUtil.java create mode 100644 src/main/java/city/norain/slimefun4/utils/TaskUtil.java diff --git a/src/main/java/city/norain/slimefun4/utils/ClassUtil.java b/src/main/java/city/norain/slimefun4/utils/ClassUtil.java deleted file mode 100644 index ea25c7cd37..0000000000 --- a/src/main/java/city/norain/slimefun4/utils/ClassUtil.java +++ /dev/null @@ -1,16 +0,0 @@ -package city.norain.slimefun4.utils; - -import lombok.experimental.UtilityClass; - -@UtilityClass -public class ClassUtil { - public String getCallerClass() { - StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); - - if (stackTrace.length > 3) { - return stackTrace[3].getClassName(); - } else { - return null; - } - } -} diff --git a/src/main/java/city/norain/slimefun4/utils/TaskUtil.java b/src/main/java/city/norain/slimefun4/utils/TaskUtil.java new file mode 100644 index 0000000000..5d7e407cea --- /dev/null +++ b/src/main/java/city/norain/slimefun4/utils/TaskUtil.java @@ -0,0 +1,29 @@ +package city.norain.slimefun4.utils; + +import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.logging.Level; +import lombok.SneakyThrows; +import lombok.experimental.UtilityClass; +import org.bukkit.Bukkit; + +@UtilityClass +public class TaskUtil { + @SneakyThrows + public T runSyncMethod(Callable callable) { + if (Bukkit.isPrimaryThread()) { + return callable.call(); + } else { + try { + return Bukkit.getScheduler() + .callSyncMethod(Slimefun.instance(), callable) + .get(1, TimeUnit.SECONDS); + } catch (TimeoutException e) { + Slimefun.logger().log(Level.WARNING, "Timeout when executing sync method", e); + return null; + } + } + } +} diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataController.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataController.java index e097ae654e..9cae260171 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataController.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataController.java @@ -323,6 +323,10 @@ public void removeBlock(Location l) { Slimefun.getBlockDataService() .getUniversalDataUUID(l.getBlock()) .ifPresent(uuid -> removeUniversalBlockData(uuid, l)); + } else { + Slimefun.runSync(() -> Slimefun.getBlockDataService() + .getUniversalDataUUID(l.getBlock()) + .ifPresent(uuid -> removeUniversalBlockData(uuid, l))); } }); diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/util/StorageCacheUtils.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/util/StorageCacheUtils.java index 066f7974d8..bce00384b3 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/util/StorageCacheUtils.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/util/StorageCacheUtils.java @@ -1,6 +1,7 @@ package com.xzavier0722.mc.plugin.slimefun4.storage.util; import city.norain.slimefun4.api.menu.UniversalMenu; +import city.norain.slimefun4.utils.TaskUtil; import com.google.common.base.Preconditions; import com.xzavier0722.mc.plugin.slimefun4.storage.callback.IAsyncReadCallback; import com.xzavier0722.mc.plugin.slimefun4.storage.controller.ADataContainer; @@ -37,7 +38,9 @@ public static boolean hasBlock(Location l) { @ParametersAreNonnullByDefault public static boolean hasUniversalBlock(Location l) { - return Slimefun.getBlockDataService().getUniversalDataUUID(l.getBlock()).isPresent(); + return TaskUtil.runSyncMethod(() -> Slimefun.getBlockDataService() + .getUniversalDataUUID(l.getBlock()) + .isPresent()); } @ParametersAreNonnullByDefault @@ -162,9 +165,11 @@ public static void removeData(Location loc, String key) { */ @ParametersAreNonnullByDefault @Nullable public static SlimefunUniversalBlockData getUniversalBlock(Block block) { - var uuid = Slimefun.getBlockDataService().getUniversalDataUUID(block); + return TaskUtil.runSyncMethod(() -> { + var uuid = Slimefun.getBlockDataService().getUniversalDataUUID(block); - return uuid.map(id -> getUniversalBlock(id, block.getLocation())).orElse(null); + return uuid.map(id -> getUniversalBlock(id, block.getLocation())).orElse(null); + }); } /** diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java index 60bd92e010..0559343845 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java @@ -109,7 +109,7 @@ public ErrorReport(T throwable, Location l, SlimefunItem item) { Slimefun.getDatabaseManager().getBlockDataController().getBlockData(l); if (blockData == null) { - Slimefun.getBlockDataService() + Slimefun.runSync(() -> Slimefun.getBlockDataService() .getUniversalDataUUID(l.getBlock()) .ifPresentOrElse( uuid -> { @@ -127,7 +127,7 @@ public ErrorReport(T throwable, Location l, SlimefunItem item) { stream.println("该方块没有任何数据."); } }, - () -> stream.println("该方块没有任何数据.")); + () -> stream.println("该方块没有任何数据."))); } else { stream.println(" 数据加载状态: " + blockData.isDataLoaded()); stream.println(" 物品栏: " + (blockData.getBlockMenu() != null)); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java index 33e22d6469..8046de2a6c 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java @@ -2,6 +2,7 @@ import city.norain.slimefun4.api.menu.UniversalMenu; import city.norain.slimefun4.api.menu.UniversalMenuPreset; +import city.norain.slimefun4.utils.TaskUtil; import com.xzavier0722.mc.plugin.slimefun4.storage.controller.SlimefunUniversalBlockData; import com.xzavier0722.mc.plugin.slimefun4.storage.controller.SlimefunUniversalData; import com.xzavier0722.mc.plugin.slimefun4.storage.controller.attributes.UniversalBlock; @@ -989,7 +990,8 @@ public boolean onClick( public void addItems(Block b, ItemStack... items) { Validate.notNull(b, "The Block cannot be null."); - Optional uuid = Slimefun.getBlockDataService().getUniversalDataUUID(b); + Optional uuid = + TaskUtil.runSyncMethod(() -> Slimefun.getBlockDataService().getUniversalDataUUID(b)); if (uuid.isEmpty()) { throw new IllegalStateException("Android missing uuid");