diff --git a/src/main/java/com/alttd/fishingevent/FishingEvent.java b/src/main/java/com/alttd/fishingevent/FishingEvent.java
index 040eafc..6e413d2 100644
--- a/src/main/java/com/alttd/fishingevent/FishingEvent.java
+++ b/src/main/java/com/alttd/fishingevent/FishingEvent.java
@@ -37,7 +37,6 @@ public final class FishingEvent extends JavaPlugin {
}
reloadFishConfigs();
registerEvents(getServer().getPluginManager());
- //add a way to stop and start the fishing event and a way to stop all fishing (so 3 modes normal, active, disabled)
if (new LoadTask(PointsManagement.getInstance(), this, logger).loadOldPointsData())
logger.info("Loaded old points data");
saveTask = new SaveTask(PointsManagement.getInstance(), this, logger);
diff --git a/src/main/java/com/alttd/fishingevent/commands/FishCommand.java b/src/main/java/com/alttd/fishingevent/commands/FishCommand.java
index d1d3452..060fcef 100644
--- a/src/main/java/com/alttd/fishingevent/commands/FishCommand.java
+++ b/src/main/java/com/alttd/fishingevent/commands/FishCommand.java
@@ -1,8 +1,10 @@
package com.alttd.fishingevent.commands;
import com.alttd.fishingevent.FishingEvent;
+import com.alttd.fishingevent.commands.fish_subcommands.End;
import com.alttd.fishingevent.commands.fish_subcommands.Leaderboard;
import com.alttd.fishingevent.commands.fish_subcommands.Points;
+import com.alttd.fishingevent.commands.fish_subcommands.Start;
import com.alttd.fishingevent.config.Messages;
import com.alttd.fishingevent.util.Logger;
import org.bukkit.command.*;
@@ -30,7 +32,9 @@ public class FishCommand implements CommandExecutor, TabExecutor {
subCommands = Arrays.asList(
new Points(),
- new Leaderboard()
+ new Leaderboard(),
+ new Start(),
+ new End()
);
}
diff --git a/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/End.java b/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/End.java
new file mode 100644
index 0000000..044a933
--- /dev/null
+++ b/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/End.java
@@ -0,0 +1,31 @@
+package com.alttd.fishingevent.commands.fish_subcommands;
+
+import com.alttd.fishingevent.commands.SubCommand;
+import com.alttd.fishingevent.timer.EventManager;
+import org.bukkit.command.CommandSender;
+
+import java.util.List;
+
+public class End extends SubCommand {
+ @Override
+ public boolean onCommand(CommandSender commandSender, String[] args) {
+ EventManager.getInstance().stop();
+ commandSender.sendMiniMessage("Stopped event", null);
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return "end";
+ }
+
+ @Override
+ public List getTabComplete(CommandSender commandSender, String[] args) {
+ return List.of();
+ }
+
+ @Override
+ public String getHelpMessage() {
+ return "Invalid command use";
+ }
+}
diff --git a/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Leaderboard.java b/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Leaderboard.java
index 44e6f6e..f07bec2 100644
--- a/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Leaderboard.java
+++ b/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Leaderboard.java
@@ -25,7 +25,7 @@ public class Leaderboard extends SubCommand {
component = component.append(Component.newline()).append(MiniMessage.miniMessage().deserialize("'s biggest fish was the at cm",
Placeholder.component("player", playerScore.player().displayName()),
Placeholder.parsed("length", String.format("%.2f", playerScore.biggestFish())),
- Placeholder.parsed("rarity", playerScore.fish().getRarity().displayName()),
+ Placeholder.unparsed("rarity", playerScore.fish().getRarity().displayName()),
Placeholder.component("fish", playerScore.fish().fishName())));
if (playerScore.player().getUniqueId().equals(uuid))
displayPlayerScore = false;
@@ -36,7 +36,7 @@ public class Leaderboard extends SubCommand {
component = component.append(Component.newline()).append(MiniMessage.miniMessage().deserialize("Your biggest fish was the at cm",
Placeholder.component("player", playerScore.player().displayName()),
Placeholder.parsed("length", String.format("%.2f", playerScore.biggestFish())),
- Placeholder.parsed("rarity", playerScore.fish().getRarity().displayName()),
+ Placeholder.unparsed("rarity", playerScore.fish().getRarity().displayName()),
Placeholder.component("fish", playerScore.fish().fishName())));
}
@@ -56,6 +56,6 @@ public class Leaderboard extends SubCommand {
@Override
public String getHelpMessage() {
- return ""; //TODO implement
+ return "Invalid command use";
}
}
diff --git a/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Points.java b/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Points.java
index ee1be2d..d335743 100644
--- a/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Points.java
+++ b/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Points.java
@@ -70,6 +70,6 @@ public class Points extends SubCommand {
@Override
public String getHelpMessage() {
- return ""; //TODO implement
+ return "Invalid command use";
}
}
diff --git a/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Start.java b/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Start.java
new file mode 100644
index 0000000..bab80c3
--- /dev/null
+++ b/src/main/java/com/alttd/fishingevent/commands/fish_subcommands/Start.java
@@ -0,0 +1,48 @@
+package com.alttd.fishingevent.commands.fish_subcommands;
+
+import com.alttd.fishingevent.commands.SubCommand;
+import com.alttd.fishingevent.timer.EventManager;
+import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
+import org.bukkit.command.CommandSender;
+
+import java.time.Duration;
+import java.util.List;
+
+public class Start extends SubCommand {
+ @Override
+ public boolean onCommand(CommandSender commandSender, String[] args) {
+ if (args.length != 2) {
+ commandSender.sendMiniMessage("Include the time (as an int in minutes)", null);
+ return true;
+ }
+ int minutes;
+ try {
+ minutes = Integer.parseInt(args[1]);
+ } catch (NumberFormatException e) {
+ commandSender.sendMiniMessage("Include the time (as an int in minutes)", null);
+ return true;
+ }
+ Duration duration = Duration.ofMinutes(minutes);
+ if (EventManager.getInstance().startEvent(commandSender.getServer(), duration)) {
+ commandSender.sendMiniMessage("Started event with duration of minutes", Placeholder.parsed("minutes", String.valueOf(minutes)));
+ } else {
+ commandSender.sendMiniMessage("Unable to start event", null);
+ }
+ return true;
+ }
+
+ @Override
+ public String getName() {
+ return "start";
+ }
+
+ @Override
+ public List getTabComplete(CommandSender commandSender, String[] args) {
+ return List.of();
+ }
+
+ @Override
+ public String getHelpMessage() {
+ return "Invalid command use";
+ }
+}
diff --git a/src/main/java/com/alttd/fishingevent/config/Messages.java b/src/main/java/com/alttd/fishingevent/config/Messages.java
index d66e2ad..3aea166 100644
--- a/src/main/java/com/alttd/fishingevent/config/Messages.java
+++ b/src/main/java/com/alttd/fishingevent/config/Messages.java
@@ -130,4 +130,21 @@ public class Messages extends AbstractConfig {
UNABLE_TO_UPDATE_ENCHANTMENT = config.getString(prefix, "unable-to-update-enchantment", UNABLE_TO_UPDATE_ENCHANTMENT);
}
}
+
+ public static class TIMER {
+ private static final String prefix = "timer.";
+
+ public static String TIME_REMAINING = "There are ";
+ public static String EVENT_START = "The fishing event has started! It will end in minutes, you will be able to sell your fishes and buy prizes during and after the event.";
+ public static String EVENT_END = "The Fishing Event has ended! Thank you all for coming and make sure to sell your remaining fish and spend your remaining points on prizes before leaving!\nWinners:";
+ public static String WINNER_FORMAT = " with a cm";
+
+ @SuppressWarnings("unused")
+ private static void load() {
+ TIME_REMAINING = config.getString(prefix, "hours-remaining", TIME_REMAINING);
+ EVENT_START = config.getString(prefix, "event-start", EVENT_START);
+ EVENT_END = config.getString(prefix, "event-end", EVENT_END);
+ WINNER_FORMAT = config.getString(prefix, "winner-format", WINNER_FORMAT);
+ }
+ }
}
diff --git a/src/main/java/com/alttd/fishingevent/listeners/CatchFish.java b/src/main/java/com/alttd/fishingevent/listeners/CatchFish.java
index 0887a35..1febe80 100644
--- a/src/main/java/com/alttd/fishingevent/listeners/CatchFish.java
+++ b/src/main/java/com/alttd/fishingevent/listeners/CatchFish.java
@@ -6,6 +6,7 @@ import com.alttd.fishingevent.fish_generator.FishGenerator;
import com.alttd.fishingevent.objects.FishType;
import com.alttd.fishingevent.points.PointsManagement;
import com.alttd.fishingevent.scoreboard.ScoreboardManager;
+import com.alttd.fishingevent.timer.EventManager;
import com.alttd.fishingevent.util.Logger;
import org.bukkit.Location;
import org.bukkit.Material;
@@ -25,6 +26,7 @@ public class CatchFish implements Listener {
private final Logger logger;
private final FishGenerator waterFishGenerator;
private final PointsManagement pointsManagement;
+ private final EventManager eventManager = EventManager.getInstance();
public CatchFish(Logger logger, FishGenerator waterFishGenerator, PointsManagement pointsManagement) {
this.logger = logger;
@@ -35,6 +37,10 @@ public class CatchFish implements Listener {
@EventHandler
public void onPlayerFish(PlayerFishEvent event) {
+ if (!eventManager.isRunning()) {
+ event.setCancelled(true);
+ return;
+ }
if (event.getState().equals(PlayerFishEvent.State.FISHING)) {
//if fishing rod in lava continue else return
// logger.debug("% might have caught a lava fish", event.getPlayer().getName());
diff --git a/src/main/java/com/alttd/fishingevent/timer/EventAutoMessages.java b/src/main/java/com/alttd/fishingevent/timer/EventAutoMessages.java
new file mode 100644
index 0000000..2fa5019
--- /dev/null
+++ b/src/main/java/com/alttd/fishingevent/timer/EventAutoMessages.java
@@ -0,0 +1,68 @@
+package com.alttd.fishingevent.timer;
+
+import com.alttd.fishingevent.config.Messages;
+import net.kyori.adventure.text.minimessage.MiniMessage;
+import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
+import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
+import org.bukkit.Server;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.util.List;
+
+public class EventAutoMessages implements Runnable {
+
+ private final Instant eventStart;
+ private final Duration eventDuration;
+ private final Server server;
+ private Instant lastTimeNotified = Instant.now();
+ private final List minutesList = List.of(30, 15, 10, 5, 2, 1);
+ private final List secondsList = List.of(30, 20, 10);
+
+ public EventAutoMessages(Instant eventStart, Duration eventDuration, Server server) {
+ this.eventStart = eventStart;
+ this.eventDuration = eventDuration;
+ this.server = server;
+ }
+
+ @Override
+ public void run() {
+ Instant currentTime = Instant.now();
+ Duration timeElapsed = Duration.between(eventStart, currentTime);
+ Duration timeRemaining = eventDuration.minus(timeElapsed);
+ Duration timeSinceLastNotification = Duration.between(lastTimeNotified, currentTime);
+
+ if (timeRemaining.isZero() || timeRemaining.isNegative()) {
+ EventManager.getInstance().end(server);
+ return;
+ }
+
+ // Check if secondsRemaining matches one of the specified intervals
+ // or if any intervals were missed since the last notification
+ if (timeSinceLastNotification.toSeconds() > 5 && timeRemaining.toSecondsPart() < 2) {
+ if (timeRemaining.toHours() > 0) {
+ printTimeRemaining(timeRemaining);
+ } else if (minutesList.contains(timeRemaining.toMinutesPart())) {
+ printTimeRemaining(timeRemaining);
+ } else if (secondsList.contains(timeRemaining.toSecondsPart())) {
+ printTimeRemaining(timeRemaining);
+ }
+ } else if (timeRemaining.toSeconds() <= 5) {
+ printTimeRemaining(timeRemaining);
+ }
+ }
+
+ private void printTimeRemaining(Duration timeRemaining) {
+ TagResolver tagResolver;
+ lastTimeNotified = Instant.now();
+
+ if (timeRemaining.toHours() > 0)
+ tagResolver = TagResolver.resolver(Placeholder.parsed("time_unit", "hours"), Placeholder.parsed("time", String.valueOf(timeRemaining.toHoursPart())));
+ else if (timeRemaining.toMinutes() > 0)
+ tagResolver = TagResolver.resolver(Placeholder.parsed("time_unit", "minutes"), Placeholder.parsed("time", String.valueOf(timeRemaining.toMinutesPart())));
+ else
+ tagResolver = TagResolver.resolver(Placeholder.parsed("time_unit", "seconds"), Placeholder.parsed("time", String.valueOf(timeRemaining.toSecondsPart())));
+ server.broadcast(MiniMessage.miniMessage().deserialize(Messages.TIMER.TIME_REMAINING, tagResolver));
+ }
+
+}
diff --git a/src/main/java/com/alttd/fishingevent/timer/EventManager.java b/src/main/java/com/alttd/fishingevent/timer/EventManager.java
new file mode 100644
index 0000000..362f317
--- /dev/null
+++ b/src/main/java/com/alttd/fishingevent/timer/EventManager.java
@@ -0,0 +1,76 @@
+package com.alttd.fishingevent.timer;
+
+import com.alttd.fishingevent.config.Messages;
+import com.alttd.fishingevent.scoreboard.ScoreboardManager;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.minimessage.MiniMessage;
+import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
+import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
+import org.bukkit.Server;
+
+import java.time.Duration;
+import java.time.Instant;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+public class EventManager {
+
+ private static EventManager instance = null;
+ private boolean running = false;
+ private Instant startTime;
+ private Duration duration;
+ private EventAutoMessages eventAutoMessages;
+ private ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
+
+ private EventManager() {}
+
+ public static EventManager getInstance() {
+ if (instance == null)
+ instance = new EventManager();
+ return instance;
+ }
+
+ public boolean startEvent(Server server, Duration duration) {
+ if (running)
+ return false;
+ running = true;
+ startTime = Instant.now();
+ this.duration = duration;
+ server.sendMessage(MiniMessage.miniMessage().deserialize(Messages.TIMER.EVENT_START, Placeholder.parsed("minutes", String.valueOf(duration.toMinutes()))));
+ eventAutoMessages = new EventAutoMessages(startTime, duration, server);
+ if (scheduler.isShutdown() || scheduler.isTerminated())
+ scheduler = Executors.newScheduledThreadPool(1);
+ scheduler.scheduleAtFixedRate(eventAutoMessages, 5, 1, TimeUnit.SECONDS);
+ return true;
+ }
+
+ public boolean isRunning() {
+ return running;
+ }
+
+
+ public void stop() {
+ if (!scheduler.isTerminated() && !scheduler.isShutdown()) {
+ scheduler.shutdownNow();
+ }
+ running = false;
+ }
+
+ protected void end(Server server) {
+ if (!scheduler.isTerminated() && !scheduler.isShutdown()) {
+ scheduler.shutdownNow();
+ }
+ running = false;
+ AtomicReference message = new AtomicReference<>(MiniMessage.miniMessage().deserialize(Messages.TIMER.EVENT_END));
+ ScoreboardManager.getInstance().getTop10().stream().limit(3).forEachOrdered(playerScore ->
+ message.set(message.get().append(Component.newline()).append(MiniMessage.miniMessage().deserialize(Messages.TIMER.WINNER_FORMAT, TagResolver.resolver(
+ Placeholder.component("player", playerScore.player().displayName()),
+ Placeholder.unparsed("rarity", playerScore.fish().getRarity().displayName()),
+ Placeholder.component("fish", playerScore.fish().fishName()),
+ Placeholder.parsed("length", String.format("%.2f", playerScore.biggestFish()))
+ )))));
+ server.sendMessage(message.get());
+ }
+}