Keep track of online players for performance reasons.

Due to Server.getPlayerExact iterating over all online players,
DataManager will now keep track of online players and allow lookup by
exact name and lower-case name.
This commit is contained in:
asofold 2013-02-26 00:39:48 +01:00
parent f37fd4b166
commit ee400b7525
13 changed files with 86 additions and 26 deletions

View File

@ -14,7 +14,6 @@ import java.util.Set;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Server;
import org.bukkit.command.PluginCommand; import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
@ -207,9 +206,8 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
final Set<String> names = nameSetPerms.getPlayers(Permissions.ADMINISTRATION_NOTIFY); final Set<String> names = nameSetPerms.getPlayers(Permissions.ADMINISTRATION_NOTIFY);
if (names == null) return 0; if (names == null) return 0;
int done = 0; int done = 0;
final Server server = Bukkit.getServer();
for (final String name : names){ for (final String name : names){
final Player player = server.getPlayerExact(name); final Player player = DataManager.getPlayerExact(name);
if (player != null){ if (player != null){
player.sendMessage(message); player.sendMessage(message);
done ++; done ++;
@ -489,6 +487,9 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
// Initialize BlockProperties // Initialize BlockProperties
initBlockProperties(config); initBlockProperties(config);
// Initialize data manager.
dataMan.onEnable();
// Allow entries to TickTask (just in case). // Allow entries to TickTask (just in case).
TickTask.setLocked(false); TickTask.setLocked(false);

View File

@ -11,7 +11,6 @@ import org.bukkit.Bukkit;
import org.bukkit.GameMode; import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.Server;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Pig; import org.bukkit.entity.Pig;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -57,6 +56,7 @@ import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
import fr.neatmonster.nocheatplus.logging.DebugUtil; import fr.neatmonster.nocheatplus.logging.DebugUtil;
import fr.neatmonster.nocheatplus.logging.LogUtil; import fr.neatmonster.nocheatplus.logging.LogUtil;
import fr.neatmonster.nocheatplus.permissions.Permissions; import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.utilities.BlockCache; import fr.neatmonster.nocheatplus.utilities.BlockCache;
import fr.neatmonster.nocheatplus.utilities.BlockProperties; import fr.neatmonster.nocheatplus.utilities.BlockProperties;
import fr.neatmonster.nocheatplus.utilities.CheckUtils; import fr.neatmonster.nocheatplus.utilities.CheckUtils;
@ -1141,7 +1141,6 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
// Hover checks ! // Hover checks !
// TODO: Change to ordering such that smallest hover time comes first ? // TODO: Change to ordering such that smallest hover time comes first ?
if (hoverTicks.isEmpty()) return; // Seldom or not ? if (hoverTicks.isEmpty()) return; // Seldom or not ?
final Server server = Bukkit.getServer();
final MoveInfo info; final MoveInfo info;
if (parkedInfo.isEmpty()) info = new MoveInfo(mcAccess); if (parkedInfo.isEmpty()) info = new MoveInfo(mcAccess);
else info = parkedInfo.remove(parkedInfo.size() - 1); else info = parkedInfo.remove(parkedInfo.size() - 1);
@ -1149,7 +1148,7 @@ public class MovingListener extends CheckListener implements TickListener, IRemo
for (final String playerName : hoverTicks){ for (final String playerName : hoverTicks){
// TODO: put players into the set (+- one tick would not matter ?) // TODO: put players into the set (+- one tick would not matter ?)
// TODO: might add an online flag to data ! // TODO: might add an online flag to data !
final Player player = server.getPlayerExact(playerName); final Player player = DataManager.getPlayerExact(playerName);
if (player == null || !player.isOnline()){ if (player == null || !player.isOnline()){
rem.add(playerName); rem.add(playerName);
continue; continue;

View File

@ -10,6 +10,7 @@ import fr.neatmonster.nocheatplus.NoCheatPlus;
import fr.neatmonster.nocheatplus.command.DelayableCommand; import fr.neatmonster.nocheatplus.command.DelayableCommand;
import fr.neatmonster.nocheatplus.logging.LogUtil; import fr.neatmonster.nocheatplus.logging.LogUtil;
import fr.neatmonster.nocheatplus.permissions.Permissions; import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
public class BanCommand extends DelayableCommand { public class BanCommand extends DelayableCommand {
@ -36,7 +37,7 @@ public class BanCommand extends DelayableCommand {
} }
void ban(CommandSender sender, String name, String reason) { void ban(CommandSender sender, String name, String reason) {
Player player = Bukkit.getPlayerExact(name); Player player = DataManager.getPlayer(name);
if (player != null) if (player != null)
player.kickPlayer(reason); player.kickPlayer(reason);
OfflinePlayer offlinePlayer = Bukkit.getServer().getOfflinePlayer(name); OfflinePlayer offlinePlayer = Bukkit.getServer().getOfflinePlayer(name);

View File

@ -1,6 +1,5 @@
package fr.neatmonster.nocheatplus.command.actions; package fr.neatmonster.nocheatplus.command.actions;
import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -9,6 +8,7 @@ import fr.neatmonster.nocheatplus.NoCheatPlus;
import fr.neatmonster.nocheatplus.command.DelayableCommand; import fr.neatmonster.nocheatplus.command.DelayableCommand;
import fr.neatmonster.nocheatplus.logging.LogUtil; import fr.neatmonster.nocheatplus.logging.LogUtil;
import fr.neatmonster.nocheatplus.permissions.Permissions; import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
public class KickCommand extends DelayableCommand { public class KickCommand extends DelayableCommand {
@ -35,7 +35,7 @@ public class KickCommand extends DelayableCommand {
} }
void kick(CommandSender sender, String name, String reason) { void kick(CommandSender sender, String name, String reason) {
Player player = Bukkit.getPlayerExact(name); Player player = DataManager.getPlayer(name);
if (player == null) return; if (player == null) return;
player.kickPlayer(reason); player.kickPlayer(reason);
LogUtil.logInfo("[NoCheatPlus] (" + sender.getName() + ") Kicked " + player.getName() + " : " + reason); LogUtil.logInfo("[NoCheatPlus] (" + sender.getName() + ") Kicked " + player.getName() + " : " + reason);

View File

@ -1,6 +1,5 @@
package fr.neatmonster.nocheatplus.command.actions; package fr.neatmonster.nocheatplus.command.actions;
import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -8,6 +7,7 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.NoCheatPlus; import fr.neatmonster.nocheatplus.NoCheatPlus;
import fr.neatmonster.nocheatplus.command.DelayableCommand; import fr.neatmonster.nocheatplus.command.DelayableCommand;
import fr.neatmonster.nocheatplus.permissions.Permissions; import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.utilities.ColorUtil; import fr.neatmonster.nocheatplus.utilities.ColorUtil;
/** /**
@ -37,7 +37,7 @@ public class TellCommand extends DelayableCommand {
} }
private void tell(String name, String message) { private void tell(String name, String message) {
Player player = Bukkit.getServer().getPlayerExact(name); Player player = DataManager.getPlayer(name);
if (player != null) player.sendMessage(ColorUtil.replaceColors(message)); if (player != null) player.sendMessage(ColorUtil.replaceColors(message));
} }

View File

@ -1,6 +1,5 @@
package fr.neatmonster.nocheatplus.command.actions; package fr.neatmonster.nocheatplus.command.actions;
import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -9,6 +8,7 @@ import fr.neatmonster.nocheatplus.NoCheatPlus;
import fr.neatmonster.nocheatplus.command.DelayableCommand; import fr.neatmonster.nocheatplus.command.DelayableCommand;
import fr.neatmonster.nocheatplus.logging.LogUtil; import fr.neatmonster.nocheatplus.logging.LogUtil;
import fr.neatmonster.nocheatplus.permissions.Permissions; import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
public class TempKickCommand extends DelayableCommand { public class TempKickCommand extends DelayableCommand {
@ -47,7 +47,7 @@ public class TempKickCommand extends DelayableCommand {
protected void tempKick(CommandSender sender, String name, long duration, String reason){ protected void tempKick(CommandSender sender, String name, long duration, String reason){
Player player = Bukkit.getPlayerExact(name); Player player = DataManager.getPlayer(name);
NoCheatPlus.denyLogin(name, duration); NoCheatPlus.denyLogin(name, duration);
if (player == null) return; if (player == null) return;
player.kickPlayer(reason); player.kickPlayer(reason);

View File

@ -3,7 +3,6 @@ package fr.neatmonster.nocheatplus.command.admin;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -14,6 +13,7 @@ import fr.neatmonster.nocheatplus.command.CommandUtil;
import fr.neatmonster.nocheatplus.command.NCPCommand; import fr.neatmonster.nocheatplus.command.NCPCommand;
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager; import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
import fr.neatmonster.nocheatplus.permissions.Permissions; import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.utilities.StringUtil; import fr.neatmonster.nocheatplus.utilities.StringUtil;
public class ExemptCommand extends NCPCommand { public class ExemptCommand extends NCPCommand {
@ -40,7 +40,7 @@ public class ExemptCommand extends NCPCommand {
} }
else checkType = CheckType.ALL; else checkType = CheckType.ALL;
final Player player = Bukkit.getPlayerExact(playerName); final Player player = DataManager.getPlayer(playerName);
if (player == null){ if (player == null){
sender.sendMessage(TAG + "Player not online: " + playerName); sender.sendMessage(TAG + "Player not online: " + playerName);
return true; return true;

View File

@ -3,7 +3,6 @@ package fr.neatmonster.nocheatplus.command.admin;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -13,6 +12,7 @@ import fr.neatmonster.nocheatplus.checks.CheckType;
import fr.neatmonster.nocheatplus.command.NCPCommand; import fr.neatmonster.nocheatplus.command.NCPCommand;
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager; import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
import fr.neatmonster.nocheatplus.permissions.Permissions; import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.utilities.StringUtil; import fr.neatmonster.nocheatplus.utilities.StringUtil;
public class ExemptionsCommand extends NCPCommand { public class ExemptionsCommand extends NCPCommand {
@ -26,7 +26,7 @@ public class ExemptionsCommand extends NCPCommand {
String label, String[] args) { String label, String[] args) {
if (args.length != 2) return false; if (args.length != 2) return false;
String playerName = args[1].trim(); String playerName = args[1].trim();
Player player = Bukkit.getPlayerExact(playerName); Player player = DataManager.getPlayer(playerName);
if (player != null) playerName = player.getName(); if (player != null) playerName = player.getName();
final List<String> entries = new LinkedList<String>(); final List<String> entries = new LinkedList<String>();
for (CheckType type : CheckType.values()){ for (CheckType type : CheckType.values()){

View File

@ -4,7 +4,6 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -15,6 +14,7 @@ import fr.neatmonster.nocheatplus.checks.ViolationHistory;
import fr.neatmonster.nocheatplus.checks.ViolationHistory.ViolationLevel; import fr.neatmonster.nocheatplus.checks.ViolationHistory.ViolationLevel;
import fr.neatmonster.nocheatplus.command.NCPCommand; import fr.neatmonster.nocheatplus.command.NCPCommand;
import fr.neatmonster.nocheatplus.permissions.Permissions; import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
public class InfoCommand extends NCPCommand { public class InfoCommand extends NCPCommand {
@ -40,7 +40,7 @@ public class InfoCommand extends NCPCommand {
* @return true, if successful * @return true, if successful
*/ */
private void handleInfoCommand(final CommandSender sender, String playerName) { private void handleInfoCommand(final CommandSender sender, String playerName) {
final Player player = Bukkit.getPlayerExact(playerName); final Player player = DataManager.getPlayer(playerName);
if (player != null) playerName = player.getName(); if (player != null) playerName = player.getName();
final ViolationHistory history = ViolationHistory.getHistory(playerName, false); final ViolationHistory history = ViolationHistory.getHistory(playerName, false);

View File

@ -3,7 +3,6 @@ package fr.neatmonster.nocheatplus.command.admin;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -48,7 +47,7 @@ public class RemovePlayerCommand extends NCPCommand {
return true; return true;
} }
final Player player = Bukkit.getPlayerExact(playerName); final Player player = DataManager.getPlayer(playerName);
if (player != null) playerName = player.getName(); if (player != null) playerName = player.getName();
ViolationHistory hist = ViolationHistory.getHistory(playerName, false); ViolationHistory hist = ViolationHistory.getHistory(playerName, false);

View File

@ -3,7 +3,6 @@ package fr.neatmonster.nocheatplus.command.admin;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import org.bukkit.Bukkit;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -14,6 +13,7 @@ import fr.neatmonster.nocheatplus.command.CommandUtil;
import fr.neatmonster.nocheatplus.command.NCPCommand; import fr.neatmonster.nocheatplus.command.NCPCommand;
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager; import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
import fr.neatmonster.nocheatplus.permissions.Permissions; import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.utilities.StringUtil; import fr.neatmonster.nocheatplus.utilities.StringUtil;
public class UnexemptCommand extends NCPCommand { public class UnexemptCommand extends NCPCommand {
@ -47,7 +47,7 @@ public class UnexemptCommand extends NCPCommand {
return true; return true;
} }
// Find player. // Find player.
final Player player = Bukkit.getPlayerExact(playerName); final Player player = DataManager.getPlayer(playerName);
if (player != null) playerName = player.getName(); if (player != null) playerName = player.getName();
NCPExemptionManager.unexempt(playerName, checkType); NCPExemptionManager.unexempt(playerName, checkType);
sender.sendMessage(TAG + "Player " + playerName + " will not be exempted from: " + checkType); sender.sendMessage(TAG + "Player " + playerName + " will not be exempted from: " + checkType);

View File

@ -10,6 +10,7 @@ import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
@ -66,6 +67,14 @@ public class DataManager implements Listener, INotifyReload, INeedConfig, Compon
*/ */
private final Map<String, Long> lastLogout = new LinkedHashMap<String, Long>(50, 0.75f, true); private final Map<String, Long> lastLogout = new LinkedHashMap<String, Long>(50, 0.75f, true);
/**
* Keeping track of online players.<br>
* Mappings:
* <li>exact player name -> Player instance</li>
* <li>lower case player name -> Player instance</li>
*/
protected final Map<String, Player> onlinePlayers = new LinkedHashMap<String, Player>(100);
/** /**
* IRemoveData instances. * IRemoveData instances.
* // TODO: might use a map for those later (extra or not). * // TODO: might use a map for those later (extra or not).
@ -132,6 +141,7 @@ public class DataManager implements Listener, INotifyReload, INeedConfig, Compon
final Player player = event.getPlayer(); final Player player = event.getPlayer();
lastLogout.remove(player.getName()); lastLogout.remove(player.getName());
CombinedData.getData(player).lastJoinTime = System.currentTimeMillis(); CombinedData.getData(player).lastJoinTime = System.currentTimeMillis();
addOnlinePlayer(player);
} }
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)
@ -152,6 +162,7 @@ public class DataManager implements Listener, INotifyReload, INeedConfig, Compon
final long now = System.currentTimeMillis(); final long now = System.currentTimeMillis();
lastLogout.put(player.getName(), now); lastLogout.put(player.getName(), now);
CombinedData.getData(player).lastLogoutTime = now; CombinedData.getData(player).lastLogoutTime = now;
removeOnlinePlayer(player);
} }
@Override @Override
@ -312,6 +323,23 @@ public class DataManager implements Listener, INotifyReload, INeedConfig, Compon
MovingConfig.clear(); MovingConfig.clear();
} }
/**
* This gets an online player by exact player name or lower-case player name only [subject to change].
* @param playerName
* @return
*/
public static Player getPlayerExact(final String playerName){
return instance.onlinePlayers.get(playerName);
}
/**
* This gets the online player with the exact name, but transforms the input to lower case.
* @param playerName
* @return
*/
public static Player getPlayer(final String playerName){
return instance.onlinePlayers.get(playerName.toLowerCase());
}
@Override @Override
public boolean addComponent(Object obj) { public boolean addComponent(Object obj) {
@ -336,6 +364,36 @@ public class DataManager implements Listener, INotifyReload, INeedConfig, Compon
} }
} }
/**
* Initializing with online players.
*/
public void onEnable(){
final Player[] players = Bukkit.getOnlinePlayers();
for (final Player player : players){
addOnlinePlayer(player);
}
}
/**
* Add mappings for player names variations.
* @param player
*/
private void addOnlinePlayer(final Player player){
final String name = player.getName();
onlinePlayers.put(name, player);
onlinePlayers.put(name.toLowerCase(), player);
}
/**
* Remove mappings for player names variations.
* @param player
*/
private void removeOnlinePlayer(final Player player){
final String name = player.getName();
onlinePlayers.remove(name);
onlinePlayers.remove(name.toLowerCase());
}
/** /**
* Cleanup method, removes all data and config, but does not call ConfigManager.cleanup. * Cleanup method, removes all data and config, but does not call ConfigManager.cleanup.
*/ */
@ -348,10 +406,12 @@ public class DataManager implements Listener, INotifyReload, INeedConfig, Compon
clearConfigs(); clearConfigs();
lastLogout.clear(); lastLogout.clear();
executionHistories.clear(); executionHistories.clear();
onlinePlayers.clear();
} }
@Override @Override
public String getComponentName() { public String getComponentName() {
return "NoCheatPlus_DataManager"; return "NoCheatPlus_DataManager";
} }
} }

View File

@ -127,7 +127,7 @@ public class TickTask implements Runnable {
permissionUpdates.clear(); permissionUpdates.clear();
} }
for (final PermissionUpdateEntry entry : copyPermissions){ for (final PermissionUpdateEntry entry : copyPermissions){
final Player player = Bukkit.getPlayerExact(entry.playerName); final Player player = DataManager.getPlayer(entry.playerName); // Might use exact name by contract.
if (player == null || !player.isOnline()) continue; if (player == null || !player.isOnline()) continue;
final String[] perms = entry.checkType.getConfigFactory().getConfig(player).getCachePermissions(); final String[] perms = entry.checkType.getConfigFactory().getConfig(player).getCachePermissions();
if (perms == null) continue; if (perms == null) continue;