Advertisement
4lender

Untitled

Feb 17th, 2025
157
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.47 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Text.Json.Serialization;
  6. using System.Text.Json;
  7. using System.Threading.Tasks;
  8. using System.Collections.Concurrent;
  9. using System.Diagnostics;
  10.  
  11. namespace eft_dma_radar.Source.Tarkov
  12. {
  13.     public class PlayerProfileAPI
  14.     {
  15.         private static readonly HttpClient _httpClient = new HttpClient();
  16.         private static readonly ConcurrentDictionary<string, PlayerStats> _playerStatsCache = new ConcurrentDictionary<string, PlayerStats>();
  17.  
  18.         private static readonly List<(int Level, int Experience)> _levelChart = new()
  19.         {
  20.             (1, 0), (2, 1000), (3, 4017), (4, 8432), (5, 14256), (6, 21477), (7, 30023), (8, 39936),
  21.             (9, 51204), (10, 63723), (11, 77563), (12, 92713), (13, 111881), (14, 134674), (15, 161139),
  22.             (16, 191417), (17, 225194), (18, 262366), (19, 302484), (20, 345751), (21, 391649), (22, 440444),
  23.             (23, 492366), (24, 547896), (25, 609066), (26, 679255), (27, 755444), (28, 837672), (29, 925976),
  24.             (30, 1020396), (31, 1120969), (32, 1227735), (33, 1344260), (34, 1470605), (35, 1606833),
  25.             (36, 1759965), (37, 1923579), (38, 2097740), (39, 2282513), (40, 2477961), (41, 2684149),
  26.             (42, 2901143), (43, 3132824), (44, 3379281), (45, 3640603), (46, 3929436), (47, 4233995),
  27.             (48, 4554372), (49, 4890662), (50, 5242956), (51, 5611348), (52, 5995931), (53, 6402287),
  28.             (54, 6830542), (55, 7280825), (56, 7753260), (57, 8247975), (58, 8765097), (59, 9304752),
  29.             (60, 9876880), (61, 10512365), (62, 11193911), (63, 11929835), (64, 12727177), (65, 13615989),
  30.             (66, 14626588), (67, 15864243), (68, 17555001), (69, 19926895), (70, 22926895), (71, 26526895),
  31.             (72, 30726895), (73, 35526895), (74, 40926895), (75, 46926895), (76, 53526895), (77, 60726895),
  32.             (78, 69126895), (79, 81126895)
  33.         };
  34.  
  35.         private static int GetPlayerLevel(int experience) => _levelChart.LastOrDefault(x => experience >= x.Experience).Level;
  36.  
  37.         private static bool IsValidAccountId(string accountId) => !string.IsNullOrEmpty(accountId) && accountId != "0" && long.TryParse(accountId, out _);
  38.  
  39.         public static async Task<PlayerStats> GetPlayerStatsAsync(string accountId)
  40.         {
  41.             if (!IsValidAccountId(accountId))
  42.             {
  43.                 Program.Log($"[GetPlayerStatsAsync] => Invalid player ID: {accountId}");
  44.                 return new PlayerStats { Nickname = "Invalid ID" };
  45.             }
  46.  
  47.             if (_playerStatsCache.TryGetValue(accountId, out var cached))
  48.                 return cached;
  49.  
  50.             try
  51.             {
  52.                 return await FetchPlayerStats(accountId);
  53.             }
  54.             catch
  55.             {
  56.                 if (await ReloadPlayerProfileAsync(accountId))
  57.                 {
  58.                     try
  59.                     {
  60.                         return await FetchPlayerStats(accountId);
  61.                     }
  62.                     catch (Exception ex)
  63.                     {
  64.                         Program.Log($"[GetPlayerStatsAsync] => Error fetching player stats '{accountId}' after reload: {ex.Message}");
  65.                         return new PlayerStats { Nickname = "Human" };
  66.                     }
  67.                 }
  68.                 return new PlayerStats { Nickname = "Human" };
  69.             }
  70.         }
  71.  
  72.         private static async Task<PlayerStats> FetchPlayerStats(string accountId)
  73.         {
  74.             var url = $"https://eft-api.tech/api/profile/{accountId}";
  75.             var response = await _httpClient.GetAsync(url);
  76.             response.EnsureSuccessStatusCode();
  77.  
  78.             var jsonResponse = await response.Content.ReadAsStringAsync();
  79.             var jsonDocument = JsonDocument.Parse(jsonResponse);
  80.             var root = jsonDocument.RootElement;
  81.  
  82.             if (!root.TryGetProperty("data", out var dataElement))
  83.             {
  84.                 Program.Log($"[FetchPlayerStats] => No 'data' field in response for AccountID: {accountId}");
  85.                 return new PlayerStats { Nickname = "Human" };
  86.             }
  87.  
  88.             var playerData = JsonSerializer.Deserialize<PlayerProfile>(dataElement.GetRawText());
  89.  
  90.             if (playerData?.info?.nickname == null)
  91.                 return new PlayerStats { Nickname = "Human" };
  92.  
  93.             var stats = CreatePlayerStats(playerData);
  94.             _playerStatsCache[accountId] = stats;
  95.             Program.Log($"[FetchPlayerStats] => Retrieved player data - AccountID: {accountId}, Nickname: {stats.Nickname}");
  96.             return stats;
  97.         }
  98.  
  99.         public static async Task<bool> ReloadPlayerProfileAsync(string accountId)
  100.         {
  101.             if (!IsValidAccountId(accountId))
  102.             {
  103.                 Program.Log($"[ReloadPlayerProfileAsync] => Invalid player ID.");
  104.                 return false;
  105.             }
  106.  
  107.             try
  108.             {
  109.                 var url = $"https://tarkov.dev/players/regular/{accountId}";
  110.                 var response = await _httpClient.GetAsync(url);
  111.                 response.EnsureSuccessStatusCode();
  112.  
  113.                 return true;
  114.             }
  115.             catch (Exception ex)
  116.             {
  117.                 Program.Log($"[ReloadPlayerProfileAsync] => Error reloading profile: {ex.Message}");
  118.                 return false;
  119.             }
  120.         }
  121.  
  122.         private static PlayerStats CreatePlayerStats(PlayerProfile profile)
  123.         {
  124.             if (profile?.pmcStats?.eft?.overAllCounters?.Items is null)
  125.             {
  126.                 return new PlayerStats
  127.                 {
  128.                     Nickname = profile?.info?.nickname ?? "Human",
  129.                     KDRatio = 0,
  130.                     HoursPlayed = 0,
  131.                     Level = profile?.info?.experience is not null ? GetPlayerLevel(profile.info.experience) : 0
  132.                 };
  133.             }
  134.  
  135.             var pmcStats = profile.pmcStats.eft.overAllCounters.Items;
  136.             var kills = pmcStats.FirstOrDefault(x => x.Key.Contains("Kills"))?.Value ?? 0;
  137.             var deaths = pmcStats.FirstOrDefault(x => x.Key.Contains("Deaths"))?.Value ?? 1;
  138.  
  139.             return new PlayerStats
  140.             {
  141.                 Nickname = profile.info.nickname,
  142.                 KDRatio = MathF.Round((float)kills / deaths, 2),
  143.                 HoursPlayed = profile.pmcStats.eft.totalInGameTime / 3600,
  144.                 Level = GetPlayerLevel(profile.info.experience)
  145.             };
  146.         }
  147.     }
  148.  
  149.     public class PlayerProfile
  150.     {
  151.         public int aid { get; set; }
  152.         public PlayerInfo info { get; set; }
  153.         public PMCStats pmcStats { get; set; }
  154.     }
  155.  
  156.     public class PlayerInfo
  157.     {
  158.         public string nickname { get; set; }
  159.         public int experience { get; set; }
  160.     }
  161.  
  162.     public class PMCStats
  163.     {
  164.         public PMCDetail eft { get; set; }
  165.     }
  166.  
  167.     public class PMCDetail
  168.     {
  169.         public int totalInGameTime { get; set; }
  170.         public PMCOverAllCounters overAllCounters { get; set; }
  171.     }
  172.  
  173.     public class PMCOverAllCounters
  174.     {
  175.         public List<PMCStatItem> Items { get; set; }
  176.     }
  177.  
  178.     public class PMCStatItem
  179.     {
  180.         public string[] Key { get; set; }
  181.         public int Value { get; set; }
  182.     }
  183.  
  184.     public class PlayerStats
  185.     {
  186.         public string Nickname { get; set; }
  187.         public float KDRatio { get; set; }
  188.         public int HoursPlayed { get; set; }
  189.         public int Level { get; set; }
  190.     }
  191. }
  192.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement