use of org.spongepowered.api.event.Event in project SpongeCommon by SpongePowered.
the class SpongeEventManager method registerListener.
@SuppressWarnings("unchecked")
public void registerListener(PluginContainer plugin, Object listenerObject) {
checkNotNull(plugin, "plugin");
checkNotNull(listenerObject, "listener");
if (this.registeredListeners.contains(listenerObject)) {
this.logger.warn("Plugin {} attempted to register an already registered listener ({})", plugin.getId(), listenerObject.getClass().getName());
Thread.dumpStack();
return;
}
List<RegisteredListener<? extends Event>> handlers = Lists.newArrayList();
Map<Method, String> methodErrors = new HashMap<>();
Class<?> handle = listenerObject.getClass();
for (Method method : handle.getMethods()) {
Listener listener = method.getAnnotation(Listener.class);
if (listener != null) {
String error = getHandlerErrorOrNull(method);
if (error == null) {
@SuppressWarnings("unchecked") final TypeToken eventType = TypeToken.of(method.getGenericParameterTypes()[0]);
AnnotatedEventListener handler;
try {
handler = this.handlerFactory.create(listenerObject, method);
} catch (Exception e) {
this.logger.error("Failed to create handler for {} on {}", method, handle, e);
continue;
}
handlers.add(createRegistration(plugin, eventType, listener, handler));
} else {
methodErrors.put(method, error);
}
}
}
// about those.
for (Class<?> handleParent = handle; handleParent != Object.class; handleParent = handleParent.getSuperclass()) {
for (Method method : handleParent.getDeclaredMethods()) {
if (method.getAnnotation(Listener.class) != null && !methodErrors.containsKey(method)) {
String error = getHandlerErrorOrNull(method);
if (error != null) {
methodErrors.put(method, error);
}
}
}
}
for (Map.Entry<Method, String> method : methodErrors.entrySet()) {
this.logger.warn("Invalid listener method {} in {}: {}", method.getKey(), method.getKey().getDeclaringClass().getName(), method.getValue());
}
this.registeredListeners.add(listenerObject);
register(handlers);
}
use of org.spongepowered.api.event.Event in project SpongeCommon by SpongePowered.
the class FilterGenerator method generateClass.
public byte[] generateClass(String name, Method method) {
name = name.replace('.', '/');
Parameter[] params = method.getParameters();
ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
MethodVisitor mv;
cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, name, null, "java/lang/Object", new String[] { Type.getInternalName(EventFilter.class) });
SubtypeFilterDelegate sfilter = null;
List<FilterDelegate> additional = Lists.newArrayList();
boolean cancellation = false;
for (Annotation anno : method.getAnnotations()) {
Object obj = filterFromAnnotation(anno.annotationType());
if (obj == null) {
continue;
}
if (obj instanceof SubtypeFilter) {
if (sfilter != null) {
throw new IllegalStateException("Cannot have both @Include and @Exclude annotations present at once");
}
sfilter = ((SubtypeFilter) obj).getDelegate(anno);
} else if (obj instanceof EventTypeFilter) {
EventTypeFilter etf = (EventTypeFilter) obj;
additional.add(etf.getDelegate(anno));
if (etf == EventTypeFilter.CANCELLATION) {
cancellation = true;
}
}
}
if (!cancellation && Cancellable.class.isAssignableFrom(method.getParameterTypes()[0])) {
additional.add(new CancellationEventFilterDelegate(Tristate.FALSE));
}
if (sfilter != null) {
sfilter.createFields(cw);
}
{
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
if (sfilter != null) {
sfilter.writeCtor(name, cw, mv);
}
mv.visitInsn(RETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
{
mv = cw.visitMethod(ACC_PUBLIC, "filter", "(" + Type.getDescriptor(Event.class) + ")[Ljava/lang/Object;", null, null);
mv.visitCode();
// index of the next available local variable
int local = 2;
if (sfilter != null) {
local = sfilter.write(name, cw, mv, method, local);
}
for (FilterDelegate eventFilter : additional) {
local = eventFilter.write(name, cw, mv, method, local);
}
// local var indices of the parameters values
int[] plocals = new int[params.length - 1];
for (int i = 1; i < params.length; i++) {
Parameter param = params[i];
ParameterFilterSourceDelegate source = null;
List<ParameterFilterDelegate> paramFilters = Lists.newArrayList();
for (Annotation anno : param.getAnnotations()) {
Object obj = filterFromAnnotation(anno.annotationType());
if (obj == null) {
continue;
}
if (obj instanceof ParameterSource) {
if (source != null) {
throw new IllegalStateException("Cannot have multiple parameter filter source annotations (for " + param.getName() + ")");
}
source = ((ParameterSource) obj).getDelegate(anno);
} else if (obj instanceof ParameterFilter) {
paramFilters.add(((ParameterFilter) obj).getDelegate(anno));
}
}
if (source == null) {
throw new IllegalStateException("Cannot have additional parameters filters without a source (for " + param.getName() + ")");
}
if (source instanceof AllCauseFilterSourceDelegate && !paramFilters.isEmpty()) {
// TODO until better handling for filtering arrays is added
throw new IllegalStateException("Cannot have additional parameters filters without an array source (for " + param.getName() + ")");
}
Tuple<Integer, Integer> localState = source.write(cw, mv, method, param, local);
local = localState.getFirst();
plocals[i - 1] = localState.getSecond();
for (ParameterFilterDelegate paramFilter : paramFilters) {
paramFilter.write(cw, mv, method, param, plocals[i - 1]);
}
}
// create the return array
if (params.length == 1) {
mv.visitInsn(ICONST_1);
} else {
mv.visitIntInsn(BIPUSH, params.length);
}
mv.visitTypeInsn(ANEWARRAY, "java/lang/Object");
// load the event into the array
mv.visitInsn(DUP);
mv.visitInsn(ICONST_0);
mv.visitVarInsn(ALOAD, 1);
mv.visitInsn(AASTORE);
// load all the params into the array
for (int i = 1; i < params.length; i++) {
mv.visitInsn(DUP);
mv.visitIntInsn(BIPUSH, i);
Type paramType = Type.getType(params[i].getType());
mv.visitVarInsn(paramType.getOpcode(ILOAD), plocals[i - 1]);
GeneratorUtils.visitBoxingMethod(mv, paramType);
mv.visitInsn(AASTORE);
}
mv.visitInsn(ARETURN);
mv.visitMaxs(0, 0);
mv.visitEnd();
}
cw.visitEnd();
byte[] data = cw.toByteArray();
if (FILTER_DEBUG) {
File outDir = new File(".sponge.debug.out");
File outFile = new File(outDir, name + ".class");
if (!outFile.getParentFile().exists()) {
outFile.getParentFile().mkdirs();
}
try (FileOutputStream out = new FileOutputStream(outFile)) {
out.write(data);
} catch (IOException ignored) {
ignored.printStackTrace();
}
}
return data;
}
use of org.spongepowered.api.event.Event in project SpongeForge by SpongePowered.
the class SpongeMod method onServerStopped.
@Subscribe
public void onServerStopped(FMLServerStoppedEvent event) throws IOException {
try {
CommandManager service = this.game.getCommandManager();
service.getCommands().stream().filter(mapping -> mapping.getCallable() instanceof MinecraftCommandWrapper).forEach(service::removeMapping);
((SqlServiceImpl) this.game.getServiceManager().provideUnchecked(SqlService.class)).close();
} catch (Throwable t) {
this.controller.errorOccurred(this, t);
}
// used by client
WorldManager.unregisterAllWorldSettings();
}
use of org.spongepowered.api.event.Event in project guardian by ichorpowered.
the class HorizontalSpeedCheck method getSequence.
@Override
public SequenceBlueprint<Event> getSequence(final Detection detection) {
final Double analysisTime = detection.getContentContainer().get(ContentKeys.ANALYSIS_TIME).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
final Double analysisIntercept = detection.getContentContainer().get(ContentKeys.ANALYSIS_INTERCEPT).orElse(GuardianValue.empty()).getDirect().orElse(0d);
final Double minimumTickRate = detection.getContentContainer().get(ContentKeys.ANALYSIS_MINIMUM_TICK).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
final Double maximumTickRate = detection.getContentContainer().get(ContentKeys.ANALYSIS_MAXIMUM_TICK).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
return new GuardianSequenceBuilder().capture(new ControlCapture(detection.getPlugin(), detection)).capture(new MaterialCapture(detection.getPlugin(), detection)).capture(new PotionEffectCapture(detection.getPlugin(), detection)).observe(MoveEntityEvent.class).after().delay(analysisTime.intValue()).condition(sequenceContext -> {
final GuardianPlayerEntry<Player> entityEntry = sequenceContext.get(CommonContextKeys.ENTITY_ENTRY);
final Summary summary = sequenceContext.get(CommonContextKeys.SUMMARY);
final GuardianCaptureRegistry captureRegistry = sequenceContext.get(CommonContextKeys.CAPTURE_REGISTRY);
final long lastActionTime = sequenceContext.get(CommonContextKeys.LAST_ACTION_TIME);
summary.set(SequenceReport.class, new SequenceReport(false, Origin.source(sequenceContext.getRoot()).owner(entityEntry).build()));
if (!entityEntry.getEntity(Player.class).isPresent())
return false;
final Player player = entityEntry.getEntity(Player.class).get();
/*
* Capture Collection
*/
final CaptureContainer captureContainer = captureRegistry.getContainer();
final Optional<Location> initial = captureContainer.get(GuardianSequence.INITIAL_LOCATION);
final Optional<Double> effectSpeedAmplifier = captureContainer.get(PotionEffectCapture.HORIZONTAL_SPEED_MODIFIER);
final Optional<Double> materialSpeedAmplifier = captureContainer.get(MaterialCapture.SPEED_MODIFIER);
final Optional<Double> horizontalOffset = captureContainer.get(ControlCapture.HORIZONTAL_DISTANCE);
final Optional<Map<String, Integer>> activeControls = captureContainer.get(ControlCapture.ACTIVE_CONTROL_TICKS);
if (!initial.isPresent() || !materialSpeedAmplifier.isPresent() || !horizontalOffset.isPresent())
return false;
long current = System.currentTimeMillis();
// Gets the average between now and the last action.
final double averageActionTime = ((current - lastActionTime) / 1000) / 0.05;
if (averageActionTime < minimumTickRate) {
detection.getLogger().warn("The server may be overloaded. A check could not be completed.");
return false;
} else if (averageActionTime > maximumTickRate) {
return false;
}
if (player.get(Keys.VEHICLE).isPresent())
return false;
double intercept = analysisIntercept + (effectSpeedAmplifier.orElse(0d) / analysisTime);
final Optional<Map.Entry<String, Integer>> validControlTicks = activeControls.get().entrySet().stream().max(Comparator.comparingInt(Map.Entry::getValue));
// Gets the players horizontal displacement in the world.
final double horizontalDisplacement = Math.abs((player.getLocation().getX() - initial.get().getX()) + (player.getLocation().getZ() - initial.get().getZ()));
// Gets the percentage of the displacement that is the most important.
final double maximumHorizontalDisplacement = validControlTicks.map(entry -> horizontalDisplacement * (entry.getValue() / averageActionTime)).orElse(horizontalDisplacement);
// Gets the players maximum horizontal speed in the world, for this analysis.
final double maximumHorizontalSpeed = (((horizontalOffset.get() * materialSpeedAmplifier.get()) / 2) / averageActionTime) + intercept;
if (horizontalDisplacement <= 1 || maximumHorizontalDisplacement < 1 || maximumHorizontalSpeed < 1)
return false;
if (maximumHorizontalDisplacement > maximumHorizontalSpeed) {
// ------------------------- DEBUG -----------------------------
System.out.println(player.getName() + " has been caught using horizontal speed hacks. (" + (maximumHorizontalDisplacement - maximumHorizontalSpeed) + ")");
// -------------------------------------------------------------
SequenceReport report = new SequenceReport(true, Origin.source(sequenceContext.getRoot()).owner(entityEntry).build());
report.put("type", "Horizontal Speed");
report.put("information", Collections.singletonList("Overshot maximum movement by " + (maximumHorizontalDisplacement - maximumHorizontalSpeed) + "."));
report.put("initial_location", initial.get());
report.put("final_location", player.getLocation());
report.put("severity", (maximumHorizontalDisplacement - maximumHorizontalSpeed) / maximumHorizontalDisplacement);
summary.set(SequenceReport.class, report);
return true;
}
return false;
}, ConditionType.NORMAL).build(SequenceContext.builder().owner(detection).root(this).build());
}
use of org.spongepowered.api.event.Event in project guardian by ichorpowered.
the class InvalidCheck method getSequence.
@Nonnull
@Override
public SequenceBlueprint<Event> getSequence(final Detection detection) {
final Double analysisTime = detection.getContentContainer().get(ContentKeys.ANALYSIS_TIME).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
final Double minimumTickRate = detection.getContentContainer().get(ContentKeys.ANALYSIS_MINIMUM_TICK).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
final Double maximumTickRate = detection.getContentContainer().get(ContentKeys.ANALYSIS_MAXIMUM_TICK).orElse(GuardianValue.empty()).getDirect().orElse(0d) / 0.05;
return new GuardianSequenceBuilder().capture(new InvalidControlCapture(detection.getPlugin(), detection)).observe(MoveEntityEvent.class).observe(MoveEntityEvent.class).delay(analysisTime.intValue()).expire(maximumTickRate.intValue()).condition(sequenceContext -> {
final GuardianPlayerEntry<Player> entityEntry = sequenceContext.get(CommonContextKeys.ENTITY_ENTRY);
final Summary summary = sequenceContext.get(CommonContextKeys.SUMMARY);
final GuardianCaptureRegistry captureRegistry = sequenceContext.get(CommonContextKeys.CAPTURE_REGISTRY);
final long lastActionTime = sequenceContext.get(CommonContextKeys.LAST_ACTION_TIME);
summary.set(SequenceReport.class, new SequenceReport(false, Origin.source(sequenceContext.getRoot()).owner(entityEntry).build()));
if (!entityEntry.getEntity(Player.class).isPresent())
return false;
final Player player = entityEntry.getEntity(Player.class).get();
/*
* Capture Collection
*/
final CaptureContainer captureContainer = captureRegistry.getContainer();
Optional<Location> initial = captureContainer.get(GuardianSequence.INITIAL_LOCATION);
Optional<Set<String>> invalidControls = captureContainer.get(InvalidControlCapture.INVALID_CONTROLS);
if (!initial.isPresent() || !invalidControls.isPresent())
return false;
long current = System.currentTimeMillis();
// Finds the average between now and the last action.
double averageClockRate = ((current - lastActionTime) / 1000) / 0.05;
if (averageClockRate < minimumTickRate) {
detection.getLogger().warn("The server may be overloaded. A check could not be completed.");
return false;
} else if (averageClockRate > maximumTickRate) {
return false;
}
if (invalidControls.get().isEmpty() || player.get(Keys.VEHICLE).isPresent())
return false;
// ------------------------- DEBUG -----------------------------
System.out.println(player.getName() + " has been caught using invalid movement hacks.");
// -------------------------------------------------------------
SequenceReport report = new SequenceReport(true, Origin.source(sequenceContext.getRoot()).owner(entityEntry).build());
report.put("type", "InvalidControlCapture Movement");
report.put("information", Collections.singletonList("Received invalid controls of " + StringUtils.join((Set<String>) invalidControls.get(), ", ") + "."));
report.put("initial_location", initial.get());
report.put("final_location", player.getLocation());
report.put("severity", 1d);
summary.set(SequenceReport.class, report);
return true;
}, ConditionType.NORMAL).build(SequenceContext.builder().owner(detection).root(this).build());
}
Aggregations