From 9f191fa52df164239c52e9c9d716d2ffa7625d58 Mon Sep 17 00:00:00 2001
From: Pieter12345
Date: Sun, 5 Feb 2023 02:36:41 +0100
Subject: [PATCH 1/3] Always inject player for player events
Prevent player events from firing for offline players in edge cases where players have just left the server.
---
.../core/events/drivers/PlayerEvents.java | 146 ++++++------------
1 file changed, 47 insertions(+), 99 deletions(-)
diff --git a/src/main/java/com/laytonsmith/core/events/drivers/PlayerEvents.java b/src/main/java/com/laytonsmith/core/events/drivers/PlayerEvents.java
index 61c0d7723..fa8151442 100644
--- a/src/main/java/com/laytonsmith/core/events/drivers/PlayerEvents.java
+++ b/src/main/java/com/laytonsmith/core/events/drivers/PlayerEvents.java
@@ -24,6 +24,7 @@
import com.laytonsmith.abstraction.events.MCFoodLevelChangeEvent;
import com.laytonsmith.abstraction.events.MCGamemodeChangeEvent;
import com.laytonsmith.abstraction.events.MCPlayerEnterBedEvent;
+import com.laytonsmith.abstraction.events.MCPlayerEvent;
import com.laytonsmith.abstraction.events.MCPlayerLeaveBedEvent;
import com.laytonsmith.abstraction.events.MCPlayerChatEvent;
import com.laytonsmith.abstraction.events.MCPlayerCommandEvent;
@@ -115,8 +116,29 @@ public static String docs() {
return "Contains events related to a player";
}
+ public abstract static class AbstractPlayerEvent extends AbstractEvent {
+
+ @Override
+ public void preExecution(Environment env, ActiveEvent activeEvent) {
+ if(activeEvent.getUnderlyingEvent() instanceof MCPlayerEvent) {
+
+ // Static lookups of the player might not work here, but the player is passed in with the event.
+ MCPlayer player = ((MCPlayerEvent) activeEvent.getUnderlyingEvent()).getPlayer();
+ Static.InjectPlayer(player);
+ }
+ }
+
+ @Override
+ public void postExecution(Environment env, ActiveEvent activeEvent) {
+ if(activeEvent.getUnderlyingEvent() instanceof MCPlayerEvent) {
+ MCPlayer player = ((MCPlayerEvent) activeEvent.getUnderlyingEvent()).getPlayer();
+ Static.UninjectPlayer(player);
+ }
+ }
+ }
+
@api
- public static class food_level_changed extends AbstractEvent {
+ public static class food_level_changed extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -193,7 +215,7 @@ public MSVersion since() {
}
@api
- public static class player_consume extends AbstractEvent {
+ public static class player_consume extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -283,7 +305,7 @@ public MSVersion since() {
}
@api
- public static class player_kick extends AbstractEvent {
+ public static class player_kick extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -361,7 +383,7 @@ public MSVersion since() {
}
@api
- public static class player_teleport extends AbstractEvent {
+ public static class player_teleport extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -580,7 +602,7 @@ public MSVersion since() {
}
@api
- public static class player_login extends AbstractEvent {
+ public static class player_login extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -661,29 +683,10 @@ public boolean modifyEvent(String key, Mixed value, BindableEvent e) {
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
- public static class player_join extends AbstractEvent {
+ public static class player_join extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -769,29 +772,10 @@ public BindableEvent convert(CArray manual, Target t) {
manual.get("join_message", Target.UNKNOWN).val());
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
- public static class player_interact extends AbstractEvent {
+ public static class player_interact extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -961,7 +945,7 @@ public boolean modifyEvent(String key, Mixed value, BindableEvent event) {
}
@api
- public static class player_enter_bed extends AbstractEvent {
+ public static class player_enter_bed extends AbstractPlayerEvent {
@Override
public String docs() {
@@ -1040,7 +1024,7 @@ public BindableEvent convert(CArray manual, Target t) {
}
@api
- public static class player_leave_bed extends AbstractEvent {
+ public static class player_leave_bed extends AbstractPlayerEvent {
@Override
public String docs() {
@@ -1107,7 +1091,7 @@ public BindableEvent convert(CArray manual, Target t) {
}
@api
- public static class pressure_plate_activated extends AbstractEvent {
+ public static class pressure_plate_activated extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -1178,7 +1162,7 @@ public MSVersion since() {
}
@api
- public static class player_spawn extends AbstractEvent {
+ public static class player_spawn extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -1287,24 +1271,6 @@ public boolean modifyEvent(String key, Mixed value, BindableEvent event) {
}
return false;
}
-
- @Override
- public void preExecution(Environment env, ActiveEvent activeEvent) {
- if(activeEvent.getUnderlyingEvent() instanceof MCPlayerRespawnEvent) {
- //Static lookups of the player don't seem to work here, but
- //the player is passed in with the event.
- MCPlayer player = ((MCPlayerRespawnEvent) activeEvent.getUnderlyingEvent()).getPlayer();
- Static.InjectPlayer(player);
- }
- }
-
- @Override
- public void postExecution(Environment env, ActiveEvent activeEvent) {
- if(activeEvent.getUnderlyingEvent() instanceof MCPlayerRespawnEvent) {
- MCPlayer player = ((MCPlayerRespawnEvent) activeEvent.getUnderlyingEvent()).getPlayer();
- Static.UninjectPlayer(player);
- }
- }
}
@api
@@ -1432,7 +1398,7 @@ public boolean modifyEvent(String key, Mixed value, BindableEvent event) {
}
@api
- public static class player_quit extends AbstractEvent {
+ public static class player_quit extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -1499,28 +1465,10 @@ 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
- public static class player_chat extends AbstractEvent {
+ public static class player_chat extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -1659,7 +1607,7 @@ public boolean modifyEvent(String key, Mixed value, BindableEvent event) {
@api
@hide("Experimental until further notice")
- public static class async_player_chat extends AbstractEvent {
+ public static class async_player_chat extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -1779,7 +1727,7 @@ public boolean modifyEvent(String key, Mixed value, BindableEvent event) {
}
@api
- public static class player_command extends AbstractEvent {
+ public static class player_command extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -1892,7 +1840,7 @@ public void cancel(BindableEvent o, boolean state) {
}
@api
- public static class world_changed extends AbstractEvent {
+ public static class world_changed extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -1991,7 +1939,7 @@ public static Map GetLastLocations(Integer i) {
}
@api
- public static class player_move extends AbstractEvent {
+ public static class player_move extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -2122,7 +2070,7 @@ public MSVersion since() {
}
@api
- public static class player_fish extends AbstractEvent {
+ public static class player_fish extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -2258,7 +2206,7 @@ public void postExecution(Environment env, ActiveEvent activeEvent) {
}
@api
- public static class gamemode_change extends AbstractEvent {
+ public static class gamemode_change extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -2327,7 +2275,7 @@ public Version since() {
}
@api
- public static class exp_change extends AbstractEvent {
+ public static class exp_change extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -2390,7 +2338,7 @@ public Version since() {
}
@api
- public static class book_edited extends AbstractEvent {
+ public static class book_edited extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -2536,7 +2484,7 @@ public boolean modifyEvent(String key, Mixed value, BindableEvent event) {
}
@api
- public static class player_toggle_flight extends AbstractEvent {
+ public static class player_toggle_flight extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -2607,7 +2555,7 @@ public boolean modifyEvent(String key, Mixed value, BindableEvent event) {
}
@api
- public static class player_toggle_sneak extends AbstractEvent {
+ public static class player_toggle_sneak extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -2679,7 +2627,7 @@ public boolean modifyEvent(String key, Mixed value, BindableEvent event) {
}
@api
- public static class player_toggle_sprint extends AbstractEvent {
+ public static class player_toggle_sprint extends AbstractPlayerEvent {
@Override
public String getName() {
@@ -2750,7 +2698,7 @@ public boolean modifyEvent(String key, Mixed value, BindableEvent event) {
}
@api
- public static class resource_pack_status extends AbstractEvent {
+ public static class resource_pack_status extends AbstractPlayerEvent {
@Override
public String getName() {
From e4e391844b3c23f78489450ec3e1499a78bbf744 Mon Sep 17 00:00:00 2001
From: Pieter12345
Date: Mon, 25 Sep 2023 01:03:06 +0200
Subject: [PATCH 2/3] Inject player for player_death event
---
.../core/events/drivers/PlayerEvents.java | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/src/main/java/com/laytonsmith/core/events/drivers/PlayerEvents.java b/src/main/java/com/laytonsmith/core/events/drivers/PlayerEvents.java
index fa8151442..b851a0319 100644
--- a/src/main/java/com/laytonsmith/core/events/drivers/PlayerEvents.java
+++ b/src/main/java/com/laytonsmith/core/events/drivers/PlayerEvents.java
@@ -1395,6 +1395,24 @@ public boolean modifyEvent(String key, Mixed value, BindableEvent event) {
return false;
}
}
+
+ @Override
+ public void preExecution(Environment env, ActiveEvent activeEvent) {
+ if(activeEvent.getUnderlyingEvent() instanceof MCPlayerEvent) {
+
+ // Static lookups of the player might not work here, but the player is passed in with the event.
+ MCPlayer player = ((MCPlayerEvent) activeEvent.getUnderlyingEvent()).getPlayer();
+ Static.InjectPlayer(player);
+ }
+ }
+
+ @Override
+ public void postExecution(Environment env, ActiveEvent activeEvent) {
+ if(activeEvent.getUnderlyingEvent() instanceof MCPlayerEvent) {
+ MCPlayer player = ((MCPlayerEvent) activeEvent.getUnderlyingEvent()).getPlayer();
+ Static.UninjectPlayer(player);
+ }
+ }
}
@api
From b12caff5525c9aa0beed47389b83f5c38c0d44c5 Mon Sep 17 00:00:00 2001
From: Pieter12345
Date: Mon, 25 Sep 2023 01:03:57 +0200
Subject: [PATCH 3/3] Support player injection for nested events
---
.../java/com/laytonsmith/core/Static.java | 38 ++++++++++++++++---
1 file changed, 32 insertions(+), 6 deletions(-)
diff --git a/src/main/java/com/laytonsmith/core/Static.java b/src/main/java/com/laytonsmith/core/Static.java
index 6611ff600..ca7dff3e6 100644
--- a/src/main/java/com/laytonsmith/core/Static.java
+++ b/src/main/java/com/laytonsmith/core/Static.java
@@ -91,6 +91,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
@@ -761,6 +762,7 @@ public static MCItemStack ParseItemNotation(String functionName, String notation
}
private static final Map INJECTED_PLAYERS = new HashMap<>();
+ private static final Map PLAYER_INJECTION_COUNT_MAP = new HashMap<>();
private static MCEntity injectedEntity;
private static final Pattern DASHLESS_PATTERN = Pattern.compile("^([A-Fa-f0-9]{8})([A-Fa-f0-9]{4})([A-Fa-f0-9]{4})([A-Fa-f0-9]{4})([A-Fa-f0-9]{12})$");
@@ -1221,26 +1223,50 @@ public static MCCommandSender GetInjectedPlayer(String name) {
return INJECTED_PLAYERS.get(name.toLowerCase());
}
+ /**
+ * Injects the given player into the global player proxy system,
+ * or increments the injection count of the already injected player with that name.
+ * @param player - The player to inject.
+ */
public static void InjectPlayer(MCCommandSender player) {
String name = player.getName();
if("CONSOLE".equals(name)) {
name = "~console";
}
- INJECTED_PLAYERS.put(name.toLowerCase(), player);
+ name = name.toLowerCase();
+ synchronized(INJECTED_PLAYERS) {
+ AtomicInteger count = PLAYER_INJECTION_COUNT_MAP.get(name);
+ if(count == null) {
+ INJECTED_PLAYERS.put(name, player);
+ PLAYER_INJECTION_COUNT_MAP.put(name, new AtomicInteger(1));
+ } else {
+ count.incrementAndGet();
+ }
+ }
}
/**
- * Removes a player into the global player proxy system. Returns the player removed (or null if none were injected).
- *
- * @param player
- * @return
+ * Decrements the injection count of the injected player and
+ * removes it from the global player proxy system if the count reaches 0.
+ * @param player - The player to uninject.
+ * @return The player, or {@code null} if the player was not injected.
*/
public static MCCommandSender UninjectPlayer(MCCommandSender player) {
String name = player.getName();
if("CONSOLE".equals(name)) {
name = "~console";
}
- return INJECTED_PLAYERS.remove(name.toLowerCase());
+ name = name.toLowerCase();
+ synchronized(INJECTED_PLAYERS) {
+ AtomicInteger count = PLAYER_INJECTION_COUNT_MAP.get(name);
+ if(count == null) {
+ return null;
+ } else if(count.decrementAndGet() <= 0) {
+ PLAYER_INJECTION_COUNT_MAP.remove(name);
+ return INJECTED_PLAYERS.remove(name);
+ }
+ return INJECTED_PLAYERS.get(name);
+ }
}
public static void InjectEntity(MCEntity entity) {