using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.Extensions.Logging; using TOOHUCardAPI.Data.Enums; using TOOHUCardAPI.Data.Models; using TOOHUCardAPI.Data.Repositories; using TOOHUCardAPI.DTO.RankData; namespace TOOHUCardAPI.Data.Services { public class RankService { private readonly ILogger _logger; private readonly RankRepository _rankRepository; private readonly UserRepository _userRepository; private readonly UserService _userService; private readonly StoreService _storeService; public RankService(ILogger logger, RankRepository rankRepository, UserRepository userRepository, UserService userService, StoreService storeService) { _logger = logger; _rankRepository = rankRepository; _userRepository = userRepository; _userService = userService; _storeService = storeService; } private async Task AwardPointsForEntry(long steamid, RankEntry entry, List allEntries) { int bonus = AppSettings.DefaultRankBonus; int index = allEntries.FindIndex(i => i.Id == entry.Id)+1; if (index <= 0) { index = allEntries.Count + 1; } switch (index) { case <= 4: bonus = 500 - (index - 1) * 100; break; case <= 9: bonus = 170 - (index - 5) * 10; break; case <=15: bonus = 125 - (index - 10) * 5; break; case <= 25: bonus = 96 - (index - 16) * 4; break; case <= 50: bonus = 58 - (index - 26) * 2; break; } await _storeService.AwardPoints(steamid, bonus, $"reached rank index {index}"); } public async Task> GetRankEntries(RankType rankType) { var rankEntries = await _rankRepository.GetRankEntries(rankType); _logger.LogInformation("Got rank entries for {RankType}", rankType.ToString()); return rankEntries.Select(entry => entry.ToRankEntryDTO()).ToList(); } public async Task UploadRankEntry(RankEntryDTO entry) { List towersUsed = entry.Cards.Select(kv => new RankTowerEntry { TowerKey = kv.Key, EncodedData = kv.Value }).ToList(); RankEntry toUpload = new RankEntry { RankType = RankTypeExtensions.ParseRankType(entry.RankType), User = await _userRepository.GetUser(entry.SteamId), Version = entry.Version, Wave = entry.Wave, Damage = entry.Damage, TowersUsed = towersUsed, UpdateTime = DateTime.Now }; var previousEntry = await _rankRepository.GetRankEntry(toUpload.User.SteamId, toUpload.RankType); bool shouldPushNew = true; if (previousEntry != null) { if (previousEntry.Wave < toUpload.Wave) { await ResetRank(toUpload.User.SteamId, toUpload.RankType); } else if (previousEntry.Wave == toUpload.Wave && previousEntry.Damage < toUpload.Damage) { await ResetRank(toUpload.User.SteamId, toUpload.RankType); } else { shouldPushNew = false; } } if (shouldPushNew) { toUpload = await _rankRepository.InsertRankEntry(toUpload); } List allEntries = (await _rankRepository.GetRankEntries(toUpload.RankType)).ToList(); await _userService.UpdateUserAccountDetails(entry.SteamId, entry.UserId, entry.Username); await _userService.UpdateUserMaxWave(entry.SteamId, entry.Wave, toUpload.RankType); await AwardPointsForEntry(entry.SteamId, toUpload, allEntries); _logger.LogInformation("Uploaded a rank entry for {SteamId} on ranking type {RankType}", entry.SteamId, toUpload.RankType.ToString()); } public async Task ResetRank(long steamid, RankType rankType) { RankEntry entry = await _rankRepository.GetRankEntry(steamid, rankType); await _rankRepository.DeleteRankEntry(entry); _logger.LogInformation("Reset rank entry for {SteamId} on ranking type {RankType}", steamid, rankType.ToString()); } } }