using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Reflection; using System.Text; namespace Prime31 { // Token: 0x02000010 RID: 16 public class Json { // Token: 0x0600005F RID: 95 RVA: 0x00004A54 File Offset: 0x00002C54 public static object decode(string json) { object result; if (Json.useSimpleJson) { result = SimpleJson.decode(json); } else { object obj = Json.Deserializer.deserialize(json); if (obj == null) { Utils.logObject("Something went wrong deserializing the json. We got a null return. Here is the json we tried to deserialize: " + json); } result = obj; } return result; } // Token: 0x06000060 RID: 96 RVA: 0x00004AA0 File Offset: 0x00002CA0 public static T decode(string json, string rootElement = null) where T : new() { T result; if (Json.useSimpleJson) { result = SimpleJson.decode(json, rootElement); } else { result = (T)((object)Json.ObjectDecoder.decode(json, rootElement)); } return result; } // Token: 0x06000061 RID: 97 RVA: 0x00004AD8 File Offset: 0x00002CD8 public static T decodeObject(object jsonObject, string rootElement = null) where T : new() { return SimpleJson.decodeObject(jsonObject, rootElement); } // Token: 0x06000062 RID: 98 RVA: 0x00004AF4 File Offset: 0x00002CF4 public static string encode(object obj) { string text = (!Json.useSimpleJson) ? Json.Serializer.serialize(obj) : SimpleJson.encode(obj); if (text == null) { Utils.logObject("Something went wrong serializing the object. We got a null return. Here is the object we tried to deserialize: "); Utils.logObject(obj); } return text; } // Token: 0x06000063 RID: 99 RVA: 0x00004B40 File Offset: 0x00002D40 public static object jsonDecode(string json) { return Json.decode(json); } // Token: 0x06000064 RID: 100 RVA: 0x00004B5C File Offset: 0x00002D5C public static string jsonEncode(object obj) { string text = Json.Serializer.serialize(obj); if (text == null) { Utils.logObject("Something went wrong serializing the object. We got a null return. Here is the object we tried to deserialize: "); Utils.logObject(obj); } return text; } // Token: 0x04000024 RID: 36 public static bool useSimpleJson; // Token: 0x02000011 RID: 17 internal class ObjectDecoder { // Token: 0x06000066 RID: 102 RVA: 0x00004B9C File Offset: 0x00002D9C public static object decode(string json, string rootElement = null) where T : new() { object obj = Json.decode(json); object result; if (obj == null) { result = null; } else { result = new Json.ObjectDecoder().decode(obj, rootElement); } return result; } // Token: 0x06000067 RID: 103 RVA: 0x00004BD4 File Offset: 0x00002DD4 private object decode(object decodedJsonObject, string rootElement = null) where T : new() { if (rootElement != null) { IDictionary dictionary = decodedJsonObject as IDictionary; if (dictionary == null) { Utils.logObject(string.Concat(new object[] { "A rootElement was requested (", rootElement, ") but the json did not decode to a Dictionary. It decoded to: ", decodedJsonObject })); return null; } if (!dictionary.Contains(rootElement)) { Utils.logObject("A rootElement was requested (" + rootElement + ") but does not exist in the decoded Dictionary"); return null; } decodedJsonObject = dictionary[rootElement]; } Type type = typeof(T); IList list = null; object result; if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>)) { list = (Activator.CreateInstance() as IList); type = list.GetType().GetGenericArguments()[0]; if (!(decodedJsonObject is IList) || !decodedJsonObject.GetType().IsGenericType) { Utils.logObject("A List was required but the json did not decode to a List. It decoded to: " + decodedJsonObject); result = null; } else { IEnumerator enumerator = ((IList)decodedJsonObject).GetEnumerator(); try { while (enumerator.MoveNext()) { object obj = enumerator.Current; Dictionary dictionary2 = (Dictionary)obj; if (dictionary2 == null) { Utils.logObject("Aborted populating List because the json did not decode to a List of Dictionaries"); return list; } list.Add(this.createAndPopulateObjectFromDictionary(type, dictionary2)); } } finally { IDisposable disposable; if ((disposable = (enumerator as IDisposable)) != null) { disposable.Dispose(); } } result = list; } } else { result = this.createAndPopulateObjectFromDictionary(type, decodedJsonObject as Dictionary); } return result; } // Token: 0x06000068 RID: 104 RVA: 0x00004D78 File Offset: 0x00002F78 private Dictionary> getMemberInfoForObject(object obj) { if (this._memberInfo == null) { this._memberInfo = Json.ObjectDecoder.getMembersWithSetters(obj); } return this._memberInfo; } // Token: 0x06000069 RID: 105 RVA: 0x00004DAC File Offset: 0x00002FAC private static Dictionary> getMembersWithSetters(object obj) { Dictionary> dictionary = new Dictionary>(); FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i = 0; i < fields.Length; i++) { FieldInfo fieldInfo = fields[i]; if (fieldInfo.FieldType.Namespace.StartsWith("System")) { FieldInfo theInfo = fieldInfo; Type theFieldType = fieldInfo.FieldType; dictionary[fieldInfo.Name] = delegate(object ownerObject, object val) { theInfo.SetValue(ownerObject, Convert.ChangeType(val, theFieldType)); }; } } foreach (PropertyInfo propertyInfo in obj.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { if (propertyInfo.PropertyType.Namespace.StartsWith("System")) { if (propertyInfo.CanWrite && propertyInfo.GetSetMethod(true) != null) { PropertyInfo theInfo = propertyInfo; Type thePropertyType = propertyInfo.PropertyType; dictionary[propertyInfo.Name] = delegate(object ownerObject, object val) { theInfo.SetValue(ownerObject, Convert.ChangeType(val, thePropertyType), null); }; } } } return dictionary; } // Token: 0x0600006A RID: 106 RVA: 0x00004EEC File Offset: 0x000030EC public object createAndPopulateObjectFromDictionary(Type objectType, Dictionary dict) { object obj = Activator.CreateInstance(objectType); Dictionary> memberInfoForObject = this.getMemberInfoForObject(obj); Dictionary.KeyCollection keys = dict.Keys; foreach (string key in keys) { if (memberInfoForObject.ContainsKey(key)) { try { memberInfoForObject[key](obj, dict[key]); } catch (Exception obj2) { Utils.logObject(obj2); } } } return obj; } // Token: 0x04000025 RID: 37 private Dictionary> _memberInfo; } // Token: 0x02000012 RID: 18 internal class Deserializer { // Token: 0x0600006B RID: 107 RVA: 0x00004FEF File Offset: 0x000031EF private Deserializer(string json) { this.charArray = json.ToCharArray(); } // Token: 0x0600006C RID: 108 RVA: 0x00005004 File Offset: 0x00003204 public static object deserialize(string json) { object result; if (json != null) { Json.Deserializer deserializer = new Json.Deserializer(json); result = deserializer.deserialize(); } else { result = null; } return result; } // Token: 0x0600006D RID: 109 RVA: 0x00005038 File Offset: 0x00003238 private object deserialize() { int num = 0; return this.parseValue(this.charArray, ref num); } // Token: 0x0600006E RID: 110 RVA: 0x00005060 File Offset: 0x00003260 protected object parseValue(char[] json, ref int index) { switch (this.lookAhead(json, index)) { case Json.Deserializer.JsonToken.CurlyOpen: return this.parseObject(json, ref index); case Json.Deserializer.JsonToken.SquaredOpen: return this.parseArray(json, ref index); case Json.Deserializer.JsonToken.String: return this.parseString(json, ref index); case Json.Deserializer.JsonToken.Number: return this.parseNumber(json, ref index); case Json.Deserializer.JsonToken.True: this.nextToken(json, ref index); return bool.Parse("TRUE"); case Json.Deserializer.JsonToken.False: this.nextToken(json, ref index); return bool.Parse("FALSE"); case Json.Deserializer.JsonToken.Null: this.nextToken(json, ref index); return null; } return null; } // Token: 0x0600006F RID: 111 RVA: 0x00005144 File Offset: 0x00003344 private IDictionary parseObject(char[] json, ref int index) { IDictionary dictionary = new Dictionary(); this.nextToken(json, ref index); bool flag = false; while (!flag) { Json.Deserializer.JsonToken jsonToken = this.lookAhead(json, index); if (jsonToken != Json.Deserializer.JsonToken.None) { if (jsonToken == Json.Deserializer.JsonToken.Comma) { this.nextToken(json, ref index); } else { if (jsonToken == Json.Deserializer.JsonToken.CurlyClose) { this.nextToken(json, ref index); return dictionary; } string text = this.parseString(json, ref index); if (text == null) { return null; } jsonToken = this.nextToken(json, ref index); if (jsonToken != Json.Deserializer.JsonToken.Colon) { return null; } object value = this.parseValue(json, ref index); dictionary[text] = value; } continue; } return null; } return dictionary; } // Token: 0x06000070 RID: 112 RVA: 0x00005204 File Offset: 0x00003404 private IList parseArray(char[] json, ref int index) { List list = new List(); this.nextToken(json, ref index); bool flag = false; while (!flag) { Json.Deserializer.JsonToken jsonToken = this.lookAhead(json, index); if (jsonToken == Json.Deserializer.JsonToken.None) { return null; } if (jsonToken == Json.Deserializer.JsonToken.Comma) { this.nextToken(json, ref index); } else { if (jsonToken == Json.Deserializer.JsonToken.SquaredClose) { this.nextToken(json, ref index); break; } object item = this.parseValue(json, ref index); list.Add(item); } } return list; } // Token: 0x06000071 RID: 113 RVA: 0x00005294 File Offset: 0x00003494 private string parseString(char[] json, ref int index) { string text = string.Empty; this.eatWhitespace(json, ref index); char c = json[index++]; bool flag = false; while (!flag) { if (index == json.Length) { break; } c = json[index++]; if (c == '"') { flag = true; break; } if (c == '\\') { if (index == json.Length) { break; } c = json[index++]; if (c == '"') { text += '"'; } else if (c == '\\') { text += '\\'; } else if (c == '/') { text += '/'; } else if (c == 'b') { text += '\b'; } else if (c == 'f') { text += '\f'; } else if (c == 'n') { text += '\n'; } else if (c == 'r') { text += '\r'; } else if (c == 't') { text += '\t'; } else if (c == 'u') { int num = json.Length - index; if (num < 4) { break; } char[] array = new char[4]; Array.Copy(json, index, array, 0, 4); uint utf = uint.Parse(new string(array), NumberStyles.HexNumber); try { text += char.ConvertFromUtf32((int)utf); } catch (Exception) { foreach (char c2 in array) { text += c2; } } index += 4; } } else { text += c; } } string result; if (!flag) { result = null; } else { result = text; } return result; } // Token: 0x06000072 RID: 114 RVA: 0x000054E4 File Offset: 0x000036E4 private object parseNumber(char[] json, ref int index) { this.eatWhitespace(json, ref index); int lastIndexOfNumber = this.getLastIndexOfNumber(json, index); int num = lastIndexOfNumber - index + 1; char[] array = new char[num]; Array.Copy(json, index, array, 0, num); index = lastIndexOfNumber + 1; string text = new string(array); if (!text.Contains(".")) { long num2; if (long.TryParse(text, NumberStyles.Integer, CultureInfo.InvariantCulture, out num2)) { return num2; } } return double.Parse(new string(array), CultureInfo.InvariantCulture); } // Token: 0x06000073 RID: 115 RVA: 0x0000557C File Offset: 0x0000377C private int getLastIndexOfNumber(char[] json, int index) { int i; for (i = index; i < json.Length; i++) { if ("0123456789+-.eE".IndexOf(json[i]) == -1) { break; } } return i - 1; } // Token: 0x06000074 RID: 116 RVA: 0x000055C2 File Offset: 0x000037C2 private void eatWhitespace(char[] json, ref int index) { while (index < json.Length) { if (" \t\n\r".IndexOf(json[index]) == -1) { break; } index++; } } // Token: 0x06000075 RID: 117 RVA: 0x000055F8 File Offset: 0x000037F8 private Json.Deserializer.JsonToken lookAhead(char[] json, int index) { int num = index; return this.nextToken(json, ref num); } // Token: 0x06000076 RID: 118 RVA: 0x00005618 File Offset: 0x00003818 private Json.Deserializer.JsonToken nextToken(char[] json, ref int index) { this.eatWhitespace(json, ref index); Json.Deserializer.JsonToken result; if (index == json.Length) { result = Json.Deserializer.JsonToken.None; } else { char c = json[index]; index++; switch (c) { case ',': result = Json.Deserializer.JsonToken.Comma; break; case '-': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': result = Json.Deserializer.JsonToken.Number; break; default: switch (c) { case '[': result = Json.Deserializer.JsonToken.SquaredOpen; break; default: switch (c) { case '{': result = Json.Deserializer.JsonToken.CurlyOpen; break; default: if (c != '"') { index--; int num = json.Length - index; if (num >= 5) { if (json[index] == 'f' && json[index + 1] == 'a' && json[index + 2] == 'l' && json[index + 3] == 's' && json[index + 4] == 'e') { index += 5; result = Json.Deserializer.JsonToken.False; break; } } if (num >= 4) { if (json[index] == 't' && json[index + 1] == 'r' && json[index + 2] == 'u' && json[index + 3] == 'e') { index += 4; result = Json.Deserializer.JsonToken.True; break; } } if (num >= 4) { if (json[index] == 'n' && json[index + 1] == 'u' && json[index + 2] == 'l' && json[index + 3] == 'l') { index += 4; result = Json.Deserializer.JsonToken.Null; break; } } result = Json.Deserializer.JsonToken.None; } else { result = Json.Deserializer.JsonToken.String; } break; case '}': result = Json.Deserializer.JsonToken.CurlyClose; break; } break; case ']': result = Json.Deserializer.JsonToken.SquaredClose; break; } break; case ':': result = Json.Deserializer.JsonToken.Colon; break; } } return result; } // Token: 0x04000026 RID: 38 private char[] charArray; // Token: 0x02000013 RID: 19 private enum JsonToken { // Token: 0x04000028 RID: 40 None, // Token: 0x04000029 RID: 41 CurlyOpen, // Token: 0x0400002A RID: 42 CurlyClose, // Token: 0x0400002B RID: 43 SquaredOpen, // Token: 0x0400002C RID: 44 SquaredClose, // Token: 0x0400002D RID: 45 Colon, // Token: 0x0400002E RID: 46 Comma, // Token: 0x0400002F RID: 47 String, // Token: 0x04000030 RID: 48 Number, // Token: 0x04000031 RID: 49 True, // Token: 0x04000032 RID: 50 False, // Token: 0x04000033 RID: 51 Null } } // Token: 0x02000014 RID: 20 internal class Serializer { // Token: 0x06000077 RID: 119 RVA: 0x000057FE File Offset: 0x000039FE private Serializer() { this._builder = new StringBuilder(); } // Token: 0x06000078 RID: 120 RVA: 0x00005814 File Offset: 0x00003A14 public static string serialize(object obj) { Json.Serializer serializer = new Json.Serializer(); serializer.serializeObject(obj); return serializer._builder.ToString(); } // Token: 0x06000079 RID: 121 RVA: 0x00005844 File Offset: 0x00003A44 private void serializeObject(object value) { if (value == null) { this._builder.Append("null"); } else if (value is string) { this.serializeString((string)value); } else if (value is IList) { this.serializeIList((IList)value); } else if (value is Dictionary) { this.serializeDictionary((Dictionary)value); } else if (value is IDictionary) { this.serializeIDictionary((IDictionary)value); } else if (value is bool) { this._builder.Append(value.ToString().ToLower()); } else if (value.GetType().IsPrimitive) { this._builder.Append(value); } else if (value is DateTime) { DateTime value2 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); double totalMilliseconds = ((DateTime)value).Subtract(value2).TotalMilliseconds; this.serializeString(Convert.ToString(totalMilliseconds, CultureInfo.InvariantCulture)); } else { try { this.serializeClass(value); } catch (Exception ex) { Utils.logObject(string.Format("failed to serialize {0} with error: {1}", value, ex.Message)); } } } // Token: 0x0600007A RID: 122 RVA: 0x000059C4 File Offset: 0x00003BC4 private void serializeIList(IList anArray) { this._builder.Append("["); bool flag = true; for (int i = 0; i < anArray.Count; i++) { object value = anArray[i]; if (!flag) { this._builder.Append(", "); } this.serializeObject(value); flag = false; } this._builder.Append("]"); } // Token: 0x0600007B RID: 123 RVA: 0x00005A38 File Offset: 0x00003C38 private void serializeIDictionary(IDictionary dict) { this._builder.Append("{"); bool flag = true; IEnumerator enumerator = dict.Keys.GetEnumerator(); try { while (enumerator.MoveNext()) { object obj = enumerator.Current; if (!flag) { this._builder.Append(", "); } this.serializeString(obj.ToString()); this._builder.Append(":"); this.serializeObject(dict[obj]); flag = false; } } finally { IDisposable disposable; if ((disposable = (enumerator as IDisposable)) != null) { disposable.Dispose(); } } this._builder.Append("}"); } // Token: 0x0600007C RID: 124 RVA: 0x00005AFC File Offset: 0x00003CFC private void serializeDictionary(Dictionary dict) { this._builder.Append("{"); bool flag = true; Dictionary.KeyCollection keys = dict.Keys; foreach (string text in keys) { if (!flag) { this._builder.Append(", "); } this.serializeString(text.ToString()); this._builder.Append(":"); this.serializeObject(dict[text]); flag = false; } this._builder.Append("}"); } // Token: 0x0600007D RID: 125 RVA: 0x00005BC0 File Offset: 0x00003DC0 private void serializeString(string str) { this._builder.Append("\""); foreach (char c in str.ToCharArray()) { if (c == '"') { this._builder.Append("\\\""); } else if (c == '\\') { this._builder.Append("\\\\"); } else if (c == '\b') { this._builder.Append("\\b"); } else if (c == '\f') { this._builder.Append("\\f"); } else if (c == '\n') { this._builder.Append("\\n"); } else if (c == '\r') { this._builder.Append("\\r"); } else if (c == '\t') { this._builder.Append("\\t"); } else { int num = Convert.ToInt32(c, CultureInfo.InvariantCulture); if (num >= 32 && num <= 126) { this._builder.Append(c); } else { this._builder.Append("\\u" + Convert.ToString(num, 16).PadLeft(4, '0')); } } } this._builder.Append("\""); } // Token: 0x0600007E RID: 126 RVA: 0x00005D4C File Offset: 0x00003F4C private void serializeClass(object value) { this._builder.Append("{"); bool flag = true; foreach (FieldInfo fieldInfo in value.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { if (!fieldInfo.IsPrivate || !fieldInfo.Name.Contains("k__BackingField")) { if (!flag) { this._builder.Append(", "); } this.serializeString(fieldInfo.Name); this._builder.Append(":"); this.serializeObject(fieldInfo.GetValue(value)); flag = false; } } foreach (PropertyInfo propertyInfo in value.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { if (!flag) { this._builder.Append(", "); } this.serializeString(propertyInfo.Name); this._builder.Append(":"); this.serializeObject(propertyInfo.GetValue(value, null)); flag = false; } this._builder.Append("}"); } // Token: 0x04000034 RID: 52 private StringBuilder _builder; } } }