diff --git a/api/src/main/java/net/momirealms/customfishing/api/manager/MarketManager.java b/api/src/main/java/net/momirealms/customfishing/api/manager/MarketManager.java index 63d9741c..c6073ce1 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/manager/MarketManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/manager/MarketManager.java @@ -34,6 +34,8 @@ public interface MarketManager { * * @return An integer representing the current date. */ + int getCachedDate(); + int getDate(); /** diff --git a/api/src/main/java/net/momirealms/customfishing/api/manager/StorageManager.java b/api/src/main/java/net/momirealms/customfishing/api/manager/StorageManager.java index 9d22369d..ebb5e863 100644 --- a/api/src/main/java/net/momirealms/customfishing/api/manager/StorageManager.java +++ b/api/src/main/java/net/momirealms/customfishing/api/manager/StorageManager.java @@ -24,6 +24,7 @@ import net.momirealms.customfishing.api.data.user.OnlineUser; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collection; import java.util.Optional; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -45,6 +46,8 @@ public interface StorageManager { */ @Nullable OnlineUser getOnlineUser(UUID uuid); + Collection getOnlineUsers(); + /** * Asynchronously retrieves an OfflineUser instance for the specified UUID. * The offline user might be a locked one with no data, use isLockedData() method diff --git a/plugin/src/main/java/net/momirealms/customfishing/compatibility/papi/CFPapi.java b/plugin/src/main/java/net/momirealms/customfishing/compatibility/papi/CFPapi.java new file mode 100644 index 00000000..34ffbcee --- /dev/null +++ b/plugin/src/main/java/net/momirealms/customfishing/compatibility/papi/CFPapi.java @@ -0,0 +1,131 @@ +/* + * 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.compatibility.papi; + +import me.clip.placeholderapi.expansion.PlaceholderExpansion; +import net.momirealms.customfishing.api.CustomFishingPlugin; +import net.momirealms.customfishing.api.data.user.OnlineUser; +import net.momirealms.customfishing.api.mechanic.competition.FishingCompetition; +import net.momirealms.customfishing.setting.CFLocale; +import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Optional; + +public class CFPapi extends PlaceholderExpansion { + + private final CustomFishingPlugin plugin; + + public CFPapi(CustomFishingPlugin plugin) { + this.plugin = plugin; + } + + public void load() { + super.register(); + } + + public void unload() { + super.unregister(); + } + + @Override + public @NotNull String getIdentifier() { + return "customfishing"; + } + + @Override + public @NotNull String getAuthor() { + return "XiaoMoMi"; + } + + @Override + public @NotNull String getVersion() { + return "2.0"; + } + + @Override + public boolean persist() { + return true; + } + + @Override + public @Nullable String onRequest(OfflinePlayer offlinePlayer, @NotNull String params) { + String[] split = params.split("_"); + + Player player = offlinePlayer.getPlayer(); + if (player == null) + return ""; + + switch (split[0]) { + case "market" -> { + if (split.length < 2) + return null; + switch (split[1]) { + case "limit" -> { + if (split.length < 3) { + return String.format("%.2f", plugin.getMarketManager().getEarningLimit(player)); + } else { + Player another = Bukkit.getPlayer(split[2]); + if (another == null) { + return ""; + } + return String.format("%.2f", plugin.getMarketManager().getEarningLimit(another)); + } + } + case "earnings" -> { + OnlineUser user; + if (split.length < 3) { + user = plugin.getStorageManager().getOnlineUser(player.getUniqueId()); + } else { + Player another = Bukkit.getPlayer(split[2]); + if (another == null) { + return ""; + } + user = plugin.getStorageManager().getOnlineUser(another.getUniqueId()); + } + if (user == null) + return ""; + return String.format("%.2f", user.getEarningData().earnings); + } + case "canearn" -> { + if (split.length < 3) { + OnlineUser user = plugin.getStorageManager().getOnlineUser(player.getUniqueId()); + if (user == null) + return ""; + return String.format("%.2f", plugin.getMarketManager().getEarningLimit(player) - user.getEarningData().earnings); + } else { + Player another = Bukkit.getPlayer(split[2]); + if (another == null) { + return ""; + } + + OnlineUser user = plugin.getStorageManager().getOnlineUser(another.getUniqueId()); + if (user == null) + return ""; + return String.format("%.2f", plugin.getMarketManager().getEarningLimit(another) - user.getEarningData().earnings); + } + } + } + } + } + return null; + } +} diff --git a/plugin/src/main/java/net/momirealms/customfishing/compatibility/papi/PlaceholderManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/compatibility/papi/PlaceholderManagerImpl.java index 2694160a..7e1d131c 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/compatibility/papi/PlaceholderManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/compatibility/papi/PlaceholderManagerImpl.java @@ -45,6 +45,7 @@ public class PlaceholderManagerImpl implements PlaceholderManager, Listener { private final HashMap customPlaceholderMap; private CompetitionPapi competitionPapi; private StatisticsPapi statisticsPapi; + private CFPapi cfPapi; private final ConcurrentHashMap cachedPlaceholders; public PlaceholderManagerImpl(CustomFishingPlugin plugin) { @@ -57,12 +58,14 @@ public class PlaceholderManagerImpl implements PlaceholderManager, Listener { if (this.hasPapi) { competitionPapi = new CompetitionPapi(plugin); statisticsPapi = new StatisticsPapi(plugin); + cfPapi = new CFPapi(plugin); } } public void load() { if (competitionPapi != null) competitionPapi.load(); if (statisticsPapi != null) statisticsPapi.load(); + if (cfPapi != null) cfPapi.load(); Bukkit.getPluginManager().registerEvents(this, plugin); loadCustomPlaceholders(); } @@ -70,6 +73,7 @@ public class PlaceholderManagerImpl implements PlaceholderManager, Listener { public void unload() { if (competitionPapi != null) competitionPapi.unload(); if (statisticsPapi != null) statisticsPapi.unload(); + if (cfPapi != null) cfPapi.unload(); HandlerList.unregisterAll(this); } diff --git a/plugin/src/main/java/net/momirealms/customfishing/mechanic/market/MarketManagerImpl.java b/plugin/src/main/java/net/momirealms/customfishing/mechanic/market/MarketManagerImpl.java index 18ce8c95..aa28e882 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/mechanic/market/MarketManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/mechanic/market/MarketManagerImpl.java @@ -26,6 +26,7 @@ import net.momirealms.customfishing.api.mechanic.action.Action; import net.momirealms.customfishing.api.mechanic.condition.Condition; import net.momirealms.customfishing.api.mechanic.item.BuildableItem; import net.momirealms.customfishing.api.mechanic.market.MarketGUIHolder; +import net.momirealms.customfishing.api.scheduler.CancellableTask; import net.momirealms.customfishing.api.util.LogUtils; import net.momirealms.customfishing.compatibility.papi.PlaceholderManagerImpl; import net.momirealms.customfishing.util.ConfigUtils; @@ -71,23 +72,41 @@ public class MarketManagerImpl implements MarketManager, Listener { private boolean allowItemWithNoPrice; private final ConcurrentHashMap marketGUIMap; private boolean enable; + private CancellableTask resetEarningsTask; + private int date; public MarketManagerImpl(CustomFishingPlugin plugin) { this.plugin = plugin; this.priceMap = new HashMap<>(); this.decorativeIcons = new HashMap<>(); this.marketGUIMap = new ConcurrentHashMap<>(); + this.date = getDate(); } public void load() { this.loadConfig(); Bukkit.getPluginManager().registerEvents(this, plugin); + if (!enable) return; + this.resetEarningsTask = plugin.getScheduler().runTaskAsyncTimer(() -> { + int now = getDate(); + if (this.date != now) { + this.date = now; + for (OnlineUser onlineUser : plugin.getStorageManager().getOnlineUsers()) { + onlineUser.getEarningData().date = now; + onlineUser.getEarningData().earnings = 0d; + } + } + }, 1, 1, TimeUnit.SECONDS); } public void unload() { HandlerList.unregisterAll(this); this.priceMap.clear(); this.decorativeIcons.clear(); + if (this.resetEarningsTask != null && !this.resetEarningsTask.isCancelled()) { + this.resetEarningsTask.cancel(); + this.resetEarningsTask = null; + } } public void disable() { @@ -254,8 +273,8 @@ public class MarketManagerImpl implements MarketManager, Listener { if (clickedInv != player.getInventory()) { EarningData data = gui.getEarningData(); - if (data.date != getDate()) { - data.date = getDate(); + if (data.date != getCachedDate()) { + data.date = getCachedDate(); data.earnings = 0; } @@ -356,6 +375,11 @@ public class MarketManagerImpl implements MarketManager, Listener { * * @return An integer representing the current date. */ + @Override + public int getCachedDate() { + return date; + } + @Override public int getDate() { Calendar calendar = Calendar.getInstance(); 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 f0c65076..724fe7fc 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/storage/StorageManagerImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/storage/StorageManagerImpl.java @@ -53,6 +53,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.nio.charset.StandardCharsets; +import java.util.Collection; import java.util.HashSet; import java.util.Optional; import java.util.UUID; @@ -177,6 +178,11 @@ public class StorageManagerImpl implements StorageManager, Listener { return onlineUserMap.get(uuid); } + @Override + public Collection getOnlineUsers() { + return onlineUserMap.values(); + } + /** * Asynchronously retrieves an OfflineUser instance for the specified UUID. * diff --git a/plugin/src/main/java/net/momirealms/customfishing/storage/user/OfflineUserImpl.java b/plugin/src/main/java/net/momirealms/customfishing/storage/user/OfflineUserImpl.java index 29feec95..94d0d1d9 100644 --- a/plugin/src/main/java/net/momirealms/customfishing/storage/user/OfflineUserImpl.java +++ b/plugin/src/main/java/net/momirealms/customfishing/storage/user/OfflineUserImpl.java @@ -18,6 +18,7 @@ package net.momirealms.customfishing.storage.user; import net.momirealms.customfishing.adventure.AdventureManagerImpl; +import net.momirealms.customfishing.api.CustomFishingPlugin; import net.momirealms.customfishing.api.data.EarningData; import net.momirealms.customfishing.api.data.InventoryData; import net.momirealms.customfishing.api.data.PlayerData; @@ -71,6 +72,13 @@ public class OfflineUserImpl implements OfflineUser { this.holder.setItems(InventoryUtils.getInventoryItems(playerData.getBagData().serialized)); this.earningData = playerData.getEarningData(); + + int date = CustomFishingPlugin.get().getMarketManager().getDate(); + if (earningData.date != date) { + earningData.date = date; + earningData.earnings = 0d; + } + this.statistics = new Statistics(playerData.getStatistics()); }