Make game logic adjustments and improve async command handling

Added permission checks for players bypassing game actions and refined block event handling based on game phase. Introduced asynchronous handling for permission commands to improve server performance. Updated constructors and dependencies to streamline game phase management.
This commit is contained in:
Teriuihi 2025-03-06 19:47:28 +01:00
parent 92f9e732a1
commit 4953cec215
7 changed files with 48 additions and 20 deletions

View File

@ -8,6 +8,7 @@ import com.alttd.ctf.events.*;
import com.alttd.ctf.flag.Flag; import com.alttd.ctf.flag.Flag;
import com.alttd.ctf.flag.FlagTryCaptureEvent; import com.alttd.ctf.flag.FlagTryCaptureEvent;
import com.alttd.ctf.game.GameManager; import com.alttd.ctf.game.GameManager;
import com.alttd.ctf.game.phases.EndedPhase;
import com.alttd.ctf.gui.ClassSelectionGUI; import com.alttd.ctf.gui.ClassSelectionGUI;
import com.alttd.ctf.gui.GUIInventory; import com.alttd.ctf.gui.GUIInventory;
import com.alttd.ctf.gui.GUIListener; import com.alttd.ctf.gui.GUIListener;
@ -38,6 +39,7 @@ public class Main extends JavaPlugin {
@Override @Override
public void onEnable() { public void onEnable() {
PlayerStat.main = this;
GUIInventory.setMain(this); // sorry GUIInventory.setMain(this); // sorry
ClassSelectionGUI.setMain(this); // sorry ClassSelectionGUI.setMain(this); // sorry
Package pkg = Main.class.getPackage(); Package pkg = Main.class.getPackage();
@ -46,7 +48,7 @@ public class Main extends JavaPlugin {
reloadConfigs(); reloadConfigs();
WorldBorderApi worldBorderApi = worldBorder(); WorldBorderApi worldBorderApi = worldBorder();
this.gameManager = new GameManager(worldBorderApi); this.gameManager = new GameManager(this, worldBorderApi);
registerTeams(); //Skipped in reloadConfig if gameManager is not created yet registerTeams(); //Skipped in reloadConfig if gameManager is not created yet
loadPlayerStats(); //Skipped in reloadConfig if gameManager is not created yet loadPlayerStats(); //Skipped in reloadConfig if gameManager is not created yet
Flag flag = new Flag(this, gameManager); Flag flag = new Flag(this, gameManager);

View File

@ -40,9 +40,11 @@ public class OnPlayerOnlineStatus implements Listener {
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
resetPlayer(player); resetPlayer(player);
handleRunningGame(player); if (!player.hasPermission("ctf.bypass")) {
handleRunningGame(player);
}
handleDiscordLink(player); handleDiscordLink(player);
gameManager.getTeamPlayer(player).ifPresent(teamPlayer -> gameManager.getTeamPlayer(player).ifPresent(teamPlayer ->
player.teleportAsync(teamPlayer.getTeam().getSpawnLocation())); player.teleportAsync(teamPlayer.getTeam().getSpawnLocation()));
} }

View File

@ -1,6 +1,7 @@
package com.alttd.ctf.events; package com.alttd.ctf.events;
import com.alttd.ctf.game.GameManager; import com.alttd.ctf.game.GameManager;
import com.alttd.ctf.game.GamePhase;
import com.alttd.ctf.stats.Stat; import com.alttd.ctf.stats.Stat;
import com.alttd.ctf.team.TeamPlayer; import com.alttd.ctf.team.TeamPlayer;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -12,6 +13,7 @@ import org.bukkit.entity.ThrownPotion;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.PotionSplashEvent; import org.bukkit.event.entity.PotionSplashEvent;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
@ -29,7 +31,8 @@ public class OtherGameEvents implements Listener {
@EventHandler @EventHandler
public void onBlockBreak(BlockBreakEvent event) { public void onBlockBreak(BlockBreakEvent event) {
if (gameManager.getGamePhase().isEmpty()) { Optional<GamePhase> gamePhase = gameManager.getGamePhase();
if (gamePhase.isEmpty() || gamePhase.get() == GamePhase.ENDED) {
return; return;
} }
if (!Tag.SNOW.isTagged(event.getBlock().getType())) { if (!Tag.SNOW.isTagged(event.getBlock().getType())) {
@ -41,8 +44,9 @@ public class OtherGameEvents implements Listener {
} }
@EventHandler @EventHandler
public void onBlockPlace(BlockBreakEvent event) { public void onBlockPlace(BlockPlaceEvent event) {
if (gameManager.getGamePhase().isEmpty()) { Optional<GamePhase> gamePhase = gameManager.getGamePhase();
if (gamePhase.isEmpty() || gamePhase.get() == GamePhase.ENDED) {
return; return;
} }
if (!Tag.SNOW.isTagged(event.getBlock().getType())) { if (!Tag.SNOW.isTagged(event.getBlock().getType())) {

View File

@ -1,5 +1,6 @@
package com.alttd.ctf.game; package com.alttd.ctf.game;
import com.alttd.ctf.Main;
import com.alttd.ctf.flag.Flag; import com.alttd.ctf.flag.Flag;
import com.alttd.ctf.game.phases.ClassSelectionPhase; import com.alttd.ctf.game.phases.ClassSelectionPhase;
import com.alttd.ctf.game.phases.CombatPhase; import com.alttd.ctf.game.phases.CombatPhase;
@ -27,12 +28,12 @@ public class GameManager {
private final HashMap<Integer, Team> teams = new HashMap<>(); private final HashMap<Integer, Team> teams = new HashMap<>();
private final HashMap<UUID, PlayerStat> playerStats = new HashMap<>(); private final HashMap<UUID, PlayerStat> playerStats = new HashMap<>();
public GameManager(WorldBorderApi worldBorderApi) { public GameManager(Main main, WorldBorderApi worldBorderApi) {
phases = new HashMap<>(); phases = new HashMap<>();
phases.put(GamePhase.CLASS_SELECTION, new ClassSelectionPhase(this, FighterCreator::createFighter, worldBorderApi)); phases.put(GamePhase.CLASS_SELECTION, new ClassSelectionPhase(this, FighterCreator::createFighter, worldBorderApi));
phases.put(GamePhase.GATHERING, new GatheringPhase(this, worldBorderApi)); phases.put(GamePhase.GATHERING, new GatheringPhase(this, worldBorderApi));
phases.put(GamePhase.COMBAT, new CombatPhase()); phases.put(GamePhase.COMBAT, new CombatPhase());
phases.put(GamePhase.ENDED, new EndedPhase(this)); phases.put(GamePhase.ENDED, new EndedPhase(main, this));
} }
public Optional<GamePhase> getGamePhase() { public Optional<GamePhase> getGamePhase() {

View File

@ -1,5 +1,6 @@
package com.alttd.ctf.game.phases; package com.alttd.ctf.game.phases;
import com.alttd.ctf.Main;
import com.alttd.ctf.config.GameConfig; import com.alttd.ctf.config.GameConfig;
import com.alttd.ctf.flag.Flag; import com.alttd.ctf.flag.Flag;
import com.alttd.ctf.game.GameManager; import com.alttd.ctf.game.GameManager;
@ -28,9 +29,11 @@ import java.util.Map;
public class EndedPhase implements GamePhaseExecutor { public class EndedPhase implements GamePhaseExecutor {
private final MiniMessage miniMessage = MiniMessage.miniMessage(); private final MiniMessage miniMessage = MiniMessage.miniMessage();
private final Main main;
private final GameManager gameManager; private final GameManager gameManager;
public EndedPhase(GameManager gameManager) { public EndedPhase(Main main, GameManager gameManager) {
this.main = main;
this.gameManager = gameManager; this.gameManager = gameManager;
} }
@ -91,14 +94,17 @@ public class EndedPhase implements GamePhaseExecutor {
Placeholder.component("team", winner.getName()), Placeholder.component("team", winner.getName()),
Placeholder.parsed("score", String.valueOf(highestScore)))); Placeholder.parsed("score", String.valueOf(highestScore))));
ConsoleCommandSender consoleSender = Bukkit.getConsoleSender(); ConsoleCommandSender consoleSender = Bukkit.getConsoleSender();
winner.getPlayers().forEach(teamPlayer -> { Bukkit.getScheduler().runTaskAsynchronously(main, () -> {
OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(teamPlayer.getUuid()); winner.getPlayers().forEach(teamPlayer -> {
String name = offlinePlayer.getName(); OfflinePlayer offlinePlayer = Bukkit.getOfflinePlayer(teamPlayer.getUuid());
if (name == null) { String name = offlinePlayer.getName();
return; if (name == null) {
} return;
Bukkit.dispatchCommand(consoleSender, String.format("lp user %s permission settemp ctf.victory.%s true 14d", name, winner.getId())); }
Bukkit.dispatchCommand(consoleSender, String.format("lp user %s permission settemp ctf.victory.%s true 14d", name, winner.getId()));
});
}); });
if (wins.size() <= 1) { if (wins.size() <= 1) {
return messages; return messages;
} }

View File

@ -1,5 +1,7 @@
package com.alttd.ctf.stats; package com.alttd.ctf.stats;
import com.alttd.ctf.Main;
import com.alttd.ctf.config.GameConfig;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Getter; import lombok.Getter;
@ -19,6 +21,9 @@ import java.util.UUID;
@RequiredArgsConstructor @RequiredArgsConstructor
@Getter @Getter
public final class PlayerStat { public final class PlayerStat {
@JsonIgnore
public static Main main;
@JsonIgnore @JsonIgnore
private boolean touched; private boolean touched;
@JsonIgnore @JsonIgnore
@ -48,7 +53,12 @@ public final class PlayerStat {
switch (stat) { switch (stat) {
case COMPLETED_GAME -> { case COMPLETED_GAME -> {
if (!completedGame) { if (!completedGame) {
Bukkit.dispatchCommand(commandSender, String.format("lp user %s permission settemp ctf.game.completed true 14d", inGameName)); Bukkit.getScheduler().runTask(main, () -> {
Bukkit.getScheduler().runTaskAsynchronously(main, () -> {
Bukkit.dispatchCommand(commandSender, String.format("lp user %s permission settemp ctf.game.completed true 14d", inGameName));
});
});
} }
completedGame = true; completedGame = true;
} }
@ -73,7 +83,10 @@ public final class PlayerStat {
} }
Bukkit.broadcast(MiniMessage.miniMessage().deserialize("<red><player> will receive a consolation prize for being the first to die in powdered snow.</red>", Bukkit.broadcast(MiniMessage.miniMessage().deserialize("<red><player> will receive a consolation prize for being the first to die in powdered snow.</red>",
Placeholder.component("player",player.displayName()))); Placeholder.component("player",player.displayName())));
Bukkit.dispatchCommand(commandSender, String.format("lp user %s permission settemp ctf.game.first_powdered_snow_death true 14d", inGameName)); Bukkit.getScheduler().runTaskAsynchronously(main, () -> {
Bukkit.dispatchCommand(commandSender, String.format("lp user %s permission settemp ctf.game.first_powdered_snow_death true 14d", inGameName));
});
someoneDiedInPowderedSnow = true; someoneDiedInPowderedSnow = true;
} }
case DAMAGE_DONE, DAMAGE_HEALED -> throw new IllegalArgumentException(String.format("%s requires a number", stat.name())); case DAMAGE_DONE, DAMAGE_HEALED -> throw new IllegalArgumentException(String.format("%s requires a number", stat.name()));

View File

@ -1,3 +1,3 @@
#Sat Mar 01 22:40:35 CET 2025 #Sun Mar 02 00:42:30 CET 2025
buildNumber=110 buildNumber=112
version=0.1 version=0.1