140 lines
5.9 KiB
Java
140 lines
5.9 KiB
Java
package com.alttd.hunger_games.services;
|
|
|
|
import com.alttd.hunger_games.config.Messages;
|
|
import com.alttd.hunger_games.data_objects.DESTINATION;
|
|
import com.alttd.hunger_games.data_objects.PLAYER_STATE;
|
|
import com.alttd.hunger_games.data_objects.ROUND_STATE;
|
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
|
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.entity.Player;
|
|
|
|
import java.util.*;
|
|
|
|
public class PlayerService implements RoundListener {
|
|
|
|
private static PlayerService instance = null;
|
|
|
|
private final RoundService roundService;
|
|
private final PlayerTeleporterService playerTeleporterService;
|
|
private ROUND_STATE roundState;
|
|
|
|
public PlayerService(Round round, RoundService roundService, PlayerTeleporterService playerTeleporterService) {
|
|
this.roundService = roundService;
|
|
this.playerTeleporterService = playerTeleporterService;
|
|
this.roundState = round.register(this);
|
|
}
|
|
|
|
public static PlayerService createSingletonInstance(Round round, RoundService roundService, PlayerTeleporterService playerTeleporterService) {
|
|
if (instance != null) {
|
|
throw new IllegalStateException("PlayerService is already initialized.");
|
|
}
|
|
instance = new PlayerService(round, roundService, playerTeleporterService);
|
|
return instance;
|
|
}
|
|
|
|
@Override
|
|
public void stateChange(ROUND_STATE roundState) {
|
|
this.roundState = roundState;
|
|
switch (roundState) {
|
|
case PLAYER_REGISTRATION, KILL_PHASE, SAFE_PHASE -> {
|
|
//Nothing
|
|
}
|
|
case COUNTDOWN -> {
|
|
setNonRegisteredPlayersToSpectator();
|
|
Set<UUID> players = roundService.getPlayers(PLAYER_STATE.REGISTERED);
|
|
Bukkit.getOnlinePlayers().stream()
|
|
.filter(player -> players.contains(player.getUniqueId()))
|
|
.forEach(player -> playerTeleporterService.teleportPlayer(player, DESTINATION.START_AREA));
|
|
}
|
|
case FINALE -> {
|
|
Set<UUID> players = roundService.getPlayers(PLAYER_STATE.REGISTERED);
|
|
Bukkit.getOnlinePlayers().stream()
|
|
.filter(player -> players.contains(player.getUniqueId()))
|
|
.forEach(player -> playerTeleporterService.teleportPlayer(player, DESTINATION.FINALE_AREA));
|
|
}
|
|
case ENDED -> {
|
|
roundService.clear();
|
|
Bukkit.getOnlinePlayers().forEach(player -> playerTeleporterService.teleportPlayer(player, DESTINATION.START_AREA));
|
|
}
|
|
}
|
|
}
|
|
|
|
private void setNonRegisteredPlayersToSpectator() {
|
|
Set<UUID> playerUUIDs = roundService.getPlayers(PLAYER_STATE.REGISTERED);
|
|
List<Player> playerList = new ArrayList<>(Bukkit.getOnlinePlayers());
|
|
List<Player> unregisteredPlayers = playerList.stream().filter(player -> !playerUUIDs.contains(player.getUniqueId())).toList();
|
|
unregisteredPlayers.forEach(player -> roundService.setPlayerState(player.getUniqueId(), PLAYER_STATE.SPECTATING));
|
|
}
|
|
|
|
public Optional<PLAYER_STATE> registerPlayer(Player player) {
|
|
if (roundState == null) {
|
|
return Optional.empty();
|
|
}
|
|
Optional<PLAYER_STATE> optionalPlayerState = determinePlayerState(player.getUniqueId());
|
|
if (optionalPlayerState.isEmpty()) {
|
|
return Optional.empty();
|
|
}
|
|
PLAYER_STATE playerState = optionalPlayerState.get();
|
|
|
|
if (playerState == PLAYER_STATE.SPECTATING) {
|
|
playerTeleporterService.teleportPlayer(player, DESTINATION.SPECTATOR_AREA);
|
|
}
|
|
|
|
roundService.setPlayerState(player.getUniqueId(), playerState);
|
|
return optionalPlayerState;
|
|
}
|
|
|
|
public void handleDisconnect(Player player) {
|
|
UUID uuid = player.getUniqueId();
|
|
roundService.setPlayerState(uuid, PLAYER_STATE.DISCONNECTED);
|
|
}
|
|
|
|
public void handleJoin(Player player) {
|
|
UUID uuid = player.getUniqueId();
|
|
Optional<PLAYER_STATE> state = roundService.getPlayerState(uuid);
|
|
if (state.isEmpty()) {
|
|
return;
|
|
}
|
|
if (state.get() != PLAYER_STATE.DISCONNECTED) {
|
|
return;
|
|
}
|
|
roundService.setPlayerState(uuid, PLAYER_STATE.SPECTATING);
|
|
player.sendRichMessage(Messages.RECONNECT.FORFEITED);
|
|
}
|
|
|
|
public void handlePlayerDeath(Player player) {
|
|
UUID uuid = player.getUniqueId();
|
|
roundService.setPlayerState(uuid, PLAYER_STATE.SPECTATING);
|
|
|
|
int remaining = roundService.getPlayers(PLAYER_STATE.REGISTERED).size();
|
|
Bukkit.broadcast(MiniMessage.miniMessage().deserialize(Messages.GAME.PLAYER_DEATH,
|
|
Placeholder.component("player", player.name()),
|
|
Placeholder.unparsed("remaining", String.valueOf(remaining))));
|
|
}
|
|
|
|
public void handlePlayerRespawn(Player player) {
|
|
roundService.getPlayerState(player.getUniqueId())
|
|
.filter(state -> state == PLAYER_STATE.SPECTATING)
|
|
.ifPresent(state -> playerTeleporterService.teleportPlayer(player, DESTINATION.SPECTATOR_AREA));
|
|
}
|
|
|
|
private Optional<PLAYER_STATE> determinePlayerState(UUID playerUuid) {
|
|
if (roundState == null) {
|
|
return Optional.empty();
|
|
}
|
|
Optional<PLAYER_STATE> optionalPlayerState = roundService.getPlayerState(playerUuid);
|
|
if (optionalPlayerState.isPresent()) {
|
|
PLAYER_STATE playerState = optionalPlayerState.get();
|
|
return Optional.of(switch (playerState) {
|
|
case DISCONNECTED, SPECTATING -> PLAYER_STATE.SPECTATING;
|
|
case REGISTERED -> PLAYER_STATE.REGISTERED;
|
|
});
|
|
}
|
|
return switch (roundState) {
|
|
case PLAYER_REGISTRATION, COUNTDOWN -> Optional.of(PLAYER_STATE.REGISTERED);
|
|
case KILL_PHASE, FINALE, ENDED, SAFE_PHASE -> Optional.of(PLAYER_STATE.SPECTATING);
|
|
};
|
|
}
|
|
}
|