mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-11-07 11:20:11 +01:00
Implemented EnderCrystal kill detection for Sponge
Affects issues: - #1571
This commit is contained in:
parent
1f76e4a7c7
commit
111affaa50
@ -25,8 +25,10 @@ import com.djrapitops.plan.processing.processors.player.MobKillProcessor;
|
|||||||
import com.djrapitops.plan.processing.processors.player.PlayerKillProcessor;
|
import com.djrapitops.plan.processing.processors.player.PlayerKillProcessor;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
import com.djrapitops.plan.utilities.logging.ErrorContext;
|
||||||
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
import com.djrapitops.plan.utilities.logging.ErrorLogger;
|
||||||
|
import org.spongepowered.api.Sponge;
|
||||||
import org.spongepowered.api.data.key.Keys;
|
import org.spongepowered.api.data.key.Keys;
|
||||||
import org.spongepowered.api.data.type.HandTypes;
|
import org.spongepowered.api.data.type.HandTypes;
|
||||||
|
import org.spongepowered.api.entity.EnderCrystal;
|
||||||
import org.spongepowered.api.entity.Entity;
|
import org.spongepowered.api.entity.Entity;
|
||||||
import org.spongepowered.api.entity.living.Living;
|
import org.spongepowered.api.entity.living.Living;
|
||||||
import org.spongepowered.api.entity.living.animal.Wolf;
|
import org.spongepowered.api.entity.living.animal.Wolf;
|
||||||
@ -41,6 +43,7 @@ import org.spongepowered.api.item.ItemTypes;
|
|||||||
import org.spongepowered.api.item.inventory.ItemStack;
|
import org.spongepowered.api.item.inventory.ItemStack;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@ -74,76 +77,74 @@ public class SpongeDeathListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Optional<EntityDamageSource> optDamageSource = event.getCause().first(EntityDamageSource.class);
|
List<EntityDamageSource> causes = event.getCause().allOf(EntityDamageSource.class);
|
||||||
if (optDamageSource.isPresent()) {
|
Optional<Player> foundKiller = findKiller(causes, 0);
|
||||||
EntityDamageSource damageSource = optDamageSource.get();
|
if (!foundKiller.isPresent()) {
|
||||||
Entity killerEntity = damageSource.getSource();
|
return;
|
||||||
handleKill(time, dead, killerEntity);
|
|
||||||
}
|
}
|
||||||
|
Player killer = foundKiller.get();
|
||||||
|
|
||||||
|
Runnable processor = dead instanceof Player
|
||||||
|
? new PlayerKillProcessor(killer.getUniqueId(), time, dead.getUniqueId(), findWeapon(event))
|
||||||
|
: new MobKillProcessor(killer.getUniqueId());
|
||||||
|
processing.submitCritical(processor);
|
||||||
} 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, Living dead, Entity killerEntity) {
|
public Optional<Player> findKiller(List<EntityDamageSource> causes, int depth) {
|
||||||
Runnable processor = null;
|
if (causes.isEmpty() || causes.size() < depth) {
|
||||||
UUID victimUUID = getUUID(dead);
|
return Optional.empty();
|
||||||
if (killerEntity instanceof Player) {
|
|
||||||
processor = handlePlayerKill(time, victimUUID, (Player) killerEntity);
|
|
||||||
} else if (killerEntity instanceof Wolf) {
|
|
||||||
processor = handleWolfKill(time, victimUUID, (Wolf) killerEntity);
|
|
||||||
} else if (killerEntity instanceof Projectile) {
|
|
||||||
processor = handleProjectileKill(time, victimUUID, (Projectile) killerEntity);
|
|
||||||
}
|
|
||||||
if (processor != null) {
|
|
||||||
processing.submit(processor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Runnable handlePlayerKill(long time, UUID victimUUID, Player killer) {
|
EntityDamageSource damageSource = causes.get(depth);
|
||||||
|
Entity killerEntity = damageSource.getSource();
|
||||||
|
|
||||||
|
if (killerEntity instanceof Player) return Optional.of((Player) killerEntity);
|
||||||
|
if (killerEntity instanceof Wolf) return getOwner((Wolf) killerEntity);
|
||||||
|
if (killerEntity instanceof Projectile) return getShooter((Projectile) killerEntity);
|
||||||
|
if (killerEntity instanceof EnderCrystal) return findKiller(causes, depth + 1);
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String findWeapon(DestructEntityEvent.Death death) {
|
||||||
|
Optional<EntityDamageSource> damagedBy = death.getCause().first(EntityDamageSource.class);
|
||||||
|
if (damagedBy.isPresent()) {
|
||||||
|
EntityDamageSource damageSource = damagedBy.get();
|
||||||
|
Entity killerEntity = damageSource.getSource();
|
||||||
|
|
||||||
|
if (killerEntity instanceof Player) return getItemInHand((Player) killerEntity);
|
||||||
|
if (killerEntity instanceof Wolf) return "Wolf";
|
||||||
|
|
||||||
|
return new EntityNameFormatter().apply(killerEntity.getType().getName());
|
||||||
|
}
|
||||||
|
return "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getItemInHand(Player killer) {
|
||||||
Optional<ItemStack> inMainHand = killer.getItemInHand(HandTypes.MAIN_HAND);
|
Optional<ItemStack> inMainHand = killer.getItemInHand(HandTypes.MAIN_HAND);
|
||||||
ItemStack inHand = inMainHand.orElse(killer.getItemInHand(HandTypes.OFF_HAND).orElse(ItemStack.empty()));
|
ItemStack inHand = inMainHand.orElse(
|
||||||
|
killer.getItemInHand(HandTypes.OFF_HAND)
|
||||||
|
.orElse(ItemStack.empty()));
|
||||||
ItemType type = inHand.isEmpty() ? ItemTypes.AIR : inHand.getType();
|
ItemType type = inHand.isEmpty() ? ItemTypes.AIR : inHand.getType();
|
||||||
|
return new ItemNameFormatter().apply(type.getName());
|
||||||
return victimUUID != null
|
|
||||||
? new PlayerKillProcessor(killer.getUniqueId(), time, victimUUID, new ItemNameFormatter().apply(type.getName()))
|
|
||||||
: new MobKillProcessor(killer.getUniqueId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private UUID getUUID(Living dead) {
|
private Optional<Player> getShooter(Projectile projectile) {
|
||||||
if (dead instanceof Player) {
|
|
||||||
return dead.getUniqueId();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Runnable handleWolfKill(long time, UUID victimUUID, Wolf wolf) {
|
|
||||||
Optional<Optional<UUID>> owner = wolf.get(Keys.TAMED_OWNER);
|
|
||||||
|
|
||||||
// Has been tamed
|
|
||||||
// Has tame owner
|
|
||||||
return owner.flatMap(ownerUUID -> ownerUUID.map(uuid ->
|
|
||||||
// Player or mob
|
|
||||||
victimUUID != null
|
|
||||||
? new PlayerKillProcessor(uuid, time, victimUUID, "Wolf")
|
|
||||||
: new MobKillProcessor(uuid)
|
|
||||||
)).orElse(null);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Runnable handleProjectileKill(long time, UUID victimUUID, Projectile projectile) {
|
|
||||||
ProjectileSource source = projectile.getShooter();
|
ProjectileSource source = projectile.getShooter();
|
||||||
if (!(source instanceof Player)) {
|
if (source instanceof Player) {
|
||||||
return null;
|
return Optional.of((Player) source);
|
||||||
}
|
}
|
||||||
|
|
||||||
Player player = (Player) source;
|
return Optional.empty();
|
||||||
String projectileName = new EntityNameFormatter().apply(projectile.getType().getName());
|
|
||||||
|
|
||||||
return victimUUID != null
|
|
||||||
? new PlayerKillProcessor(player.getUniqueId(), time, victimUUID, projectileName)
|
|
||||||
: new MobKillProcessor(player.getUniqueId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Optional<Player> getOwner(Wolf wolf) {
|
||||||
|
Optional<Optional<UUID>> isTameable = wolf.get(Keys.TAMED_OWNER);
|
||||||
|
if (!isTameable.isPresent()) return Optional.empty();
|
||||||
|
Optional<UUID> owner = isTameable.get();
|
||||||
|
|
||||||
|
return owner.flatMap(Sponge.getGame().getServer()::getPlayer);
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user