mirror of
https://github.com/CivMC/Civ.git
synced 2026-07-18 00:20:44 +00:00
Merge pull request #339 from Protonull/player-name-cache
Create centralised player-name cache
This commit is contained in:
@@ -18,6 +18,7 @@ import vg.civcraft.mc.civmodcore.inventory.items.EnchantUtils;
|
||||
import vg.civcraft.mc.civmodcore.inventory.items.MoreTags;
|
||||
import vg.civcraft.mc.civmodcore.inventory.items.SpawnEggUtils;
|
||||
import vg.civcraft.mc.civmodcore.inventory.items.TreeTypeUtils;
|
||||
import vg.civcraft.mc.civmodcore.players.PlayerNames;
|
||||
import vg.civcraft.mc.civmodcore.players.scoreboard.bottom.BottomLineAPI;
|
||||
import vg.civcraft.mc.civmodcore.players.scoreboard.side.ScoreBoardAPI;
|
||||
import vg.civcraft.mc.civmodcore.players.scoreboard.side.ScoreBoardListener;
|
||||
@@ -88,6 +89,7 @@ public class CivModCorePlugin extends ACivMod {
|
||||
registerListener(DialogManager.INSTANCE);
|
||||
registerListener(new ScoreBoardListener());
|
||||
registerListener(new WorldTracker());
|
||||
registerListener(new PlayerNames());
|
||||
// Register commands
|
||||
this.commands = new CommandManager(this);
|
||||
this.commands.init();
|
||||
|
||||
@@ -6,9 +6,11 @@ import co.aikar.commands.InvalidCommandArgument;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.ConsoleCommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import vg.civcraft.mc.civmodcore.inventory.items.ItemUtils;
|
||||
import vg.civcraft.mc.civmodcore.players.PlayerNames;
|
||||
|
||||
/**
|
||||
* This is a separate helper class that allows plugins to use ACF without needing to commit to {@link CommandManager}
|
||||
@@ -86,6 +88,22 @@ public final class CommandHelpers {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Completion for all known player names.
|
||||
*/
|
||||
public static void registerKnownPlayersCompletion(
|
||||
final @NotNull CommandCompletions<?> completions
|
||||
) {
|
||||
completions.registerCompletion(
|
||||
"allplayers",
|
||||
(context) -> PlayerNames.getPlayerNames()
|
||||
);
|
||||
completions.setDefaultCompletion(
|
||||
"allplayers",
|
||||
OfflinePlayer.class
|
||||
);
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Contexts
|
||||
// ============================================================
|
||||
|
||||
@@ -10,25 +10,15 @@ import co.aikar.commands.CommandContexts;
|
||||
import com.google.common.base.Strings;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentSkipListSet;
|
||||
import java.util.logging.Level;
|
||||
import javax.annotation.Nonnull;
|
||||
import org.apache.commons.lang3.reflect.FieldUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import vg.civcraft.mc.civmodcore.utilities.CivLogger;
|
||||
|
||||
@@ -36,9 +26,6 @@ import vg.civcraft.mc.civmodcore.utilities.CivLogger;
|
||||
* Command registration class wrapper around {@link BukkitCommandManager}.
|
||||
*/
|
||||
public class CommandManager extends BukkitCommandManager {
|
||||
// Track players to offer quick completion where necessary.
|
||||
private final Set<String> autocompletePlayerNames = new ConcurrentSkipListSet<>();
|
||||
|
||||
private final CivLogger logger;
|
||||
|
||||
/**
|
||||
@@ -57,25 +44,6 @@ public class CommandManager extends BukkitCommandManager {
|
||||
* {@link #unregisterCompletions()}, otherwise there may be issues.
|
||||
*/
|
||||
public final void init() {
|
||||
// Prepare our list with player names on init.
|
||||
// Load all known players once on initialization, then use a loginlistener to update the existing name set.
|
||||
Arrays.stream(Bukkit.getOfflinePlayers()).map(OfflinePlayer::getName)
|
||||
.filter(Objects::nonNull)
|
||||
.forEach(autocompletePlayerNames::add);
|
||||
/*TODO
|
||||
this may be better solved with a single global listener, but the implications would've needed some checks.
|
||||
This is pretty cheap and works fast.
|
||||
*/
|
||||
|
||||
Bukkit.getPluginManager().registerEvents(new Listener() {
|
||||
// Players joining should be added to our list, just in case they are new.
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onLogin(PlayerLoginEvent ev) {
|
||||
// For autocomplete we wil update the listeners.
|
||||
autocompletePlayerNames.add(ev.getPlayer().getName());
|
||||
}
|
||||
}, plugin);
|
||||
|
||||
registerContexts(getCommandContexts());
|
||||
registerCompletions(getCommandCompletions());
|
||||
registerCommands();
|
||||
@@ -100,11 +68,7 @@ public class CommandManager extends BukkitCommandManager {
|
||||
CommandHelpers.registerNoneCompletion(completions);
|
||||
CommandHelpers.registerMaterialsCompletion(completions);
|
||||
CommandHelpers.registerItemMaterialsCompletion(completions);
|
||||
|
||||
// Completion lists are copied so outer code can modify the lists without breaking our inner contracts,
|
||||
// namely that all players should be searchable by completion.
|
||||
// Using Collections.immutableList is an alternative, but both variants aren't expensive.
|
||||
completions.registerAsyncCompletion("allplayers", (context) -> new ArrayList<>(autocompletePlayerNames));
|
||||
CommandHelpers.registerKnownPlayersCompletion(completions);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package vg.civcraft.mc.civmodcore.players;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerLoginEvent;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public final class PlayerNames implements Listener {
|
||||
|
||||
private static final Set<String> names = new HashSet<>();
|
||||
|
||||
public PlayerNames() {
|
||||
names.clear();
|
||||
names.addAll(
|
||||
Stream.of(Bukkit.getOfflinePlayers())
|
||||
.map(OfflinePlayer::getName)
|
||||
.filter(StringUtils::isNotBlank)
|
||||
.toList()
|
||||
);
|
||||
}
|
||||
|
||||
@EventHandler(
|
||||
priority = EventPriority.MONITOR, // Make sure it happens after NameLayer's AssociationListener
|
||||
ignoreCancelled = true
|
||||
)
|
||||
private void onLogin(
|
||||
final @NotNull PlayerLoginEvent event
|
||||
) {
|
||||
names.add(event.getPlayer().getName());
|
||||
}
|
||||
|
||||
public static @NotNull Collection<String> getPlayerNames() {
|
||||
return Collections.unmodifiableSet(names);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user