using System; using System.Collections.Generic; using System.Net; /// !!! ATTENTION !!! /// By using these functions you agree to the ToS of the Mojang API. /// You should note that all public APIs are rate limited so you are expected to cache the results. /// This is currently set at 600 requests per 10 minutes but this may change. /// !!! ATTENTION !!! namespace MinecraftClient.Protocol { /// /// Provides methods to easily interact with the Mojang API. /// public static class MojangAPI { // Initialize webclient for all functions private static readonly WebClient wc = new WebClient(); // Can be removed in newer C# versions. // Replace with DateTimeOffset.FromUnixTimeMilliseconds() /// /// Converts a Unix time to a normal Datetime /// /// A unix timestamp as double /// Datetime of unix timestamp private static DateTime unixTimeStampToDateTime(double unixTimeStamp) { // Unix timestamp is seconds past epoch DateTime dateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc); dateTime = dateTime.AddMilliseconds(unixTimeStamp).ToLocalTime(); return dateTime; } // Can be removed in newer C# versions. /// /// Obtain the UUID of a Player through its name /// /// Playername /// UUID as string public static string NameToUuid(string name) { try { return Json.ParseJson(wc.DownloadString("https://api.mojang.com/users/profiles/minecraft/" + name)).Properties["id"].StringValue; } catch (Exception) { return string.Empty; } } /// /// Obtain the Name of a player through its UUID /// /// UUID of a player /// Players UUID public static string UuidToCurrentName(string uuid) { // Perform web request try { var nameChanges = Json.ParseJson(wc.DownloadString("https://api.mojang.com/user/profiles/" + uuid + "/names")).DataArray; // Names are sorted from past to most recent. We need to get the last name in the list return nameChanges[nameChanges.Count - 1].Properties["name"].StringValue; } catch (Exception) { return string.Empty; } } /// /// Get the name history from a UUID /// /// UUID of a player /// Name history, as a dictionary public static Dictionary UuidToNameHistory(string uuid) { Dictionary tempDict = new Dictionary(); List jsonDataList; // Perform web request try { jsonDataList = Json.ParseJson(wc.DownloadString("https://api.mojang.com/user/profiles/" + uuid + "/names")).DataArray; } catch (Exception) { return tempDict; } foreach (Json.JSONData jsonData in jsonDataList) { if (jsonData.Properties.Count > 1) { // Time is saved as long in the Unix format. // Convert it to normal time, before adding it to the dictionary. // // !! FromUnixTimeMilliseconds does not exist in the current version. !! // DateTimeOffset creationDate = DateTimeOffset.FromUnixTimeMilliseconds(Convert.ToInt64(jsonData.Properties["changedToAt"].StringValue)); // // Workaround for converting Unix time to normal time DateTimeOffset creationDate = unixTimeStampToDateTime(Convert.ToDouble(jsonData.Properties["changedToAt"].StringValue)); // Add Keyvaluepair to dict. tempDict.Add(jsonData.Properties["name"].StringValue, creationDate.DateTime); } // The first entry does not contain a change date. else if (jsonData.Properties.Count > 0) { // Add an undefined time to it. tempDict.Add(jsonData.Properties["name"].StringValue, new DateTime()); } } return tempDict; } /// /// Get the Mojang API status /// /// Dictionary of the Mojang services public static Dictionary GetMojangServiceStatus() { Dictionary tempDict = new Dictionary(); List jsonDataList; // Perform web request try { jsonDataList = Json.ParseJson(wc.DownloadString("https://status.mojang.com/check")).DataArray; } catch (Exception) { return tempDict; } // Convert JSONData to string and parse it to a dictionary. foreach (Json.JSONData jsonData in jsonDataList) { if (jsonData.Properties.Count > 0) { foreach (KeyValuePair keyValuePair in jsonData.Properties) { // Service name to status tempDict.Add(keyValuePair.Key, keyValuePair.Value.StringValue); } } } return tempDict; } } }