001package co.aikar.commands; 002 003import com.velocitypowered.api.command.CommandSource; 004import com.velocitypowered.api.proxy.Player; 005import com.velocitypowered.api.proxy.ProxyServer; 006import net.kyori.adventure.text.TextComponent; 007import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; 008 009import java.util.ArrayList; 010import java.util.Collection; 011import java.util.Collections; 012import java.util.List; 013import java.util.Optional; 014import java.util.stream.Collectors; 015 016public class ACFVelocityUtil { 017 018 public static TextComponent color(String message) { 019 return LegacyComponentSerializer.legacySection().deserialize(message); 020 } 021 022 public static Player findPlayerSmart(ProxyServer server, CommandIssuer issuer, String search) { 023 CommandSource requester = issuer.getIssuer(); 024 String name = ACFUtil.replace(search, ":confirm", ""); 025 if (!isValidName(name)) { 026 issuer.sendError(MinecraftMessageKeys.IS_NOT_A_VALID_NAME, "{name}", name); 027 return null; 028 } 029 030 List<Player> matches = new ArrayList<>(matchPlayer(server, name)); 031 032 if (matches.size() > 1) { 033 String allMatches = matches.stream().map(Player::getUsername).collect(Collectors.joining(", ")); 034 issuer.sendError(MinecraftMessageKeys.MULTIPLE_PLAYERS_MATCH, "{search}", name, "{all}", allMatches); 035 return null; 036 } 037 038 if (matches.isEmpty()) { 039 issuer.sendError(MinecraftMessageKeys.NO_PLAYER_FOUND_SERVER, "{search}", name); 040 return null; 041 } 042 043 return matches.get(0); 044 } 045 046 /* 047 * Original code written by md_5 048 * 049 * Modified to work with Velocity by Crypnotic 050 */ 051 private static Collection<Player> matchPlayer(ProxyServer server, final String partialName) { 052 // A better error message might be nice. This just mimics the previous output 053 if (partialName == null) { 054 throw new NullPointerException("partialName"); 055 } 056 057 Optional<Player> exactMatch = server.getPlayer(partialName); 058 if (exactMatch.isPresent()) { 059 return Collections.singleton(exactMatch.get()); 060 } 061 062 return server.getAllPlayers().stream() 063 .filter(player -> player.getUsername().regionMatches(true, 0, partialName, 0, partialName.length())) 064 .collect(Collectors.toList()); 065 } 066 067 public static boolean isValidName(String name) { 068 return name != null && !name.isEmpty() && ACFPatterns.VALID_NAME_PATTERN.matcher(name).matches(); 069 } 070 071 public static <T> T validate(T object, String message, Object... values) { 072 if (object == null) { 073 throw new NullPointerException(String.format(message, values)); 074 } 075 return object; 076 } 077}