package org.jibble.pircbot;
import java.util.*;
/**
* This class is used to process DCC events from the server.
*
* @author PircBot-PPF project
* @version 1.0.0
*/
public class DccManager {
/**
* Constructs a DccManager to look after all DCC SEND and CHAT events.
*
* @param bot The PircBot whose DCC events this class will handle.
*/
DccManager(PircBot bot) {
_bot = bot;
}
/**
* Processes a DCC request.
* @param nick
* @param login
* @param hostname
* @param request
*
* @return True if the type of request was handled successfully.
*/
boolean processRequest(String nick, String login, String hostname, String request) {
StringTokenizer tokenizer = new StringTokenizer(request);
tokenizer.nextToken();
String type = tokenizer.nextToken();
String filename = tokenizer.nextToken();
if (type.equals("SEND")) {
long address = Long.parseLong(tokenizer.nextToken());
int port = Integer.parseInt(tokenizer.nextToken());
long size = -1;
try {
size = Long.parseLong(tokenizer.nextToken());
}
catch (Exception e) {
// Stick with the old value.
}
DccFileTransfer transfer = new DccFileTransfer(_bot, this, nick, login, hostname, type, filename, address, port, size);
_bot.onIncomingFileTransfer(transfer);
}
else if (type.equals("RESUME")) {
int port = Integer.parseInt(tokenizer.nextToken());
long progress = Long.parseLong(tokenizer.nextToken());
DccFileTransfer transfer = null;
synchronized (_awaitingResume) {
for (int i = 0; i < _awaitingResume.size(); i++) {
transfer = (DccFileTransfer) _awaitingResume.get(i);
if (transfer.getNick().equals(nick) && transfer.getPort() == port) {
_awaitingResume.remove(i);
break;
}
}
}
if (transfer != null) {
transfer.setProgress(progress);
_bot.sendCTCPCommand(nick, "DCC ACCEPT file.ext " + port + " " + progress);
}
}
else if (type.equals("ACCEPT")) {
int port = Integer.parseInt(tokenizer.nextToken());
DccFileTransfer transfer = null;
synchronized (_awaitingResume) {
for (int i = 0; i < _awaitingResume.size(); i++) {
transfer = _awaitingResume.remove(i);
if (transfer.getNick().equals(nick) && transfer.getPort() == port) {
_awaitingResume.remove(i);
break;
}
}
}
if (transfer != null) {
transfer.doReceive(transfer.getFile(), true);
}
}
else if (type.equals("CHAT")) {
long address = Long.parseLong(tokenizer.nextToken());
int port = Integer.parseInt(tokenizer.nextToken());
final DccChat chat = new DccChat(_bot, nick, login, hostname, address, port);
new Thread() {
public void run() {
_bot.onIncomingChatRequest(chat);
}
}.start();
}
else {
return false;
}
return true;
}
/**
* Add this DccFileTransfer to the list of those awaiting possible
* resuming.
*
* @param transfer the DccFileTransfer that may be resumed.
*/
void addAwaitingResume(DccFileTransfer transfer) {
synchronized (_awaitingResume) {
_awaitingResume.add(transfer);
}
}
/**
* Remove this transfer from the list of those awaiting resuming.
* @param transfer the transfer to remove.
*/
void removeAwaitingResume(DccFileTransfer transfer) {
_awaitingResume.remove(transfer);
}
private PircBot _bot;
private List<DccFileTransfer> _awaitingResume = new ArrayList<DccFileTransfer>();
}