From 998db5487db09308f4d83cd45088ede18731619e Mon Sep 17 00:00:00 2001 From: =?utf8?q?David=20=E2=80=98Bombe=E2=80=99=20Roden?= Date: Wed, 27 Oct 2021 12:06:03 +0200 Subject: [PATCH] Improve download logic in case of mismatching filenames Because sometimes, the filenames announced by the bot and the name of the file actually offered by the bot are different, e.g. when the filesystem and the DCC protocol differ on whether letters outside of 7-bit ASCII do actually exist. I still want those files! --- .../java/net/pterodactylus/xdcc/core/Core.java | 41 ++++++++++------------ 1 file changed, 18 insertions(+), 23 deletions(-) diff --git a/src/main/java/net/pterodactylus/xdcc/core/Core.java b/src/main/java/net/pterodactylus/xdcc/core/Core.java index 649db75..01460c4 100644 --- a/src/main/java/net/pterodactylus/xdcc/core/Core.java +++ b/src/main/java/net/pterodactylus/xdcc/core/Core.java @@ -18,6 +18,7 @@ package net.pterodactylus.xdcc.core; import static java.lang.String.format; +import static java.util.stream.Collectors.toSet; import static net.pterodactylus.irc.event.ChannelNotJoined.Reason.banned; import static net.pterodactylus.irc.event.ChannelNotJoined.Reason.inviteOnly; import static net.pterodactylus.irc.event.ChannelNotJoined.Reason.registeredNicknamesOnly; @@ -411,7 +412,7 @@ public class Core extends AbstractExecutionThreadService { .map(Channel::network) .distinct() .filter((network) -> !networkConnections.containsKey(network)) - .collect(Collectors.toSet()); + .collect(toSet()); if (missingNetworks.isEmpty()) { if (!missingChannels.isEmpty()) { @@ -663,7 +664,7 @@ public class Core extends AbstractExecutionThreadService { .values().stream() .filter(bot -> bot.channel() .equalsIgnoreCase(channel.get().name())) - .collect(Collectors.toSet()); + .collect(toSet()); botsToRemove.stream() .forEach(bot -> networkBots.row(network.get()) .remove(bot.name())); @@ -891,34 +892,28 @@ public class Core extends AbstractExecutionThreadService { return; } - Collection packDownloads = downloads.get(dccSendReceived.filename()); - if (packDownloads.isEmpty()) { - /* unknown download, ignore. */ - return; - } + Set openDownloads = downloads.values().stream() + .filter(download -> download.bot().name().equalsIgnoreCase(dccSendReceived.source().nick().orNull())) + .filter(download -> download.dccReceiver() == null) + .collect(toSet()); - /* check if it’s already downloading. */ - Collection 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()))); + if (openDownloads.isEmpty()) { + /* I don't think we requested this. */ + eventBus.post(new GenericMessage(format("Ignoring offer for %s, no open download from %s.", dccSendReceived.filename(), dccSendReceived.source()))); return; } - /* locate the correct download. */ - Collection requestedDownload = FluentIterable.from(packDownloads).filter(new Predicate() { - - @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()) { + /* check if it’s already downloading. */ + if (downloads.values().stream().anyMatch(download -> download.filename().equals(dccSendReceived.filename()) && download.dccReceiver() != null)) { + eventBus.post(new GenericMessage(format("Ignoring offer for %s, it’s already being downloaded.", dccSendReceived.filename()))); return; } - Download download = requestedDownload.iterator().next(); + Download download = openDownloads.stream() + .filter(it -> it.filename().equals(dccSendReceived.filename())) + .findFirst() + .orElse(openDownloads.iterator().next()); + eventBus.post(new GenericMessage(format("Found no offer for %s, using other download from %s, %s.", dccSendReceived.filename(), dccSendReceived.source(), download.filename()))); /* check if the file already exists. */ File outputFile = new File(temporaryDirectory, dccSendReceived.filename()); -- 2.7.4