1

How to list all minecraft profiles by launcher_profiles.json file?

I tried to use the site json2csharp.com, but unfortunately when it generated the class ready code he has returned all the profiles as if it were also a class.

for example: I used this simple code minecraft profile file ...

{
"profiles": {
  "1.7.10": {
     "name": "1.7.10",
     "lastVersionId": "1.7.10"
   }
  },
  "selectedProfile": "1.7.10"
}

But when I send the site to convert C# it returns this:

public class __invalid_type__1710
{
   public string name { get; set; }
    public string lastVersionId { get; set; }
}

public class Profiles
{
    public __invalid_type__1710 __invalid_name__1.7.10 { get; set; }
}

public class RootObject
{
    public Profiles profiles { get; set; }
    public string selectedProfile { get; set; }
}

See for yourself: Json2CSharp

Have you any way I can read the launcher_profiles.json file minecraft using Newtonsoft.Json.Linq?

IAsyncResult
  • 136
  • 1
  • 13

3 Answers3

3

While useful in many cases, json2csharp.com is not foolproof. As you've seen, it does not handle cases where key names are dynamic or otherwise cannot be converted into valid C# identifiers. In these cases you will need to make manual adjustments to the generated classes. For example, you can use a Dictionary<string, Profile> in place of a static class to handle the dynamic keys of the profiles object.

Define your classes like this:

public class RootObject
{
    public Dictionary<string, Profile> profiles { get; set; }
    public string selectedProfile { get; set; }
}

public class Profile
{
    public string name { get; set; }
    public string lastVersionId { get; set; }
}

You can then deserialize into the RootObject class using either JavaScriptSerializer or Json.Net, whichever you prefer.

Here is a fiddle using Json.Net: https://dotnetfiddle.net/ZlEK63

Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
1

So the problem may be that the launcher_profiles.json is not really kosher JSON.

Put this into Json2CSharp to see what I mean:

{
"profiles": [
  {
     "name": "1.7.10",
     "lastVersionId": "1.7.10"
   }
  ],
  "selectedProfile": "1.7.10"
}

The difference here is that I've redefined the profiles node to correctly represent a collection (array) that's mapped to a generic list in C#.

You may need to manually parse that file as JSON.Net or other options will not be able to work with the invalid json format.

S. Brentson
  • 454
  • 4
  • 7
  • 1
    You can parse this with the [JObject](http://www.newtonsoft.com/json/help/html/t_newtonsoft_json_linq_jobject.htm) classes, which give a dynamic sort of access vs. a fixed class structure. – crashmstr Feb 29 '16 at 21:11
  • Right. Which is one such tool that might facilitate a semi-manual parsing. Thing is, the profiles "collection" will always be parsed as uniquely named properties due to how mine craft builds this file. It's not as clear when you're just seeing one such named profile. But consider if we added a profile named "2.09.5"? Ignoring that neither are valid c# property names, the resulting object wouldn't be very predictable to write code against. – S. Brentson Feb 29 '16 at 21:25
1

I generally don't work with the Linq versions of the Json.Net library, but I've come up with a simple example of how to get all of the names of the profiles (you can't serialize to a class with the given format).

class Program
{
    //Add another "profile" to show this works with more than one
    private static String json = "{ \"profiles\": { \"1.7.10\": { \"name\": \"1.7.10\", \"lastVersionId\": \"1.7.10\" }, \"1.7.11\": { \"name\": \"1.7.11\", \"lastVersionId\": \"1.7.11\" } }, \"selectedProfile\": \"1.7.10\" }";

    static void Main(string[] args)
    {
        //Parse to JObject
        var obj = Newtonsoft.Json.Linq.JObject.Parse(json);

        foreach (var profile in obj["profiles"])
        {
            foreach (var child in profile.Children())
            {
                Console.WriteLine(child["name"]);
            }
        }
    }
}
crashmstr
  • 28,043
  • 9
  • 61
  • 79