diff --git a/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java index 90169df5c..46d620f0d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/SpongeSystem.java @@ -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(); diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java index 793df78a4..27ccc1def 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/SpongeListenerSystem.java @@ -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); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/ChatListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/ChatListener.java index 2f767ba06..2a87cd7eb 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/ChatListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/ChatListener.java @@ -31,19 +31,23 @@ public class ChatListener implements Listener { } try { - Player p = event.getPlayer(); - UUID uuid = p.getUniqueId(); - String name = p.getName(); - String displayName = p.getDisplayName(); - - SessionCache sessionCache = SessionCache.getInstance(); - if (sessionCache.isFirstSession(uuid)) { - sessionCache.firstSessionMessageSent(uuid); - } - - Processing.submit(new NameProcessor(uuid, name, displayName)); + 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(); + String displayName = p.getDisplayName(); + + SessionCache sessionCache = SessionCache.getInstance(); + if (sessionCache.isFirstSession(uuid)) { + sessionCache.firstSessionMessageSent(uuid); + } + + Processing.submit(new NameProcessor(uuid, name, displayName)); + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandPreprocessListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandPreprocessListener.java index 0d7aabde9..9af4a5f0d 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandPreprocessListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/CommandPreprocessListener.java @@ -43,27 +43,31 @@ public class CommandPreprocessListener implements Listener { } try { - String commandName = event.getMessage().substring(1).split(" ")[0].toLowerCase(); - - boolean logUnknownCommands = Settings.LOG_UNKNOWN_COMMANDS.isTrue(); - boolean combineCommandAliases = Settings.COMBINE_COMMAND_ALIASES.isTrue(); - - if (!logUnknownCommands || combineCommandAliases) { - Command command = getBukkitCommand(commandName); - if (command == null) { - if (!logUnknownCommands) { - return; - } - } else if (combineCommandAliases) { - commandName = command.getName(); - } - } - Processing.submit(new CommandProcessor(commandName)); + 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(); + boolean combineCommandAliases = Settings.COMBINE_COMMAND_ALIASES.isTrue(); + + if (!logUnknownCommands || combineCommandAliases) { + Command command = getBukkitCommand(commandName); + if (command == null) { + if (!logUnknownCommands) { + return; + } + } else if (combineCommandAliases) { + commandName = command.getName(); + } + } + Processing.submit(new CommandProcessor(commandName)); + } + private Command getBukkitCommand(String commandName) { Command command = plugin.getServer().getPluginCommand(commandName); if (command == null) { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java index 31fd2ba4b..eda55f727 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/bukkit/PlayerOnlineListener.java @@ -72,61 +72,69 @@ public class PlayerOnlineListener implements Listener { @EventHandler(priority = EventPriority.MONITOR) public void onPlayerJoin(PlayerJoinEvent event) { try { - Player player = event.getPlayer(); - NotificationCenter.checkNotifications(player); - - UUID uuid = player.getUniqueId(); - long time = MiscUtils.getTime(); - - AFKListener.AFK_TRACKER.performedAction(uuid, time); - - String world = player.getWorld().getName(); - String gm = player.getGameMode().name(); - - String ip = player.getAddress().getAddress().getHostAddress(); - - String playerName = player.getName(); - String displayName = player.getDisplayName(); - - int playersOnline = TaskSystem.getInstance().getTpsCountTimer().getLatestPlayersOnline(); - - SessionCache.getInstance().cacheSession(uuid, new Session(time, world, gm)); - - Processing.submit( - new RegisterProcessor(uuid, player.getFirstPlayed(), time, playerName, playersOnline, - new IPUpdateProcessor(uuid, ip, time), - new NameProcessor(uuid, playerName, displayName), - new PlayerPageUpdateProcessor(uuid) - ) - ); - Processing.submit(new NetworkPageUpdateProcessor()); + actOnJoinEvent(event); } catch (Exception e) { Log.toLog(this.getClass(), e); } } + private void actOnJoinEvent(PlayerJoinEvent event) { + Player player = event.getPlayer(); + NotificationCenter.checkNotifications(player); + + UUID uuid = player.getUniqueId(); + long time = MiscUtils.getTime(); + + AFKListener.AFK_TRACKER.performedAction(uuid, time); + + String world = player.getWorld().getName(); + String gm = player.getGameMode().name(); + + String ip = player.getAddress().getAddress().getHostAddress(); + + String playerName = player.getName(); + String displayName = player.getDisplayName(); + + int playersOnline = TaskSystem.getInstance().getTpsCountTimer().getLatestPlayersOnline(); + + SessionCache.getInstance().cacheSession(uuid, new Session(time, world, gm)); + + Processing.submit( + new RegisterProcessor(uuid, player.getFirstPlayed(), time, playerName, playersOnline, + new IPUpdateProcessor(uuid, ip, time), + new NameProcessor(uuid, playerName, displayName), + new PlayerPageUpdateProcessor(uuid) + ) + ); + Processing.submit(new NetworkPageUpdateProcessor()); + } + @EventHandler(priority = EventPriority.MONITOR) public void onPlayerQuit(PlayerQuitEvent event) { try { - long time = MiscUtils.getTime(); - Player player = event.getPlayer(); - UUID uuid = player.getUniqueId(); - - AFKListener.AFK_TRACKER.loggedOut(uuid, time); - - Processing.submit(new BanAndOpProcessor(uuid, player.isBanned(), player.isOp())); - 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)); + 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(); + + AFKListener.AFK_TRACKER.loggedOut(uuid, time); + + Processing.submit(new BanAndOpProcessor(uuid, player.isBanned(), player.isOp())); + 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)); + } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeAFKListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeAFKListener.java new file mode 100644 index 000000000..62a2897fd --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeAFKListener.java @@ -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. + *

+ * 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); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeChatListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeChatListener.java new file mode 100644 index 000000000..c3f7f56af --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeChatListener.java @@ -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)); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeCommandListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeCommandListener.java new file mode 100644 index 000000000..1eccd3774 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeCommandListener.java @@ -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 existingCommand = Sponge.getCommandManager().get(commandName); + if (!existingCommand.isPresent()) { + if (!logUnknownCommands) { + return; + } + } else if (combineCommandAliases) { + commandName = existingCommand.get().getPrimaryAlias(); + } + } + Processing.submit(new CommandProcessor(commandName)); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java new file mode 100644 index 000000000..93b5cc42a --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeDeathListener.java @@ -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 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 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 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(); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeGMChangeListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeGMChangeListener.java new file mode 100644 index 000000000..c1bfa3850 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeGMChangeListener.java @@ -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 cachedSession = SessionCache.getCachedSession(uuid); + cachedSession.ifPresent(session -> session.changeState(worldName, gameMode, time)); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java new file mode 100644 index 000000000..38135e5be --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongePlayerListener.java @@ -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> 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 = 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)); + } +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeWorldChangeListener.java b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeWorldChangeListener.java new file mode 100644 index 000000000..230983ea8 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/listeners/sponge/SpongeWorldChangeListener.java @@ -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 cachedSession = SessionCache.getCachedSession(uuid); + cachedSession.ifPresent(session -> session.changeState(worldName, gameMode, time)); + } + + private String getGameMode(Player player) { + Optional gameMode = player.getGameModeData().get(Keys.GAME_MODE); + return gameMode.map(gm -> gm.getName().toUpperCase()).orElse("ADVENTURE"); + } + +} \ No newline at end of file diff --git a/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java new file mode 100644 index 000000000..d352c3b4f --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/processing/processors/player/SpongeKillProcessor.java @@ -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. + *

+ * 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 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(); + } + } +}