Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of ModsBetaTesting v1.0.0
BepInEx/patchers/Kittenji.BetaTesting.dll
Decompiled 2 years agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using BepInEx; using BepInEx.Logging; using Microsoft.CodeAnalysis; using Mono.Cecil; using SimpleJSON; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Kittenji")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("Kittenji.BetaTesting")] [assembly: AssemblyTitle("Kittenji.BetaTesting")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace SimpleJSON { public enum JSONNodeType { Array = 1, Object = 2, String = 3, Number = 4, NullValue = 5, Boolean = 6, None = 7, Custom = 255 } public enum JSONTextMode { Compact, Indent } public abstract class JSONNode { public struct Enumerator { private enum Type { None, Array, Object } private Type type; private Dictionary<string, JSONNode>.Enumerator m_Object; private List<JSONNode>.Enumerator m_Array; public bool IsValid => type != Type.None; public KeyValuePair<string, JSONNode> Current { get { if (type == Type.Array) { return new KeyValuePair<string, JSONNode>(string.Empty, m_Array.Current); } if (type == Type.Object) { return m_Object.Current; } return new KeyValuePair<string, JSONNode>(string.Empty, null); } } public Enumerator(List<JSONNode>.Enumerator aArrayEnum) { type = Type.Array; m_Object = default(Dictionary<string, JSONNode>.Enumerator); m_Array = aArrayEnum; } public Enumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum) { type = Type.Object; m_Object = aDictEnum; m_Array = default(List<JSONNode>.Enumerator); } public bool MoveNext() { if (type == Type.Array) { return m_Array.MoveNext(); } if (type == Type.Object) { return m_Object.MoveNext(); } return false; } } public struct ValueEnumerator { private Enumerator m_Enumerator; public JSONNode Current => m_Enumerator.Current.Value; public ValueEnumerator(List<JSONNode>.Enumerator aArrayEnum) : this(new Enumerator(aArrayEnum)) { } public ValueEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum) : this(new Enumerator(aDictEnum)) { } public ValueEnumerator(Enumerator aEnumerator) { m_Enumerator = aEnumerator; } public bool MoveNext() { return m_Enumerator.MoveNext(); } public ValueEnumerator GetEnumerator() { return this; } } public struct KeyEnumerator { private Enumerator m_Enumerator; public string Current => m_Enumerator.Current.Key; public KeyEnumerator(List<JSONNode>.Enumerator aArrayEnum) : this(new Enumerator(aArrayEnum)) { } public KeyEnumerator(Dictionary<string, JSONNode>.Enumerator aDictEnum) : this(new Enumerator(aDictEnum)) { } public KeyEnumerator(Enumerator aEnumerator) { m_Enumerator = aEnumerator; } public bool MoveNext() { return m_Enumerator.MoveNext(); } public KeyEnumerator GetEnumerator() { return this; } } public class LinqEnumerator : IEnumerator<KeyValuePair<string, JSONNode>>, IEnumerator, IDisposable, IEnumerable<KeyValuePair<string, JSONNode>>, IEnumerable { private JSONNode m_Node; private Enumerator m_Enumerator; public KeyValuePair<string, JSONNode> Current => m_Enumerator.Current; object IEnumerator.Current => m_Enumerator.Current; internal LinqEnumerator(JSONNode aNode) { m_Node = aNode; if (m_Node != null) { m_Enumerator = m_Node.GetEnumerator(); } } public bool MoveNext() { return m_Enumerator.MoveNext(); } public void Dispose() { m_Node = null; m_Enumerator = default(Enumerator); } public IEnumerator<KeyValuePair<string, JSONNode>> GetEnumerator() { return new LinqEnumerator(m_Node); } public void Reset() { if (m_Node != null) { m_Enumerator = m_Node.GetEnumerator(); } } IEnumerator IEnumerable.GetEnumerator() { return new LinqEnumerator(m_Node); } } public static bool forceASCII = false; public static bool longAsString = false; public static bool allowLineComments = true; [ThreadStatic] private static StringBuilder m_EscapeBuilder; public abstract JSONNodeType Tag { get; } public virtual JSONNode this[int aIndex] { get { return null; } set { } } public virtual JSONNode this[string aKey] { get { return null; } set { } } public virtual string Value { get { return ""; } set { } } public virtual int Count => 0; public virtual bool IsNumber => false; public virtual bool IsString => false; public virtual bool IsBoolean => false; public virtual bool IsNull => false; public virtual bool IsArray => false; public virtual bool IsObject => false; public virtual bool Inline { get { return false; } set { } } public virtual IEnumerable<JSONNode> Children { get { yield break; } } public IEnumerable<JSONNode> DeepChildren { get { foreach (JSONNode child in Children) { foreach (JSONNode deepChild in child.DeepChildren) { yield return deepChild; } } } } public IEnumerable<KeyValuePair<string, JSONNode>> Linq => new LinqEnumerator(this); public KeyEnumerator Keys => new KeyEnumerator(GetEnumerator()); public ValueEnumerator Values => new ValueEnumerator(GetEnumerator()); public virtual double AsDouble { get { double result = 0.0; if (double.TryParse(Value, NumberStyles.Float, CultureInfo.InvariantCulture, out result)) { return result; } return 0.0; } set { Value = value.ToString(CultureInfo.InvariantCulture); } } public virtual int AsInt { get { return (int)AsDouble; } set { AsDouble = value; } } public virtual float AsFloat { get { return (float)AsDouble; } set { AsDouble = value; } } public virtual bool AsBool { get { bool result = false; if (bool.TryParse(Value, out result)) { return result; } return !string.IsNullOrEmpty(Value); } set { Value = (value ? "true" : "false"); } } public virtual long AsLong { get { long result = 0L; if (long.TryParse(Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result)) { return result; } return 0L; } set { Value = value.ToString(CultureInfo.InvariantCulture); } } public virtual ulong AsULong { get { ulong result = 0uL; if (ulong.TryParse(Value, NumberStyles.Integer, CultureInfo.InvariantCulture, out result)) { return result; } return 0uL; } set { Value = value.ToString(CultureInfo.InvariantCulture); } } public virtual JSONArray AsArray => this as JSONArray; public virtual JSONObject AsObject => this as JSONObject; internal static StringBuilder EscapeBuilder { get { if (m_EscapeBuilder == null) { m_EscapeBuilder = new StringBuilder(); } return m_EscapeBuilder; } } public virtual void Add(string aKey, JSONNode aItem) { } public virtual void Add(JSONNode aItem) { Add("", aItem); } public virtual JSONNode Remove(string aKey) { return null; } public virtual JSONNode Remove(int aIndex) { return null; } public virtual JSONNode Remove(JSONNode aNode) { return aNode; } public virtual void Clear() { } public virtual JSONNode Clone() { return null; } public virtual bool HasKey(string aKey) { return false; } public virtual JSONNode GetValueOrDefault(string aKey, JSONNode aDefault) { return aDefault; } public override string ToString() { StringBuilder stringBuilder = new StringBuilder(); WriteToStringBuilder(stringBuilder, 0, 0, JSONTextMode.Compact); return stringBuilder.ToString(); } public virtual string ToString(int aIndent) { StringBuilder stringBuilder = new StringBuilder(); WriteToStringBuilder(stringBuilder, 0, aIndent, JSONTextMode.Indent); return stringBuilder.ToString(); } internal abstract void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode); public abstract Enumerator GetEnumerator(); public static implicit operator JSONNode(string s) { if (s != null) { return new JSONString(s); } return JSONNull.CreateOrGet(); } public static implicit operator string(JSONNode d) { if (!(d == null)) { return d.Value; } return null; } public static implicit operator JSONNode(double n) { return new JSONNumber(n); } public static implicit operator double(JSONNode d) { if (!(d == null)) { return d.AsDouble; } return 0.0; } public static implicit operator JSONNode(float n) { return new JSONNumber(n); } public static implicit operator float(JSONNode d) { if (!(d == null)) { return d.AsFloat; } return 0f; } public static implicit operator JSONNode(int n) { return new JSONNumber(n); } public static implicit operator int(JSONNode d) { if (!(d == null)) { return d.AsInt; } return 0; } public static implicit operator JSONNode(long n) { if (longAsString) { return new JSONString(n.ToString(CultureInfo.InvariantCulture)); } return new JSONNumber(n); } public static implicit operator long(JSONNode d) { if (!(d == null)) { return d.AsLong; } return 0L; } public static implicit operator JSONNode(ulong n) { if (longAsString) { return new JSONString(n.ToString(CultureInfo.InvariantCulture)); } return new JSONNumber(n); } public static implicit operator ulong(JSONNode d) { if (!(d == null)) { return d.AsULong; } return 0uL; } public static implicit operator JSONNode(bool b) { return new JSONBool(b); } public static implicit operator bool(JSONNode d) { if (!(d == null)) { return d.AsBool; } return false; } public static implicit operator JSONNode(KeyValuePair<string, JSONNode> aKeyValue) { return aKeyValue.Value; } public static bool operator ==(JSONNode a, object b) { if ((object)a == b) { return true; } bool flag = a is JSONNull || (object)a == null || a is JSONLazyCreator; bool flag2 = b is JSONNull || b == null || b is JSONLazyCreator; if (flag && flag2) { return true; } if (!flag) { return a.Equals(b); } return false; } public static bool operator !=(JSONNode a, object b) { return !(a == b); } public override bool Equals(object obj) { return (object)this == obj; } public override int GetHashCode() { return base.GetHashCode(); } internal static string Escape(string aText) { StringBuilder escapeBuilder = EscapeBuilder; escapeBuilder.Length = 0; if (escapeBuilder.Capacity < aText.Length + aText.Length / 10) { escapeBuilder.Capacity = aText.Length + aText.Length / 10; } foreach (char c in aText) { switch (c) { case '\\': escapeBuilder.Append("\\\\"); continue; case '"': escapeBuilder.Append("\\\""); continue; case '\n': escapeBuilder.Append("\\n"); continue; case '\r': escapeBuilder.Append("\\r"); continue; case '\t': escapeBuilder.Append("\\t"); continue; case '\b': escapeBuilder.Append("\\b"); continue; case '\f': escapeBuilder.Append("\\f"); continue; } if (c < ' ' || (forceASCII && c > '\u007f')) { ushort num = c; escapeBuilder.Append("\\u").Append(num.ToString("X4")); } else { escapeBuilder.Append(c); } } string result = escapeBuilder.ToString(); escapeBuilder.Length = 0; return result; } private static JSONNode ParseElement(string token, bool quoted) { if (quoted) { return token; } if (token.Length <= 5) { string text = token.ToLower(); switch (text) { case "false": case "true": return text == "true"; case "null": return JSONNull.CreateOrGet(); } } if (double.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return result; } return token; } public static JSONNode Parse(string aJSON) { Stack<JSONNode> stack = new Stack<JSONNode>(); JSONNode jSONNode = null; int i = 0; StringBuilder stringBuilder = new StringBuilder(); string aKey = ""; bool flag = false; bool flag2 = false; bool flag3 = false; for (; i < aJSON.Length; i++) { switch (aJSON[i]) { case '{': if (flag) { stringBuilder.Append(aJSON[i]); break; } stack.Push(new JSONObject()); if (jSONNode != null) { jSONNode.Add(aKey, stack.Peek()); } aKey = ""; stringBuilder.Length = 0; jSONNode = stack.Peek(); flag3 = false; break; case '[': if (flag) { stringBuilder.Append(aJSON[i]); break; } stack.Push(new JSONArray()); if (jSONNode != null) { jSONNode.Add(aKey, stack.Peek()); } aKey = ""; stringBuilder.Length = 0; jSONNode = stack.Peek(); flag3 = false; break; case ']': case '}': if (flag) { stringBuilder.Append(aJSON[i]); break; } if (stack.Count == 0) { throw new Exception("JSON Parse: Too many closing brackets"); } stack.Pop(); if (stringBuilder.Length > 0 || flag2) { jSONNode.Add(aKey, ParseElement(stringBuilder.ToString(), flag2)); } if (jSONNode != null) { jSONNode.Inline = !flag3; } flag2 = false; aKey = ""; stringBuilder.Length = 0; if (stack.Count > 0) { jSONNode = stack.Peek(); } break; case ':': if (flag) { stringBuilder.Append(aJSON[i]); break; } aKey = stringBuilder.ToString(); stringBuilder.Length = 0; flag2 = false; break; case '"': flag = !flag; flag2 = flag2 || flag; break; case ',': if (flag) { stringBuilder.Append(aJSON[i]); break; } if (stringBuilder.Length > 0 || flag2) { jSONNode.Add(aKey, ParseElement(stringBuilder.ToString(), flag2)); } flag2 = false; aKey = ""; stringBuilder.Length = 0; flag2 = false; break; case '\n': case '\r': flag3 = true; break; case '\t': case ' ': if (flag) { stringBuilder.Append(aJSON[i]); } break; case '\\': i++; if (flag) { char c = aJSON[i]; switch (c) { case 't': stringBuilder.Append('\t'); break; case 'r': stringBuilder.Append('\r'); break; case 'n': stringBuilder.Append('\n'); break; case 'b': stringBuilder.Append('\b'); break; case 'f': stringBuilder.Append('\f'); break; case 'u': { string s = aJSON.Substring(i + 1, 4); stringBuilder.Append((char)int.Parse(s, NumberStyles.AllowHexSpecifier)); i += 4; break; } default: stringBuilder.Append(c); break; } } break; case '/': if (allowLineComments && !flag && i + 1 < aJSON.Length && aJSON[i + 1] == '/') { while (++i < aJSON.Length && aJSON[i] != '\n' && aJSON[i] != '\r') { } } else { stringBuilder.Append(aJSON[i]); } break; default: stringBuilder.Append(aJSON[i]); break; case '\ufeff': break; } } if (flag) { throw new Exception("JSON Parse: Quotation marks seems to be messed up."); } if (jSONNode == null) { return ParseElement(stringBuilder.ToString(), flag2); } return jSONNode; } } public class JSONArray : JSONNode { private List<JSONNode> m_List = new List<JSONNode>(); private bool inline; public override bool Inline { get { return inline; } set { inline = value; } } public override JSONNodeType Tag => JSONNodeType.Array; public override bool IsArray => true; public override JSONNode this[int aIndex] { get { if (aIndex < 0 || aIndex >= m_List.Count) { return new JSONLazyCreator(this); } return m_List[aIndex]; } set { if (value == null) { value = JSONNull.CreateOrGet(); } if (aIndex < 0 || aIndex >= m_List.Count) { m_List.Add(value); } else { m_List[aIndex] = value; } } } public override JSONNode this[string aKey] { get { return new JSONLazyCreator(this); } set { if (value == null) { value = JSONNull.CreateOrGet(); } m_List.Add(value); } } public override int Count => m_List.Count; public override IEnumerable<JSONNode> Children { get { foreach (JSONNode item in m_List) { yield return item; } } } public override Enumerator GetEnumerator() { return new Enumerator(m_List.GetEnumerator()); } public override void Add(string aKey, JSONNode aItem) { if (aItem == null) { aItem = JSONNull.CreateOrGet(); } m_List.Add(aItem); } public override JSONNode Remove(int aIndex) { if (aIndex < 0 || aIndex >= m_List.Count) { return null; } JSONNode result = m_List[aIndex]; m_List.RemoveAt(aIndex); return result; } public override JSONNode Remove(JSONNode aNode) { m_List.Remove(aNode); return aNode; } public override void Clear() { m_List.Clear(); } public override JSONNode Clone() { JSONArray jSONArray = new JSONArray(); jSONArray.m_List.Capacity = m_List.Capacity; foreach (JSONNode item in m_List) { if (item != null) { jSONArray.Add(item.Clone()); } else { jSONArray.Add(null); } } return jSONArray; } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append('['); int count = m_List.Count; if (inline) { aMode = JSONTextMode.Compact; } for (int i = 0; i < count; i++) { if (i > 0) { aSB.Append(','); } if (aMode == JSONTextMode.Indent) { aSB.AppendLine(); } if (aMode == JSONTextMode.Indent) { aSB.Append(' ', aIndent + aIndentInc); } m_List[i].WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode); } if (aMode == JSONTextMode.Indent) { aSB.AppendLine().Append(' ', aIndent); } aSB.Append(']'); } } public class JSONObject : JSONNode { private Dictionary<string, JSONNode> m_Dict = new Dictionary<string, JSONNode>(); private bool inline; public override bool Inline { get { return inline; } set { inline = value; } } public override JSONNodeType Tag => JSONNodeType.Object; public override bool IsObject => true; public override JSONNode this[string aKey] { get { if (m_Dict.ContainsKey(aKey)) { return m_Dict[aKey]; } return new JSONLazyCreator(this, aKey); } set { if (value == null) { value = JSONNull.CreateOrGet(); } if (m_Dict.ContainsKey(aKey)) { m_Dict[aKey] = value; } else { m_Dict.Add(aKey, value); } } } public override JSONNode this[int aIndex] { get { if (aIndex < 0 || aIndex >= m_Dict.Count) { return null; } return m_Dict.ElementAt(aIndex).Value; } set { if (value == null) { value = JSONNull.CreateOrGet(); } if (aIndex >= 0 && aIndex < m_Dict.Count) { string key = m_Dict.ElementAt(aIndex).Key; m_Dict[key] = value; } } } public override int Count => m_Dict.Count; public override IEnumerable<JSONNode> Children { get { foreach (KeyValuePair<string, JSONNode> item in m_Dict) { yield return item.Value; } } } public override Enumerator GetEnumerator() { return new Enumerator(m_Dict.GetEnumerator()); } public override void Add(string aKey, JSONNode aItem) { if (aItem == null) { aItem = JSONNull.CreateOrGet(); } if (aKey != null) { if (m_Dict.ContainsKey(aKey)) { m_Dict[aKey] = aItem; } else { m_Dict.Add(aKey, aItem); } } else { m_Dict.Add(Guid.NewGuid().ToString(), aItem); } } public override JSONNode Remove(string aKey) { if (!m_Dict.ContainsKey(aKey)) { return null; } JSONNode result = m_Dict[aKey]; m_Dict.Remove(aKey); return result; } public override JSONNode Remove(int aIndex) { if (aIndex < 0 || aIndex >= m_Dict.Count) { return null; } KeyValuePair<string, JSONNode> keyValuePair = m_Dict.ElementAt(aIndex); m_Dict.Remove(keyValuePair.Key); return keyValuePair.Value; } public override JSONNode Remove(JSONNode aNode) { try { KeyValuePair<string, JSONNode> keyValuePair = m_Dict.Where((KeyValuePair<string, JSONNode> k) => k.Value == aNode).First(); m_Dict.Remove(keyValuePair.Key); return aNode; } catch { return null; } } public override void Clear() { m_Dict.Clear(); } public override JSONNode Clone() { JSONObject jSONObject = new JSONObject(); foreach (KeyValuePair<string, JSONNode> item in m_Dict) { jSONObject.Add(item.Key, item.Value.Clone()); } return jSONObject; } public override bool HasKey(string aKey) { return m_Dict.ContainsKey(aKey); } public override JSONNode GetValueOrDefault(string aKey, JSONNode aDefault) { if (m_Dict.TryGetValue(aKey, out var value)) { return value; } return aDefault; } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append('{'); bool flag = true; if (inline) { aMode = JSONTextMode.Compact; } foreach (KeyValuePair<string, JSONNode> item in m_Dict) { if (!flag) { aSB.Append(','); } flag = false; if (aMode == JSONTextMode.Indent) { aSB.AppendLine(); } if (aMode == JSONTextMode.Indent) { aSB.Append(' ', aIndent + aIndentInc); } aSB.Append('"').Append(JSONNode.Escape(item.Key)).Append('"'); if (aMode == JSONTextMode.Compact) { aSB.Append(':'); } else { aSB.Append(" : "); } item.Value.WriteToStringBuilder(aSB, aIndent + aIndentInc, aIndentInc, aMode); } if (aMode == JSONTextMode.Indent) { aSB.AppendLine().Append(' ', aIndent); } aSB.Append('}'); } } public class JSONString : JSONNode { private string m_Data; public override JSONNodeType Tag => JSONNodeType.String; public override bool IsString => true; public override string Value { get { return m_Data; } set { m_Data = value; } } public override Enumerator GetEnumerator() { return default(Enumerator); } public JSONString(string aData) { m_Data = aData; } public override JSONNode Clone() { return new JSONString(m_Data); } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append('"').Append(JSONNode.Escape(m_Data)).Append('"'); } public override bool Equals(object obj) { if (base.Equals(obj)) { return true; } if (obj is string text) { return m_Data == text; } JSONString jSONString = obj as JSONString; if (jSONString != null) { return m_Data == jSONString.m_Data; } return false; } public override int GetHashCode() { return m_Data.GetHashCode(); } public override void Clear() { m_Data = ""; } } public class JSONNumber : JSONNode { private double m_Data; public override JSONNodeType Tag => JSONNodeType.Number; public override bool IsNumber => true; public override string Value { get { return m_Data.ToString(CultureInfo.InvariantCulture); } set { if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { m_Data = result; } } } public override double AsDouble { get { return m_Data; } set { m_Data = value; } } public override long AsLong { get { return (long)m_Data; } set { m_Data = value; } } public override ulong AsULong { get { return (ulong)m_Data; } set { m_Data = value; } } public override Enumerator GetEnumerator() { return default(Enumerator); } public JSONNumber(double aData) { m_Data = aData; } public JSONNumber(string aData) { Value = aData; } public override JSONNode Clone() { return new JSONNumber(m_Data); } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append(Value.ToString(CultureInfo.InvariantCulture)); } private static bool IsNumeric(object value) { if (!(value is int) && !(value is uint) && !(value is float) && !(value is double) && !(value is decimal) && !(value is long) && !(value is ulong) && !(value is short) && !(value is ushort) && !(value is sbyte)) { return value is byte; } return true; } public override bool Equals(object obj) { if (obj == null) { return false; } if (base.Equals(obj)) { return true; } JSONNumber jSONNumber = obj as JSONNumber; if (jSONNumber != null) { return m_Data == jSONNumber.m_Data; } if (IsNumeric(obj)) { return Convert.ToDouble(obj) == m_Data; } return false; } public override int GetHashCode() { return m_Data.GetHashCode(); } public override void Clear() { m_Data = 0.0; } } public class JSONBool : JSONNode { private bool m_Data; public override JSONNodeType Tag => JSONNodeType.Boolean; public override bool IsBoolean => true; public override string Value { get { return m_Data.ToString(); } set { if (bool.TryParse(value, out var result)) { m_Data = result; } } } public override bool AsBool { get { return m_Data; } set { m_Data = value; } } public override Enumerator GetEnumerator() { return default(Enumerator); } public JSONBool(bool aData) { m_Data = aData; } public JSONBool(string aData) { Value = aData; } public override JSONNode Clone() { return new JSONBool(m_Data); } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append(m_Data ? "true" : "false"); } public override bool Equals(object obj) { if (obj == null) { return false; } if (obj is bool) { return m_Data == (bool)obj; } return false; } public override int GetHashCode() { return m_Data.GetHashCode(); } public override void Clear() { m_Data = false; } } public class JSONNull : JSONNode { private static JSONNull m_StaticInstance = new JSONNull(); public static bool reuseSameInstance = true; public override JSONNodeType Tag => JSONNodeType.NullValue; public override bool IsNull => true; public override string Value { get { return "null"; } set { } } public override bool AsBool { get { return false; } set { } } public static JSONNull CreateOrGet() { if (reuseSameInstance) { return m_StaticInstance; } return new JSONNull(); } private JSONNull() { } public override Enumerator GetEnumerator() { return default(Enumerator); } public override JSONNode Clone() { return CreateOrGet(); } public override bool Equals(object obj) { if ((object)this == obj) { return true; } return obj is JSONNull; } public override int GetHashCode() { return 0; } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append("null"); } } internal class JSONLazyCreator : JSONNode { private JSONNode m_Node; private string m_Key; public override JSONNodeType Tag => JSONNodeType.None; public override JSONNode this[int aIndex] { get { return new JSONLazyCreator(this); } set { Set(new JSONArray()).Add(value); } } public override JSONNode this[string aKey] { get { return new JSONLazyCreator(this, aKey); } set { Set(new JSONObject()).Add(aKey, value); } } public override int AsInt { get { Set(new JSONNumber(0.0)); return 0; } set { Set(new JSONNumber(value)); } } public override float AsFloat { get { Set(new JSONNumber(0.0)); return 0f; } set { Set(new JSONNumber(value)); } } public override double AsDouble { get { Set(new JSONNumber(0.0)); return 0.0; } set { Set(new JSONNumber(value)); } } public override long AsLong { get { if (JSONNode.longAsString) { Set(new JSONString("0")); } else { Set(new JSONNumber(0.0)); } return 0L; } set { if (JSONNode.longAsString) { Set(new JSONString(value.ToString(CultureInfo.InvariantCulture))); } else { Set(new JSONNumber(value)); } } } public override ulong AsULong { get { if (JSONNode.longAsString) { Set(new JSONString("0")); } else { Set(new JSONNumber(0.0)); } return 0uL; } set { if (JSONNode.longAsString) { Set(new JSONString(value.ToString(CultureInfo.InvariantCulture))); } else { Set(new JSONNumber(value)); } } } public override bool AsBool { get { Set(new JSONBool(aData: false)); return false; } set { Set(new JSONBool(value)); } } public override JSONArray AsArray => Set(new JSONArray()); public override JSONObject AsObject => Set(new JSONObject()); public override Enumerator GetEnumerator() { return default(Enumerator); } public JSONLazyCreator(JSONNode aNode) { m_Node = aNode; m_Key = null; } public JSONLazyCreator(JSONNode aNode, string aKey) { m_Node = aNode; m_Key = aKey; } private T Set<T>(T aVal) where T : JSONNode { if (m_Key == null) { m_Node.Add(aVal); } else { m_Node.Add(m_Key, aVal); } m_Node = null; return aVal; } public override void Add(JSONNode aItem) { Set(new JSONArray()).Add(aItem); } public override void Add(string aKey, JSONNode aItem) { Set(new JSONObject()).Add(aKey, aItem); } public static bool operator ==(JSONLazyCreator a, object b) { if (b == null) { return true; } return (object)a == b; } public static bool operator !=(JSONLazyCreator a, object b) { return !(a == b); } public override bool Equals(object obj) { if (obj == null) { return true; } return (object)this == obj; } public override int GetHashCode() { return 0; } internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { aSB.Append("null"); } } public static class JSON { public static JSONNode Parse(string aJSON) { return JSONNode.Parse(aJSON); } } } namespace Kittenji.BetaTesting { internal static class PSRequest { private const string DECOMP = "Sorry Robin, it seems that I can't use TLS in a patcher plugin, so I will have to use Powershell to download files instead. :("; public static string GetString(string url) { string text = "(Invoke-WebRequest -Uri '" + url + "').Content"; string result = null; using Process process = new Process { StartInfo = new ProcessStartInfo { FileName = "powershell", RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true, Arguments = "-Command \"" + text + "\"" } }; process.Start(); string text2 = process.StandardOutput.ReadToEnd(); string text3 = process.StandardError.ReadToEnd(); if (!string.IsNullOrEmpty(text2)) { result = text2; } if (!string.IsNullOrEmpty(text3)) { Log.Error(text3); } process.WaitForExit(); return result; } public static void Download(string url, string path) { string text = "Invoke-WebRequest -Uri '" + url + "' -OutFile '" + path + "'"; using Process process = new Process { StartInfo = new ProcessStartInfo { FileName = "powershell", UseShellExecute = false, CreateNoWindow = true, Arguments = "-Command \"" + text + "\"" } }; process.Start(); process.WaitForExit(); } } internal static class EntryPoint { private const string DECOMP = "Sorry Robin, it seems that I can't use TLS in a patcher plugin, so I will have to use Powershell to download files instead. :("; private static int BetaCount = 0; private static int FileCount = 0; private const string RepoOwner = "ChrisFeline"; private const string RepoName = "Mod-Beta-Testing"; private const string RequestUrl = "https://api.github.com/repos/ChrisFeline/Mod-Beta-Testing/releases"; public static string Destination { get; private set; } public static string Temporary { get; private set; } public static IEnumerable<string> TargetDLLs { get; } = Array.Empty<string>(); public static void Patch(AssemblyDefinition _) { } public static void Initialize() { Log.Init(); Log.Info(Paths.PluginPath); Destination = Path.Combine(Paths.PluginPath, "Kittenji-BetaTesting"); Temporary = Path.Combine(Paths.CachePath, "beta-temp"); try { if (Directory.Exists(Destination)) { Directory.Delete(Destination, recursive: true); } Directory.CreateDirectory(Destination); if (!Directory.Exists(Temporary)) { Directory.CreateDirectory(Temporary); } InitInternal(); } catch (Exception data) { Log.Error(data); } } internal static void InitInternal() { JSONNode.Enumerator enumerator = GetReleases().AsArray.GetEnumerator(); while (enumerator.MoveNext()) { JSONNode jSONNode = enumerator.Current; if (!jSONNode["prerelease"].AsBool) { continue; } Log.Message("Downloading Beta Release: " + jSONNode["name"].Value); Log.Info("Created at: " + jSONNode["created_at"].Value); JSONArray asArray = jSONNode["assets"].AsArray; int num = 0; JSONNode.Enumerator enumerator2 = asArray.GetEnumerator(); while (enumerator2.MoveNext()) { JSONNode jSONNode2 = enumerator2.Current; if (!(jSONNode2["content_type"].Value != "application/x-zip-compressed")) { string value = jSONNode2["name"].Value; string value2 = jSONNode2["browser_download_url"].Value; if (!string.IsNullOrEmpty(value2) && DownloadAsset(value2, value)) { FileCount++; num++; } } } if (num > 0) { BetaCount++; } } if (BetaCount == 0) { Log.Warning("No beta tests available..."); } else { Log.Message($"Downloaded '{FileCount}' assets for '{BetaCount}' beta tests."); } } internal static bool DownloadAsset(string url, string name) { Log.Message("Downloading Asset: " + name); string text = Path.Combine(Destination, Path.GetFileNameWithoutExtension(name)); string text2 = Path.Combine(Temporary, name); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); } PSRequest.Download(url, text2); Log.Info("Extracting..."); ZipFile.ExtractToDirectory(text2, text, overwriteFiles: true); string path = Path.Combine(text, "BepInEx"); string path2 = Path.Combine(text, "BepInEx", "plugins"); if (Directory.Exists(path2)) { string[] files = Directory.GetFiles(path2); foreach (string text3 in files) { Log.Info("Moving File: " + Path.GetFileName(text3)); string text4 = Path.Combine(text, Path.GetFileName(text3)); if (File.Exists(text4)) { File.Delete(text4); } File.Move(text3, text4); } files = Directory.GetDirectories(path2); foreach (string text5 in files) { Log.Info("Moving Dir: " + Path.GetFileName(text5)); string text4 = Path.Combine(text, Path.GetFileName(text5)); if (Directory.Exists(text4)) { Directory.Delete(text4); } Directory.Move(text5, Path.Combine(text, Path.GetFileName(text5))); } Directory.Delete(path, recursive: true); } File.Delete(text2); return true; } public static JSONNode GetReleases() { try { Log.Message("Checking available Beta releases: https://api.github.com/repos/ChrisFeline/Mod-Beta-Testing/releases"); string @string = PSRequest.GetString("https://api.github.com/repos/ChrisFeline/Mod-Beta-Testing/releases"); if (string.IsNullOrEmpty(@string)) { return null; } return JSON.Parse(@string); } catch (Exception data) { Log.Error(data); return null; } } } internal static class Log { private static ManualLogSource _logSource; internal static void Init() { _logSource = Logger.CreateLogSource("Kittenji.BetaTesting"); } internal static void Debug(object data) { _logSource.LogDebug(data); } internal static void Error(object data) { _logSource.LogError(data); } internal static void Fatal(object data) { _logSource.LogFatal(data); } internal static void Info(object data) { _logSource.LogInfo(data); } internal static void Message(object data) { _logSource.LogMessage(data); } internal static void Warning(object data) { _logSource.LogWarning(data); } } }