forked from Upstream/Velocitab
Add role_display_name
placeholder, add docs for sorting
This commit is contained in:
parent
4c2735337a
commit
07fd9c306a
@ -11,6 +11,7 @@ Please click through to the topic you wish to read about.
|
||||
## Documentation
|
||||
* 👥 [[Server Groups]]
|
||||
* 🎨 [[Formatting]]
|
||||
* 📊 [[Sorting]]
|
||||
* ✍️ [[Placeholders]]
|
||||
* ✨ [[Animations]]
|
||||
* 🖼️ [[Custom Logos]]
|
||||
|
@ -3,20 +3,21 @@ Velocitab supports a number of Placeholders that will be replaced with their res
|
||||
## Default placeholders
|
||||
Placeholders can be included in the header, footer and player name format of the TAB list. The following placeholders are supported out of the box:
|
||||
|
||||
| Placeholder | Description | Example |
|
||||
|--------------------------|-----------------------------------------------|--------------------|
|
||||
| `%players_online%` | Players online on the proxy | `6` |
|
||||
| `%max_players_online%` | Player capacity of the proxy | `500` |
|
||||
| `%local_players_online%` | Players online on the server the player is on | `3` |
|
||||
| `%current_date%` | Current real-world date of the server | `24 Feb 2023` |
|
||||
| `%current_time%` | Current real-world time of the server | `21:45:32` |
|
||||
| `%username%` | The player's username | `William278` |
|
||||
| `%server%` | Name of the server the player is on | `alpha` |
|
||||
| `%ping%` | Ping of the player (in ms) | `6` |
|
||||
| `%prefix%` | The player's prefix (from LuckPerms) | `&4[Admin]` |
|
||||
| `%suffix%` | The player's suffix (from LuckPerms) | `&c ` |
|
||||
| `%role%` | The player's primary LuckPerms group | `admin` |
|
||||
| `%debug_team_name%` | Internal team value, used for list sorting | `1_alpha_William2` |
|
||||
| Placeholder | Description | Example |
|
||||
|--------------------------|---------------------------------------------------|--------------------|
|
||||
| `%players_online%` | Players online on the proxy | `6` |
|
||||
| `%max_players_online%` | Player capacity of the proxy | `500` |
|
||||
| `%local_players_online%` | Players online on the server the player is on | `3` |
|
||||
| `%current_date%` | Current real-world date of the server | `24 Feb 2023` |
|
||||
| `%current_time%` | Current real-world time of the server | `21:45:32` |
|
||||
| `%username%` | The player's username | `William278` |
|
||||
| `%server%` | Name of the server the player is on | `alpha` |
|
||||
| `%ping%` | Ping of the player (in ms) | `6` |
|
||||
| `%prefix%` | The player's prefix (from LuckPerms) | `&4[Admin]` |
|
||||
| `%suffix%` | The player's suffix (from LuckPerms) | `&c ` |
|
||||
| `%role%` | The player's primary LuckPerms group name | `admin` |
|
||||
| `%role_display_name%` | The player's primary LuckPerms group display name | `Admin` |
|
||||
| `%debug_team_name%` | Internal team value, used for list sorting | `1_alpha_William2` |
|
||||
|
||||
### Customising server display names
|
||||
You can make use of the `server_display_names` feature in `config.yml` to customise how server display name appear when using the `%server%` placeholder. In the below example, if a user is connected to a server with the name "`very-long-server-`name" and the player name format for the group that server belongs to includes a `%server%` placeholder, the placeholder would be replaced with "`VSLN`" instead of the full server name.
|
||||
|
40
docs/Sorting.md
Normal file
40
docs/Sorting.md
Normal file
@ -0,0 +1,40 @@
|
||||
Velocitab can sort players in the TAB list by a number of "sorting elements." Sorting is enabled by default, and can be disabled with the `sort_players` option in the [`config.yml`](Config-File) file.
|
||||
|
||||
## Sortable elements
|
||||
To modify what players are sorted by, modify the `sort_players_by` list in the [`config.yml`](Config-File) file. This option accepts an ordered list; the first element in the list is what players will be sorted by first, with subsequent elements being used to break ties. The default sorting strategy is to sort first by `ROLE_WEIGHT` followed by `ROLE_NAME`.
|
||||
|
||||
<details>
|
||||
<summary>Sort Players By… (config.yml)</summary>
|
||||
|
||||
```yaml
|
||||
# Ordered list of elements by which players should be sorted. (ROLE_WEIGHT, ROLE_NAME and SERVER are supported)
|
||||
sort_players_by:
|
||||
- ROLE_WEIGHT
|
||||
- ROLE_NAME
|
||||
```
|
||||
</details>
|
||||
|
||||
### List of elements
|
||||
The following sorting elements are supported:
|
||||
|
||||
| Sorting element | Description |
|
||||
|:---------------:|----------------------------------------------------|
|
||||
| `ROLE_WEIGHT` | The weight of the player's primary LuckPerms group |
|
||||
| `ROLE_NAME` | The name of the player's primary LuckPerms group |
|
||||
| `SERVER_NAME` | The name of the server the player is connected to |
|
||||
|
||||
## Technical details
|
||||
In Minecraft, the TAB list is sorted by the client; the server does not handle the actual display order of names in the list. Players are sorted first by the name of their scoreboard team, then by their name. This is why having a proxy TAB plugin sort players is a surprisingly complex feature request!
|
||||
|
||||
To get the client to correctly sort the TAB list, Velocitab sends fake scoreboard "Update Teams" packets to everyone in order to trick the client into thinking players on the server are members of a fake scoreboard team. The name of the fake team for sorting is based on a number of "sorting elements," which can be customized.
|
||||
|
||||
Velocitab has a few optimizations in place to reduce the number of packets sent; if you have more sorting elements, do note this will lead to more packets being sent between clients and the proxy as the teams will need to be updated more regularly. This can lead to an observable increase in network traffic—listing fewer sorting elements in the `sort_players_by` section will reduce the number of packets sent.
|
||||
|
||||
## Compatibility issues
|
||||
There are a few compatibility caveats to bear in mind with sorting players in the TAB list:
|
||||
|
||||
* If you're using scoreboard teams on your server, then this will interfere with Velocitab's fake team packets and cause sorting to break. Most modern Minecraft proxy network servers probably won't use this feature, since there are better and more powerful plugin alternatives for teaming players, but it's still important to bear in mind.
|
||||
* Some mods can interfere with scoreboard team packets, particularly if they internally deal with managing packets or scoreboard teams.
|
||||
* Sending fake scoreboard team packets might not work correctly on some Minecraft server implementations such as [Quilt](https://quiltmc.org/).
|
||||
|
||||
In these cases, you may need to disable sorting through the `sort_players` option detailed earlier.
|
@ -5,6 +5,7 @@
|
||||
## Documentation
|
||||
* 👥 [[Server Groups]]
|
||||
* 🎨 [[Formatting]]
|
||||
* 📊 [[Sorting]]
|
||||
* ✍️ [[Placeholders]]
|
||||
* ✨ [[Animations]]
|
||||
* 🖼️ [[Custom Logos]]
|
||||
|
@ -47,6 +47,7 @@ public enum Placeholder {
|
||||
PREFIX((plugin, player) -> player.getRole().getPrefix().orElse("")),
|
||||
SUFFIX((plugin, player) -> player.getRole().getSuffix().orElse("")),
|
||||
ROLE((plugin, player) -> player.getRole().getName().orElse("")),
|
||||
ROLE_DISPLAY_NAME((plugin, player) -> player.getRole().getDisplayName().orElse("")),
|
||||
DEBUG_TEAM_NAME((plugin, player) -> plugin.getFormatter().escape(player.getTeamName(plugin)));
|
||||
|
||||
/**
|
||||
|
@ -33,6 +33,7 @@ import net.william278.velocitab.tab.PlayerTabList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.OptionalInt;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -58,9 +59,11 @@ public class LuckPermsHook extends Hook {
|
||||
if (metaData.getPrimaryGroup() == null) {
|
||||
return Role.DEFAULT_ROLE;
|
||||
}
|
||||
final Optional<Group> group = getGroup(metaData.getPrimaryGroup());
|
||||
return new Role(
|
||||
getWeight(metaData.getPrimaryGroup()).orElse(0),
|
||||
group.map(this::getGroupWeight).orElse(Role.DEFAULT_WEIGHT),
|
||||
metaData.getPrimaryGroup(),
|
||||
group.map(Group::getDisplayName).orElse(metaData.getPrimaryGroup()),
|
||||
metaData.getPrefix(),
|
||||
metaData.getSuffix()
|
||||
);
|
||||
@ -83,12 +86,17 @@ public class LuckPermsHook extends Hook {
|
||||
.schedule());
|
||||
}
|
||||
|
||||
private OptionalInt getWeight(@Nullable String groupName) {
|
||||
final Group group;
|
||||
if (groupName == null || (group = api.getGroupManager().getGroup(groupName)) == null) {
|
||||
return OptionalInt.empty();
|
||||
// Get a group by name
|
||||
private Optional<Group> getGroup(@Nullable String groupName) {
|
||||
if (groupName == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return group.getWeight();
|
||||
return Optional.ofNullable(api.getGroupManager().getGroup(groupName));
|
||||
}
|
||||
|
||||
// Get the weight of a group
|
||||
private int getGroupWeight(@NotNull Group group) {
|
||||
return group.getWeight().orElse(Role.DEFAULT_WEIGHT);
|
||||
}
|
||||
|
||||
public int getHighestWeight() {
|
||||
|
@ -26,18 +26,21 @@ import java.util.Optional;
|
||||
|
||||
public class Role implements Comparable<Role> {
|
||||
public static final int DEFAULT_WEIGHT = 0;
|
||||
public static final Role DEFAULT_ROLE = new Role(DEFAULT_WEIGHT, null, null, null);
|
||||
public static final Role DEFAULT_ROLE = new Role(DEFAULT_WEIGHT, null, null, null, null);
|
||||
private final int weight;
|
||||
@Nullable
|
||||
private final String name;
|
||||
@Nullable
|
||||
private final String displayName;
|
||||
@Nullable
|
||||
private final String prefix;
|
||||
@Nullable
|
||||
private final String suffix;
|
||||
|
||||
public Role(int weight, @Nullable String name, @Nullable String prefix, @Nullable String suffix) {
|
||||
public Role(int weight, @Nullable String name, @Nullable String displayName, @Nullable String prefix, @Nullable String suffix) {
|
||||
this.weight = weight;
|
||||
this.name = name;
|
||||
this.displayName = displayName;
|
||||
this.prefix = prefix;
|
||||
this.suffix = suffix;
|
||||
}
|
||||
@ -47,6 +50,14 @@ public class Role implements Comparable<Role> {
|
||||
return weight - o.weight;
|
||||
}
|
||||
|
||||
public Optional<String> getName() {
|
||||
return Optional.ofNullable(name);
|
||||
}
|
||||
|
||||
public Optional<String> getDisplayName() {
|
||||
return Optional.ofNullable(displayName).or(this::getName);
|
||||
}
|
||||
|
||||
public Optional<String> getPrefix() {
|
||||
return Optional.ofNullable(prefix);
|
||||
}
|
||||
@ -55,12 +66,9 @@ public class Role implements Comparable<Role> {
|
||||
return Optional.ofNullable(suffix);
|
||||
}
|
||||
|
||||
public Optional<String> getName() {
|
||||
return Optional.ofNullable(name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected String getWeightString(int highestWeight) {
|
||||
return String.format("%0" + Integer.toString(highestWeight).length() + "d", highestWeight - weight);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user