potential optimizations (ConfigureAwait, Logging Templates)
This commit is contained in:
		| @@ -113,7 +113,7 @@ namespace MareSynchronosServer.Authentication | ||||
|                     var token = failedAuth.ResetCts.Token; | ||||
|                     failedAuth.ResetTask = Task.Run(async () => | ||||
|                     { | ||||
|                         await Task.Delay(TimeSpan.FromMinutes(tempBanMinutes), token); | ||||
|                         await Task.Delay(TimeSpan.FromMinutes(tempBanMinutes), token).ConfigureAwait(false); | ||||
|                         if (token.IsCancellationRequested) return; | ||||
|                         FailedAuthorization fauth; | ||||
|                         lock (failedAuthLock) | ||||
| @@ -123,7 +123,7 @@ namespace MareSynchronosServer.Authentication | ||||
|                         fauth.Dispose(); | ||||
|                     }, token); | ||||
|  | ||||
|                     Logger.LogWarning("TempBan " + ip + " for authorization spam"); | ||||
|                     Logger.LogWarning("TempBan {ip} for authorization spam", ip); | ||||
|                     return AuthenticateResult.Fail("Failed Authorization"); | ||||
|                 } | ||||
|             } | ||||
| @@ -142,7 +142,7 @@ namespace MareSynchronosServer.Authentication | ||||
|  | ||||
|                         lock (failedAuthLock) | ||||
|                         { | ||||
|                             Logger.LogWarning("Failed authorization from " + ip); | ||||
|                             Logger.LogWarning("Failed authorization from {ip}", ip); | ||||
|                             if (FailedAuthorizations.TryGetValue(ip, out var auth)) | ||||
|                             { | ||||
|                                 auth.IncreaseFailedAttempts(); | ||||
| @@ -163,7 +163,7 @@ namespace MareSynchronosServer.Authentication | ||||
|             if (string.IsNullOrEmpty(uid)) | ||||
|             { | ||||
|                 uid = (await _mareDbContext.Auth.AsNoTracking() | ||||
|                     .FirstOrDefaultAsync(m => m.HashedKey == hashedHeader))?.UserUID; | ||||
|                     .FirstOrDefaultAsync(m => m.HashedKey == hashedHeader).ConfigureAwait(false))?.UserUID; | ||||
|  | ||||
|                 if (uid == null) | ||||
|                 { | ||||
| @@ -172,7 +172,7 @@ namespace MareSynchronosServer.Authentication | ||||
|                         Authentications[hashedHeader] = unauthorized; | ||||
|                     } | ||||
|  | ||||
|                     Logger.LogWarning("Failed authorization from " + ip); | ||||
|                     Logger.LogWarning("Failed authorization from {ip}", ip); | ||||
|                     lock (failedAuthLock) | ||||
|                     { | ||||
|                         if (FailedAuthorizations.TryGetValue(ip, out var auth)) | ||||
|   | ||||
| @@ -49,7 +49,7 @@ namespace MareSynchronosServer | ||||
|             using var scope = _services.CreateScope(); | ||||
|             using var dbContext = scope.ServiceProvider.GetService<MareDbContext>()!; | ||||
|  | ||||
|             _logger.LogInformation($"Cleaning up files older than {filesOlderThanDays} days"); | ||||
|             _logger.LogInformation("Cleaning up files older than {filesOlderThanDays} days", filesOlderThanDays); | ||||
|  | ||||
|             try | ||||
|             { | ||||
| @@ -62,13 +62,13 @@ namespace MareSynchronosServer | ||||
|                     var fi = new FileInfo(fileName); | ||||
|                     if (!fi.Exists) | ||||
|                     { | ||||
|                         _logger.LogInformation("File does not exist anymore: " + fileName); | ||||
|                         _logger.LogInformation("File does not exist anymore: {fileName}", fileName); | ||||
|                         dbContext.Files.Remove(file); | ||||
|                     } | ||||
|                     else if (fi.LastAccessTime < prevTime) | ||||
|                     { | ||||
|                         MareMetrics.FilesTotalSize.Dec(fi.Length); | ||||
|                         _logger.LogInformation("File outdated: " + fileName); | ||||
|                         _logger.LogInformation("File outdated: {fileName}", fileName); | ||||
|                         dbContext.Files.Remove(file); | ||||
|                         fi.Delete(); | ||||
|                     } | ||||
| @@ -144,7 +144,7 @@ namespace MareSynchronosServer | ||||
|                         usersOlderThanDays = 14; | ||||
|                     } | ||||
|  | ||||
|                     _logger.LogInformation($"Cleaning up users older than {usersOlderThanDays} days"); | ||||
|                     _logger.LogInformation("Cleaning up users older than {usersOlderThanDays} days", usersOlderThanDays); | ||||
|  | ||||
|                     var allUsers = dbContext.Users.ToList(); | ||||
|                     List<User> usersToRemove = new(); | ||||
| @@ -152,7 +152,7 @@ namespace MareSynchronosServer | ||||
|                     { | ||||
|                         if (user.LastLoggedIn < (DateTime.UtcNow - TimeSpan.FromDays(usersOlderThanDays))) | ||||
|                         { | ||||
|                             _logger.LogInformation("User outdated: " + user.UID); | ||||
|                             _logger.LogInformation("User outdated: {userUID}", user.UID); | ||||
|                             usersToRemove.Add(user); | ||||
|                         } | ||||
|                     } | ||||
|   | ||||
| @@ -58,21 +58,21 @@ namespace MareSynchronosServer.Discord | ||||
|  | ||||
|         private async Task DiscordClient_SlashCommandExecuted(SocketSlashCommand arg) | ||||
|         { | ||||
|             await semaphore.WaitAsync(); | ||||
|             await semaphore.WaitAsync().ConfigureAwait(false); | ||||
|             try | ||||
|             { | ||||
|                 if (arg.Data.Name == "register") | ||||
|                 { | ||||
|                     if (arg.Data.Options.FirstOrDefault(f => f.Name == "overwrite_old_account") != null) | ||||
|                     { | ||||
|                         await DeletePreviousUserAccount(arg.User.Id); | ||||
|                         await DeletePreviousUserAccount(arg.User.Id).ConfigureAwait(false); | ||||
|                     } | ||||
|  | ||||
|                     var modal = new ModalBuilder(); | ||||
|                     modal.WithTitle("Verify with Lodestone"); | ||||
|                     modal.WithCustomId("register_modal"); | ||||
|                     modal.AddTextInput("Enter the Lodestone URL of your Character", "lodestoneurl", TextInputStyle.Short, "https://*.finalfantasyxiv.com/lodestone/character/<CHARACTERID>/", required: true); | ||||
|                     await arg.RespondWithModalAsync(modal.Build()); | ||||
|                     await arg.RespondWithModalAsync(modal.Build()).ConfigureAwait(false); | ||||
|                 } | ||||
|                 else if (arg.Data.Name == "verify") | ||||
|                 { | ||||
| @@ -81,23 +81,23 @@ namespace MareSynchronosServer.Discord | ||||
|                     { | ||||
|                         eb.WithTitle("Already queued for verfication"); | ||||
|                         eb.WithDescription("You are already queued for verification. Please wait."); | ||||
|                         await arg.RespondAsync(embeds: new[] { eb.Build() }, ephemeral: true); | ||||
|                         await arg.RespondAsync(embeds: new[] { eb.Build() }, ephemeral: true).ConfigureAwait(false); | ||||
|                     } | ||||
|                     else if (!DiscordLodestoneMapping.ContainsKey(arg.User.Id)) | ||||
|                     { | ||||
|                         eb.WithTitle("Cannot verify registration"); | ||||
|                         eb.WithDescription("You need to **/register** first before you can **/verify**"); | ||||
|                         await arg.RespondAsync(embeds: new[] { eb.Build() }, ephemeral: true); | ||||
|                         await arg.RespondAsync(embeds: new[] { eb.Build() }, ephemeral: true).ConfigureAwait(false); | ||||
|                     } | ||||
|                     else | ||||
|                     { | ||||
|                         await arg.DeferAsync(ephemeral: true); | ||||
|                         await arg.DeferAsync(ephemeral: true).ConfigureAwait(false); | ||||
|                         verificationQueue.Enqueue(arg); | ||||
|                     } | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     await arg.RespondAsync("idk what you did to get here to start, just follow the instructions as provided.", ephemeral: true); | ||||
|                     await arg.RespondAsync("idk what you did to get here to start, just follow the instructions as provided.", ephemeral: true).ConfigureAwait(false); | ||||
|                 } | ||||
|             } | ||||
|             finally | ||||
| @@ -110,7 +110,7 @@ namespace MareSynchronosServer.Discord | ||||
|         { | ||||
|             using var scope = services.CreateScope(); | ||||
|             using var db = scope.ServiceProvider.GetService<MareDbContext>(); | ||||
|             var discordAuthedUser = await db.LodeStoneAuth.Include(u => u.User).FirstOrDefaultAsync(u => u.DiscordId == id); | ||||
|             var discordAuthedUser = await db.LodeStoneAuth.Include(u => u.User).FirstOrDefaultAsync(u => u.DiscordId == id).ConfigureAwait(false); | ||||
|             if (discordAuthedUser != null) | ||||
|             { | ||||
|                 if (discordAuthedUser.User != null) | ||||
| @@ -122,7 +122,7 @@ namespace MareSynchronosServer.Discord | ||||
|                     db.Remove(discordAuthedUser); | ||||
|                 } | ||||
|  | ||||
|                 await db.SaveChangesAsync(); | ||||
|                 await db.SaveChangesAsync().ConfigureAwait(false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -130,8 +130,8 @@ namespace MareSynchronosServer.Discord | ||||
|         { | ||||
|             if (arg.Data.CustomId == "register_modal") | ||||
|             { | ||||
|                 var embed = await HandleRegisterModalAsync(arg); | ||||
|                 await arg.RespondAsync(embeds: new Embed[] { embed }, ephemeral: true); | ||||
|                 var embed = await HandleRegisterModalAsync(arg).ConfigureAwait(false); | ||||
|                 await arg.RespondAsync(embeds: new Embed[] { embed }, ephemeral: true).ConfigureAwait(false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -147,10 +147,10 @@ namespace MareSynchronosServer.Discord | ||||
|             if (lodestoneAuth != null && DiscordLodestoneMapping.ContainsKey(id)) | ||||
|             { | ||||
|                 var randomServer = LodestoneServers[random.Next(LodestoneServers.Length)]; | ||||
|                 var response = await req.GetAsync($"https://{randomServer}.finalfantasyxiv.com/lodestone/character/{DiscordLodestoneMapping[id]}"); | ||||
|                 var response = await req.GetAsync($"https://{randomServer}.finalfantasyxiv.com/lodestone/character/{DiscordLodestoneMapping[id]}").ConfigureAwait(false); | ||||
|                 if (response.IsSuccessStatusCode) | ||||
|                 { | ||||
|                     var content = await response.Content.ReadAsStringAsync(); | ||||
|                     var content = await response.Content.ReadAsStringAsync().ConfigureAwait(false); | ||||
|                     if (content.Contains(lodestoneAuth.LodestoneAuthString)) | ||||
|                     { | ||||
|                         DiscordLodestoneMapping.TryRemove(id, out _); | ||||
| @@ -168,7 +168,7 @@ namespace MareSynchronosServer.Discord | ||||
|                         } | ||||
|  | ||||
|                         // make the first registered user on the service to admin | ||||
|                         if (!await db.Users.AnyAsync()) | ||||
|                         if (!await db.Users.AnyAsync().ConfigureAwait(false)) | ||||
|                         { | ||||
|                             user.IsAdmin = true; | ||||
|                         } | ||||
| @@ -187,10 +187,10 @@ namespace MareSynchronosServer.Discord | ||||
|                             User = user, | ||||
|                         }; | ||||
|  | ||||
|                         db.Users.Add(user); | ||||
|                         db.Auth.Add(auth); | ||||
|                         await db.Users.AddAsync(user).ConfigureAwait(false); | ||||
|                         await db.Auth.AddAsync(auth).ConfigureAwait(false); | ||||
|  | ||||
|                         logger.LogInformation("User registered: " + user.UID); | ||||
|                         logger.LogInformation("User registered: {userUID}", user.UID); | ||||
|  | ||||
|                         MareMetrics.UsersRegistered.Inc(); | ||||
|  | ||||
| @@ -217,7 +217,7 @@ namespace MareSynchronosServer.Discord | ||||
|                     } | ||||
|                 } | ||||
|  | ||||
|                 await db.SaveChangesAsync(); | ||||
|                 await db.SaveChangesAsync().ConfigureAwait(false); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
| @@ -270,7 +270,7 @@ namespace MareSynchronosServer.Discord | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     string lodestoneAuth = await GenerateLodestoneAuth(arg.User.Id, hashedLodestoneId, db); | ||||
|                     string lodestoneAuth = await GenerateLodestoneAuth(arg.User.Id, hashedLodestoneId, db).ConfigureAwait(false); | ||||
|                     // check if lodestone id is already in db | ||||
|                     embed.WithTitle("Authorize your character"); | ||||
|                     embed.WithDescription("Add following key to your character profile at https://na.finalfantasyxiv.com/lodestone/my/setting/profile/" | ||||
| @@ -303,7 +303,7 @@ namespace MareSynchronosServer.Discord | ||||
|             }; | ||||
|  | ||||
|             dbContext.Add(lsAuth); | ||||
|             await dbContext.SaveChangesAsync(); | ||||
|             await dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|  | ||||
|             return auth; | ||||
|         } | ||||
| @@ -345,8 +345,8 @@ namespace MareSynchronosServer.Discord | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 await discordClient.CreateGlobalApplicationCommandAsync(register.Build()); | ||||
|                 await discordClient.CreateGlobalApplicationCommandAsync(verify.Build()); | ||||
|                 await discordClient.CreateGlobalApplicationCommandAsync(register.Build()).ConfigureAwait(false); | ||||
|                 await discordClient.CreateGlobalApplicationCommandAsync(verify.Build()).ConfigureAwait(false); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
| @@ -356,7 +356,7 @@ namespace MareSynchronosServer.Discord | ||||
|  | ||||
|         private Task Log(LogMessage msg) | ||||
|         { | ||||
|             logger.LogInformation(msg.ToString()); | ||||
|             logger.LogInformation("{msg}", msg); | ||||
|  | ||||
|             return Task.CompletedTask; | ||||
|         } | ||||
| @@ -367,8 +367,8 @@ namespace MareSynchronosServer.Discord | ||||
|             { | ||||
|                 authToken = configuration.GetValue<string>("DiscordBotToken"); | ||||
|  | ||||
|                 await discordClient.LoginAsync(TokenType.Bot, authToken); | ||||
|                 await discordClient.StartAsync(); | ||||
|                 await discordClient.LoginAsync(TokenType.Bot, authToken).ConfigureAwait(false); | ||||
|                 await discordClient.StartAsync().ConfigureAwait(false); | ||||
|  | ||||
|                 discordClient.Ready += DiscordClient_Ready; | ||||
|                 discordClient.SlashCommandExecuted += DiscordClient_SlashCommandExecuted; | ||||
| @@ -388,18 +388,18 @@ namespace MareSynchronosServer.Discord | ||||
|                 { | ||||
|                     try | ||||
|                     { | ||||
|                         var dataEmbed = await HandleVerifyAsync(queueitem.User.Id); | ||||
|                         await queueitem.FollowupAsync(embed: dataEmbed, ephemeral: true); | ||||
|                         var dataEmbed = await HandleVerifyAsync(queueitem.User.Id).ConfigureAwait(false); | ||||
|                         await queueitem.FollowupAsync(embed: dataEmbed, ephemeral: true).ConfigureAwait(false); | ||||
|  | ||||
|                         logger.LogInformation("Sent login information to user"); | ||||
|                     } | ||||
|                     catch (Exception e) | ||||
|                     { | ||||
|                         logger.LogError(e.Message); | ||||
|                         logger.LogError(e, "Error during queue work"); | ||||
|                     } | ||||
|  | ||||
|                 } | ||||
|                 await Task.Delay(TimeSpan.FromSeconds(2), verificationTaskCts.Token); | ||||
|                 await Task.Delay(TimeSpan.FromSeconds(2), verificationTaskCts.Token).ConfigureAwait(false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -408,14 +408,14 @@ namespace MareSynchronosServer.Discord | ||||
|             updateStatusCts = new(); | ||||
|             while (!updateStatusCts.IsCancellationRequested) | ||||
|             { | ||||
|                 using var scope = services.CreateScope(); | ||||
|                 using var db = scope.ServiceProvider.GetService<MareDbContext>(); | ||||
|                 await using var scope = services.CreateAsyncScope(); | ||||
|                 await using var db = scope.ServiceProvider.GetService<MareDbContext>(); | ||||
|  | ||||
|                 var users = db.Users.Count(c => c.CharacterIdentification != null); | ||||
|  | ||||
|                 await discordClient.SetActivityAsync(new Game("Mare for " + users + " Users")); | ||||
|                 await discordClient.SetActivityAsync(new Game("Mare for " + users + " Users")).ConfigureAwait(false); | ||||
|  | ||||
|                 await Task.Delay(TimeSpan.FromSeconds(15)); | ||||
|                 await Task.Delay(TimeSpan.FromSeconds(15)).ConfigureAwait(false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -424,8 +424,8 @@ namespace MareSynchronosServer.Discord | ||||
|             verificationTaskCts?.Cancel(); | ||||
|             updateStatusCts?.Cancel(); | ||||
|  | ||||
|             await discordClient.LogoutAsync(); | ||||
|             await discordClient.StopAsync(); | ||||
|             await discordClient.LogoutAsync().ConfigureAwait(false); | ||||
|             await discordClient.StopAsync().ConfigureAwait(false); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -23,14 +23,14 @@ namespace MareSynchronosServer.Hubs | ||||
|         public async Task ChangeModeratorStatus(string uid, bool isModerator) | ||||
|         { | ||||
|             if (!IsAdmin) return; | ||||
|             var user = await _dbContext.Users.SingleOrDefaultAsync(u => u.UID == uid); | ||||
|             var user = await _dbContext.Users.SingleOrDefaultAsync(u => u.UID == uid).ConfigureAwait(false); | ||||
|  | ||||
|             if (user == null) return; | ||||
|  | ||||
|             user.IsModerator = isModerator; | ||||
|             _dbContext.Update(user); | ||||
|             await _dbContext.SaveChangesAsync(); | ||||
|             await Clients.Users(user.UID).SendAsync(Api.OnAdminForcedReconnect); | ||||
|             await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|             await Clients.Users(user.UID).SendAsync(Api.OnAdminForcedReconnect).ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)] | ||||
| @@ -40,15 +40,15 @@ namespace MareSynchronosServer.Hubs | ||||
|             if (!IsModerator || string.IsNullOrEmpty(dto.CharacterHash)) return; | ||||
|  | ||||
|             var existingUser = | ||||
|                 await _dbContext.BannedUsers.SingleOrDefaultAsync(b => b.CharacterIdentification == dto.CharacterHash); | ||||
|                 await _dbContext.BannedUsers.SingleOrDefaultAsync(b => b.CharacterIdentification == dto.CharacterHash).ConfigureAwait(false); | ||||
|             if (existingUser == null) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             _dbContext.Remove(existingUser); | ||||
|             await _dbContext.SaveChangesAsync(); | ||||
|             await Clients.Users(OnlineAdmins).SendAsync(Api.OnAdminDeleteBannedUser, dto); | ||||
|             await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|             await Clients.Users(OnlineAdmins).SendAsync(Api.OnAdminDeleteBannedUser, dto).ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)] | ||||
| @@ -58,15 +58,15 @@ namespace MareSynchronosServer.Hubs | ||||
|             if (!IsAdmin || string.IsNullOrEmpty(dto.Hash)) return; | ||||
|  | ||||
|             var existingFile = | ||||
|                 await _dbContext.ForbiddenUploadEntries.SingleOrDefaultAsync(b => b.Hash == dto.Hash); | ||||
|                 await _dbContext.ForbiddenUploadEntries.SingleOrDefaultAsync(b => b.Hash == dto.Hash).ConfigureAwait(false); | ||||
|             if (existingFile == null) | ||||
|             { | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             _dbContext.Remove(existingFile); | ||||
|             await _dbContext.SaveChangesAsync(); | ||||
|             await Clients.Users(OnlineAdmins).SendAsync(Api.OnAdminDeleteForbiddenFile, dto); | ||||
|             await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|             await Clients.Users(OnlineAdmins).SendAsync(Api.OnAdminDeleteForbiddenFile, dto).ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)] | ||||
| @@ -79,7 +79,7 @@ namespace MareSynchronosServer.Hubs | ||||
|             { | ||||
|                 CharacterHash = b.CharacterIdentification, | ||||
|                 Reason = b.Reason | ||||
|             }).ToListAsync(); | ||||
|             }).ToListAsync().ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)] | ||||
| @@ -92,7 +92,7 @@ namespace MareSynchronosServer.Hubs | ||||
|             { | ||||
|                 Hash = b.Hash, | ||||
|                 ForbiddenBy = b.ForbiddenBy | ||||
|             }).ToListAsync(); | ||||
|             }).ToListAsync().ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)] | ||||
| @@ -107,7 +107,7 @@ namespace MareSynchronosServer.Hubs | ||||
|                 UID = b.UID, | ||||
|                 IsModerator = b.IsModerator, | ||||
|                 IsAdmin = b.IsAdmin | ||||
|             }).ToListAsync(); | ||||
|             }).ToListAsync().ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)] | ||||
| @@ -117,7 +117,7 @@ namespace MareSynchronosServer.Hubs | ||||
|             if (!IsModerator || string.IsNullOrEmpty(dto.CharacterHash)) return; | ||||
|  | ||||
|             var existingUser = | ||||
|                 await _dbContext.BannedUsers.SingleOrDefaultAsync(b => b.CharacterIdentification == dto.CharacterHash); | ||||
|                 await _dbContext.BannedUsers.SingleOrDefaultAsync(b => b.CharacterIdentification == dto.CharacterHash).ConfigureAwait(false); | ||||
|             if (existingUser != null) | ||||
|             { | ||||
|                 existingUser.Reason = dto.Reason; | ||||
| @@ -129,16 +129,16 @@ namespace MareSynchronosServer.Hubs | ||||
|                 { | ||||
|                     CharacterIdentification = dto.CharacterHash, | ||||
|                     Reason = dto.Reason | ||||
|                 }); | ||||
|                 }).ConfigureAwait(false); | ||||
|             } | ||||
|  | ||||
|             await _dbContext.SaveChangesAsync(); | ||||
|             await Clients.Users(OnlineAdmins).SendAsync(Api.OnAdminUpdateOrAddBannedUser, dto); | ||||
|             await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|             await Clients.Users(OnlineAdmins).SendAsync(Api.OnAdminUpdateOrAddBannedUser, dto).ConfigureAwait(false); | ||||
|             var bannedUser = | ||||
|                 await _dbContext.Users.SingleOrDefaultAsync(u => u.CharacterIdentification == dto.CharacterHash); | ||||
|                 await _dbContext.Users.SingleOrDefaultAsync(u => u.CharacterIdentification == dto.CharacterHash).ConfigureAwait(false); | ||||
|             if (bannedUser != null) | ||||
|             { | ||||
|                 await Clients.User(bannedUser.UID).SendAsync(Api.OnAdminForcedReconnect); | ||||
|                 await Clients.User(bannedUser.UID).SendAsync(Api.OnAdminForcedReconnect).ConfigureAwait(false); | ||||
|             } | ||||
|         } | ||||
|  | ||||
| @@ -149,7 +149,7 @@ namespace MareSynchronosServer.Hubs | ||||
|             if (!IsAdmin || string.IsNullOrEmpty(dto.Hash)) return; | ||||
|  | ||||
|             var existingForbiddenFile = | ||||
|                 await _dbContext.ForbiddenUploadEntries.SingleOrDefaultAsync(b => b.Hash == dto.Hash); | ||||
|                 await _dbContext.ForbiddenUploadEntries.SingleOrDefaultAsync(b => b.Hash == dto.Hash).ConfigureAwait(false); | ||||
|             if (existingForbiddenFile != null) | ||||
|             { | ||||
|                 existingForbiddenFile.ForbiddenBy = dto.ForbiddenBy; | ||||
| @@ -161,12 +161,12 @@ namespace MareSynchronosServer.Hubs | ||||
|                 { | ||||
|                     Hash = dto.Hash, | ||||
|                     ForbiddenBy = dto.ForbiddenBy | ||||
|                 }); | ||||
|                 }).ConfigureAwait(false); | ||||
|             } | ||||
|  | ||||
|             await _dbContext.SaveChangesAsync(); | ||||
|             await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|  | ||||
|             await Clients.Users(OnlineAdmins).SendAsync(Api.OnAdminUpdateOrAddForbiddenFile, dto); | ||||
|             await Clients.Users(OnlineAdmins).SendAsync(Api.OnAdminUpdateOrAddForbiddenFile, dto).ConfigureAwait(false); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -25,20 +25,20 @@ namespace MareSynchronosServer.Hubs | ||||
|         [HubMethodName(Api.SendFileAbortUpload)] | ||||
|         public async Task AbortUpload() | ||||
|         { | ||||
|             _logger.LogInformation("User " + AuthenticatedUserId + " aborted upload"); | ||||
|             _logger.LogInformation("User {AuthenticatedUserId} aborted upload", AuthenticatedUserId); | ||||
|             var userId = AuthenticatedUserId; | ||||
|             var notUploadedFiles = _dbContext.Files.Where(f => !f.Uploaded && f.Uploader.UID == userId).ToList(); | ||||
|             _dbContext.RemoveRange(notUploadedFiles); | ||||
|             await _dbContext.SaveChangesAsync(); | ||||
|             await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)] | ||||
|         [HubMethodName(Api.SendFileDeleteAllFiles)] | ||||
|         public async Task DeleteAllFiles() | ||||
|         { | ||||
|             _logger.LogInformation("User " + AuthenticatedUserId + " deleted all their files"); | ||||
|             _logger.LogInformation("User {AuthenticatedUserId} deleted all their files", AuthenticatedUserId); | ||||
|  | ||||
|             var ownFiles = await _dbContext.Files.Where(f => f.Uploaded && f.Uploader.UID == AuthenticatedUserId).ToListAsync(); | ||||
|             var ownFiles = await _dbContext.Files.Where(f => f.Uploaded && f.Uploader.UID == AuthenticatedUserId).ToListAsync().ConfigureAwait(false); | ||||
|             foreach (var file in ownFiles) | ||||
|             { | ||||
|                 var fi = new FileInfo(Path.Combine(BasePath, file.Hash)); | ||||
| @@ -50,16 +50,16 @@ namespace MareSynchronosServer.Hubs | ||||
|                 } | ||||
|             } | ||||
|             _dbContext.Files.RemoveRange(ownFiles); | ||||
|             await _dbContext.SaveChangesAsync(); | ||||
|             await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)] | ||||
|         [HubMethodName(Api.InvokeGetFilesSizes)] | ||||
|         public async Task<List<DownloadFileDto>> GetFilesSizes(List<string> hashes) | ||||
|         { | ||||
|             var allFiles = await _dbContext.Files.Where(f => hashes.Contains(f.Hash)).ToListAsync(); | ||||
|             var allFiles = await _dbContext.Files.Where(f => hashes.Contains(f.Hash)).ToListAsync().ConfigureAwait(false); | ||||
|             var forbiddenFiles = await _dbContext.ForbiddenUploadEntries. | ||||
|                 Where(f => hashes.Contains(f.Hash)).ToListAsync(); | ||||
|                 Where(f => hashes.Contains(f.Hash)).ToListAsync().ConfigureAwait(false); | ||||
|             List<DownloadFileDto> response = new(); | ||||
|             foreach (var hash in hashes) | ||||
|             { | ||||
| @@ -90,7 +90,7 @@ namespace MareSynchronosServer.Hubs | ||||
|                 if (!fileInfo.Exists && downloadFile != null) | ||||
|                 { | ||||
|                     _dbContext.Files.Remove(downloadFile); | ||||
|                     await _dbContext.SaveChangesAsync(); | ||||
|                     await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @@ -103,7 +103,7 @@ namespace MareSynchronosServer.Hubs | ||||
|         { | ||||
|             var userUid = AuthenticatedUserId; | ||||
|             return await _dbContext.Files.AsNoTracking() | ||||
|                 .AnyAsync(f => f.Uploader.UID == userUid && !f.Uploaded); | ||||
|                 .AnyAsync(f => f.Uploader.UID == userUid && !f.Uploaded).ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)] | ||||
| @@ -111,12 +111,11 @@ namespace MareSynchronosServer.Hubs | ||||
|         public async Task<List<UploadFileDto>> SendFiles(List<string> fileListHashes) | ||||
|         { | ||||
|             var userSentHashes = new HashSet<string>(fileListHashes.Distinct()); | ||||
|             _logger.LogInformation($"User {AuthenticatedUserId} sending files: {userSentHashes.Count}"); | ||||
|             _logger.LogInformation("User {AuthenticatedUserId} sending files: {count}", AuthenticatedUserId, userSentHashes.Count); | ||||
|             var notCoveredFiles = new Dictionary<string, UploadFileDto>(); | ||||
|             // Todo: Check if a select can directly transform to hashset | ||||
|             var forbiddenFiles = await _dbContext.ForbiddenUploadEntries.AsNoTracking().Where(f => userSentHashes.Contains(f.Hash)).ToDictionaryAsync(f => f.Hash, f => f); | ||||
|             var existingFiles = await _dbContext.Files.AsNoTracking().Where(f => userSentHashes.Contains(f.Hash)).ToDictionaryAsync(f => f.Hash, f => f); | ||||
|             var uploader = await _dbContext.Users.SingleAsync(u => u.UID == AuthenticatedUserId); | ||||
|             var forbiddenFiles = await _dbContext.ForbiddenUploadEntries.AsNoTracking().Where(f => userSentHashes.Contains(f.Hash)).ToDictionaryAsync(f => f.Hash, f => f).ConfigureAwait(false); | ||||
|             var existingFiles = await _dbContext.Files.AsNoTracking().Where(f => userSentHashes.Contains(f.Hash)).ToDictionaryAsync(f => f.Hash, f => f).ConfigureAwait(false); | ||||
|             var uploader = await _dbContext.Users.SingleAsync(u => u.UID == AuthenticatedUserId).ConfigureAwait(false); | ||||
|  | ||||
|             List<FileCache> fileCachesToUpload = new(); | ||||
|             foreach (var file in userSentHashes) | ||||
| @@ -137,7 +136,7 @@ namespace MareSynchronosServer.Hubs | ||||
|                 } | ||||
|                 if (existingFiles.ContainsKey(file)) { continue; } | ||||
|  | ||||
|                 _logger.LogInformation("User " + AuthenticatedUserId + " needs upload: " + file); | ||||
|                 _logger.LogInformation("User {AuthenticatedUserId}  needs upload: {file}", AuthenticatedUserId, file); | ||||
|                 var userId = AuthenticatedUserId; | ||||
|                 fileCachesToUpload.Add(new FileCache() | ||||
|                 { | ||||
| @@ -152,8 +151,8 @@ namespace MareSynchronosServer.Hubs | ||||
|                 }; | ||||
|             } | ||||
|             //Save bulk | ||||
|             await _dbContext.Files.AddRangeAsync(fileCachesToUpload); | ||||
|             await _dbContext.SaveChangesAsync(); | ||||
|             await _dbContext.Files.AddRangeAsync(fileCachesToUpload).ConfigureAwait(false); | ||||
|             await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|             return notCoveredFiles.Values.ToList(); | ||||
|         } | ||||
|  | ||||
| @@ -161,7 +160,7 @@ namespace MareSynchronosServer.Hubs | ||||
|         [HubMethodName(Api.SendFileUploadFileStreamAsync)] | ||||
|         public async Task UploadFileStreamAsync(string hash, IAsyncEnumerable<byte[]> fileContent) | ||||
|         { | ||||
|             _logger.LogInformation("User " + AuthenticatedUserId + " uploading file: " + hash); | ||||
|             _logger.LogInformation("User {AuthenticatedUserId} uploading file: {hash}", AuthenticatedUserId, hash); | ||||
|  | ||||
|             var relatedFile = _dbContext.Files.SingleOrDefault(f => f.Hash == hash && f.Uploader.UID == AuthenticatedUserId && f.Uploaded == false); | ||||
|             if (relatedFile == null) return; | ||||
| @@ -173,23 +172,23 @@ namespace MareSynchronosServer.Hubs | ||||
|             long length = 0; | ||||
|             try | ||||
|             { | ||||
|                 await foreach (var chunk in fileContent) | ||||
|                 await foreach (var chunk in fileContent.ConfigureAwait(false)) | ||||
|                 { | ||||
|                     length += chunk.Length; | ||||
|                     await fileStream.WriteAsync(chunk); | ||||
|                     await fileStream.WriteAsync(chunk).ConfigureAwait(false); | ||||
|                 } | ||||
|  | ||||
|                 await fileStream.FlushAsync(); | ||||
|                 await fileStream.DisposeAsync(); | ||||
|                 await fileStream.FlushAsync().ConfigureAwait(false); | ||||
|                 await fileStream.DisposeAsync().ConfigureAwait(false); | ||||
|             } | ||||
|             catch | ||||
|             { | ||||
|                 try | ||||
|                 { | ||||
|                     await fileStream.FlushAsync(); | ||||
|                     await fileStream.DisposeAsync(); | ||||
|                     await fileStream.FlushAsync().ConfigureAwait(false); | ||||
|                     await fileStream.DisposeAsync().ConfigureAwait(false); | ||||
|                     _dbContext.Files.Remove(relatedFile); | ||||
|                     await _dbContext.SaveChangesAsync(); | ||||
|                     await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|                 } | ||||
|                 catch | ||||
|                 { | ||||
| @@ -203,20 +202,20 @@ namespace MareSynchronosServer.Hubs | ||||
|                 return; | ||||
|             } | ||||
|  | ||||
|             _logger.LogInformation("User " + AuthenticatedUserId + " upload finished: " + hash + ", size: " + length); | ||||
|             _logger.LogInformation("User {AuthenticatedUserId} upload finished: {hash}, size: {length}", AuthenticatedUserId, hash, length); | ||||
|  | ||||
|             try | ||||
|             { | ||||
|                 var decodedFile = LZ4.LZ4Codec.Unwrap(await File.ReadAllBytesAsync(tempFileName)); | ||||
|                 var decodedFile = LZ4.LZ4Codec.Unwrap(await File.ReadAllBytesAsync(tempFileName).ConfigureAwait(false)); | ||||
|                 using var sha1 = SHA1.Create(); | ||||
|                 using var ms = new MemoryStream(decodedFile); | ||||
|                 var computedHash = await sha1.ComputeHashAsync(ms); | ||||
|                 var computedHash = await sha1.ComputeHashAsync(ms).ConfigureAwait(false); | ||||
|                 var computedHashString = BitConverter.ToString(computedHash).Replace("-", ""); | ||||
|                 if (hash != computedHashString) | ||||
|                 { | ||||
|                     _logger.LogWarning($"Computed file hash was not expected file hash. Computed: {computedHashString}, Expected {hash}"); | ||||
|                     _logger.LogWarning("Computed file hash was not expected file hash. Computed: {computedHashString}, Expected {hash}", computedHashString, hash); | ||||
|                     _dbContext.Remove(relatedFile); | ||||
|                     await _dbContext.SaveChangesAsync(); | ||||
|                     await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|  | ||||
|                     return; | ||||
|                 } | ||||
| @@ -228,14 +227,14 @@ namespace MareSynchronosServer.Hubs | ||||
|                 MareMetrics.FilesTotal.Inc(); | ||||
|                 MareMetrics.FilesTotalSize.Inc(length); | ||||
|  | ||||
|                 await _dbContext.SaveChangesAsync(); | ||||
|                 _logger.LogInformation("File " + hash + " added to DB"); | ||||
|                 await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|                 _logger.LogInformation("File {hash} added to DB", hash); | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             { | ||||
|                 _logger.LogWarning(ex, "Upload failed"); | ||||
|                 _dbContext.Remove(relatedFile); | ||||
|                 await _dbContext.SaveChangesAsync(); | ||||
|                 await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|   | ||||
| @@ -18,14 +18,14 @@ namespace MareSynchronosServer.Hubs | ||||
|         [HubMethodName(Api.SendUserDeleteAccount)] | ||||
|         public async Task DeleteAccount() | ||||
|         { | ||||
|             _logger.LogInformation("User " + AuthenticatedUserId + " deleted their account"); | ||||
|             _logger.LogInformation("User {AuthenticatedUserId} deleted their account", AuthenticatedUserId); | ||||
|  | ||||
|  | ||||
|             string userid = AuthenticatedUserId; | ||||
|             var userEntry = await _dbContext.Users.SingleAsync(u => u.UID == userid); | ||||
|             var ownPairData = await _dbContext.ClientPairs.Where(u => u.User.UID == userid).ToListAsync(); | ||||
|             var auth = await _dbContext.Auth.SingleAsync(u => u.UserUID == userid); | ||||
|             var lodestone = await _dbContext.LodeStoneAuth.SingleOrDefaultAsync(a => a.User.UID == userid); | ||||
|             var userEntry = await _dbContext.Users.SingleAsync(u => u.UID == userid).ConfigureAwait(false); | ||||
|             var ownPairData = await _dbContext.ClientPairs.Where(u => u.User.UID == userid).ToListAsync().ConfigureAwait(false); | ||||
|             var auth = await _dbContext.Auth.SingleAsync(u => u.UserUID == userid).ConfigureAwait(false); | ||||
|             var lodestone = await _dbContext.LodeStoneAuth.SingleOrDefaultAsync(a => a.User.UID == userid).ConfigureAwait(false); | ||||
|  | ||||
|             if (lodestone != null) | ||||
|             { | ||||
| @@ -34,7 +34,7 @@ namespace MareSynchronosServer.Hubs | ||||
|  | ||||
|             while (_dbContext.Files.Any(f => f.Uploader == userEntry)) | ||||
|             { | ||||
|                 await Task.Delay(1000); | ||||
|                 await Task.Delay(1000).ConfigureAwait(false); | ||||
|             } | ||||
|  | ||||
|             SecretKeyAuthenticationHandler.RemoveAuthentication(userid); | ||||
| @@ -43,9 +43,9 @@ namespace MareSynchronosServer.Hubs | ||||
|             MareMetrics.PairsPaused.Dec(ownPairData.Count(c => c.IsPaused)); | ||||
|  | ||||
|             _dbContext.RemoveRange(ownPairData); | ||||
|             await _dbContext.SaveChangesAsync(); | ||||
|             await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|             var otherPairData = await _dbContext.ClientPairs.Include(u => u.User) | ||||
|                 .Where(u => u.OtherUser.UID == userid).ToListAsync(); | ||||
|                 .Where(u => u.OtherUser.UID == userid).ToListAsync().ConfigureAwait(false); | ||||
|             foreach (var pair in otherPairData) | ||||
|             { | ||||
|                 await Clients.User(pair.User.UID) | ||||
| @@ -53,38 +53,38 @@ namespace MareSynchronosServer.Hubs | ||||
|                     { | ||||
|                         OtherUID = userid, | ||||
|                         IsRemoved = true | ||||
|                     }, userEntry.CharacterIdentification); | ||||
|                     }, userEntry.CharacterIdentification).ConfigureAwait(false); | ||||
|             } | ||||
|  | ||||
|             MareMetrics.Pairs.Dec(otherPairData.Count()); | ||||
|             MareMetrics.Pairs.Dec(otherPairData.Count); | ||||
|             MareMetrics.PairsPaused.Dec(otherPairData.Count(c => c.IsPaused)); | ||||
|             MareMetrics.UsersRegistered.Dec(); | ||||
|  | ||||
|             _dbContext.RemoveRange(otherPairData); | ||||
|             _dbContext.Remove(userEntry); | ||||
|             _dbContext.Remove(auth); | ||||
|             await _dbContext.SaveChangesAsync(); | ||||
|             await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         [Authorize(AuthenticationSchemes = SecretKeyAuthenticationHandler.AuthScheme)] | ||||
|         [HubMethodName(Api.InvokeUserGetOnlineCharacters)] | ||||
|         public async Task<List<string>> GetOnlineCharacters() | ||||
|         { | ||||
|             _logger.LogInformation("User " + AuthenticatedUserId + " requested online characters"); | ||||
|             _logger.LogInformation("User {AuthenticatedUserId} requested online characters", AuthenticatedUserId); | ||||
|  | ||||
|             var ownUser = await GetAuthenticatedUserUntrackedAsync(); | ||||
|             var ownUser = await GetAuthenticatedUserUntrackedAsync().ConfigureAwait(false); | ||||
|  | ||||
|             var otherUsers = await _dbContext.ClientPairs.AsNoTracking() | ||||
|             .Include(u => u.User) | ||||
|             .Include(u => u.OtherUser) | ||||
|             .Where(w => w.User.UID == ownUser.UID && !w.IsPaused) | ||||
|             .Where(w => !string.IsNullOrEmpty(w.OtherUser.CharacterIdentification)) | ||||
|             .Select(e => e.OtherUser).ToListAsync(); | ||||
|                 .Include(u => u.User) | ||||
|                 .Include(u => u.OtherUser) | ||||
|                 .Where(w => w.User.UID == ownUser.UID && !w.IsPaused) | ||||
|                 .Where(w => !string.IsNullOrEmpty(w.OtherUser.CharacterIdentification)) | ||||
|                 .Select(e => e.OtherUser).ToListAsync().ConfigureAwait(false); | ||||
|             var otherEntries = await _dbContext.ClientPairs.AsNoTracking() | ||||
|                 .Include(u => u.User) | ||||
|                 .Where(u => otherUsers.Any(e => e == u.User) && u.OtherUser == ownUser && !u.IsPaused).ToListAsync(); | ||||
|                 .Where(u => otherUsers.Any(e => e == u.User) && u.OtherUser == ownUser && !u.IsPaused).ToListAsync().ConfigureAwait(false); | ||||
|  | ||||
|             await Clients.Users(otherEntries.Select(e => e.User.UID)).SendAsync(Api.OnUserAddOnlinePairedPlayer, ownUser.CharacterIdentification); | ||||
|             await Clients.Users(otherEntries.Select(e => e.User.UID)).SendAsync(Api.OnUserAddOnlinePairedPlayer, ownUser.CharacterIdentification).ConfigureAwait(false); | ||||
|             return otherEntries.Select(e => e.User.CharacterIdentification).Distinct().ToList(); | ||||
|         } | ||||
|  | ||||
| @@ -117,7 +117,7 @@ namespace MareSynchronosServer.Hubs | ||||
|                     IsSynced = otherEntry != null | ||||
|                 }; | ||||
|  | ||||
|             return (await query.ToListAsync()).Select(f => new ClientPairDto() | ||||
|             return (await query.ToListAsync().ConfigureAwait(false)).Select(f => new ClientPairDto() | ||||
|             { | ||||
|                 IsPaused = f.IsPaused, | ||||
|                 OtherUID = f.OtherUserUID, | ||||
| @@ -130,9 +130,9 @@ namespace MareSynchronosServer.Hubs | ||||
|         [HubMethodName(Api.InvokeUserPushCharacterDataToVisibleClients)] | ||||
|         public async Task PushCharacterDataToVisibleClients(CharacterCacheDto characterCache, List<string> visibleCharacterIds) | ||||
|         { | ||||
|             _logger.LogInformation("User " + AuthenticatedUserId + " pushing character data to " + visibleCharacterIds.Count + " visible clients"); | ||||
|             _logger.LogInformation("User {AuthenticatedUserId} pushing character data to {visibleCharacterIds} visible clients", AuthenticatedUserId, visibleCharacterIds.Count); | ||||
|  | ||||
|             var user = await GetAuthenticatedUserUntrackedAsync(); | ||||
|             var user = await GetAuthenticatedUserUntrackedAsync().ConfigureAwait(false); | ||||
|  | ||||
|             var query = | ||||
|                 from userToOther in _dbContext.ClientPairs | ||||
| @@ -154,9 +154,9 @@ namespace MareSynchronosServer.Hubs | ||||
|                     && visibleCharacterIds.Contains(userToOther.OtherUser.CharacterIdentification) | ||||
|                 select otherToUser.UserUID; | ||||
|  | ||||
|             var otherEntries = await query.ToListAsync(); | ||||
|             var otherEntries = await query.ToListAsync().ConfigureAwait(false); | ||||
|  | ||||
|             await Clients.Users(otherEntries).SendAsync(Api.OnUserReceiveCharacterData, characterCache, user.CharacterIdentification); | ||||
|             await Clients.Users(otherEntries).SendAsync(Api.OnUserReceiveCharacterData, characterCache, user.CharacterIdentification).ConfigureAwait(false); | ||||
|  | ||||
|             MareMetrics.UserPushData.Inc(); | ||||
|             MareMetrics.UserPushDataTo.Inc(otherEntries.Count); | ||||
| @@ -168,24 +168,24 @@ namespace MareSynchronosServer.Hubs | ||||
|         { | ||||
|             if (uid == AuthenticatedUserId) return; | ||||
|             uid = uid.Trim(); | ||||
|             var user = await _dbContext.Users.SingleAsync(u => u.UID == AuthenticatedUserId); | ||||
|             var user = await _dbContext.Users.SingleAsync(u => u.UID == AuthenticatedUserId).ConfigureAwait(false); | ||||
|  | ||||
|             var otherUser = await _dbContext.Users | ||||
|                 .SingleOrDefaultAsync(u => u.UID == uid); | ||||
|                 .SingleOrDefaultAsync(u => u.UID == uid).ConfigureAwait(false); | ||||
|             var existingEntry = | ||||
|                 await _dbContext.ClientPairs.AsNoTracking() | ||||
|                     .FirstOrDefaultAsync(p => | ||||
|                     p.User.UID == AuthenticatedUserId && p.OtherUser.UID == uid); | ||||
|                         p.User.UID == AuthenticatedUserId && p.OtherUser.UID == uid).ConfigureAwait(false); | ||||
|             if (otherUser == null || existingEntry != null) return; | ||||
|             _logger.LogInformation("User " + AuthenticatedUserId + " adding " + uid + " to whitelist"); | ||||
|             _logger.LogInformation("User {AuthenticatedUserId} adding {uid} to whitelist", AuthenticatedUserId, uid); | ||||
|             ClientPair wl = new ClientPair() | ||||
|             { | ||||
|                 IsPaused = false, | ||||
|                 OtherUser = otherUser, | ||||
|                 User = user | ||||
|             }; | ||||
|             await _dbContext.ClientPairs.AddAsync(wl); | ||||
|             await _dbContext.SaveChangesAsync(); | ||||
|             await _dbContext.ClientPairs.AddAsync(wl).ConfigureAwait(false); | ||||
|             await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|             var otherEntry = OppositeEntry(uid); | ||||
|             await Clients.User(user.UID) | ||||
|                 .SendAsync(Api.OnUserUpdateClientPairs, new ClientPairDto() | ||||
| @@ -194,7 +194,7 @@ namespace MareSynchronosServer.Hubs | ||||
|                     IsPaused = false, | ||||
|                     IsPausedFromOthers = otherEntry?.IsPaused ?? false, | ||||
|                     IsSynced = otherEntry != null | ||||
|                 }, string.Empty); | ||||
|                 }, string.Empty).ConfigureAwait(false); | ||||
|             if (otherEntry != null) | ||||
|             { | ||||
|                 await Clients.User(uid).SendAsync(Api.OnUserUpdateClientPairs, | ||||
| @@ -204,14 +204,14 @@ namespace MareSynchronosServer.Hubs | ||||
|                         IsPaused = otherEntry.IsPaused, | ||||
|                         IsPausedFromOthers = false, | ||||
|                         IsSynced = true | ||||
|                     }, user.CharacterIdentification); | ||||
|                     }, user.CharacterIdentification).ConfigureAwait(false); | ||||
|  | ||||
|                 if (!string.IsNullOrEmpty(otherUser.CharacterIdentification)) | ||||
|                 { | ||||
|                     await Clients.User(user.UID) | ||||
|                         .SendAsync(Api.OnUserAddOnlinePairedPlayer, otherUser.CharacterIdentification); | ||||
|                         .SendAsync(Api.OnUserAddOnlinePairedPlayer, otherUser.CharacterIdentification).ConfigureAwait(false); | ||||
|                     await Clients.User(otherUser.UID) | ||||
|                         .SendAsync(Api.OnUserAddOnlinePairedPlayer, user.CharacterIdentification); | ||||
|                         .SendAsync(Api.OnUserAddOnlinePairedPlayer, user.CharacterIdentification).ConfigureAwait(false); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @@ -223,15 +223,15 @@ namespace MareSynchronosServer.Hubs | ||||
|         public async Task SendPairedClientPauseChange(string otherUserUid, bool isPaused) | ||||
|         { | ||||
|             if (otherUserUid == AuthenticatedUserId) return; | ||||
|             ClientPair pair = await _dbContext.ClientPairs.SingleOrDefaultAsync(w => w.UserUID == AuthenticatedUserId && w.OtherUserUID == otherUserUid); | ||||
|             ClientPair pair = await _dbContext.ClientPairs.SingleOrDefaultAsync(w => w.UserUID == AuthenticatedUserId && w.OtherUserUID == otherUserUid).ConfigureAwait(false); | ||||
|             if (pair == null) return; | ||||
|  | ||||
|             _logger.LogInformation("User " + AuthenticatedUserId + " changed pause status with " + otherUserUid + " to " + isPaused); | ||||
|             _logger.LogInformation("User {AuthenticatedUserId} changed pause status with {otherUserUid} to {isPaused}", AuthenticatedUserId, otherUserUid, isPaused); | ||||
|             pair.IsPaused = isPaused; | ||||
|             _dbContext.Update(pair); | ||||
|             await _dbContext.SaveChangesAsync(); | ||||
|             var selfCharaIdent = (await _dbContext.Users.SingleAsync(u => u.UID == AuthenticatedUserId)).CharacterIdentification; | ||||
|             var otherCharaIdent = (await _dbContext.Users.SingleAsync(u => u.UID == otherUserUid)).CharacterIdentification; | ||||
|             await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|             var selfCharaIdent = (await _dbContext.Users.SingleAsync(u => u.UID == AuthenticatedUserId).ConfigureAwait(false)).CharacterIdentification; | ||||
|             var otherCharaIdent = (await _dbContext.Users.SingleAsync(u => u.UID == otherUserUid).ConfigureAwait(false)).CharacterIdentification; | ||||
|             var otherEntry = OppositeEntry(otherUserUid); | ||||
|  | ||||
|             await Clients.User(AuthenticatedUserId) | ||||
| @@ -241,7 +241,7 @@ namespace MareSynchronosServer.Hubs | ||||
|                     IsPaused = isPaused, | ||||
|                     IsPausedFromOthers = otherEntry?.IsPaused ?? false, | ||||
|                     IsSynced = otherEntry != null | ||||
|                 }, otherCharaIdent); | ||||
|                 }, otherCharaIdent).ConfigureAwait(false); | ||||
|             if (otherEntry != null) | ||||
|             { | ||||
|                 await Clients.User(otherUserUid).SendAsync(Api.OnUserUpdateClientPairs, new ClientPairDto() | ||||
| @@ -250,7 +250,7 @@ namespace MareSynchronosServer.Hubs | ||||
|                     IsPaused = otherEntry.IsPaused, | ||||
|                     IsPausedFromOthers = isPaused, | ||||
|                     IsSynced = true | ||||
|                 }, selfCharaIdent); | ||||
|                 }, selfCharaIdent).ConfigureAwait(false); | ||||
|             } | ||||
|  | ||||
|             if (isPaused) | ||||
| @@ -269,37 +269,37 @@ namespace MareSynchronosServer.Hubs | ||||
|         { | ||||
|             if (uid == AuthenticatedUserId) return; | ||||
|  | ||||
|             var sender = await _dbContext.Users.SingleAsync(u => u.UID == AuthenticatedUserId); | ||||
|             var otherUser = await _dbContext.Users.SingleOrDefaultAsync(u => u.UID == uid); | ||||
|             var sender = await _dbContext.Users.SingleAsync(u => u.UID == AuthenticatedUserId).ConfigureAwait(false); | ||||
|             var otherUser = await _dbContext.Users.SingleOrDefaultAsync(u => u.UID == uid).ConfigureAwait(false); | ||||
|             if (otherUser == null) return; | ||||
|             _logger.LogInformation("User " + AuthenticatedUserId + " removed " + uid + " from whitelist"); | ||||
|             _logger.LogInformation("User {AuthenticatedUserId} removed {uid} from whitelist", AuthenticatedUserId, uid); | ||||
|             ClientPair wl = | ||||
|                 await _dbContext.ClientPairs.SingleOrDefaultAsync(w => w.User == sender && w.OtherUser == otherUser); | ||||
|                 await _dbContext.ClientPairs.SingleOrDefaultAsync(w => w.User == sender && w.OtherUser == otherUser).ConfigureAwait(false); | ||||
|             if (wl == null) return; | ||||
|             _dbContext.ClientPairs.Remove(wl); | ||||
|             await _dbContext.SaveChangesAsync(); | ||||
|             await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|             var otherEntry = OppositeEntry(uid); | ||||
|             await Clients.User(sender.UID) | ||||
|                 .SendAsync(Api.OnUserUpdateClientPairs, new ClientPairDto() | ||||
|                 { | ||||
|                     OtherUID = otherUser.UID, | ||||
|                     IsRemoved = true | ||||
|                 }, otherUser.CharacterIdentification); | ||||
|                 }, otherUser.CharacterIdentification).ConfigureAwait(false); | ||||
|             if (otherEntry != null) | ||||
|             { | ||||
|                 if (!string.IsNullOrEmpty(otherUser.CharacterIdentification)) | ||||
|                 { | ||||
|                     await Clients.User(sender.UID) | ||||
|                         .SendAsync(Api.OnUserRemoveOnlinePairedPlayer, otherUser.CharacterIdentification); | ||||
|                         .SendAsync(Api.OnUserRemoveOnlinePairedPlayer, otherUser.CharacterIdentification).ConfigureAwait(false); | ||||
|                     await Clients.User(otherUser.UID) | ||||
|                         .SendAsync(Api.OnUserRemoveOnlinePairedPlayer, sender.CharacterIdentification); | ||||
|                         .SendAsync(Api.OnUserRemoveOnlinePairedPlayer, sender.CharacterIdentification).ConfigureAwait(false); | ||||
|                     await Clients.User(otherUser.UID).SendAsync(Api.OnUserUpdateClientPairs, new ClientPairDto() | ||||
|                     { | ||||
|                         OtherUID = sender.UID, | ||||
|                         IsPaused = otherEntry.IsPaused, | ||||
|                         IsPausedFromOthers = false, | ||||
|                         IsSynced = false | ||||
|                     }, sender.CharacterIdentification); | ||||
|                     }, sender.CharacterIdentification).ConfigureAwait(false); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|   | ||||
| @@ -41,15 +41,15 @@ namespace MareSynchronosServer.Hubs | ||||
|  | ||||
|             var userId = Context.User!.Claims.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value; | ||||
|  | ||||
|             _logger.LogInformation("Connection from " + userId + ", CI: " + characterIdentification); | ||||
|             _logger.LogInformation("Connection from {userId}, CI: {characterIdentification}", userId, characterIdentification); | ||||
|  | ||||
|             await Clients.Caller.SendAsync(Api.OnUpdateSystemInfo, _systemInfoService.SystemInfoDto); | ||||
|             await Clients.Caller.SendAsync(Api.OnUpdateSystemInfo, _systemInfoService.SystemInfoDto).ConfigureAwait(false); | ||||
|  | ||||
|             var isBanned = await _dbContext.BannedUsers.AsNoTracking().AnyAsync(u => u.CharacterIdentification == characterIdentification); | ||||
|             var isBanned = await _dbContext.BannedUsers.AsNoTracking().AnyAsync(u => u.CharacterIdentification == characterIdentification).ConfigureAwait(false); | ||||
|  | ||||
|             if (!string.IsNullOrEmpty(userId) && !isBanned && !string.IsNullOrEmpty(characterIdentification)) | ||||
|             { | ||||
|                 var user = (await _dbContext.Users.SingleAsync(u => u.UID == userId)); | ||||
|                 var user = (await _dbContext.Users.SingleAsync(u => u.UID == userId).ConfigureAwait(false)); | ||||
|                 if (!string.IsNullOrEmpty(user.CharacterIdentification) && characterIdentification != user.CharacterIdentification) | ||||
|                 { | ||||
|                     return new ConnectionDto() | ||||
| @@ -64,7 +64,7 @@ namespace MareSynchronosServer.Hubs | ||||
|  | ||||
|                 user.LastLoggedIn = DateTime.UtcNow; | ||||
|                 user.CharacterIdentification = characterIdentification; | ||||
|                 await _dbContext.SaveChangesAsync(); | ||||
|                 await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|                 return new ConnectionDto | ||||
|                 { | ||||
|                     ServerVersion = Api.Version, | ||||
| @@ -82,7 +82,7 @@ namespace MareSynchronosServer.Hubs | ||||
|  | ||||
|         public override Task OnConnectedAsync() | ||||
|         { | ||||
|             _logger.LogInformation("Connection from " + contextAccessor.GetIpAddress()); | ||||
|             _logger.LogInformation("Connection from {ip}", contextAccessor.GetIpAddress()); | ||||
|             MareMetrics.Connections.Inc(); | ||||
|             return base.OnConnectedAsync(); | ||||
|         } | ||||
| @@ -91,12 +91,12 @@ namespace MareSynchronosServer.Hubs | ||||
|         { | ||||
|             MareMetrics.Connections.Dec(); | ||||
|  | ||||
|             var user = await _dbContext.Users.SingleOrDefaultAsync(u => u.UID == AuthenticatedUserId); | ||||
|             var user = await _dbContext.Users.SingleOrDefaultAsync(u => u.UID == AuthenticatedUserId).ConfigureAwait(false); | ||||
|             if (user != null && !string.IsNullOrEmpty(user.CharacterIdentification)) | ||||
|             { | ||||
|                 MareMetrics.AuthorizedConnections.Dec(); | ||||
|  | ||||
|                 _logger.LogInformation("Disconnect from " + AuthenticatedUserId); | ||||
|                 _logger.LogInformation("Disconnect from {id}", AuthenticatedUserId); | ||||
|  | ||||
|                 var query = | ||||
|                     from userToOther in _dbContext.ClientPairs | ||||
| @@ -114,17 +114,17 @@ namespace MareSynchronosServer.Hubs | ||||
|                         && !userToOther.IsPaused | ||||
|                         && !otherToUser.IsPaused | ||||
|                     select otherToUser.UserUID; | ||||
|                 var otherEntries = await query.ToListAsync(); | ||||
|                 var otherEntries = await query.ToListAsync().ConfigureAwait(false); | ||||
|  | ||||
|                 await Clients.Users(otherEntries).SendAsync(Api.OnUserRemoveOnlinePairedPlayer, user.CharacterIdentification); | ||||
|                 await Clients.Users(otherEntries).SendAsync(Api.OnUserRemoveOnlinePairedPlayer, user.CharacterIdentification).ConfigureAwait(false); | ||||
|                                  | ||||
|                 _dbContext.RemoveRange(_dbContext.Files.Where(f => !f.Uploaded && f.UploaderUID == user.UID)); | ||||
|  | ||||
|                 user.CharacterIdentification = null; | ||||
|                 await _dbContext.SaveChangesAsync(); | ||||
|                 await _dbContext.SaveChangesAsync().ConfigureAwait(false); | ||||
|             } | ||||
|  | ||||
|             await base.OnDisconnectedAsync(exception); | ||||
|             await base.OnDisconnectedAsync(exception).ConfigureAwait(false); | ||||
|         } | ||||
|  | ||||
|         public static string GenerateRandomString(int length, string allowableChars = null) | ||||
| @@ -149,7 +149,7 @@ namespace MareSynchronosServer.Hubs | ||||
|  | ||||
|         protected async Task<Models.User> GetAuthenticatedUserUntrackedAsync() | ||||
|         { | ||||
|             return await _dbContext.Users.AsNoTrackingWithIdentityResolution().SingleAsync(u => u.UID == AuthenticatedUserId); | ||||
|             return await _dbContext.Users.AsNoTrackingWithIdentityResolution().SingleAsync(u => u.UID == AuthenticatedUserId).ConfigureAwait(false); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -14,6 +14,10 @@ | ||||
|     <PackageReference Include="EFCore.NamingConventions" Version="6.0.0" /> | ||||
|     <PackageReference Include="Karambolo.Extensions.Logging.File" Version="3.3.1" /> | ||||
|     <PackageReference Include="lz4net" Version="1.0.15.93" /> | ||||
|     <PackageReference Include="Meziantou.Analyzer" Version="1.0.715"> | ||||
|       <PrivateAssets>all</PrivateAssets> | ||||
|       <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> | ||||
|     </PackageReference> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="6.0.8" /> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="6.0.8" /> | ||||
|     <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="6.0.8" /> | ||||
|   | ||||
| @@ -40,7 +40,7 @@ public class SystemInfoService : IHostedService, IDisposable | ||||
|     private void PushSystemInfo(object state) | ||||
|     { | ||||
|         ThreadPool.GetAvailableThreads(out int workerThreads, out int ioThreads); | ||||
|         _logger.LogInformation($"ThreadPool: {workerThreads} workers available, {ioThreads} IO workers available"); | ||||
|         _logger.LogInformation("ThreadPool: {workerThreads} workers available, {ioThreads} IO workers available", workerThreads, ioThreads); | ||||
|         MareMetrics.AvailableWorkerThreads.Set(workerThreads); | ||||
|         MareMetrics.AvailableIOWorkerThreads.Set(ioThreads); | ||||
|  | ||||
|   | ||||
| @@ -37,25 +37,25 @@ public class SignalRLimitFilter : IHubFilter | ||||
|             HttpVerb = "ws", | ||||
|             ClientId = invocationContext.Context.UserIdentifier | ||||
|         }; | ||||
|         foreach (var rule in await _processor.GetMatchingRulesAsync(client)) | ||||
|         foreach (var rule in await _processor.GetMatchingRulesAsync(client).ConfigureAwait(false)) | ||||
|         { | ||||
|             var counter = await _processor.ProcessRequestAsync(client, rule); | ||||
|             var counter = await _processor.ProcessRequestAsync(client, rule).ConfigureAwait(false); | ||||
|             if (counter.Count > rule.Limit) | ||||
|             { | ||||
|                 var authUserId = invocationContext.Context.User.Claims?.SingleOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value ?? "Unknown"; | ||||
|                 var retry = counter.Timestamp.RetryAfterFrom(rule); | ||||
|                 logger.LogWarning($"Method rate limit triggered from {ip}/{authUserId}: {invocationContext.HubMethodName}"); | ||||
|                 logger.LogWarning("Method rate limit triggered from {ip}/{authUserId}: {method}", ip, authUserId, invocationContext.HubMethodName); | ||||
|                 throw new HubException($"call limit {retry}"); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return await next(invocationContext); | ||||
|         return await next(invocationContext).ConfigureAwait(false); | ||||
|     } | ||||
|  | ||||
|     // Optional method | ||||
|     public async Task OnConnectedAsync(HubLifetimeContext context, Func<HubLifetimeContext, Task> next) | ||||
|     { | ||||
|         await ConnectionLimiterSemaphore.WaitAsync(); | ||||
|         await ConnectionLimiterSemaphore.WaitAsync().ConfigureAwait(false); | ||||
|         var ip = accessor.GetIpAddress(); | ||||
|         var client = new ClientRequestIdentity | ||||
|         { | ||||
| @@ -63,13 +63,13 @@ public class SignalRLimitFilter : IHubFilter | ||||
|             Path = "Connect", | ||||
|             HttpVerb = "ws", | ||||
|         }; | ||||
|         foreach (var rule in await _processor.GetMatchingRulesAsync(client)) | ||||
|         foreach (var rule in await _processor.GetMatchingRulesAsync(client).ConfigureAwait(false)) | ||||
|         { | ||||
|             var counter = await _processor.ProcessRequestAsync(client, rule); | ||||
|             var counter = await _processor.ProcessRequestAsync(client, rule).ConfigureAwait(false); | ||||
|             if (counter.Count > rule.Limit) | ||||
|             { | ||||
|                 var retry = counter.Timestamp.RetryAfterFrom(rule); | ||||
|                 logger.LogWarning($"Connection rate limit triggered from {ip}"); | ||||
|                 logger.LogWarning("Connection rate limit triggered from {ip}", ip); | ||||
|                 ConnectionLimiterSemaphore.Release(); | ||||
|                 throw new HubException($"Connection rate limit {retry}"); | ||||
|             } | ||||
| @@ -77,8 +77,8 @@ public class SignalRLimitFilter : IHubFilter | ||||
|  | ||||
|         try | ||||
|         { | ||||
|             await Task.Delay(250); | ||||
|             await next(context); | ||||
|             await Task.Delay(250).ConfigureAwait(false); | ||||
|             await next(context).ConfigureAwait(false); | ||||
|         } | ||||
|         catch (Exception ex) | ||||
|         { | ||||
| @@ -93,7 +93,7 @@ public class SignalRLimitFilter : IHubFilter | ||||
|     public async Task OnDisconnectedAsync( | ||||
|         HubLifetimeContext context, Exception exception, Func<HubLifetimeContext, Exception, Task> next) | ||||
|     { | ||||
|         await DisconnectLimiterSemaphore.WaitAsync(); | ||||
|         await DisconnectLimiterSemaphore.WaitAsync().ConfigureAwait(false); | ||||
|         if (exception != null) | ||||
|         { | ||||
|             logger.LogWarning(exception, "InitialException on OnDisconnectedAsync"); | ||||
| @@ -101,8 +101,8 @@ public class SignalRLimitFilter : IHubFilter | ||||
|  | ||||
|         try | ||||
|         { | ||||
|             await next(context, exception); | ||||
|             await Task.Delay(250); | ||||
|             await next(context, exception).ConfigureAwait(false); | ||||
|             await Task.Delay(250).ConfigureAwait(false); | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Stanley Dimant
					Stanley Dimant