Hide ServerListPingEvent exceptions thrown by CB's LegacyPingHandler (#2378)

Fixes #2327.
This commit is contained in:
md678685 2019-01-12 17:19:11 +00:00 committed by GitHub
parent 9aef2ef883
commit d24b0616f8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -10,12 +10,17 @@ import org.bukkit.event.server.ServerListPingEvent;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
public class EssentialsServerListener implements Listener { public class EssentialsServerListener implements Listener {
private static List<String> ignoredSLPECallers = Arrays.asList(
".LegacyPingHandler.channelRead(" // CB responding to pings from pre-Netty clients
);
private final transient IEssentials ess; private final transient IEssentials ess;
private boolean unsupportedLogged = false; private boolean unsupportedLogged = false;
private boolean npeWarned = false; private boolean npeWarned = false;
@ -46,22 +51,16 @@ public class EssentialsServerListener implements Listener {
if (isPaperSample) { if (isPaperSample) {
try { try {
List<String> playerNames = (List<String>) getSampleText.invoke(event, null); List<String> playerNames = (List<String>) getSampleText.invoke(event, null);
Iterator<String> iterator = playerNames.iterator(); playerNames.removeIf(player -> ess.getUser(player).isVanished());
while (iterator.hasNext()) {
String player = iterator.next();
if (ess.getUser(player).isVanished()) {
iterator.remove();
}
}
setSampleText.invoke(event, playerNames); setSampleText.invoke(event, playerNames);
} catch (IllegalAccessException | InvocationTargetException | ClassCastException e) { } catch (IllegalAccessException | InvocationTargetException | ClassCastException e) {
if (!unsupportedLogged) { if (!unsupportedLogged && shouldWarnSLPECaller(e)) {
ess.getLogger().log(Level.WARNING, "Unable to hide players from server list ping " ess.getLogger().log(Level.WARNING, "Unable to hide players from server list ping "
+ "using Paper 1.12+ method!", e); + "using Paper 1.12 method!", e);
unsupportedLogged = true; unsupportedLogged = true;
} }
} catch (NullPointerException e) { } catch (NullPointerException e) {
if (!npeWarned) { if (!npeWarned && shouldWarnSLPECaller(e)) {
npeWarned = true; npeWarned = true;
Exception ex = new Exception("A plugin has fired a ServerListPingEvent " Exception ex = new Exception("A plugin has fired a ServerListPingEvent "
+ "without implementing Paper's methods. Point the author to https://git.io/v7Xzl."); + "without implementing Paper's methods. Point the author to https://git.io/v7Xzl.");
@ -79,11 +78,38 @@ public class EssentialsServerListener implements Listener {
} }
} }
} catch (UnsupportedOperationException e) { } catch (UnsupportedOperationException e) {
if (!unsupportedLogged) { if (!unsupportedLogged && shouldWarnSLPECaller(e)) {
ess.getLogger().log(Level.WARNING, "Could not hide vanished players while handling " + event.getClass().getName(), e); ess.getLogger().log(Level.WARNING, "Could not hide vanished players while handling " + event.getClass().getName(), e);
unsupportedLogged = true; unsupportedLogged = true;
} }
} }
} }
} }
/**
* Should we warn about this SLPE caller, or should we silently ignore it?
* This checks against the ignoredSLPECallers strings, and if it matches one of those, we
* return false.
*
* @param throwable A throwable caught by a catch block
* @return Whether or not to send a warning about this particular caller
*/
private boolean shouldWarnSLPECaller(Throwable throwable) {
final int maxStackDepth = 20; // Limit the depth when searching through the stack trace
int depth = 0;
for (StackTraceElement element : throwable.getStackTrace()) {
depth++;
if (depth > maxStackDepth) {
break;
}
for (String ignoredString : ignoredSLPECallers) {
if (element.toString().contains(ignoredString)) {
return false; // We know about this error and should ignore it, so don't warn
}
}
}
return true; // We don't know for certain that we can ignore this, so warn just to be safe
}
} }