Filter fabric player move events based on previous location

Affects issues:
- Fixed #2324
This commit is contained in:
Aurora Lahtela 2022-04-15 12:46:14 +03:00
parent 71927903aa
commit e6f3377bc2
3 changed files with 96 additions and 1 deletions

View File

@ -0,0 +1,82 @@
/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package net.playeranalytics.plan.gathering;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.locks.ReentrantLock;
public class FabricPlayerPositionTracker {
private static final ReentrantLock WRITE_LOCK = new ReentrantLock();
private static final Map<UUID, double[]> POSITIONS = new HashMap<>();
private static final double[] EMPTY_POSITION = new double[5];
public FabricPlayerPositionTracker() {
// Static method class
}
public static void removePlayer(UUID playerUUID) {
try {
WRITE_LOCK.lock();
POSITIONS.remove(playerUUID);
} finally {
WRITE_LOCK.unlock();
}
}
public static double[] getPosition(UUID playerUUID) {
return POSITIONS.getOrDefault(playerUUID, EMPTY_POSITION);
}
public static boolean moved(UUID playerUUID, double x, double y, double z, float yaw, float pitch) {
double[] previous = POSITIONS.get(playerUUID);
if (isDifferent(previous, x, y, z, yaw, pitch)) {
writeNewPosition(playerUUID, x, y, z, yaw, pitch, previous);
return true;
}
return false;
}
private static void writeNewPosition(UUID playerUUID, double x, double y, double z, float yaw, float pitch, double[] previous) {
try {
WRITE_LOCK.lock();
if (previous == null) {
previous = new double[5];
POSITIONS.put(playerUUID, previous);
}
previous[0] = x;
previous[1] = y;
previous[2] = z;
previous[3] = yaw;
previous[4] = pitch;
} finally {
WRITE_LOCK.unlock();
}
}
private static boolean isDifferent(double[] previous, double x, double y, double z, float yaw, float pitch) {
return previous == null
|| Double.compare(previous[0], x) != 0
|| Double.compare(previous[1], y) != 0
|| Double.compare(previous[2], z) != 0
|| Double.compare(previous[3], yaw) != 0
|| Double.compare(previous[4], pitch) != 0;
}
}

View File

@ -28,9 +28,11 @@ import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.text.Text;
import net.minecraft.world.GameMode;
import net.playeranalytics.plan.PlanFabric;
import net.playeranalytics.plan.gathering.FabricPlayerPositionTracker;
import java.net.SocketAddress;
import java.util.Collection;
import java.util.UUID;
public class PlanFabricEvents {
@ -48,7 +50,16 @@ public class PlanFabricEvents {
public static final Event<OnMove> ON_MOVE = EventFactory.createArrayBacked(OnMove.class, callbacks -> (handler, packet) -> {
for (OnMove callback : callbacks) {
callback.onMove(handler, packet);
UUID playerUUID = handler.player.getUuid();
double[] position = FabricPlayerPositionTracker.getPosition(playerUUID);
double x = position[0];
double y = position[1];
double z = position[2];
float yaw = (float) position[3];
float pitch = (float) position[4];
if (FabricPlayerPositionTracker.moved(playerUUID, packet.getX(x), packet.getY(y), packet.getZ(z), packet.getYaw(yaw), packet.getPitch(pitch))) {
callback.onMove(handler, packet);
}
}
});

View File

@ -42,6 +42,7 @@ import com.mojang.authlib.GameProfile;
import net.fabricmc.fabric.api.networking.v1.ServerPlayConnectionEvents;
import net.minecraft.server.dedicated.MinecraftDedicatedServer;
import net.minecraft.server.network.ServerPlayerEntity;
import net.playeranalytics.plan.gathering.FabricPlayerPositionTracker;
import net.playeranalytics.plan.gathering.listeners.FabricListener;
import net.playeranalytics.plan.gathering.listeners.events.PlanFabricEvents;
@ -234,6 +235,7 @@ public class PlayerOnlineListener implements FabricListener {
beforePlayerQuit(player);
try {
actOnQuitEvent(player);
FabricPlayerPositionTracker.removePlayer(player.getUuid());
} catch (Exception e) {
errorLogger.error(e, ErrorContext.builder().related(getClass(), player).build());
}