Initial versions of Sponge Listeners (untested) #559

This commit is contained in:
Rsl1122 2018-04-11 17:00:57 +03:00
parent e4d16685a4
commit ef05304efd
13 changed files with 711 additions and 75 deletions

View File

@ -38,7 +38,7 @@ public class SpongeSystem extends PlanSystem implements ServerSystem {
fileSystem = new FileSystem(plugin);
configSystem = new BukkitConfigSystem();
databaseSystem = new BukkitDBSystem();
listenerSystem = new SpongeListenerSystem();
listenerSystem = new SpongeListenerSystem(plugin);
taskSystem = new SpongeTaskSystem();
infoSystem = new BukkitInfoSystem();

View File

@ -1,14 +1,32 @@
package com.djrapitops.plan.system.listeners;
import com.djrapitops.plan.PlanSponge;
import com.djrapitops.plan.system.listeners.sponge.*;
import org.spongepowered.api.Sponge;
public class SpongeListenerSystem extends ListenerSystem {
private final PlanSponge plugin;
public SpongeListenerSystem(PlanSponge plugin) {
this.plugin = plugin;
}
@Override
protected void registerListeners() {
plugin.registerListener(
new SpongeAFKListener(),
new SpongeChatListener(),
new SpongeCommandListener(),
new SpongeDeathListener(),
new SpongeGMChangeListener(),
new SpongePlayerListener(),
new SpongeWorldChangeListener()
);
}
@Override
protected void unregisterListeners() {
Sponge.getEventManager().unregisterPluginListeners(plugin);
}
}

View File

@ -31,6 +31,13 @@ public class ChatListener implements Listener {
}
try {
actOnChatEvent(event);
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private void actOnChatEvent(AsyncPlayerChatEvent event) {
Player p = event.getPlayer();
UUID uuid = p.getUniqueId();
String name = p.getName();
@ -42,8 +49,5 @@ public class ChatListener implements Listener {
}
Processing.submit(new NameProcessor(uuid, name, displayName));
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
}

View File

@ -43,6 +43,13 @@ public class CommandPreprocessListener implements Listener {
}
try {
actOnCommandEvent(event);
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private void actOnCommandEvent(PlayerCommandPreprocessEvent event) {
String commandName = event.getMessage().substring(1).split(" ")[0].toLowerCase();
boolean logUnknownCommands = Settings.LOG_UNKNOWN_COMMANDS.isTrue();
@ -59,9 +66,6 @@ public class CommandPreprocessListener implements Listener {
}
}
Processing.submit(new CommandProcessor(commandName));
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private Command getBukkitCommand(String commandName) {

View File

@ -72,6 +72,13 @@ public class PlayerOnlineListener implements Listener {
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoin(PlayerJoinEvent event) {
try {
actOnJoinEvent(event);
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private void actOnJoinEvent(PlayerJoinEvent event) {
Player player = event.getPlayer();
NotificationCenter.checkNotifications(player);
@ -100,14 +107,18 @@ public class PlayerOnlineListener implements Listener {
)
);
Processing.submit(new NetworkPageUpdateProcessor());
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onPlayerQuit(PlayerQuitEvent event) {
try {
actOnQuitEvent(event);
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private void actOnQuitEvent(PlayerQuitEvent event) {
long time = MiscUtils.getTime();
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
@ -125,8 +136,5 @@ public class PlayerOnlineListener implements Listener {
}
Processing.submit(new PlayerPageUpdateProcessor(uuid));
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
}

View File

@ -0,0 +1,68 @@
package com.djrapitops.plan.system.listeners.sponge;
import com.djrapitops.plan.system.afk.AFKTracker;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.api.utility.log.Log;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.Order;
import org.spongepowered.api.event.command.SendCommandEvent;
import org.spongepowered.api.event.entity.MoveEntityEvent;
import org.spongepowered.api.event.entity.living.humanoid.player.PlayerChangeClientSettingsEvent;
import org.spongepowered.api.event.entity.living.humanoid.player.TargetPlayerEvent;
import org.spongepowered.api.event.filter.cause.First;
import org.spongepowered.api.event.message.MessageChannelEvent;
import java.util.UUID;
/**
* Listener that keeps track of actions that are not considered being AFK.
* <p>
* Additional Listener calls in SpongePlayerListener to avoid having HIGHEST priority listeners.
*
* @author Rsl1122
* @see SpongePlayerListener
*/
public class SpongeAFKListener {
// Static so that /reload does not cause afk tracking to fail.
public static final AFKTracker AFK_TRACKER = new AFKTracker();
private void event(TargetPlayerEvent event) {
try {
UUID uuid = event.getTargetEntity().getUniqueId();
long time = MiscUtils.getTime();
AFK_TRACKER.performedAction(uuid, time);
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
@Listener(order = Order.POST)
public void onMove(MoveEntityEvent event, @First Player player) {
UUID uuid = player.getUniqueId();
long time = MiscUtils.getTime();
AFK_TRACKER.performedAction(uuid, time);
}
@Listener(order = Order.POST)
public void onPlayerChat(MessageChannelEvent.Chat event, @First Player player) {
UUID uuid = player.getUniqueId();
long time = MiscUtils.getTime();
AFK_TRACKER.performedAction(uuid, time);
}
@Listener(order = Order.POST)
public void onPlayerCommand(SendCommandEvent event, @First Player player) {
UUID uuid = player.getUniqueId();
long time = MiscUtils.getTime();
AFK_TRACKER.performedAction(uuid, time);
}
@Listener(order = Order.POST)
public void onSettingsChange(PlayerChangeClientSettingsEvent event) {
event(event);
}
}

View File

@ -0,0 +1,48 @@
package com.djrapitops.plan.system.listeners.sponge;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.player.NameProcessor;
import com.djrapitops.plugin.api.utility.log.Log;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.Order;
import org.spongepowered.api.event.filter.cause.First;
import org.spongepowered.api.event.message.MessageChannelEvent;
import java.util.UUID;
/**
* Listener that keeps track of player display name.
*
* @author Rsl1122
*/
public class SpongeChatListener {
@Listener(order = Order.POST)
public void onPlayerChat(MessageChannelEvent.Chat event, @First Player player) {
if (event.isCancelled()) {
return;
}
try {
actOnChatEvent(player);
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private void actOnChatEvent(@First Player player) {
UUID uuid = player.getUniqueId();
String name = player.getName();
String displayName = player.getDisplayNameData().displayName().get().toPlain();
SessionCache sessionCache = SessionCache.getInstance();
if (sessionCache.isFirstSession(uuid)) {
sessionCache.firstSessionMessageSent(uuid);
}
Processing.submit(new NameProcessor(uuid, name, displayName));
}
}

View File

@ -0,0 +1,57 @@
package com.djrapitops.plan.system.listeners.sponge;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.CommandProcessor;
import com.djrapitops.plan.system.settings.Permissions;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plugin.api.utility.log.Log;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.command.CommandMapping;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.Order;
import org.spongepowered.api.event.command.SendCommandEvent;
import org.spongepowered.api.event.filter.cause.First;
import java.util.Optional;
/**
* Listener that keeps track of used commands.
*
* @author Rsl1122
*/
public class SpongeCommandListener {
@Listener(order = Order.POST)
public void onPlayerCommand(SendCommandEvent event, @First Player player) {
boolean hasIgnorePermission = player.hasPermission(Permissions.IGNORE_COMMANDUSE.getPermission());
if (event.isCancelled() || hasIgnorePermission) {
return;
}
try {
actOnCommandEvent(event);
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private void actOnCommandEvent(SendCommandEvent event) {
String commandName = event.getCommand();
boolean logUnknownCommands = Settings.LOG_UNKNOWN_COMMANDS.isTrue();
boolean combineCommandAliases = Settings.COMBINE_COMMAND_ALIASES.isTrue();
if (!logUnknownCommands || combineCommandAliases) {
Optional<? extends CommandMapping> existingCommand = Sponge.getCommandManager().get(commandName);
if (!existingCommand.isPresent()) {
if (!logUnknownCommands) {
return;
}
} else if (combineCommandAliases) {
commandName = existingCommand.get().getPrimaryAlias();
}
}
Processing.submit(new CommandProcessor(commandName));
}
}

View File

@ -0,0 +1,119 @@
package com.djrapitops.plan.system.listeners.sponge;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.player.SpongeKillProcessor;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.api.utility.log.Log;
import com.djrapitops.plugin.utilities.Format;
import org.spongepowered.api.data.type.HandTypes;
import org.spongepowered.api.entity.Entity;
import org.spongepowered.api.entity.living.Living;
import org.spongepowered.api.entity.living.animal.Wolf;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.projectile.arrow.Arrow;
import org.spongepowered.api.entity.projectile.source.ProjectileSource;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.cause.entity.damage.source.EntityDamageSource;
import org.spongepowered.api.event.entity.DestructEntityEvent;
import org.spongepowered.api.item.ItemType;
import org.spongepowered.api.item.ItemTypes;
import org.spongepowered.api.item.inventory.ItemStack;
import java.util.Optional;
import java.util.UUID;
/**
* Listener for Deaths and Kills on Sponge.
*
* @author Rsl1122
*/
public class SpongeDeathListener {
@Listener
public void onEntityDeath(DestructEntityEvent.Death event) {
long time = MiscUtils.getTime();
Living dead = event.getTargetEntity();
if (dead instanceof Player) {
// Process Death
Processing.submitCritical(() -> SessionCache.getCachedSession(dead.getUniqueId()).ifPresent(Session::died));
}
try {
Optional<EntityDamageSource> optDamageSource = event.getCause().first(EntityDamageSource.class);
if (optDamageSource.isPresent()) {
EntityDamageSource damageSource = optDamageSource.get();
Entity killerEntity = damageSource.getSource();
handleKill(time, dead, killerEntity);
}
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private void handleKill(long time, Living dead, Entity killerEntity) {
SpongeKillProcessor processor = null;
if (killerEntity instanceof Player) {
processor = handlePlayerKill(time, dead, (Player) killerEntity);
} else if (killerEntity instanceof Wolf) {
processor = handleWolfKill(time, dead, (Wolf) killerEntity);
} else if (killerEntity instanceof Arrow) {
processor = handleArrowKill(time, dead, (Arrow) killerEntity);
}
if (processor != null) {
Processing.submit(processor);
}
}
private SpongeKillProcessor handlePlayerKill(long time, Living dead, Player killer) {
Optional<ItemStack> inMainHand = killer.getItemInHand(HandTypes.MAIN_HAND);
ItemStack inHand = inMainHand.orElse(killer.getItemInHand(HandTypes.OFF_HAND).orElse(ItemStack.empty()));
ItemType type = inHand.isEmpty() ? ItemTypes.AIR : inHand.getType();
return new SpongeKillProcessor(killer.getUniqueId(), time, dead, normalizeItemName(type));
}
private SpongeKillProcessor handleWolfKill(long time, Living dead, Wolf wolf) {
Optional<UUID> creator = wolf.getCreator();
return creator.map(
uuid -> new SpongeKillProcessor(uuid, time, dead, "Wolf")
).orElse(null);
}
private SpongeKillProcessor handleArrowKill(long time, Living dead, Arrow arrow) {
ProjectileSource source = arrow.getShooter();
if (!(source instanceof Player)) {
return null;
}
Player player = (Player) source;
return new SpongeKillProcessor(player.getUniqueId(), time, dead, "Bow");
}
/**
* Normalizes an item name
*
* @param type The type of the item
* @return The normalized item name
*/
private String normalizeItemName(ItemType type) {
String[] parts = type.getName().split("_");
StringBuilder builder = new StringBuilder();
for (int i = 0; i < parts.length; i++) {
String part = new Format(parts[i]).capitalize().toString();
builder.append(part);
if (i < parts.length - 1) {
builder.append(" ");
}
}
return builder.toString();
}
}

View File

@ -0,0 +1,50 @@
package com.djrapitops.plan.system.listeners.sponge;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.settings.WorldAliasSettings;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.api.utility.log.Log;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.Order;
import org.spongepowered.api.event.entity.living.humanoid.ChangeGameModeEvent;
import java.util.Optional;
import java.util.UUID;
/**
* Listener for GameMode change on Sponge.
*
* @author Rsl1122
*/
public class SpongeGMChangeListener {
@Listener(order = Order.POST)
public void onGMChange(ChangeGameModeEvent.TargetPlayer event) {
if (event.isCancelled()) {
return;
}
try {
actOnGMChangeEvent(event);
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private void actOnGMChangeEvent(ChangeGameModeEvent.TargetPlayer event) {
Player player = event.getTargetEntity();
UUID uuid = player.getUniqueId();
long time = MiscUtils.getTime();
String gameMode = event.getGameMode().getName().toUpperCase();
String worldName = player.getWorld().getName();
WorldAliasSettings.addWorld(worldName);
Optional<Session> cachedSession = SessionCache.getCachedSession(uuid);
cachedSession.ifPresent(session -> session.changeState(worldName, gameMode, time));
}
}

View File

@ -0,0 +1,143 @@
package com.djrapitops.plan.system.listeners.sponge;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.processing.Processing;
import com.djrapitops.plan.system.processing.processors.info.NetworkPageUpdateProcessor;
import com.djrapitops.plan.system.processing.processors.info.PlayerPageUpdateProcessor;
import com.djrapitops.plan.system.processing.processors.player.*;
import com.djrapitops.plan.system.tasks.TaskSystem;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.api.systems.NotificationCenter;
import com.djrapitops.plugin.api.utility.log.Log;
import org.spongepowered.api.Sponge;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.gamemode.GameMode;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.Order;
import org.spongepowered.api.event.entity.living.humanoid.player.KickPlayerEvent;
import org.spongepowered.api.event.network.ClientConnectionEvent;
import org.spongepowered.api.profile.GameProfile;
import org.spongepowered.api.service.ProviderRegistration;
import org.spongepowered.api.service.ban.BanService;
import java.util.Optional;
import java.util.UUID;
/**
* Listener for Player Join/Leave on Sponge.
*
* @author Rsl1122
*/
public class SpongePlayerListener {
@Listener(order = Order.POST)
public void onLogin(ClientConnectionEvent.Login event) {
try {
actOnLoginEvent(event);
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private void actOnLoginEvent(ClientConnectionEvent.Login event) {
GameProfile profile = event.getProfile();
UUID uuid = profile.getUniqueId();
boolean banned = isBanned(profile);
Processing.submit(new BanAndOpProcessor(uuid, banned, false));
}
@Listener(order = Order.POST)
public void onKick(KickPlayerEvent event) {
try {
UUID uuid = event.getTargetEntity().getUniqueId();
Processing.submit(new KickProcessor(uuid));
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private boolean isBanned(GameProfile profile) {
Optional<ProviderRegistration<BanService>> banService = Sponge.getServiceManager().getRegistration(BanService.class);
boolean banned = false;
if (banService.isPresent()) {
banned = banService.get().getProvider().isBanned(profile);
}
return banned;
}
@Listener(order = Order.POST)
public void onJoin(ClientConnectionEvent.Join event) {
try {
actOnJoinEvent(event);
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private void actOnJoinEvent(ClientConnectionEvent.Join event) {
Player player = event.getTargetEntity();
NotificationCenter.checkNotifications(player);
UUID uuid = player.getUniqueId();
long time = MiscUtils.getTime();
SpongeAFKListener.AFK_TRACKER.performedAction(uuid, time);
String world = player.getWorld().getName();
Optional<GameMode> gameMode = player.getGameModeData().get(Keys.GAME_MODE);
String gm = "ADVENTURE";
if (gameMode.isPresent()) {
gm = gameMode.get().getName().toUpperCase();
}
String ip = player.getConnection().getAddress().getAddress().getHostAddress();
String playerName = player.getName();
String displayName = player.getDisplayNameData().displayName().get().toPlain();
int playersOnline = TaskSystem.getInstance().getTpsCountTimer().getLatestPlayersOnline();
SessionCache.getInstance().cacheSession(uuid, new Session(time, world, gm));
Processing.submit(
new RegisterProcessor(uuid, time, time, playerName, playersOnline,
new IPUpdateProcessor(uuid, ip, time),
new NameProcessor(uuid, playerName, displayName),
new PlayerPageUpdateProcessor(uuid)
)
);
Processing.submit(new NetworkPageUpdateProcessor());
}
@Listener(order = Order.POST)
public void onQuit(ClientConnectionEvent.Disconnect event) {
try {
actOnQuitEvent(event);
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private void actOnQuitEvent(ClientConnectionEvent.Disconnect event) {
long time = MiscUtils.getTime();
Player player = event.getTargetEntity();
UUID uuid = player.getUniqueId();
SpongeAFKListener.AFK_TRACKER.loggedOut(uuid, time);
Processing.submit(new BanAndOpProcessor(uuid, isBanned(player.getProfile()), false));
Processing.submit(new EndSessionProcessor(uuid, time));
Processing.submit(new NetworkPageUpdateProcessor());
SessionCache sessionCache = SessionCache.getInstance();
if (sessionCache.isFirstSession(uuid)) {
int messagesSent = sessionCache.getFirstSessionMsgCount(uuid);
Processing.submit(new FirstLeaveProcessor(uuid, time, messagesSent));
}
Processing.submit(new PlayerPageUpdateProcessor(uuid));
}
}

View File

@ -0,0 +1,58 @@
package com.djrapitops.plan.system.listeners.sponge;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.settings.WorldAliasSettings;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plugin.api.utility.log.Log;
import org.spongepowered.api.data.key.Keys;
import org.spongepowered.api.entity.living.player.Player;
import org.spongepowered.api.entity.living.player.gamemode.GameMode;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.Order;
import org.spongepowered.api.event.entity.MoveEntityEvent;
import org.spongepowered.api.event.filter.cause.First;
import java.util.Optional;
import java.util.UUID;
/**
* Listener for World change on Sponge.
*
* @author Rsl1122
*/
public class SpongeWorldChangeListener {
@Listener(order = Order.POST)
public void onWorldChange(MoveEntityEvent.Teleport event, @First Player player) {
if (event.isCancelled()) {
return;
}
try {
actOnEvent(event, player);
} catch (Exception e) {
Log.toLog(this.getClass(), e);
}
}
private void actOnEvent(MoveEntityEvent.Teleport event, Player player) {
long time = MiscUtils.getTime();
UUID uuid = player.getUniqueId();
String worldName = event.getToTransform().getExtent().getName();
String gameMode = getGameMode(player);
WorldAliasSettings.addWorld(worldName);
Optional<Session> cachedSession = SessionCache.getCachedSession(uuid);
cachedSession.ifPresent(session -> session.changeState(worldName, gameMode, time));
}
private String getGameMode(Player player) {
Optional<GameMode> gameMode = player.getGameModeData().get(Keys.GAME_MODE);
return gameMode.map(gm -> gm.getName().toUpperCase()).orElse("ADVENTURE");
}
}

View File

@ -0,0 +1,59 @@
package com.djrapitops.plan.system.processing.processors.player;
import com.djrapitops.plan.data.container.PlayerKill;
import com.djrapitops.plan.data.container.Session;
import com.djrapitops.plan.system.cache.SessionCache;
import com.djrapitops.plan.system.processing.CriticalRunnable;
import org.bukkit.entity.Player;
import org.spongepowered.api.entity.living.Living;
import java.util.Optional;
import java.util.UUID;
/**
* Processor Class for KillEvent information when the killer is a
* player.
* <p>
* Adds PlayerKill or a Mob kill to the active Session.
*
* @author Rsl1122
* @since 4.3.0
*/
public class SpongeKillProcessor implements CriticalRunnable {
private final UUID uuid;
private final Living dead;
private final String weaponName;
private final long time;
/**
* Constructor.
*
* @param uuid UUID of the killer.
* @param time Epoch ms the event occurred.
* @param dead Dead entity (Mob or Player)
* @param weaponName Weapon used.
*/
public SpongeKillProcessor(UUID uuid, long time, Living dead, String weaponName) {
this.uuid = uuid;
this.time = time;
this.dead = dead;
this.weaponName = weaponName;
}
@Override
public void run() {
Optional<Session> cachedSession = SessionCache.getCachedSession(uuid);
if (!cachedSession.isPresent()) {
return;
}
Session session = cachedSession.get();
if (dead instanceof Player) {
Player deadPlayer = (Player) dead;
session.playerKilled(new PlayerKill(deadPlayer.getUniqueId(), weaponName, time));
} else {
session.mobKilled();
}
}
}