mirror of
https://github.com/WiIIiam278/Velocitab.git
synced 2025-03-13 13:30:01 +01:00
1.7.3 - Placeholders Replacements & 1.21.4 (#236)
* Added PlaceholderReplacements * Removed server display names * Fixed disconnect problem * Added support for 1.21.4
This commit is contained in:
parent
2ba208002a
commit
24c29e632f
@ -165,7 +165,7 @@ tasks {
|
||||
velocityVersion("${velocity_api_version}-SNAPSHOT")
|
||||
|
||||
downloadPlugins {
|
||||
modrinth ("papiproxybridge", papi)
|
||||
github ("WiIIiam278", "PAPIProxyBridge", "1.7.1", "PAPIProxyBridge-Velocity-1.7.1.jar")
|
||||
modrinth ("miniplaceholders", "2.2.4")
|
||||
}
|
||||
}
|
||||
|
@ -28,10 +28,6 @@ fallback_enabled: true
|
||||
fallback_group: default
|
||||
# Whether to show all players from all groups in the TAB list.
|
||||
show_all_players_from_all_groups: false
|
||||
# Define custom names to be shown in the TAB list for specific server names.
|
||||
# If no custom display name is provided for a server, its original name will be used.
|
||||
server_display_names:
|
||||
very-long-server-name: VLSN
|
||||
# Whether to enable the PAPIProxyBridge hook for PAPI support
|
||||
enable_papi_hook: true
|
||||
# How long in seconds to cache PAPI placeholders for, in milliseconds. (0 to disable)
|
||||
@ -101,6 +97,14 @@ groups:
|
||||
sorting_placeholders:
|
||||
- '%role_weight%'
|
||||
- '%username_lower%'
|
||||
placeholder_replaments:
|
||||
'%current_date_weekday_en-US%':
|
||||
- placeholder: Monday
|
||||
replacement: <red>Monday</red>
|
||||
- placeholder: Tuesday
|
||||
replacement: <gold>Tuesday</gold>
|
||||
- placeholder: Else
|
||||
replacement: <green>Other day</green>
|
||||
collisions: false
|
||||
header_footer_update_rate: 1000
|
||||
placeholder_update_rate: 1000
|
||||
@ -127,3 +131,6 @@ You can use various placeholders that will be replaced with values (for example,
|
||||
|
||||
### Server Links
|
||||
For Minecraft 1.21+ clients, Velocitab supports specifying a list of URLs that will be sent to display in the player pause menu. See [[Server Links]] for more information.
|
||||
|
||||
### Placeholder Replaments
|
||||
Velocitab supports replacing values of placeholders with other values. See [[Placeholders Replaments]] for more information.
|
88
docs/Placeholders-Replaments.md
Normal file
88
docs/Placeholders-Replaments.md
Normal file
@ -0,0 +1,88 @@
|
||||
|
||||
Velocitab supports placeholder replacements, which allow you to replace a placeholder with a different value. This is useful for things like changing the text of a date placeholder to a localized version, changing the text of a biome placeholder to a color or you can use a vanish placeholder to show a player's vanish status if the placeholder returns just a boolean (true/false).
|
||||
|
||||
|
||||
## Configuring
|
||||
|
||||
Placeholder replacements are configured in the `placeholder_replaments` section of the every Tab Group.
|
||||
You can specify a list of replacements for a placeholder, and the replacements will be applied in the order they are listed.
|
||||
|
||||
The replacements are specified as a list of objects with two properties: `placeholder` and `replacement`.
|
||||
`placeholder` is the placeholder to replace, and `replacement` is the replacement text.
|
||||
|
||||
### Example section
|
||||
```yaml
|
||||
placeholder_replaments:
|
||||
'%current_date_weekday_en-US%':
|
||||
- placeholder: Monday
|
||||
replacement: <red>Monday</red>
|
||||
- placeholder: Tuesday
|
||||
replacement: <gold>Tuesday</gold>
|
||||
- placeholder: Else
|
||||
replacement: <green>Other day</green>
|
||||
'%player_world_type%':
|
||||
- placeholder: Overworld
|
||||
replacement: '<aqua>Overworld</aqua>'
|
||||
- placeholder: Nether
|
||||
replacement: '<red>Nether</red>'
|
||||
- placeholder: End
|
||||
replacement: '<yellow>End</yellow>'
|
||||
'%player_biome%':
|
||||
- placeholder: PLAINS
|
||||
replacement: <red>Plains</red>
|
||||
- placeholder: DESERT
|
||||
replacement: <yellow>Desert</yellow>
|
||||
- placeholder: RIVER
|
||||
replacement: <aqua>River</aqua>
|
||||
```
|
||||
|
||||
## Specified cases
|
||||
|
||||
### Vanish status
|
||||
If you want to show a player's vanish status, for example, you can use the `%advancedvanish_is_vanished%` placeholder.
|
||||
This placeholder returns a boolean value, so you can use it to show a player's vanish status.
|
||||
|
||||
For example, if you wanted to show a player's vanish status as a color, you could use the following replacements:
|
||||
```yaml
|
||||
placeholder_replaments:
|
||||
'%advancedvanish_is_vanished%':
|
||||
- placeholder: Yes
|
||||
replacement: <red>Vanished</red>
|
||||
- placeholder: No
|
||||
replacement: <green>Not vanished</green>
|
||||
```
|
||||
|
||||
### Else clause
|
||||
If you don't want to specify every possible value for a placeholder, you can use the `ELSE` placeholder.
|
||||
This placeholder will be replaced with the replacement text of the first replacement that doesn't have a placeholder.
|
||||
|
||||
For example, if you wanted to show the current date as a color, you could use the following replacements:
|
||||
```yaml
|
||||
placeholder_replaments:
|
||||
'%current_date_weekday_en-US%':
|
||||
- placeholder: Monday
|
||||
replacement: <red>Monday</red>
|
||||
- placeholder: Tuesday
|
||||
replacement: <gold>Tuesday</gold>
|
||||
- placeholder: ELSE
|
||||
replacement: <green>Other day</green>
|
||||
```
|
||||
|
||||
### Placeholder not present in a server
|
||||
If you have a group with multiple servers, and you have a placeholder that is not present in one of the servers, you can use the `%<placeholder>%` as a placeholder it will handle the case where the placeholder is not present in the server.
|
||||
|
||||
```yaml
|
||||
placeholder_replaments:
|
||||
'%huskhomes_homes_count%':
|
||||
- placeholder: '%huskhomes_homes_count%'
|
||||
replacement: <red>No homes in this server</red>
|
||||
```
|
||||
|
||||
If you want you can also set the replacement as an empty string, which will be replaced with the empty string.
|
||||
|
||||
```yaml
|
||||
placeholder_replaments:
|
||||
'%huskhomes_homes_count%':
|
||||
- placeholder: '%huskhomes_homes_count%'
|
||||
replacement: ''
|
||||
```
|
@ -3,7 +3,7 @@ javaVersion=17
|
||||
org.gradle.jvmargs='-Dfile.encoding=UTF-8'
|
||||
org.gradle.daemon=true
|
||||
|
||||
plugin_version=1.7.2
|
||||
plugin_version=1.7.3
|
||||
plugin_archive=velocitab
|
||||
plugin_description=A beautiful and versatile TAB list plugin for Velocity proxies
|
||||
|
||||
|
@ -31,6 +31,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.slf4j.event.Level;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@ -46,6 +47,7 @@ public record Group(
|
||||
Nametag nametag,
|
||||
Set<String> servers,
|
||||
List<String> sortingPlaceholders,
|
||||
Map<String, List<PlaceholderReplacement>> placeholderReplaments,
|
||||
boolean collisions,
|
||||
int headerFooterUpdateRate,
|
||||
int placeholderUpdateRate,
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
package net.william278.velocitab.config;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.velocitypowered.api.proxy.ServerConnection;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import it.unimi.dsi.fastutil.Pair;
|
||||
@ -36,8 +38,7 @@ import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.time.format.FormatStyle;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.regex.Matcher;
|
||||
@ -95,7 +96,7 @@ public enum Placeholder {
|
||||
}),
|
||||
USERNAME((plugin, player) -> player.getCustomName().orElse(player.getPlayer().getUsername())),
|
||||
USERNAME_LOWER((plugin, player) -> player.getCustomName().orElse(player.getPlayer().getUsername()).toLowerCase()),
|
||||
SERVER((plugin, player) -> player.getServerDisplayName(plugin)),
|
||||
SERVER((plugin, player) -> player.getServerName()),
|
||||
PING((plugin, player) -> Long.toString(player.getPlayer().getPing())),
|
||||
PREFIX((plugin, player) -> player.getRole().getPrefix()
|
||||
.orElse(getPlaceholderFallback(plugin, "%luckperms_prefix%"))),
|
||||
@ -126,6 +127,9 @@ public enum Placeholder {
|
||||
"*LESS*", "*LESS2*",
|
||||
"*GREATER*", "*GREATER2*"
|
||||
);
|
||||
private final static String VEL_PLACEHOLDER = "<vel";
|
||||
private final static String VELOCITAB_PLACEHOLDER = "<velocitab_rel";
|
||||
private final static String ELSE_PLACEHOLDER = "ELSE";
|
||||
|
||||
/**
|
||||
* Function to replace placeholders with a real value
|
||||
@ -162,17 +166,13 @@ public enum Placeholder {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String replaceInternal(@NotNull String format, @NotNull Velocitab plugin, @Nullable TabPlayer player) {
|
||||
final Pair<Boolean, String> result = processRelationalPlaceholders(format, plugin);
|
||||
format = result.right();
|
||||
format = replacePlaceholders(format, plugin, player);
|
||||
|
||||
return format;
|
||||
public static Pair<String, Map<String, String>> replaceInternal(@NotNull String format, @NotNull Velocitab plugin, @Nullable TabPlayer player) {
|
||||
format = processRelationalPlaceholders(format, plugin);
|
||||
return replacePlaceholders(format, plugin, player);
|
||||
}
|
||||
|
||||
private static Pair<Boolean, String> processRelationalPlaceholders(@NotNull String format, @NotNull Velocitab plugin) {
|
||||
boolean foundRelational = false;
|
||||
if (plugin.getFormatter().equals(Formatter.MINIMESSAGE) && format.contains("<vel")) {
|
||||
private static String processRelationalPlaceholders(@NotNull String format, @NotNull Velocitab plugin) {
|
||||
if (plugin.getFormatter().equals(Formatter.MINIMESSAGE) && format.contains(VEL_PLACEHOLDER)) {
|
||||
final Matcher conditionReplacer = CONDITION_REPLACER.matcher(format);
|
||||
while (conditionReplacer.find()) {
|
||||
|
||||
@ -189,7 +189,7 @@ public enum Placeholder {
|
||||
|
||||
final Matcher testMatcher = TEST.matcher(format);
|
||||
while (testMatcher.find()) {
|
||||
if (testMatcher.group().startsWith("<velocitab_rel")) {
|
||||
if (testMatcher.group().startsWith(VELOCITAB_PLACEHOLDER)) {
|
||||
final Matcher second = TEST.matcher(testMatcher.group().substring(1));
|
||||
while (second.find()) {
|
||||
String s = second.group();
|
||||
@ -209,7 +209,6 @@ public enum Placeholder {
|
||||
|
||||
final Matcher velocitabRelationalMatcher = VELOCITAB_PATTERN.matcher(format);
|
||||
while (velocitabRelationalMatcher.find()) {
|
||||
foundRelational = true;
|
||||
final String relationalPlaceholder = velocitabRelationalMatcher.group().substring(1, velocitabRelationalMatcher.group().length() - 1);
|
||||
String fixedString = relationalPlaceholder;
|
||||
for (Map.Entry<String, String> entry : SYMBOL_SUBSTITUTES_2.entrySet()) {
|
||||
@ -223,25 +222,58 @@ public enum Placeholder {
|
||||
}
|
||||
|
||||
}
|
||||
return Pair.of(foundRelational, format);
|
||||
return format;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String replacePlaceholders(@NotNull String format, @NotNull Velocitab plugin, @Nullable TabPlayer player) {
|
||||
private static Pair<String, Map<String, String>> replacePlaceholders(@NotNull String format, @NotNull Velocitab plugin,
|
||||
@Nullable TabPlayer player) {
|
||||
final Map<String, String> replacedPlaceholders = Maps.newHashMap();
|
||||
for (Placeholder placeholder : values()) {
|
||||
Matcher matcher = placeholder.pattern.matcher(format);
|
||||
final Matcher matcher = placeholder.pattern.matcher(format);
|
||||
if (placeholder.parameterised) {
|
||||
format = matcher.replaceAll(matchResult ->
|
||||
Matcher.quoteReplacement(
|
||||
placeholder.replacer.apply(StringUtils.chop(matchResult.group().replace("%" + placeholder.name().toLowerCase(), "")
|
||||
.replaceFirst("_", ""))
|
||||
, plugin, player)
|
||||
));
|
||||
format = matcher.replaceAll(matchResult -> {
|
||||
final String replacement = placeholder.replacer.apply(StringUtils.chop(matchResult.group().replace("%" + placeholder.name().toLowerCase(), "")
|
||||
.replaceFirst("_", "")), plugin, player);
|
||||
replacedPlaceholders.put(matchResult.group(), replacement);
|
||||
return Matcher.quoteReplacement(replacement);
|
||||
});
|
||||
} else {
|
||||
format = matcher.replaceAll(matchResult -> Matcher.quoteReplacement(placeholder.replacer.apply(null, plugin, player)));
|
||||
format = matcher.replaceAll(matchResult -> {
|
||||
final String replacement = placeholder.replacer.apply(null, plugin, player);
|
||||
replacedPlaceholders.put(matchResult.group(), replacement);
|
||||
return Matcher.quoteReplacement(replacement);
|
||||
});
|
||||
}
|
||||
}
|
||||
return format;
|
||||
return Pair.of(format, replacedPlaceholders);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String applyPlaceholderReplacements(@NotNull String text, @NotNull TabPlayer player,
|
||||
@NotNull Map<String, String> parsed) {
|
||||
for (final Map.Entry<String, List<PlaceholderReplacement>> entry : player.getGroup().placeholderReplaments().entrySet()) {
|
||||
if (!parsed.containsKey(entry.getKey())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final String replaced = parsed.get(entry.getKey());
|
||||
final Optional<PlaceholderReplacement> replacement = entry.getValue().stream()
|
||||
.filter(r -> r.placeholder().equalsIgnoreCase(replaced))
|
||||
.findFirst();
|
||||
|
||||
if (replacement.isPresent()) {
|
||||
text = text.replace(entry.getKey(), replacement.get().replacement());
|
||||
} else {
|
||||
final Optional<PlaceholderReplacement> elseReplacement = entry.getValue().stream()
|
||||
.filter(r -> r.placeholder().equalsIgnoreCase(ELSE_PLACEHOLDER))
|
||||
.findFirst();
|
||||
if (elseReplacement.isPresent()) {
|
||||
text = text.replace(entry.getKey(), elseReplacement.get().replacement());
|
||||
}
|
||||
}
|
||||
}
|
||||
return applyPlaceholders(text, parsed);
|
||||
}
|
||||
|
||||
public static CompletableFuture<String> replace(@NotNull String format, @NotNull Velocitab plugin,
|
||||
@ -251,22 +283,47 @@ public enum Placeholder {
|
||||
return CompletableFuture.completedFuture("");
|
||||
}
|
||||
|
||||
final String replaced = replaceInternal(format, plugin, player);
|
||||
|
||||
if (!PLACEHOLDER_PATTERN.matcher(replaced).find()) {
|
||||
return CompletableFuture.completedFuture(replaced);
|
||||
final Pair<String, Map<String, String>> replaced = replaceInternal(format, plugin, player);
|
||||
if (!PLACEHOLDER_PATTERN.matcher(replaced.first()).find()) {
|
||||
return CompletableFuture.completedFuture(replaced.first());
|
||||
}
|
||||
|
||||
final List<String> placeholders = extractPlaceholders(replaced.first());
|
||||
return plugin.getPAPIProxyBridgeHook()
|
||||
.map(hook -> hook.formatPlaceholders(replaced, player.getPlayer())
|
||||
.map(hook -> hook.parsePlaceholders(placeholders, player.getPlayer())
|
||||
.exceptionally(e -> {
|
||||
plugin.log(Level.ERROR, "An error occurred whilst parsing placeholders: " + e.getMessage());
|
||||
return replaced;
|
||||
return Map.of();
|
||||
})
|
||||
)
|
||||
.orElse(CompletableFuture.completedFuture(replaced)).exceptionally(e -> {
|
||||
.orElse(CompletableFuture.completedFuture(Maps.newHashMap())).exceptionally(e -> {
|
||||
plugin.log(Level.ERROR, "An error occurred whilst parsing placeholders: " + e.getMessage());
|
||||
return replaced;
|
||||
});
|
||||
return Map.of();
|
||||
})
|
||||
.thenApply(m -> applyPlaceholderReplacements(format, player, mergeMaps(m, replaced.second())));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String applyPlaceholders(@NotNull String text, @NotNull Map<String, String> replacements) {
|
||||
for (Map.Entry<String, String> entry : replacements.entrySet()) {
|
||||
text = text.replace(entry.getKey(), entry.getValue());
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Map<String, String> mergeMaps(@NotNull Map<String, String> map1, @NotNull Map<String, String> map2) {
|
||||
map1.putAll(map2);
|
||||
return map1;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<String> extractPlaceholders(@NotNull String text) {
|
||||
final List<String> placeholders = Lists.newArrayList();
|
||||
final Matcher matcher = PLACEHOLDER_PATTERN.matcher(text);
|
||||
while (matcher.find()) {
|
||||
placeholders.add(matcher.group());
|
||||
}
|
||||
return placeholders;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* This file is part of Velocitab, licensed under the Apache License 2.0.
|
||||
*
|
||||
* Copyright (c) William278 <will27528@gmail.com>
|
||||
* Copyright (c) contributors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package net.william278.velocitab.config;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record PlaceholderReplacement(@NotNull String placeholder, @NotNull String replacement) {
|
||||
}
|
@ -67,10 +67,6 @@ public class Settings implements ConfigValidator {
|
||||
@Comment("Whether to show all players from all groups in the TAB list.")
|
||||
private boolean showAllPlayersFromAllGroups = false;
|
||||
|
||||
@Comment("Define custom names to be shown in the TAB list for specific server names."
|
||||
+ "\nIf no custom display name is provided for a server, its original name will be used.")
|
||||
private Map<String, String> serverDisplayNames = Map.of("very-long-server-name", "VLSN");
|
||||
|
||||
@Comment("Whether to enable the PAPIProxyBridge hook for PAPI support")
|
||||
private boolean enablePapiHook = true;
|
||||
|
||||
@ -112,17 +108,6 @@ public class Settings implements ConfigValidator {
|
||||
)
|
||||
);
|
||||
|
||||
/**
|
||||
* Get display name for the server
|
||||
*
|
||||
* @param serverName The server name
|
||||
* @return The display name, or the server name if no display name is defined
|
||||
*/
|
||||
@NotNull
|
||||
public String getServerDisplayName(@NotNull String serverName) {
|
||||
return serverDisplayNames.getOrDefault(serverName, serverName);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<ServerUrl> getUrlsForGroup(@NotNull Group group) {
|
||||
return serverLinks.stream()
|
||||
|
@ -54,6 +54,13 @@ public class TabGroups implements ConfigValidator {
|
||||
new Nametag("", ""),
|
||||
Set.of("lobby", "survival", "creative", "minigames", "skyblock", "prison", "hub"),
|
||||
List.of("%role_weight%", "%username_lower%"),
|
||||
new LinkedHashMap<>() {{
|
||||
put("%current_date_weekday_en-US%", List.of(
|
||||
new PlaceholderReplacement("Monday", "<red>Monday</red>"),
|
||||
new PlaceholderReplacement("Tuesday", "<gold>Tuesday</gold>"),
|
||||
new PlaceholderReplacement("Else", "<green>Other day</green>")
|
||||
));
|
||||
}},
|
||||
false,
|
||||
1000,
|
||||
1000,
|
||||
@ -140,6 +147,10 @@ public class TabGroups implements ConfigValidator {
|
||||
if (group.sortingPlaceholders() == null) {
|
||||
missingKeys.put(group, "sortingPlaceholders");
|
||||
}
|
||||
|
||||
if (group.placeholderReplaments() == null) {
|
||||
missingKeys.put(group, "placeholderReplaments");
|
||||
}
|
||||
}
|
||||
|
||||
return missingKeys;
|
||||
@ -160,6 +171,7 @@ public class TabGroups implements ConfigValidator {
|
||||
group.nametag() == null ? DEFAULT_GROUP.nametag() : group.nametag(),
|
||||
group.servers() == null ? DEFAULT_GROUP.servers() : group.servers(),
|
||||
group.sortingPlaceholders() == null ? DEFAULT_GROUP.sortingPlaceholders() : group.sortingPlaceholders(),
|
||||
group.placeholderReplaments() == null ? DEFAULT_GROUP.placeholderReplaments() : group.placeholderReplaments(),
|
||||
group.collisions(),
|
||||
group.headerFooterUpdateRate(),
|
||||
group.placeholderUpdateRate(),
|
||||
|
@ -19,11 +19,15 @@
|
||||
|
||||
package net.william278.velocitab.hook;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import net.william278.papiproxybridge.api.PlaceholderAPI;
|
||||
import net.william278.velocitab.Velocitab;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class PAPIProxyBridgeHook extends Hook {
|
||||
@ -41,4 +45,17 @@ public class PAPIProxyBridgeHook extends Hook {
|
||||
return api.formatPlaceholders(input, player.getUniqueId());
|
||||
}
|
||||
|
||||
public CompletableFuture<Map<String, String>> parsePlaceholders(@NotNull List<String> input, @NotNull Player player) {
|
||||
final Map<String, String> map = Maps.newConcurrentMap();
|
||||
final List<CompletableFuture<String>> futures = Lists.newArrayList();
|
||||
|
||||
for (String s : input) {
|
||||
final CompletableFuture<String> future = formatPlaceholders(s, player);
|
||||
futures.add(future);
|
||||
future.thenAccept(r -> map.put(s, r));
|
||||
}
|
||||
|
||||
return CompletableFuture.allOf(futures.toArray(CompletableFuture[]::new)).thenApply(v -> map);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ public class VelocitabMiniExpansion {
|
||||
}
|
||||
|
||||
final String value = fixValue(popAll(queue));
|
||||
String replaced = Placeholder.replaceInternal(value, plugin, targetPlayer);
|
||||
final String replaced = Placeholder.replaceInternal(value, plugin, targetPlayer).first();
|
||||
|
||||
return Tag.selfClosingInserting(MiniMessage.miniMessage().deserialize(replaced, MiniPlaceholders.getAudienceGlobalPlaceholders(audience)));
|
||||
}));
|
||||
|
@ -110,7 +110,7 @@ public class MiniConditionManager {
|
||||
}
|
||||
|
||||
|
||||
condition = Placeholder.replaceInternal(condition, plugin, tabPlayer.get());
|
||||
condition = Placeholder.replaceInternal(condition, plugin, tabPlayer.get()).first();
|
||||
final String falseValue = processFalseValue(parameters.get(2));
|
||||
final String expression = buildExpression(condition);
|
||||
return evaluateAndFormatCondition(expression, target, audience, parameters.get(1), falseValue);
|
||||
|
@ -422,7 +422,7 @@ public class ScoreboardManager {
|
||||
.mapping(0x5C, MINECRAFT_1_20_2, false)
|
||||
.mapping(0x5E, MINECRAFT_1_20_3, false)
|
||||
.mapping(0x60, MINECRAFT_1_20_5, false)
|
||||
.mapping(0x67, MINECRAFT_1_21_2, false);
|
||||
.mapping(0x67, MINECRAFT_1_21_4, false);
|
||||
packetRegistration.register();
|
||||
} catch (Throwable e) {
|
||||
plugin.log(Level.ERROR, "Failed to register UpdateTeamsPacket", e);
|
||||
|
@ -123,18 +123,6 @@ public final class TabPlayer implements Comparable<TabPlayer> {
|
||||
return plugin.getTabGroups().getPosition(group);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the display name of the server the player is currently on.
|
||||
* Affected by server aliases defined in the config.
|
||||
*
|
||||
* @param plugin The plugin instance
|
||||
* @return The display name of the server
|
||||
*/
|
||||
@NotNull
|
||||
public String getServerDisplayName(@NotNull Velocitab plugin) {
|
||||
return plugin.getSettings().getServerDisplayName(getServerName());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CompletableFuture<String> getDisplayName(@NotNull Velocitab plugin) {
|
||||
final String format = formatGroup();
|
||||
@ -166,7 +154,7 @@ public final class TabPlayer implements Comparable<TabPlayer> {
|
||||
displayName = displayName.replace(placeholder, value);
|
||||
}
|
||||
|
||||
displayName = Placeholder.replaceInternal(displayName, plugin, this);
|
||||
displayName = Placeholder.replaceInternal(displayName, plugin, this).first();
|
||||
return lastDisplayName = displayName;
|
||||
}
|
||||
|
||||
|
@ -32,13 +32,13 @@ public record Nametag(@NotNull String prefix, @NotNull String suffix) {
|
||||
|
||||
@NotNull
|
||||
public Component getPrefixComponent(@NotNull Velocitab plugin, @NotNull TabPlayer tabPlayer, @NotNull TabPlayer target) {
|
||||
final String formatted = Placeholder.replaceInternal(prefix, plugin, tabPlayer);
|
||||
final String formatted = Placeholder.replaceInternal(prefix, plugin, tabPlayer).first();
|
||||
return plugin.getFormatter().format(formatted, tabPlayer, target, plugin);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Component getSuffixComponent(@NotNull Velocitab plugin, @NotNull TabPlayer tabPlayer, @NotNull TabPlayer target) {
|
||||
final String formatted = Placeholder.replaceInternal(suffix, plugin, tabPlayer);
|
||||
final String formatted = Placeholder.replaceInternal(suffix, plugin, tabPlayer).first();
|
||||
return plugin.getFormatter().format(formatted, tabPlayer, target, plugin);
|
||||
}
|
||||
|
||||
|
@ -26,6 +26,7 @@ import com.velocitypowered.api.proxy.ServerConnection;
|
||||
import com.velocitypowered.api.proxy.player.TabList;
|
||||
import com.velocitypowered.api.proxy.player.TabListEntry;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import com.velocitypowered.api.util.GameProfile;
|
||||
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
|
||||
import com.velocitypowered.proxy.protocol.packet.UpsertPlayerInfoPacket;
|
||||
import com.velocitypowered.proxy.tablist.KeyedVelocityTabList;
|
||||
|
@ -160,6 +160,9 @@ public class TabListListener {
|
||||
@SuppressWarnings("deprecation")
|
||||
@Subscribe(order = PostOrder.CUSTOM, priority = Short.MIN_VALUE)
|
||||
public void onPlayerQuit(@NotNull DisconnectEvent event) {
|
||||
if(event.getLoginStatus() == DisconnectEvent.LoginStatus.CONFLICTING_LOGIN) {
|
||||
return;
|
||||
}
|
||||
if (event.getLoginStatus() != DisconnectEvent.LoginStatus.SUCCESSFUL_LOGIN) {
|
||||
checkDelayedDisconnect(event);
|
||||
return;
|
||||
@ -180,6 +183,7 @@ public class TabListListener {
|
||||
return;
|
||||
}
|
||||
|
||||
tabList.removeOfflinePlayer(player);
|
||||
tabList.removeTabListUUID(event.getPlayer().getUniqueId());
|
||||
}).delay(750, TimeUnit.MILLISECONDS).schedule();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user