private async Task UpdateAsync(CocApi.Model.ClanWar clanWar, bool downloadBadges = false) { Logger.LogTrace("Running UpdateAsync..."); foreach (ClanOption clanOption in _settings.Value.Clans.Where(c => clanWar.Clans.Any(cw => c.Tag == cw.Key))) { if (clanOption.Folder == null || clanWar.Clans.FirstOrDefault(c => c.Value.Tag == clanOption.Tag).Value == null) { continue; } await _semaphoreSlim.WaitAsync(); try { string clanFolder = Path.Combine(Program.ClansFolder, clanOption.Folder, "clan"); string opponentFolder = Path.Combine(Program.ClansFolder, clanOption.Folder, "enemy"); Logger.LogTrace("Creating clan folders..."); Directory.CreateDirectory(clanFolder); Directory.CreateDirectory(opponentFolder); string clanStatsFolder = Path.Combine(clanFolder, "stats"); string opponentStatsFolder = Path.Combine(opponentFolder, "stats"); Logger.LogTrace("Creating stats folders..."); Directory.CreateDirectory(clanStatsFolder); Directory.CreateDirectory(opponentStatsFolder); Logger.LogTrace("Writing stats to files..."); File.WriteAllText(Path.Combine(clanFolder, "attacks.txt"), clanWar.Attacks.Count.ToString()); File.WriteAllText(Path.Combine(clanFolder, "endTime.txt"), clanWar.EndTime.ToString()); File.WriteAllText(Path.Combine(clanFolder, "preparationStartTime.txt"), clanWar.PreparationStartTime.ToString()); File.WriteAllText(Path.Combine(clanFolder, "serverExpiration.txt"), clanWar.ServerExpiration.ToString()); File.WriteAllText(Path.Combine(clanFolder, "startTime.txt"), clanWar.StartTime.ToString()); File.WriteAllText(Path.Combine(clanFolder, "state.txt"), clanWar.State.ToString()); File.WriteAllText(Path.Combine(clanFolder, "warTag.txt"), clanWar.WarTag); Update(clanWar, clanWar.Clans.First(c => c.Key == clanOption.Tag).Value, clanFolder, clanStatsFolder); Update(clanWar, clanWar.Clans.First(c => c.Key != clanOption.Tag).Value, opponentFolder, opponentStatsFolder); if (downloadBadges) { await DownloadBadgesAsync(clanWar.Clans.First(c => c.Key == clanOption.Tag).Value, clanFolder); await DownloadBadgesAsync(clanWar.Clans.First(c => c.Key != clanOption.Tag).Value, opponentFolder); } } catch (Exception e) { Logger.LogError(e, "An exception occured at UpdateAsync"); throw; } finally { _semaphoreSlim.Release(); } } }
private void Update(CocApi.Model.ClanWar clanWar, CocApi.Model.WarClan warClan, string clanFolder, string statsFolder) { Logger.LogTrace("Running update..."); try { File.WriteAllText(Path.Combine(clanFolder, "name.txt"), warClan.Name); File.WriteAllText(Path.Combine(clanFolder, "attacks.txt"), warClan.Attacks.ToString()); File.WriteAllText(Path.Combine(clanFolder, "clanLevel.txt"), warClan.ClanLevel.ToString()); File.WriteAllText(Path.Combine(clanFolder, "clanProfileUrl.txt"), warClan.ClanProfileUrl); File.WriteAllText(Path.Combine(clanFolder, "destructionPercentage.txt"), FormatNumber(warClan.DestructionPercentage)); File.WriteAllText(Path.Combine(clanFolder, "members.txt"), warClan.Members.Count.ToString()); File.WriteAllText(Path.Combine(clanFolder, "result.txt"), warClan.Result.ToString()); File.WriteAllText(Path.Combine(clanFolder, "stars.txt"), warClan.Stars.ToString()); File.WriteAllText(Path.Combine(clanFolder, "tag.txt"), warClan.Tag.ToString()); Logger.LogTrace("Created various stats files."); List <CocApi.Model.ClanWarAttack> bestClanAttacks = new(); CocApi.Model.ClanWarAttack[] clanAttacks = clanWar.Attacks.Where(a => a.AttackerClanTag == warClan.Tag && a.DefenderTag != null).ToArray(); var grouped = clanAttacks.GroupBy(a => a.DefenderTag); foreach (IGrouping <string, CocApi.Model.ClanWarAttack> group in grouped) { bestClanAttacks.Add(group .OrderByDescending(a => a.Stars) .ThenByDescending(a => a.DestructionPercentage) .ThenByDescending(a => a.Duration) .First()); } for (int i = _settings.Value.MinTownhall; i < _settings.Value.MaxTownhall + 1; i++) { File.WriteAllText(Path.Combine(statsFolder, $"{i} three.txt"), bestClanAttacks.Count(a => a.DefenderTownHall == i && a.Stars == 3).ToString()); File.WriteAllText(Path.Combine(statsFolder, $"{i} two.txt"), bestClanAttacks.Count(a => a.DefenderTownHall == i && a.Stars == 2).ToString()); File.WriteAllText(Path.Combine(statsFolder, $"{i} one.txt"), bestClanAttacks.Count(a => a.DefenderTownHall == i && a.Stars == 1).ToString()); int[] attackerThs = new int[] { i--, i, i++ }; foreach (int attackerTh in attackerThs) { if (attackerTh < _settings.Value.MinTownhall || attackerTh > _settings.Value.MaxTownhall) { continue; } CocApi.Model.ClanWarAttack[] scope = clanAttacks.Where(a => a.AttackerTownHall == attackerTh && a.DefenderTownHall == i).ToArray(); CocApi.Model.ClanWarAttack[] scopeBest = bestClanAttacks.Where(a => a.AttackerTownHall == attackerTh && a.DefenderTownHall == i).ToArray(); int tries = scope.Length; int threes = scopeBest.Count(a => a.Stars == 3); if (tries == 0) { File.WriteAllText(Path.Combine(statsFolder, $"{attackerTh}v{i}P.txt"), "0"); } else { float percent = (float)threes / tries * 100; string s = FormatNumber(percent); File.WriteAllText(Path.Combine(statsFolder, $"{attackerTh}v{i}P.txt"), s); } File.WriteAllText(Path.Combine(statsFolder, $"{attackerTh}v{i}Three.txt"), threes.ToString()); File.WriteAllText(Path.Combine(statsFolder, $"{attackerTh}v{i}Tries.txt"), tries.ToString()); } } Logger.LogTrace("Done writing files to stats."); } catch (Exception err) { Logger.LogError(err, "An error occured at {0}", nameof(Update)); } }