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

Added debug command

This commit is contained in:
XiaoMoMi
2024-07-10 19:40:47 +08:00
parent c2b8392f58
commit d5eea4cdb7
16 changed files with 219 additions and 7 deletions

View File

@@ -53,6 +53,8 @@ public class ContextKeys<T> {
public static final ContextKeys<String> SCORE_FORMATTED = of("score_formatted", String.class); public static final ContextKeys<String> SCORE_FORMATTED = of("score_formatted", String.class);
public static final ContextKeys<Double> SCORE = of("score", Double.class); public static final ContextKeys<Double> SCORE = of("score", Double.class);
public static final ContextKeys<Double> CUSTOM_SCORE = of("custom_score", Double.class); public static final ContextKeys<Double> CUSTOM_SCORE = of("custom_score", Double.class);
public static final ContextKeys<Double> MIN_SIZE = of("min_size", Double.class);
public static final ContextKeys<Double> MAX_SIZE = of("max_size", Double.class);
public static final ContextKeys<String> RANK = of("rank", String.class); public static final ContextKeys<String> RANK = of("rank", String.class);
public static final ContextKeys<Location> OTHER_LOCATION = of("other_location", Location.class); public static final ContextKeys<Location> OTHER_LOCATION = of("other_location", Location.class);
public static final ContextKeys<Integer> OTHER_X = of("other_x", Integer.class); public static final ContextKeys<Integer> OTHER_X = of("other_x", Integer.class);

View File

@@ -40,6 +40,8 @@ import org.incendo.cloud.exception.handling.ExceptionContext;
import org.incendo.cloud.minecraft.extras.MinecraftExceptionHandler; import org.incendo.cloud.minecraft.extras.MinecraftExceptionHandler;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
@@ -138,6 +140,11 @@ public abstract class AbstractCommandManager<C> implements CustomFishingCommandM
@Override @Override
public void registerDefaultFeatures() { public void registerDefaultFeatures() {
YamlDocument document = plugin.getConfigManager().loadConfig(commandsFile); YamlDocument document = plugin.getConfigManager().loadConfig(commandsFile);
try {
document.save(new File(plugin.getDataDirectory().toFile(), "commands.yml"));
} catch (IOException e) {
throw new RuntimeException(e);
}
this.getFeatures().values().forEach(feature -> { this.getFeatures().values().forEach(feature -> {
CommandConfig<C> config = getCommandConfig(document, feature.getFeatureID()); CommandConfig<C> config = getCommandConfig(document, feature.getFeatureID());
if (config.isEnable()) { if (config.isEnable()) {

View File

@@ -75,6 +75,9 @@ public interface MessageConstants {
TranslatableComponent.Builder COMMAND_STATISTICS_RESET_SUCCESS = Component.translatable().key("command.statistics.reset.success"); TranslatableComponent.Builder COMMAND_STATISTICS_RESET_SUCCESS = Component.translatable().key("command.statistics.reset.success");
TranslatableComponent.Builder COMMAND_STATISTICS_QUERY_AMOUNT = Component.translatable().key("command.statistics.query.amount"); TranslatableComponent.Builder COMMAND_STATISTICS_QUERY_AMOUNT = Component.translatable().key("command.statistics.query.amount");
TranslatableComponent.Builder COMMAND_STATISTICS_QUERY_SIZE = Component.translatable().key("command.statistics.query.size"); TranslatableComponent.Builder COMMAND_STATISTICS_QUERY_SIZE = Component.translatable().key("command.statistics.query.size");
TranslatableComponent.Builder COMMAND_DEBUG_LOOT_FAILURE_ROD = Component.translatable().key("command.debug.loot.failure.rod");
TranslatableComponent.Builder COMMAND_DEBUG_LOOT_SUCCESS = Component.translatable().key("command.debug.loot.success");
TranslatableComponent.Builder COMMAND_DEBUG_LOOT_FAILURE_NO_LOOT = Component.translatable().key("command.debug.loot.failure.no_loot");
// TranslatableComponent.Builder GUI_SELECT_FILE = Component.translatable().key("gui.select_file"); // TranslatableComponent.Builder GUI_SELECT_FILE = Component.translatable().key("gui.select_file");
// TranslatableComponent.Builder GUI_SELECT_ITEM = Component.translatable().key("gui.select_item"); // TranslatableComponent.Builder GUI_SELECT_ITEM = Component.translatable().key("gui.select_item");

View File

@@ -26,6 +26,7 @@ import net.momirealms.customfishing.common.plugin.CustomFishingPlugin;
import net.momirealms.customfishing.common.util.Pair; import net.momirealms.customfishing.common.util.Pair;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@@ -37,7 +38,7 @@ import java.util.stream.Stream;
public class TranslationManager { public class TranslationManager {
public static final Locale DEFAULT_LOCALE = Locale.ENGLISH; public static final Locale DEFAULT_LOCALE = Locale.ENGLISH;
private static final List<String> locales = List.of("en"); private static final List<String> locales = List.of("en", "zh_cn");
private static TranslationManager instance; private static TranslationManager instance;
private final CustomFishingPlugin plugin; private final CustomFishingPlugin plugin;
@@ -57,7 +58,6 @@ public class TranslationManager {
MiniMessageTranslator.translator().removeSource(this.registry); MiniMessageTranslator.translator().removeSource(this.registry);
this.installed.clear(); this.installed.clear();
} }
for (String lang : locales) { for (String lang : locales) {
this.plugin.getConfigManager().saveResource("translations/" + lang + ".yml"); this.plugin.getConfigManager().saveResource("translations/" + lang + ".yml");
} }
@@ -158,6 +158,11 @@ public class TranslationManager {
Map<String, String> bundle = new HashMap<>(); Map<String, String> bundle = new HashMap<>();
YamlDocument document = plugin.getConfigManager().loadConfig("translations" + "\\" + translationFile.getFileName(), '@'); YamlDocument document = plugin.getConfigManager().loadConfig("translations" + "\\" + translationFile.getFileName(), '@');
try {
document.save(new File(plugin.getDataDirectory().toFile(), "translations" + "\\" + translationFile.getFileName()));
} catch (IOException e) {
throw new IllegalStateException("Could not update translation file: " + translationFile.getFileName(), e);
}
Map<String, Object> map = document.getStringRouteMappedValues(false); Map<String, Object> map = document.getStringRouteMappedValues(false);
map.remove("config-version"); map.remove("config-version");
for (Map.Entry<String, Object> entry : map.entrySet()) { for (Map.Entry<String, Object> entry : map.entrySet()) {

View File

@@ -21,6 +21,7 @@ import me.clip.placeholderapi.expansion.PlaceholderExpansion;
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin; import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import net.momirealms.customfishing.api.mechanic.context.Context; import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.storage.user.UserData; import net.momirealms.customfishing.api.storage.user.UserData;
import net.momirealms.customfishing.common.util.RandomUtils;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -70,6 +71,9 @@ public class CustomFishingPapi extends PlaceholderExpansion {
if (player == null) if (player == null)
return ""; return "";
switch (split[0]) { switch (split[0]) {
case "random" -> {
return String.valueOf(RandomUtils.generateRandomDouble(0,1));
}
case "market" -> { case "market" -> {
if (split.length < 2) if (split.length < 2)
return null; return null;

View File

@@ -54,7 +54,8 @@ public class BukkitCommandManager extends AbstractCommandManager<CommandSender>
new AddStatisticsCommand(this), new AddStatisticsCommand(this),
new SetStatisticsCommand(this), new SetStatisticsCommand(this),
new ResetStatisticsCommand(this), new ResetStatisticsCommand(this),
new QueryStatisticsCommand(this) new QueryStatisticsCommand(this),
new DebugLootCommand(this)
); );
private final Index<String, CommandFeature<CommandSender>> INDEX = Index.create(CommandFeature::getFeatureID, FEATURES); private final Index<String, CommandFeature<CommandSender>> INDEX = Index.create(CommandFeature::getFeatureID, FEATURES);

View File

@@ -0,0 +1,165 @@
/*
* Copyright (C) <2022> <XiaoMoMi>
*
* 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 <https://www.gnu.org/licenses/>.
*/
package net.momirealms.customfishing.bukkit.command.feature;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import net.momirealms.customfishing.api.BukkitCustomFishingPlugin;
import net.momirealms.customfishing.api.mechanic.context.Context;
import net.momirealms.customfishing.api.mechanic.context.ContextKeys;
import net.momirealms.customfishing.api.mechanic.effect.Effect;
import net.momirealms.customfishing.api.mechanic.effect.EffectModifier;
import net.momirealms.customfishing.api.mechanic.effect.EffectProperties;
import net.momirealms.customfishing.api.mechanic.fishing.FishingGears;
import net.momirealms.customfishing.bukkit.command.BukkitCommandFeature;
import net.momirealms.customfishing.common.command.CustomFishingCommandManager;
import net.momirealms.customfishing.common.locale.MessageConstants;
import net.momirealms.customfishing.common.util.TriConsumer;
import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.incendo.cloud.Command;
import org.incendo.cloud.CommandManager;
import org.incendo.cloud.context.CommandContext;
import org.incendo.cloud.context.CommandInput;
import org.incendo.cloud.parser.standard.StringParser;
import org.incendo.cloud.parser.standard.UUIDParser;
import org.incendo.cloud.suggestion.Suggestion;
import org.incendo.cloud.suggestion.SuggestionProvider;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Stream;
public class DebugLootCommand extends BukkitCommandFeature<CommandSender> {
public DebugLootCommand(CustomFishingCommandManager<CommandSender> commandManager) {
super(commandManager);
}
@Override
public Command.Builder<? extends CommandSender> assembleCommand(CommandManager<CommandSender> manager, Command.Builder<CommandSender> builder) {
return builder
.senderType(Player.class)
.required("surrounding", StringParser.stringComponent().suggestionProvider(new SuggestionProvider<>() {
@Override
public @NonNull CompletableFuture<? extends @NonNull Iterable<? extends @NonNull Suggestion>> suggestionsFuture(@NonNull CommandContext<Object> context, @NonNull CommandInput input) {
return CompletableFuture.completedFuture(Stream.of("lava", "water", "void").map(Suggestion::suggestion).toList());
}
}))
.handler(context -> {
String surrounding = context.get("surrounding");
if (context.sender().getInventory().getItemInMainHand().getType() != Material.FISHING_ROD) {
handleFeedback(context, MessageConstants.COMMAND_DEBUG_LOOT_FAILURE_ROD);
return;
}
final Player player = context.sender();
Context<Player> playerContext = Context.player(player);
FishingGears gears = new FishingGears(playerContext);
Effect effect = Effect.newInstance();
// The effects impact mechanism at this stage
for (EffectModifier modifier : gears.effectModifiers()) {
for (TriConsumer<Effect, Context<Player>, Integer> consumer : modifier.modifiers()) {
consumer.accept(effect, playerContext, 0);
}
}
playerContext.arg(ContextKeys.SURROUNDING, surrounding);
Effect tempEffect = effect.copy();
for (EffectModifier modifier : gears.effectModifiers()) {
for (TriConsumer<Effect, Context<Player>, Integer> consumer : modifier.modifiers()) {
consumer.accept(tempEffect, playerContext, 1);
}
}
playerContext.arg(ContextKeys.OTHER_LOCATION, player.getLocation());
playerContext.arg(ContextKeys.OTHER_X, player.getLocation().getBlockX());
playerContext.arg(ContextKeys.OTHER_Y, player.getLocation().getBlockY());
playerContext.arg(ContextKeys.OTHER_Z, player.getLocation().getBlockZ());
Map<String, Double> weightMap = BukkitCustomFishingPlugin.getInstance().getLootManager().getWeightedLoots(tempEffect, playerContext);
if (weightMap.isEmpty()) {
handleFeedback(context, MessageConstants.COMMAND_DEBUG_LOOT_FAILURE_NO_LOOT);
return;
}
List<LootWithWeight> loots = new ArrayList<>();
double sum = 0;
for (Map.Entry<String, Double> entry : weightMap.entrySet()) {
double weight = entry.getValue();
String loot = entry.getKey();
if (weight <= 0) continue;
loots.add(new LootWithWeight(loot, weight));
sum += weight;
}
LootWithWeight[] lootArray = loots.toArray(new LootWithWeight[0]);
quickSort(lootArray, 0,lootArray.length - 1);
Component component = Component.text().build();
for (LootWithWeight loot : lootArray) {
component = component.append(Component.newline())
.append(Component.text(loot.key + ": ").color(NamedTextColor.WHITE))
.append(Component.text(String.format("%.4f", loot.weight * 100 / sum) + "% ").color(NamedTextColor.GOLD))
.append(Component.text("(" + loot.weight + ")").color(NamedTextColor.GRAY));
}
handleFeedback(context, MessageConstants.COMMAND_DEBUG_LOOT_SUCCESS, component);
});
}
@Override
public String getFeatureID() {
return "debug_loot";
}
public record LootWithWeight(String key, double weight) {
}
private static void quickSort(LootWithWeight[] loot, int low, int high) {
if (low < high) {
int pi = partition(loot, low, high);
quickSort(loot, low, pi - 1);
quickSort(loot, pi + 1, high);
}
}
private static int partition(LootWithWeight[] loot, int low, int high) {
double pivot = loot[high].weight();
int i = low - 1;
for (int j = low; j <= high - 1; j++) {
if (loot[j].weight() > pivot) {
i++;
swap(loot, i, j);
}
}
swap(loot, i + 1, high);
return i + 1;
}
private static void swap(LootWithWeight[] loot, int i, int j) {
LootWithWeight temp = loot[i];
loot[i] = loot[j];
loot[j] = temp;
}
}

View File

@@ -439,6 +439,8 @@ public class BukkitConfigManager extends ConfigManager {
float size = (float) RandomUtils.generateRandomDouble(minSize, maxSize); float size = (float) RandomUtils.generateRandomDouble(minSize, maxSize);
item.setTag(size, "CustomFishing", "size"); item.setTag(size, "CustomFishing", "size");
context.arg(ContextKeys.SIZE, size); context.arg(ContextKeys.SIZE, size);
context.arg(ContextKeys.MIN_SIZE, minSize);
context.arg(ContextKeys.MAX_SIZE, maxSize);
context.arg(ContextKeys.SIZE_FORMATTED, String.format("%.2f", size)); context.arg(ContextKeys.SIZE_FORMATTED, String.format("%.2f", size));
}; };
}, 1_000, "size"); }, 1_000, "size");

View File

@@ -155,6 +155,7 @@ public class Migration {
try (BufferedWriter writer = new BufferedWriter( try (BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(new FileOutputStream(outPut), StandardCharsets.UTF_8))) { new OutputStreamWriter(new FileOutputStream(outPut), StandardCharsets.UTF_8))) {
writer.write(sb.toString() writer.write(sb.toString()
.replace("{sold-item-amount}", "{sold_item_amount}")
.replace("{size}", "{size_formatted}") .replace("{size}", "{size_formatted}")
.replace("{record}", "{record_formatted}") .replace("{record}", "{record_formatted}")
.replace("{loot}", "{id}") .replace("{loot}", "{id}")

View File

@@ -46,6 +46,8 @@ import org.bukkit.event.player.PlayerQuitEvent;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Collection; import java.util.Collection;
import java.util.HashSet; import java.util.HashSet;
@@ -77,6 +79,11 @@ public class BukkitStorageManager implements StorageManager, Listener {
@Override @Override
public void reload() { public void reload() {
YamlDocument config = plugin.getConfigManager().loadConfig("database.yml"); YamlDocument config = plugin.getConfigManager().loadConfig("database.yml");
try {
config.save(new File(plugin.getDataFolder(), "database.yml"));
} catch (IOException e) {
throw new RuntimeException(e);
}
this.serverID = config.getString("unique-server-id", "default"); this.serverID = config.getString("unique-server-id", "default");
// Check if storage type has changed and reinitialize if necessary // Check if storage type has changed and reinitialize if necessary
@@ -291,7 +298,7 @@ public class BukkitStorageManager implements StorageManager, Listener {
if (player == null || !player.isOnline()) if (player == null || !player.isOnline())
return; return;
if (times > 3) { if (times > 3) {
plugin.getPluginLogger().warn("Tried 3 times when getting data for " + uuid + ". Giving up."); plugin.getPluginLogger().warn("Tried 3 times getting data for " + uuid + ". Giving up.");
return; return;
} }
this.dataSource.getPlayerData(uuid, ConfigManager.lockData()).thenAccept(optionalData -> { this.dataSource.getPlayerData(uuid, ConfigManager.lockData()).thenAccept(optionalData -> {

View File

@@ -183,4 +183,13 @@ statistics_add:
permission: customfishing.command.statistics permission: customfishing.command.statistics
usage: usage:
- /customfishing statistics add - /customfishing statistics add
- /cfishing statistics add - /cfishing statistics add
# A command to debug the loot table
# Usage: [COMMAND] [surrounding]
debug_loot:
enable: true
permission: customfishing.command.debug
usage:
- /customfishing debug loot
- /cfishing debug loot

View File

@@ -417,6 +417,7 @@ other-settings:
'{date}': '%server_time_yyyy-MM-dd-HH:mm:ss%' '{date}': '%server_time_yyyy-MM-dd-HH:mm:ss%'
# Requires player expansion # Requires player expansion
'{yaw}': '%player_yaw%' '{yaw}': '%player_yaw%'
'{random}': '%customfishing_random%'
# CustomFishing supports using items/blocks from other plugins # CustomFishing supports using items/blocks from other plugins
# If items share the same id, they would inherit the effects # If items share the same id, they would inherit the effects
# Check the wiki for examples # Check the wiki for examples

View File

@@ -117,7 +117,7 @@ rubbish:
display: display:
name: <#00BFFF>Radioactive Fish</#00BFFF> name: <#00BFFF>Radioactive Fish</#00BFFF>
lore: lore:
- <gray>Protect the environment... - <gray>Time to protect the environment
custom-model-data: 50000 custom-model-data: 50000
show-in-fishfinder: false show-in-fishfinder: false
disable-stat: true disable-stat: true

View File

@@ -76,6 +76,9 @@ command.statistics.modify.success: "<white>Successfully modified the fishing sta
command.statistics.reset.success: "<white>Successfully reset the fishing statistics for <arg:0></white>" command.statistics.reset.success: "<white>Successfully reset the fishing statistics for <arg:0></white>"
command.statistics.query.size: "<white>Max sizes: <arg:0></white>" command.statistics.query.size: "<white>Max sizes: <arg:0></white>"
command.statistics.query.amount: "<white>Amount of fish caught: <arg:0></white>" command.statistics.query.amount: "<white>Amount of fish caught: <arg:0></white>"
command.debug.loot.failure.rod: "<red>Please hold a fishing rod before using this command</red>"
command.debug.loot.failure.no_loot: "<red>No loot available</red>"
command.debug.loot.success: "<yellow><b>Available loots:</b></yellow> <arg:0>"
competition.no_score: "No Score" competition.no_score: "No Score"
competition.no_player: "No Player" competition.no_player: "No Player"
competition.no_rank: "No Rank" competition.no_rank: "No Rank"

View File

@@ -76,6 +76,8 @@ command.statistics.modify.success: "<white>成功修改 <arg:0> 的钓鱼统计
command.statistics.reset.success: "<white>成功重置 <arg:0> 的钓鱼统计数据</white>" command.statistics.reset.success: "<white>成功重置 <arg:0> 的钓鱼统计数据</white>"
command.statistics.query.size: "<white>最长的鱼的长度: <arg:0></white>" command.statistics.query.size: "<white>最长的鱼的长度: <arg:0></white>"
command.statistics.query.amount: "<white>钓到鱼的数量: <arg:0></white>" command.statistics.query.amount: "<white>钓到鱼的数量: <arg:0></white>"
command.debug.loot.failure.rod: "<red>请手持鱼竿后再执行此命令</red>"
command.debug.loot.success: "<yellow><b>战利品概率表:</b></yellow> <arg:0>"
competition.no_score: "暂无得分" competition.no_score: "暂无得分"
competition.no_player: "暂无玩家" competition.no_player: "暂无玩家"
competition.no_rank: "暂无排名" competition.no_rank: "暂无排名"

View File

@@ -1,7 +1,7 @@
# Project settings # Project settings
# Rule: [major update].[feature update].[bug fix] # Rule: [major update].[feature update].[bug fix]
project_version=2.2.0 project_version=2.2.0
config_version=33 config_version=34
project_group=net.momirealms project_group=net.momirealms
# Dependency settings # Dependency settings