#738 Add check that shooter is of type Player in ProjectileLaunchEvent

- Use reflection the opposite way: if it is an old version (getShooter() returns LivingEntity), use reflection; otherwise, call the method directly
- Add missing instanceof Player check
This commit is contained in:
ljacqu 2016-06-01 14:06:36 +02:00
parent 58a6b6060f
commit e59bbbf10e

View File

@ -1,5 +1,6 @@
package fr.xephi.authme.listener; package fr.xephi.authme.listener;
import fr.xephi.authme.ConsoleLogger;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile; import org.bukkit.entity.Projectile;
@ -14,9 +15,6 @@ import org.bukkit.event.entity.EntityShootBowEvent;
import org.bukkit.event.entity.EntityTargetEvent; import org.bukkit.event.entity.EntityTargetEvent;
import org.bukkit.event.entity.FoodLevelChangeEvent; import org.bukkit.event.entity.FoodLevelChangeEvent;
import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.projectiles.ProjectileSource;
import fr.xephi.authme.ConsoleLogger;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
@ -26,12 +24,12 @@ import static fr.xephi.authme.listener.ListenerService.shouldCancelEvent;
public class AuthMeEntityListener implements Listener { public class AuthMeEntityListener implements Listener {
private Method getShooter; private Method getShooter;
private boolean shooterIsProjectileSource; private boolean shooterIsLivingEntity;
public AuthMeEntityListener() { public AuthMeEntityListener() {
try { try {
getShooter = Projectile.class.getDeclaredMethod("getShooter"); getShooter = Projectile.class.getDeclaredMethod("getShooter");
shooterIsProjectileSource = getShooter.getReturnType() != LivingEntity.class; shooterIsLivingEntity = getShooter.getReturnType() == LivingEntity.class;
} catch (NoSuchMethodException | SecurityException e) { } catch (NoSuchMethodException | SecurityException e) {
ConsoleLogger.logException("Cannot load getShooter() method on Projectile class", e); ConsoleLogger.logException("Cannot load getShooter() method on Projectile class", e);
} }
@ -98,28 +96,22 @@ public class AuthMeEntityListener implements Listener {
return; return;
} }
Player player = null;
Projectile projectile = event.getEntity(); Projectile projectile = event.getEntity();
// In old versions of the Bukkit API getShooter() returns a Player object instead of a ProjectileSource // In the Bukkit API prior to 1.7, getShooter() returns a LivingEntity instead of a ProjectileSource
if (shooterIsProjectileSource) { Object shooterRaw = null;
ProjectileSource shooter = projectile.getShooter(); if (shooterIsLivingEntity) {
if (shooter == null || !(shooter instanceof Player)) {
return;
}
player = (Player) shooter;
} else {
try { try {
if (getShooter == null) { if (getShooter == null) {
getShooter = Projectile.class.getMethod("getShooter"); getShooter = Projectile.class.getMethod("getShooter");
} }
Object obj = getShooter.invoke(projectile); shooterRaw = getShooter.invoke(projectile);
player = (Player) obj;
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) { } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
ConsoleLogger.logException("Error getting shooter", e); ConsoleLogger.logException("Error getting shooter", e);
} }
} else {
shooterRaw = projectile.getShooter();
} }
if (shooterRaw instanceof Player && shouldCancelEvent((Player) shooterRaw)) {
if (ListenerService.shouldCancelEvent(player)) {
event.setCancelled(true); event.setCancelled(true);
} }
} }