mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-12-21 05:50:18 +08:00
Implemented EnderCrystal kill detection for Bukkit
Marks player EnderCrystal kills for a player and also counts mobs killed with EnderCrystal explosions as mob kills for a player. Affects issues: - Close #1571
This commit is contained in:
parent
8e0d833f3f
commit
89a3d63d8b
@ -36,7 +36,7 @@ import org.bukkit.event.entity.EntityDeathEvent;
|
|||||||
import org.bukkit.projectiles.ProjectileSource;
|
import org.bukkit.projectiles.ProjectileSource;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.UUID;
|
import java.util.Optional;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Event Listener for EntityDeathEvents.
|
* Event Listener for EntityDeathEvents.
|
||||||
@ -68,36 +68,57 @@ public class DeathEventListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
EntityDamageEvent entityDamageEvent = dead.getLastDamageCause();
|
Optional<Player> foundKiller = findKiller(dead);
|
||||||
if (!(entityDamageEvent instanceof EntityDamageByEntityEvent)) {
|
if (!foundKiller.isPresent()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Player killer = foundKiller.get();
|
||||||
|
|
||||||
EntityDamageByEntityEvent entityDamageByEntityEvent = (EntityDamageByEntityEvent) entityDamageEvent;
|
Runnable processor = dead instanceof Player
|
||||||
Entity killerEntity = entityDamageByEntityEvent.getDamager();
|
? new PlayerKillProcessor(killer.getUniqueId(), time, dead.getUniqueId(), findWeapon(dead))
|
||||||
|
: new MobKillProcessor(killer.getUniqueId());
|
||||||
UUID uuid = dead instanceof Player ? dead.getUniqueId() : null;
|
processing.submitCritical(processor);
|
||||||
handleKill(time, uuid, killerEntity);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
errorLogger.error(e, ErrorContext.builder().related(event, dead).build());
|
errorLogger.error(e, ErrorContext.builder().related(event, dead).build());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleKill(long time, UUID victimUUID, Entity killerEntity) {
|
public Optional<Player> findKiller(Entity dead) {
|
||||||
Runnable processor = null;
|
EntityDamageEvent entityDamageEvent = dead.getLastDamageCause();
|
||||||
if (killerEntity instanceof Player) {
|
if (!(entityDamageEvent instanceof EntityDamageByEntityEvent)) {
|
||||||
processor = handlePlayerKill(time, victimUUID, (Player) killerEntity);
|
// Not damaged by entity, can't be a player
|
||||||
} else if (killerEntity instanceof Tameable) {
|
return Optional.empty();
|
||||||
processor = handlePetKill(time, victimUUID, (Tameable) killerEntity);
|
|
||||||
} else if (killerEntity instanceof Projectile) {
|
|
||||||
processor = handleProjectileKill(time, victimUUID, (Projectile) killerEntity);
|
|
||||||
}
|
}
|
||||||
if (processor != null) {
|
|
||||||
processing.submit(processor);
|
Entity killer = ((EntityDamageByEntityEvent) entityDamageEvent).getDamager();
|
||||||
|
if (killer instanceof Player) return Optional.of((Player) killer);
|
||||||
|
if (killer instanceof Tameable) return getOwner((Tameable) killer);
|
||||||
|
if (killer instanceof Projectile) return getShooter((Projectile) killer);
|
||||||
|
if (killer instanceof EnderCrystal) return findKiller(killer); // Recursive call
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String findWeapon(Entity dead) {
|
||||||
|
EntityDamageEvent entityDamageEvent = dead.getLastDamageCause();
|
||||||
|
Entity killer = ((EntityDamageByEntityEvent) entityDamageEvent).getDamager();
|
||||||
|
if (killer instanceof Player) return getItemInHand((Player) killer);
|
||||||
|
if (killer instanceof Tameable) return getPetType((Tameable) killer);
|
||||||
|
|
||||||
|
// Projectile, EnderCrystal and all other causes that are not known yet
|
||||||
|
return new EntityNameFormatter().apply(killer.getType().name());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getPetType(Tameable tameable) {
|
||||||
|
try {
|
||||||
|
return tameable.getType().name();
|
||||||
|
} catch (NoSuchMethodError oldVersionNoTypesError) {
|
||||||
|
// getType introduced in 1.9
|
||||||
|
return tameable.getClass().getSimpleName();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable handlePlayerKill(long time, UUID victimUUID, Player killer) {
|
private String getItemInHand(Player killer) {
|
||||||
Material itemInHand;
|
Material itemInHand;
|
||||||
try {
|
try {
|
||||||
itemInHand = killer.getInventory().getItemInMainHand().getType();
|
itemInHand = killer.getInventory().getItemInMainHand().getType();
|
||||||
@ -109,48 +130,29 @@ public class DeathEventListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String weaponName = new ItemNameFormatter().apply(itemInHand.name());
|
return new ItemNameFormatter().apply(itemInHand.name());
|
||||||
|
|
||||||
return victimUUID != null
|
|
||||||
? new PlayerKillProcessor(killer.getUniqueId(), time, victimUUID, weaponName)
|
|
||||||
: new MobKillProcessor(killer.getUniqueId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable handlePetKill(long time, UUID victimUUID, Tameable tameable) {
|
private Optional<Player> getShooter(Projectile projectile) {
|
||||||
|
ProjectileSource source = projectile.getShooter();
|
||||||
|
if (source instanceof Player) {
|
||||||
|
return Optional.of((Player) source);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<Player> getOwner(Tameable tameable) {
|
||||||
if (!tameable.isTamed()) {
|
if (!tameable.isTamed()) {
|
||||||
return null;
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimalTamer owner = tameable.getOwner();
|
AnimalTamer owner = tameable.getOwner();
|
||||||
if (!(owner instanceof Player)) {
|
if (owner instanceof Player) {
|
||||||
return null;
|
return Optional.of((Player) owner);
|
||||||
}
|
}
|
||||||
|
|
||||||
String name;
|
return Optional.empty();
|
||||||
try {
|
|
||||||
name = tameable.getType().name();
|
|
||||||
} catch (NoSuchMethodError oldVersionNoTypesError) {
|
|
||||||
// getType introduced in 1.9
|
|
||||||
name = tameable.getClass().getSimpleName();
|
|
||||||
}
|
|
||||||
|
|
||||||
return victimUUID != null
|
|
||||||
? new PlayerKillProcessor(owner.getUniqueId(), time, victimUUID, new EntityNameFormatter().apply(name))
|
|
||||||
: new MobKillProcessor(owner.getUniqueId());
|
|
||||||
}
|
|
||||||
|
|
||||||
private Runnable handleProjectileKill(long time, UUID victimUUID, Projectile projectile) {
|
|
||||||
ProjectileSource source = projectile.getShooter();
|
|
||||||
if (!(source instanceof Player)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Player player = (Player) source;
|
|
||||||
String projectileName = new EntityNameFormatter().apply(projectile.getType().name());
|
|
||||||
|
|
||||||
return victimUUID != null
|
|
||||||
? new PlayerKillProcessor(player.getUniqueId(), time, victimUUID, projectileName)
|
|
||||||
: new MobKillProcessor(player.getUniqueId());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user