Implemented timer and commands to start/stop the event
Prevent players from fishing while the event is not active
This commit is contained in:
parent
430e827e32
commit
7b818cb126
|
|
@ -37,7 +37,6 @@ public final class FishingEvent extends JavaPlugin {
|
||||||
}
|
}
|
||||||
reloadFishConfigs();
|
reloadFishConfigs();
|
||||||
registerEvents(getServer().getPluginManager());
|
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())
|
if (new LoadTask(PointsManagement.getInstance(), this, logger).loadOldPointsData())
|
||||||
logger.info("Loaded old points data");
|
logger.info("Loaded old points data");
|
||||||
saveTask = new SaveTask(PointsManagement.getInstance(), this, logger);
|
saveTask = new SaveTask(PointsManagement.getInstance(), this, logger);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
package com.alttd.fishingevent.commands;
|
package com.alttd.fishingevent.commands;
|
||||||
|
|
||||||
import com.alttd.fishingevent.FishingEvent;
|
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.Leaderboard;
|
||||||
import com.alttd.fishingevent.commands.fish_subcommands.Points;
|
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.config.Messages;
|
||||||
import com.alttd.fishingevent.util.Logger;
|
import com.alttd.fishingevent.util.Logger;
|
||||||
import org.bukkit.command.*;
|
import org.bukkit.command.*;
|
||||||
|
|
@ -30,7 +32,9 @@ public class FishCommand implements CommandExecutor, TabExecutor {
|
||||||
|
|
||||||
subCommands = Arrays.asList(
|
subCommands = Arrays.asList(
|
||||||
new Points(),
|
new Points(),
|
||||||
new Leaderboard()
|
new Leaderboard(),
|
||||||
|
new Start(),
|
||||||
|
new End()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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("<red>Stopped event</red>", null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "end";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getTabComplete(CommandSender commandSender, String[] args) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHelpMessage() {
|
||||||
|
return "<red>Invalid command use</red>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -25,7 +25,7 @@ public class Leaderboard extends SubCommand {
|
||||||
component = component.append(Component.newline()).append(MiniMessage.miniMessage().deserialize("<player>'s biggest fish was the <rarity> <fish> at <length> cm",
|
component = component.append(Component.newline()).append(MiniMessage.miniMessage().deserialize("<player>'s biggest fish was the <rarity> <fish> at <length> cm",
|
||||||
Placeholder.component("player", playerScore.player().displayName()),
|
Placeholder.component("player", playerScore.player().displayName()),
|
||||||
Placeholder.parsed("length", String.format("%.2f", playerScore.biggestFish())),
|
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())));
|
Placeholder.component("fish", playerScore.fish().fishName())));
|
||||||
if (playerScore.player().getUniqueId().equals(uuid))
|
if (playerScore.player().getUniqueId().equals(uuid))
|
||||||
displayPlayerScore = false;
|
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 <rarity> <fish> at <length> cm",
|
component = component.append(Component.newline()).append(MiniMessage.miniMessage().deserialize("Your biggest fish was the <rarity> <fish> at <length> cm",
|
||||||
Placeholder.component("player", playerScore.player().displayName()),
|
Placeholder.component("player", playerScore.player().displayName()),
|
||||||
Placeholder.parsed("length", String.format("%.2f", playerScore.biggestFish())),
|
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())));
|
Placeholder.component("fish", playerScore.fish().fishName())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,6 +56,6 @@ public class Leaderboard extends SubCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getHelpMessage() {
|
public String getHelpMessage() {
|
||||||
return ""; //TODO implement
|
return "<red>Invalid command use</red>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -70,6 +70,6 @@ public class Points extends SubCommand {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getHelpMessage() {
|
public String getHelpMessage() {
|
||||||
return ""; //TODO implement
|
return "<red>Invalid command use</red>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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("<red>Include the time (as an int in minutes)</red>", null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
int minutes;
|
||||||
|
try {
|
||||||
|
minutes = Integer.parseInt(args[1]);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
commandSender.sendMiniMessage("<red>Include the time (as an int in minutes)</red>", null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Duration duration = Duration.ofMinutes(minutes);
|
||||||
|
if (EventManager.getInstance().startEvent(commandSender.getServer(), duration)) {
|
||||||
|
commandSender.sendMiniMessage("<green>Started event with duration of <minutes> minutes", Placeholder.parsed("minutes", String.valueOf(minutes)));
|
||||||
|
} else {
|
||||||
|
commandSender.sendMiniMessage("<red>Unable to start event</red>", null);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "start";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> getTabComplete(CommandSender commandSender, String[] args) {
|
||||||
|
return List.of();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHelpMessage() {
|
||||||
|
return "<red>Invalid command use</red>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -130,4 +130,21 @@ public class Messages extends AbstractConfig {
|
||||||
UNABLE_TO_UPDATE_ENCHANTMENT = config.getString(prefix, "unable-to-update-enchantment", UNABLE_TO_UPDATE_ENCHANTMENT);
|
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 = "<green>There are <time> <time_unit>(s) remaining before the end of the event! You will be able to keep selling your fish and buying prizes for some time after the event ends.</green>";
|
||||||
|
public static String EVENT_START = "<green>The fishing event has started! It will end in <minutes> minutes, you will be able to sell your fishes and buy prizes during and after the event.</green>";
|
||||||
|
public static String EVENT_END = "<green>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:</green>";
|
||||||
|
public static String WINNER_FORMAT = "<green><gold><player></gold> with a <rarity> <fish> <gold><length> cm</gold></green>";
|
||||||
|
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import com.alttd.fishingevent.fish_generator.FishGenerator;
|
||||||
import com.alttd.fishingevent.objects.FishType;
|
import com.alttd.fishingevent.objects.FishType;
|
||||||
import com.alttd.fishingevent.points.PointsManagement;
|
import com.alttd.fishingevent.points.PointsManagement;
|
||||||
import com.alttd.fishingevent.scoreboard.ScoreboardManager;
|
import com.alttd.fishingevent.scoreboard.ScoreboardManager;
|
||||||
|
import com.alttd.fishingevent.timer.EventManager;
|
||||||
import com.alttd.fishingevent.util.Logger;
|
import com.alttd.fishingevent.util.Logger;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
|
|
@ -25,6 +26,7 @@ public class CatchFish implements Listener {
|
||||||
private final Logger logger;
|
private final Logger logger;
|
||||||
private final FishGenerator waterFishGenerator;
|
private final FishGenerator waterFishGenerator;
|
||||||
private final PointsManagement pointsManagement;
|
private final PointsManagement pointsManagement;
|
||||||
|
private final EventManager eventManager = EventManager.getInstance();
|
||||||
|
|
||||||
public CatchFish(Logger logger, FishGenerator waterFishGenerator, PointsManagement pointsManagement) {
|
public CatchFish(Logger logger, FishGenerator waterFishGenerator, PointsManagement pointsManagement) {
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
|
|
@ -35,6 +37,10 @@ public class CatchFish implements Listener {
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerFish(PlayerFishEvent event) {
|
public void onPlayerFish(PlayerFishEvent event) {
|
||||||
|
if (!eventManager.isRunning()) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (event.getState().equals(PlayerFishEvent.State.FISHING)) {
|
if (event.getState().equals(PlayerFishEvent.State.FISHING)) {
|
||||||
//if fishing rod in lava continue else return
|
//if fishing rod in lava continue else return
|
||||||
// logger.debug("% might have caught a lava fish", event.getPlayer().getName());
|
// logger.debug("% might have caught a lava fish", event.getPlayer().getName());
|
||||||
|
|
|
||||||
|
|
@ -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<Integer> minutesList = List.of(30, 15, 10, 5, 2, 1);
|
||||||
|
private final List<Integer> 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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
76
src/main/java/com/alttd/fishingevent/timer/EventManager.java
Normal file
76
src/main/java/com/alttd/fishingevent/timer/EventManager.java
Normal file
|
|
@ -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<Component> 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user