9
0
mirror of https://github.com/Xiao-MoMi/Custom-Fishing.git synced 2025-12-29 03:49:07 +00:00

限制收购

This commit is contained in:
Xiao-MoMi
2022-10-22 00:04:20 +08:00
parent 3217977e43
commit 809d9d688b
18 changed files with 212 additions and 68 deletions

View File

@@ -0,0 +1,42 @@
package net.momirealms.customfishing.api.event;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.NotNull;
public class SellFishEvent extends PlayerEvent implements Cancellable {
private boolean cancelled;
private float money;
private static final HandlerList handlerList = new HandlerList();
public SellFishEvent(@NotNull Player who, float money) {
super(who);
this.money = money;
}
@Override
public boolean isCancelled() {
return cancelled;
}
@Override
public void setCancelled(boolean cancel) {
cancelled = cancel;
}
@Override
public @NotNull HandlerList getHandlers() {
return handlerList;
}
public float getMoney() {
return money;
}
public void setMoney(float money) {
this.money = money;
}
}

View File

@@ -23,14 +23,18 @@ import org.bukkit.plugin.RegisteredServiceProvider;
public class VaultHook {
public static Economy economy;
private Economy economy;
public static boolean initialize() {
public boolean initialize() {
RegisteredServiceProvider<Economy> rsp = CustomFishing.plugin.getServer().getServicesManager().getRegistration(Economy.class);
if (rsp == null) {
return false;
}
economy = rsp.getProvider();
this.economy = rsp.getProvider();
return true;
}
public Economy getEconomy() {
return economy;
}
}

View File

@@ -77,7 +77,7 @@ public class BagDataManager extends Function {
dataStorageInterface.saveBagData(playerBagData);
}
AdventureUtil.consoleMessage("[CustomFishing] Fishing bag data saving for " + dataCache.size() + " online players...");
}, 6000, 6000);
}, 12000, 12000);
}
@Override

View File

@@ -115,6 +115,7 @@ public class BonusManager extends Function {
case "difficulty" -> bonus.setDifficulty(config.getInt(key + "." + level + ".difficulty"));
case "double-loot" -> bonus.setDoubleLoot(config.getDouble(key + "." + level + ".double-loot"));
case "score" -> bonus.setScore(config.getDouble(key + "." + level + ".score"));
case "lava-fishing" -> bonus.setCanLavaFishing(config.getBoolean(key + "." + level + ".lava-fishing"));
}
});
ENCHANTS.put(key + ":" + level, bonus);

View File

@@ -52,6 +52,7 @@ public class IntegrationManager extends Function {
private BlockInterface blockInterface;
private PlaceholderManager placeholderManager;
private AntiGriefInterface[] antiGriefs;
private VaultHook vaultHook;
@Override
public void load() {
@@ -67,8 +68,9 @@ public class IntegrationManager extends Function {
YamlConfiguration config = ConfigUtil.getConfig("config.yml");
if (ConfigManager.vaultHook) {
if (!VaultHook.initialize()) {
if (ConfigManager.vaultHook && pluginManager.getPlugin("Vault") != null) {
vaultHook = new VaultHook();
if (!vaultHook.initialize()) {
ConfigManager.vaultHook = false;
Log.warn("Failed to initialize Vault!");
}
@@ -235,4 +237,9 @@ public class IntegrationManager extends Function {
private void hookMessage(String plugin){
AdventureUtil.consoleMessage("[CustomFishing] <white>" + plugin + " Hooked!");
}
@Nullable
public VaultHook getVaultHook() {
return vaultHook;
}
}

View File

@@ -54,6 +54,7 @@ public class MessageManager {
public static String noScore;
public static String noRod;
public static String hookOther;
public static String reachSellLimit;
public static void load() {
YamlConfiguration config = ConfigUtil.getConfig("messages" + File.separator + "messages_" + ConfigManager.lang +".yml");
@@ -87,5 +88,6 @@ public class MessageManager {
noScore = config.getString("messages.no-score", "messages.no-score is missing");
noRod = config.getString("messages.no-rod", "messages.no-rod is missing");
hookOther = config.getString("messages.hook-other-entity","messages.hook-other-entity is missing");
reachSellLimit = config.getString("messages.reach-sell-limit","messages.reach-sell-limit is missing");
}
}

View File

@@ -27,7 +27,7 @@ import net.kyori.adventure.sound.Sound;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import net.momirealms.customfishing.CustomFishing;
import net.momirealms.customfishing.integration.VaultHook;
import net.momirealms.customfishing.api.event.SellFishEvent;
import net.momirealms.customfishing.integration.papi.PlaceholderManager;
import net.momirealms.customfishing.listener.InventoryListener;
import net.momirealms.customfishing.listener.WindowPacketListener;
@@ -50,6 +50,8 @@ import org.bukkit.event.inventory.InventoryOpenEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.io.File;
import java.io.IOException;
import java.util.*;
public class SellManager extends Function {
@@ -77,14 +79,17 @@ public class SellManager extends Function {
public static HashMap<Integer, ItemStack> guiItems;
public static HashSet<Integer> functionIconSlots;
public static HashMap<Material, Float> vanillaPrices = new HashMap<>();
public static boolean sellLimitation;
public static int upperLimit;
private final HashMap<Player, Inventory> inventoryCache;
private final HashMap<Player, Long> coolDown;
private HashMap<String, Double> todayEarning;
private int date;
public SellManager() {
this.windowPacketListener = new WindowPacketListener(this);
this.inventoryListener = new InventoryListener(this);
this.inventoryCache = new HashMap<>();
this.coolDown = new HashMap<>();
}
@Override
@@ -92,6 +97,41 @@ public class SellManager extends Function {
loadConfig();
CustomFishing.protocolManager.addPacketListener(windowPacketListener);
Bukkit.getPluginManager().registerEvents(inventoryListener, CustomFishing.plugin);
if (sellLimitation) {
readLimitationCache();
}
}
private void readLimitationCache() {
this.todayEarning = new HashMap<>();
YamlConfiguration data = ConfigUtil.readData(new File(CustomFishing.plugin.getDataFolder(), "sell-cache.yml"));
Calendar calendar = Calendar.getInstance();
date = calendar.get(Calendar.DATE);
int lastDate = data.getInt("date");
if (lastDate == date) {
ConfigurationSection configurationSection = data.getConfigurationSection("player_data");
if (configurationSection != null) {
for (String player : configurationSection.getKeys(false)) {
todayEarning.put(player, configurationSection.getDouble(player));
}
}
}
}
private void unloadLimitationCache() {
YamlConfiguration data = new YamlConfiguration();
data.set("date", date);
for (Map.Entry<String, Double> entry : todayEarning.entrySet()) {
data.set("player_data." + entry.getKey(), entry.getValue());
}
try {
data.save(new File(CustomFishing.plugin.getDataFolder(), "sell-cache.yml"));
}
catch (IOException e) {
AdventureUtil.consoleMessage("<red>[CustomFishing] Failed to unload earnings data!");
e.printStackTrace();
}
this.todayEarning.clear();
}
@Override
@@ -102,6 +142,7 @@ public class SellManager extends Function {
this.inventoryCache.clear();
CustomFishing.protocolManager.removePacketListener(windowPacketListener);
HandlerList.unregisterAll(inventoryListener);
if (sellLimitation) unloadLimitationCache();
}
private void loadConfig() {
@@ -110,6 +151,8 @@ public class SellManager extends Function {
vanillaPrices = new HashMap<>();
YamlConfiguration config = ConfigUtil.getConfig("sell-fish.yml");
formula = config.getString("price-formula", "{base} + {bonus} * {size}");
sellLimitation = config.getBoolean("sell-limitation.enable", false);
upperLimit = config.getInt("sell-limitation.upper-limit", 10000);
title = config.getString("container-title");
guiSize = config.getInt("rows") * 9;
openKey = config.contains("sounds.open") ? Key.key(config.getString("sounds.open")) : null;
@@ -207,12 +250,38 @@ public class SellManager extends Function {
List<ItemStack> playerItems = getPlayerItems(inventory);
float totalPrice = getTotalPrice(playerItems);
if (totalPrice > 0) {
if (sellLimitation) {
Calendar calendar = Calendar.getInstance();
int currentDate = calendar.get(Calendar.DATE);
if (currentDate != date) {
date = currentDate;
todayEarning.clear();
}
}
double earnings = Optional.ofNullable(todayEarning.get(player.getName())).orElse(0d);
if (earnings + totalPrice > upperLimit) {
inventory.close();
AdventureUtil.playerMessage(player, MessageManager.prefix + MessageManager.reachSellLimit);
if (denyKey != null) AdventureUtil.playerSound(player, soundSource, denyKey, 1, 1);
return;
}
SellFishEvent sellFishEvent = new SellFishEvent(player, totalPrice);
Bukkit.getPluginManager().callEvent(sellFishEvent);
if (sellFishEvent.isCancelled()) {
return;
}
for (ItemStack playerItem : playerItems) {
if (playerItem == null || playerItem.getType() == Material.AIR) continue;
if (getSingleItemPrice(playerItem) == 0) continue;
playerItem.setAmount(0);
}
doActions(player, totalPrice);
todayEarning.put(player.getName(), earnings + totalPrice);
doActions(player, sellFishEvent.getMoney(), upperLimit - earnings - totalPrice);
inventory.close();
}
else {
@@ -239,7 +308,6 @@ public class SellManager extends Function {
final Player player = (Player) event.getPlayer();
Inventory inventory = inventoryCache.remove(player);
if (inventory == null) return;
coolDown.remove(player);
if (event.getInventory() == inventory) {
returnItems(getPlayerItems(event.getInventory()), player);
if (closeKey != null) AdventureUtil.playerSound(player, soundSource, closeKey, 1, 1);
@@ -296,31 +364,34 @@ public class SellManager extends Function {
return price;
}
private void doActions(Player player, float earnings) {
private void doActions(Player player, float earnings, double remains) {
if (titleNotification != null) AdventureUtil.playerTitle(
player,
titleNotification.replace("{money}", String.format("%.2f", earnings)),
subtitleNotification.replace("{money}", String.format("%.2f", earnings)),
titleNotification.replace("{money}", String.format("%.2f", earnings)).replace("{remains}", String.format("%.2f", remains)),
subtitleNotification.replace("{money}", String.format("%.2f", earnings)).replace("{remains}", String.format("%.2f", remains)),
titleIn * 50,
titleStay * 50,
titleOut * 50
);
if (msgNotification != null) {
AdventureUtil.playerMessage(player, msgNotification.replace("{money}", String.format("%.2f", earnings)));
AdventureUtil.playerMessage(player, msgNotification.replace("{money}", String.format("%.2f", earnings)).replace("{remains}", String.format("%.2f", remains)));
}
if (actionbarNotification != null) {
AdventureUtil.playerActionbar(player, actionbarNotification.replace("{money}", String.format("%.2f", earnings)));
AdventureUtil.playerActionbar(player, actionbarNotification.replace("{money}", String.format("%.2f", earnings)).replace("{remains}", String.format("%.2f", remains)));
}
if (commands != null) {
for (String cmd : commands) {
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), cmd.replace("{player}", player.getName()).replace("{money}", String.format("%.2f", earnings)));
Bukkit.getServer().dispatchCommand(Bukkit.getConsoleSender(), cmd.replace("{player}", player.getName()).replace("{money}", String.format("%.2f", earnings)).replace("{remains}", String.format("%.2f", remains)));
}
}
if (ConfigManager.logEarning) {
AdventureUtil.consoleMessage("[CustomFishing] Log: " + player.getName() + " earns " + String.format("%.2f", earnings) + " from selling fish");
}
if (successKey != null) AdventureUtil.playerSound(player, soundSource, successKey, 1, 1);
if (ConfigManager.vaultHook) VaultHook.economy.depositPlayer(player, earnings);
if (ConfigManager.vaultHook) {
assert CustomFishing.plugin.getIntegrationManager().getVaultHook() != null;
CustomFishing.plugin.getIntegrationManager().getVaultHook().getEconomy().depositPlayer(player, earnings);
}
}
@Override

View File

@@ -6,25 +6,10 @@ simple_bait:
- '<white>Reduce the time spent fishing'
- '<white>But make it more difficult to catch fish'
custom-model-data: 646
# Bait Modifier
# Click here to learn how modifier system works: https://www.yuque.com/docs/share/4842ac5f-b5ea-4568-acef-d510f8bc9064?# 《Modifier System》
modifier:
# Change the loot weight of the specified group
# Add or subtract weights
weight-add:
silver: 5
gold: 3
# Multiply or divide weights
weight-multiply:
silver: 1.1
gold: 0.9
# Change the time to fish (>1 for longer, <1 for shorter)
time: 0.85
# Change the difficulty, for example, if the original difficulty is (1-6), now it becomes (1-9)
difficulty: 3
# Double loot probability
double-loot: 0.06
# Multiply the score got in competition
score: 1.2
difficulty: 2
wild_bait:
material: paper
@@ -41,7 +26,7 @@ magnet_bait:
display:
name: '<gray>Magnet Bait'
lore:
- '<white>Increases the probability of better loot by 15%.'
- '<white>Increases the probability of better loots by 15%.'
custom-model-data: 695
modifier:
weight-MQ:

View File

@@ -1,5 +1,5 @@
# CustomFishing does not contain an enchantment system but it's able to
# read enchantments from NBT tags and customize its bonus!
# CustomFishing does not contain an enchantment system but it's able to read enchantments from NBT tags and customize its bonus!
# https://www.yuque.com/docs/share/4842ac5f-b5ea-4568-acef-d510f8bc9064?# 《Modifier System》
minecraft:luck_of_the_sea:
#levels
1:
@@ -25,7 +25,7 @@ minecraft:lucky_catch:
double-loot: 0.3
# You can register an enchantment in EcoEnchants called "easy_catch"
# And then config its effects in CustomFishing!
# And then create its effects in CustomFishing!
minecraft:easy_catch:
1:
difficulty: -1

View File

@@ -16,6 +16,7 @@ messages:
none-args: '非空参数!'
invalid-args: '无效参数!'
possible-loots: '此处可能钓到: '
reach-sell-limit: '你今天已经卖了很多鱼了!明天再来吧~'
split-char: ','
no-loot: '这个地方什么鱼都没有!'
competition-ongoing: '当前有一场钓鱼比赛进行中! 开始钓鱼以加入比赛获取奖励!'
@@ -28,4 +29,4 @@ messages:
hook-other-entity: '你的鱼钩被其他生物钩走了!'
no-rod: '你必须使用特殊鱼竿才能获得战利品!'
no-player: '虚位以待'
no-score: '无分数'
no-score: '无分数'

View File

@@ -16,6 +16,7 @@ messages:
none-args: 'None arguments!'
invalid-args: 'Invalid arguments!'
possible-loots: 'Possible loots here: '
reach-sell-limit: 'You have earned a lot from selling fish! Come tomorrow.'
split-char: ', '
no-loot: 'There''s no fish in this place!'
competition-ongoing: 'There is currently a fishing tournament in progress! Start fishing to join the contest for a prize!'

View File

@@ -16,6 +16,7 @@ messages:
none-args: '¡Ningún argumento!'
invalid-args: 'Argumentos no válidos'
possible-loots: 'Posible pesca aquí: '
reach-sell-limit: '¡Ganaste mucho dinero vendiendo pescado! Ven mañana.'
split-char: ', '
no-loot: '¡No hay peces en este lugar!'
competition-ongoing: '¡Actualmente hay un torneo de pesca en curso! Empieza a pescar para participar en el concurso y ganar un premio.'

View File

@@ -3,22 +3,32 @@ version: '${version}'
main: net.momirealms.customfishing.CustomFishing
api-version: 1.17
authors: [ XiaoMoMi ]
depend:
- ProtocolLib
softdepend:
- ItemsAdder
- MythicMobs
- Oraxen
- PlaceholderAPI
- Residence
- Kingdoms
- WorldGuard
- GriefDefender
- PlotSquared
- Towny
- EcoEnchants
- Lands
- GriefPrevention
- mcMMO
- AureliumSkills
- CustomCrops
- MMOCore
- EcoSkills
- EcoEnchants
- CrashClaim
- RealisticSeasons
- CustomCrops
- ItemsAdder
- Oraxen
- Jobs
- MMOItems
- eco
- Jobs
- Vault
commands:

View File

@@ -2,21 +2,28 @@ wooden_rod:
display:
name: 'Ordinary wooden fishing rod'
lore:
- 'Its just an ordinary fishing rod'
# The same to baits.yml
- '<gray>Its just an ordinary fishing rod'
- '<gray>But it''s quite friendly to a starter!'
# Click here to learn how modifier system works: https://www.yuque.com/docs/share/4842ac5f-b5ea-4568-acef-d510f8bc9064?# 《Modifier System》
modifier:
difficulty: 1
difficulty: -1
nature_fishing_cane:
display:
name: 'Nature Fishing Cane'
lore:
- '<gray>The wild power makes it easier to be hooked'
- '<gray>But also increase the difficulty'
custom-model-data: 2
modifier:
weight-add:
silver: 5
time: 0.9
difficulty: 1
silver_fishing_rod:
display:
name: 'Silver Fishing Rod'
lore:
- '<gray>Increase the chance of getting silver quality fish'
custom-model-data: 3
modifier:
weight-add:
@@ -26,6 +33,8 @@ silver_fishing_rod:
golden_fishing_rod:
display:
name: 'Golden Fishing Rod'
lore:
- '<gray>Increase the chance of getting golden quality fish'
custom-model-data: 4
modifier:
weight-add:
@@ -35,8 +44,11 @@ golden_fishing_rod:
star_fishing_rod:
display:
name: 'Star Fishing Rod'
lore:
- '<gray>Grants you the ability to fish in the lava'
custom-model-data: 5
modifier:
weight-add:
silver: 20
gold: 10
gold: 10
lava-fishing: true

View File

@@ -20,17 +20,17 @@ sounds:
actions:
message:
enable: true
text: 'You earned {money} from selling the fish'
text: 'You earned {money}$ from selling the fish! You can still gain {remains}$ from selling fish today'
title:
enable: true
title: '<green>Success'
subtitle: 'You earned {money} from selling the fish'
subtitle: 'You earned {money}$ from selling the fish'
in: 20
stay: 40
out: 20
actionbar:
enable: true
text: 'You earned {money} from selling the fish'
text: 'You earned {money}$ from selling the fish'
commands:
enable: false
value:

View File

@@ -1,4 +1,7 @@
# Vanilla blocks should be in capital format
# ItemsAdder: namespace:id: 'a'
# Oraxen: id: 'a'
AIR: 'air'
ANVIL: 'a'

View File

@@ -1,4 +1,4 @@
primary_fishing_totem:
double_loot_fishing_totem:
# Totem Core Block ID
core:
- o
@@ -11,9 +11,8 @@ primary_fishing_totem:
hologram:
enable: true
text:
- '<white>{time}s <gray>/ <white>{max_time}s'
- '<#87CEFA>Fishing Totem'
- '<white>{time}s <gray>/ <white>{max_time}s'
y-offset: 3.8
# Potion effect type and its amplifier
@@ -26,23 +25,22 @@ primary_fishing_totem:
# placeholders: {activator} {player} {world} {x} {y} {z}
action:
commands-activator:
- ''
#commands-activator: []
messages-activator:
- ''
commands-nearby-players:
- ''
- You activated a double loot totem!
#commands-nearby-players: []
messages-nearby-players:
- ''
- '{activator} activated a fishing totem!'
- 'Players inside of the effective range would get fishing buffs!'
# The layout of the totem
# The greater the layer is, the higher the y position is
# The greater the layer number is, the higher the y position is
# Totem core can be put anywhere in the layout
# “*” represents any type of block is allowed here
# “()“ represents the block is protected and will not be removed when activating
# “>“ represents the block would turn into another block after activating
# “|“ represents alternative block choice for this place
# “*” represents any type of block is allowed here [example *]
# “()“ represents the block is protected and will not be removed when activating [example (a)]
# “>“ represents the block would turn into another block after activating [example: a>b]
# “|“ represents alternative block choice for this place [example a|b>c]
layer:
4:
- '(p) (o) (p)'

View File

@@ -0,0 +1,6 @@
totem_activator:
material: DIAMOND
display:
name: '<gradient:#F0F8FF:#87CEFA:#F0F8FF>Double Loot Fishing Totem Core'
nbt:
Totem: (String) double_loot_fishing_totem