Added Sorting Manager (#105)

* Added SortingManager.

* Fixed initialization problem + added cache for team name

* Improved code readability

* Commit with the requested changes.

* Update src/main/java/net/william278/velocitab/Velocitab.java

Co-authored-by: William <will27528@gmail.com>

---------

Co-authored-by: William <will27528@gmail.com>
This commit is contained in:
AlexDev_ 2023-10-15 14:04:10 +02:00 committed by GitHub
parent 3d82ebe809
commit 1e2aff4cf0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 118 additions and 38 deletions

View File

@ -44,6 +44,7 @@ import net.william278.velocitab.hook.PAPIProxyBridgeHook;
import net.william278.velocitab.packet.ScoreboardManager;
import net.william278.velocitab.player.Role;
import net.william278.velocitab.player.TabPlayer;
import net.william278.velocitab.sorting.SortingManager;
import net.william278.velocitab.tab.PlayerTabList;
import org.bstats.charts.SimplePie;
import org.bstats.velocity.Metrics;
@ -73,6 +74,7 @@ public class Velocitab {
private PlayerTabList tabList;
private List<Hook> hooks;
private ScoreboardManager scoreboardManager;
private SortingManager sortingManager;
@Inject
public Velocitab(@NotNull ProxyServer server, @NotNull Logger logger, @DataDirectory Path dataDirectory) {
@ -87,6 +89,7 @@ public class Velocitab {
loadHooks();
prepareScoreboardManager();
prepareTabList();
prepareSortingManager();
registerCommands();
registerMetrics();
checkForUpdates();
@ -170,6 +173,15 @@ public class Velocitab {
}
}
private void prepareSortingManager() {
this.sortingManager = new SortingManager(this);
}
@NotNull
public SortingManager getSortingManager() {
return sortingManager;
}
@NotNull
public Optional<ScoreboardManager> getScoreboardManager() {
return Optional.ofNullable(scoreboardManager);

View File

@ -23,10 +23,7 @@ import lombok.Getter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class Role implements Comparable<Role> {
public static final int DEFAULT_WEIGHT = 0;
@ -73,29 +70,9 @@ public class Role implements Comparable<Role> {
@NotNull
protected String getWeightString() {
return compressNumber(Integer.MAX_VALUE / 4d - weight);
return Integer.toString(weight);
}
public String compressNumber(double number) {
int wholePart = (int) number;
final char decimalChar = (char) ((number - wholePart) * Character.MAX_VALUE);
final List<Character> charList = new ArrayList<>();
while (wholePart > 0) {
char digit = (char) (wholePart % Character.MAX_VALUE);
charList.add(0, digit);
wholePart /= Character.MAX_VALUE;
}
if (charList.isEmpty()) {
charList.add((char) 0);
}
return charList.stream().map(String::valueOf).collect(Collectors.joining()) + decimalChar;
}
}

View File

@ -26,7 +26,6 @@ import net.william278.velocitab.Velocitab;
import net.william278.velocitab.config.Placeholder;
import net.william278.velocitab.tab.PlayerTabList;
import org.jetbrains.annotations.NotNull;
import org.slf4j.event.Level;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
@ -126,19 +125,8 @@ public final class TabPlayer implements Comparable<TabPlayer> {
@NotNull
public CompletableFuture<String> getTeamName(@NotNull Velocitab plugin) {
if (!plugin.getSettings().isSortPlayers()) {
return CompletableFuture.completedFuture("");
}
final String sortingFormat = String.join("", plugin.getSettings().getSortingElements());
return Placeholder.replace(sortingFormat, plugin, this) // Replace placeholders
.thenApply(formatted -> formatted.length() > 12 ? formatted.substring(0, 12) : formatted) // Truncate
.thenApply(truncated -> truncated + getPlayer().getUniqueId().toString().substring(0, 4)) // Make unique
.thenApply(teamName -> this.teamName = teamName)
.exceptionally(e -> {
plugin.log(Level.ERROR, "Failed to get team name for " + player.getUsername(), e);
return "";
});
return plugin.getSortingManager().getTeamName(this)
.thenApply(teamName -> this.teamName = teamName);
}
public Optional<String> getLastTeamName() {

View File

@ -0,0 +1,103 @@
/*
* 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.sorting;
import net.william278.velocitab.Velocitab;
import net.william278.velocitab.config.Placeholder;
import net.william278.velocitab.player.TabPlayer;
import org.slf4j.event.Level;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;
public class SortingManager {
private final Velocitab plugin;
private static final String DELIMITER = ":::";
public SortingManager(Velocitab plugin) {
this.plugin = plugin;
}
public CompletableFuture<String> getTeamName(TabPlayer player) {
if (!plugin.getSettings().isSortPlayers()) {
return CompletableFuture.completedFuture("");
}
return Placeholder.replace(String.join(DELIMITER, plugin.getSettings().getSortingElements()), plugin, player)
.thenApply(s -> Arrays.asList(s.split(DELIMITER)))
.thenApply(v -> v.stream().map(this::adaptValue).collect(Collectors.toList()))
.thenApply(v -> handleList(player, v));
}
private String handleList(TabPlayer player, List<String> values) {
String result = String.join("", values);
if (result.length() > 12) {
result = result.substring(0, 12);
plugin.log(Level.WARN, "Sorting element list is too long, truncating to 16 characters");
}
result += player.getPlayer().getUniqueId().toString().substring(0, 4); // Make unique
return result;
}
private String adaptValue(String value) {
if (value.isEmpty()) {
return "";
}
if (value.matches("[0-9]+")) {
double parsed = Double.parseDouble(value);
return compressNumber(Integer.MAX_VALUE / 4d - parsed);
}
if (value.length() > 6) {
return value.substring(0, 4);
}
return value;
}
public String compressNumber(double number) {
int wholePart = (int) number;
final char decimalChar = (char) ((number - wholePart) * Character.MAX_VALUE);
final List<Character> charList = new ArrayList<>();
while (wholePart > 0) {
char digit = (char) (wholePart % Character.MAX_VALUE);
charList.add(0, digit);
wholePart /= Character.MAX_VALUE;
}
if (charList.isEmpty()) {
charList.add((char) 0);
}
return charList.stream().map(String::valueOf).collect(Collectors.joining()) + decimalChar;
}
}