diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/BukkitTaskSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/BukkitTaskSystem.java index b99dde0c8..1a769c767 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/BukkitTaskSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/BukkitTaskSystem.java @@ -8,7 +8,7 @@ import com.djrapitops.plan.Plan; import com.djrapitops.plan.system.settings.Settings; import com.djrapitops.plan.system.tasks.server.BukkitTPSCountTimer; import com.djrapitops.plan.system.tasks.server.PaperTPSCountTimer; -import com.djrapitops.plan.system.tasks.server.PingCountTimer; +import com.djrapitops.plan.system.tasks.server.PingCountTimerBukkit; import com.djrapitops.plugin.api.Check; import com.djrapitops.plugin.api.TimeAmount; import com.djrapitops.plugin.task.RunnableFactory; @@ -33,11 +33,11 @@ public class BukkitTaskSystem extends ServerTaskSystem { public void enable() { super.enable(); try { - PingCountTimer pingCountTimer = new PingCountTimer(); + PingCountTimerBukkit pingCountTimer = new PingCountTimerBukkit(); ((Plan) plugin).registerListener(pingCountTimer); long startDelay = TimeAmount.SECOND.ticks() * (long) Settings.PING_SERVER_ENABLE_DELAY.getNumber(); RunnableFactory.createNew("PingCountTimer", pingCountTimer) - .runTaskTimer(startDelay, PingCountTimer.PING_INTERVAL); + .runTaskTimer(startDelay, PingCountTimerBukkit.PING_INTERVAL); } catch (ExceptionInInitializerError | NoClassDefFoundError ignore) { // Running CraftBukkit } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/SpongeTaskSystem.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/SpongeTaskSystem.java index 7b0017108..9b13ed881 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/SpongeTaskSystem.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/SpongeTaskSystem.java @@ -1,7 +1,11 @@ package com.djrapitops.plan.system.tasks; import com.djrapitops.plan.PlanSponge; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plan.system.tasks.server.PingCountTimerSponge; import com.djrapitops.plan.system.tasks.server.SpongeTPSCountTimer; +import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plugin.task.RunnableFactory; import org.spongepowered.api.Sponge; import org.spongepowered.api.scheduler.Task; @@ -10,6 +14,20 @@ public class SpongeTaskSystem extends ServerTaskSystem { public SpongeTaskSystem(PlanSponge plugin) { super(plugin, new SpongeTPSCountTimer(plugin)); } + + @Override + public void enable() { + super.enable(); + try { + PingCountTimerSponge pingCountTimer = new PingCountTimerSponge(); + Sponge.getEventManager().registerListeners(plugin, pingCountTimer); + long startDelay = TimeAmount.SECOND.ticks() * (long) Settings.PING_SERVER_ENABLE_DELAY.getNumber(); + RunnableFactory.createNew("PingCountTimer", pingCountTimer) + .runTaskTimer(startDelay, PingCountTimerSponge.PING_INTERVAL); + } catch (ExceptionInInitializerError | NoClassDefFoundError ignore) { + // Running CraftBukkit + } + } @Override public void disable() { diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimer.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimerBukkit.java similarity index 97% rename from Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimer.java rename to Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimerBukkit.java index 37c0b728b..97c818546 100644 --- a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimer.java +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimerBukkit.java @@ -53,7 +53,7 @@ import java.util.*; * * @author games647 */ -public class PingCountTimer extends AbsRunnable implements Listener { +public class PingCountTimerBukkit extends AbsRunnable implements Listener { //the server is pinging the client every 40 Ticks (2 sec) - so check it then //https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/PlayerConnection.java#L178 @@ -80,7 +80,7 @@ public class PingCountTimer extends AbsRunnable implements Listener { localPing = lookup.findGetter(entityPlayer, "ping", Integer.TYPE); } catch (NoSuchMethodException | IllegalAccessException | NoSuchFieldException reflectiveEx) { - Log.toLog(PingCountTimer.class, reflectiveEx); + Log.toLog(PingCountTimerBukkit.class, reflectiveEx); } } diff --git a/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimerSponge.java b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimerSponge.java new file mode 100644 index 000000000..cfed96452 --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/system/tasks/server/PingCountTimerSponge.java @@ -0,0 +1,110 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2016-2018 + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.djrapitops.plan.system.tasks.server; + +import com.djrapitops.plan.data.store.objects.DateObj; +import com.djrapitops.plan.system.processing.Processing; +import com.djrapitops.plan.system.processing.processors.player.PingInsertProcessor; +import com.djrapitops.plan.system.settings.Settings; +import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plugin.task.AbsRunnable; +import com.djrapitops.plugin.task.RunnableFactory; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.network.ClientConnectionEvent; + +import java.util.*; + +/** + * Task that handles player ping calculation on Sponge based servers. + * + * @author BrainStone + */ +public class PingCountTimerSponge extends AbsRunnable { + + //the server is pinging the client every 40 Ticks (2 sec) - so check it then + //https://github.com/bergerkiller/CraftSource/blob/master/net.minecraft.server/PlayerConnection.java#L178 + public static final int PING_INTERVAL = 2 * 20; + + private final Map>> playerHistory = new HashMap<>(); + + @Override + public void run() { + List loggedOut = new ArrayList<>(); + long time = System.currentTimeMillis(); + playerHistory.forEach((uuid, history) -> { + Optional player = Sponge.getServer().getPlayer(uuid); + if (player.isPresent()) { + int ping = getPing(player.get()); + if (ping < -1 || ping > TimeAmount.SECOND.ms() * 8L) { + // Don't accept bad values + return; + } + history.add(new DateObj<>(time, ping)); + if (history.size() >= 30) { + Processing.submit(new PingInsertProcessor(uuid, new ArrayList<>(history))); + history.clear(); + } + } else { + loggedOut.add(uuid); + } + }); + loggedOut.forEach(playerHistory::remove); + } + + public void addPlayer(Player player) { + playerHistory.put(player.getUniqueId(), new ArrayList<>()); + } + + public void removePlayer(Player player) { + playerHistory.remove(player.getUniqueId()); + } + + private int getPing(Player player) { + return player.getConnection().getLatency(); + } + + @Listener + public void onPlayerJoin(ClientConnectionEvent.Join joinEvent) { + Player player = joinEvent.getTargetEntity(); + RunnableFactory.createNew("Add Player to Ping list", new AbsRunnable() { + @Override + public void run() { + if (player.isOnline()) { + addPlayer(player); + } + } + }).runTaskLater(TimeAmount.SECOND.ticks() * (long) Settings.PING_PLAYER_LOGIN_DELAY.getNumber()); + } + + @Listener + public void onPlayerQuit(ClientConnectionEvent.Disconnect quitEvent) { + removePlayer(quitEvent.getTargetEntity()); + } + + public void clear() { + playerHistory.clear(); + } +}