Skip to content

Commit 11fa985

Browse files
committed
Make SkriptReflection#copyLocals make a proper deep copy, not a shallow copy. Use Skript's VariablesMap#copy method
Code to reproduce issue (trigger effect twice): ``` effect do stuff: parse: set {_a::*} to 1 continue trigger: broadcast "%{_a::*}%" # first time triggered: `1`, second time triggered: `1 and 2` set {_a::2} to 2 ```
1 parent 52ffed7 commit 11fa985

File tree

1 file changed

+18
-43
lines changed

1 file changed

+18
-43
lines changed

src/main/java/com/btk5h/skriptmirror/util/SkriptReflection.java

Lines changed: 18 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import com.btk5h.skriptmirror.skript.custom.event.ExprReplacedEventValue;
1818
import org.bukkit.event.Event;
1919

20-
import java.lang.reflect.Constructor;
2120
import java.lang.reflect.Field;
2221
import java.lang.reflect.InvocationTargetException;
2322
import java.lang.reflect.Method;
@@ -32,9 +31,7 @@ public class SkriptReflection {
3231
private static Field PATTERNS;
3332
private static Field LOCAL_VARIABLES;
3433
private static Field NODES;
35-
private static Field VARIABLES_MAP_HASHMAP;
36-
private static Field VARIABLES_MAP_TREEMAP;
37-
private static Constructor<?> VARIABLES_MAP;
34+
private static Method VARIABLES_MAP_COPY;
3835
private static Field DEFAULT_EXPRESSION;
3936
private static Field PARSED_VALUE;
4037
private static Method PARSE_I;
@@ -43,7 +40,6 @@ public class SkriptReflection {
4340
static {
4441
Field _FIELD;
4542
Method _METHOD;
46-
Constructor<?> _CONSTRUCTOR;
4743

4844
try {
4945
_FIELD = SyntaxElementInfo.class.getDeclaredField("patterns");
@@ -74,27 +70,11 @@ public class SkriptReflection {
7470
Class<?> variablesMap = Class.forName("ch.njol.skript.variables.VariablesMap");
7571

7672
try {
77-
_FIELD = variablesMap.getDeclaredField("hashMap");
78-
_FIELD.setAccessible(true);
79-
VARIABLES_MAP_HASHMAP = _FIELD;
80-
} catch (NoSuchFieldException e) {
81-
warning("Skript's hash map field could not be resolved.");
82-
}
83-
84-
try {
85-
_FIELD = variablesMap.getDeclaredField("treeMap");
86-
_FIELD.setAccessible(true);
87-
VARIABLES_MAP_TREEMAP = _FIELD;
88-
} catch (NoSuchFieldException e) {
89-
warning("Skript's tree map field could not be resolved.");
90-
}
91-
92-
try {
93-
_CONSTRUCTOR = variablesMap.getDeclaredConstructor();
94-
_CONSTRUCTOR.setAccessible(true);
95-
VARIABLES_MAP = _CONSTRUCTOR;
73+
_METHOD = variablesMap.getDeclaredMethod("copy");
74+
_METHOD.setAccessible(true);
75+
VARIABLES_MAP_COPY = _METHOD;
9676
} catch (NoSuchMethodException e) {
97-
warning("Skript's variables map constructors could not be resolved.");
77+
warning("Skript's variables map 'copy' method could not be resolved.");
9878
}
9979
} catch (ClassNotFoundException e) {
10080
warning("Skript's variables map class could not be resolved.");
@@ -106,7 +86,7 @@ public class SkriptReflection {
10686
DEFAULT_EXPRESSION = _FIELD;
10787
} catch (NoSuchFieldException e) {
10888
warning("Skript's default expression field could not be resolved, " +
109-
"therefore event-values won't work in custom events");
89+
"therefore event-values won't work in custom events");
11090
}
11191

11292
try {
@@ -115,7 +95,7 @@ public class SkriptReflection {
11595
PARSED_VALUE = _FIELD;
11696
} catch (NoSuchFieldException e) {
11797
warning("Skript's parsed value field could not be resolved, " +
118-
"therefore and/or warnings won't be suppressed");
98+
"therefore and/or warnings won't be suppressed");
11999
}
120100

121101
try {
@@ -132,7 +112,7 @@ public class SkriptReflection {
132112
EXPRESSIONS = _FIELD;
133113
} catch (NoSuchFieldException e) {
134114
warning("Skript's expressions field could not be resolved, " +
135-
"therefore you might get syntax conflict problems");
115+
"therefore you might get syntax conflict problems");
136116
}
137117
}
138118

@@ -203,21 +183,16 @@ public static Object getLocals(Event event) {
203183
* @param locals The local variables to copy.
204184
* @return The copied local variables.
205185
*/
206-
@SuppressWarnings("unchecked")
207186
public static Object copyLocals(Object locals) {
208187
if (locals == null)
209188
return null;
210189

211190
try {
212-
Object copiedLocals = VARIABLES_MAP.newInstance();
213-
214-
((Map<String, Object>) VARIABLES_MAP_HASHMAP.get(copiedLocals))
215-
.putAll((Map<String, Object>) VARIABLES_MAP_HASHMAP.get(locals));
216-
((Map<String, Object>) VARIABLES_MAP_TREEMAP.get(copiedLocals))
217-
.putAll((Map<String, Object>) VARIABLES_MAP_TREEMAP.get(locals));
218-
return copiedLocals;
219-
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
220-
throw new RuntimeException();
191+
return VARIABLES_MAP_COPY.invoke(locals);
192+
} catch (IllegalAccessException e) {
193+
throw new IllegalStateException(e); // setAccessible called
194+
} catch (InvocationTargetException e) {
195+
throw new RuntimeException(e);
221196
}
222197
}
223198

@@ -254,7 +229,7 @@ public static void replaceEventValues(List<ClassInfo<?>> classInfoList) {
254229
DefaultExpression<?> defaultExpression = classInfo.getDefaultExpression();
255230
if (defaultExpression instanceof EventValueExpression && !(defaultExpression instanceof ExprReplacedEventValue)) {
256231
DEFAULT_EXPRESSION.set(classInfo,
257-
new ExprReplacedEventValue<>((EventValueExpression<?>) defaultExpression));
232+
new ExprReplacedEventValue<>((EventValueExpression<?>) defaultExpression));
258233

259234
replaceExtraList.add(classInfo);
260235
}
@@ -271,10 +246,10 @@ public static void replaceEventValues(List<ClassInfo<?>> classInfoList) {
271246
*/
272247
public static void replaceExtra(ClassInfo<?> classInfo) {
273248
List<ClassInfo<?>> classInfoList = Classes.getClassInfos().stream()
274-
.filter(loopedClassInfo -> !(loopedClassInfo.getDefaultExpression() instanceof ExprReplacedEventValue))
275-
.filter(loopedClassInfo -> classInfo.getC().isAssignableFrom(loopedClassInfo.getC())
276-
|| loopedClassInfo.getC().isAssignableFrom(classInfo.getC()))
277-
.collect(Collectors.toList());
249+
.filter(loopedClassInfo -> !(loopedClassInfo.getDefaultExpression() instanceof ExprReplacedEventValue))
250+
.filter(loopedClassInfo -> classInfo.getC().isAssignableFrom(loopedClassInfo.getC())
251+
|| loopedClassInfo.getC().isAssignableFrom(classInfo.getC()))
252+
.collect(Collectors.toList());
278253
replaceEventValues(classInfoList);
279254
}
280255

0 commit comments

Comments
 (0)