Skip to content

Commit

Permalink
[BLEEDING][BREAKING] Store PlayerData by UUID, use a PlayerTickListener.
Browse files Browse the repository at this point in the history
Instead of maps for each individual purpose, and the rather expensive
TickListener adding and removing, player specific task will be done via
one PlayerTickListener that can be registered with the TickTask. Thus
PlayerData has the access methods requestUpdateInventory and
requestPlayerSetBack, and so on, later more. For the
DataManager.playerData map it'll be UUID first now.

Consequently some calls have been altered to prefer passing Player or
UUID for PlayerData getting.
  • Loading branch information
asofold committed Apr 8, 2017
1 parent 0cd0d50 commit 9a4b3f6
Show file tree
Hide file tree
Showing 8 changed files with 268 additions and 205 deletions.
Expand Up @@ -84,7 +84,7 @@ public void onItemConsume(final PlayerItemConsumeEvent event){
final long time = System.currentTimeMillis();
if (check(player, event.getItem(), time, data)){
event.setCancelled(true);
DataManager.getPlayerData(player).task.updateInventory();
DataManager.getPlayerData(player).requestUpdateInventory();
}
}

Expand Down
Expand Up @@ -104,6 +104,7 @@
import fr.neatmonster.nocheatplus.logging.debug.DebugUtil;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.players.PlayerData;
import fr.neatmonster.nocheatplus.stats.Counters;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.utilities.PotionUtil;
Expand Down Expand Up @@ -527,7 +528,6 @@ else if (data.hasTeleported()) {
private boolean handleTeleportedOnMove(final Player player, final PlayerMoveEvent event,
final MovingData data, final MovingConfig cc) {
// This could also happen with a packet based set back such as with cancelling move events.
// TODO: Alter the move from location and let it get through?
if (data.isTeleportedPosition(event.getFrom())) {
// Treat as ACK (!).
// Adjust.
Expand All @@ -538,8 +538,9 @@ private boolean handleTeleportedOnMove(final Player player, final PlayerMoveEven
}
return false;
}
else if (TickTask.isPlayerGoingToBeSetBack(player.getUniqueId())) {
else if (DataManager.getPlayerData(player).isPlayerSetBackScheduled()) {
// A set back has been scheduled, but the player is moving randomly.
// TODO: Instead alter the move from location and let it get through? +- when
event.setCancelled(true);
if (data.debug) {
debug(player, "Cancel move, due to a scheduled teleport (set back).");
Expand Down Expand Up @@ -1448,16 +1449,16 @@ private void onCancelledMove(final Player player, final Location from, final int
}
if (method.shouldSchedule()) {
// Schedule the teleport, because it might be faster than the next incoming packet.
final UUID playerId = player.getUniqueId();
if (!TickTask.isPlayerGoingToBeSetBack(playerId)) {
TickTask.requestPlayerSetBack(playerId);
final PlayerData pd = DataManager.getPlayerData(player);
if (pd.isPlayerSetBackScheduled()) {
debug(player, "Teleport (set back) already scheduled to: " + ref);
}
else if (mData.debug) {
pd.requestPlayerSetBack();
if (mData.debug) {
debug(player, "Schedule teleport (set back) to: " + ref);
}
}
else if (mData.debug) {
debug(player, "Teleport (set back) already scheduled to: " + ref);
}
}
// (Position adaption will happen with the teleport on tick, or with the next move.)
}
Expand Down Expand Up @@ -1526,14 +1527,15 @@ private void onPlayerMoveMonitorNotCancelledHasTeleported(final Player player, f
if (mData.debug) {
debug(player, "Event not cancelled, with teleported (set back) set, assume legacy behavior.");
}
return;
}
else if (TickTask.isPlayerGoingToBeSetBack(player.getUniqueId())) {
else if (DataManager.getPlayerData(player).isPlayerSetBackScheduled()) {
// Skip, because the scheduled teleport has been overridden.
// TODO: Only do this, if cancel is set, because it is not an un-cancel otherwise.
if (mData.debug) {
debug(player, "Event not cancelled, despite a set back has been scheduled. Ignore set back.");
debug(player, "Event not cancelled, despite a set back has been scheduled. Cancel set back.");
}
mData.resetTeleported(); // (TickTask will notice it's not set.)
mData.resetTeleported(); // (PlayerTickListener will notice it's not set.)
}
else {
if (mData.debug) {
Expand Down Expand Up @@ -1921,7 +1923,7 @@ private void onPlayerTeleportMonitorNullTarget(final Player player, final Player
debugTeleportMessage(player, event, "No target location (to) set.");
}
if (data.hasTeleported()) {
if (TickTask.isPlayerGoingToBeSetBack(player.getUniqueId())) {
if (DataManager.getPlayerData(player).isPlayerSetBackScheduled()) {
// Assume set back event following later.
event.setCancelled(true);
if (data.debug) {
Expand Down
Expand Up @@ -32,15 +32,18 @@
import fr.neatmonster.nocheatplus.checks.moving.magic.Magic;
import fr.neatmonster.nocheatplus.checks.moving.model.MoveData;
import fr.neatmonster.nocheatplus.checks.moving.model.PlayerMoveData;
import fr.neatmonster.nocheatplus.checks.moving.player.PlayerSetBackMethod;
import fr.neatmonster.nocheatplus.checks.net.NetData;
import fr.neatmonster.nocheatplus.checks.net.model.CountableLocation;
import fr.neatmonster.nocheatplus.compat.Bridge1_9;
import fr.neatmonster.nocheatplus.compat.BridgeMisc;
import fr.neatmonster.nocheatplus.compat.MCAccess;
import fr.neatmonster.nocheatplus.components.debug.IDebugPlayer;
import fr.neatmonster.nocheatplus.hooks.NCPExemptionManager;
import fr.neatmonster.nocheatplus.logging.StaticLog;
import fr.neatmonster.nocheatplus.permissions.Permissions;
import fr.neatmonster.nocheatplus.players.DataManager;
import fr.neatmonster.nocheatplus.utilities.CheckUtils;
import fr.neatmonster.nocheatplus.utilities.TickTask;
import fr.neatmonster.nocheatplus.utilities.location.PlayerLocation;
import fr.neatmonster.nocheatplus.utilities.location.RichBoundsLocation;
import fr.neatmonster.nocheatplus.utilities.location.TrigUtil;
Expand Down Expand Up @@ -411,8 +414,65 @@ public static boolean hasScheduledPlayerSetBack(final Player player) {
* @return
*/
public static boolean hasScheduledPlayerSetBack(final UUID playerId, final MovingData data) {
return TickTask.isPlayerGoingToBeSetBack(playerId)
&& data.hasTeleported();
return data.hasTeleported() && DataManager.getPlayerData(playerId).isPlayerSetBackScheduled();
}

/**
*
* @param player
* @param debugMessagePrefix
* @return
*/
public static boolean processStoredSetBack(final Player player, final String debugMessagePrefix) {
final MovingData data = MovingData.getData(player);
if (!data.hasTeleported()) {
if (data.debug) {
CheckUtils.debug(player, CheckType.MOVING, debugMessagePrefix + "No stored location available.");
}
return false;
}
// (teleported is set.).
final Location loc = player.getLocation(useLoc);
if (data.isTeleportedPosition(loc)) {
// Skip redundant teleport.
if (data.debug) {
CheckUtils.debug(player, CheckType.MOVING, debugMessagePrefix + "Skip teleport, player is there, already.");
}
useLoc.setWorld(null);
return false;
}
useLoc.setWorld(null);
// (player is somewhere else.)
// TODO: Consider to skip checking for packet level, if not available (plus optimize access).
// TODO: Consider a config flag, so this can be turned off (set back method).
final PlayerSetBackMethod method = MovingConfig.getConfig(player).playerSetBackMethod;
if (method.shouldCancel() || method.shouldSetTo()) {
/*
* Another leniency option: Skip, if we have already received an
* ACK for this position on packet level.
*/
// (CANCEL + UPDATE_FROM mean a certain teleport to the set back, still could be repeated tp.)
final CountableLocation cl = ((NetData) CheckType.NET.getDataFactory().getData(player)).teleportQueue.getLastAck();
if (data.isTeleportedPosition(cl)) {
if (data.debug) {
CheckUtils.debug(player, CheckType.MOVING, debugMessagePrefix + "Skip teleport, having received an ACK for the teleport on packet level.");
}
return false;
}
}

// (No ACK received yet.)
final Location teleported = data.getTeleported();
// (Data resetting is done during PlayerTeleportEvent handling.)
if (player.teleport(teleported, BridgeMisc.TELEPORT_CAUSE_CORRECTION_OF_POSITION)) {
return true;
}
else {
if (data .debug) {
CheckUtils.debug(player, CheckType.MOVING, "Player set back on tick: Teleport failed.");
}
return false;
}
}

}
Expand Up @@ -90,7 +90,7 @@ public class DataManager implements Listener, INeedConfig, ComponentRegistry<IRe

// TODO: Switch to UUIDs as keys, get data by uuid when possible, use PlayerMap for getting
/** PlayerData storage. */
private final Map<String, PlayerData> playerData = new LinkedHashMap<String, PlayerData>(100);
private final Map<UUID, PlayerData> playerData = new LinkedHashMap<UUID, PlayerData>(100);

/**
* Access order for playerName (exact) -> ms time of logout.
Expand Down Expand Up @@ -671,8 +671,7 @@ public static PlayerData getPlayerData(final Player player) {
* @return
*/
public static PlayerData getPlayerData(final UUID playerId, final String playerName, final boolean create) {
final String lcName = playerName.toLowerCase(); // TODO: Store by both lower case and exact case (also store the Player reference).
final PlayerData data = instance.playerData.get(lcName);
final PlayerData data = instance.playerData.get(playerId);
if (data != null) {
return data;
}
Expand All @@ -681,18 +680,30 @@ else if (!create) {
}
else {
final PlayerData newData = new PlayerData(playerId, playerName);
instance.playerData.put(lcName, newData);
instance.playerData.put(playerId, newData);
return newData;
}
}

/**
* Get the player data, if present.
*
* @param playerName
* @return The PlayerData instance if present, null otherwise.
*/
public static PlayerData getPlayerData(final String playerName) {
return instance.playerData.get(playerName.toLowerCase());
final UUID playerId = getUUID(playerName);
return playerId == null ? null : instance.playerData.get(playerId);
}

/**
* Get the player data, if present.
*
* @param playerID
* @return The PlayerData instance if present, null otherwise.
*/
public static PlayerData getPlayerData(final UUID playerID) {
return instance.playerData.get(playerID);
}

/**
Expand Down

0 comments on commit 9a4b3f6

Please sign in to comment.