+ public void dccSendReceived(final DccSendReceived dccSendReceived) {
+ final Optional<Network> network = getNetwork(dccSendReceived.connection());
+ if (!network.isPresent()) {
+ return;
+ }
+
+ Collection<Download> packDownloads = downloads.get(dccSendReceived.filename());
+ if (packDownloads.isEmpty()) {
+ /* unknown download, ignore. */
+ return;
+ }
+
+ /* check if it’s already downloading. */
+ Collection<Download> runningDownloads = FluentIterable.from(packDownloads).filter(FILTER_RUNNING).toSet();
+ if (!runningDownloads.isEmpty()) {
+ eventBus.post(new GenericMessage(String.format("Ignoring offer for %s, it’s already being downloaded.", dccSendReceived.filename())));
+ return;
+ }
+
+ /* locate the correct download. */
+ Collection<Download> requestedDownload = FluentIterable.from(packDownloads).filter(new Predicate<Download>() {
+
+ @Override
+ public boolean apply(Download download) {
+ return download.bot().network().equals(network.get()) && download.bot().name().equalsIgnoreCase(dccSendReceived.source().nick().get());
+ }
+ }).toSet();
+
+ /* we did not request this download. */
+ if (requestedDownload.isEmpty()) {
+ return;
+ }
+
+ Download download = requestedDownload.iterator().next();
+
+ /* check if the file already exists. */
+ File outputFile = new File(temporaryDirectory, dccSendReceived.filename());
+ if (outputFile.exists()) {
+ long existingFileSize = outputFile.length();
+
+ /* file already complete? */
+ if ((dccSendReceived.filesize() > -1) && (existingFileSize >= dccSendReceived.filesize())) {
+ /* file is apparently already complete. just move it. */
+ if (outputFile.renameTo(new File(finalDirectory, download.pack().name()))) {
+ eventBus.post(new GenericMessage(String.format("File %s already downloaded.", download.pack().name())));
+ } else {
+ eventBus.post(new GenericMessage(String.format("File %s already downloaded but not moved to %s.", download.pack().name(), finalDirectory)));
+ }
+
+ /* remove download. */
+ downloads.removeAll(download.pack().name());
+ return;
+ }
+
+ /* file not complete yet, DCC resume it. */
+ try {
+ download.remoteAddress(dccSendReceived.inetAddress()).filesize(dccSendReceived.filesize());
+ dccSendReceived.connection().sendDccResume(dccSendReceived.source().nick().get(), dccSendReceived.filename(), dccSendReceived.port(), existingFileSize);
+ } catch (IOException ioe1) {
+ eventBus.post(new GenericError(String.format("Could not send DCC RESUME %s to %s (%s).", dccSendReceived.filename(), dccSendReceived.source().nick().get(), ioe1.getMessage())));
+ }
+
+ return;
+ }
+
+ /* file does not exist, start the download. */
+ try {
+ OutputStream fileOutputStream = new FileOutputStream(outputFile);
+ DccReceiver dccReceiver = new DccReceiver(eventBus, dccSendReceived.inetAddress(), dccSendReceived.port(), dccSendReceived.filename(), dccSendReceived.filesize(), fileOutputStream);
+ download.filename(outputFile.getPath()).outputStream(fileOutputStream).dccReceiver(dccReceiver);
+ dccReceivers.add(dccReceiver);
+ dccReceiver.start();
+ eventBus.post(new DownloadStarted(download));
+ } catch (FileNotFoundException fnfe1) {
+ eventBus.post(new GenericError(String.format("Could not start download of %s from %s (%s).", dccSendReceived.filename(), dccSendReceived.source().nick().get(), fnfe1.getMessage())));
+ }
+ }
+
+ @Subscribe
+ public void dccAcceptReceived(final DccAcceptReceived dccAcceptReceived) {
+ final Optional<Network> network = getNetwork(dccAcceptReceived.connection());
+ if (!network.isPresent()) {
+ return;
+ }
+
+ Collection<Download> packDownloads = downloads.get(dccAcceptReceived.filename());
+ if (packDownloads.isEmpty()) {
+ /* unknown download, ignore. */
+ return;
+ }
+
+ /* check if it’s already downloading. */
+ Collection<Download> runningDownloads = FluentIterable.from(packDownloads).filter(FILTER_RUNNING).toSet();
+ if (!runningDownloads.isEmpty()) {
+ eventBus.post(new GenericMessage(String.format("Ignoring offer for %s, it’s already being downloaded.", dccAcceptReceived.filename())));
+ return;
+ }
+
+ /* locate the correct download. */
+ Collection<Download> requestedDownload = FluentIterable.from(packDownloads).filter(new Predicate<Download>() {
+
+ @Override
+ public boolean apply(Download download) {
+ return download.bot().network().equals(network.get()) && download.bot().name().equalsIgnoreCase(dccAcceptReceived.source().nick().get());
+ }
+ }).toSet();
+
+ /* we did not request this download. */
+ if (requestedDownload.isEmpty()) {
+ return;
+ }
+
+ Download download = requestedDownload.iterator().next();
+