|
1 | 1 | package com.laytonsmith.core.events; |
2 | 2 |
|
3 | | -import com.laytonsmith.PureUtilities.ClassLoading.ClassDiscovery; |
4 | | -import com.laytonsmith.PureUtilities.Common.StreamUtils; |
5 | | -import com.laytonsmith.abstraction.MCCommandSender; |
6 | | -import com.laytonsmith.abstraction.MCPlayer; |
7 | | -import com.laytonsmith.abstraction.events.MCPlayerEvent; |
8 | | -import com.laytonsmith.annotations.core; |
9 | | -import com.laytonsmith.annotations.hide; |
10 | | -import com.laytonsmith.core.Documentation; |
11 | | -import com.laytonsmith.core.LogLevel; |
12 | | -import com.laytonsmith.core.MSLog; |
13 | | -import com.laytonsmith.core.MSLog.Tags; |
14 | | -import com.laytonsmith.core.MethodScriptCompiler; |
15 | | -import com.laytonsmith.core.ParseTree; |
16 | | -import com.laytonsmith.core.Static; |
17 | | -import com.laytonsmith.core.constructs.CArray; |
18 | | -import com.laytonsmith.core.constructs.CNull; |
19 | | -import com.laytonsmith.core.constructs.Target; |
20 | | -import com.laytonsmith.core.environments.CommandHelperEnvironment; |
21 | | -import com.laytonsmith.core.environments.Environment; |
22 | | -import com.laytonsmith.core.environments.StaticRuntimeEnv; |
23 | | -import com.laytonsmith.core.events.prefilters.Prefilter; |
24 | | -import com.laytonsmith.core.events.prefilters.PrefilterBuilder; |
25 | | -import com.laytonsmith.core.exceptions.CRE.CREFormatException; |
26 | | -import com.laytonsmith.core.exceptions.CancelCommandException; |
27 | | -import com.laytonsmith.core.exceptions.ConfigRuntimeException; |
28 | | -import com.laytonsmith.core.exceptions.EventException; |
29 | | -import com.laytonsmith.core.exceptions.FunctionReturnException; |
30 | | -import com.laytonsmith.core.exceptions.PrefilterNonMatchException; |
31 | | -import com.laytonsmith.core.exceptions.ProgramFlowManipulationException; |
32 | | -import com.laytonsmith.core.natives.interfaces.Mixed; |
33 | | -import com.laytonsmith.core.profiler.ProfilePoint; |
34 | | - |
35 | | -import java.net.URL; |
36 | | -import java.util.HashMap; |
37 | | -import java.util.Map; |
38 | | - |
39 | 3 | /** |
40 | | - * This helper class implements a few of the common functions in event, and most (all?) Events should extend this class. |
41 | | - * |
| 4 | + * This class is deprecated, and events should extend AbstractGenericEvent directly instead. |
| 5 | + * @deprecated Use {@link AbstractGenericEvent} instead. |
42 | 6 | */ |
43 | | -public abstract class AbstractEvent implements Event, Comparable<Event> { |
44 | | - |
45 | | - private EventMixinInterface mixin; |
46 | | -// protected EventHandlerInterface handler; |
47 | | -// |
48 | | -// protected AbstractEvent(EventHandlerInterface handler){ |
49 | | -// this.handler = handler; |
50 | | -// } |
51 | | -// |
52 | | - |
53 | | - public final void setAbstractEventMixin(EventMixinInterface mixin) { |
54 | | - this.mixin = mixin; |
55 | | - } |
56 | | - |
57 | | - /** |
58 | | - * This function should return true if the event code should be run, based on implementation specific conditions |
59 | | - * for the BindableEvent. |
60 | | - * |
61 | | - * @param e The bindable event itself |
62 | | - * @return {@code true} if the event code should be run |
63 | | - */ |
64 | | - public boolean shouldFire(BindableEvent e) { |
65 | | - return this.mixin.shouldFire(e); |
66 | | - } |
67 | | - |
68 | | - /** |
69 | | - * If the event needs to run special code when a player binds the event, it can be done here. By default, an |
70 | | - * UnsupportedOperationException is thrown, but is caught and ignored. |
71 | | - */ |
72 | | - @Override |
73 | | - public void bind(BoundEvent event) { |
74 | | - |
75 | | - } |
76 | | - |
77 | | - /** |
78 | | - * If the event needs to run special code when a player unbinds the event, it can be done here. By default, an |
79 | | - * UnsupportedOperationException is thrown, but is caught and ignored. |
80 | | - */ |
81 | | - @Override |
82 | | - public void unbind(BoundEvent event) { |
83 | | - |
84 | | - } |
85 | | - |
86 | | - /** |
87 | | - * If the event needs to run special code at server startup, it can be done here. By default, nothing happens. |
88 | | - */ |
89 | | - @Override |
90 | | - public void hook() { |
91 | | - |
92 | | - } |
93 | | - |
94 | | - @Override |
95 | | - public boolean matches(Map<String, Mixed> prefilter, BindableEvent e) throws PrefilterNonMatchException { |
96 | | - throw new UnsupportedOperationException(); |
97 | | - } |
98 | | - |
99 | | - /** |
100 | | - * This function is run when the actual event occurs. |
101 | | - * |
102 | | - * @param tree The compiled parse tree |
103 | | - * @param b The bound event |
104 | | - * @param env The operating environment |
105 | | - * @param activeEvent The active event being executed |
106 | | - */ |
107 | | - @Override |
108 | | - public final void execute(ParseTree tree, BoundEvent b, Environment env, BoundEvent.ActiveEvent activeEvent) throws ConfigRuntimeException { |
109 | | - preExecution(env, activeEvent); |
110 | | - |
111 | | - // Events can have a player to put into the CommandHelperEnvironment. |
112 | | - if(activeEvent.getUnderlyingEvent() instanceof MCPlayerEvent playerEvent) { |
113 | | - env.getEnv(CommandHelperEnvironment.class).SetPlayer(playerEvent.getPlayer()); |
114 | | - } else { |
115 | | - // Probably not a player event, but might still have a player context. |
116 | | - Mixed c = activeEvent.getParsedEvent().get("player"); |
117 | | - if(c != null) { |
118 | | - if(c instanceof CNull) { |
119 | | - // This is a CNull "player", likely from an entity event, so we need to ensure player() does |
120 | | - // not return a player inherited from the bind's parent environment. |
121 | | - if(env.getEnv(CommandHelperEnvironment.class).GetPlayer() != null) { |
122 | | - env.getEnv(CommandHelperEnvironment.class).SetPlayer(null); |
123 | | - } |
124 | | - } else { |
125 | | - MCCommandSender p = Static.getServer().getPlayer(c.val()); |
126 | | - if(p == null) { |
127 | | - // Check if event (possibly from an extension) injected the player but didn't extend MCPlayerEvent |
128 | | - p = Static.GetInjectedPlayer(c.val()); |
129 | | - } |
130 | | - if(p != null) { |
131 | | - env.getEnv(CommandHelperEnvironment.class).SetPlayer((MCPlayer) p); |
132 | | - } else { |
133 | | - MSLog.GetLogger().w(Tags.GENERAL, c.val() + " offline for " + b.getEventName(), tree.getTarget()); |
134 | | - // Set env CommandSender to prevent incorrect inherited player from being used in a player event. |
135 | | - if(env.getEnv(CommandHelperEnvironment.class).GetPlayer() != null) { |
136 | | - env.getEnv(CommandHelperEnvironment.class).SetPlayer(null); |
137 | | - } |
138 | | - } |
139 | | - } |
140 | | - } |
141 | | - } |
142 | | - |
143 | | - ProfilePoint event = null; |
144 | | - if(env.getEnv(StaticRuntimeEnv.class).GetProfiler() != null) { |
145 | | - event = env.getEnv(StaticRuntimeEnv.class).GetProfiler().start( |
146 | | - "Event " + b.getEventName() + " (defined at " + b.getTarget().toString() + ")", LogLevel.ERROR); |
147 | | - } |
148 | | - try { |
149 | | - try { |
150 | | - MethodScriptCompiler.execute(tree, env, null, null); |
151 | | - } catch (CancelCommandException ex) { |
152 | | - if(ex.getMessage() != null && !ex.getMessage().isEmpty()) { |
153 | | - StreamUtils.GetSystemOut().println(ex.getMessage()); |
154 | | - } |
155 | | - } catch (FunctionReturnException ex) { |
156 | | - //We simply allow this to end the event execution |
157 | | - } catch (ProgramFlowManipulationException ex) { |
158 | | - ConfigRuntimeException.HandleUncaughtException(new CREFormatException("Unexpected control flow operation used.", ex.getTarget()), env); |
159 | | - } |
160 | | - } finally { |
161 | | - if(event != null) { |
162 | | - event.stop(); |
163 | | - } |
164 | | - // Finally, among other things, we need to clean-up injected players and entities |
165 | | - postExecution(env, activeEvent); |
166 | | - } |
167 | | - } |
168 | | - |
169 | | - /** |
170 | | - * This method is called before the event handling code is run, and provides a place for the event code itself to |
171 | | - * modify the environment or active event data. |
172 | | - * |
173 | | - * @param env The environment, at the time just before the event handler is called. |
174 | | - * @param activeEvent The event handler code. |
175 | | - */ |
176 | | - public void preExecution(Environment env, BoundEvent.ActiveEvent activeEvent) { |
177 | | - |
178 | | - } |
179 | | - |
180 | | - /** |
181 | | - * This method is called after the event handling code is run, and provides a place for the event code itself to |
182 | | - * modify or cleanup the environment or active event data. |
183 | | - * |
184 | | - * @param env The environment, at the time just before the event handler is called. |
185 | | - * @param activeEvent The event handler code. |
186 | | - * @throws UnsupportedOperationException If the preExecution isn't supported, this may be thrown, and it will be |
187 | | - * ignored. |
188 | | - */ |
189 | | - public void postExecution(Environment env, BoundEvent.ActiveEvent activeEvent) { |
190 | | - |
191 | | - } |
192 | | - |
193 | | - /** |
194 | | - * For sorting and optimizing events, we need a comparison operation. By default it is compared by looking at the |
195 | | - * event name. |
196 | | - * |
197 | | - * @param o |
198 | | - * @return |
199 | | - */ |
200 | | - @Override |
201 | | - public int compareTo(Event o) { |
202 | | - return this.getName().compareTo(o.getName()); |
203 | | - } |
204 | | - |
205 | | - /** |
206 | | - * Since most events are minecraft events, we return true by default. |
207 | | - * |
208 | | - * @return |
209 | | - */ |
210 | | - @Override |
211 | | - public boolean supportsExternal() { |
212 | | - return true; |
213 | | - } |
214 | | - |
215 | | - /** |
216 | | - * If it is ok to by default do a simple conversion from a CArray to a Map, this method can do it for you. Likely |
217 | | - * this is not acceptable, so hard-coding the conversion will be necessary. |
218 | | - * |
219 | | - * @param manualObject |
220 | | - * @return |
221 | | - */ |
222 | | - public static Object DoConvert(CArray manualObject) { |
223 | | - Map<String, Mixed> map = new HashMap<>(); |
224 | | - for(String key : manualObject.stringKeySet()) { |
225 | | - map.put(key, manualObject.get(key, Target.UNKNOWN)); |
226 | | - } |
227 | | - return map; |
228 | | - } |
229 | | - |
230 | | - public Map<String, Mixed> evaluate_helper(BindableEvent e) throws EventException { |
231 | | - return mixin.evaluate_helper(e); |
232 | | - } |
233 | | - |
234 | | - /** |
235 | | - * By default, this function triggers the event by calling the mixin handler. If this is not the desired behavior, |
236 | | - * this method can be overridden in the actual event (if it's an external event, for instance) |
237 | | - * |
238 | | - * @param o |
239 | | - */ |
240 | | - @Override |
241 | | - public void manualTrigger(BindableEvent o) { |
242 | | - mixin.manualTrigger(o); |
243 | | - } |
244 | | - |
245 | | - @Override |
246 | | - public void cancel(BindableEvent o, boolean state) { |
247 | | - mixin.cancel(o, state); |
248 | | - } |
249 | | - |
250 | | - @Override |
251 | | - public boolean isCancellable(BindableEvent o) { |
252 | | - return mixin.isCancellable(o); |
253 | | - } |
254 | | - |
255 | | - @Override |
256 | | - public boolean isCancelled(BindableEvent o) { |
257 | | - return mixin.isCancelled(o); |
258 | | - } |
259 | | - |
260 | | - @Override |
261 | | - public URL getSourceJar() { |
262 | | - return ClassDiscovery.GetClassContainer(this.getClass()); |
263 | | - } |
264 | | - |
265 | | - /** |
266 | | - * Returns true if the event is annotated with @hide |
267 | | - * |
268 | | - * @return |
269 | | - */ |
270 | | - @Override |
271 | | - public final boolean appearInDocumentation() { |
272 | | - return this.getClass().getAnnotation(hide.class) != null; |
273 | | - } |
274 | | - |
275 | | - private static final Class[] EMPTY_CLASS = new Class[0]; |
276 | | - |
277 | | - @Override |
278 | | - public Class<? extends Documentation>[] seeAlso() { |
279 | | - return EMPTY_CLASS; |
280 | | - } |
281 | | - |
282 | | - /** |
283 | | - * Most events should return true for this, but passive events may override this to return null. |
284 | | - * |
285 | | - * @return |
286 | | - */ |
287 | | - @Override |
288 | | - public boolean addCounter() { |
289 | | - return true; |
290 | | - } |
291 | | - |
292 | | - @Override |
293 | | - public final boolean isCore() { |
294 | | - Class c = this.getClass(); |
295 | | - do { |
296 | | - if(c.getAnnotation(core.class) != null) { |
297 | | - return true; |
298 | | - } |
299 | | - c = c.getDeclaringClass(); |
300 | | - } while(c != null); |
301 | | - return false; |
302 | | - } |
303 | | - |
304 | | - private Map<String, Prefilter<? extends BindableEvent>> prefilterCache = null; |
305 | | - private volatile boolean isCacheSaturated = false; |
306 | | - |
307 | | - @Override |
308 | | - public final Map<String, Prefilter<? extends BindableEvent>> getPrefilters() { |
309 | | - if(!isCacheSaturated) { |
310 | | - synchronized(this) { |
311 | | - if(!isCacheSaturated) { |
312 | | - PrefilterBuilder builder = getPrefilterBuilder(); |
313 | | - if(builder != null) { |
314 | | - prefilterCache = builder.build(); |
315 | | - } |
316 | | - isCacheSaturated = true; |
317 | | - } |
318 | | - } |
319 | | - } |
320 | | - return prefilterCache; |
321 | | - } |
322 | | - |
323 | | - /** |
324 | | - * Returns the prefilter builder for this subclass. This is built by AbstractEvent and cached, so that calls |
325 | | - * to getPrefilters will be faster for future calls. |
326 | | - * @return |
327 | | - */ |
328 | | - // TODO: Once everything has this, this should be re-added, since everything should have its own version. |
329 | | -// @ForceImplementation |
330 | | - protected PrefilterBuilder getPrefilterBuilder() { |
331 | | - return null; |
332 | | - } |
| 7 | +@Deprecated |
| 8 | +public abstract class AbstractEvent |
| 9 | + extends AbstractGenericEvent<BindableEvent> { |
333 | 10 |
|
334 | 11 | } |
0 commit comments