Add support for list entries in sign templates.

This commit adds support for listing arena players on arena signs by
introducing the following _dynamic variables_:

- `<arena-n>` the _nth_ live arena player
- `<lobby-n>` the _nth_ player in the lobby
- `<ready-n>` the _nth_ ready player in the lobby
- `<notready-n>` the _nth_ player in the lobby who hasn't readied up

Each variable points to a list of players (sorted by name), and the `n`
is the index into that list (1-indexed). This means that putting the
variable `<notready-1>` in a template will result in the name of the
first player in the list of lobby players who haven't readied up, sorted
by player name.

Implements #592
This commit is contained in:
Bobcat00 2020-01-11 01:05:06 +01:00 committed by Andreas Troelsen
parent 8f9664670f
commit 6e8a3e1626

View File

@ -2,11 +2,25 @@ package com.garbagemule.MobArena.signs;
import static java.lang.String.valueOf;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import com.garbagemule.MobArena.framework.Arena;
import org.bukkit.ChatColor;
import org.bukkit.entity.Player;
class RendersTemplate {
// Regex Pattern for player list variables.
// Changes to the list types must also be made in getPlayerList.
// group(1) is the list type as a String.
// group(2) is player index+1 as a String.
private final Pattern playerListPattern = Pattern.compile("<(arena|lobby|ready|notready)-([1-9][0-9]?)>");
String[] render(Template template, Arena arena) {
String[] lines = getTemplateByState(template, arena);
@ -46,7 +60,8 @@ class RendersTemplate {
}
private String running(String line, Arena arena) {
return line
String result = replacePlayerListEntry(line, arena);
return result
.replace("<initial-players>", valueOf(arena.getPlayerCount()))
.replace("<live-players>", valueOf(arena.getPlayersInArena().size()))
.replace("<dead-players>", valueOf(arena.getPlayerCount() - arena.getPlayersInArena().size()))
@ -57,7 +72,8 @@ class RendersTemplate {
}
private String joining(String line, Arena arena) {
return line
String result = replacePlayerListEntry(line, arena);
return result
.replace("<initial-players>", valueOf(arena.getPlayersInLobby().size()))
.replace("<live-players>", valueOf(arena.getPlayersInLobby().size()))
.replace("<dead-players>", "-")
@ -66,6 +82,50 @@ class RendersTemplate {
.replace("<ready-players>", valueOf(arena.getReadyPlayersInLobby().size()));
}
private String replacePlayerListEntry(String line, Arena arena) {
Matcher matcher = playerListPattern.matcher(line);
if (!matcher.find()) {
return line;
}
List<String> list = getNameList(matcher.group(1), arena);
int index = Integer.parseInt(matcher.group(2)) - 1;
if (index < list.size()) {
String value = list.get(index);
return matcher.replaceFirst(value);
} else {
return matcher.replaceFirst("");
}
}
private List<String> getNameList(String name, Arena arena) {
return getPlayerList(name, arena)
.stream()
.map(Player::getName)
.sorted()
.collect(Collectors.toList());
}
private Collection<Player> getPlayerList(String name, Arena arena) {
switch (name) {
case "arena": {
return arena.getPlayersInArena();
}
case "lobby": {
return arena.getPlayersInLobby();
}
case "ready": {
return arena.getReadyPlayersInLobby();
}
case "notready": {
return arena.getNonreadyPlayers();
}
default: {
return Collections.emptyList();
}
}
}
private String truncate(String rendered) {
if (rendered.length() <= 15) {
return rendered;