updated playtimer and teamtasks

This commit is contained in:
2025-06-21 17:18:47 +02:00
parent 220fb9e229
commit 0d1e6070ce
9 changed files with 111 additions and 31 deletions

View File

@ -4,4 +4,5 @@ dependencies {
compileOnly 'io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT' compileOnly 'io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT'
compileOnly 'org.geysermc.floodgate:api:2.2.2-SNAPSHOT' compileOnly 'org.geysermc.floodgate:api:2.2.2-SNAPSHOT'
implementation 'org.apache.httpcomponents:httpclient:4.5.14' implementation 'org.apache.httpcomponents:httpclient:4.5.14'
implementation 'com.sparkjava:spark-core:2.9.4'
} }

View File

@ -34,12 +34,12 @@ public class Countdown {
this.onDone = onDone; this.onDone = onDone;
this.defaultAnnouncements = count -> { this.defaultAnnouncements = count -> {
if(this.current > 60 && this.current % 60 == 0) { if(count > 60 && count % 60 == 0) {
return new AnnouncementData(this.current / 60, "Minuten"); return new AnnouncementData(count / 60, "Minuten");
} }
if(this.current <= 60 && (this.current <= 10 || this.current % 10 == 0)) { if(count <= 60 && (count <= 10 || count % 10 == 0)) {
return new AnnouncementData(this.current, "Sekunden"); return new AnnouncementData(count, "Sekunden");
} }
return null; return null;
@ -87,7 +87,7 @@ public class Countdown {
if(this.isDone()) { if(this.isDone()) {
this.onDone.run(); this.onDone.run();
this.cancel(); this.cancelIfRunning();
} }
} }

View File

@ -0,0 +1,6 @@
package eu.mhsl.craftattack.spawn.varo.appliances.internal.teamTasks;
public interface Task {
void stopTask();
boolean isRunning();
}

View File

@ -4,7 +4,6 @@ import eu.mhsl.craftattack.spawn.core.Main;
import eu.mhsl.craftattack.spawn.core.appliance.Appliance; import eu.mhsl.craftattack.spawn.core.appliance.Appliance;
import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.teams.VaroTeam; import eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.teams.VaroTeam;
import org.bukkit.scheduler.BukkitTask;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.HashMap; import java.util.HashMap;
@ -20,25 +19,25 @@ public class TeamTasks extends Appliance {
TIME_KICK TIME_KICK
} }
private final Map<VaroTeam, Map<Type, BukkitTask>> tasks = new HashMap<>(); private final Map<VaroTeam, Map<Type, Task>> tasks = new HashMap<>();
private Map<Type, BukkitTask> getTeamTasks(VaroTeam team) { private Map<Type, Task> getTeamTasks(VaroTeam team) {
return this.tasks.computeIfAbsent(team, varoTeam -> new HashMap<>()); return this.tasks.computeIfAbsent(team, varoTeam -> new HashMap<>());
} }
public Map<Type, BukkitTask> getRunningTeamTasks(VaroTeam team) { public Map<Type, Task> getRunningTeamTasks(VaroTeam team) {
return this.getTeamTasks(team).entrySet().stream() return this.getTeamTasks(team).entrySet().stream()
.filter(entry -> !entry.getValue().isCancelled()) .filter(entry -> entry.getValue().isRunning())
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
} }
public void cancelTeamTasks(VaroTeam team) { public void cancelTeamTasks(VaroTeam team) {
Main.logger().info(String.format("All TeamTasks for Team %s were cancelled: %s", team.name, this.getRunningTeamTasks(team))); Main.logger().info(String.format("All TeamTasks for Team %s were cancelled: %s", team.name, this.getRunningTeamTasks(team)));
this.getTeamTasks(team).forEach((type, bukkitTask) -> bukkitTask.cancel()); this.getTeamTasks(team).forEach((type, bukkitTask) -> bukkitTask.stopTask());
} }
public void addTask(VaroTeam team, Type type, BukkitTask runnable) { public void addTask(VaroTeam team, Type type, Task runnable) {
if(this.getTeamTasks(team).containsKey(type) && !this.getTeamTasks(team).get(type).isCancelled()) { if(this.getTeamTasks(team).containsKey(type) && this.getTeamTasks(team).get(type).isRunning()) {
throw new IllegalStateException(String.format("Task %s for Team %s was already running!", type.name(), team.name)); throw new IllegalStateException(String.format("Task %s for Team %s was already running!", type.name(), team.name));
} }

View File

@ -28,7 +28,7 @@ public class TeamTasksCommand extends ApplianceCommand<TeamTasks> {
sender.sendMessage( sender.sendMessage(
tasks.entrySet() tasks.entrySet()
.stream() .stream()
.map(entry -> String.format("%s: %d", entry.getKey().name(), entry.getValue().getTaskId())) .map(entry -> String.format("%s: %s", entry.getKey().name(), entry.getValue().getClass().getSimpleName()))
.collect(Collectors.joining("\n")) .collect(Collectors.joining("\n"))
); );
} }

View File

@ -0,0 +1,16 @@
package eu.mhsl.craftattack.spawn.varo.appliances.internal.teamTasks.tasks;
import eu.mhsl.craftattack.spawn.varo.appliances.internal.teamTasks.Task;
import org.bukkit.scheduler.BukkitTask;
public abstract class BukkitTeamTask implements Task, BukkitTask {
@Override
public void stopTask() {
this.cancel();
}
@Override
public boolean isRunning() {
return !this.isCancelled();
}
}

View File

@ -0,0 +1,24 @@
package eu.mhsl.craftattack.spawn.varo.appliances.internal.teamTasks.tasks;
import eu.mhsl.craftattack.spawn.core.util.text.Countdown;
import eu.mhsl.craftattack.spawn.varo.appliances.internal.teamTasks.Task;
import net.kyori.adventure.text.Component;
import java.util.function.Consumer;
import java.util.function.Function;
public class CountdownTeamTask extends Countdown implements Task {
public CountdownTeamTask(int countdownFrom, Function<AnnouncementData, Component> announcementBuilder, Consumer<Component> announcementConsumer, Runnable onDone) {
super(countdownFrom, announcementBuilder, announcementConsumer, onDone);
}
@Override
public void stopTask() {
super.cancelIfRunning();
}
@Override
public boolean isRunning() {
return !super.isDone();
}
}

View File

@ -8,17 +8,21 @@ import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import java.util.Objects;
class ConnectivityChangeListener extends ApplianceListener<Teams> { class ConnectivityChangeListener extends ApplianceListener<Teams> {
@EventHandler @EventHandler
public void onLogin(AsyncPlayerPreLoginEvent event) { public void onLogin(AsyncPlayerPreLoginEvent event) {
boolean result = this.getAppliance().canLogin(event.getUniqueId()); boolean result = this.getAppliance().canLogin(event.getUniqueId());
event.kickMessage(new DisconnectInfo( if(!result) {
"Kein Teilnehmer", event.kickMessage(new DisconnectInfo(
"Du bist nicht als Teilnehmer registriert oder bist ausgeschieden!", "Kein Teilnehmer",
"Sollte dies ein Fehler sein, kontaktiere bitte einen Admin.", "Du bist nicht als Teilnehmer registriert oder bist ausgeschieden!",
event.getUniqueId() "Sollte dies ein Fehler sein, kontaktiere bitte einen Admin.",
).getComponent()); event.getUniqueId()
if(!result) event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER); ).getComponent());
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
}
} }
@EventHandler @EventHandler
@ -37,6 +41,7 @@ class ConnectivityChangeListener extends ApplianceListener<Teams> {
} }
VaroTeam team = Main.instance().getAppliance(Teams.class).getTeamFromPlayer(event.getPlayer().getUniqueId()); VaroTeam team = Main.instance().getAppliance(Teams.class).getTeamFromPlayer(event.getPlayer().getUniqueId());
Objects.requireNonNull(team, "Team not found for player " + event.getPlayer().getUniqueId());
Main.logger().info(String.format("Team %s got a Strike, because they %s left early!", team.name, event.getPlayer().getName())); Main.logger().info(String.format("Team %s got a Strike, because they %s left early!", team.name, event.getPlayer().getName()));
// TODO: strike team // TODO: strike team
this.getAppliance().enforceTeamLeave(event.getPlayer()); this.getAppliance().enforceTeamLeave(event.getPlayer());

View File

@ -3,10 +3,12 @@ package eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.teams;
import eu.mhsl.craftattack.spawn.core.Main; import eu.mhsl.craftattack.spawn.core.Main;
import eu.mhsl.craftattack.spawn.core.appliance.Appliance; import eu.mhsl.craftattack.spawn.core.appliance.Appliance;
import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand; import eu.mhsl.craftattack.spawn.core.appliance.ApplianceCommand;
import eu.mhsl.craftattack.spawn.core.util.text.Countdown;
import eu.mhsl.craftattack.spawn.core.util.text.DisconnectInfo; import eu.mhsl.craftattack.spawn.core.util.text.DisconnectInfo;
import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.displayName.DisplayName; import eu.mhsl.craftattack.spawn.common.appliances.metaGameplay.displayName.DisplayName;
import eu.mhsl.craftattack.spawn.varo.api.repositories.TeamRepository; import eu.mhsl.craftattack.spawn.varo.api.repositories.TeamRepository;
import eu.mhsl.craftattack.spawn.varo.appliances.internal.teamTasks.TeamTasks; import eu.mhsl.craftattack.spawn.varo.appliances.internal.teamTasks.TeamTasks;
import eu.mhsl.craftattack.spawn.varo.appliances.internal.teamTasks.tasks.CountdownTeamTask;
import eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.joinProtection.JoinProtection; import eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.joinProtection.JoinProtection;
import eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.playTimer.PlayTimer; import eu.mhsl.craftattack.spawn.varo.appliances.metaGameplay.playTimer.PlayTimer;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@ -17,7 +19,6 @@ import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.scheduler.BukkitTask;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
@ -56,7 +57,7 @@ public class Teams extends Appliance implements DisplayName.Prefixed {
updatedTeam.color() updatedTeam.color()
); );
this.teams.add(newTeam); this.teams.add(newTeam);
Main.logger().info("Added missing team to Teams registry: " + newTeam); Main.logger().info("Added missing team to Teams registry: " + newTeam.name);
} }
} }
} }
@ -70,10 +71,20 @@ public class Teams extends Appliance implements DisplayName.Prefixed {
public boolean canLogin(UUID playerId) { public boolean canLogin(UUID playerId) {
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerId); OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(playerId);
if(offlinePlayer.isOp()) return true; if(offlinePlayer.isOp()) {
Main.logger().info(String.format("Allowing player %s to login, because he ist OP!", playerId));
return true;
}
return this.teams.stream() Optional<VaroTeam> team = this.teams.stream()
.anyMatch(varoTeam -> varoTeam.hasMember(playerId) && !Objects.requireNonNull(varoTeam.getMemberById(playerId)).isDead); .filter(varoTeam -> varoTeam.hasMember(playerId) && !Objects.requireNonNull(varoTeam.getMemberById(playerId)).isDead)
.findAny();
team.ifPresentOrElse(
found -> Main.logger().info(String.format("Player %s is in Team %s!", playerId, found.name)),
() -> Main.logger().info(String.format("No valid Team found for %s (or he is in a Team but dead)!", playerId))
);
return team.isPresent();
} }
public @Nullable VaroTeam getTeamFromPlayer(UUID playerId) { public @Nullable VaroTeam getTeamFromPlayer(UUID playerId) {
@ -143,12 +154,30 @@ public class Teams extends Appliance implements DisplayName.Prefixed {
.ifPresentOrElse( .ifPresentOrElse(
member -> team.kickTeam(teamNotCompleteInfo), member -> team.kickTeam(teamNotCompleteInfo),
() -> { () -> {
BukkitTask kickTask = Bukkit.getScheduler().runTaskLater( Main.logger().info(String.format("Starting Time countdown for Team %s with %d", team.name, PlayTimer.PLAYTIME_MINUTES));
Main.instance(), CountdownTeamTask countdown = new CountdownTeamTask(
team::timeOverKick, 60 * PlayTimer.PLAYTIME_MINUTES,
Ticks.TICKS_PER_SECOND * 60 * PlayTimer.PLAYTIME_MINUTES announcementData -> Component.text(
String.format("Es verbleiben noch %d %s Spielzeit!", announcementData.count(), announcementData.unit()),
NamedTextColor.RED
),
component -> team.getOnlinePlayers().forEach(player -> player.sendMessage(component)),
team::timeOverKick
); );
this.queryAppliance(TeamTasks.class).addTask(team, TeamTasks.Type.TIME_KICK, kickTask); countdown.setDefaultAnnouncements(count -> {
if(count > 300) return null;
if(count > 60 && count % 60 == 0) {
return new Countdown.AnnouncementData(count / 60, "Minuten");
}
if(count <= 30 && (count <= 10 || count % 10 == 0)) {
return new Countdown.AnnouncementData(count, "Sekunden");
}
return null;
});
countdown.start();
this.queryAppliance(TeamTasks.class).addTask(team, TeamTasks.Type.TIME_KICK, countdown);
} }
), ),
Ticks.TICKS_PER_SECOND * (JoinProtection.resistanceDuration / 2) Ticks.TICKS_PER_SECOND * (JoinProtection.resistanceDuration / 2)