2015-11-14 20:31:45 +01:00
|
|
|
/**
|
2013-09-05 04:03:01 +02:00
|
|
|
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
|
|
|
* Copyright (C) 2012 Kristian S. Stangeland
|
|
|
|
*
|
2014-11-24 17:41:04 +01:00
|
|
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
|
|
|
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
2013-09-05 04:03:01 +02:00
|
|
|
* the License, or (at your option) any later version.
|
|
|
|
*
|
2014-11-24 17:41:04 +01:00
|
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
|
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
2013-09-05 04:03:01 +02:00
|
|
|
* See the GNU General Public License for more details.
|
|
|
|
*
|
2014-11-24 17:41:04 +01:00
|
|
|
* You should have received a copy of the GNU General Public License along with this program;
|
|
|
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
2013-09-05 04:03:01 +02:00
|
|
|
* 02111-1307 USA
|
|
|
|
*/
|
|
|
|
package com.comphenix.protocol;
|
|
|
|
|
2013-09-20 22:35:59 +02:00
|
|
|
import java.io.File;
|
2015-07-13 03:07:09 +02:00
|
|
|
import java.io.FileWriter;
|
2013-09-05 04:03:01 +02:00
|
|
|
import java.io.IOException;
|
2015-07-13 03:07:09 +02:00
|
|
|
import java.io.PrintWriter;
|
|
|
|
import java.text.SimpleDateFormat;
|
|
|
|
import java.util.Date;
|
|
|
|
import java.util.Set;
|
|
|
|
import java.util.logging.Level;
|
2014-11-15 19:02:03 +01:00
|
|
|
|
2013-09-05 04:03:01 +02:00
|
|
|
import org.bukkit.ChatColor;
|
|
|
|
import org.bukkit.command.CommandSender;
|
|
|
|
import org.bukkit.plugin.Plugin;
|
2015-04-11 22:47:07 +02:00
|
|
|
import org.bukkit.plugin.PluginDescriptionFile;
|
2013-09-05 04:03:01 +02:00
|
|
|
|
2015-07-13 03:07:09 +02:00
|
|
|
import com.comphenix.protocol.error.DetailedErrorReporter;
|
2013-09-05 04:03:01 +02:00
|
|
|
import com.comphenix.protocol.error.ErrorReporter;
|
2013-12-07 00:47:13 +01:00
|
|
|
import com.comphenix.protocol.events.PacketListener;
|
2013-09-20 22:35:59 +02:00
|
|
|
import com.comphenix.protocol.timing.TimedListenerManager;
|
|
|
|
import com.comphenix.protocol.timing.TimingReportGenerator;
|
2015-11-14 20:31:45 +01:00
|
|
|
import com.comphenix.protocol.updater.Updater;
|
|
|
|
import com.comphenix.protocol.updater.Updater.UpdateType;
|
|
|
|
import com.comphenix.protocol.utility.Closer;
|
2013-09-05 04:03:01 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Handles the "protocol" administration command.
|
2014-11-24 17:41:04 +01:00
|
|
|
*
|
2013-09-05 04:03:01 +02:00
|
|
|
* @author Kristian
|
|
|
|
*/
|
|
|
|
class CommandProtocol extends CommandBase {
|
|
|
|
/**
|
|
|
|
* Name of this command.
|
|
|
|
*/
|
|
|
|
public static final String NAME = "protocol";
|
2015-11-14 20:31:45 +01:00
|
|
|
|
2013-09-05 04:03:01 +02:00
|
|
|
private Plugin plugin;
|
2015-11-14 20:31:45 +01:00
|
|
|
private Updater updater;
|
|
|
|
private ProtocolConfig config;
|
2013-09-05 04:03:01 +02:00
|
|
|
|
2015-11-14 20:31:45 +01:00
|
|
|
public CommandProtocol(ErrorReporter reporter, Plugin plugin, Updater updater, ProtocolConfig config) {
|
2013-09-05 04:03:01 +02:00
|
|
|
super(reporter, CommandBase.PERMISSION_ADMIN, NAME, 1);
|
|
|
|
this.plugin = plugin;
|
2015-11-14 20:31:45 +01:00
|
|
|
this.updater = updater;
|
|
|
|
this.config = config;
|
2013-09-05 04:03:01 +02:00
|
|
|
}
|
2015-11-14 20:31:45 +01:00
|
|
|
|
2013-09-05 04:03:01 +02:00
|
|
|
@Override
|
|
|
|
protected boolean handleCommand(CommandSender sender, String[] args) {
|
|
|
|
String subCommand = args[0];
|
2014-11-24 17:41:04 +01:00
|
|
|
|
2013-09-05 04:03:01 +02:00
|
|
|
// Only return TRUE if we executed the correct command
|
2015-11-14 20:31:45 +01:00
|
|
|
if (subCommand.equalsIgnoreCase("config") || subCommand.equalsIgnoreCase("reload")) {
|
2013-09-05 04:03:01 +02:00
|
|
|
reloadConfiguration(sender);
|
2015-11-14 20:31:45 +01:00
|
|
|
} else if (subCommand.equalsIgnoreCase("check")) {
|
|
|
|
checkVersion(sender);
|
|
|
|
} else if (subCommand.equalsIgnoreCase("update")) {
|
|
|
|
updateVersion(sender);
|
|
|
|
} else if (subCommand.equalsIgnoreCase("timings")) {
|
2013-09-20 22:35:59 +02:00
|
|
|
toggleTimings(sender, args);
|
2015-11-14 20:31:45 +01:00
|
|
|
} else if (subCommand.equalsIgnoreCase("listeners")) {
|
2015-11-24 21:35:23 +01:00
|
|
|
printListeners(sender);
|
2015-11-14 20:31:45 +01:00
|
|
|
} else if (subCommand.equalsIgnoreCase("version")) {
|
2015-04-11 22:47:07 +02:00
|
|
|
printVersion(sender);
|
2015-11-14 20:31:45 +01:00
|
|
|
} else if (subCommand.equalsIgnoreCase("dump")) {
|
2015-07-13 03:07:09 +02:00
|
|
|
dump(sender);
|
2015-11-14 20:31:45 +01:00
|
|
|
} else {
|
2013-09-05 04:03:01 +02:00
|
|
|
return false;
|
2015-11-14 20:31:45 +01:00
|
|
|
}
|
|
|
|
|
2013-09-05 04:03:01 +02:00
|
|
|
return true;
|
|
|
|
}
|
2015-11-14 20:31:45 +01:00
|
|
|
|
|
|
|
public void checkVersion(final CommandSender sender) {
|
|
|
|
performUpdate(sender, UpdateType.NO_DOWNLOAD);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void updateVersion(final CommandSender sender) {
|
|
|
|
performUpdate(sender, UpdateType.DEFAULT);
|
|
|
|
}
|
|
|
|
|
2013-12-07 00:47:13 +01:00
|
|
|
// Display every listener on the server
|
2015-11-24 21:35:23 +01:00
|
|
|
private void printListeners(final CommandSender sender) {
|
2014-03-13 23:55:33 +01:00
|
|
|
ProtocolManager manager = ProtocolLibrary.getProtocolManager();
|
2015-11-14 20:31:45 +01:00
|
|
|
|
2015-04-11 22:47:07 +02:00
|
|
|
sender.sendMessage(ChatColor.GOLD + "Packet listeners:");
|
2014-03-13 23:55:33 +01:00
|
|
|
for (PacketListener listener : manager.getPacketListeners()) {
|
2015-04-17 03:13:58 +02:00
|
|
|
sender.sendMessage(ChatColor.GOLD + " - " + listener);
|
2013-12-07 00:47:13 +01:00
|
|
|
}
|
2015-04-11 22:47:07 +02:00
|
|
|
|
2014-03-13 23:55:33 +01:00
|
|
|
// Along with every asynchronous listener
|
2015-04-11 22:47:07 +02:00
|
|
|
sender.sendMessage(ChatColor.GOLD + "Asynchronous listeners:");
|
2014-03-13 23:55:33 +01:00
|
|
|
for (PacketListener listener : manager.getAsynchronousManager().getAsyncHandlers()) {
|
2015-04-17 03:13:58 +02:00
|
|
|
sender.sendMessage(ChatColor.GOLD + " - " + listener);
|
2014-03-13 23:55:33 +01:00
|
|
|
}
|
2013-12-07 00:47:13 +01:00
|
|
|
}
|
2015-11-14 20:31:45 +01:00
|
|
|
|
|
|
|
private void performUpdate(final CommandSender sender, UpdateType type) {
|
|
|
|
if (updater.isChecking()) {
|
|
|
|
sender.sendMessage(ChatColor.RED + "Already checking for an update.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Perform on an async thread
|
|
|
|
Runnable notify = new Runnable() {
|
|
|
|
@Override
|
|
|
|
public void run() {
|
|
|
|
if (updater.shouldNotify() || config.isDebug()) {
|
|
|
|
sender.sendMessage(ChatColor.YELLOW + "[ProtocolLib] " + updater.getResult());
|
|
|
|
}
|
2014-11-24 17:41:04 +01:00
|
|
|
|
2015-11-14 20:31:45 +01:00
|
|
|
updater.removeListener(this);
|
|
|
|
updateFinished();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
updater.start(type);
|
|
|
|
updater.addListener(notify);
|
|
|
|
}
|
|
|
|
|
2013-09-20 22:35:59 +02:00
|
|
|
private void toggleTimings(CommandSender sender, String[] args) {
|
|
|
|
TimedListenerManager manager = TimedListenerManager.getInstance();
|
|
|
|
boolean state = !manager.isTiming(); // toggle
|
2015-11-14 20:31:45 +01:00
|
|
|
|
2013-09-20 22:35:59 +02:00
|
|
|
// Parse the boolean parameter
|
|
|
|
if (args.length == 2) {
|
2013-12-19 02:17:06 +01:00
|
|
|
Boolean parsed = parseBoolean(toQueue(args, 2), "start");
|
2015-11-14 20:31:45 +01:00
|
|
|
|
2013-09-20 22:35:59 +02:00
|
|
|
if (parsed != null) {
|
|
|
|
state = parsed;
|
|
|
|
} else {
|
|
|
|
sender.sendMessage(ChatColor.RED + "Specify a state: ON or OFF.");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else if (args.length > 2) {
|
|
|
|
sender.sendMessage(ChatColor.RED + "Too many parameters.");
|
|
|
|
return;
|
|
|
|
}
|
2015-11-14 20:31:45 +01:00
|
|
|
|
2013-09-20 22:35:59 +02:00
|
|
|
// Now change the state
|
|
|
|
if (state) {
|
|
|
|
if (manager.startTiming())
|
|
|
|
sender.sendMessage(ChatColor.GOLD + "Started timing packet listeners.");
|
|
|
|
else
|
|
|
|
sender.sendMessage(ChatColor.RED + "Packet timing already started.");
|
|
|
|
} else {
|
|
|
|
if (manager.stopTiming()) {
|
|
|
|
saveTimings(manager);
|
|
|
|
sender.sendMessage(ChatColor.GOLD + "Stopped and saved result in plugin folder.");
|
|
|
|
} else {
|
|
|
|
sender.sendMessage(ChatColor.RED + "Packet timing already stopped.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-11-14 20:31:45 +01:00
|
|
|
|
2013-09-20 22:35:59 +02:00
|
|
|
private void saveTimings(TimedListenerManager manager) {
|
|
|
|
try {
|
|
|
|
File destination = new File(plugin.getDataFolder(), "Timings - " + System.currentTimeMillis() + ".txt");
|
|
|
|
TimingReportGenerator generator = new TimingReportGenerator();
|
2015-11-14 20:31:45 +01:00
|
|
|
|
2013-09-20 22:35:59 +02:00
|
|
|
// Print to a text file
|
|
|
|
generator.saveTo(destination, manager);
|
|
|
|
manager.clear();
|
2015-11-14 20:31:45 +01:00
|
|
|
|
2013-09-20 22:35:59 +02:00
|
|
|
} catch (IOException e) {
|
|
|
|
reporter.reportMinimal(plugin, "saveTimings()", e);
|
|
|
|
}
|
|
|
|
}
|
2015-11-14 20:31:45 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Prevent further automatic updates until the next delay.
|
|
|
|
*/
|
|
|
|
public void updateFinished() {
|
|
|
|
long currentTime = System.currentTimeMillis() / ProtocolLibrary.MILLI_PER_SECOND;
|
|
|
|
|
|
|
|
config.setAutoLastTime(currentTime);
|
|
|
|
config.saveAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void reloadConfiguration(CommandSender sender) {
|
|
|
|
plugin.reloadConfig();
|
|
|
|
sender.sendMessage(ChatColor.YELLOW + "Reloaded configuration!");
|
|
|
|
}
|
2014-11-24 17:41:04 +01:00
|
|
|
|
2015-04-11 22:47:07 +02:00
|
|
|
private void printVersion(CommandSender sender) {
|
|
|
|
PluginDescriptionFile desc = plugin.getDescription();
|
|
|
|
|
|
|
|
sender.sendMessage(ChatColor.GREEN + desc.getName() + ChatColor.WHITE + " v" + ChatColor.GREEN + desc.getVersion());
|
2015-04-17 03:13:58 +02:00
|
|
|
sender.sendMessage(ChatColor.WHITE + "Authors: " + ChatColor.GREEN + "dmulloy2" + ChatColor.WHITE + " and " + ChatColor.GREEN + "Comphenix");
|
|
|
|
sender.sendMessage(ChatColor.WHITE + "Issues: " + ChatColor.GREEN + "https://github.com/dmulloy2/ProtocolLib/issues");
|
2015-04-11 22:47:07 +02:00
|
|
|
}
|
|
|
|
|
2015-07-13 03:07:09 +02:00
|
|
|
private static SimpleDateFormat FILE_FORMAT;
|
|
|
|
private static SimpleDateFormat TIMESTAMP_FORMAT;
|
|
|
|
|
|
|
|
private void dump(CommandSender sender) {
|
|
|
|
Closer closer = Closer.create();
|
|
|
|
|
|
|
|
if (FILE_FORMAT == null)
|
|
|
|
FILE_FORMAT = new SimpleDateFormat("yyyy-MM-dd_HH.mm.ss");
|
|
|
|
if (TIMESTAMP_FORMAT == null)
|
|
|
|
TIMESTAMP_FORMAT = new SimpleDateFormat("MM/dd/yy HH:mm:ss");
|
|
|
|
|
|
|
|
try {
|
|
|
|
Date date = new Date();
|
|
|
|
File file = new File(plugin.getDataFolder(), "dump-" + FILE_FORMAT.format(date) + ".txt");
|
|
|
|
if (file.exists()) {
|
|
|
|
file.delete();
|
|
|
|
}
|
|
|
|
|
|
|
|
file.createNewFile();
|
|
|
|
|
|
|
|
FileWriter fw = closer.register(new FileWriter(file));
|
|
|
|
PrintWriter pw = closer.register(new PrintWriter(fw));
|
|
|
|
|
|
|
|
pw.println("ProtocolLib Dump");
|
|
|
|
pw.println("Timestamp: " + TIMESTAMP_FORMAT.format(date));
|
|
|
|
pw.println();
|
|
|
|
|
|
|
|
pw.println("ProtocolLib Version: " + plugin.toString());
|
|
|
|
pw.println("Bukkit Version: " + plugin.getServer().getBukkitVersion());
|
|
|
|
pw.println("Server Version: " + plugin.getServer().getVersion());
|
2015-07-13 03:49:04 +02:00
|
|
|
pw.println("Java Version: " + System.getProperty("java.version"));
|
2015-07-13 03:07:09 +02:00
|
|
|
pw.println();
|
|
|
|
|
|
|
|
ProtocolManager manager = ProtocolLibrary.getProtocolManager();
|
|
|
|
pw.println("ProtocolLib: " + DetailedErrorReporter.getStringDescription(plugin));
|
|
|
|
pw.println("Manager: " + DetailedErrorReporter.getStringDescription(manager));
|
|
|
|
pw.println();
|
|
|
|
|
|
|
|
Set<PacketListener> listeners = manager.getPacketListeners();
|
|
|
|
if (listeners.size() > 0) {
|
|
|
|
pw.println("Listeners:");
|
|
|
|
|
|
|
|
for (PacketListener listener : listeners) {
|
|
|
|
pw.println(DetailedErrorReporter.getStringDescription(listener));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
pw.println("No listeners");
|
|
|
|
}
|
|
|
|
|
|
|
|
sender.sendMessage("Data dump written to " + file.getAbsolutePath());
|
|
|
|
} catch (IOException ex) {
|
2016-01-30 05:41:26 +01:00
|
|
|
ProtocolLibrary.log(Level.SEVERE, "Failed to create dump:", ex);
|
2015-07-13 03:07:09 +02:00
|
|
|
sender.sendMessage(ChatColor.RED + "Failed to create dump! Check console!");
|
|
|
|
} finally {
|
2015-11-14 20:31:45 +01:00
|
|
|
closer.close();
|
2015-07-13 03:07:09 +02:00
|
|
|
}
|
|
|
|
}
|
2013-09-05 04:03:01 +02:00
|
|
|
}
|