diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/event/Event.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/event/Event.java index d6580c4..1dad133 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/appliances/event/Event.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/event/Event.java @@ -5,15 +5,15 @@ import eu.mhsl.craftattack.spawn.Main; import eu.mhsl.craftattack.spawn.api.HttpServer; import eu.mhsl.craftattack.spawn.appliance.Appliance; import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; -import eu.mhsl.craftattack.spawn.appliances.event.command.EventCommand; -import eu.mhsl.craftattack.spawn.appliances.event.command.EventEndSessionCommand; -import eu.mhsl.craftattack.spawn.appliances.event.command.EventOpenSessionCommand; -import eu.mhsl.craftattack.spawn.appliances.event.command.MoveEventVillagerCommand; +import eu.mhsl.craftattack.spawn.appliances.event.command.*; import eu.mhsl.craftattack.spawn.appliances.event.listener.ApplyPendingRewardsListener; +import eu.mhsl.craftattack.spawn.util.IteratorUtil; import eu.mhsl.craftattack.spawn.util.entity.DisplayVillager; import eu.mhsl.craftattack.spawn.util.server.PluginMessage; import eu.mhsl.craftattack.spawn.util.listener.DismissInventoryOpenFromHolder; import eu.mhsl.craftattack.spawn.util.listener.PlayerInteractAtEntityEventListener; +import eu.mhsl.craftattack.spawn.util.text.ComponentUtil; +import eu.mhsl.craftattack.spawn.util.text.Countdown; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.format.NamedTextColor; import org.bukkit.Bukkit; @@ -23,6 +23,7 @@ import org.bukkit.entity.Villager; import org.bukkit.event.Listener; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import org.eclipse.jetty.util.security.CertificateUtils; import org.jetbrains.annotations.NotNull; import java.io.IOException; @@ -34,8 +35,25 @@ import java.net.http.HttpResponse; import java.util.*; public class Event extends Appliance { + enum AdvertisementStatus { + BEFORE, + ADVERTISED, + DONE + } + Countdown advertiseCountdown = new Countdown( + 120, + announcementData -> Component.text() + .append(ComponentUtil.createRainbowText("Event", 30)) + .append(Component.text(" Start in ", NamedTextColor.GOLD)) + .append(Component.text(announcementData.count(), NamedTextColor.AQUA)) + .append(Component.text(" " + announcementData.unit() + "!", NamedTextColor.GOLD)) + .build(), + component -> IteratorUtil.onlinePlayers(player -> player.sendMessage(component)), + () -> this.advertiseStatus = AdvertisementStatus.DONE + ); public DisplayVillager.ConfigBound villager; private boolean isOpen = false; + private AdvertisementStatus advertiseStatus = AdvertisementStatus.BEFORE; private UUID roomId; private final HttpClient eventServerClient = HttpClient.newHttpClient(); private final List pendingRewards = new ArrayList<>(); @@ -84,6 +102,16 @@ public class Event extends Appliance { return; } + if(!p.hasPermission("admin") && advertiseStatus == AdvertisementStatus.BEFORE) { + p.sendMessage(Component.text("Die Event befinden sich noch in der Vorbereitung.", NamedTextColor.RED)); + return; + } + + if(!p.hasPermission("admin") && advertiseStatus == AdvertisementStatus.DONE) { + p.sendMessage(Component.text("Die Events laufen bereits. Ein nachträgliches Beitreten ist nicht möglich.", NamedTextColor.RED)); + return; + } + try { Main.instance().getLogger().info("Verbinde mit eventserver: " + p.getName()); p.sendMessage(Component.text("Authentifiziere...", NamedTextColor.GREEN)); @@ -162,6 +190,23 @@ public class Event extends Appliance { givenRewards.forEach(this::giveReward); } + public void advertise() { + advertiseCountdown.cancelIfRunning(); + this.advertiseStatus = AdvertisementStatus.ADVERTISED; + IteratorUtil.onlinePlayers(player -> { + player.sendMessage( + Component.text() + .append(Component.text("-".repeat(10), NamedTextColor.GRAY)).appendNewline() + .append(Component.text("Ein Event wurde gestartet!", NamedTextColor.GOLD)).appendNewline() + .append(Component.text("Nutze ")) + .append(Component.text("/event", NamedTextColor.AQUA)) + .append(Component.text(", um dem Event beizutreten!")).appendNewline() + .append(Component.text("-".repeat(10), NamedTextColor.GRAY)).appendNewline() + ); + }); + advertiseCountdown.start(); + } + @Override public void httpApi(HttpServer.ApiBuilder apiBuilder) { apiBuilder.post("reward", RewardConfiguration.class, (rewardConfiguration, request) -> { @@ -176,7 +221,8 @@ public class Event extends Appliance { new EventCommand(), new MoveEventVillagerCommand(), new EventOpenSessionCommand(), - new EventEndSessionCommand() + new EventEndSessionCommand(), + new EventAdvertiseCommand() ); } diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/event/command/EventAdvertiseCommand.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/event/command/EventAdvertiseCommand.java new file mode 100644 index 0000000..cfd486a --- /dev/null +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/event/command/EventAdvertiseCommand.java @@ -0,0 +1,18 @@ +package eu.mhsl.craftattack.spawn.appliances.event.command; + +import eu.mhsl.craftattack.spawn.appliance.ApplianceCommand; +import eu.mhsl.craftattack.spawn.appliances.event.Event; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.jetbrains.annotations.NotNull; + +public class EventAdvertiseCommand extends ApplianceCommand { + public EventAdvertiseCommand() { + super("eventAdvertise"); + } + + @Override + protected void execute(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) throws Exception { + getAppliance().advertise(); + } +} diff --git a/src/main/java/eu/mhsl/craftattack/spawn/appliances/outlawed/Outlawed.java b/src/main/java/eu/mhsl/craftattack/spawn/appliances/outlawed/Outlawed.java index 2e55f90..cabca11 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/appliances/outlawed/Outlawed.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/appliances/outlawed/Outlawed.java @@ -34,6 +34,7 @@ public class Outlawed extends Appliance { Main.instance(), () -> { playerStatusMap.forEach((player, status) -> { + if(!player.isOnline()) return; if(status != Status.FORCED) return; try { Main.instance().getAppliance(Whitelist.class).integrityCheck(player); @@ -89,7 +90,7 @@ public class Outlawed extends Appliance { public Component getStatusDescription(Status status) { return switch (status) { case DISABLED -> Component.text("Vogelfreistatus inaktiv: ", NamedTextColor.GREEN) - .append(Component.text("Es gelten die Standart Regeln!", NamedTextColor.GOLD)); + .append(Component.text("Es gelten die Standard Regeln!", NamedTextColor.GOLD)); case VOLUNTARILY, FORCED -> Component.text("Vogelfreistatus aktiv: ", NamedTextColor.RED) .append(Component.text("Du darfst von jedem angegriffen und getötet werden!", NamedTextColor.GOLD)); diff --git a/src/main/java/eu/mhsl/craftattack/spawn/util/text/Countdown.java b/src/main/java/eu/mhsl/craftattack/spawn/util/text/Countdown.java index 5fc8b9a..87ca702 100644 --- a/src/main/java/eu/mhsl/craftattack/spawn/util/text/Countdown.java +++ b/src/main/java/eu/mhsl/craftattack/spawn/util/text/Countdown.java @@ -66,6 +66,10 @@ public class Countdown { this.current = countdownFrom; } + public void cancelIfRunning() { + if(this.running) cancel(); + } + private void tick() { AnnouncementData defaultAnnouncementData = this.defaultAnnouncements.apply(current); if(defaultAnnouncementData != null) { diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 9b5866b..a30cb7f 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -23,6 +23,7 @@ commands: event: eventOpenSession: eventEndSession: + eventAdvertise: help: spawn: teamspeak: