use of fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying in project NoCheatPlus by NoCheatPlus.
the class FlyingQueueLookBlockChecker method checkFlyingQueue.
/**
* Run check with the given start position (e.g. eye coordinates), but use
* yaw and pitch from the flying queue. Non matching entries are nulled,
* unless setUnusableToNull is set to false.
*
* @param x
* @param y
* @param z
* @param oldYaw
* @param oldPitch
* @param blockX
* @param blockY
* @param blockZ
* @param flyingHandle
* @return True, if check returned true (the first time is returned). False
* if the queue is empty or check has not returned true for any
* contained element. Special return values have to be set
* elsewhere. An empty queue also yields false as return value.
*/
public boolean checkFlyingQueue(final double x, final double y, final double z, final float oldYaw, final float oldPitch, final int blockX, final int blockY, final int blockZ, final FlyingQueueHandle flyingHandle) {
if (checkOldLook && flyingHandle.isCurrentLocationValid()) {
if (check(x, y, z, oldYaw, oldPitch, blockX, blockY, blockZ)) {
return true;
} else {
// Invalidate.
flyingHandle.setCurrentLocationValid(false);
}
}
final DataPacketFlying[] queue = flyingHandle.getHandle();
if (queue.length == 0) {
return false;
}
for (int i = 0; i < queue.length; i++) {
final DataPacketFlying packetData = queue[i];
if (packetData == null) {
continue;
}
if (!packetData.hasLook) {
if (invalidateFailed) {
queue[i] = null;
}
continue;
}
final float yaw = packetData.getYaw();
final float pitch = packetData.getPitch();
// TODO: Other heuristic / what's typical?
if (yaw == oldYaw && pitch == oldPitch) {
if (invalidateFailed) {
queue[i] = null;
}
continue;
}
// TODO: Consider support some other type of metric (possibly checking positions too?);
if (check(x, y, z, yaw, pitch, blockX, blockY, blockZ)) {
// TODO: Consider to remember index and entry as well?
return true;
} else {
if (invalidateFailed) {
queue[i] = null;
}
}
}
return false;
}
use of fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying in project NoCheatPlus by NoCheatPlus.
the class BlockBreakListener method debugBlockBreakResult.
private void debugBlockBreakResult(final Player player, final Block block, final int skippedRedundantChecks, final FlyingQueueHandle flyingHandle, final IPlayerData pData) {
debug(player, "Block break(" + block.getType() + "): " + block.getX() + ", " + block.getY() + ", " + block.getZ());
BlockInteractListener.debugBlockVSBlockInteract(player, checkType, block, "onBlockBreak", Action.LEFT_CLICK_BLOCK, pData);
if (skippedRedundantChecks > 0) {
debug(player, "Skipped redundant checks: " + skippedRedundantChecks);
}
if (flyingHandle != null && flyingHandle.isFlyingQueueFetched()) {
final int flyingIndex = flyingHandle.getFirstIndexWithContentIfFetched();
final DataPacketFlying packet = flyingHandle.getIfFetched(flyingIndex);
if (packet != null) {
debug(player, "Flying packet queue used at index " + flyingIndex + ": pitch=" + packet.getPitch() + ",yaw=" + packet.getYaw());
return;
}
}
}
use of fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying in project NoCheatPlus by NoCheatPlus.
the class NetData method peekFlyingQueue.
/**
* Fetch the latest packet (under lock).
*
* @return
*/
public DataPacketFlying peekFlyingQueue() {
lock.lock();
final DataPacketFlying latest = flyingQueue.isEmpty() ? null : flyingQueue.getFirst();
lock.unlock();
return latest;
}
use of fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying in project NoCheatPlus by NoCheatPlus.
the class MovingFlying method onFlyingPacket.
private void onFlyingPacket(final PacketEvent event) {
// TODO: Code review protocol plugin :p.
final boolean primaryThread = Bukkit.isPrimaryThread();
counters.add(idFlying, 1, primaryThread);
if (event.isAsync() == primaryThread) {
counters.add(ProtocolLibComponent.idInconsistentIsAsync, 1, primaryThread);
}
if (!primaryThread) {
// Count all asynchronous events extra.
counters.addSynchronized(idAsyncFlying, 1);
// TODO: Detect game phase for the player?
}
final long time = System.currentTimeMillis();
final Player player = event.getPlayer();
if (player == null) {
// TODO: Need config?
counters.add(ProtocolLibComponent.idNullPlayer, 1, primaryThread);
event.setCancelled(true);
return;
}
final IPlayerData pData = DataManager.getPlayerData(player);
// Always update last received time.
final NetData data = pData.getGenericInstance(NetData.class);
// Update without much of a contract.
data.lastKeepAliveTime = time;
// TODO: Leniency options too (packet order inversion). -> current: flyingQueue is fetched.
final IWorldData worldData = pData.getCurrentWorldDataSafe();
if (!worldData.isCheckActive(CheckType.NET_FLYINGFREQUENCY)) {
return;
}
final NetConfig cc = pData.getGenericInstance(NetConfig.class);
boolean cancel = false;
// Interpret the packet content.
final DataPacketFlying packetData = interpretPacket(event, time);
// Early return tests, if the packet can be interpreted.
boolean skipFlyingFrequency = false;
if (packetData != null) {
// Prevent processing packets with obviously malicious content.
if (isInvalidContent(packetData)) {
// TODO: extra actions: log and kick (cancel state is not evaluated)
event.setCancelled(true);
if (pData.isDebugActive(this.checkType)) {
debug(player, "Incoming packet, cancel due to malicious content: " + packetData.toString());
}
return;
}
switch(data.teleportQueue.processAck(packetData)) {
case WAITING:
{
if (pData.isDebugActive(this.checkType)) {
debug(player, "Incoming packet, still waiting for ACK on outgoing position.");
}
if (confirmTeleportType != null && cc.supersededFlyingCancelWaiting) {
// Don't add to the flying queue for now (assumed invalid).
final AckReference ackReference = data.teleportQueue.getLastAckReference();
if (ackReference.lastOutgoingId != Integer.MIN_VALUE && ackReference.lastOutgoingId != ackReference.maxConfirmedId) {
// Still waiting for a 'confirm teleport' packet. More or less safe to cancel this out.
/*
* TODO: The actual issue with this, apart from
* potential freezing, also concerns gameplay experience
* in case of minor set backs, which also could be
* caused by the server, e.g. with 'moved wrongly' or
* setting players outside of blocks. In this case the
* moves sent before teleport ack would still be valid
* after the teleport, because distances are small. The
* actual solution should still be to a) not have false
* positives b) somehow get rid all the
* position-correction teleporting the server does, for
* the cases a plugin can handle.
*/
// TODO: Timeout -> either skip cancel or schedule a set back (to last valid pos or other).
// TODO: Config?
cancel = true;
}
}
break;
}
case ACK:
{
// Skip processing ACK packets, no cancel.
skipFlyingFrequency = true;
if (pData.isDebugActive(this.checkType)) {
debug(player, "Incoming packet, interpret as ACK for outgoing position.");
}
}
default:
{
// Continue.
// TODO: Not the optimal position, perhaps.
data.addFlyingQueue(packetData);
}
}
// Add as valid packet (exclude invalid coordinates etc. for now).
validContent.add(packetData.getSimplifiedContentType());
}
// TODO: Consider using the NetStatic check.
if (!cancel && !skipFlyingFrequency && !pData.hasBypass(CheckType.NET_FLYINGFREQUENCY, player) && flyingFrequency.check(player, packetData, time, data, cc, pData)) {
cancel = true;
}
// Process cancel and debug log.
if (cancel) {
event.setCancelled(true);
}
if (pData.isDebugActive(this.checkType)) {
debug(player, (packetData == null ? "(Incompatible data)" : packetData.toString()) + (event.isCancelled() ? " CANCEL" : ""));
}
}
use of fr.neatmonster.nocheatplus.checks.net.model.DataPacketFlying in project NoCheatPlus by NoCheatPlus.
the class MovingFlying method interpretPacket.
/**
* Interpret the packet content and do with it whatever is suitable.
* @param player
* @param event
* @param allScore
* @param time
* @param data
* @param cc
* @return Packet data if successful, or null on packet mismatch.
*/
private DataPacketFlying interpretPacket(final PacketEvent event, final long time) {
final PacketContainer packet = event.getPacket();
final List<Boolean> booleans = packet.getBooleans().getValues();
if (booleans.size() != 3) {
packetMismatch(event);
return null;
}
final boolean onGround = booleans.get(MovingFlying.indexOnGround).booleanValue();
final boolean hasPos = booleans.get(MovingFlying.indexhasPos).booleanValue();
final boolean hasLook = booleans.get(MovingFlying.indexhasLook).booleanValue();
if (!hasPos && !hasLook) {
return new DataPacketFlying(onGround, time);
}
final List<Double> doubles;
final List<Float> floats;
if (hasPos) {
doubles = packet.getDoubles().getValues();
if (doubles.size() != 3 && doubles.size() != 4) {
// 3: 1.8, 4: 1.7.10 and before (stance).
packetMismatch(event);
return null;
}
// TODO: before 1.8: stance (should make possible to reject in isInvalidContent).
} else {
doubles = null;
}
if (hasLook) {
floats = packet.getFloat().getValues();
if (floats.size() != 2) {
packetMismatch(event);
return null;
}
} else {
floats = null;
}
if (hasPos && hasLook) {
return new DataPacketFlying(onGround, doubles.get(indexX), doubles.get(indexY), doubles.get(indexZ), floats.get(indexYaw), floats.get(indexPitch), time);
} else if (hasLook) {
return new DataPacketFlying(onGround, floats.get(indexYaw), floats.get(indexPitch), time);
} else if (hasPos) {
return new DataPacketFlying(onGround, doubles.get(indexX), doubles.get(indexY), doubles.get(indexZ), time);
} else {
throw new IllegalStateException("Can't be, it can't be!");
}
}
Aggregations