ProjectAres/Commons/bukkit/src/main/java/tc/oc/commons/bukkit/commands/TraceCommands.java

140 lines
4.8 KiB
Java

package tc.oc.commons.bukkit.commands;
import static tc.oc.commons.bukkit.commands.CommandUtils.getCommandSenderOrSelf;
import com.sk89q.minecraft.util.commands.Command;
import com.sk89q.minecraft.util.commands.CommandContext;
import com.sk89q.minecraft.util.commands.CommandException;
import com.sk89q.minecraft.util.commands.CommandPermissions;
import com.sk89q.minecraft.util.commands.NestedCommand;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.inject.Inject;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.craftbukkit.event.AsyncClientConnectEvent;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import tc.oc.api.bukkit.users.OnlinePlayers;
import tc.oc.api.util.Permissions;
import tc.oc.commons.bukkit.util.PacketTracer;
import tc.oc.commons.core.commands.Commands;
import tc.oc.commons.core.commands.NestedCommands;
/**
* Packet tracing commands
*/
public class TraceCommands implements NestedCommands, Listener {
private final OnlinePlayers onlinePlayers;
private final AtomicBoolean traceAll = new AtomicBoolean(false);
@Inject TraceCommands(OnlinePlayers onlinePlayers) {
this.onlinePlayers = onlinePlayers;
}
@EventHandler
void onLogin(AsyncClientConnectEvent event) {
if(traceAll.get()) {
PacketTracer.start(event.channel(), event.channel().remoteAddress().toString(), Bukkit.getLogger());
}
}
public static class Parent implements Commands {
@Command(
aliases = "trace",
desc = "Packet dumping commands",
min = 1,
max = -1
)
@CommandPermissions(Permissions.DEVELOPER)
@NestedCommand(TraceCommands.class)
public void trace(CommandContext args, CommandSender sender) throws CommandException {}
}
@Command(
aliases = {"on", "start"},
desc = "Start logging packets",
min = 0,
max = 1
)
public void start(CommandContext args, CommandSender sender) throws CommandException {
if(sender instanceof Player || args.argsLength() >= 1) {
final Player player = (Player) getCommandSenderOrSelf(args, sender, 0);
if(PacketTracer.start(player, Bukkit.getLogger())) {
sender.sendMessage("Started packet trace for " + player.getName(sender));
}
} else if(traceAll.compareAndSet(false, true)) {
onlinePlayers.all().forEach(player -> PacketTracer.start(player, Bukkit.getLogger()));
sender.sendMessage("Started global packet trace");
}
}
@Command(
aliases = {"off", "stop"},
desc = "Stop logging packets",
min = 0,
max = 1
)
public void stop(CommandContext args, CommandSender sender) throws CommandException {
if(sender instanceof Player || args.argsLength() >= 1) {
final Player player = (Player) getCommandSenderOrSelf(args, sender, 0);
if(PacketTracer.stop(player)) {
sender.sendMessage("Stopped packet trace for " + player.getName(sender));
}
} else {
traceAll.set(false);
if(onlinePlayers.all().stream().anyMatch(PacketTracer::stop)) {
sender.sendMessage("Stopped all packet tracing");
}
}
}
@Command(
aliases = {"clear", "cl"},
desc = "Clear all filters",
min = 0,
max = -1
)
public void clear(CommandContext args, CommandSender sender) throws CommandException {
PacketTracer.clearFilter();
sender.sendMessage("Trace filters cleared");
}
@Command(
aliases = {"include", "inc"},
desc = "Include packets in the trace",
min = 0,
max = -1
)
public void include(CommandContext args, CommandSender sender) throws CommandException {
filter(args, sender, true);
}
@Command(
aliases = {"exclude", "ex"},
desc = "Exclude packets from the trace",
min = 0,
max = -1
)
public void exclude(CommandContext args, CommandSender sender) throws CommandException {
filter(args, sender, false);
}
private static void filter(CommandContext args, CommandSender sender, boolean include) throws CommandException {
if(PacketTracer.getDefaultInclude() == include) {
PacketTracer.clearFilter();
PacketTracer.setDefaultInclude(!include);
}
for(String name : args.getSlice(1)) {
Class<?> type = PacketTracer.findPacketType(name);
if(type == null) {
throw new CommandException("No packet named '" + name + "'");
}
PacketTracer.filter(type, include);
sender.sendMessage((include ? "Including" : "Excluding") + " packet " + type.getSimpleName());
}
}
}