mirror of
https://github.com/NoCheatPlus/NoCheatPlus.git
synced 2024-11-02 00:29:59 +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.EntityPlayer;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.server.NetServerHandler;
|
||||
import net.minecraft.server.NetworkManager;
|
||||
import net.minecraft.server.ServerConnection;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -103,8 +104,10 @@ public class NoCheatPlus extends JavaPlugin implements Listener {
|
||||
getCommand("nocheatplus").setExecutor(new CommandHandler(this));
|
||||
|
||||
// Set the NetServerHandler of every player.
|
||||
for (final Player player : Bukkit.getOnlinePlayers())
|
||||
setCustomNetServerHandler(player);
|
||||
for (final Player player : Bukkit.getOnlinePlayers()) {
|
||||
resetNetServerHandler(player);
|
||||
updateNetServerHandler(player);
|
||||
}
|
||||
|
||||
// Tell the server administrator that we finished loading NoCheatPlus now.
|
||||
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.
|
||||
*
|
||||
* @param event
|
||||
* the event
|
||||
*/
|
||||
@EventHandler(
|
||||
priority = EventPriority.LOWEST)
|
||||
public void onPlayerJoinLowest(final PlayerJoinEvent event) {
|
||||
// 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 NetServerHandler oldNSH = entityPlayer.netServerHandler;
|
||||
if (oldNSH instanceof CustomNetServerHandler)
|
||||
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);
|
||||
newNSH.a(player.getLocation().getX(), player.getLocation().getY(), player.getLocation().getZ(), player
|
||||
.getLocation().getYaw(), player.getLocation().getPitch());
|
||||
entityPlayer.netServerHandler = newNSH;
|
||||
try {
|
||||
final Field field = NetworkManager.class.getDeclaredField("packetListener");
|
||||
field.setAccessible(true);
|
||||
field.set(oldNSH.networkManager, newNSH);
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
setNetServerHandler(server, oldNSH, newNSH);
|
||||
oldNSH.disconnected = true;
|
||||
server.ac().a(newNSH);
|
||||
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
|
||||
* 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
|
||||
*/
|
||||
|
@ -167,7 +167,6 @@ public class NoPwnage extends Check {
|
||||
|
||||
boolean cancel = false;
|
||||
|
||||
|
||||
String message = "";
|
||||
if (event instanceof AsyncPlayerChatEvent)
|
||||
message = ((AsyncPlayerChatEvent) event).getMessage();
|
||||
@ -175,9 +174,9 @@ public class NoPwnage extends Check {
|
||||
message = ((PlayerCommandPreprocessEvent) event).getMessage();
|
||||
final boolean isCommand = event instanceof PlayerCommandPreprocessEvent;
|
||||
final long now = System.currentTimeMillis();
|
||||
|
||||
if (!data.noPwnageHasFilledCaptcha) {
|
||||
if (cc.noPwnageCaptchaCheck && data.noPwnageHasStartedCaptcha) {
|
||||
|
||||
if (!data.noPwnageHasFilledCaptcha)
|
||||
if (cc.noPwnageCaptchaCheck && data.noPwnageHasStartedCaptcha) {
|
||||
// Correct answer to the captcha?
|
||||
if (message.equals(data.noPwnageGeneratedCaptcha)) {
|
||||
// Yes, clear his data and do not worry anymore about him.
|
||||
@ -206,7 +205,6 @@ public class NoPwnage extends Check {
|
||||
((PlayerCommandPreprocessEvent) event).setCancelled(true);
|
||||
return cancel;
|
||||
}
|
||||
}
|
||||
|
||||
if (data.noPwnageLastLocation == null)
|
||||
data.noPwnageLastLocation = player.getLocation();
|
||||
@ -295,7 +293,6 @@ public class NoPwnage extends Check {
|
||||
data.noPwnageLastMessageTime = now;
|
||||
lastGlobalMessage = message;
|
||||
lastGlobalMessageTime = now;
|
||||
|
||||
|
||||
return cancel;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ public class InstantEat extends Check {
|
||||
if (data.instantEatFood == null || level <= player.getFoodLevel())
|
||||
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;
|
||||
|
||||
if (expectedTimeWhenEatingFinished < System.currentTimeMillis())
|
||||
|
@ -6,8 +6,6 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.GameMode;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.EntityType;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.entity.Vehicle;
|
||||
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.
|
||||
*
|
||||
@ -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,
|
||||
* because it is definitely invalid now.
|
||||
* Just for security, if a player switches between worlds, reset the fly and more packets checks data, because it is
|
||||
* definitely invalid now.
|
||||
*
|
||||
* @param event
|
||||
* the event
|
||||
@ -519,16 +542,4 @@ public class MovingListener implements Listener {
|
||||
}
|
||||
}.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;
|
||||
}
|
||||
}
|
||||
|
@ -50,12 +50,11 @@ public class NoFall extends Check {
|
||||
public void check(final Player player, final PlayerLocation from, final PlayerLocation to) {
|
||||
final MovingConfig cc = MovingConfig.getConfig(player);
|
||||
final MovingData data = MovingData.getData(player);
|
||||
|
||||
|
||||
// If the player has just started falling, is falling into a liquid, in web or is on a ladder.
|
||||
if (to.isInLiquid() || to.isInWeb() || to.isOnLadder())
|
||||
// Reset his fall distance.
|
||||
data.noFallFallDistance = data.noFallNewFallDistance = 0D;
|
||||
|
||||
|
||||
// If the player just touched the ground for the server, but no for the client.
|
||||
if (!data.noFallWasOnGroundServer && data.noFallOnGroundServer
|
||||
|
Loading…
Reference in New Issue
Block a user