Skip to content

Commit

Permalink
Update player injection for events
Browse files Browse the repository at this point in the history
Uses MCPlayerEvent to insert the player into the environment, and only uses injection for player_spawn since that is the only known event where an online player cannot be retrieved by name.
  • Loading branch information
PseudoKnight committed Oct 4, 2023
1 parent 45ffc9f commit 6a7749c
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 118 deletions.
76 changes: 34 additions & 42 deletions src/main/java/com/laytonsmith/core/Static.java
Original file line number Diff line number Diff line change
Expand Up @@ -828,46 +828,45 @@ public static MCOfflinePlayer GetUser(String search, Target t) {
}

/**
* Returns the player specified by name. Injected players also are returned in this list. If provided a string
* Returns the player specified by name or UUID. Injected players are also returned in this list. If provided a string
* between 1 and 16 characters, the lookup will be name-based. If provided a string that is 32 or 36 characters, the
* lookup will be uuid-based.
* lookup will be UUID-based. Throws CREPlayerOfflineException if the player is not online.
*
* @param player
* @param t
* @return
* @throws ConfigRuntimeException
*/
public static MCPlayer GetPlayer(String player, Target t) throws ConfigRuntimeException {
MCCommandSender m;

if(player == null) {
throw new CREPlayerOfflineException("No player was specified!", t);
}

MCPlayer p;
if(player.length() > 0 && player.length() <= 16) {
m = GetCommandSender(player, t);
MCCommandSender sender = GetCommandSender(player, t);
if(!(sender instanceof MCPlayer)) {
throw new CREPlayerOfflineException("Expecting a player name, but \"" + player + "\" was found.", t);
}
p = (MCPlayer) sender;
// May be injected, so check if online.
if(!p.isOnline()) {
throw new CREPlayerOfflineException("The specified player (" + player + ") is not online", t);
}
} else {
try {
m = getServer().getPlayer(GetUUID(player, t));
} catch(ConfigRuntimeException cre) {
if(cre instanceof CREThrowable && ((CREThrowable) cre).isInstanceOf(CRELengthException.TYPE)) {
p = getServer().getPlayer(GetUUID(player, t));
if(p == null) {
throw new CREPlayerOfflineException("The specified player (" + player + ") is not online", t);
}
} catch(CREThrowable ex) {
if(ex.isInstanceOf(CRELengthException.TYPE)) {
throw new CRELengthException("The given string was the wrong size to identify a player."
+ " A player name is expected to be between 1 and 16 characters. " + cre.getMessage(), t);
+ " A player name is expected to be between 1 and 16 characters. " + ex.getMessage(), t);
} else {
throw cre;
throw ex;
}
}
}
if(m == null) {
throw new CREPlayerOfflineException("The specified player (" + player + ") is not online", t);
}
if(!(m instanceof MCPlayer)) {
throw new CREPlayerOfflineException("Expecting a player name, but \"" + player + "\" was found.", t);
}
MCPlayer p = (MCPlayer) m;
if(!p.isOnline()) {
throw new CREPlayerOfflineException("The specified player (" + player + ") is not online", t);
}
return p;
}

Expand All @@ -876,34 +875,27 @@ public static MCPlayer GetPlayer(Mixed player, Target t) throws ConfigRuntimeExc
}

/**
* Returns the specified command sender. Players are supported, as is the special ~console user. The special
* ~console user will always return a user.
* Returns the specified command sender by name. Players are supported, as is the special ~console user. The special
* ~console user will always return a user. Throws CREPlayerOfflineException if the player is not online or injected.
*
* @param player
* @param name
* @param t
* @return
* @throws ConfigRuntimeException
*/
public static MCCommandSender GetCommandSender(String player, Target t) throws ConfigRuntimeException {
MCCommandSender m = null;
if(INJECTED_PLAYERS.containsKey(player.toLowerCase())) {
m = INJECTED_PLAYERS.get(player.toLowerCase());
} else if(CONSOLE_NAME.equals(player)) {
m = Static.getServer().getConsole();
} else {
try {
m = Static.getServer().getPlayer(player);
} catch(Exception e) {
//Apparently the server can occasionally throw exceptions here, so instead of rethrowing
//a NPE or whatever, we'll assume that the player just isn't online, and
//throw a CRE instead.
}
public static MCCommandSender GetCommandSender(String name, Target t) throws ConfigRuntimeException {
MCCommandSender injectedPlayer = INJECTED_PLAYERS.get(name.toLowerCase());
if(injectedPlayer != null) {
return injectedPlayer;
}
if(m == null || (m instanceof MCPlayer && (!((MCPlayer) m).isOnline()
&& !INJECTED_PLAYERS.containsKey(player.toLowerCase())))) {
throw new CREPlayerOfflineException("The specified player (" + player + ") is not online", t);
if(CONSOLE_NAME.equals(name)) {
return getServer().getConsole();
}
return m;
MCPlayer p = getServer().getPlayer(name);
if(p == null) {
throw new CREPlayerOfflineException("The specified player (" + name + ") is not online", t);
}
return p;
}

/**
Expand Down
53 changes: 31 additions & 22 deletions src/main/java/com/laytonsmith/core/events/AbstractEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
import com.laytonsmith.PureUtilities.Common.StreamUtils;
import com.laytonsmith.abstraction.MCCommandSender;
import com.laytonsmith.abstraction.MCPlayer;
import com.laytonsmith.abstraction.events.MCPlayerEvent;
import com.laytonsmith.annotations.core;
import com.laytonsmith.annotations.hide;
import com.laytonsmith.core.Documentation;
import com.laytonsmith.core.LogLevel;
import com.laytonsmith.core.MSLog;
import com.laytonsmith.core.MSLog.Tags;
import com.laytonsmith.core.MethodScriptCompiler;
import com.laytonsmith.core.ParseTree;
import com.laytonsmith.core.Static;
Expand All @@ -32,7 +35,6 @@
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;

/**
* This helper class implements a few of the common functions in event, and most (all?) Events should extend this class.
Expand Down Expand Up @@ -105,32 +107,39 @@ public boolean matches(Map<String, Mixed> prefilter, BindableEvent e) throws Pre
@Override
public final void execute(ParseTree tree, BoundEvent b, Environment env, BoundEvent.ActiveEvent activeEvent) throws ConfigRuntimeException {
preExecution(env, activeEvent);
// Various events have a player to put into the env.
// Do this after preExecution() in case the particular event needs to inject the player first.
Mixed c = activeEvent.getParsedEvent().get("player");
if(c != null) {
if(c instanceof CNull) {
// This is a CNull "player", likely from an entity event, so we need to ensure player() does
// not return a player inherited from the bind's parent environment.
if(env.getEnv(CommandHelperEnvironment.class).GetPlayer() != null) {
env.getEnv(CommandHelperEnvironment.class).SetCommandSender(Static.getServer().getConsole());
}
} else {
MCCommandSender p = Static.getServer().getPlayer(c.val());
if(p == null) {
p = Static.GetInjectedPlayer(c.val());
}
if(p != null) {
env.getEnv(CommandHelperEnvironment.class).SetPlayer((MCPlayer) p);
} else {
Static.getLogger().log(Level.WARNING, "Player offline for event: " + b.getEventName());
// Set env CommandSender to prevent incorrect inherited player from being used in a player event.

// Events can have a player to put into the CommandHelperEnvironment.
if(activeEvent.getUnderlyingEvent() instanceof MCPlayerEvent playerEvent) {
env.getEnv(CommandHelperEnvironment.class).SetPlayer(playerEvent.getPlayer());
} else {
// Probably not a player event, but might still have a player context.
Mixed c = activeEvent.getParsedEvent().get("player");
if(c != null) {
if(c instanceof CNull) {
// This is a CNull "player", likely from an entity event, so we need to ensure player() does
// not return a player inherited from the bind's parent environment.
if(env.getEnv(CommandHelperEnvironment.class).GetPlayer() != null) {
env.getEnv(CommandHelperEnvironment.class).SetCommandSender(Static.getServer().getConsole());
env.getEnv(CommandHelperEnvironment.class).SetPlayer(null);
}
} else {
MCCommandSender p = Static.getServer().getPlayer(c.val());
if(p == null) {
// Check if event (possibly from an extension) injected the player but didn't extend MCPlayerEvent
p = Static.GetInjectedPlayer(c.val());
}
if(p != null) {
env.getEnv(CommandHelperEnvironment.class).SetPlayer((MCPlayer) p);
} else {
MSLog.GetLogger().w(Tags.GENERAL, c.val() + " offline for " + b.getEventName(), tree.getTarget());
// Set env CommandSender to prevent incorrect inherited player from being used in a player event.
if(env.getEnv(CommandHelperEnvironment.class).GetPlayer() != null) {
env.getEnv(CommandHelperEnvironment.class).SetPlayer(null);
}
}
}
}
}

ProfilePoint event = null;
if(env.getEnv(StaticRuntimeEnv.class).GetProfiler() != null) {
event = env.getEnv(StaticRuntimeEnv.class).GetProfiler().start(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -664,24 +664,6 @@ public MSVersion since() {
return MSVersion.V3_3_1;
}

@Override
public void preExecution(Environment env, ActiveEvent activeEvent) {
if(activeEvent.getUnderlyingEvent() instanceof MCPlayerLoginEvent) {
//Static lookups of the player don't seem to work here, but
//the player is passed in with the event.
MCPlayer player = ((MCPlayerLoginEvent) activeEvent.getUnderlyingEvent()).getPlayer();
Static.InjectPlayer(player);
}
}

@Override
public void postExecution(Environment env, ActiveEvent activeEvent) {
if(activeEvent.getUnderlyingEvent() instanceof MCPlayerLoginEvent) {
MCPlayer player = ((MCPlayerLoginEvent) activeEvent.getUnderlyingEvent()).getPlayer();
Static.UninjectPlayer(player);
}
}

}

@api
Expand Down Expand Up @@ -772,24 +754,6 @@ public BindableEvent convert(CArray manual, Target t) {
return e;
}

@Override
public void preExecution(Environment env, ActiveEvent activeEvent) {
if(activeEvent.getUnderlyingEvent() instanceof MCPlayerJoinEvent) {
//Static lookups of the player as entity don't seem to work here, but
//the player is passed in with the event.
MCPlayer player = ((MCPlayerJoinEvent) activeEvent.getUnderlyingEvent()).getPlayer();
Static.InjectEntity(player);
}
}

@Override
public void postExecution(Environment env, ActiveEvent activeEvent) {
if(activeEvent.getUnderlyingEvent() instanceof MCPlayerJoinEvent) {
MCPlayer player = ((MCPlayerJoinEvent) activeEvent.getUnderlyingEvent()).getPlayer();
Static.UninjectEntity(player);
}
}

}

@api
Expand Down Expand Up @@ -1501,24 +1465,6 @@ public boolean modifyEvent(String key, Mixed value, BindableEvent event) {
}
return false;
}

@Override
public void preExecution(Environment env, ActiveEvent activeEvent) {
if(activeEvent.getUnderlyingEvent() instanceof MCPlayerQuitEvent) {
//Static lookups of the player don't seem to work here, but
//the player is passed in with the event.
MCPlayer player = ((MCPlayerQuitEvent) activeEvent.getUnderlyingEvent()).getPlayer();
Static.InjectPlayer(player);
}
}

@Override
public void postExecution(Environment env, ActiveEvent activeEvent) {
if(activeEvent.getUnderlyingEvent() instanceof MCPlayerQuitEvent) {
MCPlayer player = ((MCPlayerQuitEvent) activeEvent.getUnderlyingEvent()).getPlayer();
Static.UninjectPlayer(player);
}
}
}

@api
Expand Down

0 comments on commit 6a7749c

Please sign in to comment.