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.ChatColor;
import org.bukkit.Server;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
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);
if (names == null) return 0;
int done = 0;
final Server server = Bukkit.getServer();
for (final String name : names){
final Player player = server.getPlayerExact(name);
final Player player = DataManager.getPlayerExact(name);
if (player != null){
player.sendMessage(message);
done ++;
@ -488,6 +486,9 @@ public class NoCheatPlus extends JavaPlugin implements NoCheatPlusAPI {
// Initialize BlockProperties
initBlockProperties(config);
// Initialize data manager.
dataMan.onEnable();
// Allow entries to TickTask (just in case).
TickTask.setLocked(false);

View File

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

View File

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

View File

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

View File

@ -1,6 +1,5 @@
package fr.neatmonster.nocheatplus.command.actions;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -8,6 +7,7 @@ import org.bukkit.entity.Player;
import fr.neatmonster.nocheatplus.NoCheatPlus;
import fr.neatmonster.nocheatplus.command.DelayableCommand;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.utilities.ColorUtil;
/**
@ -37,7 +37,7 @@ public class TellCommand extends DelayableCommand {
}
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));
}

View File

@ -1,6 +1,5 @@
package fr.neatmonster.nocheatplus.command.actions;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -9,6 +8,7 @@ import fr.neatmonster.nocheatplus.NoCheatPlus;
import fr.neatmonster.nocheatplus.command.DelayableCommand;
import fr.neatmonster.nocheatplus.logging.LogUtil;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
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){
Player player = Bukkit.getPlayerExact(name);
Player player = DataManager.getPlayer(name);
NoCheatPlus.denyLogin(name, duration);
if (player == null) return;
player.kickPlayer(reason);

View File

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

View File

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

View File

@ -4,7 +4,6 @@ import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
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.command.NCPCommand;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
public class InfoCommand extends NCPCommand {
@ -40,7 +40,7 @@ public class InfoCommand extends NCPCommand {
* @return true, if successful
*/
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();
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.List;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -48,7 +47,7 @@ public class RemovePlayerCommand extends NCPCommand {
return true;
}
final Player player = Bukkit.getPlayerExact(playerName);
final Player player = DataManager.getPlayer(playerName);
if (player != null) playerName = player.getName();
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.List;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
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.hooks.NCPExemptionManager;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.utilities.StringUtil;
public class UnexemptCommand extends NCPCommand {
@ -47,7 +47,7 @@ public class UnexemptCommand extends NCPCommand {
return true;
}
// Find player.
final Player player = Bukkit.getPlayerExact(playerName);
final Player player = DataManager.getPlayer(playerName);
if (player != null) playerName = player.getName();
NCPExemptionManager.unexempt(playerName, 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.Set;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
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);
/**
* 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.
* // TODO: might use a map for those later (extra or not).
@ -131,7 +140,8 @@ public class DataManager implements Listener, INotifyReload, INeedConfig, Compon
public void onPlayerJoin(final PlayerJoinEvent event){
final Player player = event.getPlayer();
lastLogout.remove(player.getName());
CombinedData.getData(player).lastJoinTime = System.currentTimeMillis();
CombinedData.getData(player).lastJoinTime = System.currentTimeMillis();
addOnlinePlayer(player);
}
@EventHandler(priority = EventPriority.MONITOR)
@ -152,8 +162,9 @@ public class DataManager implements Listener, INotifyReload, INeedConfig, Compon
final long now = System.currentTimeMillis();
lastLogout.put(player.getName(), now);
CombinedData.getData(player).lastLogoutTime = now;
removeOnlinePlayer(player);
}
@Override
public void onReload() {
// present.
@ -312,6 +323,23 @@ public class DataManager implements Listener, INotifyReload, INeedConfig, Compon
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
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.
*/
@ -348,10 +406,12 @@ public class DataManager implements Listener, INotifyReload, INeedConfig, Compon
clearConfigs();
lastLogout.clear();
executionHistories.clear();
onlinePlayers.clear();
}
@Override
public String getComponentName() {
return "NoCheatPlus_DataManager";
}
}

View File

@ -127,7 +127,7 @@ public class TickTask implements Runnable {
permissionUpdates.clear();
}
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;
final String[] perms = entry.checkType.getConfigFactory().getConfig(player).getCachePermissions();
if (perms == null) continue;