mirror of
https://github.com/Xiao-MoMi/Custom-Fishing.git
synced 2025-12-29 11:59:11 +00:00
Updated expansions & placeholders
This commit is contained in:
@@ -41,6 +41,7 @@ import net.momirealms.customfishing.mechanic.loot.LootManagerImpl;
|
||||
import net.momirealms.customfishing.mechanic.market.MarketManagerImpl;
|
||||
import net.momirealms.customfishing.mechanic.mob.MobManagerImpl;
|
||||
import net.momirealms.customfishing.mechanic.requirement.RequirementManagerImpl;
|
||||
import net.momirealms.customfishing.mechanic.statistic.StatisticsManagerImpl;
|
||||
import net.momirealms.customfishing.scheduler.SchedulerImpl;
|
||||
import net.momirealms.customfishing.setting.Config;
|
||||
import net.momirealms.customfishing.setting.Locale;
|
||||
@@ -92,6 +93,7 @@ public class CustomFishingPluginImpl extends CustomFishingPlugin {
|
||||
this.storageManager = new StorageManagerImpl(this);
|
||||
this.competitionManager = new CompetitionManagerImpl(this);
|
||||
this.integrationManager = new IntegrationManagerImpl(this);
|
||||
this.statisticsManager = new StatisticsManagerImpl(this);
|
||||
this.reload();
|
||||
if (Config.updateChecker)
|
||||
this.versionManager.checkUpdate().thenAccept(result -> {
|
||||
@@ -118,6 +120,8 @@ public class CustomFishingPluginImpl extends CustomFishingPlugin {
|
||||
((StorageManagerImpl) this.storageManager).disable();
|
||||
((CompetitionManagerImpl) this.competitionManager).disable();
|
||||
((PlaceholderManagerImpl) this.placeholderManager).disable();
|
||||
((StatisticsManagerImpl) this.statisticsManager).disable();
|
||||
((ActionManagerImpl) this.actionManager).disable();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -127,6 +131,10 @@ public class CustomFishingPluginImpl extends CustomFishingPlugin {
|
||||
((SchedulerImpl) this.scheduler).reload();
|
||||
((RequirementManagerImpl) this.requirementManager).unload();
|
||||
((RequirementManagerImpl) this.requirementManager).load();
|
||||
((ActionManagerImpl) this.actionManager).unload();
|
||||
((ActionManagerImpl) this.actionManager).load();
|
||||
((GameManagerImpl) this.gameManager).unload();
|
||||
((GameManagerImpl) this.gameManager).load();
|
||||
((ItemManagerImpl) this.itemManager).unload();
|
||||
((ItemManagerImpl) this.itemManager).load();
|
||||
((LootManagerImpl) this.lootManager).unload();
|
||||
@@ -141,13 +149,13 @@ public class CustomFishingPluginImpl extends CustomFishingPlugin {
|
||||
((BagManagerImpl) this.bagManager).load();
|
||||
((BlockManagerImpl) this.blockManager).unload();
|
||||
((BlockManagerImpl) this.blockManager).load();
|
||||
((GameManagerImpl) this.gameManager).unload();
|
||||
((GameManagerImpl) this.gameManager).load();
|
||||
((MobManagerImpl) this.mobManager).unload();
|
||||
((MobManagerImpl) this.mobManager).load();
|
||||
((CompetitionManagerImpl) this.competitionManager).unload();
|
||||
((CompetitionManagerImpl) this.competitionManager).load();
|
||||
((StorageManagerImpl) this.storageManager).reload();
|
||||
((StatisticsManagerImpl) this.statisticsManager).unload();
|
||||
((StatisticsManagerImpl) this.statisticsManager).load();
|
||||
((PlaceholderManagerImpl) this.placeholderManager).unload();
|
||||
((PlaceholderManagerImpl) this.placeholderManager).load();
|
||||
this.commandManager.loadCommands();
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* 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.compatibility.papi;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.mechanic.competition.FishingCompetition;
|
||||
import net.momirealms.customfishing.setting.Locale;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class CompetitionPapi extends PlaceholderExpansion {
|
||||
|
||||
private final CustomFishingPlugin plugin;
|
||||
|
||||
public CompetitionPapi(CustomFishingPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void load() {
|
||||
super.register();
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
super.unregister();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getIdentifier() {
|
||||
return "cfcompetition";
|
||||
}
|
||||
|
||||
@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 player, @NotNull String params) {
|
||||
switch (params) {
|
||||
case "goingon" -> {
|
||||
return String.valueOf(plugin.getCompetitionManager().getOnGoingCompetition() != null);
|
||||
}
|
||||
case "nextseconds" -> {
|
||||
return String.valueOf(plugin.getCompetitionManager().getNextCompetitionSeconds());
|
||||
}
|
||||
case "nextminutes" -> {
|
||||
return String.valueOf(plugin.getCompetitionManager().getNextCompetitionSeconds() / 60);
|
||||
}
|
||||
case "nextsecond" -> {
|
||||
return plugin.getCompetitionManager().getNextCompetitionSeconds() % 60 + Locale.FORMAT_Second;
|
||||
}
|
||||
case "nextminute" -> {
|
||||
int sec = plugin.getCompetitionManager().getNextCompetitionSeconds();
|
||||
int min = (sec % 3600) / 60;
|
||||
return sec < 60 ? "" : min + Locale.FORMAT_Minute;
|
||||
}
|
||||
case "nexthour" -> {
|
||||
int sec = plugin.getCompetitionManager().getNextCompetitionSeconds();
|
||||
int h = (sec % (3600 * 24)) / 3600;
|
||||
return sec < 3600 ? "" : h + Locale.FORMAT_Hour;
|
||||
}
|
||||
case "nextday" -> {
|
||||
int sec = plugin.getCompetitionManager().getNextCompetitionSeconds();
|
||||
int day = sec / (3600 * 24);
|
||||
return day == 0 ? "" : day + Locale.FORMAT_Day;
|
||||
}
|
||||
case "rank" -> {
|
||||
FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition();
|
||||
if (competition == null) return "";
|
||||
else return String.valueOf(competition.getRanking().getPlayerRank(player.getName()));
|
||||
}
|
||||
case "goal" -> {
|
||||
FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition();
|
||||
if (competition == null) return "";
|
||||
else return competition.getGoal().name();
|
||||
}
|
||||
case "seconds" -> {
|
||||
FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition();
|
||||
if (competition == null) return "";
|
||||
return competition.getCachedPlaceholder("{seconds}");
|
||||
}
|
||||
case "second" -> {
|
||||
FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition();
|
||||
if (competition == null) return "";
|
||||
return competition.getCachedPlaceholder("{second}");
|
||||
}
|
||||
case "minute" -> {
|
||||
FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition();
|
||||
if (competition == null) return "";
|
||||
return competition.getCachedPlaceholder("{minute}");
|
||||
}
|
||||
case "hour" -> {
|
||||
FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition();
|
||||
if (competition == null) return "";
|
||||
return competition.getCachedPlaceholder("{hour}");
|
||||
}
|
||||
}
|
||||
|
||||
String[] split = params.split("_", 2);
|
||||
switch (split[0]) {
|
||||
case "score" -> {
|
||||
FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition();
|
||||
if (competition == null) return "";
|
||||
if (split[1].equals("")) {
|
||||
return String.format("%.2f", competition.getRanking().getPlayerScore(player.getName()));
|
||||
} else {
|
||||
return String.format("%.2f", competition.getRanking().getScoreAt(Integer.parseInt(split[1])));
|
||||
}
|
||||
}
|
||||
case "player" -> {
|
||||
FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition();
|
||||
if (competition == null) return "";
|
||||
if (split[1].equals("")) return "Invalid format";
|
||||
return competition.getRanking().getPlayerAt(Integer.parseInt(split[1]));
|
||||
}
|
||||
}
|
||||
return "null";
|
||||
}
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
* 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.compatibility.papi;
|
||||
|
||||
public class MiniPlaceholdersHook {
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* 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.compatibility.papi;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class PlaceholderAPIHook extends PlaceholderExpansion {
|
||||
|
||||
private CustomFishingPlugin plugin;
|
||||
|
||||
public PlaceholderAPIHook(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 "1.4";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean persist() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @Nullable String onRequest(OfflinePlayer player, @NotNull String params) {
|
||||
|
||||
|
||||
|
||||
return super.onRequest(player, params);
|
||||
}
|
||||
}
|
||||
@@ -37,11 +37,12 @@ import java.util.stream.Collectors;
|
||||
public class PlaceholderManagerImpl implements PlaceholderManager {
|
||||
|
||||
private static PlaceholderManagerImpl instance;
|
||||
private CustomFishingPlugin plugin;
|
||||
private final CustomFishingPlugin plugin;
|
||||
private final boolean hasPapi;
|
||||
private final Pattern pattern;
|
||||
private final HashMap<String, String> customPlaceholderMap;
|
||||
private PlaceholderAPIHook placeholderAPIHook;
|
||||
private CompetitionPapi competitionPapi;
|
||||
private StatisticsPapi statisticsPapi;
|
||||
|
||||
public PlaceholderManagerImpl(CustomFishingPlugin plugin) {
|
||||
instance = this;
|
||||
@@ -50,17 +51,20 @@ public class PlaceholderManagerImpl implements PlaceholderManager {
|
||||
this.pattern = Pattern.compile("\\{[^{}]+}");
|
||||
this.customPlaceholderMap = new HashMap<>();
|
||||
if (this.hasPapi) {
|
||||
placeholderAPIHook = new PlaceholderAPIHook(plugin);
|
||||
competitionPapi = new CompetitionPapi(plugin);
|
||||
statisticsPapi = new StatisticsPapi(plugin);
|
||||
}
|
||||
}
|
||||
|
||||
public void load() {
|
||||
if (placeholderAPIHook != null) placeholderAPIHook.load();
|
||||
if (competitionPapi != null) competitionPapi.load();
|
||||
if (statisticsPapi != null) statisticsPapi.load();
|
||||
loadCustomPlaceholders();
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
if (placeholderAPIHook != null) placeholderAPIHook.unload();
|
||||
if (competitionPapi != null) competitionPapi.unload();
|
||||
if (statisticsPapi != null) statisticsPapi.unload();
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* 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.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.statistic.Statistics;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class StatisticsPapi extends PlaceholderExpansion {
|
||||
|
||||
private final CustomFishingPlugin plugin;
|
||||
|
||||
public StatisticsPapi(CustomFishingPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public void load() {
|
||||
super.register();
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
super.unregister();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getIdentifier() {
|
||||
return "fishingstats";
|
||||
}
|
||||
|
||||
@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 player, @NotNull String params) {
|
||||
OnlineUser onlineUser = plugin.getStorageManager().getOnlineUser(player.getUniqueId());
|
||||
if (onlineUser == null) return "";
|
||||
Statistics statistics = onlineUser.getStatistics();
|
||||
if (params.equals("total")) {
|
||||
return String.valueOf(statistics.getTotalCatchAmount());
|
||||
}
|
||||
|
||||
String[] split = params.split("_");
|
||||
switch (split[0]) {
|
||||
case "hascaught" -> {
|
||||
return String.valueOf(statistics.getLootAmount(split[1]) != 0);
|
||||
}
|
||||
case "category" -> {
|
||||
List<String> category = plugin.getStatisticsManager().getCategory(split[2]);
|
||||
if (category == null) return "0";
|
||||
if (split[1].equals("total")) {
|
||||
int total = 0;
|
||||
for (String loot : category) {
|
||||
total += statistics.getLootAmount(loot);
|
||||
}
|
||||
return String.valueOf(total);
|
||||
} else if (split[1].equals("progress")) {
|
||||
int size = category.size();
|
||||
int unlocked = 0;
|
||||
for (String loot : category) {
|
||||
if (statistics.getLootAmount(loot) != 0) unlocked++;
|
||||
}
|
||||
double percent = (double) unlocked / size;
|
||||
String progress = String.format("%.1f", percent);
|
||||
return progress.equals("100.0") ? "100" : progress;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return "null";
|
||||
}
|
||||
}
|
||||
@@ -23,9 +23,11 @@ import net.momirealms.customfishing.adventure.AdventureManagerImpl;
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.manager.ActionManager;
|
||||
import net.momirealms.customfishing.api.mechanic.action.Action;
|
||||
import net.momirealms.customfishing.api.mechanic.action.ActionBuilder;
|
||||
import net.momirealms.customfishing.api.mechanic.action.ActionExpansion;
|
||||
import net.momirealms.customfishing.api.mechanic.action.ActionFactory;
|
||||
import net.momirealms.customfishing.api.util.LogUtils;
|
||||
import net.momirealms.customfishing.compatibility.papi.PlaceholderManagerImpl;
|
||||
import net.momirealms.customfishing.util.ClassUtils;
|
||||
import net.momirealms.customfishing.util.ConfigUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@@ -35,6 +37,9 @@ import org.bukkit.potion.PotionEffect;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -42,7 +47,8 @@ import java.util.concurrent.TimeUnit;
|
||||
public class ActionManagerImpl implements ActionManager {
|
||||
|
||||
private final CustomFishingPlugin plugin;
|
||||
private final HashMap<String, ActionBuilder> actionBuilderMap;
|
||||
private final HashMap<String, ActionFactory> actionBuilderMap;
|
||||
private final String EXPANSION_FOLDER = "expansions/actions";
|
||||
|
||||
public ActionManagerImpl(CustomFishingPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
@@ -65,10 +71,22 @@ public class ActionManagerImpl implements ActionManager {
|
||||
this.registerDelayedAction();
|
||||
}
|
||||
|
||||
public void load() {
|
||||
this.loadExpansions();
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
this.actionBuilderMap.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerAction(String type, ActionBuilder actionBuilder) {
|
||||
public boolean registerAction(String type, ActionFactory actionFactory) {
|
||||
if (this.actionBuilderMap.containsKey(type)) return false;
|
||||
this.actionBuilderMap.put(type, actionBuilder);
|
||||
this.actionBuilderMap.put(type, actionFactory);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -96,7 +114,7 @@ public class ActionManagerImpl implements ActionManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionBuilder getActionBuilder(String type) {
|
||||
public ActionFactory getActionBuilder(String type) {
|
||||
return actionBuilderMap.get(type);
|
||||
}
|
||||
|
||||
@@ -371,4 +389,34 @@ public class ActionManagerImpl implements ActionManager {
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
private void loadExpansions() {
|
||||
File expansionFolder = new File(plugin.getDataFolder(), EXPANSION_FOLDER);
|
||||
if (!expansionFolder.exists())
|
||||
expansionFolder.mkdirs();
|
||||
|
||||
List<Class<? extends ActionExpansion>> classes = new ArrayList<>();
|
||||
File[] expansionJars = expansionFolder.listFiles();
|
||||
if (expansionJars == null) return;
|
||||
for (File expansionJar : expansionJars) {
|
||||
if (expansionJar.getName().endsWith(".jar")) {
|
||||
try {
|
||||
Class<? extends ActionExpansion> expansionClass = ClassUtils.findClass(expansionJar, ActionExpansion.class);
|
||||
classes.add(expansionClass);
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
LogUtils.warn("Failed to load expansion: " + expansionJar.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
for (Class<? extends ActionExpansion> expansionClass : classes) {
|
||||
ActionExpansion expansion = expansionClass.getDeclaredConstructor().newInstance();
|
||||
unregisterAction(expansion.getActionType());
|
||||
registerAction(expansion.getActionType(), expansion.getActionFactory());
|
||||
LogUtils.info("Loaded action expansion: " + expansion.getActionType() + "[" + expansion.getVersion() + "]" + " by " + expansion.getAuthor() );
|
||||
}
|
||||
} catch (InvocationTargetException | InstantiationException | IllegalAccessException | NoSuchMethodException e) {
|
||||
LogUtils.warn("Error occurred when creating expansion instance.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,29 +17,14 @@
|
||||
|
||||
package net.momirealms.customfishing.mechanic.bag;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ScoreComponent;
|
||||
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
|
||||
import net.momirealms.customfishing.CustomFishingPluginImpl;
|
||||
import net.momirealms.customfishing.adventure.AdventureManagerImpl;
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.manager.BagManager;
|
||||
import net.momirealms.customfishing.api.mechanic.bag.FishingBagHolder;
|
||||
import net.momirealms.customfishing.api.util.LogUtils;
|
||||
import net.momirealms.customfishing.compatibility.papi.PlaceholderManagerImpl;
|
||||
import net.momirealms.customfishing.setting.Config;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
@@ -47,12 +32,10 @@ public class BagManagerImpl implements BagManager {
|
||||
|
||||
private final CustomFishingPlugin plugin;
|
||||
private final ConcurrentHashMap<UUID, FishingBagHolder> bagMap;
|
||||
private final WindowPacketListener windowPacketListener;
|
||||
|
||||
public BagManagerImpl(CustomFishingPluginImpl plugin) {
|
||||
this.plugin = plugin;
|
||||
this.bagMap = new ConcurrentHashMap<>();
|
||||
this.windowPacketListener = new WindowPacketListener();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,11 +44,11 @@ public class BagManagerImpl implements BagManager {
|
||||
}
|
||||
|
||||
public void load() {
|
||||
CustomFishingPluginImpl.getProtocolManager().addPacketListener(windowPacketListener);
|
||||
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
CustomFishingPluginImpl.getProtocolManager().removePacketListener(windowPacketListener);
|
||||
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
@@ -81,34 +64,4 @@ public class BagManagerImpl implements BagManager {
|
||||
}
|
||||
return onlinePlayer.getHolder().getInventory();
|
||||
}
|
||||
|
||||
public static class WindowPacketListener extends PacketAdapter {
|
||||
|
||||
public WindowPacketListener() {
|
||||
super(CustomFishingPlugin.getInstance(), PacketType.Play.Server.OPEN_WINDOW);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent event) {
|
||||
final PacketContainer packet = event.getPacket();
|
||||
StructureModifier<WrappedChatComponent> wrappedChatComponentStructureModifier = packet.getChatComponents();
|
||||
WrappedChatComponent component = wrappedChatComponentStructureModifier.getValues().get(0);
|
||||
String windowTitleJson = component.getJson();
|
||||
Component titleComponent = GsonComponentSerializer.gson().deserialize(windowTitleJson);
|
||||
if (titleComponent instanceof ScoreComponent scoreComponent && scoreComponent.name().equals("bag")) {
|
||||
HashMap<String, String> placeholders = new HashMap<>();
|
||||
String uuidStr = scoreComponent.objective();
|
||||
UUID uuid = UUID.fromString(uuidStr);
|
||||
placeholders.put("{uuid}", uuidStr);
|
||||
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(uuid);
|
||||
placeholders.put("{player}", Optional.ofNullable(offlinePlayer.getName()).orElse(uuidStr));
|
||||
wrappedChatComponentStructureModifier.write(0,
|
||||
WrappedChatComponent.fromJson(
|
||||
GsonComponentSerializer.gson().serialize(
|
||||
AdventureManagerImpl.getInstance().getComponentFromMiniMessage(
|
||||
PlaceholderManagerImpl.getInstance().parse(offlinePlayer, Config.bagTitle, placeholders)
|
||||
))));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ public class Competition implements FishingCompetition {
|
||||
if (Config.redisRanking) this.ranking = new RedisRankingImpl();
|
||||
else this.ranking = new LocalRankingImpl();
|
||||
this.publicPlaceholders = new ConcurrentHashMap<>();
|
||||
this.publicPlaceholders.put("{goal}", getCompetitionLocale(goal));
|
||||
this.publicPlaceholders.put("{goal}", CustomFishingPlugin.get().getCompetitionManager().getCompetitionLocale(goal));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -112,10 +112,10 @@ public class Competition implements FishingCompetition {
|
||||
publicPlaceholders.put("{" + finalI + "_score}", Locale.MSG_No_Score);
|
||||
});
|
||||
}
|
||||
publicPlaceholders.put("{hour}", String.valueOf(remainingTime / 3600));
|
||||
publicPlaceholders.put("{minute}", String.valueOf((remainingTime % 3600) / 60));
|
||||
publicPlaceholders.put("{second}", String.valueOf(remainingTime % 60));
|
||||
publicPlaceholders.put("{time}", String.valueOf(remainingTime));
|
||||
publicPlaceholders.put("{hour}", remainingTime < 3600 ? "" : (remainingTime / 3600) + Locale.FORMAT_Hour);
|
||||
publicPlaceholders.put("{minute}", remainingTime < 60 ? "" : (remainingTime % 3600) / 60 + Locale.FORMAT_Minute);
|
||||
publicPlaceholders.put("{second}", remainingTime == 0 ? "" : remainingTime % 60 + Locale.FORMAT_Second);
|
||||
publicPlaceholders.put("{seconds}", remainingTime + Locale.FORMAT_Second);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -195,7 +195,7 @@ public class Competition implements FishingCompetition {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void refreshData(Player player, double score, boolean doubleScore) {
|
||||
public void refreshData(Player player, double score) {
|
||||
// if player join for the first time, trigger join actions
|
||||
if (!hasPlayerJoined(player)) {
|
||||
Action[] actions = config.getJoinActions();
|
||||
@@ -213,8 +213,8 @@ public class Competition implements FishingCompetition {
|
||||
|
||||
// refresh data
|
||||
switch (this.goal) {
|
||||
case CATCH_AMOUNT -> ranking.refreshData(player.getName(), doubleScore ? 2 : 1);
|
||||
case TOTAL_SIZE, TOTAL_SCORE -> ranking.refreshData(player.getName(), doubleScore ? 2 * score : score);
|
||||
case CATCH_AMOUNT -> ranking.refreshData(player.getName(), 1);
|
||||
case TOTAL_SIZE, TOTAL_SCORE -> ranking.refreshData(player.getName(), score);
|
||||
case MAX_SIZE -> {
|
||||
if (score > ranking.getPlayerScore(player.getName())) {
|
||||
ranking.setData(player.getName(), score);
|
||||
@@ -258,25 +258,13 @@ public class Competition implements FishingCompetition {
|
||||
return ranking;
|
||||
}
|
||||
|
||||
public ConcurrentHashMap<String, String> getPublicPlaceholders() {
|
||||
@Override
|
||||
public ConcurrentHashMap<String, String> getCachedPlaceholders() {
|
||||
return publicPlaceholders;
|
||||
}
|
||||
|
||||
private String getCompetitionLocale(CompetitionGoal goal) {
|
||||
switch (goal) {
|
||||
case MAX_SIZE -> {
|
||||
return Locale.MSG_Max_Size;
|
||||
}
|
||||
case CATCH_AMOUNT -> {
|
||||
return Locale.MSG_Catch_Amount;
|
||||
}
|
||||
case TOTAL_SCORE -> {
|
||||
return Locale.MSG_Total_Score;
|
||||
}
|
||||
case TOTAL_SIZE -> {
|
||||
return Locale.MSG_Total_Size;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
@Override
|
||||
public String getCachedPlaceholder(String papi) {
|
||||
return publicPlaceholders.get(papi);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,6 +201,25 @@ public class CompetitionManagerImpl implements CompetitionManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCompetitionLocale(CompetitionGoal goal) {
|
||||
switch (goal) {
|
||||
case MAX_SIZE -> {
|
||||
return net.momirealms.customfishing.setting.Locale.MSG_Max_Size;
|
||||
}
|
||||
case CATCH_AMOUNT -> {
|
||||
return net.momirealms.customfishing.setting.Locale.MSG_Catch_Amount;
|
||||
}
|
||||
case TOTAL_SCORE -> {
|
||||
return net.momirealms.customfishing.setting.Locale.MSG_Total_Score;
|
||||
}
|
||||
case TOTAL_SIZE -> {
|
||||
return net.momirealms.customfishing.setting.Locale.MSG_Total_Size;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startCompetition(String competition, boolean force, boolean allServer) {
|
||||
CompetitionConfig config = commandConfigMap.get(competition);
|
||||
|
||||
@@ -64,7 +64,7 @@ public class ActionBarSender {
|
||||
this.privatePlaceholders.put("{score}", String.format("%.2f", competition.getRanking().getPlayerScore(player.getName())));
|
||||
int rank = competition.getRanking().getPlayerRank(player.getName());
|
||||
this.privatePlaceholders.put("{rank}", rank != -1 ? String.valueOf(rank) : Locale.MSG_No_Rank);
|
||||
this.privatePlaceholders.putAll(competition.getPublicPlaceholders());
|
||||
this.privatePlaceholders.putAll(competition.getCachedPlaceholders());
|
||||
}
|
||||
|
||||
public void show() {
|
||||
|
||||
@@ -77,7 +77,7 @@ public class BossBarSender {
|
||||
this.privatePlaceholders.put("{score}", String.format("%.2f", competition.getRanking().getPlayerScore(player.getName())));
|
||||
int rank = competition.getRanking().getPlayerRank(player.getName());
|
||||
this.privatePlaceholders.put("{rank}", rank != -1 ? String.valueOf(rank) : Locale.MSG_No_Rank);
|
||||
this.privatePlaceholders.putAll(competition.getPublicPlaceholders());
|
||||
this.privatePlaceholders.putAll(competition.getCachedPlaceholders());
|
||||
}
|
||||
|
||||
public void show() {
|
||||
|
||||
@@ -28,10 +28,11 @@ import net.momirealms.customfishing.api.manager.RequirementManager;
|
||||
import net.momirealms.customfishing.api.mechanic.TempFishingState;
|
||||
import net.momirealms.customfishing.api.mechanic.action.Action;
|
||||
import net.momirealms.customfishing.api.mechanic.action.ActionTrigger;
|
||||
import net.momirealms.customfishing.api.mechanic.competition.FishingCompetition;
|
||||
import net.momirealms.customfishing.api.mechanic.condition.FishingPreparation;
|
||||
import net.momirealms.customfishing.api.mechanic.effect.Effect;
|
||||
import net.momirealms.customfishing.api.mechanic.game.Game;
|
||||
import net.momirealms.customfishing.api.mechanic.game.GameConfig;
|
||||
import net.momirealms.customfishing.api.mechanic.game.GameInstance;
|
||||
import net.momirealms.customfishing.api.mechanic.game.GameSettings;
|
||||
import net.momirealms.customfishing.api.mechanic.game.GamingPlayer;
|
||||
import net.momirealms.customfishing.api.mechanic.loot.Loot;
|
||||
@@ -488,20 +489,16 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
var fishingPreparation = state.getPreparation();
|
||||
var player = fishingPreparation.getPlayer();
|
||||
|
||||
fishingPreparation.insertArg("{score}", String.format("%.2f", loot.getScore() * effect.getScoreMultiplier()));
|
||||
fishingPreparation.insertArg("{size-multiplier}", String.format("%.2f", effect.getSizeMultiplier()));
|
||||
fishingPreparation.insertArg("{x}", String.valueOf(hook.getLocation().getBlockX()));
|
||||
fishingPreparation.insertArg("{y}", String.valueOf(hook.getLocation().getBlockY()));
|
||||
fishingPreparation.insertArg("{z}", String.valueOf(hook.getLocation().getBlockZ()));
|
||||
fishingPreparation.insertArg("{loot}", loot.getID());
|
||||
fishingPreparation.insertArg("{nick}", loot.getNick());
|
||||
|
||||
plugin.getScheduler().runTaskSync(() -> {
|
||||
switch (loot.getType()) {
|
||||
case LOOT -> {
|
||||
int amount = (int) effect.getMultipleLootChance();
|
||||
amount += Math.random() < (effect.getMultipleLootChance() - amount) ? 2 : 1;
|
||||
fishingPreparation.insertArg("{amount}", String.valueOf(amount));
|
||||
// build the items for multiple times instead of using setAmount() to make sure that each item is unique
|
||||
if (loot.getID().equals("vanilla")) {
|
||||
ItemStack itemStack = vanillaLootMap.remove(player.getUniqueId());
|
||||
@@ -509,13 +506,13 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
fishingPreparation.insertArg("{loot}", "<lang:item.minecraft." + itemStack.getType().toString().toLowerCase() + ">");
|
||||
for (int i = 0; i < amount; i++) {
|
||||
plugin.getItemManager().dropItem(hook.getLocation(), player.getLocation(), itemStack.clone());
|
||||
doSuccessActions(loot, fishingPreparation, player);
|
||||
doSuccessActions(loot, effect, fishingPreparation, player);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < amount; i++) {
|
||||
plugin.getItemManager().dropItem(player, hook.getLocation(), player.getLocation(), loot, fishingPreparation.getArgs());
|
||||
doSuccessActions(loot, fishingPreparation, player);
|
||||
doSuccessActions(loot, effect, fishingPreparation, player);
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -523,11 +520,41 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
case MOB -> plugin.getMobManager().summonMob(hook.getLocation(), player.getLocation(), loot);
|
||||
case BLOCK -> plugin.getBlockManager().summonBlock(player, hook.getLocation(), player.getLocation(), loot);
|
||||
}
|
||||
doSuccessActions(loot, fishingPreparation, player);
|
||||
doSuccessActions(loot, effect, fishingPreparation, player);
|
||||
}, hook.getLocation());
|
||||
}
|
||||
|
||||
private void doSuccessActions(Loot loot, FishingPreparation fishingPreparation, Player player) {
|
||||
private void doSuccessActions(Loot loot, Effect effect, FishingPreparation fishingPreparation, Player player) {
|
||||
FishingCompetition competition = plugin.getCompetitionManager().getOnGoingCompetition();
|
||||
if (competition != null) {
|
||||
switch (competition.getGoal()) {
|
||||
case CATCH_AMOUNT -> {
|
||||
fishingPreparation.insertArg("{score}", "1");
|
||||
competition.refreshData(player, 1);
|
||||
}
|
||||
case MAX_SIZE, TOTAL_SIZE -> {
|
||||
String size = fishingPreparation.getArg("{size}");
|
||||
if (size != null) {
|
||||
fishingPreparation.insertArg("{score}", size);
|
||||
competition.refreshData(player, Double.parseDouble(size));
|
||||
} else {
|
||||
fishingPreparation.insertArg("{score}", "0");
|
||||
}
|
||||
}
|
||||
case TOTAL_SCORE -> {
|
||||
double score = loot.getScore();
|
||||
if (score != 0) {
|
||||
fishingPreparation.insertArg("{score}", String.format("%.2f", score * effect.getScoreMultiplier()));
|
||||
competition.refreshData(player, score * effect.getScoreMultiplier());
|
||||
} else {
|
||||
fishingPreparation.insertArg("{score}", "0");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
fishingPreparation.insertArg("{score}","-1");
|
||||
}
|
||||
|
||||
Action[] globalActions = LootManagerImpl.globalLootProperties.getActions(ActionTrigger.SUCCESS);
|
||||
if (globalActions != null)
|
||||
for (Action action : globalActions)
|
||||
@@ -580,10 +607,10 @@ public class FishingManagerImpl implements Listener, FishingManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startFishingGame(Player player, GameSettings settings, Game game) {
|
||||
public void startFishingGame(Player player, GameSettings settings, GameInstance gameInstance) {
|
||||
Optional<FishHook> hook = getHook(player.getUniqueId());
|
||||
if (hook.isPresent()) {
|
||||
this.gamingPlayerMap.put(player.getUniqueId(), game.start(player, hook.get(), settings));
|
||||
this.gamingPlayerMap.put(player.getUniqueId(), gameInstance.start(player, hook.get(), settings));
|
||||
} else {
|
||||
LogUtils.warn("It seems that player " + player.getName() + " is not fishing. Fishing game failed to start.");
|
||||
}
|
||||
|
||||
@@ -161,8 +161,8 @@ public class HookCheckTimerTask implements Runnable {
|
||||
Loot nextLoot = manager.getNextLoot(initialEffect, fishingPreparation);
|
||||
if (nextLoot == null)
|
||||
return;
|
||||
fishingPreparation.insertArg("loot", nextLoot.getNick());
|
||||
fishingPreparation.insertArg("id", nextLoot.getID());
|
||||
fishingPreparation.insertArg("{nick}", nextLoot.getNick());
|
||||
fishingPreparation.insertArg("{loot}", nextLoot.getID());
|
||||
CustomFishingPlugin.get().getScheduler().runTaskAsync(() -> manager.setTempFishingState(fishingPreparation.getPlayer(), new TempFishingState(
|
||||
initialEffect,
|
||||
fishingPreparation,
|
||||
|
||||
@@ -40,8 +40,8 @@ import java.util.concurrent.TimeUnit;
|
||||
public class GameManagerImpl implements GameManager {
|
||||
|
||||
private final CustomFishingPlugin plugin;
|
||||
private final HashMap<String, GameCreator> gameCreatorMap;
|
||||
private final HashMap<String, Game> gameMap;
|
||||
private final HashMap<String, GameFactory> gameCreatorMap;
|
||||
private final HashMap<String, GameInstance> gameMap;
|
||||
private final HashMap<String, GameConfig> gameConfigMap;
|
||||
private final String EXPANSION_FOLDER = "expansions/minigames";
|
||||
|
||||
@@ -76,11 +76,11 @@ public class GameManagerImpl implements GameManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerGameType(String type, GameCreator gameCreator) {
|
||||
public boolean registerGameType(String type, GameFactory gameFactory) {
|
||||
if (gameCreatorMap.containsKey(type))
|
||||
return false;
|
||||
else
|
||||
gameCreatorMap.put(type, gameCreator);
|
||||
gameCreatorMap.put(type, gameFactory);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -91,13 +91,13 @@ public class GameManagerImpl implements GameManager {
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public GameCreator getGameCreator(String type) {
|
||||
public GameFactory getGameCreator(String type) {
|
||||
return gameCreatorMap.get(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public Game getGame(String key) {
|
||||
public GameInstance getGame(String key) {
|
||||
return gameMap.get(key);
|
||||
}
|
||||
|
||||
@@ -108,9 +108,9 @@ public class GameManagerImpl implements GameManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Game getRandomGame() {
|
||||
Collection<Game> collection = gameMap.values();
|
||||
return (Game) collection.toArray()[ThreadLocalRandom.current().nextInt(collection.size())];
|
||||
public GameInstance getRandomGame() {
|
||||
Collection<GameInstance> collection = gameMap.values();
|
||||
return (GameInstance) collection.toArray()[ThreadLocalRandom.current().nextInt(collection.size())];
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -164,7 +164,7 @@ public class GameManagerImpl implements GameManager {
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
|
||||
for (Map.Entry<String, Object> entry : config.getValues(false).entrySet()) {
|
||||
if (entry.getValue() instanceof ConfigurationSection section) {
|
||||
GameCreator creator = this.getGameCreator(section.getString("game-type"));
|
||||
GameFactory creator = this.getGameCreator(section.getString("game-type"));
|
||||
if (creator != null) {
|
||||
gameMap.put(entry.getKey(), creator.setArgs(section));
|
||||
}
|
||||
@@ -489,13 +489,12 @@ public class GameManagerImpl implements GameManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
for (Class<? extends GameExpansion> expansionClass : classes) {
|
||||
GameExpansion expansion = expansionClass.getDeclaredConstructor().newInstance();
|
||||
unregisterGameType(expansion.getGameType());
|
||||
registerGameType(expansion.getGameType(), expansion.getGameCreator());
|
||||
LogUtils.info("Loaded expansion: " + expansion.getGameType() + " made by " + expansion.getAuthor() + "[" + expansion.getVersion() + "]");
|
||||
registerGameType(expansion.getGameType(), expansion.getGameFactory());
|
||||
LogUtils.info("Loaded minigame expansion: " + expansion.getGameType() + "[" + expansion.getVersion() + "]" + " by " + expansion.getAuthor() );
|
||||
}
|
||||
} catch (InvocationTargetException | InstantiationException | IllegalAccessException | NoSuchMethodException e) {
|
||||
LogUtils.warn("Error occurred when creating expansion instance.", e);
|
||||
|
||||
@@ -25,10 +25,13 @@ import net.momirealms.customfishing.api.integration.SeasonInterface;
|
||||
import net.momirealms.customfishing.api.manager.RequirementManager;
|
||||
import net.momirealms.customfishing.api.mechanic.action.Action;
|
||||
import net.momirealms.customfishing.api.mechanic.condition.Condition;
|
||||
import net.momirealms.customfishing.api.mechanic.game.GameExpansion;
|
||||
import net.momirealms.customfishing.api.mechanic.requirement.Requirement;
|
||||
import net.momirealms.customfishing.api.mechanic.requirement.RequirementBuilder;
|
||||
import net.momirealms.customfishing.api.mechanic.requirement.RequirementExpansion;
|
||||
import net.momirealms.customfishing.api.mechanic.requirement.RequirementFactory;
|
||||
import net.momirealms.customfishing.api.util.LogUtils;
|
||||
import net.momirealms.customfishing.compatibility.papi.ParseUtils;
|
||||
import net.momirealms.customfishing.util.ClassUtils;
|
||||
import net.momirealms.customfishing.util.ConfigUtils;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@@ -37,14 +40,18 @@ import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.*;
|
||||
|
||||
public class RequirementManagerImpl implements RequirementManager {
|
||||
|
||||
public static Requirement[] mechanicRequirements;
|
||||
private final CustomFishingPluginImpl plugin;
|
||||
private final HashMap<String, RequirementBuilder> requirementBuilderMap;
|
||||
private final HashMap<String, RequirementFactory> requirementBuilderMap;
|
||||
private final LinkedHashMap<String, ConditionalLoots> conditionalLootsMap;
|
||||
private final String EXPANSION_FOLDER = "expansions/requirements";
|
||||
|
||||
public RequirementManagerImpl(CustomFishingPluginImpl plugin) {
|
||||
this.plugin = plugin;
|
||||
@@ -54,6 +61,7 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
}
|
||||
|
||||
public void load() {
|
||||
this.loadExpansions();
|
||||
this.loadRequirementGroupFileConfig();
|
||||
}
|
||||
|
||||
@@ -79,9 +87,9 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean registerRequirement(String type, RequirementBuilder requirementBuilder) {
|
||||
public boolean registerRequirement(String type, RequirementFactory requirementFactory) {
|
||||
if (this.requirementBuilderMap.containsKey(type)) return false;
|
||||
this.requirementBuilderMap.put(type, requirementBuilder);
|
||||
this.requirementBuilderMap.put(type, requirementFactory);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -212,7 +220,7 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequirementBuilder getRequirementBuilder(String type) {
|
||||
public RequirementFactory getRequirementBuilder(String type) {
|
||||
return requirementBuilderMap.get(type);
|
||||
}
|
||||
|
||||
@@ -724,4 +732,34 @@ public class RequirementManagerImpl implements RequirementManager {
|
||||
for (Action action : actions)
|
||||
action.trigger(condition);
|
||||
}
|
||||
|
||||
private void loadExpansions() {
|
||||
File expansionFolder = new File(plugin.getDataFolder(), EXPANSION_FOLDER);
|
||||
if (!expansionFolder.exists())
|
||||
expansionFolder.mkdirs();
|
||||
|
||||
List<Class<? extends RequirementExpansion>> classes = new ArrayList<>();
|
||||
File[] expansionJars = expansionFolder.listFiles();
|
||||
if (expansionJars == null) return;
|
||||
for (File expansionJar : expansionJars) {
|
||||
if (expansionJar.getName().endsWith(".jar")) {
|
||||
try {
|
||||
Class<? extends RequirementExpansion> expansionClass = ClassUtils.findClass(expansionJar, RequirementExpansion.class);
|
||||
classes.add(expansionClass);
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
LogUtils.warn("Failed to load expansion: " + expansionJar.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
for (Class<? extends RequirementExpansion> expansionClass : classes) {
|
||||
RequirementExpansion expansion = expansionClass.getDeclaredConstructor().newInstance();
|
||||
unregisterRequirement(expansion.getRequirementType());
|
||||
registerRequirement(expansion.getRequirementType(), expansion.getRequirementFactory());
|
||||
LogUtils.info("Loaded requirement expansion: " + expansion.getRequirementType() + "[" + expansion.getVersion() + "]" + " by " + expansion.getAuthor());
|
||||
}
|
||||
} catch (InvocationTargetException | InstantiationException | IllegalAccessException | NoSuchMethodException e) {
|
||||
LogUtils.warn("Error occurred when creating expansion instance.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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.mechanic.statistic;
|
||||
|
||||
import net.momirealms.customfishing.api.CustomFishingPlugin;
|
||||
import net.momirealms.customfishing.api.data.user.OnlineUser;
|
||||
import net.momirealms.customfishing.api.manager.StatisticsManager;
|
||||
import net.momirealms.customfishing.api.mechanic.statistic.Statistics;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.*;
|
||||
|
||||
public class StatisticsManagerImpl implements StatisticsManager {
|
||||
|
||||
private final CustomFishingPlugin plugin;
|
||||
private final HashMap<String, List<String>> categoryMap;
|
||||
|
||||
public StatisticsManagerImpl(CustomFishingPlugin plugin) {
|
||||
this.plugin = plugin;
|
||||
this.categoryMap = new HashMap<>();
|
||||
}
|
||||
|
||||
public void load() {
|
||||
this.loadCategoriesFromPluginFolder();
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
this.categoryMap.clear();
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
unload();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Statistics getStatistics(UUID uuid) {
|
||||
OnlineUser onlineUser = plugin.getStorageManager().getOnlineUser(uuid);
|
||||
if (onlineUser == null) return null;
|
||||
return onlineUser.getStatistics();
|
||||
}
|
||||
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
public void loadCategoriesFromPluginFolder() {
|
||||
Deque<File> fileDeque = new ArrayDeque<>();
|
||||
for (String type : List.of("categories")) {
|
||||
File typeFolder = new File(plugin.getDataFolder() + File.separator + "contents" + File.separator + type);
|
||||
if (!typeFolder.exists()) {
|
||||
if (!typeFolder.mkdirs()) return;
|
||||
plugin.saveResource("contents" + File.separator + type + File.separator + "default.yml", false);
|
||||
}
|
||||
fileDeque.push(typeFolder);
|
||||
while (!fileDeque.isEmpty()) {
|
||||
File file = fileDeque.pop();
|
||||
File[] files = file.listFiles();
|
||||
if (files == null) continue;
|
||||
for (File subFile : files) {
|
||||
if (subFile.isDirectory()) {
|
||||
fileDeque.push(subFile);
|
||||
} else if (subFile.isFile() && subFile.getName().endsWith(".yml")) {
|
||||
this.loadSingleFile(subFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadSingleFile(File file) {
|
||||
YamlConfiguration config = YamlConfiguration.loadConfiguration(file);
|
||||
for (String key : config.getKeys(false)) {
|
||||
categoryMap.put(key, config.getStringList(key));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public List<String> getCategory(String key) {
|
||||
return categoryMap.get(key);
|
||||
}
|
||||
}
|
||||
@@ -51,6 +51,10 @@ public class Locale {
|
||||
public static String MSG_Give_Item;
|
||||
public static String MSG_Never_Played;
|
||||
public static String MSG_Unsafe_Modification;
|
||||
public static String FORMAT_Day;
|
||||
public static String FORMAT_Hour;
|
||||
public static String FORMAT_Minute;
|
||||
public static String FORMAT_Second;
|
||||
|
||||
public static void load() {
|
||||
try {
|
||||
|
||||
@@ -26,6 +26,7 @@ public class ClassUtils {
|
||||
URL jar = file.toURI().toURL();
|
||||
URLClassLoader loader = new URLClassLoader(new URL[]{jar}, clazz.getClassLoader());
|
||||
List<String> matches = new ArrayList<>();
|
||||
List<Class<? extends T>> classes = new ArrayList<>();
|
||||
|
||||
try (JarInputStream stream = new JarInputStream(jar.openStream())) {
|
||||
JarEntry entry;
|
||||
@@ -41,14 +42,16 @@ public class ClassUtils {
|
||||
try {
|
||||
Class<?> loaded = loader.loadClass(match);
|
||||
if (clazz.isAssignableFrom(loaded)) {
|
||||
loader.close();
|
||||
return loaded.asSubclass(clazz);
|
||||
classes.add(loaded.asSubclass(clazz));
|
||||
}
|
||||
} catch (NoClassDefFoundError ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
loader.close();
|
||||
return null;
|
||||
if (classes.isEmpty()) {
|
||||
loader.close();
|
||||
return null;
|
||||
}
|
||||
return classes.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,8 +93,7 @@ mechanics:
|
||||
competition:
|
||||
# Use redis for cross server data synchronization
|
||||
redis-ranking: false
|
||||
# Increase this value would increase cpu load
|
||||
# But would allow you to use more placeholders like {4_player} {5_score}
|
||||
# Increase this value would allow you to use more placeholders like {4_player} {5_score} in sacrifice of some performance
|
||||
placeholder-limit: 3
|
||||
|
||||
# Enable vanilla fishing mechanic if there's no loot available
|
||||
|
||||
51
plugin/src/main/resources/contents/categories/default.yml
Normal file
51
plugin/src/main/resources/contents/categories/default.yml
Normal file
@@ -0,0 +1,51 @@
|
||||
# %fishingstats_amount_<id>% get the number of a certain fish caught
|
||||
# %fishingstats_hascaught_<id>% return if a player has caught this fish
|
||||
# %fishingstats_category_total_<id>% get the total number of a certain category's fish caught
|
||||
# %fishingstats_category_progress_<id>% get the player's exploration of this category of fish
|
||||
normal_fish:
|
||||
- tuna_fish
|
||||
- pike_fish
|
||||
- gold_fish
|
||||
- perch_fish
|
||||
- mullet_fish
|
||||
- sardine_fish
|
||||
- carp_fish
|
||||
- cat_fish
|
||||
- octopus
|
||||
- sunfish
|
||||
- red_snapper_fish
|
||||
- salmon_void_fish
|
||||
- woodskip_fish
|
||||
- sturgeon_fish
|
||||
|
||||
sliver_star_fish:
|
||||
- tuna_fish_silver_star
|
||||
- pike_fish_silver_star
|
||||
- gold_fish_silver_star
|
||||
- perch_fish_silver_star
|
||||
- mullet_fish_silver_star
|
||||
- sardine_fish_silver_star
|
||||
- carp_fish_silver_star
|
||||
- cat_fish_silver_star
|
||||
- octopus_silver_star
|
||||
- sunfish_silver_star
|
||||
- red_snapper_fish_silver_star
|
||||
- salmon_void_fish_silver_star
|
||||
- woodskip_fish_silver_star
|
||||
- sturgeon_fish_silver_star
|
||||
|
||||
golden_star_fish:
|
||||
- tuna_fish_golden_star
|
||||
- pike_fish_golden_star
|
||||
- gold_fish_golden_star
|
||||
- perch_fish_golden_star
|
||||
- mullet_fish_golden_star
|
||||
- sardine_fish_golden_star
|
||||
- carp_fish_golden_star
|
||||
- cat_fish_golden_star
|
||||
- octopus_golden_star
|
||||
- sunfish_golden_star
|
||||
- red_snapper_fish_golden_star
|
||||
- salmon_void_fish_golden_star
|
||||
- woodskip_fish_golden_star
|
||||
- sturgeon_fish_golden_star
|
||||
@@ -34,9 +34,9 @@ example:
|
||||
color: WHITE
|
||||
overlay: PROGRESS
|
||||
text:
|
||||
- '<gray>[<#87CEFA>🎣<gray>] <gradient:#F0F8FF:#87CEFA:#F0F8FF>Time Left: <#E6E6FA>{time}s <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>Your Rank: <#E6E6FA>{rank} <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>No.1 Player: <#E6E6FA>{1_player}'
|
||||
- '<gray>[<#87CEFA>🎣<gray>] <gradient:#F0F8FF:#87CEFA:#F0F8FF>Time Left: <#E6E6FA>{minute}m{second}s <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>Your Score: <#E6E6FA>{score} <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>No.1 Score: <#E6E6FA>{1_score}'
|
||||
- '<gray>[<#87CEFA>🎣<gray>] <gradient:#F0F8FF:#87CEFA:#F0F8FF>Time Left: <#E6E6FA>{minute}m{second}s <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>Winning condition: <#E6E6FA>{goal}'
|
||||
- '<gray>[<#87CEFA>🎣<gray>] <gradient:#F0F8FF:#87CEFA:#F0F8FF>Time Left: <#E6E6FA>{seconds} <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>Your Rank: <#E6E6FA>{rank} <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>No.1 Player: <#E6E6FA>{1_player}'
|
||||
- '<gray>[<#87CEFA>🎣<gray>] <gradient:#F0F8FF:#87CEFA:#F0F8FF>Time Left: <#E6E6FA>{minute}{second} <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>Your Score: <#E6E6FA>{score} <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>No.1 Score: <#E6E6FA>{1_score}'
|
||||
- '<gray>[<#87CEFA>🎣<gray>] <gradient:#F0F8FF:#87CEFA:#F0F8FF>Time Left: <#E6E6FA>{minute}{second} <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>Winning condition: <#E6E6FA>{goal}'
|
||||
refresh-rate: 20
|
||||
switch-interval: 200
|
||||
only-show-to-participants: true
|
||||
@@ -44,9 +44,9 @@ example:
|
||||
actionbar:
|
||||
enable: false
|
||||
text:
|
||||
- '<gradient:#F0F8FF:#87CEFA:#F0F8FF>Time Left: <#E6E6FA>{time}s <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>Your Rank: <#E6E6FA>{rank} <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>No.1 Player: <#E6E6FA>{1_player}'
|
||||
- '<gradient:#F0F8FF:#87CEFA:#F0F8FF>Time Left: <#E6E6FA>{minute}m{second}s <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>Your Score: <#E6E6FA>{score} <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>No.1 Score: <#E6E6FA>{1_score}'
|
||||
- '<gradient:#F0F8FF:#87CEFA:#F0F8FF>Time Left: <#E6E6FA>{minute}m{second}s <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>Winning condition: <#E6E6FA>{goal}'
|
||||
- '<gradient:#F0F8FF:#87CEFA:#F0F8FF>Time Left: <#E6E6FA>{seconds} <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>Your Rank: <#E6E6FA>{rank} <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>No.1 Player: <#E6E6FA>{1_player}'
|
||||
- '<gradient:#F0F8FF:#87CEFA:#F0F8FF>Time Left: <#E6E6FA>{minute}{second} <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>Your Score: <#E6E6FA>{score} <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>No.1 Score: <#E6E6FA>{1_score}'
|
||||
- '<gradient:#F0F8FF:#87CEFA:#F0F8FF>Time Left: <#E6E6FA>{minute}{second} <gray>| <gradient:#F0F8FF:#87CEFA:#F0F8FF>Winning condition: <#E6E6FA>{goal}'
|
||||
refresh-rate: 5
|
||||
switch-interval: 200
|
||||
only-show-to-participants: true
|
||||
|
||||
Reference in New Issue
Block a user