From cf49f333d050123f0a4988901be7d464e6460214 Mon Sep 17 00:00:00 2001 From: sean Date: Sat, 8 Jun 2024 18:31:44 +0200 Subject: [PATCH] Change: Increase the default friend search similarity to 50% This also makes use of parallel streams in the search function to increase search speeds --- .../bukkit/config/DefaultConfig.java | 2 +- .../FriendSearchResultInventory.java | 40 +++++++++---------- spigot/src/main/resources/config.yml | 2 +- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/config/DefaultConfig.java b/spigot/src/main/java/de/sean/blockprot/bukkit/config/DefaultConfig.java index d7aace7f..483a5501 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/config/DefaultConfig.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/config/DefaultConfig.java @@ -331,7 +331,7 @@ public long getLockHintCooldown() { */ public double getFriendSearchSimilarityPercentage() { if (!config.contains("friend_search_similarity")) { - return 0.3; + return 0.5; } return config.getDouble("friend_search_similarity"); } diff --git a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchResultInventory.java b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchResultInventory.java index f5e09d1c..91ad3578 100644 --- a/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchResultInventory.java +++ b/spigot/src/main/java/de/sean/blockprot/bukkit/inventories/FriendSearchResultInventory.java @@ -22,10 +22,8 @@ import de.sean.blockprot.bukkit.TranslationKey; import de.sean.blockprot.bukkit.Translator; import de.sean.blockprot.bukkit.integrations.PluginIntegration; -import de.sean.blockprot.bukkit.nbt.FriendSupportingHandler; import de.sean.blockprot.bukkit.nbt.PlayerSettingsHandler; import de.sean.blockprot.nbt.FriendModifyAction; -import de.tr7zw.changeme.nbtapi.NBTCompound; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.OfflinePlayer; @@ -37,9 +35,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.stream.StreamSupport; + +import static java.util.Arrays.spliterator; public class FriendSearchResultInventory extends BlockProtInventory { @Override @@ -148,53 +146,53 @@ public Inventory fill(@NotNull Player player, String searchQuery) { InventoryState state = InventoryState.get(player.getUniqueId()); if (state == null) return inventory; - ArrayList potentialFriends = new ArrayList<>(Arrays.asList(Bukkit.getOfflinePlayers())); - // The already existing friends we want to add to. - final @Nullable FriendSupportingHandler handler = + final @Nullable var handler = getFriendSupportingHandler(state.friendSearchState, player, state.getBlock()); if (handler == null) return null; // return null to indicate an issue. // We'll filter all doubled friends out of the list and add them to the current InventoryState. double minimumSimilarity = BlockProt.getDefaultConfig().getFriendSearchSimilarityPercentage(); - potentialFriends.removeIf(p -> { + final var offlinePlayers = Bukkit.getOfflinePlayers(); + final var filterStream = StreamSupport.stream(spliterator(offlinePlayers, 0, offlinePlayers.length), true).filter(p -> { // Filter all the players by search criteria. // If the strings are similar by 30%, the strings are considered similar (imo) and should be added. // If they're less than 30% similar, we should still check if it possibly contains the search criteria // and still add that user. - if (p.getName() == null || p.getUniqueId().equals(player.getUniqueId())) return true; - else if (handler.containsFriend(p.getUniqueId().toString())) return true; - else if (p.getName().contains(searchQuery)) return false; - else return compareStrings(p.getName(), searchQuery) < minimumSimilarity; + if (p.getName() == null || p.getUniqueId().equals(player.getUniqueId())) return false; + else if (p.getName().contains(searchQuery)) return true; + else return compareStrings(p.getName(), searchQuery) >= minimumSimilarity; + }).sequential().filter(p -> { + // We need to convert it back to a sequential list since NBT can only be accessed from the main thread. + return !handler.containsFriend(p.getUniqueId().toString()); }); state.friendResultCache.clear(); if (state.friendSearchState == InventoryState.FriendSearchState.FRIEND_SEARCH && state.getBlock() != null) { // Allow integrations to additionally filter friends. - var filtered = potentialFriends.stream() + var filtered = filterStream .filter(f -> PluginIntegration.filterFriendByUuidForAll(f.getUniqueId(), player, state.getBlock())) .toList(); state.friendResultCache.addAll(filtered); } else { - state.friendResultCache.addAll(potentialFriends); + state.friendResultCache.addAll(filterStream.toList()); } - // Finally, construct the inventory with all the potential friends. // To not delay when the inventory opens, we'll asynchronously get the items after // the inventory has been opened and later add them to the inventory. In the meantime, // we'll show the same amount of skeleton heads. - final int maxPlayers = Math.min(potentialFriends.size(), InventoryConstants.tripleLine - 1); + final var finalList = state.friendResultCache; + final int maxPlayers = Math.min(finalList.size(), InventoryConstants.tripleLine - 1); for (int i = 0; i < maxPlayers; i++) { - this.setItemStack(i, Material.SKELETON_SKULL, potentialFriends.get(i).getName()); + this.setItemStack(i, Material.SKELETON_SKULL, finalList.get(i).getName()); } - final List finalPotentialFriends = potentialFriends; Bukkit.getScheduler().runTaskAsynchronously(BlockProt.getInstance(), () -> { // Only show the 9 * 3 - 1 most relevant players. Don't show any extra. int playersIndex = 0; - while (playersIndex < maxPlayers && playersIndex < finalPotentialFriends.size()) { + while (playersIndex < maxPlayers && playersIndex < finalList.size()) { // Only add to the inventory if this is not a friend (yet) - var profile = finalPotentialFriends.get(playersIndex).getPlayerProfile(); + var profile = finalList.get(playersIndex).getPlayerProfile(); try { profile = profile.update().get(); } catch (Exception e) { diff --git a/spigot/src/main/resources/config.yml b/spigot/src/main/resources/config.yml index 63c3f724..bbbad0f6 100644 --- a/spigot/src/main/resources/config.yml +++ b/spigot/src/main/resources/config.yml @@ -61,7 +61,7 @@ lock_hint_cooldown_in_seconds: 10 # default, this is 0.3, meaning only names that are less than 30% similar # are shown in the friend search. To determine similarity, the levenshtein # algorithm is used. -friend_search_similarity: 0.3 +friend_search_similarity: 0.5 # If desired, you can disable the friends functionality entirely. This will # no longer allow players to give other players access to their blocks, and