9
0
mirror of https://github.com/Xiao-MoMi/Custom-Fishing.git synced 2025-12-19 15:09:24 +00:00
This commit is contained in:
XiaoMoMi
2024-01-03 03:17:15 +08:00
parent d523a319e0
commit 23fc9c33bd
29 changed files with 268 additions and 187 deletions

View File

@@ -99,4 +99,8 @@ public class PlayerData {
public String getName() {
return name;
}
public boolean isLocked() {
return this == LOCKED;
}
}

View File

@@ -25,14 +25,23 @@ import java.util.Map;
public class StatisticData {
@SerializedName("map")
public Map<String, Integer> statisticMap;
@SerializedName(value="amount", alternate={"map"})
public Map<String, Integer> amountMap;
public StatisticData(@NotNull Map<String, Integer> data) {
this.statisticMap = data;
@SerializedName("size")
public Map<String, Float> sizeMap;
public StatisticData() {
this.sizeMap = new HashMap<>();
this.amountMap = new HashMap<>();
}
public StatisticData(@NotNull Map<String, Integer> amount, @NotNull Map<String, Float> size) {
this.amountMap = amount;
this.sizeMap = size;
}
public static StatisticData empty() {
return new StatisticData(new HashMap<>());
return new StatisticData();
}
}

View File

@@ -20,6 +20,8 @@ package net.momirealms.customfishing.api.manager;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import java.util.Map;
public interface MarketManager {
/**
@@ -56,12 +58,9 @@ public interface MarketManager {
/**
* Calculates the price based on a formula with provided variables.
*
* @param base The base value for the formula.
* @param bonus The bonus value for the formula.
* @param size The size value for the formula.
* @return The calculated price based on the formula and provided variables.
*/
double getFishPrice(float base, float bonus, float size);
double getFishPrice(Player player, Map<String, String> vars);
/**
* Gets the character representing the item slot in the MarketGUI.

View File

@@ -28,5 +28,6 @@ public enum ActionTrigger {
LAND,
ACTIVATE,
TIMER,
INTERACT
INTERACT,
NEW_SIZE_RECORD
}

View File

@@ -20,6 +20,7 @@ package net.momirealms.customfishing.api.mechanic.loot;
import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.statistic.StatisticsKey;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
@@ -38,6 +39,7 @@ public class CFLoot implements Loot {
private double score;
private String[] lootGroup;
private String filePath;
private StatisticsKey statisticsKey;
public CFLoot(String id, LootType type) {
this.id = id;
@@ -149,6 +151,17 @@ public class CFLoot implements Loot {
return this;
}
/**
* Set the statistics key for this loot
*
* @param statisticsKey statistics key
* @return The builder.
*/
public Builder statsKey(StatisticsKey statisticsKey) {
this.loot.statisticsKey = statisticsKey;
return this;
}
/**
* Add actions triggered by a specific trigger.
*
@@ -245,6 +258,11 @@ public class CFLoot implements Loot {
return this.nick;
}
@Override
public StatisticsKey getStatisticKey() {
return this.statisticsKey;
}
/**
* Check if this loot should be shown in the finder.
*

View File

@@ -20,6 +20,7 @@ package net.momirealms.customfishing.api.mechanic.loot;
import net.momirealms.customfishing.api.mechanic.action.Action;
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
import net.momirealms.customfishing.api.mechanic.condition.Condition;
import net.momirealms.customfishing.api.mechanic.statistic.StatisticsKey;
import org.jetbrains.annotations.NotNull;
import java.util.HashMap;
@@ -55,6 +56,8 @@ public interface Loot {
@NotNull
String getNick();
StatisticsKey getStatisticKey();
/**
* Check if this loot should be shown in the finder.
*

View File

@@ -32,6 +32,7 @@ import java.util.concurrent.ConcurrentHashMap;
public class Statistics {
private final ConcurrentHashMap<String, Integer> statisticMap;
private final ConcurrentHashMap<String, Float> sizeMap;
private int total;
/**
@@ -40,7 +41,8 @@ public class Statistics {
* @param statisticData The initial statistic data.
*/
public Statistics(StatisticData statisticData) {
this.statisticMap = new ConcurrentHashMap<>(statisticData.statisticMap);
this.statisticMap = new ConcurrentHashMap<>(statisticData.amountMap);
this.sizeMap = new ConcurrentHashMap<>(statisticData.sizeMap);
this.total = statisticMap.values().stream().mapToInt(Integer::intValue).sum();
}
@@ -52,14 +54,17 @@ public class Statistics {
* @param amount The amount of loot to add.
*/
public synchronized void addLootAmount(Loot loot, Condition condition, int amount) {
if (amount < 1) {
return;
}
if (amount == 1) {
addSingleLootAmount(loot, condition);
return;
}
Integer previous = statisticMap.get(loot.getID());
Integer previous = statisticMap.get(loot.getStatisticKey().getAmountKey());
if (previous == null) previous = 0;
int after = previous + amount;
statisticMap.put(loot.getID(), after);
statisticMap.put(loot.getStatisticKey().getAmountKey(), after);
total += amount;
doSuccessTimesAction(previous, after, condition, loot);
}
@@ -85,6 +90,13 @@ public class Statistics {
}
}
public boolean setSizeIfHigher(String loot, float size) {
float previous = sizeMap.getOrDefault(loot, 0f);
if (previous >= size) return false;
sizeMap.put(loot, size);
return true;
}
/**
* Adds a single loot amount to the statistics.
*
@@ -111,8 +123,11 @@ public class Statistics {
* @return The amount of the specified loot item.
*/
public int getLootAmount(String key) {
Integer amount = statisticMap.get(key);
return amount == null ? 0 : amount;
return statisticMap.getOrDefault(key, 0);
}
public float getSizeRecord(String key) {
return sizeMap.getOrDefault(key, 0f);
}
/**
@@ -132,6 +147,10 @@ public class Statistics {
return statisticMap;
}
public ConcurrentHashMap<String, Float> getSizeMap() {
return sizeMap;
}
/**
* Sets data for a specific key in the statistics.
*

View File

@@ -0,0 +1,20 @@
package net.momirealms.customfishing.api.mechanic.statistic;
public class StatisticsKey {
private final String amountKey;
private final String sizeKey;
public StatisticsKey(String amountKey, String sizeKey) {
this.amountKey = amountKey;
this.sizeKey = sizeKey;
}
public String getAmountKey() {
return amountKey;
}
public String getSizeKey() {
return sizeKey;
}
}

View File

@@ -7,7 +7,7 @@ plugins {
allprojects {
version = "2.0.8"
version = "2.0.9"
apply<JavaPlugin>()
apply(plugin = "java")

View File

@@ -149,10 +149,8 @@ public class IntegrationManagerImpl implements IntegrationManager {
hookMessage("ClueScrolls");
}
if (plugin.isHookedPluginEnabled("BetonQuest")) {
if (Objects.requireNonNull(Bukkit.getPluginManager().getPlugin("BetonQuest")).getPluginMeta().getVersion().startsWith("2")) {
BetonQuestHook.register();
hookMessage("BetonQuest");
}
BetonQuestHook.register();
hookMessage("BetonQuest");
}
// if (plugin.isHookedPluginEnabled("NotQuests")) {
// NotQuestHook notQuestHook = new NotQuestHook();

View File

@@ -82,6 +82,9 @@ public class StatisticsPapi extends PlaceholderExpansion {
if (split.length == 1) return "Invalid format";
return String.valueOf(statistics.getLootAmount(split[1]));
}
case "size-record" -> {
return String.format("%.2f", statistics.getSizeRecord(split[1]));
}
case "category" -> {
if (split.length == 1) return "Invalid format";
String[] categorySplit = split[1].split("_", 2);

View File

@@ -1,48 +0,0 @@
package net.momirealms.customfishing.gui.icon.property.requirement;
import net.momirealms.customfishing.adventure.AdventureManagerImpl;
import net.momirealms.customfishing.adventure.component.ShadedAdventureComponentWrapper;
import net.momirealms.customfishing.gui.SectionPage;
import org.bukkit.Material;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.jetbrains.annotations.NotNull;
import xyz.xenondevs.invui.item.ItemProvider;
import xyz.xenondevs.invui.item.builder.ItemBuilder;
import xyz.xenondevs.invui.item.impl.AbstractItem;
public class RequirementEditorIcon extends AbstractItem {
private final SectionPage sectionPage;
private final String sectionName;
public RequirementEditorIcon(SectionPage sectionPage, String requirementSectionName) {
this.sectionPage = sectionPage;
this.sectionName = requirementSectionName;
}
@Override
public ItemProvider getItemProvider() {
ItemBuilder itemBuilder = new ItemBuilder(Material.COMPASS)
.setDisplayName(new ShadedAdventureComponentWrapper(AdventureManagerImpl.getInstance().getComponentFromMiniMessage(
"<#B0E0E6>● Requirements"
)))
.addLoreLines("")
.addLoreLines(new ShadedAdventureComponentWrapper(AdventureManagerImpl.getInstance().getComponentFromMiniMessage(
"<#00FF7F> -> Click to edit requirements"
)));
return itemBuilder;
}
@Override
public void handleClick(@NotNull ClickType clickType, @NotNull Player player, @NotNull InventoryClickEvent event) {
ConfigurationSection reqSection = sectionPage.getSection().getConfigurationSection(sectionName);
if (reqSection == null)
reqSection = sectionPage.getSection().createSection(sectionName);
}
}

View File

@@ -1,17 +0,0 @@
package net.momirealms.customfishing.gui.page.requirement;
import net.momirealms.customfishing.gui.SectionPage;
import org.bukkit.entity.Player;
public class RequirementEditor {
private Player player;
private SectionPage sectionPage;
public RequirementEditor(Player player, SectionPage sectionPage) {
this.player = player;
this.sectionPage = sectionPage;
}
}

View File

@@ -79,7 +79,6 @@ public class Competition implements FishingCompetition {
this.progress = 1;
this.remainingTime = config.getDurationInSeconds();
this.startTime = Instant.now().getEpochSecond();
this.updatePublicPlaceholders();
this.arrangeTimerTask();
if (config.getBossBarConfig() != null) {
@@ -99,6 +98,9 @@ public class Competition implements FishingCompetition {
}
}
this.ranking.clear();
this.updatePublicPlaceholders();
CompetitionEvent competitionStartEvent = new CompetitionEvent(CompetitionEvent.State.START, this);
Bukkit.getPluginManager().callEvent(competitionStartEvent);
}

View File

@@ -20,6 +20,7 @@ package net.momirealms.customfishing.mechanic.competition.ranking;
import net.momirealms.customfishing.api.common.Pair;
import net.momirealms.customfishing.api.mechanic.competition.CompetitionPlayer;
import net.momirealms.customfishing.api.mechanic.competition.Ranking;
import net.momirealms.customfishing.setting.CFConfig;
import net.momirealms.customfishing.storage.method.database.nosql.RedisManager;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.resps.Tuple;
@@ -35,7 +36,7 @@ public class RedisRankingImpl implements Ranking {
@Override
public void clear() {
try (Jedis jedis = RedisManager.getInstance().getJedis()) {
jedis.zremrangeByRank("cf_competition",0,-1);
jedis.del("cf_competition_" + CFConfig.serverGroup);
}
}
@@ -48,7 +49,7 @@ public class RedisRankingImpl implements Ranking {
@Override
public CompetitionPlayer getCompetitionPlayer(String player) {
try (Jedis jedis = RedisManager.getInstance().getJedis()) {
Double score = jedis.zscore("cf_competition", player);
Double score = jedis.zscore("cf_competition_" + CFConfig.serverGroup, player);
if (score == null || score == 0) return null;
return new CompetitionPlayer(player, Float.parseFloat(score.toString()));
}
@@ -57,7 +58,7 @@ public class RedisRankingImpl implements Ranking {
@Override
public CompetitionPlayer getCompetitionPlayer(int rank) {
try (Jedis jedis = RedisManager.getInstance().getJedis()) {
List<Tuple> player = jedis.zrevrangeWithScores("cf_competition", rank - 1, rank -1);
List<Tuple> player = jedis.zrevrangeWithScores("cf_competition_" + CFConfig.serverGroup, rank - 1, rank -1);
if (player == null || player.size() == 0) return null;
return new CompetitionPlayer(player.get(0).getElement(), player.get(0).getScore());
}
@@ -66,14 +67,14 @@ public class RedisRankingImpl implements Ranking {
@Override
public void addPlayer(CompetitionPlayer competitionPlayer) {
try (Jedis jedis = RedisManager.getInstance().getJedis()) {
jedis.zincrby("cf_competition", competitionPlayer.getScore(), competitionPlayer.getPlayer());
jedis.zincrby("cf_competition_" + CFConfig.serverGroup, competitionPlayer.getScore(), competitionPlayer.getPlayer());
}
}
@Override
public void removePlayer(String player) {
try (Jedis jedis = RedisManager.getInstance().getJedis()) {
jedis.del("cf_competition", player);
jedis.zrem("cf_competition_" + CFConfig.serverGroup, player);
}
}
@@ -85,7 +86,7 @@ public class RedisRankingImpl implements Ranking {
@Override
public Iterator<Pair<String, Double>> getIterator() {
try (Jedis jedis = RedisManager.getInstance().getJedis()) {
List<Tuple> players = jedis.zrevrangeWithScores("cf_competition", 0, -1);
List<Tuple> players = jedis.zrevrangeWithScores("cf_competition_" + CFConfig.serverGroup, 0, -1);
return players.stream().map(it -> Pair.of(it.getElement(), it.getScore())).toList().iterator();
}
}
@@ -98,7 +99,7 @@ public class RedisRankingImpl implements Ranking {
@Override
public int getSize() {
try (Jedis jedis = RedisManager.getInstance().getJedis()) {
long size = jedis.zcard("cf_competition");
long size = jedis.zcard("cf_competition_" + CFConfig.serverGroup);
return (int) size;
}
}
@@ -112,7 +113,7 @@ public class RedisRankingImpl implements Ranking {
@Override
public int getPlayerRank(String player) {
try (Jedis jedis = RedisManager.getInstance().getJedis()) {
Long rank = jedis.zrevrank("cf_competition", player);
Long rank = jedis.zrevrank("cf_competition_" + CFConfig.serverGroup, player);
if (rank == null)
return -1;
return (int) (rank + 1);
@@ -128,7 +129,7 @@ public class RedisRankingImpl implements Ranking {
@Override
public double getPlayerScore(String player) {
try (Jedis jedis = RedisManager.getInstance().getJedis()) {
Double rank = jedis.zscore("cf_competition", player);
Double rank = jedis.zscore("cf_competition_" + CFConfig.serverGroup, player);
if (rank == null)
return 0;
return rank.floatValue();
@@ -144,7 +145,7 @@ public class RedisRankingImpl implements Ranking {
@Override
public void refreshData(String player, double score) {
try (Jedis jedis = RedisManager.getInstance().getJedis()) {
jedis.zincrby("cf_competition", score, player);
jedis.zincrby("cf_competition_" + CFConfig.serverGroup, score, player);
}
}
@@ -157,7 +158,7 @@ public class RedisRankingImpl implements Ranking {
@Override
public void setData(String player, double score) {
try (Jedis jedis = RedisManager.getInstance().getJedis()) {
jedis.zadd("cf_competition", score, player);
jedis.zadd("cf_competition_" + CFConfig.serverGroup, score, player);
}
}
@@ -170,7 +171,7 @@ public class RedisRankingImpl implements Ranking {
@Override
public String getPlayerAt(int rank) {
try (Jedis jedis = RedisManager.getInstance().getJedis()) {
List<String> player = jedis.zrevrange("cf_competition", rank - 1, rank -1);
List<String> player = jedis.zrevrange("cf_competition_" + CFConfig.serverGroup, rank - 1, rank -1);
if (player == null || player.size() == 0) return null;
return player.get(0);
}
@@ -185,7 +186,7 @@ public class RedisRankingImpl implements Ranking {
@Override
public double getScoreAt(int rank) {
try (Jedis jedis = RedisManager.getInstance().getJedis()) {
List<Tuple> players = jedis.zrevrangeWithScores("cf_competition", rank - 1, rank -1);
List<Tuple> players = jedis.zrevrangeWithScores("cf_competition_" + CFConfig.serverGroup, rank - 1, rank -1);
if (players == null || players.size() == 0) return 0;
return players.get(0).getScore();
}

View File

@@ -678,37 +678,33 @@ public class FishingManagerImpl implements Listener, FishingManager {
if (scoreStr != null) {
competition.refreshData(player, Double.parseDouble(scoreStr));
} else {
double score = 0;
switch (competition.getGoal()) {
case CATCH_AMOUNT -> {
fishingPreparation.insertArg("{score}", "1.00");
competition.refreshData(player, 1);
fishingPreparation.insertArg("{SCORE}", "1");
score = 1;
competition.refreshData(player, score);
}
case MAX_SIZE, TOTAL_SIZE -> {
String size = fishingPreparation.getArg("{SIZE}");
if (size != null) {
double score = Double.parseDouble(size);
fishingPreparation.insertArg("{score}", String.format("%.2f", score));
score = Double.parseDouble(size);
competition.refreshData(player, score);
fishingPreparation.insertArg("{SCORE}", size);
} else {
fishingPreparation.insertArg("{score}", String.format("%.2f", 0.00));
fishingPreparation.insertArg("{SCORE}", "0");
score = 0;
}
}
case TOTAL_SCORE -> {
double score = loot.getScore();
if (score != 0) {
double finalScore = score * effect.getScoreMultiplier() + effect.getScore();
fishingPreparation.insertArg("{score}", String.format("%.2f", finalScore));
competition.refreshData(player, finalScore);
fishingPreparation.insertArg("{SCORE}", String.valueOf(finalScore));
score = loot.getScore();
if (score > 0) {
score = score * effect.getScoreMultiplier() + effect.getScore();
competition.refreshData(player, score);
} else {
fishingPreparation.insertArg("{score}", "0.00");
fishingPreparation.insertArg("{SCORE}", "0");
score = 0;
}
}
}
fishingPreparation.insertArg("{score}", String.format("%.2f", score));
fishingPreparation.insertArg("{SCORE}", String.valueOf(score));
}
}
@@ -726,7 +722,15 @@ public class FishingManagerImpl implements Listener, FishingManager {
Optional.ofNullable(
plugin.getStatisticsManager()
.getStatistics(player.getUniqueId())
).ifPresent(it -> it.addLootAmount(loot, fishingPreparation, 1));
).ifPresent(it -> {
it.addLootAmount(loot, fishingPreparation, 1);
String size = fishingPreparation.getArg("{SIZE}");
if (size != null)
if (it.setSizeIfHigher(loot.getStatisticKey().getSizeKey(), Float.parseFloat(size))) {
GlobalSettings.triggerLootActions(ActionTrigger.NEW_SIZE_RECORD, fishingPreparation);
loot.triggerActions(ActionTrigger.NEW_SIZE_RECORD, fishingPreparation);
}
});
}
/**

View File

@@ -188,6 +188,10 @@ public class HookCheckTimerTask implements Runnable {
fishingPreparation.insertArg("{x}", String.valueOf(fishHook.getLocation().getBlockX()));
fishingPreparation.insertArg("{y}", String.valueOf(fishHook.getLocation().getBlockY()));
fishingPreparation.insertArg("{z}", String.valueOf(fishHook.getLocation().getBlockZ()));
if (!nextLoot.disableStats()) {
fishingPreparation.insertArg("{statistics_size}", nextLoot.getStatisticKey().getSizeKey());
fishingPreparation.insertArg("{statistics_amount}", nextLoot.getStatisticKey().getAmountKey());
}
CustomFishingPlugin.get().getScheduler().runTaskAsync(() -> manager.setTempFishingState(fishingPreparation.getPlayer(), new TempFishingState(
initialEffect,
fishingPreparation,

View File

@@ -727,19 +727,13 @@ public class ItemManagerImpl implements ItemManager, Listener {
public ItemBuilder price(float base, float bonus) {
if (base == 0 && bonus == 0) return this;
editors.put("price", (player, nbtItem, placeholders) -> {
if (base != 0) {
placeholders.put("{base}", String.format("%.2f", base));
placeholders.put("{BASE}", String.valueOf(base));
}
if (bonus != 0) {
placeholders.put("{bonus}", String.format("%.2f", bonus));
placeholders.put("{BONUS}", String.valueOf(bonus));
}
float size = Float.parseFloat(placeholders.getOrDefault("{SIZE}", "0"));
placeholders.put("{base}", String.format("%.2f", base));
placeholders.put("{BASE}", String.valueOf(base));
placeholders.put("{bonus}", String.format("%.2f", bonus));
placeholders.put("{BONUS}", String.valueOf(bonus));
double price = CustomFishingPlugin.get().getMarketManager().getFishPrice(
base,
bonus,
size
player,
placeholders
);
nbtItem.setDouble("Price", price);
placeholders.put("{price}", String.format("%.2f", price));

View File

@@ -26,6 +26,7 @@ import net.momirealms.customfishing.api.mechanic.loot.CFLoot;
import net.momirealms.customfishing.api.mechanic.loot.Loot;
import net.momirealms.customfishing.api.mechanic.loot.LootType;
import net.momirealms.customfishing.api.mechanic.loot.WeightModifier;
import net.momirealms.customfishing.api.mechanic.statistic.StatisticsKey;
import net.momirealms.customfishing.api.util.LogUtils;
import net.momirealms.customfishing.api.util.WeightUtils;
import net.momirealms.customfishing.mechanic.requirement.RequirementManagerImpl;
@@ -273,6 +274,7 @@ public class LootManagerImpl implements LootManager {
.nick(section.getString("nick", section.getString("display.name", key)))
.addActions(plugin.getActionManager().getActionMap(section.getConfigurationSection("events")))
.addTimesActions(plugin.getActionManager().getTimesActionMap(section.getConfigurationSection("events.success-times")))
.statsKey(new StatisticsKey(section.getString("statistics.amount", key), section.getString("statistics.size", key)))
.build();
}
}

View File

@@ -429,20 +429,11 @@ public class MarketManagerImpl implements MarketManager, Listener {
/**
* Calculates the price based on a formula with provided variables.
*
* @param base The base value for the formula.
* @param bonus The bonus value for the formula.
* @param size The size value for the formula.
* @return The calculated price based on the formula and provided variables.
*/
@Override
public double getFishPrice(float base, float bonus, float size) {
Expression expression = new ExpressionBuilder(getFormula())
.variables("base", "bonus", "size")
.build()
.setVariable("base", base)
.setVariable("bonus", bonus)
.setVariable("size", size);
return expression.evaluate();
public double getFishPrice(Player player, Map<String, String> vars) {
return ConfigUtils.getExpressionValue(player, formula, vars);
}
/**

View File

@@ -213,6 +213,8 @@ public class RequirementManagerImpl implements RequirementManager {
this.registerListRequirement();
this.registerEnvironmentRequirement();
this.registerPotionEffectRequirement();
this.registerSizeRequirement();
this.registerHasStatsRequirement();
}
public HashMap<String, Double> getLootWithWeight(Condition condition) {
@@ -1044,6 +1046,35 @@ public class RequirementManagerImpl implements RequirementManager {
});
}
private void registerSizeRequirement() {
registerRequirement("has-size", (args, actions, advanced) -> {
boolean has = (boolean) args;
return condition -> {
String size = condition.getArg("{SIZE}");
if (size != null && has) return true;
if (size == null && !has) return true;
if (advanced) triggerActions(actions, condition);
return false;
};
});
}
private void registerHasStatsRequirement() {
registerRequirement("has-stats", (args, actions, advanced) -> {
boolean has = (boolean) args;
return condition -> {
String loot = condition.getArg("{loot}");
Loot lootInstance = plugin.getLootManager().getLoot(loot);
if (lootInstance != null) {
if (!lootInstance.disableStats() && has) return true;
if (lootInstance.disableStats() && !has) return true;
}
if (advanced) triggerActions(actions, condition);
return false;
};
});
}
private void registerEnvironmentRequirement() {
registerRequirement("environment", (args, actions, advanced) -> {
List<String> environments = ConfigUtils.stringListArgs(args);

View File

@@ -80,7 +80,7 @@ public class CFConfig {
// Competition
public static boolean redisRanking;
public static List<String> serverGroup;
public static String serverGroup;
public static int placeholderLimit;
// Data save interval
@@ -163,7 +163,7 @@ public class CFConfig {
redisRanking = config.getBoolean("mechanics.competition.redis-ranking", false);
placeholderLimit = config.getInt("mechanics.competition.placeholder-limit", 3);
serverGroup = ConfigUtils.stringListArgs(config.get("mechanics.competition.server-group","default"));
serverGroup = config.getString("mechanics.competition.server-group","default");
dataSaveInterval = config.getInt("other-settings.data-saving-interval", 600);
logDataSaving = config.getBoolean("other-settings.log-data-saving", true);

View File

@@ -200,7 +200,7 @@ public class StorageManagerImpl implements StorageManager, Listener {
return CompletableFuture.completedFuture(Optional.empty());
}
PlayerData data = optionalUser.get();
if (data == PlayerData.LOCKED) {
if (data.isLocked()) {
return CompletableFuture.completedFuture(Optional.of(OfflineUserImpl.LOCKED_USER));
} else {
OfflineUser offlineUser = new OfflineUserImpl(uuid, data.getName(), data);
@@ -343,7 +343,7 @@ public class StorageManagerImpl implements StorageManager, Listener {
// Data should not be empty
if (optionalData.isEmpty())
return;
if (optionalData.get() == PlayerData.LOCKED) {
if (optionalData.get().isLocked()) {
waitForDataLockRelease(uuid, times + 1);
} else {
putDataInCache(player, optionalData.get());

View File

@@ -184,7 +184,7 @@ public abstract class AbstractHikariDatabase extends AbstractSQLDatabase impleme
.map(element -> element.split(":"))
.filter(pair -> pair.length == 2)
.collect(Collectors.toMap(pair -> pair[0], pair -> Integer.parseInt(pair[1])));
builder.setStats(new StatisticData(amountMap));
builder.setStats(new StatisticData(amountMap, new HashMap<>()));
} else {
builder.setStats(StatisticData.empty());
}

View File

@@ -63,12 +63,13 @@ public class YAMLImpl extends AbstractStorage implements LegacyDataStorageInterf
File dataFile = getPlayerDataFile(uuid);
if (!dataFile.exists()) {
if (Bukkit.getPlayer(uuid) != null) {
return CompletableFuture.completedFuture(Optional.of(PlayerData.LOCKED));
} else {
return CompletableFuture.completedFuture(Optional.of(PlayerData.empty()));
} else {
return CompletableFuture.completedFuture(Optional.empty());
}
}
YamlConfiguration data = ConfigUtils.readData(dataFile);
PlayerData playerData = new PlayerData.Builder()
.setBagData(new InventoryData(data.getString("bag", ""), data.getInt("size", 9)))
.setEarningData(new EarningData(data.getDouble("earnings"), data.getInt("date")))
@@ -87,8 +88,13 @@ public class YAMLImpl extends AbstractStorage implements LegacyDataStorageInterf
data.set("date", playerData.getEarningData().date);
data.set("earnings", playerData.getEarningData().earnings);
ConfigurationSection section = data.createSection("stats");
for (Map.Entry<String, Integer> entry : playerData.getStatistics().statisticMap.entrySet()) {
section.set(entry.getKey(), entry.getValue());
ConfigurationSection amountSection = section.createSection("amount");
ConfigurationSection sizeSection = section.createSection("size");
for (Map.Entry<String, Integer> entry : playerData.getStatistics().amountMap.entrySet()) {
amountSection.set(entry.getKey(), entry.getValue());
}
for (Map.Entry<String, Float> entry : playerData.getStatistics().sizeMap.entrySet()) {
sizeSection.set(entry.getKey(), entry.getValue());
}
try {
data.save(getPlayerDataFile(uuid));
@@ -125,15 +131,24 @@ public class YAMLImpl extends AbstractStorage implements LegacyDataStorageInterf
* @return The parsed StatisticData object.
*/
private StatisticData getStatistics(ConfigurationSection section) {
if (section == null)
return StatisticData.empty();
else {
HashMap<String, Integer> map = new HashMap<>();
for (Map.Entry<String, Object> entry : section.getValues(false).entrySet()) {
map.put(entry.getKey(), (Integer) entry.getValue());
}
return new StatisticData(map);
HashMap<String, Integer> amountMap = new HashMap<>();
HashMap<String, Float> sizeMap = new HashMap<>();
if (section == null) {
return new StatisticData(amountMap, sizeMap);
}
ConfigurationSection amountSection = section.getConfigurationSection("amount");
if (amountSection != null) {
for (Map.Entry<String, Object> entry : amountSection.getValues(false).entrySet()) {
amountMap.put(entry.getKey(), (Integer) entry.getValue());
}
}
ConfigurationSection sizeSection = section.getConfigurationSection("size");
if (sizeSection != null) {
for (Map.Entry<String, Object> entry : sizeSection.getValues(false).entrySet()) {
sizeMap.put(entry.getKey(), ((Double) entry.getValue()).floatValue());
}
}
return new StatisticData(amountMap, sizeMap);
}
@Override
@@ -159,7 +174,7 @@ public class YAMLImpl extends AbstractStorage implements LegacyDataStorageInterf
map.put(entry.getKey(), integer);
}
}
builder.setStats(new StatisticData(map));
builder.setStats(new StatisticData(map, new HashMap<>()));
} else {
builder.setStats(StatisticData.empty());
}

View File

@@ -119,7 +119,7 @@ public class OfflineUserImpl implements OfflineUser {
return new PlayerData.Builder()
.setBagData(new InventoryData(InventoryUtils.stacksToBase64(holder.getInventory().getStorageContents()), holder.getInventory().getSize()))
.setEarningData(earningData)
.setStats(new StatisticData(statistics.getStatisticMap()))
.setStats(new StatisticData(statistics.getStatisticMap(), statistics.getSizeMap()))
.setName(name)
.build();
}

View File

@@ -45,7 +45,46 @@ mechanics:
hook: {}
bait: {}
loot:
new_size_record:
conditional_size_record_action:
type: conditional
value:
conditions:
has-stats: true
actions:
actionbar_action:
type: actionbar
value: '<#FFD700>[New Record]</#FFD700> <#FFFFF0>You caught a(n) {nick} which is <#FFA500>{size}cm</#FFA500> long!</#FFFFF0>'
sound_action:
type: sound
value:
key: "minecraft:block.note_block.cow_bell"
source: 'player'
volume: 1
pitch: 1
delayed_sound:
type: delay
value:
delay: 2
actions:
sound_action:
type: sound
value:
key: "minecraft:block.note_block.bell"
source: 'player'
volume: 1
pitch: 1
success:
conditional_size_info_action:
type: conditional
value:
conditions:
has-size: true
has-stats: true
actions:
actionbar_action:
type: actionbar
value: '<gray>You caught a(n) {nick} which is <#F5F5F5>{size}cm</#F5F5F5> long!</gray> <#C0C0C0>(Best record: {record}cm)</#C0C0C0>'
title_action:
type: random-title
value:
@@ -53,7 +92,7 @@ mechanics:
- '<green>GG!</green>'
- '<green>Good Job!</green>'
subtitles:
- 'You caught a {nick}'
- 'You caught a(n) {nick}'
- 'Whoa! Nice catch!'
- 'Oh {nick} here we go!'
- 'Let''s see what it is!'
@@ -191,6 +230,8 @@ other-settings:
# Requires PlaceholderAPI to work
placeholder-register:
'{record}': '%fishingstats_size-record_{loot}%'
# Requires server expansion
'{date}': '%server_time_yyyy-MM-dd-HH:mm:ss%'
# CustomFishing supports using items/blocks from other plugins

View File

@@ -4,6 +4,8 @@
# customized configurations based on your own ideas,
# allowing players to experience the uniqueness of your server.
# https://mo-mi.gitbook.io/xiaomomi-plugins/plugin-wiki/customfishing/loot/item
# Vanilla loots settings
vanilla:
show-in-fishfinder: false
@@ -131,6 +133,7 @@ sharpness_book:
tag: false
material: enchanted_book
group: enchantments
nick: "<lang:item.minecraft.enchanted_book>"
show-in-fishfinder: false
disable-stat: true
random-stored-enchantments:
@@ -159,6 +162,7 @@ efficiency_book:
material: enchanted_book
group: enchantments
show-in-fishfinder: false
nick: "<lang:item.minecraft.enchanted_book>"
disable-stat: true
random-stored-enchantments:
lv5:
@@ -186,6 +190,7 @@ unbreaking_book:
material: enchanted_book
group: enchantments
show-in-fishfinder: false
nick: "<lang:item.minecraft.enchanted_book>"
disable-stat: true
random-stored-enchantments:
lv3:
@@ -205,6 +210,7 @@ protection_book:
material: enchanted_book
group: enchantments
show-in-fishfinder: false
nick: "<lang:item.minecraft.enchanted_book>"
disable-stat: true
random-stored-enchantments:
lv4:
@@ -226,7 +232,6 @@ protection_book:
# Fish
tuna_fish:
material: cod
nick: <gradient:#F0FFFF:#4682B4:#F0FFFF>Tuna Fish</gradient>
display:
name: <gradient:#F0FFFF:#4682B4:#F0FFFF>Tuna Fish</gradient>
lore:
@@ -292,7 +297,6 @@ tuna_fish_golden_star:
bonus: 0.7
pike_fish:
material: cod
nick: <gradient:#F0F8FF:#5F9EA0:#F0F8FF>Pike Fish</gradient>
display:
name: <gradient:#F0F8FF:#5F9EA0:#F0F8FF>Pike Fish</gradient>
lore:
@@ -506,7 +510,6 @@ perch_fish_golden_star:
bonus: 3
mullet_fish:
material: cod
nick: <gradient:#D4F2E7:#E1FFFF:#D4F2E7>Mullet Fish</gradient>
display:
name: <gradient:#D4F2E7:#E1FFFF:#D4F2E7>Mullet Fish</gradient>
lore:
@@ -575,7 +578,6 @@ mullet_fish_golden_star:
bonus: 1.5
sardine_fish:
material: cod
nick: <gradient:#E1FFFF:#5F9EA0>Sardine Fish</gradient>
display:
name: <gradient:#E1FFFF:#5F9EA0>Sardine Fish</gradient>
lore:
@@ -642,7 +644,6 @@ sardine_fish_golden_star:
bonus: 3.4
carp_fish:
material: cod
nick: <gradient:#808000:#556B2F>Carp Fish</gradient>
display:
name: <gradient:#808000:#556B2F>Carp Fish</gradient>
lore:
@@ -772,7 +773,6 @@ cat_fish_golden_star:
bonus: 2.2
octopus:
material: cod
nick: <gradient:#D2691E:#FF6347>Octopus</gradient>
display:
name: <gradient:#D2691E:#FF6347>Octopus</gradient>
lore:
@@ -839,9 +839,8 @@ octopus_golden_star:
bonus: 1.5
sunfish:
material: cod
nick: <#F5DEB3>Sunfish</#F5DEB3>
display:
name: <#F5DEB3>Sunfish
name: <#F5DEB3>Sunfish</#F5DEB3>
lore:
- <gray>It only has one huge head
- '<white>size: {size}cm'
@@ -971,8 +970,6 @@ red_snapper_fish_golden_star:
bonus: 2.3
salmon_void_fish:
material: cod
in-lava: true
nick: <gradient:#800000:#800080>Void Salmon</gradient>
display:
name: <gradient:#800000:#800080>Void Salmon</gradient>
lore:
@@ -993,10 +990,9 @@ salmon_void_fish:
bonus: 2.4
salmon_void_fish_silver_star:
show-in-fishfinder: false
in-lava: true
material: cod
display:
name: <gradient:#800000:#800080>Void Salmon</gradient><#F5F5F5>(Silver Star)</#F5F5F5>
name: <gradient:#800000:#800080>Void Salmon</gradient> <#F5F5F5>(Silver Star)</#F5F5F5>
lore:
- <gray>A fish from the hell
- <gray>It's looking at you...
@@ -1017,7 +1013,6 @@ salmon_void_fish_silver_star:
bonus: 2.6
salmon_void_fish_golden_star:
show-in-fishfinder: false
in-lava: true
material: cod
display:
name: <gradient:#800000:#800080>Void Salmon</gradient> <#FFD700>(Golden Star)</#FFD700>
@@ -1041,9 +1036,8 @@ salmon_void_fish_golden_star:
bonus: 3
woodskip_fish:
material: cod
nick: <#CD5C5C>Woodskip Fish</#CD5C5C>
display:
name: <#CD5C5C>Woodskip Fish
name: <#CD5C5C>Woodskip Fish</#CD5C5C>
lore:
- <gray>A very sensitive fish that can only
- <gray>live in pools deep in the forest
@@ -1064,7 +1058,7 @@ woodskip_fish_silver_star:
show-in-fishfinder: false
material: cod
display:
name: <#CD5C5C>Woodskip Fish <#F5F5F5>(Silver Star)</#F5F5F5>
name: <#CD5C5C>Woodskip Fish</#CD5C5C> <#F5F5F5>(Silver Star)</#F5F5F5>
lore:
- <gray>A very sensitive fish that can only
- <gray>live in pools deep in the forest
@@ -1087,7 +1081,7 @@ woodskip_fish_golden_star:
show-in-fishfinder: false
material: cod
display:
name: <#CD5C5C>Woodskip Fish <#FFD700>(Golden Star)</#FFD700>
name: <#CD5C5C>Woodskip Fish</#CD5C5C> <#FFD700>(Golden Star)</#FFD700>
lore:
- <gray>A very sensitive fish that can only
- <gray>live in pools deep in the forest
@@ -1108,9 +1102,8 @@ woodskip_fish_golden_star:
bonus: 2.8
sturgeon_fish:
material: cod
nick: <#48D1CC>Sturgeon Fish</#48D1CC>
display:
name: <#48D1CC>Sturgeon Fish
name: <#48D1CC>Sturgeon Fish</#48D1CC>
lore:
- <gray>An ancient bottom-feeder with a dwindling
- <gray>population. Females can live up to 150 years
@@ -1131,7 +1124,7 @@ sturgeon_fish_silver_star:
show-in-fishfinder: false
material: cod
display:
name: <#48D1CC>Sturgeon Fish <#F5F5F5>(Silver Star)</#F5F5F5>
name: <#48D1CC>Sturgeon Fish</#48D1CC> <#F5F5F5>(Silver Star)</#F5F5F5>
lore:
- <gray>An ancient bottom-feeder with a dwindling
- <gray>population. Females can live up to 150 years
@@ -1154,7 +1147,7 @@ sturgeon_fish_golden_star:
show-in-fishfinder: false
material: cod
display:
name: <#48D1CC>Sturgeon Fish <#FFD700>(Golden Star)</#FFD700>
name: <#48D1CC>Sturgeon Fish</#48D1CC> <#FFD700>(Golden Star)</#FFD700>
lore:
- <gray>An ancient bottom-feeder with a dwindling
- <gray>population. Females can live up to 150 years
@@ -1175,7 +1168,6 @@ sturgeon_fish_golden_star:
bonus: 10
blue_jellyfish:
material: cod
nick: <#87CEFA>Jellyfish</#87CEFA>
display:
name: <#87CEFA>Jellyfish</#87CEFA>
lore:
@@ -1196,7 +1188,6 @@ blue_jellyfish:
blue_jellyfish_silver_star:
show-in-fishfinder: false
material: cod
nick: <#87CEFA>Jellyfish</#87CEFA>
display:
name: <#87CEFA>Jellyfish</#87CEFA>
lore:
@@ -1219,7 +1210,6 @@ blue_jellyfish_silver_star:
blue_jellyfish_golden_star:
show-in-fishfinder: false
material: cod
nick: <#87CEFA>Jellyfish</#87CEFA>
display:
name: <#87CEFA>Jellyfish</#87CEFA>
lore:
@@ -1241,7 +1231,6 @@ blue_jellyfish_golden_star:
bonus: 8
pink_jellyfish:
material: cod
nick: <#FFC0CB>Jellyfish</#FFC0CB>
display:
name: <#FFC0CB>Jellyfish</#FFC0CB>
lore:
@@ -1262,7 +1251,6 @@ pink_jellyfish:
pink_jellyfish_silver_star:
show-in-fishfinder: false
material: cod
nick: <#FFC0CB>Jellyfish</#FFC0CB>
display:
name: <#FFC0CB>Jellyfish</#FFC0CB>
lore:
@@ -1285,7 +1273,6 @@ pink_jellyfish_silver_star:
pink_jellyfish_golden_star:
show-in-fishfinder: false
material: cod
nick: <#FFC0CB>Jellyfish</#FFC0CB>
display:
name: <#FFC0CB>Jellyfish</#FFC0CB>
lore:

View File

@@ -17,7 +17,7 @@ layout:
- 'AAAABAAAA'
# Price formula (For CustomFishing loots)
price-formula: '{base} + {bonus} * {size}'
price-formula: '{BASE} + {BONUS} * {SIZE}'
# Item price (For vanilla items & other plugin items that have CustomModelData)
item-price: