/*
* XNap
*
* A pure java file sharing client.
*
* See AUTHORS for copyright information.
*
* 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 the License, or
* (at your option) any later version.
*
* 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. See the
* GNU General Public License for more details.
*
* 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 02111-1307 USA
*
*/
package xnap.plugin.nap;
import xnap.XNap;
import xnap.cmdl.*;
import xnap.net.*;
import xnap.plugin.*;
import xnap.plugin.nap.net.*;
import xnap.plugin.nap.net.msg.ExceptionListener;
import xnap.plugin.nap.net.msg.MessageHandler;
import xnap.plugin.nap.net.msg.MessageSender;
import xnap.plugin.nap.net.msg.client.ClientStatisticsMessage;
import xnap.plugin.nap.net.msg.client.ServerStatisticsMessage;
import xnap.plugin.nap.net.msg.client.WhoisRequestMessage;
import xnap.plugin.nap.util.*;
import xnap.util.*;
import java.io.IOException;
import java.util.*;
public class Plugin extends AbstractPlugin
implements INetworkPlugin, CommandLineSupport
{
//--- Constant(s) ---
public static final String VERSION = XNap.VERSION;
//--- Data Field(s) ---
private static Plugin singleton;
protected Console console = Console.getInstance();
protected Preferences prefs = Preferences.getInstance();
protected NapPreferences napPrefs = NapPreferences.getInstance();
private int index = 0;
private AbstractCommand[] commands = {
new ConnectCmd(), new StatsCmd(), new ServerListCmd(), new WhoisCmd(),
new ConnectorCmd(), new ClientStatisticsCmd(), new PluginStatsCmd()
};
//--- Constructor(s) ---
public Plugin()
{
singleton = this;
}
//--- Method(s) ---
public String getDescription()
{
return Plugin.tr("Support for the OpenNap protocol.");
}
public String getName()
{
return "OpenNap";
}
public String getVersion()
{
return VERSION;
}
public AbstractCommand[] getCommands()
{
return commands;
}
public static Plugin getInstance()
{
return singleton;
}
public int getStatus()
{
if (Connector.getInstance().getConnectedCount() > 0) {
return STATUS_GREEN;
}
else {
return STATUS_RED;
}
}
public String getStatusMessage()
{
return Connector.getInstance().getConnectedCount() + " " + XNap.tr("Servers");
}
public ISearch[] search(SearchFilter filter, int priority)
{
Debug.log("nap: search");
LinkedList searches = new LinkedList();
HashSet set = new HashSet();
int serverCount = 0;
Object[] servers
= Connector.getInstance().getConnectedServers().toArray();
if (servers.length == 0) {
return null;
}
if (index >= servers.length) {
index = 0;
}
int start = index;
while (serverCount < napPrefs.getMaxSearchServers()
|| napPrefs.getMaxSearchServers() <= 0) {
Server s = (Server)servers[index];
if (s.getNetwork().equals("") || set.add(s.getNetwork())) {
Search search = new Search
(filter, priority,
napPrefs.getMaxSearchResultsPerServer(), s);
searches.add(search);
serverCount++;
}
index++;
if (index == servers.length) {
index = 0;
}
if (index == start) {
break;
}
}
ISearch[] array = new ISearch[searches.size()];
System.arraycopy(searches.toArray(), 0, array, 0, array.length);
return array;
}
public void start()
{
Debug.log("nap: start");
MessageSender.getInstance().start();
Connector.getInstance().init();
Connector.getInstance().setEnabled(napPrefs.getUseAutoconnector());
Executer.installHandler(this);
super.start();
}
public void stop()
{
super.stop();
Debug.log("nap: stop");
Executer.removeHandler(this);
Connector.getInstance().die();
MessageSender.getInstance().stop();
}
public static final String tr(String text)
{
return XNap.tr(text);
}
public static final String tr(String text, int padding)
{
return XNap.tr(text, padding);
}
public static final String tr(String text, int lpadding, int rpadding)
{
return XNap.tr(text, lpadding, rpadding);
}
protected class ConnectCmd extends AbstractCommand
{
public ConnectCmd()
{
putValue(CMD, new String[] {"opennapconnect"});
putValue(PARAMETER, "server:port [network]");
putValue(SHORT_HELP, "Connect to OpenNap server.");
}
public boolean execute(String[] argv)
{
boolean success = true;
if (argv.length == 2) {
success
= Connector.getInstance().addServer(argv[1], "", true);
}
else if (argv.length == 3) {
success = Connector.getInstance().addServer(argv[1], argv[2],
true);
}
else {
return false;
}
if (!success) {
console.println("Could not add server.");
}
return true;
}
}
protected class StatsCmd extends AbstractCommand
{
public StatsCmd()
{
putValue(CMD, new String[] {"opennapstats"});
putValue(SHORT_HELP, "Show OpenNap statistics.");
}
public boolean execute(String[] argv)
{
console.println(Connector.getInstance().getStats());
return true;
}
}
protected class ServerListCmd extends AbstractCommand
{
public ServerListCmd()
{
putValue(CMD, new String[] {"opennapserverlist"});
putValue(SHORT_HELP, "Show list of OpenNap servers.");
}
public boolean execute(String[] argv)
{
Server[] servers = Connector.getInstance().getServers();
if (servers.length == 0) {
console.println("(list is empty)");
}
else {
String[] table = new String[servers.length];
for (int i = 0; i < servers.length; i++) {
StringBuffer sb = new StringBuffer();
sb.append(i + 1);
sb.append("|" + servers[i].getHost() + ":"
+ servers[i].getPort());
sb.append("|" + servers[i].getStatusText());
if (servers[i].isConnected()) {
sb.append("|" + servers[i].getVersion());
sb.append("|" + servers[i].getUserCount() + " users");
sb.append("|" + servers[i].getFileCount() + " files");
int s = servers[i].getFileSize();
sb.append("|" + Formatter.formatSize(s) + " shared");
}
table[i] = sb.toString();
}
int L = Formatter.LEFT;
int R = Formatter.RIGHT;
int[] cols = new int[] { R, L, L, L, R, R, R };
console.println(Formatter.formatTable(table, cols));
}
return true;
}
}
protected class WhoisCmd extends AbstractCommand implements ExceptionListener
{
public WhoisCmd()
{
putValue(CMD, new String[] {"opennapwhois", "who"});
putValue(PARAMETER, "(server user|user@server)");
putValue(SHORT_HELP, "Do a whois query.");
}
public void exceptionThrown(Exception e)
{
console.println(e.getMessage());
}
public boolean execute(String[] argv)
throws SyntaxException, ParameterException
{
String nick;
String host = null;
boolean sendToAll = false;
if (argv.length == 2) {
StringTokenizer t = new StringTokenizer(argv[1], "@");
nick = t.nextToken();
if (t.countTokens() == 1) {
host = t.nextToken();
}
else {
sendToAll = true;
}
}
else if (argv.length == 3) {
host = argv[1];
nick = argv[2];
}
else {
throw new SyntaxException();
}
WhoisRequestMessage m = new WhoisRequestMessage(nick);
m.setExceptionListener(this);
if (sendToAll) {
MessageHandler.send(m);
}
else {
Server s = Connector.getInstance().getServer(host);
if (s == null) {
throw new ParameterException("server not found");
}
MessageHandler.send(s, m);
}
return true;
}
}
protected class ConnectorCmd extends AbstractCommand
{
public ConnectorCmd()
{
putValue(CMD, new String[] {"opennapconnector"});
putValue(SHORT_HELP, "Toggle auto connector.");
}
public boolean execute(String[] argv)
{
Connector c = Connector.getInstance();
c.setEnabled(!c.isEnabled());
console.println("OpenNap auto connector is " +
((c.isEnabled()) ? "enabled" : "disabled")
+ ".");
return true;
}
}
protected class ClientStatisticsCmd extends AbstractCommand
{
public ClientStatisticsCmd()
{
putValue(CMD, new String[] {"opennapclientstatistics"});
putValue(SHORT_HELP, "Query Opennap server for client statistics.");
}
public boolean execute(String[] argv)
{
MessageHandler.send(new ClientStatisticsMessage());
return true;
}
}
protected class PluginStatsCmd extends AbstractCommand
{
public PluginStatsCmd()
{
putValue(CMD, new String[] {"opennappluginstatus"});
putValue(SHORT_HELP, "Show plugin status.");
}
public boolean execute(String[] argv)
{
StringBuffer sb = new StringBuffer();
sb.append("Connected servers: ");
sb.append(Connector.getInstance().getConnectedServers().size());
sb.append("\n");
// sb.append("Send queue size : ");
// sb.append(queueStats.sendQueueSize);
// sb.append("\n");
// sb.append("Send worker count: ");
// sb.append(queueStats.sendWorkerCount);
// sb.append("\n");
// sb.append("Busy send workers: ");
// sb.append(queueStats.busySendWorkerCount);
console.println(sb.toString());
return true;
}
}
}