diff --git a/api/src/main/java/net/momirealms/customfishing/api/CustomFishingPlugin.java b/api/src/main/java/net/momirealms/customfishing/api/CustomFishingPlugin.java index c5be8207..7755f6c2 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/CustomFishingPlugin.java +++ b/api/src/main/java/net/momirealms/customfishing/api/CustomFishingPlugin.java @@ -144,4 +144,6 @@ public abstract class CustomFishingPlugin extends JavaPlugin { public CompetitionManager getCompetitionManager() { return competitionManager; } + + public abstract void debug(String message); } diff --git a/plugin/src/main/java/net/momirealms/customfishing/CustomFishingPluginImpl.java b/plugin/src/main/java/net/momirealms/customfishing/CustomFishingPluginImpl.java index e93ec799..a2d5a540 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/CustomFishingPluginImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/CustomFishingPluginImpl.java @@ -239,6 +239,7 @@ public class CustomFishingPluginImpl extends CustomFishingPlugin { return protocolManager; } + @Override public void debug(String message) { if (!CFConfig.debug) return; LogUtils.info(message); diff --git a/plugin/src/main/java/net/momirealms/customfishing/command/sub/CompetitionCommand.java b/plugin/src/main/java/net/momirealms/customfishing/command/sub/CompetitionCommand.java index 8f66e716..ec0a6b50 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/command/sub/CompetitionCommand.java +++ b/plugin/src/main/java/net/momirealms/customfishing/command/sub/CompetitionCommand.java @@ -18,7 +18,10 @@ package net.momirealms.customfishing.command.sub; import dev.jorel.commandapi.CommandAPICommand; +import dev.jorel.commandapi.IStringTooltip; +import dev.jorel.commandapi.StringTooltip; import dev.jorel.commandapi.arguments.ArgumentSuggestions; +import dev.jorel.commandapi.arguments.BooleanArgument; import dev.jorel.commandapi.arguments.StringArgument; import net.momirealms.customfishing.adventure.AdventureManagerImpl; import net.momirealms.customfishing.api.CustomFishingPlugin; @@ -52,7 +55,10 @@ public class CompetitionCommand { ArgumentSuggestions.strings(allCompetitions) ) ); - if (CFConfig.redisRanking) command.withOptionalArguments(new StringArgument("-allservers")); + if (CFConfig.redisRanking) command.withOptionalArguments(new BooleanArgument("servers").replaceSuggestions(ArgumentSuggestions.stringsWithTooltips(new IStringTooltip[]{ + StringTooltip.ofString("true", "all the servers that connected to Redis"), + StringTooltip.ofString("false", "only this server") + }))); command.executes((sender, args) -> { String id = (String) args.get(0); assert id != null; @@ -60,7 +66,7 @@ public class CompetitionCommand { AdventureManagerImpl.getInstance().sendMessageWithPrefix(sender, CFLocale.MSG_Competition_Not_Exist.replace("{id}", id)); return; } - boolean allServer = args.getOrDefault(1, "").equals("-allservers"); + boolean allServer = (boolean) args.getOrDefault("servers", false); CustomFishingPlugin.get().getCompetitionManager().startCompetition(id, true, allServer); }); return command; @@ -68,9 +74,12 @@ public class CompetitionCommand { private CommandAPICommand getCompetitionEndCommand() { var command = new CommandAPICommand("end"); - if (CFConfig.redisRanking) command.withOptionalArguments(new StringArgument("-allservers")); + if (CFConfig.redisRanking) command.withOptionalArguments(new BooleanArgument("servers").replaceSuggestions(ArgumentSuggestions.stringsWithTooltips(new IStringTooltip[]{ + StringTooltip.ofString("true", "all the servers that connected to Redis"), + StringTooltip.ofString("false", "only this server") + }))); command.executes((sender, args) -> { - boolean allServer = args.getOrDefault(1, "").equals("-allservers"); + boolean allServer = (boolean) args.getOrDefault("servers", false); if (allServer) { RedisManager.getInstance().sendRedisMessage("cf_competition", "end"); } else { @@ -88,9 +97,12 @@ public class CompetitionCommand { private CommandAPICommand getCompetitionStopCommand() { var command = new CommandAPICommand("stop"); - if (CFConfig.redisRanking) command.withOptionalArguments(new StringArgument("-allservers")); + if (CFConfig.redisRanking) command.withOptionalArguments(new BooleanArgument("servers").replaceSuggestions(ArgumentSuggestions.stringsWithTooltips(new IStringTooltip[]{ + StringTooltip.ofString("true", "all the servers that connected to Redis"), + StringTooltip.ofString("false", "only this server") + }))); command.executes((sender, args) -> { - boolean allServer = args.getOrDefault(1, "").equals("-allservers"); + boolean allServer = (boolean) args.getOrDefault("servers", false); if (allServer) { RedisManager.getInstance().sendRedisMessage("cf_competition", "stop"); } else { diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingManagerImpl.java index 9e4ff51b..0a7f3583 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/fishing/FishingManagerImpl.java @@ -213,6 +213,20 @@ public class FishingManagerImpl implements Listener, FishingManager { } } + @EventHandler + public void onLeftClick(PlayerInteractEvent event) { + if (event.useItemInHand() == Event.Result.DENY) + return; + if (event.getAction() != org.bukkit.event.block.Action.LEFT_CLICK_AIR) + return; + GamingPlayer gamingPlayer = gamingPlayerMap.get(event.getPlayer().getUniqueId()); + if (gamingPlayer != null) { + if (gamingPlayer.onLeftClick()) { + event.setCancelled(true); + } + } + } + @EventHandler public void onInteractWithUtils(PlayerInteractEvent event) { if (event.useItemInHand() == Event.Result.DENY) @@ -220,6 +234,9 @@ public class FishingManagerImpl implements Listener, FishingManager { ItemStack itemStack = event.getPlayer().getInventory().getItemInMainHand(); if (itemStack.getType() == Material.AIR) return; + if (event.getAction() != org.bukkit.event.block.Action.RIGHT_CLICK_AIR || event.getAction() != org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK) + return; + String id = plugin.getItemManager().getAnyItemID(itemStack); EffectCarrier carrier = plugin.getEffectManager().getEffect("util", id); if (carrier == null) @@ -665,27 +682,21 @@ public class FishingManagerImpl implements Listener, FishingManager { @Override public void startFishingGame(Player player, Condition condition, Effect effect) { Map gameWithWeight = plugin.getRequirementManager().getGameWithWeight(condition); - if (CFConfig.debug) { - plugin.debug(gameWithWeight.toString()); - } + plugin.debug(gameWithWeight.toString()); String random = WeightUtils.getRandom(gameWithWeight); Optional> gamePair = plugin.getGameManager().getGame(random); if (gamePair.isEmpty()) { LogUtils.warn(String.format("Game %s doesn't exist!", random)); return; } - if (CFConfig.debug) { - plugin.debug("Game: " + random); - } + plugin.debug("Game: " + random); startFishingGame(player, gamePair.get().left().getGameSetting(effect), gamePair.get().right()); } @Override public void startFishingGame(Player player, GameSettings settings, GameInstance gameInstance) { - if (CFConfig.debug) { - plugin.debug("Difficulty:" + settings.getDifficulty()); - plugin.debug("Time:" + settings.getTime()); - } + plugin.debug("Difficulty:" + settings.getDifficulty()); + plugin.debug("Time:" + settings.getTime()); Optional hook = getHook(player.getUniqueId()); if (hook.isPresent()) { this.gamingPlayerMap.put(player.getUniqueId(), gameInstance.start(player, hook.get(), settings)); diff --git a/plugin/src/main/java/net/momirealms/customfishing/storage/StorageManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/storage/StorageManagerImpl.java index fd582d4e..55860c73 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/storage/StorageManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/storage/StorageManagerImpl.java @@ -232,7 +232,7 @@ public class StorageManagerImpl implements StorageManager, Listener { public RedisGetDataTask(UUID uuid) { this.uuid = uuid; - this.task = plugin.getScheduler().runTaskAsyncTimer(this, 200, 200, TimeUnit.MILLISECONDS); + this.task = plugin.getScheduler().runTaskAsyncTimer(this, 0, 333, TimeUnit.MILLISECONDS); } @Override @@ -244,7 +244,7 @@ public class StorageManagerImpl implements StorageManager, Listener { task.cancel(); return; } - if (triedTimes >= 10) { + if (triedTimes >= 6) { waitForDataLockRelease(uuid, 3); return; } diff --git a/plugin/src/main/java/net/momirealms/customfishing/storage/method/database/nosql/RedisManager.java b/plugin/src/main/java/net/momirealms/customfishing/storage/method/database/nosql/RedisManager.java index c5d26b8c..0f097bf4 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/storage/method/database/nosql/RedisManager.java +++ b/plugin/src/main/java/net/momirealms/customfishing/storage/method/database/nosql/RedisManager.java @@ -20,14 +20,12 @@ package net.momirealms.customfishing.storage.method.database.nosql; import net.momirealms.customfishing.api.CustomFishingPlugin; import net.momirealms.customfishing.api.data.PlayerData; import net.momirealms.customfishing.api.data.StorageType; -import net.momirealms.customfishing.api.scheduler.CancellableTask; import net.momirealms.customfishing.api.util.LogUtils; import net.momirealms.customfishing.storage.method.AbstractStorage; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.YamlConfiguration; import org.jetbrains.annotations.NotNull; import redis.clients.jedis.*; -import redis.clients.jedis.exceptions.JedisConnectionException; import redis.clients.jedis.exceptions.JedisException; import redis.clients.jedis.resps.Tuple; @@ -36,7 +34,6 @@ import java.time.Duration; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.TimeUnit; public class RedisManager extends AbstractStorage { @@ -47,9 +44,6 @@ public class RedisManager extends AbstractStorage { private String host; private JedisPoolConfig jedisPoolConfig; private boolean useSSL; - private Jedis subscriber; - private JedisPubSub pubSub; - private CancellableTask checkConnectionTask; public RedisManager(CustomFishingPlugin plugin) { super(plugin); @@ -95,78 +89,68 @@ public class RedisManager extends AbstractStorage { } try (Jedis jedis = jedisPool.getResource()) { jedis.ping(); + LogUtils.warn("Redis server connected."); } catch (JedisException e) { LogUtils.warn("Failed to connect redis.", e); } - this.checkConnectionTask = plugin.getScheduler().runTaskAsyncTimer(() -> { - try { - pubSub.ping(); - } catch (JedisConnectionException e) { - subscribe(); - } - }, 30, 30, TimeUnit.SECONDS); + subscribe(); } @Override public void disable() { this.removeServerPlayers(plugin.getStorageManager().getUniqueID()); - if (checkConnectionTask != null && !checkConnectionTask.isCancelled()) - checkConnectionTask.cancel(); if (jedisPool != null && !jedisPool.isClosed()) jedisPool.close(); - if (pubSub != null && !pubSub.isSubscribed()) - pubSub.unsubscribe(); - if (subscriber != null) - subscriber.close(); } public void sendRedisMessage(@NotNull String channel, @NotNull String message) { try (Jedis jedis = jedisPool.getResource()) { jedis.publish(channel, message); + plugin.debug("Sent Redis message: " + message); } } private void subscribe() { - new Thread(() -> { - try (final Jedis jedis = password.isBlank() ? - new Jedis(host, port, 0, useSSL) : - new Jedis(host, port, DefaultJedisClientConfig - .builder() - .password(password) - .timeoutMillis(0) - .ssl(useSSL) - .build()) - ) { - subscriber = jedis; - subscriber.connect(); - pubSub = new JedisPubSub() { - @Override - public void onMessage(String channel, String message) { - if (!channel.equals("cf_competition")) { - return; - } - String[] split = message.split(";"); - String action = split[0]; - switch (action) { - case "start" -> { - // start competition for all the servers that connected to redis - plugin.getCompetitionManager().startCompetition(split[1], true, false); + Thread thread = new Thread(() -> { + try (final Jedis jedis = password.isBlank() ? + new Jedis(host, port, 0, useSSL) : + new Jedis(host, port, DefaultJedisClientConfig + .builder() + .password(password) + .timeoutMillis(0) + .ssl(useSSL) + .build()) + ) { + jedis.connect(); + jedis.subscribe(new JedisPubSub() { + @Override + public void onMessage(String channel, String message) { + if (!channel.equals("cf_competition")) { + return; } - case "end" -> { - if (plugin.getCompetitionManager().getOnGoingCompetition() != null) - plugin.getCompetitionManager().getOnGoingCompetition().end(); - } - case "stop" -> { - if (plugin.getCompetitionManager().getOnGoingCompetition() != null) - plugin.getCompetitionManager().getOnGoingCompetition().stop(); + plugin.debug("Received Redis message: " + message); + String[] split = message.split(";"); + String action = split[0]; + switch (action) { + case "start" -> { + // start competition for all the servers that connected to redis + plugin.getCompetitionManager().startCompetition(split[1], true, false); + } + case "end" -> { + if (plugin.getCompetitionManager().getOnGoingCompetition() != null) + plugin.getCompetitionManager().getOnGoingCompetition().end(); + } + case "stop" -> { + if (plugin.getCompetitionManager().getOnGoingCompetition() != null) + plugin.getCompetitionManager().getOnGoingCompetition().stop(); + } } } - } - }; - subscriber.subscribe(pubSub, "cf_competition"); - } - }).start(); + }, "cf_competition"); + } + }); + thread.start(); } @Override @@ -217,6 +201,7 @@ public class RedisManager extends AbstractStorage { ); } future.complete(null); + plugin.debug("Server data set for " + uuid); }); return future; } @@ -229,9 +214,12 @@ public class RedisManager extends AbstractStorage { if (jedis.get(key) != null) { jedis.del(key); future.complete(true); + plugin.debug("Server data retrieved for " + uuid + "; value: true"); } else { future.complete(false); + plugin.debug("Server data retrieved for " + uuid + "; value: false"); } + } }); return future; @@ -239,7 +227,7 @@ public class RedisManager extends AbstractStorage { @Override public CompletableFuture> getPlayerData(UUID uuid, boolean ignore) { - var future = new CompletableFuture>(); + var future = new CompletableFuture>(); plugin.getScheduler().runTaskAsync(() -> { try (Jedis jedis = jedisPool.getResource()) { byte[] key = getRedisKey("cf_data", uuid); @@ -247,9 +235,14 @@ public class RedisManager extends AbstractStorage { jedis.del(key); if (data != null) { future.complete(Optional.of(plugin.getStorageManager().fromBytes(data))); + plugin.debug("Redis data retrieved for " + uuid + "; normal data"); } else { future.complete(Optional.empty()); + plugin.debug("Redis data retrieved for " + uuid + "; empty data"); } + } catch (Exception e) { + future.complete(Optional.empty()); + LogUtils.warn("Failed to get redis data for " + uuid, e); } }); return future; @@ -257,7 +250,7 @@ public class RedisManager extends AbstractStorage { @Override public CompletableFuture savePlayerData(UUID uuid, PlayerData playerData, boolean ignore) { - var future = new CompletableFuture(); + var future = new CompletableFuture(); plugin.getScheduler().runTaskAsync(() -> { try (Jedis jedis = jedisPool.getResource()) { jedis.setex( @@ -265,6 +258,11 @@ public class RedisManager extends AbstractStorage { 10, plugin.getStorageManager().toBytes(playerData) ); + future.complete(true); + plugin.debug("Redis data set for " + uuid); + } catch (Exception e) { + future.complete(false); + LogUtils.warn("Failed to set redis data for player " + uuid, e); } }); return future; diff --git a/plugin/src/main/java/net/momirealms/customfishing/storage/method/database/sql/AbstractSQLDatabase.java b/plugin/src/main/java/net/momirealms/customfishing/storage/method/database/sql/AbstractSQLDatabase.java index aefab05f..cac6dc4d 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/storage/method/database/sql/AbstractSQLDatabase.java +++ b/plugin/src/main/java/net/momirealms/customfishing/storage/method/database/sql/AbstractSQLDatabase.java @@ -128,6 +128,7 @@ public abstract class AbstractSQLDatabase extends AbstractStorage { statement.setString(3, uuid.toString()); statement.executeUpdate(); future.complete(true); + plugin.debug("SQL data saved for " + uuid + "; unlock: " + unlock); } catch (SQLException e) { LogUtils.warn("Failed to update " + uuid + "'s data.", e); future.completeExceptionally(e); diff --git a/plugin/src/main/resources/config.yml b/plugin/src/main/resources/config.yml index 1a36dfdc..abf8ac7f 100644 --- a/plugin/src/main/resources/config.yml +++ b/plugin/src/main/resources/config.yml @@ -2,6 +2,9 @@ # Wiki: https://mo-mi.gitbook.io/xiaomomi-plugins/ config-version: '26' +# Debug +debug: false + # BStats metrics: true