Skip to content

Commit f1dbc2f

Browse files
committed
Fix download spam
1 parent fe3fd5f commit f1dbc2f

3 files changed

Lines changed: 23 additions & 16 deletions

File tree

Snowcloak/Snowcloak.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<Project Sdk="Dalamud.NET.Sdk/15.0.0">
33
<PropertyGroup>
44
<AssemblyName>Snowcloak</AssemblyName>
5-
<Version>4.0.0.2</Version>
5+
<Version>4.0.1.0</Version>
66
<PackageProjectUrl>https://github.com/Eauldane/SnowcloakClient/</PackageProjectUrl>
77
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
88
<Configurations>Release;Debug</Configurations>
@@ -34,12 +34,12 @@
3434
<PackageReference Include="Microsoft.AspNetCore.SignalR.Client" Version="10.0.10" />
3535
<PackageReference Include="Microsoft.AspNetCore.SignalR.Protocols.MessagePack" Version="10.0.10" />
3636
<PackageReference Include="Microsoft.Data.Sqlite" Version="10.0.10" />
37+
<PackageReference Include="Snowcloak.Ipc" Version="1.4.0" />
3738
<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3" Version="3.0.5" />
3839
<PackageReference Include="Microsoft.Extensions.Hosting" Version="10.0.10" />
3940
<PackageReference Include="NAudio" Version="2.3.0" />
4041
<PackageReference Include="Penumbra.Api" Version="5.15.1" />
4142
<PackageReference Include="Scrutor" Version="7.0.0" />
42-
<PackageReference Include="Snowcloak.Ipc" Version="1.4.0" />
4343
<PackageReference Include="Snowcloak.API" Version="4.0.0" />
4444
<PackageReference Include="Snowcloak.CacheFile" Version="4.0.0" />
4545
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.21.0" />

Snowcloak/WebAPI/Files/FileDownloadManager.cs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public sealed partial class FileDownloadManager : DisposableMediatorSubscriberBa
2727
private readonly FileDownloadNegativeCache _negativeCache;
2828
private readonly ConcurrentDictionary<ThrottledStream, byte> _activeDownloadStreams = new();
2929
private List<DownloadFileTransfer> _currentDownloads = [];
30-
private Dictionary<string, string> _preflightUnavailable = new(StringComparer.OrdinalIgnoreCase);
30+
private Dictionary<string, FileDownloadNegativeEntry> _preflightUnavailable = new(StringComparer.OrdinalIgnoreCase);
3131

3232
public FileDownloadManager(ILogger<FileDownloadManager> logger, SnowMediator mediator,
3333
FileTransferOrchestrator orchestrator, IFileDownloadTransport transport,
@@ -69,7 +69,7 @@ public async Task<List<DownloadFileTransfer>> InitiateDownloadList(GameObjectHan
6969
_preflightUnavailable = requestedHashes
7070
.Select(hash => _negativeCache.TryGet(hash, out var entry) ? entry : null)
7171
.Where(entry => entry != null)
72-
.ToDictionary(entry => entry!.Hash, entry => entry!.Message, StringComparer.OrdinalIgnoreCase);
72+
.ToDictionary(entry => entry!.Hash, entry => entry!, StringComparer.OrdinalIgnoreCase);
7373
var eligibleHashes = requestedHashes.Where(hash => !_preflightUnavailable.ContainsKey(hash)).ToList();
7474
var fileInfo = eligibleHashes.Count == 0
7575
? []
@@ -79,22 +79,22 @@ public async Task<List<DownloadFileTransfer>> InitiateDownloadList(GameObjectHan
7979
{
8080
var entry = _negativeCache.Record(missingHash, FileDownloadNegativeReason.Missing, TimeSpan.FromMinutes(10),
8181
"The requested file is not available on the server. Snowcloak will check again later.");
82-
_preflightUnavailable[entry.Hash] = entry.Message;
82+
_preflightUnavailable[entry.Hash] = entry;
8383
}
8484

8585
foreach (var dto in fileInfo.Where(file => file.IsForbidden))
8686
{
8787
_orchestrator.AddForbiddenTransfer(new ForbiddenTransfer(dto.Hash, dto.ForbiddenBy, ForbiddenTransferKind.Download));
8888
var entry = _negativeCache.Record(dto.Hash, FileDownloadNegativeReason.Rejected, TimeSpan.FromMinutes(30),
8989
"The requested file is blocked from transfer.");
90-
_preflightUnavailable[entry.Hash] = entry.Message;
90+
_preflightUnavailable[entry.Hash] = entry;
9191
}
9292

9393
foreach (var dto in fileInfo.Where(file => !file.FileExists))
9494
{
9595
var entry = _negativeCache.Record(dto.Hash, FileDownloadNegativeReason.Missing, TimeSpan.FromMinutes(10),
9696
"The requested file is not available on the server. Snowcloak will check again later.");
97-
_preflightUnavailable[entry.Hash] = entry.Message;
97+
_preflightUnavailable[entry.Hash] = entry;
9898
}
9999

100100
_currentDownloads = fileInfo.Distinct()
@@ -147,10 +147,11 @@ private async Task DownloadFilesInternal(GameObjectHandler gameObjectHandler, IR
147147
var downloadGroups = _currentDownloads.GroupBy(GetDownloadGroupKey, StringComparer.Ordinal).ToList();
148148

149149
using var download = _statusStore.Begin(gameObjectHandler, uid);
150-
var unavailable = new ConcurrentDictionary<string, string>(_preflightUnavailable, StringComparer.OrdinalIgnoreCase);
150+
var unavailable = new ConcurrentDictionary<string, FileDownloadNegativeEntry>(_preflightUnavailable, StringComparer.OrdinalIgnoreCase);
151151
if (!unavailable.IsEmpty)
152152
{
153-
var message = unavailable.Values.First();
153+
var message = unavailable.Values.FirstOrDefault(entry => entry.Reason != FileDownloadNegativeReason.Missing)?.Message
154+
?? string.Empty;
154155
download.AddGroup("Unavailable", 0, unavailable.Count).SetUnavailable(message);
155156
}
156157
var groupHandles = downloadGroups.ToDictionary(group => group.Key,
@@ -185,8 +186,8 @@ await DownloadAndExtractAsync(transfer, expectedExtensionByHash[transfer.Hash],
185186
}
186187
catch (FileDownloadUnavailableException ex)
187188
{
188-
unavailable.TryAdd(transfer.Hash, ex.Entry.Message);
189-
groupHandle.SetUnavailable(ex.Entry.Message);
189+
unavailable.TryAdd(transfer.Hash, ex.Entry);
190+
groupHandle.SetUnavailable(ex.Entry.Reason == FileDownloadNegativeReason.Missing ? string.Empty : ex.Entry.Message);
190191
LogDownloadError(Logger, ex, transfer.Hash, gameObjectHandler.Name);
191192
}
192193
catch (Exception ex) when (ex is HttpRequestException or IOException or InvalidOperationException or UnauthorizedAccessException)
@@ -201,10 +202,16 @@ await DownloadAndExtractAsync(transfer, expectedExtensionByHash[transfer.Hash],
201202

202203
if (!unavailable.IsEmpty)
203204
{
204-
var reasons = string.Join(" ", unavailable.Values.Distinct(StringComparer.Ordinal).Take(2));
205-
Mediator.Publish(new NotificationMessage("Some files are temporarily unavailable",
206-
$"{unavailable.Count} file(s) could not be downloaded. {reasons}",
207-
Configuration.Models.NotificationType.Warning, TimeSpan.FromSeconds(8)));
205+
var actionableUnavailable = unavailable.Values
206+
.Where(entry => entry.Reason != FileDownloadNegativeReason.Missing)
207+
.ToList();
208+
if (actionableUnavailable.Count > 0)
209+
{
210+
var reasons = string.Join(" ", actionableUnavailable.Select(entry => entry.Message).Distinct(StringComparer.Ordinal).Take(2));
211+
Mediator.Publish(new NotificationMessage("Some files are temporarily unavailable",
212+
$"{actionableUnavailable.Count} file(s) could not be downloaded. {reasons}",
213+
Configuration.Models.NotificationType.Warning, TimeSpan.FromSeconds(8)));
214+
}
208215
}
209216

210217
LogDownloadEnd(Logger, gameObjectHandler.Name);

Snowcloak/packages.lock.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@
231231
"type": "Direct",
232232
"requested": "[1.4.0, )",
233233
"resolved": "1.4.0",
234-
"contentHash": "SQCaEHmiuNkZZM+cXWYDk7/iT+Wdh6+46sst1eb1fy4NuN/NHTUkHbraF+pd0Mwdm/Y4WUti8yU5Vaqen6X8KA=="
234+
"contentHash": "eaOCzzeYgfHVgbixXGFPHYPfelTLC/nGI2eJMLWakQqkz3yS8yDda2e+D+agaBk1oxrf9dfpJd+R5Y1SV2e9Qw=="
235235
},
236236
"SonarAnalyzer.CSharp": {
237237
"type": "Direct",

0 commit comments

Comments
 (0)