mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-11-02 08:40:01 +01:00
Fixed server sometimes ignoring players due to our custom
NetServerHandler.
This commit is contained in:
parent
f515f57231
commit
96a7f493f8
@ -6,11 +6,12 @@ import java.util.List;
|
|||||||
|
|
||||||
import net.minecraft.server.DedicatedServer;
|
import net.minecraft.server.DedicatedServer;
|
||||||
import net.minecraft.server.EntityPlayer;
|
import net.minecraft.server.EntityPlayer;
|
||||||
|
import net.minecraft.server.MinecraftServer;
|
||||||
import net.minecraft.server.NetServerHandler;
|
import net.minecraft.server.NetServerHandler;
|
||||||
import net.minecraft.server.NetworkManager;
|
import net.minecraft.server.NetworkManager;
|
||||||
|
import net.minecraft.server.ServerConnection;
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.craftbukkit.CraftServer;
|
|
||||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
@ -103,8 +104,10 @@ public class NoCheatPlus extends JavaPlugin implements Listener {
|
|||||||
getCommand("nocheatplus").setExecutor(new CommandHandler(this));
|
getCommand("nocheatplus").setExecutor(new CommandHandler(this));
|
||||||
|
|
||||||
// Set the NetServerHandler of every player.
|
// Set the NetServerHandler of every player.
|
||||||
for (final Player player : Bukkit.getOnlinePlayers())
|
for (final Player player : Bukkit.getOnlinePlayers()) {
|
||||||
setCustomNetServerHandler(player);
|
resetNetServerHandler(player);
|
||||||
|
updateNetServerHandler(player);
|
||||||
|
}
|
||||||
|
|
||||||
// Tell the server administrator that we finished loading NoCheatPlus now.
|
// Tell the server administrator that we finished loading NoCheatPlus now.
|
||||||
System.out.println("[NoCheatPlus] Version " + getDescription().getVersion() + " is enabled.");
|
System.out.println("[NoCheatPlus] Version " + getDescription().getVersion() + " is enabled.");
|
||||||
@ -216,33 +219,87 @@ public class NoCheatPlus extends JavaPlugin implements Listener {
|
|||||||
* Setting the net server handler at the earliest possible point.
|
* Setting the net server handler at the earliest possible point.
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event
|
||||||
|
* the event
|
||||||
*/
|
*/
|
||||||
@EventHandler(
|
@EventHandler(
|
||||||
priority = EventPriority.LOWEST)
|
priority = EventPriority.LOWEST)
|
||||||
public void onPlayerJoinLowest(final PlayerJoinEvent event) {
|
public void onPlayerJoinLowest(final PlayerJoinEvent event) {
|
||||||
// Set the NetServerHandler of the player.
|
// Set the NetServerHandler of the player.
|
||||||
setCustomNetServerHandler(event.getPlayer());
|
resetNetServerHandler(event.getPlayer());
|
||||||
|
updateNetServerHandler(event.getPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean setCustomNetServerHandler(final Player player) {
|
/**
|
||||||
|
* Reset the net server handler of the player.
|
||||||
|
*
|
||||||
|
* @param player
|
||||||
|
* the player
|
||||||
|
* @return true, if needed
|
||||||
|
*/
|
||||||
|
private boolean resetNetServerHandler(final Player player) {
|
||||||
|
final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
||||||
|
final NetServerHandler oldNSH = entityPlayer.netServerHandler;
|
||||||
|
if (!(oldNSH instanceof CustomNetServerHandler))
|
||||||
|
return false;
|
||||||
|
final DedicatedServer server = (DedicatedServer) MinecraftServer.getServer();
|
||||||
|
final NetServerHandler newNSH = new NetServerHandler(server, oldNSH.networkManager, entityPlayer);
|
||||||
|
newNSH.a(player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), player
|
||||||
|
.getLocation().getYaw(), player.getLocation().getPitch());
|
||||||
|
entityPlayer.netServerHandler = newNSH;
|
||||||
|
setNetServerHandler(server, oldNSH, newNSH);
|
||||||
|
oldNSH.disconnected = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the net server handler.
|
||||||
|
*
|
||||||
|
* @param server
|
||||||
|
* the server
|
||||||
|
* @param oldNSH
|
||||||
|
* the old net server handler
|
||||||
|
* @param newNSH
|
||||||
|
* the new net server handler
|
||||||
|
* @return true, if successful
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||||
|
private boolean setNetServerHandler(final DedicatedServer server, final NetServerHandler oldNSH,
|
||||||
|
final NetServerHandler newNSH) {
|
||||||
|
try {
|
||||||
|
Field field = NetworkManager.class.getDeclaredField("packetListener");
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(oldNSH.networkManager, newNSH);
|
||||||
|
field = ServerConnection.class.getDeclaredField("d");
|
||||||
|
field.setAccessible(true);
|
||||||
|
final List handlerList = (List) field.get(server.ac());
|
||||||
|
handlerList.remove(oldNSH);
|
||||||
|
handlerList.add(newNSH);
|
||||||
|
return true;
|
||||||
|
} catch (final Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the net server handler of the player.
|
||||||
|
*
|
||||||
|
* @param player
|
||||||
|
* the player
|
||||||
|
* @return true, if needed
|
||||||
|
*/
|
||||||
|
private boolean updateNetServerHandler(final Player player) {
|
||||||
final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
final EntityPlayer entityPlayer = ((CraftPlayer) player).getHandle();
|
||||||
final NetServerHandler oldNSH = entityPlayer.netServerHandler;
|
final NetServerHandler oldNSH = entityPlayer.netServerHandler;
|
||||||
if (oldNSH instanceof CustomNetServerHandler)
|
if (oldNSH instanceof CustomNetServerHandler)
|
||||||
return false;
|
return false;
|
||||||
final DedicatedServer server = ((CraftServer) Bukkit.getServer()).getHandle().getServer();
|
final DedicatedServer server = (DedicatedServer) MinecraftServer.getServer();
|
||||||
final NetServerHandler newNSH = new CustomNetServerHandler(server, oldNSH.networkManager, entityPlayer);
|
final NetServerHandler newNSH = new CustomNetServerHandler(server, oldNSH.networkManager, entityPlayer);
|
||||||
newNSH.a(player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), player
|
newNSH.a(player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), player
|
||||||
.getLocation().getYaw(), player.getLocation().getPitch());
|
.getLocation().getYaw(), player.getLocation().getPitch());
|
||||||
entityPlayer.netServerHandler = newNSH;
|
entityPlayer.netServerHandler = newNSH;
|
||||||
try {
|
setNetServerHandler(server, oldNSH, newNSH);
|
||||||
final Field field = NetworkManager.class.getDeclaredField("packetListener");
|
|
||||||
field.setAccessible(true);
|
|
||||||
field.set(oldNSH.networkManager, newNSH);
|
|
||||||
} catch (final Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
oldNSH.disconnected = true;
|
oldNSH.disconnected = true;
|
||||||
server.ac().a(newNSH);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ public abstract class ActionWithParameters extends Action {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a string with all the wildcards replaced with data from LogData.
|
* Get a string with all the wildcards replaced with data from the violation data.
|
||||||
*
|
*
|
||||||
* @param check
|
* @param check
|
||||||
* the check
|
* the check
|
||||||
|
@ -57,7 +57,7 @@ public class CommandAction extends ActionWithParameters {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the commands into a string that can be used in the configuration files.
|
* Convert the commands data into a string that can be used in the configuration files.
|
||||||
*
|
*
|
||||||
* @return the string
|
* @return the string
|
||||||
*/
|
*/
|
||||||
|
@ -167,7 +167,6 @@ public class NoPwnage extends Check {
|
|||||||
|
|
||||||
boolean cancel = false;
|
boolean cancel = false;
|
||||||
|
|
||||||
|
|
||||||
String message = "";
|
String message = "";
|
||||||
if (event instanceof AsyncPlayerChatEvent)
|
if (event instanceof AsyncPlayerChatEvent)
|
||||||
message = ((AsyncPlayerChatEvent) event).getMessage();
|
message = ((AsyncPlayerChatEvent) event).getMessage();
|
||||||
@ -176,8 +175,8 @@ public class NoPwnage extends Check {
|
|||||||
final boolean isCommand = event instanceof PlayerCommandPreprocessEvent;
|
final boolean isCommand = event instanceof PlayerCommandPreprocessEvent;
|
||||||
final long now = System.currentTimeMillis();
|
final long now = System.currentTimeMillis();
|
||||||
|
|
||||||
if (!data.noPwnageHasFilledCaptcha) {
|
if (!data.noPwnageHasFilledCaptcha)
|
||||||
if (cc.noPwnageCaptchaCheck && data.noPwnageHasStartedCaptcha) {
|
if (cc.noPwnageCaptchaCheck && data.noPwnageHasStartedCaptcha) {
|
||||||
// Correct answer to the captcha?
|
// Correct answer to the captcha?
|
||||||
if (message.equals(data.noPwnageGeneratedCaptcha)) {
|
if (message.equals(data.noPwnageGeneratedCaptcha)) {
|
||||||
// Yes, clear his data and do not worry anymore about him.
|
// Yes, clear his data and do not worry anymore about him.
|
||||||
@ -206,7 +205,6 @@ public class NoPwnage extends Check {
|
|||||||
((PlayerCommandPreprocessEvent) event).setCancelled(true);
|
((PlayerCommandPreprocessEvent) event).setCancelled(true);
|
||||||
return cancel;
|
return cancel;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (data.noPwnageLastLocation == null)
|
if (data.noPwnageLastLocation == null)
|
||||||
data.noPwnageLastLocation = player.getLocation();
|
data.noPwnageLastLocation = player.getLocation();
|
||||||
@ -296,7 +294,6 @@ public class NoPwnage extends Check {
|
|||||||
lastGlobalMessage = message;
|
lastGlobalMessage = message;
|
||||||
lastGlobalMessageTime = now;
|
lastGlobalMessageTime = now;
|
||||||
|
|
||||||
|
|
||||||
return cancel;
|
return cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ public class InstantEat extends Check {
|
|||||||
if (data.instantEatFood == null || level <= player.getFoodLevel())
|
if (data.instantEatFood == null || level <= player.getFoodLevel())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// rough estimation about how long it should take to eat
|
// Rough estimation about how long it should take to eat
|
||||||
final long expectedTimeWhenEatingFinished = data.instantEatLastTime + 700L;
|
final long expectedTimeWhenEatingFinished = data.instantEatLastTime + 700L;
|
||||||
|
|
||||||
if (expectedTimeWhenEatingFinished < System.currentTimeMillis())
|
if (expectedTimeWhenEatingFinished < System.currentTimeMillis())
|
||||||
|
@ -6,8 +6,6 @@ import org.bukkit.Bukkit;
|
|||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.bukkit.entity.EntityType;
|
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.bukkit.entity.Vehicle;
|
import org.bukkit.entity.Vehicle;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
@ -137,6 +135,31 @@ public class MovingListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We listen to EntityDamage events the reset the fall distance when a damage is dealt.
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
* the event
|
||||||
|
*/
|
||||||
|
@EventHandler(
|
||||||
|
priority = EventPriority.MONITOR, ignoreCancelled = false)
|
||||||
|
public void onEntityDamage(final EntityDamageEvent event) {
|
||||||
|
/*
|
||||||
|
* _____ _ _ _ ____
|
||||||
|
* | ____|_ __ | |_(_) |_ _ _ | _ \ __ _ _ __ ___ __ _ __ _ ___
|
||||||
|
* | _| | '_ \| __| | __| | | | | | | |/ _` | '_ ` _ \ / _` |/ _` |/ _ \
|
||||||
|
* | |___| | | | |_| | |_| |_| | | |_| | (_| | | | | | | (_| | (_| | __/
|
||||||
|
* |_____|_| |_|\__|_|\__|\__, | |____/ \__,_|_| |_| |_|\__,_|\__, |\___|
|
||||||
|
* |___/ |___/
|
||||||
|
*/
|
||||||
|
// Workaround fix attempt for NoFall multiple damage.
|
||||||
|
if (event.getCause() == DamageCause.FALL && event.getEntity() instanceof Player) {
|
||||||
|
final MovingData data = MovingData.getData((Player) event.getEntity());
|
||||||
|
// Simple model: once damage dealt the fall distance is reset.
|
||||||
|
data.noFallFallDistance = data.noFallNewFallDistance = 0D;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We listen to this event to prevent player from flying by sending bed leaving packets.
|
* We listen to this event to prevent player from flying by sending bed leaving packets.
|
||||||
*
|
*
|
||||||
@ -181,8 +204,8 @@ public class MovingListener implements Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Just for security, if a player switches between worlds, reset the fly and more packets checks data,
|
* Just for security, if a player switches between worlds, reset the fly and more packets checks data, because it is
|
||||||
* because it is definitely invalid now.
|
* definitely invalid now.
|
||||||
*
|
*
|
||||||
* @param event
|
* @param event
|
||||||
* the event
|
* the event
|
||||||
@ -519,16 +542,4 @@ public class MovingListener implements Listener {
|
|||||||
}
|
}
|
||||||
}.set(event.getVehicle(), newTo), 1L);
|
}.set(event.getVehicle(), newTo), 1L);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority=EventPriority.MONITOR, ignoreCancelled=false)
|
|
||||||
public void onEntityDamage(final EntityDamageEvent event){
|
|
||||||
// Workaround fix attempt for NoFall multiple damage.
|
|
||||||
if (event.getCause() != DamageCause.FALL) return;
|
|
||||||
final Entity entity = event.getEntity();
|
|
||||||
if (entity.getType() != EntityType.PLAYER) return;
|
|
||||||
final Player player = (Player) entity;
|
|
||||||
final MovingData data = MovingData.getData(player);
|
|
||||||
// Simple model: Once damage dealt the fall distance is reset.
|
|
||||||
data.noFallFallDistance = data.noFallNewFallDistance = 0.0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,6 @@ public class NoFall extends Check {
|
|||||||
// Reset his fall distance.
|
// Reset his fall distance.
|
||||||
data.noFallFallDistance = data.noFallNewFallDistance = 0D;
|
data.noFallFallDistance = data.noFallNewFallDistance = 0D;
|
||||||
|
|
||||||
|
|
||||||
// If the player just touched the ground for the server, but no for the client.
|
// If the player just touched the ground for the server, but no for the client.
|
||||||
if (!data.noFallWasOnGroundServer && data.noFallOnGroundServer
|
if (!data.noFallWasOnGroundServer && data.noFallOnGroundServer
|
||||||
&& (data.noFallWasOnGroundClient || !data.noFallOnGroundClient)) {
|
&& (data.noFallWasOnGroundClient || !data.noFallOnGroundClient)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user