From c573213c0dab094805fbd5791c5456a5f83534ff Mon Sep 17 00:00:00 2001 From: Xiao-MoMi <70987828+Xiao-MoMi@users.noreply.github.com> Date: Sat, 21 Jan 2023 00:56:12 +0800 Subject: [PATCH] 1.2.21 --- build.gradle | 2 +- .../customfishing/CustomFishing.java | 20 ++- .../api/event/TotemActivationEvent.java | 8 +- .../competition/Competition.java | 51 ++---- .../competition/ranking/LocalRankingImpl.java | 51 +----- .../competition/ranking/RankingInterface.java | 11 +- .../competition/ranking/RedisRankingImpl.java | 93 +---------- .../integration/papi/CompetitionPapi.java | 17 +- .../integration/papi/ParseUtil.java | 33 ++++ .../integration/papi/PlaceholderManager.java | 22 +-- .../listener/BreakBlockListener.java | 38 +++++ .../customfishing/manager/FishingManager.java | 59 +++++-- .../manager/IntegrationManager.java | 7 +- .../customfishing/manager/SellManager.java | 2 +- .../customfishing/manager/TotemManager.java | 157 ++++++++++++++++-- .../customfishing/object/Function.java | 4 + .../customfishing/object/SimpleLocation.java | 74 +++++++++ .../customfishing/object/TextCache.java | 35 ++-- .../object/fishing/FishingCondition.java | 10 +- .../object/totem/ActivatedTotem.java | 10 +- .../object/totem/TotemConfig.java | 126 ++++++++++++++ .../customfishing/util/LocationUtils.java | 57 +++++++ src/main/resources/competition.yml | 7 +- 23 files changed, 625 insertions(+), 269 deletions(-) create mode 100644 src/main/java/net/momirealms/customfishing/integration/papi/ParseUtil.java create mode 100644 src/main/java/net/momirealms/customfishing/listener/BreakBlockListener.java create mode 100644 src/main/java/net/momirealms/customfishing/object/SimpleLocation.java create mode 100644 src/main/java/net/momirealms/customfishing/object/totem/TotemConfig.java create mode 100644 src/main/java/net/momirealms/customfishing/util/LocationUtils.java diff --git a/build.gradle b/build.gradle index bea2805f..936ff704 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ plugins { } group = 'net.momirealms' -version = '1.2.20' +version = '1.2.21' repositories { mavenCentral() diff --git a/src/main/java/net/momirealms/customfishing/CustomFishing.java b/src/main/java/net/momirealms/customfishing/CustomFishing.java index 68425fb9..9e8c31a4 100644 --- a/src/main/java/net/momirealms/customfishing/CustomFishing.java +++ b/src/main/java/net/momirealms/customfishing/CustomFishing.java @@ -84,6 +84,7 @@ public final class CustomFishing extends JavaPlugin { adventure = BukkitAudiences.create(this); protocolManager = ProtocolLibrary.getProtocolManager(); version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3]; + this.fishingManager = new FishingManager(); this.dataManager = new DataManager(); this.integrationManager = new IntegrationManager(); @@ -91,13 +92,13 @@ public final class CustomFishing extends JavaPlugin { this.bonusManager = new BonusManager(); this.lootManager = new LootManager(); this.layoutManager = new LayoutManager(); - this.totemManager = new TotemManager(); + this.totemManager = new TotemManager(this); this.sellManager = new SellManager(); this.bagDataManager = new BagDataManager(); - ConfigUtil.reload(); + reloadConfig(); registerCommands(); - integrationManager.registerQuests(); + registerQuests(); AdventureUtil.consoleMessage("[CustomFishing] Plugin Enabled!"); new Metrics(this, 16648); @@ -117,6 +118,7 @@ public final class CustomFishing extends JavaPlugin { this.sellManager.unload(); this.sellManager.disable(); this.dataManager.unload(); + if (adventure != null) { adventure.close(); adventure = null; @@ -135,6 +137,18 @@ public final class CustomFishing extends JavaPlugin { Bukkit.getPluginCommand("sellfish").setTabCompleter(sellFishCommand); } + public static CustomFishing getInstance() { + return plugin; + } + + public void reloadConfig() { + ConfigUtil.reload(); + } + + private void registerQuests() { + this.integrationManager.registerQuests(); + } + public IntegrationManager getIntegrationManager() { return integrationManager; } diff --git a/src/main/java/net/momirealms/customfishing/api/event/TotemActivationEvent.java b/src/main/java/net/momirealms/customfishing/api/event/TotemActivationEvent.java index ffc7f0c7..639e1540 100644 --- a/src/main/java/net/momirealms/customfishing/api/event/TotemActivationEvent.java +++ b/src/main/java/net/momirealms/customfishing/api/event/TotemActivationEvent.java @@ -17,7 +17,7 @@ package net.momirealms.customfishing.api.event; -import net.momirealms.customfishing.object.totem.Totem; +import net.momirealms.customfishing.object.totem.TotemConfig; import org.bukkit.Location; import org.bukkit.entity.Player; import org.bukkit.event.Cancellable; @@ -28,12 +28,12 @@ import org.jetbrains.annotations.NotNull; public class TotemActivationEvent extends PlayerEvent implements Cancellable { private boolean cancelled; - private final Totem totem; + private final TotemConfig totem; private final Location location; private static final HandlerList handlerList = new HandlerList(); - public TotemActivationEvent(@NotNull Player who, Location location, Totem totem) { + public TotemActivationEvent(@NotNull Player who, Location location, TotemConfig totem) { super(who); this.cancelled = false; this.totem = totem; @@ -60,7 +60,7 @@ public class TotemActivationEvent extends PlayerEvent implements Cancellable { return getHandlerList(); } - public Totem getTotem() { + public TotemConfig getTotem() { return totem; } diff --git a/src/main/java/net/momirealms/customfishing/competition/Competition.java b/src/main/java/net/momirealms/customfishing/competition/Competition.java index b6f1bb99..c593972f 100644 --- a/src/main/java/net/momirealms/customfishing/competition/Competition.java +++ b/src/main/java/net/momirealms/customfishing/competition/Competition.java @@ -22,6 +22,7 @@ import net.momirealms.customfishing.competition.bossbar.BossBarManager; import net.momirealms.customfishing.competition.ranking.LocalRankingImpl; import net.momirealms.customfishing.competition.ranking.RankingInterface; import net.momirealms.customfishing.competition.ranking.RedisRankingImpl; +import net.momirealms.customfishing.integration.papi.PlaceholderManager; import net.momirealms.customfishing.manager.ConfigManager; import net.momirealms.customfishing.manager.MessageManager; import net.momirealms.customfishing.object.action.ActionInterface; @@ -117,18 +118,22 @@ public class Competition { givePrize(); List newMessage = new ArrayList<>(); + PlaceholderManager placeholderManager = CustomFishing.plugin.getIntegrationManager().getPlaceholderManager(); + for (String endMsg : competitionConfig.getEndMessage()) { - CompetitionPlayer[] competitionPlayers = ranking.getTop3Player(); - float first = Optional.ofNullable(competitionPlayers[0]).orElse(CompetitionPlayer.emptyPlayer).getScore(); - float second = Optional.ofNullable(competitionPlayers[1]).orElse(CompetitionPlayer.emptyPlayer).getScore(); - float third = Optional.ofNullable(competitionPlayers[2]).orElse(CompetitionPlayer.emptyPlayer).getScore(); - newMessage.add(endMsg - .replace("{1st}", Optional.ofNullable(Optional.ofNullable(competitionPlayers[0]).orElse(CompetitionPlayer.emptyPlayer).getPlayer()).orElse(MessageManager.noPlayer)) - .replace("{2nd}", Optional.ofNullable(Optional.ofNullable(competitionPlayers[1]).orElse(CompetitionPlayer.emptyPlayer).getPlayer()).orElse(MessageManager.noPlayer)) - .replace("{3rd}", Optional.ofNullable(Optional.ofNullable(competitionPlayers[2]).orElse(CompetitionPlayer.emptyPlayer).getPlayer()).orElse(MessageManager.noPlayer)) - .replace("{1st_points}", first < 0 ? MessageManager.noScore : String.format("%.1f",(first))) - .replace("{2nd_points}", second < 0 ? MessageManager.noScore : String.format("%.1f",(second))) - .replace("{3rd_points}", third < 0 ? MessageManager.noScore : String.format("%.1f",(third)))); + List placeholders = new ArrayList<>(placeholderManager.detectPlaceholders(endMsg)); + for (String placeholder : placeholders) { + if (placeholder.endsWith("_player%")) { + int rank = Integer.parseInt(placeholder.substring(1, placeholder.length() - 8)); + endMsg = endMsg.replace(placeholder, Optional.ofNullable(ranking.getPlayerAt(rank)).orElse(MessageManager.noPlayer)); + } + else if (placeholder.endsWith("_score%")) { + int rank = Integer.parseInt(placeholder.substring(1, placeholder.length() - 7)); + float score = ranking.getScoreAt(rank); + endMsg = endMsg.replace(placeholder, score == 0 ? MessageManager.noScore : String.format("%.1f", score)); + } + } + newMessage.add(endMsg); } for (Player player : Bukkit.getOnlinePlayers()) { @@ -230,30 +235,6 @@ public class Competition { return Optional.ofNullable(ranking.getCompetitionPlayer(player.getName())).orElse(CompetitionPlayer.emptyPlayer).getScore(); } - public float getFirstScore() { - return ranking.getFirstScore(); - } - - public float getSecondScore() { - return ranking.getSecondScore(); - } - - public float getThirdScore() { - return ranking.getThirdScore(); - } - - public String getFirstPlayer() { - return ranking.getFirstPlayer(); - } - - public String getSecondPlayer() { - return ranking.getSecondPlayer(); - } - - public String getThirdPlayer() { - return ranking.getThirdPlayer(); - } - public boolean isJoined(Player player) { return ranking.getCompetitionPlayer(player.getName()) != null; } diff --git a/src/main/java/net/momirealms/customfishing/competition/ranking/LocalRankingImpl.java b/src/main/java/net/momirealms/customfishing/competition/ranking/LocalRankingImpl.java index 664f0dd2..5fa92658 100644 --- a/src/main/java/net/momirealms/customfishing/competition/ranking/LocalRankingImpl.java +++ b/src/main/java/net/momirealms/customfishing/competition/ranking/LocalRankingImpl.java @@ -87,26 +87,6 @@ public class LocalRankingImpl implements RankingInterface { } @Override - public CompetitionPlayer[] getTop3Player() { - CompetitionPlayer[] competitionPlayers = new CompetitionPlayer[3]; - int index = 1; - for (CompetitionPlayer competitionPlayer : this.competitionPlayers) { - if (index == 1) { - competitionPlayers[0] = competitionPlayer; - } - if (index == 2) { - competitionPlayers[1] = competitionPlayer; - } - if (index == 3) { - competitionPlayers[2] = competitionPlayer; - return competitionPlayers; - } - index++; - } - return competitionPlayers; - } - - public String getPlayerAt(int i) { int index = 1; for (CompetitionPlayer competitionPlayer : competitionPlayers) { @@ -118,6 +98,7 @@ public class LocalRankingImpl implements RankingInterface { return null; } + @Override public float getScoreAt(int i) { int index = 1; for (CompetitionPlayer competitionPlayer : competitionPlayers) { @@ -154,34 +135,4 @@ public class LocalRankingImpl implements RankingInterface { addPlayer(competitionPlayer); } } - - @Override - public float getFirstScore() { - return getScoreAt(1); - } - - @Override - public float getSecondScore() { - return getScoreAt(2); - } - - @Override - public float getThirdScore() { - return getScoreAt(3); - } - - @Override - public String getFirstPlayer() { - return Optional.ofNullable(getPlayerAt(1)).orElse(MessageManager.noPlayer); - } - - @Override - public String getSecondPlayer() { - return Optional.ofNullable(getPlayerAt(2)).orElse(MessageManager.noPlayer); - } - - @Override - public String getThirdPlayer() { - return Optional.ofNullable(getPlayerAt(3)).orElse(MessageManager.noPlayer); - } } diff --git a/src/main/java/net/momirealms/customfishing/competition/ranking/RankingInterface.java b/src/main/java/net/momirealms/customfishing/competition/ranking/RankingInterface.java index 24ff17d0..6b15cfcb 100644 --- a/src/main/java/net/momirealms/customfishing/competition/ranking/RankingInterface.java +++ b/src/main/java/net/momirealms/customfishing/competition/ranking/RankingInterface.java @@ -18,6 +18,7 @@ package net.momirealms.customfishing.competition.ranking; import net.momirealms.customfishing.competition.CompetitionPlayer; +import org.jetbrains.annotations.Nullable; import java.util.Iterator; @@ -29,13 +30,9 @@ public interface RankingInterface { int getSize(); String getPlayerRank(String player); float getPlayerScore(String player); - CompetitionPlayer[] getTop3Player(); void refreshData(String player, float score); void setData(String player, float score); - float getFirstScore(); - float getSecondScore(); - float getThirdScore(); - String getFirstPlayer(); - String getSecondPlayer(); - String getThirdPlayer(); + @Nullable + String getPlayerAt(int rank); + float getScoreAt(int rank); } diff --git a/src/main/java/net/momirealms/customfishing/competition/ranking/RedisRankingImpl.java b/src/main/java/net/momirealms/customfishing/competition/ranking/RedisRankingImpl.java index e7963d91..0d995351 100644 --- a/src/main/java/net/momirealms/customfishing/competition/ranking/RedisRankingImpl.java +++ b/src/main/java/net/momirealms/customfishing/competition/ranking/RedisRankingImpl.java @@ -28,18 +28,6 @@ import java.util.List; public class RedisRankingImpl implements RankingInterface { - public void addPlayer(CompetitionPlayer competitionPlayer) { - Jedis jedis = JedisUtil.getJedis(); - jedis.zadd("cf_competition", competitionPlayer.getScore(), competitionPlayer.getPlayer()); - jedis.close(); - } - - public void removePlayer(CompetitionPlayer competitionPlayer) { - Jedis jedis = JedisUtil.getJedis(); - jedis.zrem("cf_competition", competitionPlayer.getPlayer()); - jedis.close(); - } - @Override public void clear() { Jedis jedis = JedisUtil.getJedis(); @@ -94,29 +82,6 @@ public class RedisRankingImpl implements RankingInterface { return rank.floatValue(); } - @Override - public CompetitionPlayer[] getTop3Player() { - CompetitionPlayer[] competitionPlayers = new CompetitionPlayer[3]; - Jedis jedis = JedisUtil.getJedis(); - List players = jedis.zrevrangeWithScores("cf_competition", 0, -1); - jedis.close(); - int index = 1; - for (Tuple tuple : players){ - if (index == 1) { - competitionPlayers[0] = new CompetitionPlayer(tuple.getElement(), (float) tuple.getScore()); - } - if (index == 2) { - competitionPlayers[1] = new CompetitionPlayer(tuple.getElement(), (float) tuple.getScore()); - } - if (index == 3) { - competitionPlayers[2] = new CompetitionPlayer(tuple.getElement(), (float) tuple.getScore()); - return competitionPlayers; - } - index++; - } - return competitionPlayers; - } - @Override public void refreshData(String player, float score) { Jedis jedis = JedisUtil.getJedis(); @@ -132,62 +97,22 @@ public class RedisRankingImpl implements RankingInterface { } @Override - public float getFirstScore() { + public String getPlayerAt(int rank) { Jedis jedis = JedisUtil.getJedis(); - List players = jedis.zrevrangeWithScores("cf_competition", 0, 0); + List player = jedis.zrevrange("cf_competition", rank - 1, rank -1); jedis.close(); - if (players == null) return 0; - if (players.size() == 0) return 0; - return (float) players.get(0).getScore(); - } - - @Override - public float getSecondScore() { - Jedis jedis = JedisUtil.getJedis(); - List players = jedis.zrevrangeWithScores("cf_competition", 1, 1); - jedis.close(); - if (players == null) return 0; - if (players.size() == 0) return 0; - return (float) players.get(0).getScore(); - } - - @Override - public float getThirdScore() { - Jedis jedis = JedisUtil.getJedis(); - List players = jedis.zrevrangeWithScores("cf_competition", 2, 2); - jedis.close(); - if (players == null) return 0; - if (players.size() == 0) return 0; - return (float) players.get(0).getScore(); - } - - @Override - public String getFirstPlayer() { - Jedis jedis = JedisUtil.getJedis(); - List player = jedis.zrevrange("cf_competition", 0,0); - jedis.close(); - if (player == null) return MessageManager.noPlayer; - if (player.size() == 0) return MessageManager.noPlayer; + if (player == null) return null; + if (player.size() == 0) return null; return player.get(0); } @Override - public String getSecondPlayer() { + public float getScoreAt(int rank) { Jedis jedis = JedisUtil.getJedis(); - List player = jedis.zrevrange("cf_competition", 1,1); + List players = jedis.zrevrangeWithScores("cf_competition", rank - 1, rank -1); jedis.close(); - if (player == null) return MessageManager.noPlayer; - if (player.size() == 0) return MessageManager.noPlayer; - return player.get(0); - } - - @Override - public String getThirdPlayer() { - Jedis jedis = JedisUtil.getJedis(); - List player = jedis.zrevrange("cf_competition", 2,2); - jedis.close(); - if (player == null) return MessageManager.noPlayer; - if (player.size() == 0) return MessageManager.noPlayer; - return player.get(0); + if (players == null) return 0; + if (players.size() == 0) return 0; + return (float) players.get(0).getScore(); } } diff --git a/src/main/java/net/momirealms/customfishing/integration/papi/CompetitionPapi.java b/src/main/java/net/momirealms/customfishing/integration/papi/CompetitionPapi.java index 0d83c496..bb01be80 100644 --- a/src/main/java/net/momirealms/customfishing/integration/papi/CompetitionPapi.java +++ b/src/main/java/net/momirealms/customfishing/integration/papi/CompetitionPapi.java @@ -19,10 +19,14 @@ package net.momirealms.customfishing.integration.papi; import me.clip.placeholderapi.expansion.PlaceholderExpansion; import net.momirealms.customfishing.competition.Competition; +import net.momirealms.customfishing.competition.ranking.RankingInterface; +import net.momirealms.customfishing.manager.MessageManager; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Optional; + public class CompetitionPapi extends PlaceholderExpansion { @Override @@ -48,6 +52,7 @@ public class CompetitionPapi extends PlaceholderExpansion { @Override public @Nullable String onPlaceholderRequest(Player player, @NotNull String params) { if (Competition.currentCompetition == null) return ""; + RankingInterface ranking = Competition.currentCompetition.getRanking(); switch (params) { case "rank" -> { return Competition.currentCompetition.getPlayerRank(player); @@ -65,22 +70,22 @@ public class CompetitionPapi extends PlaceholderExpansion { return String.format("%02d", Competition.currentCompetition.getRemainingTime() % 60); } case "1st_score" -> { - return String.format("%.1f", Competition.currentCompetition.getFirstScore()); + return ranking.getScoreAt(1) <= 0 ? MessageManager.noScore : String.format("%.1f", ranking.getScoreAt(1)); } case "1st_player" -> { - return Competition.currentCompetition.getFirstPlayer(); + return Optional.ofNullable(ranking.getPlayerAt(1)).orElse(MessageManager.noPlayer); } case "2nd_score" -> { - return String.format("%.1f", Competition.currentCompetition.getSecondScore()); + return ranking.getScoreAt(2) <= 0 ? MessageManager.noScore : String.format("%.1f", ranking.getScoreAt(2)); } case "2nd_player" -> { - return Competition.currentCompetition.getSecondPlayer(); + return Optional.ofNullable(ranking.getPlayerAt(2)).orElse(MessageManager.noPlayer); } case "3rd_score" -> { - return String.format("%.1f", Competition.currentCompetition.getThirdScore()); + return ranking.getScoreAt(3) <= 0 ? MessageManager.noScore : String.format("%.1f", ranking.getScoreAt(3)); } case "3rd_player" -> { - return Competition.currentCompetition.getThirdPlayer(); + return Optional.ofNullable(ranking.getPlayerAt(3)).orElse(MessageManager.noPlayer); } } return "null"; diff --git a/src/main/java/net/momirealms/customfishing/integration/papi/ParseUtil.java b/src/main/java/net/momirealms/customfishing/integration/papi/ParseUtil.java new file mode 100644 index 00000000..77c7b369 --- /dev/null +++ b/src/main/java/net/momirealms/customfishing/integration/papi/ParseUtil.java @@ -0,0 +1,33 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.integration.papi; + +import me.clip.placeholderapi.PlaceholderAPI; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; + +public class ParseUtil { + + public static String setPlaceholders(Player player, String text) { + return PlaceholderAPI.setPlaceholders(player, text); + } + + public static String setPlaceholders(OfflinePlayer player, String text) { + return PlaceholderAPI.setPlaceholders(player, text); + } +} diff --git a/src/main/java/net/momirealms/customfishing/integration/papi/PlaceholderManager.java b/src/main/java/net/momirealms/customfishing/integration/papi/PlaceholderManager.java index f6b82830..57e821c5 100644 --- a/src/main/java/net/momirealms/customfishing/integration/papi/PlaceholderManager.java +++ b/src/main/java/net/momirealms/customfishing/integration/papi/PlaceholderManager.java @@ -17,9 +17,8 @@ package net.momirealms.customfishing.integration.papi; -import me.clip.placeholderapi.PlaceholderAPI; import net.momirealms.customfishing.object.Function; -import org.bukkit.OfflinePlayer; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import java.util.ArrayList; @@ -31,24 +30,27 @@ import java.util.regex.Pattern; public class PlaceholderManager extends Function { private final Pattern placeholderPattern = Pattern.compile("%([^%]*)%"); - private final CompetitionPapi competitionPapi; + private CompetitionPapi competitionPapi; + private boolean hasPlaceholderAPI = false; public PlaceholderManager() { - this.competitionPapi = new CompetitionPapi(); + if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) { + hasPlaceholderAPI = true; + this.competitionPapi = new CompetitionPapi(); + } load(); } public String parse(Player player, String text) { - return PlaceholderAPI.setPlaceholders(player, text); - } - - public String parse(OfflinePlayer offlinePlayer, String text) { - return PlaceholderAPI.setPlaceholders(offlinePlayer, text); + if (hasPlaceholderAPI) { + return ParseUtil.setPlaceholders(player, text); + } + return text; } @Override public void load() { - competitionPapi.register(); + if (competitionPapi != null) competitionPapi.register(); } @Override diff --git a/src/main/java/net/momirealms/customfishing/listener/BreakBlockListener.java b/src/main/java/net/momirealms/customfishing/listener/BreakBlockListener.java new file mode 100644 index 00000000..07b4f8d4 --- /dev/null +++ b/src/main/java/net/momirealms/customfishing/listener/BreakBlockListener.java @@ -0,0 +1,38 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.listener; + +import net.momirealms.customfishing.object.Function; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; + +public class BreakBlockListener implements Listener { + + private final Function function; + + public BreakBlockListener(Function function) { + this.function = function; + } + + @EventHandler + public void onBreak(BlockBreakEvent event) { + if (event.isCancelled()) return; + function.onBreakBlock(event); + } +} diff --git a/src/main/java/net/momirealms/customfishing/manager/FishingManager.java b/src/main/java/net/momirealms/customfishing/manager/FishingManager.java index a66292d9..7358c975 100644 --- a/src/main/java/net/momirealms/customfishing/manager/FishingManager.java +++ b/src/main/java/net/momirealms/customfishing/manager/FishingManager.java @@ -34,6 +34,7 @@ import net.momirealms.customfishing.integration.MobInterface; import net.momirealms.customfishing.integration.item.McMMOTreasure; import net.momirealms.customfishing.listener.*; import net.momirealms.customfishing.object.Function; +import net.momirealms.customfishing.object.SimpleLocation; import net.momirealms.customfishing.object.action.ActionInterface; import net.momirealms.customfishing.object.fishing.*; import net.momirealms.customfishing.object.loot.DroppedItem; @@ -41,10 +42,11 @@ import net.momirealms.customfishing.object.loot.Loot; import net.momirealms.customfishing.object.loot.Mob; import net.momirealms.customfishing.object.requirements.RequirementInterface; import net.momirealms.customfishing.object.totem.ActivatedTotem; -import net.momirealms.customfishing.object.totem.Totem; +import net.momirealms.customfishing.object.totem.TotemConfig; import net.momirealms.customfishing.util.AdventureUtil; import net.momirealms.customfishing.util.FakeItemUtil; import net.momirealms.customfishing.util.ItemStackUtil; +import net.momirealms.customfishing.util.LocationUtils; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.GameMode; @@ -54,6 +56,7 @@ import org.bukkit.block.Block; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.*; import org.bukkit.event.HandlerList; +import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.player.PlayerFishEvent; import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.Inventory; @@ -75,18 +78,21 @@ public class FishingManager extends Function { private PickUpListener pickUpListener; private MMOItemsListener mmoItemsListener; private JobsRebornXPListener jobsRebornXPListener; + private BreakBlockListener breakBlockListener; private final HashMap coolDown; private final HashMap hooksCache; private final HashMap nextLoot; private final HashMap nextBonus; private final HashMap vanillaLoot; private final ConcurrentHashMap fishingPlayerCache; - private final ConcurrentHashMap totemCache; + private final ConcurrentHashMap totemCache; + private final ConcurrentHashMap breakDetectCache; private final ConcurrentHashMap bobberTaskCache; public FishingManager() { this.playerFishListener = new PlayerFishListener(this); this.interactListener = new InteractListener(this); + this.breakBlockListener = new BreakBlockListener(this); this.coolDown = new HashMap<>(); this.hooksCache = new HashMap<>(); this.nextLoot = new HashMap<>(); @@ -95,6 +101,7 @@ public class FishingManager extends Function { this.fishingPlayerCache = new ConcurrentHashMap<>(); this.totemCache = new ConcurrentHashMap<>(); this.bobberTaskCache = new ConcurrentHashMap<>(); + this.breakDetectCache = new ConcurrentHashMap<>(); load(); } @@ -102,6 +109,7 @@ public class FishingManager extends Function { public void load() { Bukkit.getPluginManager().registerEvents(this.playerFishListener, CustomFishing.plugin); Bukkit.getPluginManager().registerEvents(this.interactListener, CustomFishing.plugin); + Bukkit.getPluginManager().registerEvents(this.breakBlockListener, CustomFishing.plugin); if (ConfigManager.preventPickUp) { this.pickUpListener = new PickUpListener(); Bukkit.getPluginManager().registerEvents(this.pickUpListener, CustomFishing.plugin); @@ -120,6 +128,7 @@ public class FishingManager extends Function { public void unload() { HandlerList.unregisterAll(this.playerFishListener); HandlerList.unregisterAll(this.interactListener); + HandlerList.unregisterAll(this.breakBlockListener); if (this.pickUpListener != null) HandlerList.unregisterAll(this.pickUpListener); if (this.mmoItemsListener != null) HandlerList.unregisterAll(this.mmoItemsListener); if (this.jobsRebornXPListener != null) HandlerList.unregisterAll(this.jobsRebornXPListener); @@ -783,7 +792,7 @@ public class FishingManager extends Function { if(itemStack.getType() != Material.FISHING_ROD) return; NBTItem nbtItem = new NBTItem(itemStack); if (nbtItem.getCompound("CustomFishing") != null) return; - if (!nbtItem.hasKey("MMOITEMS_ITEM_ID")) return; + if (!nbtItem.hasTag("MMOITEMS_ITEM_ID")) return; ItemStackUtil.addIdentifier(itemStack, "rod", nbtItem.getString("MMOITEMS_ITEM_ID")); } @@ -844,16 +853,16 @@ public class FishingManager extends Function { if (block == null) return; String totemID = nbtItem.getString("Totem"); if (totemID.equals("")) return; - Totem totem = TotemManager.TOTEMS.get(totemID); + TotemConfig totem = TotemManager.TOTEMS.get(totemID); if (totem == null) return; if (isCoolDown(player, 1000)) return; String blockID = CustomFishing.plugin.getIntegrationManager().getBlockInterface().getID(block); if (blockID == null) return; - List totemList = TotemManager.CORES.get(blockID); + List totemList = TotemManager.CORES.get(blockID); if (totemList == null || !totemList.contains(totem)) return; Location coreLoc = block.getLocation(); - int type = CustomFishing.plugin.getTotemManager().checkLocationModel(totem.getOriginalModel(), coreLoc); - if (type == 0) return; + int direction = CustomFishing.plugin.getTotemManager().checkLocationModel(totem.getOriginalModel(), coreLoc); + if (direction == 0) return; if (!AntiGriefInterface.testBreak(player, coreLoc)) return; TotemActivationEvent totemActivationEvent = new TotemActivationEvent(player, coreLoc, totem); @@ -862,11 +871,11 @@ public class FishingManager extends Function { return; } - if (totemCache.get(coreLoc) != null) { - totemCache.get(coreLoc).stop(); + if (totemCache.get(LocationUtils.getSimpleLocation(coreLoc)) != null) { + totemCache.get(LocationUtils.getSimpleLocation(coreLoc)).stop(); } - CustomFishing.plugin.getTotemManager().removeModel(totem.getFinalModel(), coreLoc, type); + CustomFishing.plugin.getTotemManager().removeModel(totem.getFinalModel(), coreLoc, direction); if (player.getGameMode() != GameMode.CREATIVE) itemStack.setAmount(itemStack.getAmount() - 1); for (ActionInterface action : totem.getActivatorActions()) { @@ -879,9 +888,9 @@ public class FishingManager extends Function { } Location bottomLoc = coreLoc.clone().subtract(0, totem.getOriginalModel().getCorePos().getY(), 0); - ActivatedTotem activatedTotem = new ActivatedTotem(bottomLoc, totem, this); + ActivatedTotem activatedTotem = new ActivatedTotem(bottomLoc, totem, this, direction); activatedTotem.runTaskTimer(CustomFishing.plugin, 10, 20); - totemCache.put(bottomLoc, activatedTotem); + totemCache.put(LocationUtils.getSimpleLocation(bottomLoc), activatedTotem); } private void useFinder(Player player) { @@ -911,7 +920,7 @@ public class FishingManager extends Function { layout = loot.getLayout()[new Random().nextInt(loot.getLayout().length)]; } else { - layout = (Layout) LayoutManager.LAYOUTS.values().stream().toArray()[new Random().nextInt(LayoutManager.LAYOUTS.values().size())]; + layout = (Layout) LayoutManager.LAYOUTS.values().toArray()[new Random().nextInt(LayoutManager.LAYOUTS.values().size())]; } int speed; @@ -1000,11 +1009,7 @@ public class FishingManager extends Function { } public void removeTotem(Location location) { - totemCache.remove(location); - } - - public void addPlayerToLavaFishing(Player player, BobberCheckTask task) { - this.bobberTaskCache.put(player, task); + totemCache.remove(LocationUtils.getSimpleLocation(location)); } public void removePlayerFromLavaFishing(Player player) { @@ -1019,4 +1024,22 @@ public class FishingManager extends Function { } return 0; } + + public void addTotemBreakDetectToCache(SimpleLocation part, SimpleLocation bottom) { + breakDetectCache.put(part, bottom); + } + + public void removeTotemBreakDetectFromCache(SimpleLocation part) { + breakDetectCache.remove(part); + } + + @Override + public void onBreakBlock(BlockBreakEvent event) { + final Block block = event.getBlock(); + SimpleLocation bottomLoc = breakDetectCache.get(LocationUtils.getSimpleLocation(block.getLocation())); + if (bottomLoc == null) return; + ActivatedTotem activatedTotem = totemCache.get(bottomLoc); + if (activatedTotem == null) return; + activatedTotem.stop(); + } } diff --git a/src/main/java/net/momirealms/customfishing/manager/IntegrationManager.java b/src/main/java/net/momirealms/customfishing/manager/IntegrationManager.java index 77259008..7071aa1f 100644 --- a/src/main/java/net/momirealms/customfishing/manager/IntegrationManager.java +++ b/src/main/java/net/momirealms/customfishing/manager/IntegrationManager.java @@ -69,9 +69,8 @@ public class IntegrationManager extends Function { if (this.placeholderManager != null) { this.placeholderManager.unload(); } - if (pluginManager.getPlugin("PlaceholderAPI") != null) { - this.placeholderManager = new PlaceholderManager(); - } + + this.placeholderManager = new PlaceholderManager(); YamlConfiguration config = ConfigUtil.getConfig("config.yml"); @@ -267,7 +266,7 @@ public class IntegrationManager extends Function { return blockInterface; } - @Nullable + @NotNull public PlaceholderManager getPlaceholderManager() { return placeholderManager; } diff --git a/src/main/java/net/momirealms/customfishing/manager/SellManager.java b/src/main/java/net/momirealms/customfishing/manager/SellManager.java index a19f827d..f8893cc9 100644 --- a/src/main/java/net/momirealms/customfishing/manager/SellManager.java +++ b/src/main/java/net/momirealms/customfishing/manager/SellManager.java @@ -423,7 +423,7 @@ public class SellManager extends Function { if (component.getJson().equals("{\"text\":\"{CustomFishing_Sell}\"}")) { PlaceholderManager placeholderManager = CustomFishing.plugin.getIntegrationManager().getPlaceholderManager(); String text = SellManager.title.replace("{player}", player.getName()); - if (placeholderManager != null) placeholderManager.parse(player, text); + placeholderManager.parse(player, text); wrappedChatComponentStructureModifier.write(0, WrappedChatComponent.fromJson( GsonComponentSerializer.gson().serialize( diff --git a/src/main/java/net/momirealms/customfishing/manager/TotemManager.java b/src/main/java/net/momirealms/customfishing/manager/TotemManager.java index 7a9ba04e..f6198403 100644 --- a/src/main/java/net/momirealms/customfishing/manager/TotemManager.java +++ b/src/main/java/net/momirealms/customfishing/manager/TotemManager.java @@ -27,9 +27,10 @@ import net.momirealms.customfishing.object.requirements.*; import net.momirealms.customfishing.object.totem.CorePos; import net.momirealms.customfishing.object.totem.FinalModel; import net.momirealms.customfishing.object.totem.OriginalModel; -import net.momirealms.customfishing.object.totem.Totem; +import net.momirealms.customfishing.object.totem.TotemConfig; import net.momirealms.customfishing.util.AdventureUtil; import net.momirealms.customfishing.util.ConfigUtil; +import net.momirealms.customfishing.util.LocationUtils; import org.apache.commons.lang.StringUtils; import org.bukkit.Location; import org.bukkit.Particle; @@ -44,11 +45,17 @@ import java.util.Objects; public class TotemManager extends Function { - public static HashMap TOTEMS; - public static HashMap> CORES; + private final CustomFishing plugin; + + public static HashMap TOTEMS; + public static HashMap> CORES; public static HashMap BLOCKS; public static HashMap INVERTED; + public TotemManager(CustomFishing plugin) { + this.plugin = plugin; + } + @Override public void unload() { if (TOTEMS != null) TOTEMS.clear(); @@ -97,7 +104,7 @@ public class TotemManager extends Function { return; } for (int i = 0; i < length; i++) { - if (args[i].startsWith("(") && args[i].endsWith(")")){ + if (args[i].startsWith("(") && args[i].endsWith(")")) { String content = args[i].substring(1, args[i].length()-1); corePos = getCorePos(cores, corePos, originalModel, k, j, i, content); finalModel.setElement("*", i, j, k); @@ -131,7 +138,7 @@ public class TotemManager extends Function { originalModel.setCorePos(corePos); } - Totem totem = new Totem( + TotemConfig totem = new TotemConfig( originalModel, finalModel, config.getInt(key + ".radius", 16), @@ -199,7 +206,7 @@ public class TotemManager extends Function { for (String core : cores) { if (CORES.get(core) == null){ - List totems = new ArrayList<>(); + List totems = new ArrayList<>(); totems.add(totem); CORES.put(core, totems); } @@ -400,8 +407,7 @@ public class TotemManager extends Function { return 0; } - - public void removeModel(FinalModel model, Location location, int id) { + public void removeModel(FinalModel model, Location location, int direction) { BlockInterface blockInterface = CustomFishing.plugin.getIntegrationManager().getBlockInterface(); @@ -416,7 +422,7 @@ public class TotemManager extends Function { Location startLoc = location.clone().subtract(0, yOffset, 0); - switch (id) { + switch (direction) { case 1: for (int i = 0; i < height; i++) { Location loc = startLoc.clone().add(-xOffset, i, -zOffset); @@ -424,10 +430,12 @@ public class TotemManager extends Function { for (int x = 0; x < length; x++) { if (model.getElement(x, z, i) == null) { blockInterface.removeBlock(loc.clone().add(x, 0, z).getBlock()); + continue; } - else if (!model.getElement(x, z, i).equals("*")){ + if (!model.getElement(x, z, i).equals("*")) { blockInterface.replaceBlock(loc.clone().add(x, 0, z), model.getElement(x, z, i)); } + plugin.getFishingManager().addTotemBreakDetectToCache(LocationUtils.getSimpleLocation(loc.clone().add(x, 0, z)), LocationUtils.getSimpleLocation(startLoc)); } } break; @@ -438,10 +446,12 @@ public class TotemManager extends Function { for (int x = 0; x < length; x++) { if (model.getElement(x, z, i) == null) { blockInterface.removeBlock(loc.clone().add(-x, 0, -z).getBlock()); + continue; } - else if (!model.getElement(x, z, i).equals("*")){ + if (!model.getElement(x, z, i).equals("*")){ blockInterface.replaceBlock(loc.clone().add(-x, 0, -z), model.getElement(x, z, i)); } + plugin.getFishingManager().addTotemBreakDetectToCache(LocationUtils.getSimpleLocation(loc.clone().add(-x, 0, -z)), LocationUtils.getSimpleLocation(startLoc)); } } break; @@ -452,10 +462,12 @@ public class TotemManager extends Function { for (int x = 0; x < length; x++) { if (model.getElement(x, z, i) == null) { blockInterface.removeBlock(loc.clone().add(z, 0, -x).getBlock()); + continue; } - else if (!model.getElement(x, z, i).equals("*")){ + if (!model.getElement(x, z, i).equals("*")){ blockInterface.replaceBlock(loc.clone().add(z, 0, -x), model.getElement(x, z, i)); } + plugin.getFishingManager().addTotemBreakDetectToCache(LocationUtils.getSimpleLocation(loc.clone().add(z, 0, -x)), LocationUtils.getSimpleLocation(startLoc)); } } break; @@ -466,10 +478,12 @@ public class TotemManager extends Function { for (int x = 0; x < length; x++) { if (model.getElement(x, z, i) == null) { blockInterface.removeBlock(loc.clone().add(-z, 0, x).getBlock()); + continue; } - else if (!model.getElement(x, z, i).equals("*")){ + if (!model.getElement(x, z, i).equals("*")){ blockInterface.replaceBlock(loc.clone().add(-z, 0, x), model.getElement(x, z, i)); } + plugin.getFishingManager().addTotemBreakDetectToCache(LocationUtils.getSimpleLocation(loc.clone().add(-z, 0, x)), LocationUtils.getSimpleLocation(startLoc)); } } break; @@ -480,10 +494,12 @@ public class TotemManager extends Function { for (int x = 0; x < length; x++) { if (model.getElement(x, z, i) == null) { blockInterface.removeBlock(loc.clone().add(z, 0, x).getBlock()); + continue; } - else if (!model.getElement(x, z, i).equals("*")){ + if (!model.getElement(x, z, i).equals("*")){ blockInterface.replaceBlock(loc.clone().add(z, 0, x), model.getElement(x, z, i)); } + plugin.getFishingManager().addTotemBreakDetectToCache(LocationUtils.getSimpleLocation(loc.clone().add(z, 0, x)), LocationUtils.getSimpleLocation(startLoc)); } } break; @@ -494,10 +510,12 @@ public class TotemManager extends Function { for (int x = 0; x < length; x++) { if (model.getElement(x, z, i) == null) { blockInterface.removeBlock(loc.clone().add(-z, 0, -x).getBlock()); + continue; } - else if (!model.getElement(x, z, i).equals("*")){ + if (!model.getElement(x, z, i).equals("*")){ blockInterface.replaceBlock(loc.clone().add(-z, 0, -x), model.getElement(x, z, i)); } + plugin.getFishingManager().addTotemBreakDetectToCache(LocationUtils.getSimpleLocation(loc.clone().add(-z, 0, -x)), LocationUtils.getSimpleLocation(startLoc)); } } break; @@ -508,10 +526,12 @@ public class TotemManager extends Function { for (int x = 0; x < length; x++) { if (model.getElement(x, z, i) == null) { blockInterface.removeBlock(loc.clone().add(x, 0, -z).getBlock()); + continue; } - else if (!model.getElement(x, z, i).equals("*")){ + if (!model.getElement(x, z, i).equals("*")){ blockInterface.replaceBlock(loc.clone().add(x, 0, -z), model.getElement(x, z, i)); } + plugin.getFishingManager().addTotemBreakDetectToCache(LocationUtils.getSimpleLocation(loc.clone().add(x, 0, -z)), LocationUtils.getSimpleLocation(startLoc)); } } break; @@ -522,10 +542,113 @@ public class TotemManager extends Function { for (int x = 0; x < length; x++) { if (model.getElement(x, z, i) == null) { blockInterface.removeBlock(loc.clone().add(-x, 0, z).getBlock()); + continue; } - else if (!model.getElement(x, z, i).equals("*")){ + if (!model.getElement(x, z, i).equals("*")){ blockInterface.replaceBlock(loc.clone().add(-x, 0, z), model.getElement(x, z, i)); } + plugin.getFishingManager().addTotemBreakDetectToCache(LocationUtils.getSimpleLocation(loc.clone().add(-x, 0, z)), LocationUtils.getSimpleLocation(startLoc)); + } + } + break; + } + } + + public void clearBreakDetectCache(FinalModel model, Location location, int direction) { + CorePos corePos = model.getCorePos(); + int xOffset = corePos.getX(); + int yOffset = corePos.getY(); + int zOffset = corePos.getZ(); + int height = model.getHeight(); + int length = model.getLength(); + int width = model.getWidth(); + Location startLoc = location.clone().subtract(0, yOffset, 0); + switch (direction) { + case 1: + for (int i = 0; i < height; i++) { + Location loc = startLoc.clone().add(-xOffset, i, -zOffset); + for (int z = 0; z < width; z++) + for (int x = 0; x < length; x++) { + if (model.getElement(x, z, i) != null) { + plugin.getFishingManager().removeTotemBreakDetectFromCache(LocationUtils.getSimpleLocation(loc.clone().add(x, 0, z))); + } + } + } + break; + case 2: + for (int i = 0; i < height; i++) { + Location loc = startLoc.clone().add(xOffset, i, zOffset); + for (int z = 0; z < width; z++) + for (int x = 0; x < length; x++) { + if (model.getElement(x, z, i) != null) { + plugin.getFishingManager().removeTotemBreakDetectFromCache(LocationUtils.getSimpleLocation(loc.clone().add(-x, 0, -z))); + } + } + } + break; + case 3: + for (int i = 0; i < height; i++) { + Location loc = startLoc.clone().add(-zOffset, i, xOffset); + for (int z = 0; z < width; z++) + for (int x = 0; x < length; x++) { + if (model.getElement(x, z, i) != null) { + plugin.getFishingManager().removeTotemBreakDetectFromCache(LocationUtils.getSimpleLocation(loc.clone().add(z, 0, -x))); + } + } + } + break; + case 4: + for (int i = 0; i < height; i++) { + Location loc = startLoc.clone().add(zOffset, i, -xOffset); + for (int z = 0; z < width; z++) + for (int x = 0; x < length; x++) { + if (model.getElement(x, z, i) != null) { + plugin.getFishingManager().removeTotemBreakDetectFromCache(LocationUtils.getSimpleLocation(loc.clone().add(-z, 0, x))); + } + } + } + break; + case 5: + for (int i = 0; i < height; i++) { + Location loc = startLoc.clone().add(-zOffset, i, -xOffset); + for (int z = 0; z < width; z++) + for (int x = 0; x < length; x++) { + if (model.getElement(x, z, i) != null) { + plugin.getFishingManager().removeTotemBreakDetectFromCache(LocationUtils.getSimpleLocation(loc.clone().add(z, 0, x))); + } + } + } + break; + case 6: + for (int i = 0; i < height; i++) { + Location loc = startLoc.clone().add(zOffset, i, xOffset); + for (int z = 0; z < width; z++) + for (int x = 0; x < length; x++) { + if (model.getElement(x, z, i) != null) { + plugin.getFishingManager().removeTotemBreakDetectFromCache(LocationUtils.getSimpleLocation(loc.clone().add(-z, 0, -x))); + } + } + } + break; + case 7: + for (int i = 0; i < height; i++) { + Location loc = startLoc.clone().add(-xOffset, i, zOffset); + for (int z = 0; z < width; z++) + for (int x = 0; x < length; x++) { + if (model.getElement(x, z, i) != null) { + plugin.getFishingManager().removeTotemBreakDetectFromCache(LocationUtils.getSimpleLocation(loc.clone().add(x, 0, -z))); + } + } + } + break; + case 8: + for (int i = 0; i < height; i++) { + Location loc = startLoc.clone().add(xOffset, i, -zOffset); + for (int z = 0; z < width; z++) + for (int x = 0; x < length; x++) { + if (model.getElement(x, z, i) != null) { + plugin.getFishingManager().removeTotemBreakDetectFromCache(LocationUtils.getSimpleLocation(loc.clone().add(-x, 0, z))); + } } } break; diff --git a/src/main/java/net/momirealms/customfishing/object/Function.java b/src/main/java/net/momirealms/customfishing/object/Function.java index c09168cb..bd335d1b 100644 --- a/src/main/java/net/momirealms/customfishing/object/Function.java +++ b/src/main/java/net/momirealms/customfishing/object/Function.java @@ -19,6 +19,7 @@ package net.momirealms.customfishing.object; import com.comphenix.protocol.events.PacketContainer; import org.bukkit.entity.Player; +import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.inventory.InventoryCloseEvent; import org.bukkit.event.inventory.InventoryOpenEvent; @@ -58,4 +59,7 @@ public class Function { public void onOpenInventory(InventoryOpenEvent event) { } + + public void onBreakBlock(BlockBreakEvent event) { + } } diff --git a/src/main/java/net/momirealms/customfishing/object/SimpleLocation.java b/src/main/java/net/momirealms/customfishing/object/SimpleLocation.java new file mode 100644 index 00000000..371de963 --- /dev/null +++ b/src/main/java/net/momirealms/customfishing/object/SimpleLocation.java @@ -0,0 +1,74 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.object; + +import java.util.Objects; + +public class SimpleLocation { + + private final int x; + private final int y; + private final int z; + private final String worldName; + + public SimpleLocation(String worldName, int x, int y, int z){ + this.worldName = worldName; + this.x = x; + this.y = y; + this.z = z; + } + + public int getX() {return x;} + public int getZ() {return z;} + public int getY() {return y;} + public String getWorldName() {return worldName;} + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final SimpleLocation other = (SimpleLocation) obj; + if (!Objects.equals(worldName, other.getWorldName())) { + return false; + } + if (Double.doubleToLongBits(this.x) != Double.doubleToLongBits(other.x)) { + return false; + } + if (Double.doubleToLongBits(this.y) != Double.doubleToLongBits(other.y)) { + return false; + } + if (Double.doubleToLongBits(this.z) != Double.doubleToLongBits(other.z)) { + return false; + } + return true; + } + + @Override + public int hashCode() { + int hash = 3; + hash = 19 * hash + (worldName != null ? worldName.hashCode() : 0); + hash = 19 * hash + (int) (Double.doubleToLongBits(this.x) ^ (Double.doubleToLongBits(this.x) >>> 32)); + hash = 19 * hash + (int) (Double.doubleToLongBits(this.y) ^ (Double.doubleToLongBits(this.y) >>> 32)); + hash = 19 * hash + (int) (Double.doubleToLongBits(this.z) ^ (Double.doubleToLongBits(this.z) >>> 32)); + return hash; + } +} \ No newline at end of file diff --git a/src/main/java/net/momirealms/customfishing/object/TextCache.java b/src/main/java/net/momirealms/customfishing/object/TextCache.java index 2361fb61..0f34d65e 100644 --- a/src/main/java/net/momirealms/customfishing/object/TextCache.java +++ b/src/main/java/net/momirealms/customfishing/object/TextCache.java @@ -19,11 +19,14 @@ package net.momirealms.customfishing.object; import net.momirealms.customfishing.CustomFishing; import net.momirealms.customfishing.competition.Competition; +import net.momirealms.customfishing.competition.ranking.RankingInterface; import net.momirealms.customfishing.integration.papi.PlaceholderManager; +import net.momirealms.customfishing.manager.MessageManager; import org.bukkit.entity.Player; import java.util.ArrayList; import java.util.List; +import java.util.Optional; public class TextCache { @@ -57,31 +60,31 @@ public class TextCache { String string = originalValue; if (ownerPlaceholders.length != 0) { PlaceholderManager placeholderManager = CustomFishing.plugin.getIntegrationManager().getPlaceholderManager(); - if (placeholderManager != null) { - if ("%s".equals(originalValue)) { - string = placeholderManager.parse(owner, ownerPlaceholders[0]); - } - else { - Object[] values = new String[ownerPlaceholders.length]; - for (int i = 0; i < ownerPlaceholders.length; i++) { - values[i] = placeholderManager.parse(owner, ownerPlaceholders[i]); - } - string = String.format(originalValue, values); + if ("%s".equals(originalValue)) { + string = placeholderManager.parse(owner, ownerPlaceholders[0]); + } + else { + Object[] values = new String[ownerPlaceholders.length]; + for (int i = 0; i < ownerPlaceholders.length; i++) { + values[i] = placeholderManager.parse(owner, ownerPlaceholders[i]); } + string = String.format(originalValue, values); } } + RankingInterface ranking = Competition.currentCompetition.getRanking(); + string = string.replace("{rank}", Competition.currentCompetition.getPlayerRank(owner)) .replace("{time}", String.valueOf(Competition.currentCompetition.getRemainingTime())) .replace("{minute}", String.format("%02d", Competition.currentCompetition.getRemainingTime() / 60)) .replace("{second}",String.format("%02d", Competition.currentCompetition.getRemainingTime() % 60)) .replace("{score}", String.format("%.1f", Competition.currentCompetition.getScore(owner))) - .replace("{1st_player}", Competition.currentCompetition.getFirstPlayer()) - .replace("{1st_score}", String.format("%.1f", Competition.currentCompetition.getFirstScore())) - .replace("{2nd_player}", Competition.currentCompetition.getSecondPlayer()) - .replace("{2nd_score}", String.format("%.1f", Competition.currentCompetition.getSecondScore())) - .replace("{3rd_player}", Competition.currentCompetition.getThirdPlayer()) - .replace("{3rd_score}", String.format("%.1f", Competition.currentCompetition.getThirdScore())); + .replace("{1st_player}", Optional.ofNullable(ranking.getPlayerAt(1)).orElse(MessageManager.noPlayer)) + .replace("{1st_score}", ranking.getScoreAt(1) <= 0 ? MessageManager.noScore : String.format("%.1f", ranking.getScoreAt(1))) + .replace("{2nd_player}", Optional.ofNullable(ranking.getPlayerAt(2)).orElse(MessageManager.noPlayer)) + .replace("{2nd_score}", ranking.getScoreAt(2) <= 0 ? MessageManager.noScore : String.format("%.1f", ranking.getScoreAt(2))) + .replace("{3rd_player}", Optional.ofNullable(ranking.getPlayerAt(3)).orElse(MessageManager.noPlayer)) + .replace("{3rd_score}", ranking.getScoreAt(3) <= 0 ? MessageManager.noScore : String.format("%.1f", ranking.getScoreAt(3))); if (!latestValue.equals(string)) { latestValue = string; diff --git a/src/main/java/net/momirealms/customfishing/object/fishing/FishingCondition.java b/src/main/java/net/momirealms/customfishing/object/fishing/FishingCondition.java index f058f388..163464ce 100644 --- a/src/main/java/net/momirealms/customfishing/object/fishing/FishingCondition.java +++ b/src/main/java/net/momirealms/customfishing/object/fishing/FishingCondition.java @@ -29,17 +29,15 @@ public class FishingCondition{ private final Location location; private final Player player; - private HashMap papiMap; + private final HashMap papiMap; public FishingCondition(Location location, Player player) { this.location = location; this.player = player; PlaceholderManager placeholderManager = CustomFishing.plugin.getIntegrationManager().getPlaceholderManager(); - if (placeholderManager != null) { - this.papiMap = new HashMap<>(); - for (String papi : CustomPapi.allPapi) { - this.papiMap.put(papi, placeholderManager.parse(player, papi)); - } + this.papiMap = new HashMap<>(); + for (String papi : CustomPapi.allPapi) { + this.papiMap.put(papi, placeholderManager.parse(player, papi)); } } diff --git a/src/main/java/net/momirealms/customfishing/object/totem/ActivatedTotem.java b/src/main/java/net/momirealms/customfishing/object/totem/ActivatedTotem.java index b87e8a11..5113d329 100644 --- a/src/main/java/net/momirealms/customfishing/object/totem/ActivatedTotem.java +++ b/src/main/java/net/momirealms/customfishing/object/totem/ActivatedTotem.java @@ -34,15 +34,16 @@ public class ActivatedTotem extends BukkitRunnable { public static int id = 127616121; private int timer; - private final Totem totem; + private final TotemConfig totem; private final Location location; private final Set nearbyPlayerSet; private final int[] entityID; private final boolean hasHolo; private final BukkitRunnable particleTimerTask; private final FishingManager fishingManager; + private final int direction; - public ActivatedTotem(Location location, Totem totem, FishingManager fishingManager) { + public ActivatedTotem(Location location, TotemConfig totem, FishingManager fishingManager, int direction) { this.fishingManager = fishingManager; this.totem = totem; this.location = location; @@ -54,6 +55,7 @@ public class ActivatedTotem extends BukkitRunnable { this.nearbyPlayerSet = Collections.synchronizedSet(new HashSet<>()); this.particleTimerTask = new TotemParticle(location, totem.getRadius(), totem.getParticle()); this.particleTimerTask.runTaskTimerAsynchronously(CustomFishing.plugin, 0, 4); + this.direction = direction; } @Override @@ -109,7 +111,7 @@ public class ActivatedTotem extends BukkitRunnable { return nearbyPlayerSet; } - public Totem getTotem() { + public TotemConfig getTotem() { return totem; } @@ -117,7 +119,7 @@ public class ActivatedTotem extends BukkitRunnable { this.particleTimerTask.cancel(); cancel(); fishingManager.removeTotem(location); - + CustomFishing.plugin.getTotemManager().clearBreakDetectCache(totem.getFinalModel(), location, direction); if (hasHolo) { for (Player player : nearbyPlayerSet) { for (int j : entityID) { diff --git a/src/main/java/net/momirealms/customfishing/object/totem/TotemConfig.java b/src/main/java/net/momirealms/customfishing/object/totem/TotemConfig.java new file mode 100644 index 00000000..813c09a4 --- /dev/null +++ b/src/main/java/net/momirealms/customfishing/object/totem/TotemConfig.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.object.totem; + +import net.momirealms.customfishing.object.action.ActionInterface; +import net.momirealms.customfishing.object.fishing.Bonus; +import net.momirealms.customfishing.object.requirements.RequirementInterface; +import org.bukkit.Particle; +import org.bukkit.potion.PotionEffect; + +public class TotemConfig { + + private final OriginalModel originalModel; + private FinalModel finalModel; + private RequirementInterface[] requirements; + private final int radius; + private final Particle particle; + private final int duration; + private final Bonus bonus; + private ActionInterface[] activatorActions; + private ActionInterface[] nearbyActions; + private double holoOffset; + private String[] holoText; + private PotionEffect[] potionEffects; + + public TotemConfig(OriginalModel originalModel, FinalModel finalModel, int radius, int duration, Particle particle, Bonus bonus) { + this.originalModel = originalModel; + this.finalModel = finalModel; + this.radius = radius; + this.duration = duration; + this.particle = particle; + this.bonus = bonus; + } + + public RequirementInterface[] getRequirements() { + return requirements; + } + + public void setRequirements(RequirementInterface[] requirements) { + this.requirements = requirements; + } + + public OriginalModel getOriginalModel() { + return originalModel; + } + + + public FinalModel getFinalModel() { + return finalModel; + } + + public void setFinalModel(FinalModel finalModel) { + this.finalModel = finalModel; + } + + public int getRadius() { + return radius; + } + + public Particle getParticle() { + return particle; + } + + public int getDuration() { + return duration; + } + + public Bonus getBonus() { + return bonus; + } + + public ActionInterface[] getActivatorActions() { + return activatorActions; + } + + public void setActivatorActions(ActionInterface[] activatorActions) { + this.activatorActions = activatorActions; + } + + public ActionInterface[] getNearbyActions() { + return nearbyActions; + } + + public void setNearbyActions(ActionInterface[] nearbyActions) { + this.nearbyActions = nearbyActions; + } + + public double getHoloOffset() { + return holoOffset; + } + + public void setHoloOffset(double holoOffset) { + this.holoOffset = holoOffset; + } + + public String[] getHoloText() { + return holoText; + } + + public void setHoloText(String[] holoText) { + this.holoText = holoText; + } + + public PotionEffect[] getPotionEffects() { + return potionEffects; + } + + public void setPotionEffects(PotionEffect[] potionEffects) { + this.potionEffects = potionEffects; + } +} diff --git a/src/main/java/net/momirealms/customfishing/util/LocationUtils.java b/src/main/java/net/momirealms/customfishing/util/LocationUtils.java new file mode 100644 index 00000000..984e66a8 --- /dev/null +++ b/src/main/java/net/momirealms/customfishing/util/LocationUtils.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) <2022> + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package net.momirealms.customfishing.util; + +import net.momirealms.customfishing.object.SimpleLocation; +import org.apache.commons.lang.StringUtils; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.World; +import org.jetbrains.annotations.Nullable; + +public class LocationUtils { + + public static SimpleLocation getSimpleLocation(Location location) { + return new SimpleLocation(location.getWorld().getName(), location.getBlockX(), location.getBlockY(), location.getBlockZ()); + } + + public static Location getItemFrameBlockLocation(Location frameLoc) { + return new Location(frameLoc.getWorld(), frameLoc.getBlockX(), frameLoc.getBlockY(), frameLoc.getBlockZ()); + } + + @Nullable + public static Location getLocation(SimpleLocation location) { + World world = Bukkit.getWorld(location.getWorldName()); + if (world == null) return null; + return new Location(world, location.getX(), location.getY(), location.getZ()); + } + + public static SimpleLocation getSimpleLocation(String location, String world) { + String[] loc = StringUtils.split(location, ","); + return new SimpleLocation(world, Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2])); + } + + public static Location getLocation(String location, World world) { + String[] loc = StringUtils.split(location, ","); + return new Location(world, Integer.parseInt(loc[0]), Integer.parseInt(loc[1]), Integer.parseInt(loc[2])); + } + + public static String getStringLocation(Location location) { + return location.getBlockX() + "," + location.getBlockY() + "," + location.getBlockZ(); + } +} diff --git a/src/main/resources/competition.yml b/src/main/resources/competition.yml index a6963a62..a1ec0760 100644 --- a/src/main/resources/competition.yml +++ b/src/main/resources/competition.yml @@ -59,15 +59,16 @@ example: - ' <#B0C4DE>Start fishing to participate!' - '' - '<#D4F2E7>◣─────────────────────────◢' + # You can add unlimited player rank info by using %x_player% & %x_score% end: - '<#D4F2E7>◤─────────────────────────◥' - '' - ' [<#87CEFA>🎣] Fishing Competition' - '' - ' <#E1FFFF>Results:' - - ' No.①: {1st} - {1st_points}' - - ' No.②: {2nd} - {2nd_points}' - - ' No.③: {3rd} - {3rd_points}' + - ' No.①: %1_player% - %1_score%' + - ' No.②: %2_player% - %2_score%' + - ' No.③: %3_player% - %3_score%' - '' - '<#D4F2E7>◣─────────────────────────◢'