/// <summary> /// Refreshes invalid token /// </summary> /// <param name="user">Login</param> /// <param name="session">In case of successful token refresh, will contain session information for multiplayer</param> /// <returns>Returns the status of the new token request (Success, Failure, etc.)</returns> public static LoginResult GetNewToken(SessionToken currentsession, out SessionToken session) { session = new SessionToken(); try { string result = ""; string json_request = "{ \"accessToken\": \"" + JsonEncode(currentsession.ID) + "\", \"clientToken\": \"" + JsonEncode(currentsession.ClientID) + "\", \"selectedProfile\": { \"id\": \"" + JsonEncode(currentsession.PlayerID) + "\", \"name\": \"" + JsonEncode(currentsession.PlayerName) + "\" } }"; int code = DoHTTPSPost("authserver.mojang.com", "/refresh", json_request, ref result); if (code == 200) { if (result == null) { return(LoginResult.NullError); } else { Json.JSONData loginResponse = Json.ParseJson(result); if (loginResponse.Properties.ContainsKey("accessToken") && loginResponse.Properties.ContainsKey("selectedProfile") && loginResponse.Properties["selectedProfile"].Properties.ContainsKey("id") && loginResponse.Properties["selectedProfile"].Properties.ContainsKey("name")) { session.ID = loginResponse.Properties["accessToken"].StringValue; session.PlayerID = loginResponse.Properties["selectedProfile"].Properties["id"].StringValue; session.PlayerName = loginResponse.Properties["selectedProfile"].Properties["name"].StringValue; return(LoginResult.Success); } else { return(LoginResult.InvalidResponse); } } } else if (code == 403 && result.Contains("InvalidToken")) { return(LoginResult.InvalidToken); } else { ConsoleIO.WriteLineFormatted("§8Got error code from server while refreshing authentication: " + code); return(LoginResult.OtherError); } } catch { return(LoginResult.OtherError); } }
/// <summary> /// Check if user own Minecraft by access token /// </summary> /// <param name="accessToken"></param> /// <returns>True if the user own the game</returns> public bool UserHasGame(string accessToken) { var request = new ProxiedWebRequest(ownership); request.Headers.Add("Authorization", string.Format("Bearer {0}", accessToken)); var response = request.Get(); if (Settings.DebugMessages) { ConsoleIO.WriteLine(response.ToString()); } string jsonString = response.Body; Json.JSONData json = Json.ParseJson(jsonString); return(json.Properties["items"].DataArray.Count > 0); }
/// <summary> /// Retrieve available Realms worlds of a player and display them /// </summary> /// <param name="username">Player Minecraft username</param> /// <param name="uuid">Player UUID</param> /// <param name="accesstoken">Access token</param> /// <returns>List of ID of available Realms worlds</returns> public static List <string> RealmsListWorlds(string username, string uuid, string accesstoken) { string result = ""; string cookies = String.Format("sid=token:{0}:{1};user={2};version={3}", accesstoken, uuid, username, Program.MCHighestVersion); DoHTTPSGet("pc.realms.minecraft.net", "/worlds", cookies, ref result); Json.JSONData realmsWorlds = Json.ParseJson(result); List <string> realmsWorldsResult = new List <string>(); // Store world ID if (realmsWorlds.Properties.ContainsKey("servers") && realmsWorlds.Properties["servers"].Type == Json.JSONData.DataType.Array && realmsWorlds.Properties["servers"].DataArray.Count > 0) { List <string> availableWorlds = new List <string>(); // Store string to print int index = 0; foreach (Json.JSONData realmsServer in realmsWorlds.Properties["servers"].DataArray) { if (realmsServer.Properties.ContainsKey("name") && realmsServer.Properties.ContainsKey("owner") && realmsServer.Properties.ContainsKey("id") && realmsServer.Properties.ContainsKey("expired")) { if (realmsServer.Properties["expired"].StringValue == "false") { availableWorlds.Add(String.Format("[{0}] {2} ({3}) - {1}", index++, realmsServer.Properties["id"].StringValue, realmsServer.Properties["name"].StringValue, realmsServer.Properties["owner"].StringValue)); realmsWorldsResult.Add(realmsServer.Properties["id"].StringValue); } } } if (availableWorlds.Count > 0) { Translations.WriteLine("mcc.realms_available"); foreach (var world in availableWorlds) { ConsoleIO.WriteLine(world); } Translations.WriteLine("mcc.realms_join"); } } return(realmsWorldsResult); }
/// <summary> /// Login to Minecraft using the XSTS token and user hash obtained before /// </summary> /// <param name="userHash"></param> /// <param name="xstsToken"></param> /// <returns></returns> public string LoginWithXbox(string userHash, string xstsToken) { var request = new ProxiedWebRequest(loginWithXbox); request.Accept = "application/json"; string payload = "{\"identityToken\": \"XBL3.0 x=" + userHash + ";" + xstsToken + "\"}"; var response = request.Post("application/json", payload); if (Settings.DebugMessages) { ConsoleIO.WriteLine(response.ToString()); } string jsonString = response.Body; Json.JSONData json = Json.ParseJson(jsonString); return(json.Properties["access_token"].StringValue); }
/// <summary> /// Xbox Live Authenticate /// </summary> /// <param name="loginResponse"></param> /// <returns></returns> public XblAuthenticateResponse XblAuthenticate(UserLoginResponse loginResponse) { var request = new ProxiedWebRequest(xbl); request.UserAgent = userAgent; request.Accept = "application/json"; request.Headers.Add("x-xbl-contract-version", "0"); string payload = "{" + "\"Properties\": {" + "\"AuthMethod\": \"RPS\"," + "\"SiteName\": \"user.auth.xboxlive.com\"," + "\"RpsTicket\": \"" + loginResponse.AccessToken + "\"" + "}," + "\"RelyingParty\": \"http://auth.xboxlive.com\"," + "\"TokenType\": \"JWT\"" + "}"; var response = request.Post("application/json", payload); if (Settings.DebugMessages) { ConsoleIO.WriteLine(response.ToString()); } if (response.StatusCode == 200) { string jsonString = response.Body; //Console.WriteLine(jsonString); Json.JSONData json = Json.ParseJson(jsonString); string token = json.Properties["Token"].StringValue; string userHash = json.Properties["DisplayClaims"].Properties["xui"].DataArray[0].Properties["uhs"].StringValue; return(new XblAuthenticateResponse() { Token = token, UserHash = userHash }); } else { throw new Exception("XBL Authentication failed"); } }
/// <summary> /// Generate ItemType.cs from Minecraft registries.json /// </summary> /// <param name="registriesJsonFile">path to registries.json</param> /// <param name="outputEnum">output path for ItemTypes.cs</param> /// <remarks>java -cp minecraft_server.jar net.minecraft.data.Main --reports</remarks> public static void JsonToClass(string registriesJsonFile, string outputEnum) { HashSet <int> itemIds = new HashSet <int>(); Json.JSONData registries = Json.ParseJson(File.ReadAllText(registriesJsonFile)); Json.JSONData itemRegistry = registries.Properties["minecraft:item"].Properties["entries"]; List <string> outFile = new List <string>(); outFile.AddRange(new[] { "namespace MinecraftClient.Inventory", "{", " public enum ItemType", " {" }); foreach (KeyValuePair <string, Json.JSONData> item in itemRegistry.Properties) { int itemId = int.Parse(item.Value.Properties["protocol_id"].StringValue); //minecraft:item_name => ItemName string itemName = String.Concat( item.Key.Replace("minecraft:", "") .Split('_') .Select(word => char.ToUpper(word[0]) + word.Substring(1)) ); if (itemIds.Contains(itemId)) { throw new InvalidDataException("Duplicate item ID " + itemId + "!?"); } outFile.Add(" " + itemName + " = " + itemId + ','); } outFile.AddRange(new[] { " }", "}" }); File.WriteAllLines(outputEnum, outFile); }
public UserProfile GetUserProfile(string accessToken) { var request = new ProxiedWebRequest(profile); request.Headers.Add("Authorization", string.Format("Bearer {0}", accessToken)); var response = request.Get(); if (Settings.DebugMessages) { ConsoleIO.WriteLine(response.ToString()); } string jsonString = response.Body; Json.JSONData json = Json.ParseJson(jsonString); return(new UserProfile() { UUID = json.Properties["id"].StringValue, UserName = json.Properties["name"].StringValue }); }
/// <summary> /// Get the server address of a Realms world by world ID /// </summary> /// <param name="worldId">The world ID of the Realms world</param> /// <param name="username">Player Minecraft username</param> /// <param name="uuid">Player UUID</param> /// <param name="accesstoken">Access token</param> /// <returns>Server address (host:port) or empty string if failure</returns> public static string GetRealmsWorldServerAddress(string worldId, string username, string uuid, string accesstoken) { try { string result = ""; string cookies = String.Format("sid=token:{0}:{1};user={2};version={3}", accesstoken, uuid, username, Program.MCHighestVersion); int statusCode = DoHTTPSGet("pc.realms.minecraft.net", "/worlds/v1/" + worldId + "/join/pc", cookies, ref result); if (statusCode == 200) { Json.JSONData serverAddress = Json.ParseJson(result); if (serverAddress.Properties.ContainsKey("address")) { return(serverAddress.Properties["address"].StringValue); } else { Translations.WriteLine("error.realms.ip_error"); return(""); } } else { Translations.WriteLine("error.realms.access_denied"); return(""); } } catch (Exception e) { ConsoleIO.WriteLineFormatted("§8" + e.GetType().ToString() + ": " + e.Message); if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8" + e.StackTrace); } return(""); } }
/// <summary> /// Allows to login to a premium Minecraft account using the Yggdrasil authentication scheme. /// </summary> /// <param name="user">Login</param> /// <param name="pass">Password</param> /// <param name="session">In case of successful login, will contain session information for multiplayer</param> /// <returns>Returns the status of the login (Success, Failure, etc.)</returns> public static LoginResult GetLogin(string user, string pass, out SessionToken session) { session = new SessionToken() { ClientID = Guid.NewGuid().ToString().Replace("-", "") }; try { string result = ""; string json_request = "{\"agent\": { \"name\": \"Minecraft\", \"version\": 1 }, \"username\": \"" + JsonEncode(user) + "\", \"password\": \"" + JsonEncode(pass) + "\", \"clientToken\": \"" + JsonEncode(session.ClientID) + "\" }"; int code = DoHTTPSPost("authserver.mojang.com", "/authenticate", json_request, ref result); if (code == 200) { if (result.Contains("availableProfiles\":[]}")) { return(LoginResult.NotPremium); } else { Json.JSONData loginResponse = Json.ParseJson(result); if (loginResponse.Properties.ContainsKey("accessToken") && loginResponse.Properties.ContainsKey("selectedProfile") && loginResponse.Properties["selectedProfile"].Properties.ContainsKey("id") && loginResponse.Properties["selectedProfile"].Properties.ContainsKey("name")) { session.ID = loginResponse.Properties["accessToken"].StringValue; session.PlayerID = loginResponse.Properties["selectedProfile"].Properties["id"].StringValue; session.PlayerName = loginResponse.Properties["selectedProfile"].Properties["name"].StringValue; return(LoginResult.Success); } else { return(LoginResult.InvalidResponse); } } } else if (code == 403) { if (result.Contains("UserMigratedException")) { return(LoginResult.AccountMigrated); } else { return(LoginResult.WrongPassword); } } else if (code == 503) { return(LoginResult.ServiceUnavailable); } else { ConsoleIO.WriteLineFormatted("§8Got error code from server: " + code); return(LoginResult.OtherError); } } catch (System.Security.Authentication.AuthenticationException e) { if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8" + e.ToString()); } return(LoginResult.SSLError); } catch (System.IO.IOException e) { if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8" + e.ToString()); } if (e.Message.Contains("authentication")) { return(LoginResult.SSLError); } else { return(LoginResult.OtherError); } } catch (Exception e) { if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8" + e.ToString()); } return(LoginResult.OtherError); } }
/// <summary> /// Reads cache file and loads SessionTokens into SessionCache. /// </summary> /// <returns>True if data is successfully loaded</returns> private static bool LoadFromDisk() { //Grab sessions in the Minecraft directory if (File.Exists(SessionCacheFileMinecraft)) { if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8Loading Minecraft profiles: " + Path.GetFileName(SessionCacheFileMinecraft)); } Json.JSONData mcSession = new Json.JSONData(Json.JSONData.DataType.String); try { mcSession = Json.ParseJson(File.ReadAllText(SessionCacheFileMinecraft)); } catch (IOException) { /* Failed to read file from disk -- ignoring */ } if (mcSession.Type == Json.JSONData.DataType.Object && mcSession.Properties.ContainsKey("clientToken") && mcSession.Properties.ContainsKey("authenticationDatabase")) { Guid temp; string clientID = mcSession.Properties["clientToken"].StringValue.Replace("-", ""); Dictionary <string, Json.JSONData> sessionItems = mcSession.Properties["authenticationDatabase"].Properties; foreach (string key in sessionItems.Keys) { if (Guid.TryParseExact(key, "N", out temp)) { Dictionary <string, Json.JSONData> sessionItem = sessionItems[key].Properties; if (sessionItem.ContainsKey("displayName") && sessionItem.ContainsKey("accessToken") && sessionItem.ContainsKey("username") && sessionItem.ContainsKey("uuid")) { string login = sessionItem["username"].StringValue.ToLower(); try { SessionToken session = SessionToken.FromString(String.Join(",", sessionItem["accessToken"].StringValue, sessionItem["displayName"].StringValue, sessionItem["uuid"].StringValue.Replace("-", ""), clientID )); if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8Loaded session: " + login + ':' + session.ID); } sessions[login] = session; } catch (InvalidDataException) { /* Not a valid session */ } } } } } } //Serialized session cache file in binary format if (File.Exists(SessionCacheFileSerialized)) { if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8Converting session cache from disk: " + SessionCacheFileSerialized); } try { using (FileStream fs = new FileStream(SessionCacheFileSerialized, FileMode.Open, FileAccess.Read, FileShare.Read)) { Dictionary <string, SessionToken> sessionsTemp = (Dictionary <string, SessionToken>)formatter.Deserialize(fs); foreach (KeyValuePair <string, SessionToken> item in sessionsTemp) { if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8Loaded session: " + item.Key + ':' + item.Value.ID); } sessions[item.Key] = item.Value; } } } catch (IOException ex) { ConsoleIO.WriteLineFormatted("§8Failed to read session cache from disk: " + ex.Message); } catch (SerializationException ex2) { ConsoleIO.WriteLineFormatted("§8Got malformed data while reading session cache from disk: " + ex2.Message); } } //User-editable session cache file in text format if (File.Exists(SessionCacheFilePlaintext)) { if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8Loading session cache from disk: " + SessionCacheFilePlaintext); } foreach (string line in File.ReadAllLines(SessionCacheFilePlaintext)) { if (!line.Trim().StartsWith("#")) { string[] keyValue = line.Split('='); if (keyValue.Length == 2) { try { string login = keyValue[0].ToLower(); SessionToken session = SessionToken.FromString(keyValue[1]); if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8Loaded session: " + login + ':' + session.ID); } sessions[login] = session; } catch (InvalidDataException e) { if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8Ignoring session token string '" + keyValue[1] + "': " + e.Message); } } } else if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8Ignoring invalid session token line: " + line); } } } } return(sessions.Count > 0); }
private static string JSONData2String(Json.JSONData data, string colorcode, List <string> links) { string extra_result = ""; switch (data.Type) { case Json.JSONData.DataType.Object: if (data.Properties.ContainsKey("clickEvent") && links != null) { Json.JSONData clickEvent = data.Properties["clickEvent"]; if (clickEvent.Properties.ContainsKey("action") && clickEvent.Properties.ContainsKey("value") && clickEvent.Properties["action"].StringValue == "open_url" && !String.IsNullOrEmpty(clickEvent.Properties["value"].StringValue)) { links.Add(clickEvent.Properties["value"].StringValue); } } if (data.Properties.ContainsKey("extra")) { Json.JSONData[] extras = data.Properties["extra"].DataArray.ToArray(); foreach (Json.JSONData item in extras) { extra_result = extra_result + JSONData2String(item, colorcode, links) + "§r"; } } if (data.Properties.ContainsKey("text")) { return(colorcode + JSONData2String(data.Properties["text"], colorcode, links) + extra_result); } else if (data.Properties.ContainsKey("translate")) { List <string> using_data = new List <string>(); if (data.Properties.ContainsKey("using") && !data.Properties.ContainsKey("with")) { data.Properties["with"] = data.Properties["using"]; } if (data.Properties.ContainsKey("with")) { Json.JSONData[] array = data.Properties["with"].DataArray.ToArray(); for (int i = 0; i < array.Length; i++) { using_data.Add(JSONData2String(array[i], colorcode, links)); } } return(colorcode + JSONData2String(data.Properties["translate"], "", links) + extra_result); } else { return(extra_result); } case Json.JSONData.DataType.Array: string result = ""; foreach (Json.JSONData item in data.DataArray) { result += JSONData2String(item, colorcode, links); } return(result); case Json.JSONData.DataType.String: return(colorcode + data.StringValue); } return(""); }
/// <summary> /// Request new images from the Spotlight API and return image urls (Single Attempt) /// </summary> /// <param name="maxres">Force maximum image resolution. Otherwise, current main monitor screen resolution is used</param> /// <param name="portrait">Null = Auto detect from current main monitor resolution, True = portrait, False = landscape.</param> /// <param name="locale">Null = Auto detect from current system, or specify xx-XX value format such as en-US</param> /// <returns>List of images</returns> /// <exception cref="System.Net.WebException">An exception is thrown if the request fails</exception> /// <exception cref="System.IO.InvalidDataException">An exception is thrown if the JSON data is invalid</exception> private static SpotlightImage[] GetImageUrlsSingleAttempt(bool maxres = false, bool?portrait = null, string locale = null) { List <SpotlightImage> images = new List <SpotlightImage>(); Json.JSONData imageData = Json.ParseJson(PerformApiRequest(maxres, locale)); if (portrait == null) { portrait = Screen.PrimaryScreen.Bounds.Height > Screen.PrimaryScreen.Bounds.Width; } if (imageData.Type == Json.JSONData.DataType.Object && imageData.Properties.ContainsKey("batchrsp")) { imageData = imageData.Properties["batchrsp"]; if (imageData.Type == Json.JSONData.DataType.Object && imageData.Properties.ContainsKey("items")) { if (!imageData.Properties.ContainsKey("ver") || imageData.Properties["ver"].StringValue != "1.0") { Console.Error.WriteLine("SpotlightAPI: Unknown or missing API response version. Errors may occur."); } imageData = imageData.Properties["items"]; if (imageData.Type == Json.JSONData.DataType.Array) { foreach (Json.JSONData element in imageData.DataArray) { if (element.Type == Json.JSONData.DataType.Object && element.Properties.ContainsKey("item")) { Json.JSONData item = element.Properties["item"]; if (item.Type == Json.JSONData.DataType.String) { item = Json.ParseJson(item.StringValue); } if (item.Type == Json.JSONData.DataType.Object && item.Properties.ContainsKey("ad") && item.Properties["ad"].Type == Json.JSONData.DataType.Object) { item = item.Properties["ad"]; string title; Json.JSONData titleObj = item.Properties.ContainsKey("title_text") ? item.Properties["title_text"] : null; if (titleObj != null && titleObj.Type == Json.JSONData.DataType.Object && titleObj.Properties.ContainsKey("tx")) { title = titleObj.Properties["tx"].StringValue; } else { title = null; } string copyright; Json.JSONData copyrightObj = item.Properties.ContainsKey("copyright_text") ? item.Properties["copyright_text"] : null; if (copyrightObj != null && copyrightObj.Type == Json.JSONData.DataType.Object && copyrightObj.Properties.ContainsKey("tx")) { copyright = copyrightObj.Properties["tx"].StringValue; } else { copyright = null; } string urlField = portrait.Value ? "image_fullscreen_001_portrait" : "image_fullscreen_001_landscape"; if (item.Properties.ContainsKey(urlField) && item.Properties[urlField].Type == Json.JSONData.DataType.Object) { item = item.Properties[urlField]; if (item.Properties.ContainsKey("u") && item.Properties.ContainsKey("sha256") && item.Properties.ContainsKey("fileSize") && item.Properties["u"].Type == Json.JSONData.DataType.String && item.Properties["sha256"].Type == Json.JSONData.DataType.String && item.Properties["fileSize"].Type == Json.JSONData.DataType.String) { int fileSizeParsed = 0; if (int.TryParse(item.Properties["fileSize"].StringValue, out fileSizeParsed)) { SpotlightImage image = new SpotlightImage() { Uri = item.Properties["u"].StringValue, Sha256 = item.Properties["sha256"].StringValue, FileSize = fileSizeParsed, Title = title, Copyright = copyright }; try { System.Convert.FromBase64String(image.Sha256); } catch { image.Sha256 = null; } if (!String.IsNullOrEmpty(image.Uri) && !String.IsNullOrEmpty(image.Sha256) && image.FileSize > 0) { images.Add(image); } else { Console.Error.WriteLine("SpotlightAPI: Ignoring image with empty uri, hash and/or file size less or equal to 0."); } } else { Console.Error.WriteLine("SpotlightAPI: Ignoring image with invalid, non-number file size."); } } else { Console.Error.WriteLine("SpotlightAPI: Ignoring item image uri with missing 'u', 'sha256' and/or 'fileSize' field(s)."); } } else { Console.Error.WriteLine("SpotlightAPI: Ignoring item image with missing uri."); } } else { Console.Error.WriteLine("SpotlightAPI: Ignoring item with missing 'ad' object."); } } else { Console.Error.WriteLine("SpotlightAPI: Ignoring non-object item while parsing 'batchrsp/items' field in JSON API response."); } } } else { throw new InvalidDataException("SpotlightAPI: 'batchrsp/items' field in JSON API response is not an array."); } } else { throw new InvalidDataException("SpotlightAPI: Missing 'batchrsp/items' field in JSON API response." + (locale != null ? " Locale '" + locale + "' may be invalid." : "")); } } else { throw new InvalidDataException("SpotlightAPI: API did not return a 'batchrsp' JSON object."); } return(images.ToArray()); }
/// <summary> /// Create a new ForgeInfo from the given data. /// </summary> /// <param name="data">The modinfo JSON tag.</param> /// <param name="fmlVersion">Forge protocol version</param> internal ForgeInfo(Json.JSONData data, FMLVersion fmlVersion) { this.Mods = new List <ForgeMod>(); this.Version = fmlVersion; switch (fmlVersion) { case FMLVersion.FML: // Example ModInfo for Minecraft 1.12 and lower (FML) // "modinfo": { // "type": "FML", // "modList": [{ // "modid": "mcp", // "version": "9.05" // }, { // "modid": "FML", // "version": "8.0.99.99" // }, { // "modid": "Forge", // "version": "11.14.3.1512" // }, { // "modid": "rpcraft", // "version": "Beta 1.3 - 1.8.0" // }] // } foreach (Json.JSONData mod in data.Properties["modList"].DataArray) { String modid = mod.Properties["modid"].StringValue; String modversion = mod.Properties["version"].StringValue; this.Mods.Add(new ForgeMod(modid, modversion)); } break; case FMLVersion.FML2: // Example ModInfo for Minecraft 1.13 and greater (FML2) // "forgeData": { // "channels": [{ // "res": "minecraft:unregister", // "version": "FML2", // "required": true // }, { // "res": "minecraft:register", // "version": "FML2", // "required": true // }], // "mods": [{ // "modId": "minecraft", // "modmarker": "1.15.2" // }, { // "modId": "forge", // "modmarker": "ANY" // }, { // "modId": "rats", // "modmarker": "5.3.2" // }, { // "modId": "citadel", // "modmarker": "1.1.11" // }], // "fmlNetworkVersion": 2 // } foreach (Json.JSONData mod in data.Properties["mods"].DataArray) { String modid = mod.Properties["modId"].StringValue; String modmarker = mod.Properties["modmarker"].StringValue; this.Mods.Add(new ForgeMod(modid, modmarker)); } break; default: throw new NotImplementedException("FMLVersion '" + fmlVersion + "' not implemented!"); } }
/// <summary> /// Generate mapping from Minecraft blocks.json /// </summary> /// <param name="blocksJsonFile">path to blocks.json</param> /// <param name="outputClass">output path for blocks.cs</param> /// <param name="outputEnum">output path for material.cs</param> /// <remarks>java -cp minecraft_server.jar net.minecraft.data.Main --reports</remarks> /// <returns>state => block name mappings</returns> public static void JsonToClass(string blocksJsonFile, string outputClass, string outputEnum = null) { HashSet <int> knownStates = new HashSet <int>(); Dictionary <string, HashSet <int> > blocks = new Dictionary <string, HashSet <int> >(); Json.JSONData palette = Json.ParseJson(File.ReadAllText(blocksJsonFile, Encoding.UTF8)); foreach (KeyValuePair <string, Json.JSONData> item in palette.Properties) { //minecraft:item_name => ItemName string blockType = String.Concat( item.Key.Replace("minecraft:", "") .Split('_') .Select(word => char.ToUpper(word[0]) + word.Substring(1)) ); if (blocks.ContainsKey(blockType)) { throw new InvalidDataException("Duplicate block type " + blockType + "!?"); } blocks[blockType] = new HashSet <int>(); foreach (Json.JSONData state in item.Value.Properties["states"].DataArray) { int id = int.Parse(state.Properties["id"].StringValue); if (knownStates.Contains(id)) { throw new InvalidDataException("Duplicate state id " + id + "!?"); } knownStates.Add(id); blocks[blockType].Add(id); } } HashSet <string> materials = new HashSet <string>(); List <string> outFile = new List <string>(); outFile.AddRange(new[] { "using System;", "using System.Collections.Generic;", "", "namespace MinecraftClient.Mapping.BlockPalettes", "{", " public class PaletteXXX : PaletteMapping", " {", " private static Dictionary<int, Material> materials = new Dictionary<int, Material>();", "", " static PaletteXXX()", " {", }); foreach (KeyValuePair <string, HashSet <int> > blockType in blocks) { if (blockType.Value.Count > 0) { List <int> idList = blockType.Value.ToList(); string materialName = blockType.Key; materials.Add(materialName); if (idList.Count > 1) { idList.Sort(); Queue <int> idQueue = new Queue <int>(idList); while (idQueue.Count > 0) { int startValue = idQueue.Dequeue(); int endValue = startValue; while (idQueue.Count > 0 && idQueue.Peek() == endValue + 1) { endValue = idQueue.Dequeue(); } if (endValue > startValue) { outFile.Add(" for (int i = " + startValue + "; i <= " + endValue + "; i++)"); outFile.Add(" materials[i] = Material." + materialName + ";"); } else { outFile.Add(" materials[" + startValue + "] = Material." + materialName + ";"); } } } else { outFile.Add(" materials[" + idList[0] + "] = Material." + materialName + ";"); } } else { throw new InvalidDataException("No state id for block type " + blockType.Key + "!?"); } } outFile.AddRange(new[] { " }", "", " protected override Dictionary<int, Material> GetDict()", " {", " return materials;", " }", " }", "}" }); File.WriteAllLines(outputClass, outFile); if (outputEnum != null) { outFile = new List <string>(); outFile.AddRange(new[] { "namespace MinecraftClient.Mapping", "{", " public enum Material", " {" }); foreach (string material in materials) { outFile.Add(" " + material + ","); } outFile.AddRange(new[] { " }", "}" }); File.WriteAllLines(outputEnum, outFile); } }
/// <summary> /// Login using Mojang account. Will be outdated after account migration /// </summary> /// <param name="user"></param> /// <param name="pass"></param> /// <param name="session"></param> /// <returns></returns> private static LoginResult MojangLogin(string user, string pass, out SessionToken session) { session = new SessionToken() { ClientID = Guid.NewGuid().ToString().Replace("-", "") }; try { string result = ""; int code = 0; if (Settings.AccountType == AccountType.MCLeaks) { string json_request = "{\"token\": \"" + user + "\"}"; code = DoHTTPSPost("auth.mcleaks.net", "/v1/redeem", json_request, ref result); if (code == 200) { result = result.Split('\n')[1]; Json.JSONData loginResponse = Json.ParseJson(result); if (loginResponse.Properties["success"].StringValue == "true") { session.ID = loginResponse.Properties["result"].Properties["session"].StringValue; session.PlayerName = loginResponse.Properties["result"].Properties["mcname"].StringValue; string newResult = ""; DoHTTPSGet("api.mojang.com", "/users/profiles/minecraft/" + session.PlayerName, "", ref newResult); Json.JSONData UUIDJSON = Json.ParseJson(newResult); session.PlayerID = UUIDJSON.Properties["id"].StringValue; return(LoginResult.Success); } else { return(LoginResult.WrongPassword); } } else { return(LoginResult.OtherError); } } else { string json_request = "{\"agent\": { \"name\": \"Minecraft\", \"version\": 1 }, \"username\": \"" + JsonEncode(user) + "\", \"password\": \"" + JsonEncode(pass) + "\", \"clientToken\": \"" + JsonEncode(session.ClientID) + "\" }"; if (Settings.AccountType == AccountType.TheAltening) { code = DoHTTPPost("authserver.thealtening.com", "/authenticate", json_request, ref result); result = result.Split('\n')[1]; } else { code = DoHTTPSPost("authserver.mojang.com", "/authenticate", json_request, ref result); } if (code == 200) { if (result.Contains("availableProfiles\":[]}")) { return(LoginResult.NotPremium); } else { Json.JSONData loginResponse = Json.ParseJson(result); if (loginResponse.Properties.ContainsKey("accessToken") && loginResponse.Properties.ContainsKey("selectedProfile") && loginResponse.Properties["selectedProfile"].Properties.ContainsKey("id") && loginResponse.Properties["selectedProfile"].Properties.ContainsKey("name")) { session.ID = loginResponse.Properties["accessToken"].StringValue; session.PlayerID = loginResponse.Properties["selectedProfile"].Properties["id"].StringValue; session.PlayerName = loginResponse.Properties["selectedProfile"].Properties["name"].StringValue; return(LoginResult.Success); } else { return(LoginResult.InvalidResponse); } } } else if (code == 403) { if (result.Contains("UserMigratedException")) { return(LoginResult.AccountMigrated); } else { return(LoginResult.WrongPassword); } } else if (code == 503) { return(LoginResult.ServiceUnavailable); } else { ConsoleIO.WriteLineFormatted(Translations.Get("error.http_code", code)); return(LoginResult.OtherError); } } } catch (System.Security.Authentication.AuthenticationException e) { if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8" + e.ToString()); } return(LoginResult.SSLError); } catch (System.IO.IOException e) { if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8" + e.ToString()); } if (e.Message.Contains("authentication")) { return(LoginResult.SSLError); } else { return(LoginResult.OtherError); } } catch (Exception e) { if (Settings.DebugMessages) { ConsoleIO.WriteLineFormatted("§8" + e.ToString()); } return(LoginResult.OtherError); } }