using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; namespace ArkData { /// /// The container for the data. /// public partial class DataContainer { /// /// Instantiates the DataContainer and parses all the user-data files /// /// The async task context containing the resulting container. public static async Task CreateAsync(string playerFileFolder, string tribeFileFolder) { IEnumerable playerFiles = null; IEnumerable tribeFiles = null; if (Directory.Exists(playerFileFolder)) { playerFiles = Directory.GetFiles(playerFileFolder).Where(f => Path.GetFileNameWithoutExtension(f).StartsWith(DataFileDetails.PlayerFilePrefix) && Path.GetFileNameWithoutExtension(f).EndsWith(DataFileDetails.PlayerFileSuffix) && Path.GetExtension(f).Equals(DataFileDetails.PlayerFileExtension)); } if (Directory.Exists(tribeFileFolder)) { tribeFiles = Directory.GetFiles(tribeFileFolder).Where(f => Path.GetFileNameWithoutExtension(f).StartsWith(DataFileDetails.TribeFilePrefix) && Path.GetFileNameWithoutExtension(f).EndsWith(DataFileDetails.TribeFileSuffix) && Path.GetExtension(f).Equals(DataFileDetails.TribeFileExtension)); } var container = new DataContainer(); if (playerFiles != null) { foreach (var file in playerFiles) container.Players.Add(await Parser.ParsePlayerAsync(file)); } if (tribeFiles != null) { foreach (var file in tribeFiles) container.Tribes.Add(await Parser.ParseTribeAsync(file)); } container.LinkPlayerTribe(); return container; } /// /// Loads the profile data for all users from the steam service /// /// The async task context. public async Task LoadSteamAsync(string apiKey, int steamUpdateInterval = 0) { const int MAX_STEAM_IDS = 100; // need to make multiple calls of 100 steam id's. var lastSteamUpdateUtc = DateTime.UtcNow; var startIndex = 0; var playerSteamIds = Players.Where(p => p.LastPlatformUpdateUtc.AddMinutes(steamUpdateInterval) < DateTime.UtcNow).Select(p => p.PlayerId); while (true) { // check if the start index has exceeded the Players list count. if (startIndex >= playerSteamIds.Count()) break; // get the number of steam ids to read. int steamIdsCount = Math.Min(MAX_STEAM_IDS, playerSteamIds.Count() - startIndex); // get a comma delimited list of the steam ids to process var builder = string.Join(",", playerSteamIds, startIndex, steamIdsCount); using (var client = new HttpClient()) { client.BaseAddress = new System.Uri("https://api.steampowered.com/"); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var response = await client.GetAsync(string.Format("ISteamUser/GetPlayerSummaries/v0002/?key={0}&steamids={1}", apiKey, builder)); if (response.IsSuccessStatusCode) using (var reader = new StreamReader(await response.Content.ReadAsStreamAsync())) { LinkSteamProfiles(await reader.ReadToEndAsync(), lastSteamUpdateUtc); } else throw new System.Net.WebException("The Steam API request was unsuccessful. Are you using a valid key?"); } startIndex += steamIdsCount; } SteamLoaded = true; return lastSteamUpdateUtc; } /// /// Fetches the player server status. Can only be done after fetching Steam player data. /// /// The IP of the server. /// The port of the server. /// The async task context. public Task LoadOnlinePlayersAsync(string ipString, int port) { if (SteamLoaded) return Task.Run(() => { LinkOnlinePlayers(ipString, port); }); else throw new System.Exception("The Steam user data should be loaded before the server status can be checked."); } } }