mirror of
https://github.com/SunNetservers/MiniGames.git
synced 2025-01-31 08:49:34 +01:00
Implements #35
This commit is contained in:
parent
3a68d30044
commit
87788e60a3
42
README.md
42
README.md
@ -282,7 +282,9 @@ These are all the options that can be changed for an arena.
|
||||
- LIGHTNING_ROD
|
||||
- CHAIN
|
||||
|
||||
## Record placeholders
|
||||
## Placeholders
|
||||
|
||||
### Record Placeholders
|
||||
|
||||
Player records can be displayed on a leaderboard by using PlaceholderAPI. If you want to display a sign-based
|
||||
leaderboard, you can use the [Placeholder Signs](https://git.knarcraft.net/EpicKnarvik97/PlaceholderSigns) plugin. The
|
||||
@ -290,16 +292,34 @@ format for the built-in placeholders is as follows:
|
||||
|
||||
`%gameMode_record_recordType_gameModeType_identifierType_identifier_recordPosition_infoType%`
|
||||
|
||||
| Variable | Values | Description |
|
||||
|----------------|-----------------------------|------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| gameMode | dropper / parkour | A selection of which game-mode you are getting a record for |
|
||||
| record | | This must be as-is. It's a selector in case placeholders are added for more than records. |
|
||||
| recordType | deaths / time | Selects the type of record to get (deaths or time). |
|
||||
| gameModeType | default / inverted / random | Selects the game-mode to get the record for. |
|
||||
| identifierType | arena / group | The type of thing the following identifier points to (an arena or an arena group). |
|
||||
| identifier | ? | An identifier (the name or UUID) for an arena or a group (whichever was chosen as identifierType). |
|
||||
| recordPosition | 1 / 2 / 3 / ... | The position of the record to get (1 = first place, 2 = second place, etc.). |
|
||||
| infoType | player / value / combined | The type of info to get. Player gets the player name, Value gets the value of the achieved record. Combined gets "Player: Record". |
|
||||
| Variable | Values | Description |
|
||||
|----------------|----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| gameMode | dropper / parkour | A selection of which game-mode you are getting a record for |
|
||||
| record | | This must be as-is. It's a selector for the type of placeholder to get. |
|
||||
| recordType | deaths / time | Selects the type of record to get (deaths or time). |
|
||||
| gameModeType | default / inverted / random / hardcore | Selects the game-mode to get the record for. |
|
||||
| identifierType | arena / group | The type of thing the following identifier points to (an arena or an arena group). |
|
||||
| identifier | ? | An identifier (the name or UUID) for an arena or a group (whichever was chosen as identifierType). |
|
||||
| recordPosition | 1 / 2 / 3 / ... | The position of the record to get (1 = first place, 2 = second place, etc.). |
|
||||
| infoType | player / value / combined | The type of info to get. Player gets the player name, Value gets the value of the achieved record. Combined gets "Player: Record". |
|
||||
|
||||
### Player Placeholders
|
||||
|
||||
The number of currently playing players can be displayed using PlaceholderAPI. If you want to display a sign-based
|
||||
leaderboard, you can use the [Placeholder Signs](https://git.knarcraft.net/EpicKnarvik97/PlaceholderSigns) plugin. The
|
||||
format for the built-in placeholders is as follows:
|
||||
|
||||
`%gameMode_players_playing_gameModeType_identifierType_identifier_infoType_additionalSpecifier%`
|
||||
|
||||
| Variable | Values | Description |
|
||||
|-----------------|----------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| gameMode | dropper / parkour | A selection of which game-mode you are getting a record for |
|
||||
| players_playing | | This must be as-is. It's a selector in case placeholders are added for more than playing players. |
|
||||
| gameModeType | default / inverted / random / hardcore / all | Selects the game-mode to get the players for. Note that "all" combines players for all game-modes. |
|
||||
| identifierType | arena / group | The type of thing the following identifier points to (an arena or an arena group). |
|
||||
| identifier | ? | An identifier (the name or UUID) for an arena or a group (whichever was chosen as identifierType). |
|
||||
| playerInfoType | player / count | The type of info to get. Player gets the player name, and count gets the total number of players. |
|
||||
| playerNumber | 1 / 2 / 3 / ... | The player number to get the name of. Players are numbered after their sorted names. This argument is not used when getting the player count. |
|
||||
|
||||
## Notes about material tags
|
||||
|
||||
|
@ -70,8 +70,8 @@ import net.knarcraft.minigames.listener.MoveListener;
|
||||
import net.knarcraft.minigames.listener.PlayerStateChangeListener;
|
||||
import net.knarcraft.minigames.manager.EconomyManager;
|
||||
import net.knarcraft.minigames.manager.PermissionManager;
|
||||
import net.knarcraft.minigames.placeholder.DropperRecordExpansion;
|
||||
import net.knarcraft.minigames.placeholder.ParkourRecordExpansion;
|
||||
import net.knarcraft.minigames.placeholder.DropperExpansion;
|
||||
import net.knarcraft.minigames.placeholder.ParkourExpansion;
|
||||
import net.md_5.bungee.api.ChatColor;
|
||||
import net.milkbowl.vault.economy.Economy;
|
||||
import net.milkbowl.vault.permission.Permission;
|
||||
@ -102,8 +102,8 @@ public final class MiniGames extends JavaPlugin {
|
||||
private ParkourConfiguration parkourConfiguration;
|
||||
private DropperArenaHandler dropperArenaHandler;
|
||||
private ArenaPlayerRegistry<DropperArena> dropperArenaPlayerRegistry;
|
||||
private DropperRecordExpansion dropperRecordExpansion;
|
||||
private ParkourRecordExpansion parkourRecordExpansion;
|
||||
private DropperExpansion dropperExpansion;
|
||||
private ParkourExpansion parkourExpansion;
|
||||
private ParkourArenaHandler parkourArenaHandler;
|
||||
private ArenaPlayerRegistry<ParkourArena> parkourArenaPlayerRegistry;
|
||||
private PlayerVisibilityManager playerVisibilityManager;
|
||||
@ -253,8 +253,8 @@ public final class MiniGames extends JavaPlugin {
|
||||
this.parkourConfiguration.load(this.getConfig());
|
||||
|
||||
// Clear record caches
|
||||
this.dropperRecordExpansion.clearCaches();
|
||||
this.parkourRecordExpansion.clearCaches();
|
||||
this.dropperExpansion.clearCaches();
|
||||
this.parkourExpansion.clearCaches();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -316,12 +316,12 @@ public final class MiniGames extends JavaPlugin {
|
||||
*/
|
||||
private void doPluginIntegration() {
|
||||
if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) {
|
||||
this.dropperRecordExpansion = new DropperRecordExpansion(this);
|
||||
if (!this.dropperRecordExpansion.register()) {
|
||||
this.dropperExpansion = new DropperExpansion(this);
|
||||
if (!this.dropperExpansion.register()) {
|
||||
log(Level.WARNING, "Unable to register PlaceholderAPI dropper expansion!");
|
||||
}
|
||||
this.parkourRecordExpansion = new ParkourRecordExpansion(this);
|
||||
if (!this.parkourRecordExpansion.register()) {
|
||||
this.parkourExpansion = new ParkourExpansion(this);
|
||||
if (!this.parkourExpansion.register()) {
|
||||
log(Level.WARNING, "Unable to register PlaceholderAPI parkour expansion!");
|
||||
}
|
||||
}
|
||||
|
@ -52,4 +52,11 @@ public interface ArenaSession {
|
||||
*/
|
||||
void reset();
|
||||
|
||||
/**
|
||||
* Gets the game-mode the player is playing
|
||||
*
|
||||
* @return <p>The game-mode the player is playing</p>
|
||||
*/
|
||||
@NotNull ArenaGameMode getGameMode();
|
||||
|
||||
}
|
||||
|
@ -11,5 +11,5 @@ public class ParkourArenaPlayerRegistry extends AbstractArenaPlayerRegistry<Park
|
||||
protected String getEntryStateStorageKey() {
|
||||
return "parkour";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -123,6 +123,10 @@ public class ParkourArenaSession extends AbstractArenaSession {
|
||||
|
||||
// Teleport the player out of the arena
|
||||
teleportToExit(false);
|
||||
|
||||
if (MiniGames.getInstance().getParkourArenaPlayerRegistry().getPlayingPlayers(this.arena).isEmpty()) {
|
||||
resetLevers();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -0,0 +1,73 @@
|
||||
package net.knarcraft.minigames.placeholder;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArena;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaHandler;
|
||||
import net.knarcraft.minigames.placeholder.parsing.PlayerPlaceholderParser;
|
||||
import net.knarcraft.minigames.placeholder.parsing.RecordPlaceholderParser;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A placeholderAPI expansion for Dropper-related placeholders
|
||||
*/
|
||||
public class DropperExpansion extends PlaceholderExpansion {
|
||||
|
||||
private final @NotNull RecordPlaceholderParser recordPlaceholderParser;
|
||||
private final @NotNull PlayerPlaceholderParser<DropperArena> playerPlaceholderParser;
|
||||
|
||||
/**
|
||||
* Instantiates a new dropper expansion
|
||||
*
|
||||
* @param plugin <p>A reference to the mini-games plugin</p>
|
||||
*/
|
||||
public DropperExpansion(@NotNull MiniGames plugin) {
|
||||
DropperArenaHandler arenaHandler = plugin.getDropperArenaHandler();
|
||||
this.recordPlaceholderParser = new RecordPlaceholderParser(arenaHandler, DropperArenaGameMode::matchGameMode);
|
||||
this.playerPlaceholderParser = new PlayerPlaceholderParser<>(arenaHandler, DropperArenaGameMode::matchGameMode,
|
||||
plugin.getDropperArenaPlayerRegistry());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears record caches
|
||||
*/
|
||||
public void clearCaches() {
|
||||
this.recordPlaceholderParser.clearCaches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "dropper";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return "EpicKnarvik97";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return "1.0.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean persist() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onRequest(OfflinePlayer player, String parameters) {
|
||||
String[] parts = parameters.split("_");
|
||||
// Record is used as the prefix for all record placeholders in case more placeholder types are added
|
||||
if (parts[0].equalsIgnoreCase("record") && parts.length >= 7) {
|
||||
return recordPlaceholderParser.onRequest(parameters, parts);
|
||||
} else if (parts[0].equalsIgnoreCase("players")) {
|
||||
return this.playerPlaceholderParser.onRequest(parameters, parts);
|
||||
} else {
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package net.knarcraft.minigames.placeholder;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.ArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.dropper.DropperArenaGameMode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A placeholder expansion for dropper record placeholders
|
||||
*/
|
||||
public class DropperRecordExpansion extends RecordExpansion {
|
||||
|
||||
/**
|
||||
* Initializes a new record expansion
|
||||
*
|
||||
* @param plugin <p>A reference to the dropper plugin</p>
|
||||
*/
|
||||
public DropperRecordExpansion(MiniGames plugin) {
|
||||
super(plugin.getDropperArenaHandler());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "dropper";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull ArenaGameMode parseGameMode(@NotNull String gameMode) {
|
||||
return DropperArenaGameMode.matchGameMode(gameMode);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,73 @@
|
||||
package net.knarcraft.minigames.placeholder;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArena;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaHandler;
|
||||
import net.knarcraft.minigames.placeholder.parsing.PlayerPlaceholderParser;
|
||||
import net.knarcraft.minigames.placeholder.parsing.RecordPlaceholderParser;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A placeholderAPI expansion for Parkour-related placeholders
|
||||
*/
|
||||
public class ParkourExpansion extends PlaceholderExpansion {
|
||||
|
||||
private final @NotNull RecordPlaceholderParser recordPlaceholderParser;
|
||||
private final @NotNull PlayerPlaceholderParser<ParkourArena> playerPlaceholderParser;
|
||||
|
||||
/**
|
||||
* Instantiates a new dropper expansion
|
||||
*
|
||||
* @param plugin <p>A reference to the mini-games plugin</p>
|
||||
*/
|
||||
public ParkourExpansion(@NotNull MiniGames plugin) {
|
||||
ParkourArenaHandler arenaHandler = plugin.getParkourArenaHandler();
|
||||
this.recordPlaceholderParser = new RecordPlaceholderParser(arenaHandler, ParkourArenaGameMode::matchGamemode);
|
||||
this.playerPlaceholderParser = new PlayerPlaceholderParser<>(arenaHandler, ParkourArenaGameMode::matchGamemode,
|
||||
plugin.getParkourArenaPlayerRegistry());
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears record caches
|
||||
*/
|
||||
public void clearCaches() {
|
||||
this.recordPlaceholderParser.clearCaches();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "parkour";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return "EpicKnarvik97";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return "1.0.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean persist() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onRequest(OfflinePlayer player, String parameters) {
|
||||
String[] parts = parameters.split("_");
|
||||
// Record is used as the prefix for all record placeholders in case more placeholder types are added
|
||||
if (parts[0].equalsIgnoreCase("record") && parts.length >= 7) {
|
||||
return recordPlaceholderParser.onRequest(parameters, parts);
|
||||
} else if (parts[0].equalsIgnoreCase("players")) {
|
||||
return this.playerPlaceholderParser.onRequest(parameters, parts);
|
||||
} else {
|
||||
return parameters;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package net.knarcraft.minigames.placeholder;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.ArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.parkour.ParkourArenaGameMode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* A placeholder expansion for parkour record placeholders
|
||||
*/
|
||||
public class ParkourRecordExpansion extends RecordExpansion {
|
||||
|
||||
/**
|
||||
* Initializes a new record expansion
|
||||
*
|
||||
* @param plugin <p>A reference to the dropper plugin</p>
|
||||
*/
|
||||
public ParkourRecordExpansion(MiniGames plugin) {
|
||||
super(plugin.getParkourArenaHandler());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getIdentifier() {
|
||||
return "parkour";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected @NotNull ArenaGameMode parseGameMode(@NotNull String gameMode) {
|
||||
return ParkourArenaGameMode.matchGamemode(gameMode);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package net.knarcraft.minigames.placeholder.parsing;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* The types of player information that can be retrieved in placeholders
|
||||
*/
|
||||
public enum PlayerInfoType {
|
||||
|
||||
/**
|
||||
* The number of current players
|
||||
*/
|
||||
COUNT,
|
||||
|
||||
/**
|
||||
* Information about a single player
|
||||
*/
|
||||
PLAYER,
|
||||
;
|
||||
|
||||
/**
|
||||
* Gets the info type specified in the given string
|
||||
*
|
||||
* @param type <p>The string specifying the info type</p>
|
||||
* @return <p>The info type, or null if not found</p>
|
||||
*/
|
||||
public static @Nullable PlayerInfoType getFromString(@NotNull String type) {
|
||||
for (PlayerInfoType infoType : PlayerInfoType.values()) {
|
||||
if (infoType.name().equalsIgnoreCase(type)) {
|
||||
return infoType;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,271 @@
|
||||
package net.knarcraft.minigames.placeholder.parsing;
|
||||
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.Arena;
|
||||
import net.knarcraft.minigames.arena.ArenaGameMode;
|
||||
import net.knarcraft.minigames.arena.ArenaGroup;
|
||||
import net.knarcraft.minigames.arena.ArenaHandler;
|
||||
import net.knarcraft.minigames.arena.ArenaPlayerRegistry;
|
||||
import net.knarcraft.minigames.arena.ArenaSession;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* A parser for player-related placeholders
|
||||
*/
|
||||
public class PlayerPlaceholderParser<K extends Arena> {
|
||||
|
||||
private final @NotNull ArenaHandler<K, ?> arenaHandler;
|
||||
private final @NotNull Function<String, ArenaGameMode> gameModeParser;
|
||||
private final ArenaPlayerRegistry<K> playerRegistry;
|
||||
|
||||
/**
|
||||
* Initializes a new player placeholder parser
|
||||
*
|
||||
* @param arenaHandler <p>The arena handler to get arenas from</p>
|
||||
* @param gameModeParser <p>The function to use for parsing the specified game-mode</p>
|
||||
* @param playerRegistry <p>The player registry to get player info from</p>
|
||||
*/
|
||||
public PlayerPlaceholderParser(@NotNull ArenaHandler<K, ?> arenaHandler,
|
||||
@NotNull Function<String, ArenaGameMode> gameModeParser,
|
||||
ArenaPlayerRegistry<K> playerRegistry) {
|
||||
this.arenaHandler = arenaHandler;
|
||||
this.gameModeParser = gameModeParser;
|
||||
this.playerRegistry = playerRegistry;
|
||||
}
|
||||
|
||||
/**
|
||||
* The method to run when parsing a record placeholder request
|
||||
*
|
||||
* @param parameters <p>The parameters specified</p>
|
||||
* @return <p>The resulting string</p>
|
||||
*/
|
||||
@NotNull
|
||||
public String onRequest(@NotNull String parameters, @NotNull String[] parts) {
|
||||
if (parts.length < 6) {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
// String selector = parts[1]; // The selector for which aspect of players to get. Playing is the only one available yet.
|
||||
String gameModeName = parts[2];
|
||||
ArenaGameMode gameMode = gameModeParser.apply(gameModeName);
|
||||
if (gameModeName.equalsIgnoreCase("combined") || gameModeName.equalsIgnoreCase("all")) {
|
||||
gameMode = null;
|
||||
}
|
||||
|
||||
SelectionType selectionType = SelectionType.getFromString(parts[3]);
|
||||
String identifier = parts[4];
|
||||
|
||||
// The type of info to get. Either count (number of players) or player_position (a named player).
|
||||
PlayerInfoType infoType = PlayerInfoType.getFromString(parts[5]);
|
||||
if (infoType == null) {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
String info = null;
|
||||
if (selectionType == SelectionType.GROUP) {
|
||||
ArenaGroup<?, ?> group = arenaHandler.getGroup(identifier);
|
||||
if (group != null) {
|
||||
info = getGroupInfo(group, gameMode, infoType, parts);
|
||||
}
|
||||
} else if (selectionType == SelectionType.ARENA) {
|
||||
info = getArenaInfo(identifier, gameMode, infoType, parts);
|
||||
}
|
||||
|
||||
return Objects.requireNonNullElse(info, parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about an arena group's players
|
||||
*
|
||||
* @param group <p>The group to get info about</p>
|
||||
* @param gameMode <p>The game-mode to get information for</p>
|
||||
* @param infoType <p>The type of information to get</p>
|
||||
* @param parts <p>The placeholder arguments specified by a user</p>
|
||||
* @return <p>The specified group info, or null if the placeholder is invalid</p>
|
||||
*/
|
||||
@Nullable
|
||||
private String getGroupInfo(@NotNull ArenaGroup<?, ?> group, @Nullable ArenaGameMode gameMode,
|
||||
@NotNull PlayerInfoType infoType, @NotNull String[] parts) {
|
||||
List<UUID> arenaIds = group.getArenas();
|
||||
List<K> arenas = new ArrayList<>();
|
||||
for (UUID arenaId : arenaIds) {
|
||||
K arena = arenaHandler.getArena(arenaId);
|
||||
if (arena != null) {
|
||||
arenas.add(arena);
|
||||
}
|
||||
}
|
||||
|
||||
if (infoType == PlayerInfoType.COUNT) {
|
||||
int playerCount = 0;
|
||||
for (K arena : arenas) {
|
||||
playerCount += getArenaPlayers(arena, gameMode).size();
|
||||
}
|
||||
return String.valueOf(playerCount);
|
||||
} else if (infoType == PlayerInfoType.PLAYER) {
|
||||
if (parts.length < 7) {
|
||||
return null;
|
||||
}
|
||||
Integer playerNumber = getPositionNumber(parts[6]);
|
||||
|
||||
List<String> arenaPlayerNames = new ArrayList<>();
|
||||
for (K arena : arenas) {
|
||||
arenaPlayerNames.addAll(getArenaPlayersSorted(arena, gameMode));
|
||||
}
|
||||
arenaPlayerNames.sort(Comparator.naturalOrder());
|
||||
if (playerNumber != null) {
|
||||
if (playerNumber >= arenaPlayerNames.size()) {
|
||||
return "";
|
||||
} else {
|
||||
return arenaPlayerNames.get(playerNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets information about an arena's players
|
||||
*
|
||||
* @param arenaName <p>The name of the arena</p>
|
||||
* @param gameMode <p>The game-mode to get information for</p>
|
||||
* @param infoType <p>The type of information to get</p>
|
||||
* @param parts <p>The placeholder arguments specified by a user</p>
|
||||
* @return <p>The specified arena info, or null if the placeholder is invalid</p>
|
||||
*/
|
||||
@Nullable
|
||||
private String getArenaInfo(@NotNull String arenaName, @Nullable ArenaGameMode gameMode,
|
||||
@NotNull PlayerInfoType infoType, @NotNull String[] parts) {
|
||||
if (infoType == PlayerInfoType.COUNT) {
|
||||
Set<UUID> arenaPlayers = getArenaPlayers(arenaName, gameMode);
|
||||
if (arenaPlayers != null) {
|
||||
return String.valueOf(arenaPlayers.size());
|
||||
}
|
||||
} else if (infoType == PlayerInfoType.PLAYER) {
|
||||
if (parts.length < 7) {
|
||||
return null;
|
||||
}
|
||||
Integer playerNumber = getPositionNumber(parts[6]);
|
||||
List<String> players = getArenaPlayersSorted(arenaName, gameMode);
|
||||
if (playerNumber != null && players != null) {
|
||||
if (playerNumber >= players.size()) {
|
||||
return "";
|
||||
} else {
|
||||
return players.get(playerNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the position number from the given string
|
||||
*
|
||||
* @param positionNumber <p>The position number to parse</p>
|
||||
* @return <p>The position number, or null if not valid</p>
|
||||
*/
|
||||
@Nullable
|
||||
private Integer getPositionNumber(@NotNull String positionNumber) {
|
||||
try {
|
||||
return Integer.parseInt(positionNumber) - 1;
|
||||
} catch (NumberFormatException exception) {
|
||||
MiniGames.log(Level.WARNING, "Invalid placeholder given. " + positionNumber +
|
||||
" supplied instead of player number.");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets names of all players in an arena in sorted order
|
||||
*
|
||||
* @param arenaName <p>The name of the arena to get players from</p>
|
||||
* @param arenaGameMode <p>The game-mode to get players for</p>
|
||||
* @return <p>Player names in sorted order, or null if the arena name is invalid</p>
|
||||
*/
|
||||
@Nullable
|
||||
private List<String> getArenaPlayersSorted(@NotNull String arenaName, @Nullable ArenaGameMode arenaGameMode) {
|
||||
K arena = arenaHandler.getArena(arenaName);
|
||||
if (arena == null) {
|
||||
return null;
|
||||
}
|
||||
return getArenaPlayersSorted(arena, arenaGameMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets names of all players in an arena in sorted order
|
||||
*
|
||||
* @param arena <p>The arena to get players from</p>
|
||||
* @param arenaGameMode <p>The game-mode to get players for</p>
|
||||
* @return <p>Player names in sorted order, or null if the arena name is invalid</p>
|
||||
*/
|
||||
@NotNull
|
||||
private List<String> getArenaPlayersSorted(@NotNull K arena, @Nullable ArenaGameMode arenaGameMode) {
|
||||
Set<UUID> players = getArenaPlayers(arena, arenaGameMode);
|
||||
List<String> playerNames = new ArrayList<>(players.size());
|
||||
for (UUID playerId : players) {
|
||||
Player player = Bukkit.getPlayer(playerId);
|
||||
if (player != null) {
|
||||
playerNames.add(player.getName());
|
||||
}
|
||||
}
|
||||
playerNames.sort(Comparator.naturalOrder());
|
||||
return playerNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all players from the given arena
|
||||
*
|
||||
* @param arenaName <p>The name of the arena to get players from</p>
|
||||
* @param arenaGameMode <p>The game-mode to get players for</p>
|
||||
* @return <p>The players in the given arena playing the given game-mode</p>
|
||||
*/
|
||||
@Nullable
|
||||
private Set<UUID> getArenaPlayers(@NotNull String arenaName, @Nullable ArenaGameMode arenaGameMode) {
|
||||
K arena = arenaHandler.getArena(arenaName);
|
||||
if (arena == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getArenaPlayers(arena, arenaGameMode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all players from the given arena
|
||||
*
|
||||
* @param arena <p>The arena to get players from</p>
|
||||
* @param arenaGameMode <p>The game-mode to get players for</p>
|
||||
* @return <p>The players in the given arena playing the given game-mode</p>
|
||||
*/
|
||||
@NotNull
|
||||
private Set<UUID> getArenaPlayers(@NotNull K arena, @Nullable ArenaGameMode arenaGameMode) {
|
||||
// If getting count for any game-mode, skip filtering
|
||||
Set<UUID> players = playerRegistry.getPlayingPlayers(arena);
|
||||
if (arenaGameMode == null) {
|
||||
return players;
|
||||
}
|
||||
|
||||
Set<UUID> output = new HashSet<>();
|
||||
for (UUID playerId : players) {
|
||||
ArenaSession arenaSession = playerRegistry.getArenaSession(playerId);
|
||||
if (arenaSession == null || arenaSession.getGameMode() != arenaGameMode) {
|
||||
continue;
|
||||
}
|
||||
|
||||
output.add(playerId);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package net.knarcraft.minigames.placeholder;
|
||||
package net.knarcraft.minigames.placeholder.parsing;
|
||||
|
||||
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
|
||||
import net.knarcraft.minigames.MiniGames;
|
||||
import net.knarcraft.minigames.arena.Arena;
|
||||
import net.knarcraft.minigames.arena.ArenaGameMode;
|
||||
@ -8,12 +7,10 @@ import net.knarcraft.minigames.arena.ArenaGroup;
|
||||
import net.knarcraft.minigames.arena.ArenaHandler;
|
||||
import net.knarcraft.minigames.arena.ArenaRecordsRegistry;
|
||||
import net.knarcraft.minigames.arena.record.ArenaRecord;
|
||||
import net.knarcraft.minigames.placeholder.parsing.InfoType;
|
||||
import net.knarcraft.minigames.placeholder.parsing.SelectionType;
|
||||
import net.knarcraft.minigames.placeholder.GroupRecordCache;
|
||||
import net.knarcraft.minigames.property.RecordType;
|
||||
import net.knarcraft.minigames.util.GroupRecordHelper;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@ -26,51 +23,45 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* A placeholder expansion for parkour record placeholders
|
||||
* A parser for record-related placeholders
|
||||
*/
|
||||
public abstract class RecordExpansion extends PlaceholderExpansion {
|
||||
public class RecordPlaceholderParser {
|
||||
|
||||
private final ArenaHandler<?, ?> arenaHandler;
|
||||
private final Map<UUID, Set<GroupRecordCache<Integer>>> groupRecordDeathsCache;
|
||||
private final Map<UUID, Set<GroupRecordCache<Long>>> groupRecordTimeCache;
|
||||
private final @NotNull ArenaHandler<?, ?> arenaHandler;
|
||||
private final @NotNull Map<UUID, Set<GroupRecordCache<Integer>>> groupRecordDeathsCache;
|
||||
private final @NotNull Map<UUID, Set<GroupRecordCache<Long>>> groupRecordTimeCache;
|
||||
private final @NotNull Function<String, ArenaGameMode> gameModeParser;
|
||||
|
||||
/**
|
||||
* Initializes a new record expansion
|
||||
* Initializes a new record placeholder parser
|
||||
*/
|
||||
public RecordExpansion(ArenaHandler<?, ?> arenaHandler) {
|
||||
public RecordPlaceholderParser(@NotNull ArenaHandler<?, ?> arenaHandler,
|
||||
@NotNull Function<String, ArenaGameMode> gameModeParser) {
|
||||
this.groupRecordDeathsCache = new HashMap<>();
|
||||
this.groupRecordTimeCache = new HashMap<>();
|
||||
this.arenaHandler = arenaHandler;
|
||||
this.gameModeParser = gameModeParser;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return "EpicKnarvik97";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return "1.0.0";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean persist() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onRequest(OfflinePlayer player, String parameters) {
|
||||
String[] parts = parameters.split("_");
|
||||
// Record is used as the prefix for all record placeholders in case more placeholder types are added
|
||||
if (parts.length < 7 || !parts[0].equals("record")) {
|
||||
/**
|
||||
* The method to run when parsing a record placeholder request
|
||||
*
|
||||
* @param parameters <p>The parameters specified</p>
|
||||
* @return <p>The resulting string</p>
|
||||
*/
|
||||
@NotNull
|
||||
public String onRequest(@NotNull String parameters, @NotNull String[] parts) {
|
||||
if (parts.length < 7) {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
RecordType recordType = RecordType.getFromString(parts[1]);
|
||||
ArenaGameMode gameMode = parseGameMode(parts[2]);
|
||||
ArenaGameMode gameMode = gameModeParser.apply(parts[2]);
|
||||
SelectionType selectionType = SelectionType.getFromString(parts[3]);
|
||||
String identifier = parts[4];
|
||||
int recordNumber;
|
||||
@ -78,7 +69,7 @@ public abstract class RecordExpansion extends PlaceholderExpansion {
|
||||
recordNumber = Integer.parseInt(parts[5]) - 1;
|
||||
} catch (NumberFormatException exception) {
|
||||
MiniGames.log(Level.WARNING, "Invalid placeholder given. " + parts[5] +
|
||||
" supplied instead of record placement.");
|
||||
" supplied instead of record position.");
|
||||
return parameters;
|
||||
}
|
||||
InfoType infoType = InfoType.getFromString(parts[6]);
|
||||
@ -97,14 +88,6 @@ public abstract class RecordExpansion extends PlaceholderExpansion {
|
||||
return Objects.requireNonNullElse(info, parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the game-mode specified in the given string
|
||||
*
|
||||
* @param gameMode <p>The game-mode to parse</p>
|
||||
* @return <p>The parsed game-mode</p>
|
||||
*/
|
||||
protected abstract @NotNull ArenaGameMode parseGameMode(@NotNull String gameMode);
|
||||
|
||||
/**
|
||||
* Clears all record caches
|
||||
*/
|
||||
@ -124,9 +107,10 @@ public abstract class RecordExpansion extends PlaceholderExpansion {
|
||||
* @param infoType <p>The type of info (player, value, combined) to get</p>
|
||||
* @return <p>The selected information about the record, or null if not found</p>
|
||||
*/
|
||||
private @Nullable String getGroupRecord(@NotNull ArenaHandler<?, ?> arenaHandler, @NotNull String identifier,
|
||||
@NotNull ArenaGameMode gameMode, @NotNull RecordType recordType,
|
||||
int recordNumber, @NotNull InfoType infoType) {
|
||||
@Nullable
|
||||
private String getGroupRecord(@NotNull ArenaHandler<?, ?> arenaHandler, @NotNull String identifier,
|
||||
@NotNull ArenaGameMode gameMode, @NotNull RecordType recordType,
|
||||
int recordNumber, @NotNull InfoType infoType) {
|
||||
// Allow specifying the group UUID or the arena name
|
||||
ArenaGroup<?, ?> group;
|
||||
try {
|
||||
@ -162,9 +146,10 @@ public abstract class RecordExpansion extends PlaceholderExpansion {
|
||||
* @param arenaHandler <p>The handler to get arenas from</p>
|
||||
* @return <p>The record, or null if not found</p>
|
||||
*/
|
||||
private @Nullable ArenaRecord<?> getGroupTimeRecord(@NotNull ArenaGroup<?, ?> group,
|
||||
@NotNull ArenaGameMode gameMode, int recordNumber,
|
||||
@NotNull ArenaHandler<?, ?> arenaHandler) {
|
||||
@Nullable
|
||||
private ArenaRecord<?> getGroupTimeRecord(@NotNull ArenaGroup<?, ?> group,
|
||||
@NotNull ArenaGameMode gameMode, int recordNumber,
|
||||
@NotNull ArenaHandler<?, ?> arenaHandler) {
|
||||
return getCachedGroupRecord(group, gameMode, RecordType.TIME, recordNumber, groupRecordTimeCache,
|
||||
() -> GroupRecordHelper.getCombinedTime(group, gameMode, arenaHandler));
|
||||
}
|
||||
@ -178,9 +163,10 @@ public abstract class RecordExpansion extends PlaceholderExpansion {
|
||||
* @param arenaHandler <p>The handler to get arenas from</p>
|
||||
* @return <p>The record, or null if not found</p>
|
||||
*/
|
||||
private @Nullable ArenaRecord<?> getGroupDeathRecord(@NotNull ArenaGroup<?, ?> group,
|
||||
@NotNull ArenaGameMode gameMode, int recordNumber,
|
||||
@NotNull ArenaHandler<?, ?> arenaHandler) {
|
||||
@Nullable
|
||||
private ArenaRecord<?> getGroupDeathRecord(@NotNull ArenaGroup<?, ?> group,
|
||||
@NotNull ArenaGameMode gameMode, int recordNumber,
|
||||
@NotNull ArenaHandler<?, ?> arenaHandler) {
|
||||
return getCachedGroupRecord(group, gameMode, RecordType.DEATHS, recordNumber, groupRecordDeathsCache,
|
||||
() -> GroupRecordHelper.getCombinedDeaths(group, gameMode, arenaHandler));
|
||||
}
|
||||
@ -197,12 +183,13 @@ public abstract class RecordExpansion extends PlaceholderExpansion {
|
||||
* @param <K> <p>The type of the provided records</p>
|
||||
* @return <p>The specified record, or null if not found</p>
|
||||
*/
|
||||
private <K extends Comparable<K>> @Nullable ArenaRecord<?> getCachedGroupRecord(@NotNull ArenaGroup<?, ?> group,
|
||||
@NotNull ArenaGameMode gameMode,
|
||||
@NotNull RecordType recordType,
|
||||
int recordNumber,
|
||||
@NotNull Map<UUID, Set<GroupRecordCache<K>>> caches,
|
||||
@NotNull Supplier<Set<ArenaRecord<K>>> recordProvider) {
|
||||
@Nullable
|
||||
private <K extends Comparable<K>> ArenaRecord<?> getCachedGroupRecord(@NotNull ArenaGroup<?, ?> group,
|
||||
@NotNull ArenaGameMode gameMode,
|
||||
@NotNull RecordType recordType,
|
||||
int recordNumber,
|
||||
@NotNull Map<UUID, Set<GroupRecordCache<K>>> caches,
|
||||
@NotNull Supplier<Set<ArenaRecord<K>>> recordProvider) {
|
||||
UUID groupId = group.getGroupId();
|
||||
if (!caches.containsKey(groupId)) {
|
||||
caches.put(groupId, new HashSet<>());
|
||||
@ -244,9 +231,10 @@ public abstract class RecordExpansion extends PlaceholderExpansion {
|
||||
* @param infoType <p>The type of info (player, value, combined) to get</p>
|
||||
* @return <p>The selected information about the record, or null if not found</p>
|
||||
*/
|
||||
private @Nullable String getArenaRecord(@NotNull ArenaHandler<?, ?> arenaHandler, @NotNull String identifier,
|
||||
@NotNull ArenaGameMode gameMode, @NotNull RecordType recordType,
|
||||
int recordNumber, @NotNull InfoType infoType) {
|
||||
@Nullable
|
||||
private String getArenaRecord(@NotNull ArenaHandler<?, ?> arenaHandler, @NotNull String identifier,
|
||||
@NotNull ArenaGameMode gameMode, @NotNull RecordType recordType,
|
||||
int recordNumber, @NotNull InfoType infoType) {
|
||||
// Allow specifying the arena UUID or the arena name
|
||||
Arena arena;
|
||||
try {
|
||||
@ -278,8 +266,9 @@ public abstract class RecordExpansion extends PlaceholderExpansion {
|
||||
* @param recordNumber <p>The position of the record to get (1st place, 2nd place, etc.)</p>
|
||||
* @return <p>The record, or null if not found</p>
|
||||
*/
|
||||
private @Nullable ArenaRecord<?> getRecord(@NotNull ArenaRecordsRegistry recordsRegistry,
|
||||
@NotNull RecordType recordType, int recordNumber) {
|
||||
@Nullable
|
||||
private ArenaRecord<?> getRecord(@NotNull ArenaRecordsRegistry recordsRegistry,
|
||||
@NotNull RecordType recordType, int recordNumber) {
|
||||
return switch (recordType) {
|
||||
case TIME -> getRecord(new HashSet<>(recordsRegistry.getShortestTimeMilliSecondsRecords()), recordNumber);
|
||||
case DEATHS -> getRecord(new HashSet<>(recordsRegistry.getLeastDeathsRecords()), recordNumber);
|
||||
@ -294,7 +283,8 @@ public abstract class RecordExpansion extends PlaceholderExpansion {
|
||||
* @param <K> <p>The type of record in the record list</p>
|
||||
* @return <p>The record, or null if index is out of bounds</p>
|
||||
*/
|
||||
private <K extends Comparable<K>> @Nullable ArenaRecord<K> getRecord(Set<ArenaRecord<K>> records, int index) {
|
||||
@Nullable
|
||||
private <K extends Comparable<K>> ArenaRecord<K> getRecord(@NotNull Set<ArenaRecord<K>> records, int index) {
|
||||
List<ArenaRecord<K>> sorted = getSortedRecords(records);
|
||||
if (index < sorted.size() && index >= 0) {
|
||||
return sorted.get(index);
|
||||
@ -310,6 +300,7 @@ public abstract class RecordExpansion extends PlaceholderExpansion {
|
||||
* @param arenaRecord <p>The record to get the data from</p>
|
||||
* @return <p>The requested data as a string, or null</p>
|
||||
*/
|
||||
@Nullable
|
||||
private String getRecordData(@NotNull InfoType infoType, @NotNull ArenaRecord<?> arenaRecord) {
|
||||
return switch (infoType) {
|
||||
case PLAYER -> getPlayerName(arenaRecord.getUserId());
|
||||
@ -325,8 +316,8 @@ public abstract class RecordExpansion extends PlaceholderExpansion {
|
||||
* @param <K> <p>The type of the records</p>
|
||||
* @return <p>The sorted records</p>
|
||||
*/
|
||||
private <K extends Comparable<K>> @NotNull List<ArenaRecord<K>> getSortedRecords(
|
||||
@NotNull Set<ArenaRecord<K>> recordSet) {
|
||||
@NotNull
|
||||
private <K extends Comparable<K>> List<ArenaRecord<K>> getSortedRecords(@NotNull Set<ArenaRecord<K>> recordSet) {
|
||||
List<ArenaRecord<K>> records = new ArrayList<>(recordSet);
|
||||
Collections.sort(records);
|
||||
return records;
|
||||
@ -338,6 +329,7 @@ public abstract class RecordExpansion extends PlaceholderExpansion {
|
||||
* @param playerId <p>The id of the player to get the name for</p>
|
||||
* @return <p>The name of the player, or a string representation of the UUID if not found</p>
|
||||
*/
|
||||
@Nullable
|
||||
private String getPlayerName(@NotNull UUID playerId) {
|
||||
return Bukkit.getOfflinePlayer(playerId).getName();
|
||||
}
|
@ -7,6 +7,8 @@ description: A plugin that adds various mini-games
|
||||
softdepend:
|
||||
- PlaceholderAPI
|
||||
- Vault
|
||||
- Geyser-Spigot
|
||||
- floodgate
|
||||
|
||||
# Note to self: Aliases must be lowercase!
|
||||
commands:
|
||||
|
Loading…
x
Reference in New Issue
Block a user