package io.github.lucaseasedup.logit.logging;
import io.github.lucaseasedup.logit.LogItCoreObject;
import io.github.lucaseasedup.logit.util.CollectionUtils;
import io.github.lucaseasedup.logit.util.PlayerUtils;
import java.util.Collection;
import java.util.HashSet;
import java.util.logging.Filter;
import java.util.logging.LogRecord;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.bukkit.Bukkit;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.Player;
public final class CommandSilencer extends LogItCoreObject
{
public CommandSilencer(Collection<PluginCommand> silencedCommands)
{
if (silencedCommands == null)
throw new IllegalArgumentException();
for (PluginCommand command : silencedCommands)
{
if (command == null)
{
throw new IllegalArgumentException();
}
}
this.silencedCommands = new HashSet<>(silencedCommands);
}
public void registerFilters()
{
Bukkit.getLogger().setFilter(new Filter()
{
@Override
public boolean isLoggable(LogRecord record)
{
if (!isFiltersRegistered())
return true;
if (!"Minecraft-Server".equals(record.getLoggerName()))
return true;
// Short-circut with fast contains() call.
if (!record.getMessage().contains(" issued server command: /"))
return true;
/* Use regular expression to check if this command should be silenced. */
Matcher matcher = getMatcherForMsg(record.getMessage());
if (matcher.find())
{
String username = matcher.group(1);
String label = matcher.group(2);
Player player = PlayerUtils.getPlayer(username);
// If the player isn't logged in and has to log in, do not
// show any commands issued -- they might have mistakenly
// typed e.g. "/logni 1234" instead of "/login 1234".
if (!getSessionManager().isSessionAlive(player)
&& getCore().isPlayerForcedToLogIn(player))
{
return false;
}
if (isCommandSilenced(label))
{
return false;
}
}
return true;
}
});
try
{
Class.forName("org.apache.logging.log4j.core.Filter");
new Log4jFilter(this).register();
}
catch (ClassNotFoundException | NoClassDefFoundError ex)
{
// If the class was not found, it means we're running an old
// version of CraftBukkit. Standard logger will be used instead.
}
filtersRegistered = true;
}
/* package */ boolean isCommandSilenced(String label)
{
if (label == null)
throw new IllegalArgumentException();
for (PluginCommand command : silencedCommands)
{
if (command.getLabel().equalsIgnoreCase(label))
return true;
if (hasAlias(command, label))
{
return true;
}
}
return false;
}
/* package */ boolean hasAlias(PluginCommand command, String label)
{
if (command == null || label == null)
throw new IllegalArgumentException();
return CollectionUtils.containsIgnoreCase(label, command.getAliases());
}
/* package */ Matcher getMatcherForMsg(String msg)
{
if (msg == null)
throw new IllegalArgumentException();
return SERVER_COMMAND_PATTERN.matcher(msg);
}
public void unregisterFilters()
{
filtersRegistered = false;
Bukkit.getLogger().setFilter(null);
}
/* package */ boolean isFiltersRegistered()
{
return filtersRegistered;
}
private static final Pattern SERVER_COMMAND_PATTERN = Pattern
.compile("(.+) issued server command: /([A-Za-z]+)");
private boolean filtersRegistered = false;
private final Collection<PluginCommand> silencedCommands;
}