PlayerState improvements. MUtil#prepareCommand(String).

This commit is contained in:
Olof Larsson 2016-05-20 12:11:21 +02:00
parent b44750a64c
commit b780fd8f30
No known key found for this signature in database
GPG Key ID: BBEF14F97DA52474
2 changed files with 163 additions and 57 deletions

View File

@ -11,9 +11,7 @@ import org.bukkit.event.EventPriority;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.MassiveCore;
import com.massivecraft.massivecore.PlayerState;
import com.massivecraft.massivecore.event.EventMassiveCorePlayerLeave;
import com.massivecraft.massivecore.util.MUtil;
@ -36,10 +34,10 @@ public class EngineMassiveCorePlayerState extends Engine
{
if ( ! active) return;
idToState.clear();
this.idToState.clear();
for (Player player : MUtil.getOnlinePlayers())
{
idToState.put(player.getUniqueId(), PlayerState.JOINED);
this.idToState.put(player.getUniqueId(), PlayerState.JOINED);
}
}
@ -47,30 +45,88 @@ public class EngineMassiveCorePlayerState extends Engine
// STATE STORAGE
// -------------------------------------------- //
protected Map<UUID, PlayerState> idToState = new ConcurrentHashMap<UUID, PlayerState>();
public PlayerState getState(UUID id)
{
PlayerState ret = this.idToState.get(id);
if (ret == null) ret = PlayerState.LEFT;
return ret;
}
private Map<UUID, PlayerState> idToState = new ConcurrentHashMap<UUID, PlayerState>();
public PlayerState getState(Player player)
{
return this.getState(player.getUniqueId());
if (player == null) throw new NullPointerException("player");
if (MUtil.isntPlayer(player)) return PlayerState.JOINED;
UUID id = player.getUniqueId();
return this.getState(id);
}
public PlayerState getState(UUID id)
{
if (id == null) throw new NullPointerException("id");
PlayerState ret = this.idToState.get(id);
if (ret == null) ret = PlayerState.LEFT;
return ret;
}
public void setState(Player player, PlayerState state, boolean delayed, PlayerState replaceable)
{
if (player == null) throw new NullPointerException("player");
if (MUtil.isntPlayer(player)) return;
UUID id = player.getUniqueId();
this.setState(id, state, delayed, replaceable);
}
public void setState(final UUID id, final PlayerState state, boolean delayed, final PlayerState replaceable)
{
// Delayed!
if (delayed)
{
Bukkit.getScheduler().runTask(this.getPlugin(), new Runnable()
{
@Override
public void run()
{
EngineMassiveCorePlayerState.this.setState(id, state, false, replaceable);
}
});
return;
}
// Immediately!
// Before
PlayerState before = this.idToState.get(id);
if (before == null) before = PlayerState.LEFT;
// After
PlayerState after = state;
if (after == null) after = PlayerState.LEFT;
// NoChange
if (before == after) return;
// Not Replaceable
if (replaceable != null && replaceable != before) return;
// Perform
if (after != PlayerState.LEFT)
{
this.idToState.put(id, after);
}
else
{
this.idToState.remove(id);
}
}
// -------------------------------------------- //
// LOGASYNC
// -------------------------------------------- //
// AsyncPlayerPreLoginEvent: LOWEST and MONITOR
@EventHandler(priority = EventPriority.LOWEST)
public void logasync(AsyncPlayerPreLoginEvent event)
{
final UUID id = event.getUniqueId();
this.idToState.put(id, PlayerState.LOGASYNC);
UUID id = event.getUniqueId();
PlayerState state = PlayerState.LOGASYNC;
boolean delayed = false;
PlayerState replaceable = PlayerState.LEFT;
this.setState(id, state, delayed, replaceable);
}
@EventHandler(priority = EventPriority.MONITOR)
@ -79,23 +135,26 @@ public class EngineMassiveCorePlayerState extends Engine
// If the player was denied entrance they are now offline.
if (event.getLoginResult() == AsyncPlayerPreLoginEvent.Result.ALLOWED) return;
final UUID id = event.getUniqueId();
this.idToState.remove(id);
UUID id = event.getUniqueId();
PlayerState state = PlayerState.LEFT;
boolean delayed = false; // We would actually like to delay but this only works properly for synchronous events.
PlayerState replaceable = PlayerState.LOGASYNC;
this.setState(id, state, delayed, replaceable);
}
// -------------------------------------------- //
// LOGSYNC
// -------------------------------------------- //
// PlayerLoginEvent: LOWEST and MONITOR DELAYED
@EventHandler(priority = EventPriority.LOWEST)
public void logsync(PlayerLoginEvent event)
{
final Player player = event.getPlayer();
if (MUtil.isntPlayer(player)) return;
final UUID id = player.getUniqueId();
this.idToState.put(id, PlayerState.LOGSYNC);
Player player = event.getPlayer();
PlayerState state = PlayerState.LOGSYNC;
boolean delayed = false;
PlayerState replaceable = null;
this.setState(player, state, delayed, replaceable);
}
@EventHandler(priority = EventPriority.MONITOR)
@ -104,74 +163,71 @@ public class EngineMassiveCorePlayerState extends Engine
// If the player was denied entrance they are now offline.
if (event.getResult() == PlayerLoginEvent.Result.ALLOWED) return;
final Player player = event.getPlayer();
if (MUtil.isntPlayer(player)) return;
final UUID id = player.getUniqueId();
this.idToState.remove(id);
Player player = event.getPlayer();
PlayerState state = PlayerState.LEFT;
boolean delayed = true;
PlayerState replaceable = PlayerState.LOGSYNC;
this.setState(player, state, delayed, replaceable);
}
// -------------------------------------------- //
// JOINING
// -------------------------------------------- //
// PlayerJoinEvent: LOWEST
@EventHandler(priority = EventPriority.LOWEST)
public void joining(PlayerJoinEvent event)
{
final Player player = event.getPlayer();
if (MUtil.isntPlayer(player)) return;
final UUID id = player.getUniqueId();
this.idToState.put(id, PlayerState.JOINING);
Player player = event.getPlayer();
PlayerState state = PlayerState.JOINING;
boolean delayed = false;
PlayerState replaceable = null;
this.setState(player, state, delayed, replaceable);
}
// -------------------------------------------- //
// JOINED
// -------------------------------------------- //
// PlayerJoinEvent: MONITOR DELAYED
@EventHandler(priority = EventPriority.MONITOR)
public void joined(PlayerJoinEvent event)
{
final Player player = event.getPlayer();
if (MUtil.isntPlayer(player)) return;
final UUID id = player.getUniqueId();
Bukkit.getScheduler().scheduleSyncDelayedTask(MassiveCore.get(), new Runnable()
{
@Override
public void run()
{
idToState.put(id, PlayerState.JOINED);
}
});
Player player = event.getPlayer();
PlayerState state = PlayerState.JOINED;
boolean delayed = true;
PlayerState replaceable = PlayerState.JOINING;
this.setState(player, state, delayed, replaceable);
}
// -------------------------------------------- //
// LEAVING
// -------------------------------------------- //
// EventMassiveCorePlayerLeave: LOWEST
@EventHandler(priority = EventPriority.LOWEST)
public void leaving(EventMassiveCorePlayerLeave event)
{
final Player player = event.getPlayer();
if (MUtil.isntPlayer(player)) return;
final UUID id = player.getUniqueId();
this.idToState.put(id, PlayerState.LEAVING);
Player player = event.getPlayer();
PlayerState state = PlayerState.LEAVING;
boolean delayed = false;
PlayerState replaceable = null;
this.setState(player, state, delayed, replaceable);
}
// -------------------------------------------- //
// LEFT
// -------------------------------------------- //
// EventMassiveCorePlayerLeave: MONITOR DELAYED
@EventHandler(priority = EventPriority.MONITOR)
public void left(PlayerQuitEvent event)
public void left(EventMassiveCorePlayerLeave event)
{
final Player player = event.getPlayer();
if (MUtil.isntPlayer(player)) return;
final UUID id = player.getUniqueId();
this.idToState.remove(id);
Player player = event.getPlayer();
PlayerState state = PlayerState.LEFT;
boolean delayed = true;
PlayerState replaceable = PlayerState.LEAVING;
this.setState(player, state, delayed, replaceable);
}
}

View File

@ -58,6 +58,7 @@ import org.bukkit.potion.PotionEffectType;
import org.bukkit.projectiles.ProjectileSource;
import com.massivecraft.massivecore.MassiveCore;
import com.massivecraft.massivecore.collections.ExceptionSet;
import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.collections.MassiveSet;
import com.massivecraft.massivecore.collections.MassiveTreeSet;
@ -239,6 +240,55 @@ public class MUtil
return asUuid(string) != null;
}
// -------------------------------------------- //
// CONTAINS COMMAND
// -------------------------------------------- //
public static boolean containsCommand(String needle, ExceptionSet haystack)
{
boolean ret = haystack.isStandard();
if (containsCommand(needle, haystack.exceptions)) ret = !ret;
return ret;
}
public static boolean containsCommand(String needle, Iterable<String> haystack)
{
if (needle == null) return false;
needle = prepareCommand(needle);
for (String straw : haystack)
{
if (straw == null) continue;
straw = prepareCommand(straw);
// If it starts with then it is possibly a subject.
if ( ! needle.startsWith(straw)) continue;
// Get the remainder.
String remainder = needle.substring(straw.length());
// If they were equal, definitely true.
if (remainder.isEmpty()) return true;
// If the next is a space, the space is used as separator for sub commands or arguments.
// Otherwise it might just have been another command coincidentally starting with the first command.
// The old behaviour was if (needle.startsWith(straw)) return true;
// If "s" was block, then all commands starting with "s" was, now it isn't.
if (remainder.startsWith(" ")) return true;
}
return false;
}
private static String prepareCommand(String string)
{
if (string == null) return null;
string = Txt.removeLeadingCommandDust(string);
string = string.toLowerCase();
string = string.trim();
return string;
}
// -------------------------------------------- //
// IP
// -------------------------------------------- //