

using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Data;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Numerics;
using System.Reflection;
using System.Reflection.Emit;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Linq;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json.Bson;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Linq.JsonPath;
using Newtonsoft.Json.Schema;
using Newtonsoft.Json.Serialization;
using Newtonsoft.Json.Utilities;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AllowPartiallyTrustedCallers]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Schema, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Tests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100f561df277c6c0b497d629032b410cdcf286e537c054724f7ffa0164345f62b3e642029d7a80cc351918955328c4adc8a048823ef90b0cf38ea7db0d729caf2b633c3babe08b0310198c1081995c19029bc675193744eab9d7345b8a67258ec17d112cebdbbb2a281487dceeafb9d83aa930f32103fbe1d2911425bc5744002c7")]
[assembly: InternalsVisibleTo("Newtonsoft.Json.Dynamic, PublicKey=0024000004800000940000000602000000240000525341310004000001000100cbd8d53b9d7de30f1f1278f636ec462cf9c254991291e66ebb157a885638a517887633b898ccbcf0d5c5ff7be85a6abe9e765d0ac7cd33c68dac67e7e64530e8222101109f154ab14a941c490ac155cd1d4fcba0fabb49016b4ef28593b015cab5937da31172f03f67d09edda404b88a60023f062ae71d0b2e4438b74cc11dc9")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("9ca358aa-317b-4925-8ada-4a29e943a363")]
[assembly: CLSCompliant(true)]
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
[assembly: AssemblyCompany("Newtonsoft")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyCopyright("Copyright © James Newton-King 2008")]
[assembly: AssemblyDescription("Json.NET is a popular high-performance JSON framework for .NET")]
[assembly: AssemblyFileVersion("13.0.4.30916")]
[assembly: AssemblyInformationalVersion("13.0.4+4e13299d4b0ec96bd4df9954ef646bd2d1b5bf2a")]
[assembly: AssemblyProduct("Json.NET")]
[assembly: AssemblyTitle("Json.NET .NET 4.5")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/JamesNK/Newtonsoft.Json")]
[assembly: NeutralResourcesLanguage("en-US")]
[assembly: AssemblyVersion("13.0.0.0")]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class IsReadOnlyAttribute : Attribute
{
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
namespace System.Diagnostics.CodeAnalysis
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, Inherited = false)]
internal sealed class DynamicallyAccessedMembersAttribute : Attribute
{
public DynamicallyAccessedMemberTypes MemberTypes { get; }
public DynamicallyAccessedMembersAttribute(DynamicallyAccessedMemberTypes memberTypes)
{
MemberTypes = memberTypes;
}
}
[Flags]
internal enum DynamicallyAccessedMemberTypes
{
None = 0,
PublicParameterlessConstructor = 1,
PublicConstructors = 3,
NonPublicConstructors = 4,
PublicMethods = 8,
NonPublicMethods = 0x10,
PublicFields = 0x20,
NonPublicFields = 0x40,
PublicNestedTypes = 0x80,
NonPublicNestedTypes = 0x100,
PublicProperties = 0x200,
NonPublicProperties = 0x400,
PublicEvents = 0x800,
NonPublicEvents = 0x1000,
Interfaces = 0x2000,
All = -1
}
[AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
internal sealed class FeatureGuardAttribute : Attribute
{
public Type FeatureType { get; }
public FeatureGuardAttribute(Type featureType)
{
FeatureType = featureType;
}
}
[AttributeUsage(AttributeTargets.Property, Inherited = false)]
internal sealed class FeatureSwitchDefinitionAttribute : Attribute
{
public string SwitchName { get; }
public FeatureSwitchDefinitionAttribute(string switchName)
{
SwitchName = switchName;
}
}
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, AllowMultiple = true)]
internal sealed class NotNullAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false)]
internal sealed class NotNullWhenAttribute : Attribute
{
public bool ReturnValue { get; }
public NotNullWhenAttribute(bool returnValue)
{
ReturnValue = returnValue;
}
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue, Inherited = false)]
internal sealed class MaybeNullAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, Inherited = false)]
internal sealed class AllowNullAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
internal class DoesNotReturnIfAttribute : Attribute
{
public bool ParameterValue { get; }
public DoesNotReturnIfAttribute(bool parameterValue)
{
ParameterValue = parameterValue;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)]
internal sealed class RequiresDynamicCodeAttribute : Attribute
{
public string Message { get; }
public string? Url { get; set; }
public RequiresDynamicCodeAttribute(string message)
{
Message = message;
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Method, Inherited = false)]
internal sealed class RequiresUnreferencedCodeAttribute : Attribute
{
public string Message { get; }
public string? Url { get; set; }
public RequiresUnreferencedCodeAttribute(string message)
{
Message = message;
}
}
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
internal sealed class UnconditionalSuppressMessageAttribute : Attribute
{
public string Category { get; }
public string CheckId { get; }
public string? Scope { get; set; }
public string? Target { get; set; }
public string? MessageId { get; set; }
public string? Justification { get; set; }
public UnconditionalSuppressMessageAttribute(string category, string checkId)
{
Category = category;
CheckId = checkId;
}
}
}
namespace Newtonsoft.Json
{
public enum ConstructorHandling
{
Default,
AllowNonPublicDefaultConstructor
}
public enum DateFormatHandling
{
IsoDateFormat,
MicrosoftDateFormat
}
public enum DateParseHandling
{
None,
DateTime,
DateTimeOffset
}
public enum DateTimeZoneHandling
{
Local,
Utc,
Unspecified,
RoundtripKind
}
public class DefaultJsonNameTable : JsonNameTable
{
private class Entry
{
internal readonly string Value;
internal readonly int HashCode;
internal Entry Next;
internal Entry(string value, int hashCode, Entry next)
{
Value = value;
HashCode = hashCode;
Next = next;
}
}
private static readonly int HashCodeRandomizer;
private int _count;
private Entry[] _entries;
private int _mask = 31;
static DefaultJsonNameTable()
{
HashCodeRandomizer = Environment.TickCount;
}
public DefaultJsonNameTable()
{
_entries = new Entry[_mask + 1];
}
public override string? Get(char[] key, int start, int length)
{
if (length == 0)
{
return string.Empty;
}
int num = length + HashCodeRandomizer;
num += (num << 7) ^ key[start];
int num2 = start + length;
for (int i = start + 1; i < num2; i++)
{
num += (num << 7) ^ key[i];
}
num -= num >> 17;
num -= num >> 11;
num -= num >> 5;
int num3 = Volatile.Read(ref _mask);
int num4 = num & num3;
for (Entry entry = _entries[num4]; entry != null; entry = entry.Next)
{
if (entry.HashCode == num && TextEquals(entry.Value, key, start, length))
{
return entry.Value;
}
}
return null;
}
public string Add(string key)
{
if (key == null)
{
throw new ArgumentNullException("key");
}
int length = key.Length;
if (length == 0)
{
return string.Empty;
}
int num = length + HashCodeRandomizer;
for (int i = 0; i < key.Length; i++)
{
num += (num << 7) ^ key[i];
}
num -= num >> 17;
num -= num >> 11;
num -= num >> 5;
for (Entry entry = _entries[num & _mask]; entry != null; entry = entry.Next)
{
if (entry.HashCode == num && entry.Value.Equals(key, StringComparison.Ordinal))
{
return entry.Value;
}
}
return AddEntry(key, num);
}
private string AddEntry(string str, int hashCode)
{
int num = hashCode & _mask;
Entry entry = new Entry(str, hashCode, _entries[num]);
_entries[num] = entry;
if (_count++ == _mask)
{
Grow();
}
return entry.Value;
}
private void Grow()
{
Entry[] entries = _entries;
int num = _mask * 2 + 1;
Entry[] array = new Entry[num + 1];
for (int i = 0; i < entries.Length; i++)
{
Entry entry = entries[i];
while (entry != null)
{
int num2 = entry.HashCode & num;
Entry next = entry.Next;
entry.Next = array[num2];
array[num2] = entry;
entry = next;
}
}
_entries = array;
Volatile.Write(ref _mask, num);
}
private static bool TextEquals(string str1, char[] str2, int str2Start, int str2Length)
{
if (str1.Length != str2Length)
{
return false;
}
for (int i = 0; i < str1.Length; i++)
{
if (str1[i] != str2[str2Start + i])
{
return false;
}
}
return true;
}
}
[Flags]
public enum DefaultValueHandling
{
Include = 0,
Ignore = 1,
Populate = 2,
IgnoreAndPopulate = 3
}
public enum FloatFormatHandling
{
String,
Symbol,
DefaultValue
}
public enum FloatParseHandling
{
Double,
Decimal
}
public enum Formatting
{
None,
Indented
}
public interface IArrayPool<T>
{
T[] Rent(int minimumLength);
void Return(T[]? array);
}
public interface IJsonLineInfo
{
int LineNumber { get; }
int LinePosition { get; }
bool HasLineInfo();
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
public sealed class JsonArrayAttribute : JsonContainerAttribute
{
private bool _allowNullItems;
public bool AllowNullItems
{
get
{
return _allowNullItems;
}
set
{
_allowNullItems = value;
}
}
public JsonArrayAttribute()
{
}
public JsonArrayAttribute(bool allowNullItems)
{
_allowNullItems = allowNullItems;
}
public JsonArrayAttribute(string id)
: base(id)
{
}
}
[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)]
public sealed class JsonConstructorAttribute : Attribute
{
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
public abstract class JsonContainerAttribute : Attribute
{
internal bool? _isReference;
internal bool? _itemIsReference;
internal ReferenceLoopHandling? _itemReferenceLoopHandling;
internal TypeNameHandling? _itemTypeNameHandling;
private Type? _namingStrategyType;
private object[]? _namingStrategyParameters;
public string? Id { get; set; }
public string? Title { get; set; }
public string? Description { get; set; }
public Type? ItemConverterType { get; set; }
public object[]? ItemConverterParameters { get; set; }
public Type? NamingStrategyType
{
get
{
return _namingStrategyType;
}
set
{
_namingStrategyType = value;
NamingStrategyInstance = null;
}
}
public object[]? NamingStrategyParameters
{
get
{
return _namingStrategyParameters;
}
set
{
_namingStrategyParameters = value;
NamingStrategyInstance = null;
}
}
internal NamingStrategy? NamingStrategyInstance { get; set; }
public bool IsReference
{
get
{
return _isReference.GetValueOrDefault();
}
set
{
_isReference = value;
}
}
public bool ItemIsReference
{
get
{
return _itemIsReference.GetValueOrDefault();
}
set
{
_itemIsReference = value;
}
}
public ReferenceLoopHandling ItemReferenceLoopHandling
{
get
{
return _itemReferenceLoopHandling.GetValueOrDefault();
}
set
{
_itemReferenceLoopHandling = value;
}
}
public TypeNameHandling ItemTypeNameHandling
{
get
{
return _itemTypeNameHandling.GetValueOrDefault();
}
set
{
_itemTypeNameHandling = value;
}
}
protected JsonContainerAttribute()
{
}
protected JsonContainerAttribute(string id)
{
Id = id;
}
}
public static class JsonConvert
{
public static readonly string True = "true";
public static readonly string False = "false";
public static readonly string Null = "null";
public static readonly string Undefined = "undefined";
public static readonly string PositiveInfinity = "Infinity";
public static readonly string NegativeInfinity = "-Infinity";
public static readonly string NaN = "NaN";
public static Func<JsonSerializerSettings>? DefaultSettings { get; set; }
public static string ToString(DateTime value)
{
return ToString(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind);
}
public static string ToString(DateTime value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling)
{
DateTime value2 = DateTimeUtils.EnsureDateTime(value, timeZoneHandling);
using StringWriter stringWriter = StringUtils.CreateStringWriter(64);
stringWriter.Write('"');
DateTimeUtils.WriteDateTimeString(stringWriter, value2, format, null, CultureInfo.InvariantCulture);
stringWriter.Write('"');
return stringWriter.ToString();
}
public static string ToString(DateTimeOffset value)
{
return ToString(value, DateFormatHandling.IsoDateFormat);
}
public static string ToString(DateTimeOffset value, DateFormatHandling format)
{
using StringWriter stringWriter = StringUtils.CreateStringWriter(64);
stringWriter.Write('"');
DateTimeUtils.WriteDateTimeOffsetString(stringWriter, value, format, null, CultureInfo.InvariantCulture);
stringWriter.Write('"');
return stringWriter.ToString();
}
public static string ToString(bool value)
{
if (!value)
{
return False;
}
return True;
}
public static string ToString(char value)
{
return ToString(char.ToString(value));
}
public static string ToString(Enum value)
{
return value.ToString("D");
}
public static string ToString(int value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
public static string ToString(short value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
[CLSCompliant(false)]
public static string ToString(ushort value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
[CLSCompliant(false)]
public static string ToString(uint value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
public static string ToString(long value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
private static string ToStringInternal(BigInteger value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
[CLSCompliant(false)]
public static string ToString(ulong value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
public static string ToString(float value)
{
return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
}
internal static string ToString(float value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
{
return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
}
private static string EnsureFloatFormat(double value, string text, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
{
if (floatFormatHandling == FloatFormatHandling.Symbol || (!double.IsInfinity(value) && !double.IsNaN(value)))
{
return text;
}
if (floatFormatHandling == FloatFormatHandling.DefaultValue)
{
if (nullable)
{
return Null;
}
return "0.0";
}
return quoteChar + text + quoteChar;
}
public static string ToString(double value)
{
return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
}
internal static string ToString(double value, FloatFormatHandling floatFormatHandling, char quoteChar, bool nullable)
{
return EnsureFloatFormat(value, EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture)), floatFormatHandling, quoteChar, nullable);
}
private static string EnsureDecimalPlace(double value, string text)
{
if (double.IsNaN(value) || double.IsInfinity(value) || StringUtils.IndexOf(text, '.') != -1 || StringUtils.IndexOf(text, 'E') != -1 || StringUtils.IndexOf(text, 'e') != -1)
{
return text;
}
return text + ".0";
}
private static string EnsureDecimalPlace(string text)
{
if (StringUtils.IndexOf(text, '.') != -1)
{
return text;
}
return text + ".0";
}
public static string ToString(byte value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
[CLSCompliant(false)]
public static string ToString(sbyte value)
{
return value.ToString(null, CultureInfo.InvariantCulture);
}
public static string ToString(decimal value)
{
return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture));
}
public static string ToString(Guid value)
{
return ToString(value, '"');
}
internal static string ToString(Guid value, char quoteChar)
{
string text = value.ToString("D", CultureInfo.InvariantCulture);
string text2 = quoteChar.ToString(CultureInfo.InvariantCulture);
return text2 + text + text2;
}
public static string ToString(TimeSpan value)
{
return ToString(value, '"');
}
internal static string ToString(TimeSpan value, char quoteChar)
{
return ToString(value.ToString(), quoteChar);
}
public static string ToString(Uri? value)
{
if (value == null)
{
return Null;
}
return ToString(value, '"');
}
internal static string ToString(Uri value, char quoteChar)
{
return ToString(value.OriginalString, quoteChar);
}
public static string ToString(string? value)
{
return ToString(value, '"');
}
public static string ToString(string? value, char delimiter)
{
return ToString(value, delimiter, StringEscapeHandling.Default);
}
public static string ToString(string? value, char delimiter, StringEscapeHandling stringEscapeHandling)
{
if (delimiter != '"' && delimiter != '\'')
{
throw new ArgumentException("Delimiter must be a single or double quote.", "delimiter");
}
return JavaScriptUtils.ToEscapedJavaScriptString(value, delimiter, appendDelimiters: true, stringEscapeHandling);
}
public static string ToString(object? value)
{
if (value == null)
{
return Null;
}
return ConvertUtils.GetTypeCode(value.GetType()) switch
{
PrimitiveTypeCode.String => ToString((string)value),
PrimitiveTypeCode.Char => ToString((char)value),
PrimitiveTypeCode.Boolean => ToString((bool)value),
PrimitiveTypeCode.SByte => ToString((sbyte)value),
PrimitiveTypeCode.Int16 => ToString((short)value),
PrimitiveTypeCode.UInt16 => ToString((ushort)value),
PrimitiveTypeCode.Int32 => ToString((int)value),
PrimitiveTypeCode.Byte => ToString((byte)value),
PrimitiveTypeCode.UInt32 => ToString((uint)value),
PrimitiveTypeCode.Int64 => ToString((long)value),
PrimitiveTypeCode.UInt64 => ToString((ulong)value),
PrimitiveTypeCode.Single => ToString((float)value),
PrimitiveTypeCode.Double => ToString((double)value),
PrimitiveTypeCode.DateTime => ToString((DateTime)value),
PrimitiveTypeCode.Decimal => ToString((decimal)value),
PrimitiveTypeCode.DBNull => Null,
PrimitiveTypeCode.DateTimeOffset => ToString((DateTimeOffset)value),
PrimitiveTypeCode.Guid => ToString((Guid)value),
PrimitiveTypeCode.Uri => ToString((Uri)value),
PrimitiveTypeCode.TimeSpan => ToString((TimeSpan)value),
PrimitiveTypeCode.BigInteger => ToStringInternal((BigInteger)value),
_ => throw new ArgumentException("Unsupported type: {0}. Use the JsonSerializer class to get the object's JSON representation.".FormatWith(CultureInfo.InvariantCulture, value.GetType())),
};
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static string SerializeObject(object? value)
{
return SerializeObject(value, (Type?)null, (JsonSerializerSettings?)null);
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static string SerializeObject(object? value, Formatting formatting)
{
return SerializeObject(value, formatting, (JsonSerializerSettings?)null);
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static string SerializeObject(object? value, params JsonConverter[] converters)
{
JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
{
Converters = converters
} : null);
return SerializeObject(value, null, settings);
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static string SerializeObject(object? value, Formatting formatting, params JsonConverter[] converters)
{
JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
{
Converters = converters
} : null);
return SerializeObject(value, null, formatting, settings);
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static string SerializeObject(object? value, JsonSerializerSettings? settings)
{
return SerializeObject(value, null, settings);
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static string SerializeObject(object? value, Type? type, JsonSerializerSettings? settings)
{
JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
return SerializeObjectInternal(value, type, jsonSerializer);
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static string SerializeObject(object? value, Formatting formatting, JsonSerializerSettings? settings)
{
return SerializeObject(value, null, formatting, settings);
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static string SerializeObject(object? value, Type? type, Formatting formatting, JsonSerializerSettings? settings)
{
JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
jsonSerializer.Formatting = formatting;
return SerializeObjectInternal(value, type, jsonSerializer);
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
private static string SerializeObjectInternal(object? value, Type? type, JsonSerializer jsonSerializer)
{
StringWriter stringWriter = new StringWriter(new StringBuilder(256), CultureInfo.InvariantCulture);
using (JsonTextWriter jsonTextWriter = new JsonTextWriter(stringWriter))
{
jsonTextWriter.Formatting = jsonSerializer.Formatting;
jsonSerializer.Serialize(jsonTextWriter, value, type);
}
return stringWriter.ToString();
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static object? DeserializeObject(string value)
{
return DeserializeObject(value, (Type?)null, (JsonSerializerSettings?)null);
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static object? DeserializeObject(string value, JsonSerializerSettings settings)
{
return DeserializeObject(value, null, settings);
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static object? DeserializeObject(string value, Type type)
{
return DeserializeObject(value, type, (JsonSerializerSettings?)null);
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static T? DeserializeObject<T>(string value)
{
return JsonConvert.DeserializeObject<T>(value, (JsonSerializerSettings?)null);
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject)
{
return DeserializeObject<T>(value);
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static T? DeserializeAnonymousType<T>(string value, T anonymousTypeObject, JsonSerializerSettings settings)
{
return DeserializeObject<T>(value, settings);
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static T? DeserializeObject<T>(string value, params JsonConverter[] converters)
{
return (T)DeserializeObject(value, typeof(T), converters);
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static T? DeserializeObject<T>(string value, JsonSerializerSettings? settings)
{
return (T)DeserializeObject(value, typeof(T), settings);
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static object? DeserializeObject(string value, Type type, params JsonConverter[] converters)
{
JsonSerializerSettings settings = ((converters != null && converters.Length != 0) ? new JsonSerializerSettings
{
Converters = converters
} : null);
return DeserializeObject(value, type, settings);
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static object? DeserializeObject(string value, Type? type, JsonSerializerSettings? settings)
{
ValidationUtils.ArgumentNotNull(value, "value");
JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
if (!jsonSerializer.IsCheckAdditionalContentSet())
{
jsonSerializer.CheckAdditionalContent = true;
}
using JsonTextReader reader = new JsonTextReader(new StringReader(value));
return jsonSerializer.Deserialize(reader, type);
}
[DebuggerStepThrough]
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static void PopulateObject(string value, object target)
{
PopulateObject(value, target, null);
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static void PopulateObject(string value, object target, JsonSerializerSettings? settings)
{
JsonSerializer jsonSerializer = JsonSerializer.CreateDefault(settings);
using JsonReader jsonReader = new JsonTextReader(new StringReader(value));
jsonSerializer.Populate(jsonReader, target);
if (settings == null || !settings.CheckAdditionalContent)
{
return;
}
while (jsonReader.Read())
{
if (jsonReader.TokenType != JsonToken.Comment)
{
throw JsonSerializationException.Create(jsonReader, "Additional text found in JSON string after finishing deserializing object.");
}
}
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static string SerializeXmlNode(XmlNode? node)
{
return SerializeXmlNode(node, Formatting.None);
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static string SerializeXmlNode(XmlNode? node, Formatting formatting)
{
XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
return SerializeObject(node, formatting, xmlNodeConverter);
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static string SerializeXmlNode(XmlNode? node, Formatting formatting, bool omitRootObject)
{
XmlNodeConverter xmlNodeConverter = new XmlNodeConverter
{
OmitRootObject = omitRootObject
};
return SerializeObject(node, formatting, xmlNodeConverter);
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static XmlDocument? DeserializeXmlNode(string value)
{
return DeserializeXmlNode(value, null);
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName)
{
return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute: false);
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute)
{
return DeserializeXmlNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false);
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static XmlDocument? DeserializeXmlNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
{
XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName;
xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute;
xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters;
return (XmlDocument)DeserializeObject(value, typeof(XmlDocument), xmlNodeConverter);
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static string SerializeXNode(XObject? node)
{
return SerializeXNode(node, Formatting.None);
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static string SerializeXNode(XObject? node, Formatting formatting)
{
return SerializeXNode(node, formatting, omitRootObject: false);
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static string SerializeXNode(XObject? node, Formatting formatting, bool omitRootObject)
{
XmlNodeConverter xmlNodeConverter = new XmlNodeConverter
{
OmitRootObject = omitRootObject
};
return SerializeObject(node, formatting, xmlNodeConverter);
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static XDocument? DeserializeXNode(string value)
{
return DeserializeXNode(value, null);
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName)
{
return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute: false);
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute)
{
return DeserializeXNode(value, deserializeRootElementName, writeArrayAttribute, encodeSpecialCharacters: false);
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public static XDocument? DeserializeXNode(string value, string? deserializeRootElementName, bool writeArrayAttribute, bool encodeSpecialCharacters)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Expected O, but got Unknown
XmlNodeConverter xmlNodeConverter = new XmlNodeConverter();
xmlNodeConverter.DeserializeRootElementName = deserializeRootElementName;
xmlNodeConverter.WriteArrayAttribute = writeArrayAttribute;
xmlNodeConverter.EncodeSpecialCharacters = encodeSpecialCharacters;
return (XDocument)DeserializeObject(value, typeof(XDocument), xmlNodeConverter);
}
}
public abstract class JsonConverter
{
public virtual bool CanRead => true;
public virtual bool CanWrite => true;
public abstract void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer);
public abstract object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer);
public abstract bool CanConvert(Type objectType);
}
public abstract class JsonConverter<T> : JsonConverter
{
public sealed override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
{
if (!((value != null) ? (value is T) : ReflectionUtils.IsNullable(typeof(T))))
{
throw new JsonSerializationException("Converter cannot write specified value to JSON. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
}
WriteJson(writer, (T)value, serializer);
}
public abstract void WriteJson(JsonWriter writer, T? value, JsonSerializer serializer);
public sealed override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
{
bool flag = existingValue == null;
if (!flag && !(existingValue is T))
{
throw new JsonSerializationException("Converter cannot read JSON with the specified existing value. {0} is required.".FormatWith(CultureInfo.InvariantCulture, typeof(T)));
}
return ReadJson(reader, objectType, flag ? default(T) : ((T)existingValue), !flag, serializer);
}
public abstract T? ReadJson(JsonReader reader, Type objectType, T? existingValue, bool hasExistingValue, JsonSerializer serializer);
public sealed override bool CanConvert(Type objectType)
{
return typeof(T).IsAssignableFrom(objectType);
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Parameter, AllowMultiple = false)]
public sealed class JsonConverterAttribute : Attribute
{
private readonly Type _converterType;
public Type ConverterType => _converterType;
public object[]? ConverterParameters { get; }
public JsonConverterAttribute(Type converterType)
{
if (converterType == null)
{
throw new ArgumentNullException("converterType");
}
_converterType = converterType;
}
public JsonConverterAttribute(Type converterType, params object[] converterParameters)
: this(converterType)
{
ConverterParameters = converterParameters;
}
}
public class JsonConverterCollection : Collection<JsonConverter>
{
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false)]
public sealed class JsonDictionaryAttribute : JsonContainerAttribute
{
public JsonDictionaryAttribute()
{
}
public JsonDictionaryAttribute(string id)
: base(id)
{
}
}
[Serializable]
public class JsonException : Exception
{
public JsonException()
{
}
public JsonException(string message)
: base(message)
{
}
public JsonException(string message, Exception? innerException)
: base(message, innerException)
{
}
public JsonException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
internal static JsonException Create(IJsonLineInfo lineInfo, string path, string message)
{
message = JsonPosition.FormatMessage(lineInfo, path, message);
return new JsonException(message);
}
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public class JsonExtensionDataAttribute : Attribute
{
public bool WriteData { get; set; }
public bool ReadData { get; set; }
public JsonExtensionDataAttribute()
{
WriteData = true;
ReadData = true;
}
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public sealed class JsonIgnoreAttribute : Attribute
{
}
public abstract class JsonNameTable
{
public abstract string? Get(char[] key, int start, int length);
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, AllowMultiple = false)]
public sealed class JsonObjectAttribute : JsonContainerAttribute
{
private MemberSerialization _memberSerialization;
internal MissingMemberHandling? _missingMemberHandling;
internal Required? _itemRequired;
internal NullValueHandling? _itemNullValueHandling;
public MemberSerialization MemberSerialization
{
get
{
return _memberSerialization;
}
set
{
_memberSerialization = value;
}
}
public MissingMemberHandling MissingMemberHandling
{
get
{
return _missingMemberHandling.GetValueOrDefault();
}
set
{
_missingMemberHandling = value;
}
}
public NullValueHandling ItemNullValueHandling
{
get
{
return _itemNullValueHandling.GetValueOrDefault();
}
set
{
_itemNullValueHandling = value;
}
}
public Required ItemRequired
{
get
{
return _itemRequired.GetValueOrDefault();
}
set
{
_itemRequired = value;
}
}
public JsonObjectAttribute()
{
}
public JsonObjectAttribute(MemberSerialization memberSerialization)
{
MemberSerialization = memberSerialization;
}
public JsonObjectAttribute(string id)
: base(id)
{
}
}
internal enum JsonContainerType
{
None,
Object,
Array,
Constructor
}
internal struct JsonPosition
{
private static readonly char[] SpecialCharacters = new char[18]
{
'.', ' ', '\'', '/', '"', '[', ']', '(', ')', '\t',
'\n', '\r', '\f', '\b', '\\', '\u0085', '\u2028', '\u2029'
};
internal JsonContainerType Type;
internal int Position;
internal string? PropertyName;
internal bool HasIndex;
public JsonPosition(JsonContainerType type)
{
Type = type;
HasIndex = TypeHasIndex(type);
Position = -1;
PropertyName = null;
}
internal int CalculateLength()
{
switch (Type)
{
case JsonContainerType.Object:
return PropertyName.Length + 5;
case JsonContainerType.Array:
case JsonContainerType.Constructor:
return MathUtils.IntLength((ulong)Position) + 2;
default:
throw new ArgumentOutOfRangeException("Type");
}
}
internal void WriteTo(StringBuilder sb, ref StringWriter? writer, ref char[]? buffer)
{
switch (Type)
{
case JsonContainerType.Object:
{
string propertyName = PropertyName;
if (propertyName.IndexOfAny(SpecialCharacters) != -1)
{
sb.Append("['");
if (writer == null)
{
writer = new StringWriter(sb);
}
JavaScriptUtils.WriteEscapedJavaScriptString(writer, propertyName, '\'', appendDelimiters: false, JavaScriptUtils.SingleQuoteCharEscapeFlags, StringEscapeHandling.Default, null, ref buffer);
sb.Append("']");
}
else
{
if (sb.Length > 0)
{
sb.Append('.');
}
sb.Append(propertyName);
}
break;
}
case JsonContainerType.Array:
case JsonContainerType.Constructor:
sb.Append('[');
sb.Append(Position);
sb.Append(']');
break;
}
}
internal static bool TypeHasIndex(JsonContainerType type)
{
if (type != JsonContainerType.Array)
{
return type == JsonContainerType.Constructor;
}
return true;
}
internal static string BuildPath(List<JsonPosition> positions, JsonPosition? currentPosition)
{
int num = 0;
if (positions != null)
{
for (int i = 0; i < positions.Count; i++)
{
num += positions[i].CalculateLength();
}
}
if (currentPosition.HasValue)
{
num += currentPosition.GetValueOrDefault().CalculateLength();
}
StringBuilder stringBuilder = new StringBuilder(num);
StringWriter writer = null;
char[] buffer = null;
if (positions != null)
{
foreach (JsonPosition position in positions)
{
position.WriteTo(stringBuilder, ref writer, ref buffer);
}
}
currentPosition?.WriteTo(stringBuilder, ref writer, ref buffer);
return stringBuilder.ToString();
}
internal static string FormatMessage(IJsonLineInfo? lineInfo, string path, string message)
{
if (!message.EndsWith(Environment.NewLine, StringComparison.Ordinal))
{
message = message.Trim();
if (!StringUtils.EndsWith(message, '.'))
{
message += ".";
}
message += " ";
}
message += "Path '{0}'".FormatWith(CultureInfo.InvariantCulture, path);
if (lineInfo != null && lineInfo.HasLineInfo())
{
message += ", line {0}, position {1}".FormatWith(CultureInfo.InvariantCulture, lineInfo.LineNumber, lineInfo.LinePosition);
}
message += ".";
return message;
}
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false)]
public sealed class JsonPropertyAttribute : Attribute
{
internal NullValueHandling? _nullValueHandling;
internal DefaultValueHandling? _defaultValueHandling;
internal ReferenceLoopHandling? _referenceLoopHandling;
internal ObjectCreationHandling? _objectCreationHandling;
internal TypeNameHandling? _typeNameHandling;
internal bool? _isReference;
internal int? _order;
internal Required? _required;
internal bool? _itemIsReference;
internal ReferenceLoopHandling? _itemReferenceLoopHandling;
internal TypeNameHandling? _itemTypeNameHandling;
public Type? ItemConverterType { get; set; }
public object[]? ItemConverterParameters { get; set; }
public Type? NamingStrategyType { get; set; }
public object[]? NamingStrategyParameters { get; set; }
public NullValueHandling NullValueHandling
{
get
{
return _nullValueHandling.GetValueOrDefault();
}
set
{
_nullValueHandling = value;
}
}
public DefaultValueHandling DefaultValueHandling
{
get
{
return _defaultValueHandling.GetValueOrDefault();
}
set
{
_defaultValueHandling = value;
}
}
public ReferenceLoopHandling ReferenceLoopHandling
{
get
{
return _referenceLoopHandling.GetValueOrDefault();
}
set
{
_referenceLoopHandling = value;
}
}
public ObjectCreationHandling ObjectCreationHandling
{
get
{
return _objectCreationHandling.GetValueOrDefault();
}
set
{
_objectCreationHandling = value;
}
}
public TypeNameHandling TypeNameHandling
{
get
{
return _typeNameHandling.GetValueOrDefault();
}
set
{
_typeNameHandling = value;
}
}
public bool IsReference
{
get
{
return _isReference.GetValueOrDefault();
}
set
{
_isReference = value;
}
}
public int Order
{
get
{
return _order.GetValueOrDefault();
}
set
{
_order = value;
}
}
public Required Required
{
get
{
return _required.GetValueOrDefault();
}
set
{
_required = value;
}
}
public string? PropertyName { get; set; }
public ReferenceLoopHandling ItemReferenceLoopHandling
{
get
{
return _itemReferenceLoopHandling.GetValueOrDefault();
}
set
{
_itemReferenceLoopHandling = value;
}
}
public TypeNameHandling ItemTypeNameHandling
{
get
{
return _itemTypeNameHandling.GetValueOrDefault();
}
set
{
_itemTypeNameHandling = value;
}
}
public bool ItemIsReference
{
get
{
return _itemIsReference.GetValueOrDefault();
}
set
{
_itemIsReference = value;
}
}
public JsonPropertyAttribute()
{
}
public JsonPropertyAttribute(string propertyName)
{
PropertyName = propertyName;
}
}
public abstract class JsonReader : IDisposable
{
protected internal enum State
{
Start,
Complete,
Property,
ObjectStart,
Object,
ArrayStart,
Array,
Closed,
PostValue,
ConstructorStart,
Constructor,
Error,
Finished
}
private JsonToken _tokenType;
private object? _value;
internal char _quoteChar;
internal State _currentState;
private JsonPosition _currentPosition;
private CultureInfo? _culture;
private DateTimeZoneHandling _dateTimeZoneHandling;
private int? _maxDepth;
private bool _hasExceededMaxDepth;
internal DateParseHandling _dateParseHandling;
internal FloatParseHandling _floatParseHandling;
private string? _dateFormatString;
private List<JsonPosition>? _stack;
protected State CurrentState => _currentState;
public bool CloseInput { get; set; }
public bool SupportMultipleContent { get; set; }
public virtual char QuoteChar
{
get
{
return _quoteChar;
}
protected internal set
{
_quoteChar = value;
}
}
public DateTimeZoneHandling DateTimeZoneHandling
{
get
{
return _dateTimeZoneHandling;
}
set
{
if (value < DateTimeZoneHandling.Local || value > DateTimeZoneHandling.RoundtripKind)
{
throw new ArgumentOutOfRangeException("value");
}
_dateTimeZoneHandling = value;
}
}
public DateParseHandling DateParseHandling
{
get
{
return _dateParseHandling;
}
set
{
if (value < DateParseHandling.None || value > DateParseHandling.DateTimeOffset)
{
throw new ArgumentOutOfRangeException("value");
}
_dateParseHandling = value;
}
}
public FloatParseHandling FloatParseHandling
{
get
{
return _floatParseHandling;
}
set
{
if (value < FloatParseHandling.Double || value > FloatParseHandling.Decimal)
{
throw new ArgumentOutOfRangeException("value");
}
_floatParseHandling = value;
}
}
public string? DateFormatString
{
get
{
return _dateFormatString;
}
set
{
_dateFormatString = value;
}
}
public int? MaxDepth
{
get
{
return _maxDepth;
}
set
{
if (value <= 0)
{
throw new ArgumentException("Value must be positive.", "value");
}
_maxDepth = value;
}
}
public virtual JsonToken TokenType => _tokenType;
public virtual object? Value => _value;
public virtual Type? ValueType => _value?.GetType();
public virtual int Depth
{
get
{
int num = _stack?.Count ?? 0;
if (JsonTokenUtils.IsStartToken(TokenType) || _currentPosition.Type == JsonContainerType.None)
{
return num;
}
return num + 1;
}
}
public virtual string Path
{
get
{
if (_currentPosition.Type == JsonContainerType.None)
{
return string.Empty;
}
JsonPosition? currentPosition = ((_currentState != State.ArrayStart && _currentState != State.ConstructorStart && _currentState != State.ObjectStart) ? new JsonPosition?(_currentPosition) : null);
return JsonPosition.BuildPath(_stack, currentPosition);
}
}
public CultureInfo Culture
{
get
{
return _culture ?? CultureInfo.InvariantCulture;
}
set
{
_culture = value;
}
}
public virtual Task<bool> ReadAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return cancellationToken.CancelIfRequestedAsync<bool>() ?? Read().ToAsync();
}
public async Task SkipAsync(CancellationToken cancellationToken = default(CancellationToken))
{
if (TokenType == JsonToken.PropertyName)
{
await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
}
if (JsonTokenUtils.IsStartToken(TokenType))
{
int depth = Depth;
while (await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false) && depth < Depth)
{
}
}
}
internal async Task ReaderReadAndAssertAsync(CancellationToken cancellationToken)
{
if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
{
throw CreateUnexpectedEndException();
}
}
public virtual Task<bool?> ReadAsBooleanAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return cancellationToken.CancelIfRequestedAsync<bool?>() ?? Task.FromResult(ReadAsBoolean());
}
public virtual Task<byte[]?> ReadAsBytesAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return cancellationToken.CancelIfRequestedAsync<byte[]>() ?? Task.FromResult(ReadAsBytes());
}
internal async Task<byte[]?> ReadArrayIntoByteArrayAsync(CancellationToken cancellationToken)
{
List<byte> buffer = new List<byte>();
do
{
if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
{
SetToken(JsonToken.None);
}
}
while (!ReadArrayElementIntoByteArrayReportDone(buffer));
byte[] array = buffer.ToArray();
SetToken(JsonToken.Bytes, array, updateIndex: false);
return array;
}
public virtual Task<DateTime?> ReadAsDateTimeAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return cancellationToken.CancelIfRequestedAsync<DateTime?>() ?? Task.FromResult(ReadAsDateTime());
}
public virtual Task<DateTimeOffset?> ReadAsDateTimeOffsetAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return cancellationToken.CancelIfRequestedAsync<DateTimeOffset?>() ?? Task.FromResult(ReadAsDateTimeOffset());
}
public virtual Task<decimal?> ReadAsDecimalAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return cancellationToken.CancelIfRequestedAsync<decimal?>() ?? Task.FromResult(ReadAsDecimal());
}
public virtual Task<double?> ReadAsDoubleAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return Task.FromResult(ReadAsDouble());
}
public virtual Task<int?> ReadAsInt32Async(CancellationToken cancellationToken = default(CancellationToken))
{
return cancellationToken.CancelIfRequestedAsync<int?>() ?? Task.FromResult(ReadAsInt32());
}
public virtual Task<string?> ReadAsStringAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return cancellationToken.CancelIfRequestedAsync<string>() ?? Task.FromResult(ReadAsString());
}
internal async Task<bool> ReadAndMoveToContentAsync(CancellationToken cancellationToken)
{
bool flag = await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
if (flag)
{
flag = await MoveToContentAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
}
return flag;
}
internal Task<bool> MoveToContentAsync(CancellationToken cancellationToken)
{
JsonToken tokenType = TokenType;
if (tokenType == JsonToken.None || tokenType == JsonToken.Comment)
{
return MoveToContentFromNonContentAsync(cancellationToken);
}
return AsyncUtils.True;
}
private async Task<bool> MoveToContentFromNonContentAsync(CancellationToken cancellationToken)
{
JsonToken tokenType;
do
{
if (!(await ReadAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false)))
{
return false;
}
tokenType = TokenType;
}
while (tokenType == JsonToken.None || tokenType == JsonToken.Comment);
return true;
}
internal JsonPosition GetPosition(int depth)
{
if (_stack != null && depth < _stack.Count)
{
return _stack[depth];
}
return _currentPosition;
}
protected JsonReader()
{
_currentState = State.Start;
_dateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind;
_dateParseHandling = DateParseHandling.DateTime;
_floatParseHandling = FloatParseHandling.Double;
_maxDepth = 64;
CloseInput = true;
}
private void Push(JsonContainerType value)
{
UpdateScopeWithFinishedValue();
if (_currentPosition.Type == JsonContainerType.None)
{
_currentPosition = new JsonPosition(value);
return;
}
if (_stack == null)
{
_stack = new List<JsonPosition>();
}
_stack.Add(_currentPosition);
_currentPosition = new JsonPosition(value);
if (!_maxDepth.HasValue || !(Depth + 1 > _maxDepth) || _hasExceededMaxDepth)
{
return;
}
_hasExceededMaxDepth = true;
throw JsonReaderException.Create(this, "The reader's MaxDepth of {0} has been exceeded.".FormatWith(CultureInfo.InvariantCulture, _maxDepth));
}
private JsonContainerType Pop()
{
JsonPosition currentPosition;
if (_stack != null && _stack.Count > 0)
{
currentPosition = _currentPosition;
_currentPosition = _stack[_stack.Count - 1];
_stack.RemoveAt(_stack.Count - 1);
}
else
{
currentPosition = _currentPosition;
_currentPosition = default(JsonPosition);
}
if (_maxDepth.HasValue && Depth <= _maxDepth)
{
_hasExceededMaxDepth = false;
}
return currentPosition.Type;
}
private JsonContainerType Peek()
{
return _currentPosition.Type;
}
public abstract bool Read();
public virtual int? ReadAsInt32()
{
JsonToken contentToken = GetContentToken();
switch (contentToken)
{
case JsonToken.None:
case JsonToken.Null:
case JsonToken.EndArray:
return null;
case JsonToken.Integer:
case JsonToken.Float:
{
object value = Value;
if (value is int)
{
return (int)value;
}
int num;
if (value is BigInteger bigInteger)
{
num = (int)bigInteger;
}
else
{
try
{
num = Convert.ToInt32(value, CultureInfo.InvariantCulture);
}
catch (Exception ex)
{
throw JsonReaderException.Create(this, "Could not convert to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex);
}
}
SetToken(JsonToken.Integer, num, updateIndex: false);
return num;
}
case JsonToken.String:
{
string s = (string)Value;
return ReadInt32String(s);
}
default:
throw JsonReaderException.Create(this, "Error reading integer. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
}
}
internal int? ReadInt32String(string? s)
{
if (StringUtils.IsNullOrEmpty(s))
{
SetToken(JsonToken.Null, null, updateIndex: false);
return null;
}
if (int.TryParse(s, NumberStyles.Integer, Culture, out var result))
{
SetToken(JsonToken.Integer, result, updateIndex: false);
return result;
}
SetToken(JsonToken.String, s, updateIndex: false);
throw JsonReaderException.Create(this, "Could not convert string to integer: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
}
public virtual string? ReadAsString()
{
JsonToken contentToken = GetContentToken();
switch (contentToken)
{
case JsonToken.None:
case JsonToken.Null:
case JsonToken.EndArray:
return null;
case JsonToken.String:
return (string)Value;
default:
if (JsonTokenUtils.IsPrimitiveToken(contentToken))
{
object value = Value;
if (value != null)
{
string text = ((!(value is IFormattable formattable)) ? ((value is Uri uri) ? uri.OriginalString : value.ToString()) : formattable.ToString(null, Culture));
SetToken(JsonToken.String, text, updateIndex: false);
return text;
}
}
throw JsonReaderException.Create(this, "Error reading string. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
}
}
public virtual byte[]? ReadAsBytes()
{
JsonToken contentToken = GetContentToken();
switch (contentToken)
{
case JsonToken.StartObject:
{
ReadIntoWrappedTypeObject();
byte[] array2 = ReadAsBytes();
ReaderReadAndAssert();
if (TokenType != JsonToken.EndObject)
{
throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
}
SetToken(JsonToken.Bytes, array2, updateIndex: false);
return array2;
}
case JsonToken.String:
{
string text = (string)Value;
Guid g;
byte[] array3 = ((text.Length == 0) ? CollectionUtils.ArrayEmpty<byte>() : ((!ConvertUtils.TryConvertGuid(text, out g)) ? Convert.FromBase64String(text) : g.ToByteArray()));
SetToken(JsonToken.Bytes, array3, updateIndex: false);
return array3;
}
case JsonToken.None:
case JsonToken.Null:
case JsonToken.EndArray:
return null;
case JsonToken.Bytes:
if (Value is Guid guid)
{
byte[] array = guid.ToByteArray();
SetToken(JsonToken.Bytes, array, updateIndex: false);
return array;
}
return (byte[])Value;
case JsonToken.StartArray:
return ReadArrayIntoByteArray();
default:
throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
}
}
internal byte[] ReadArrayIntoByteArray()
{
List<byte> list = new List<byte>();
do
{
if (!Read())
{
SetToken(JsonToken.None);
}
}
while (!ReadArrayElementIntoByteArrayReportDone(list));
byte[] array = list.ToArray();
SetToken(JsonToken.Bytes, array, updateIndex: false);
return array;
}
private bool ReadArrayElementIntoByteArrayReportDone(List<byte> buffer)
{
switch (TokenType)
{
case JsonToken.None:
throw JsonReaderException.Create(this, "Unexpected end when reading bytes.");
case JsonToken.Integer:
buffer.Add(Convert.ToByte(Value, CultureInfo.InvariantCulture));
return false;
case JsonToken.EndArray:
return true;
case JsonToken.Comment:
return false;
default:
throw JsonReaderException.Create(this, "Unexpected token when reading bytes: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
}
}
public virtual double? ReadAsDouble()
{
JsonToken contentToken = GetContentToken();
switch (contentToken)
{
case JsonToken.None:
case JsonToken.Null:
case JsonToken.EndArray:
return null;
case JsonToken.Integer:
case JsonToken.Float:
{
object value = Value;
if (value is double)
{
return (double)value;
}
double num = ((!(value is BigInteger bigInteger)) ? Convert.ToDouble(value, CultureInfo.InvariantCulture) : ((double)bigInteger));
SetToken(JsonToken.Float, num, updateIndex: false);
return num;
}
case JsonToken.String:
return ReadDoubleString((string)Value);
default:
throw JsonReaderException.Create(this, "Error reading double. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
}
}
internal double? ReadDoubleString(string? s)
{
if (StringUtils.IsNullOrEmpty(s))
{
SetToken(JsonToken.Null, null, updateIndex: false);
return null;
}
if (double.TryParse(s, NumberStyles.Float | NumberStyles.AllowThousands, Culture, out var result))
{
SetToken(JsonToken.Float, result, updateIndex: false);
return result;
}
SetToken(JsonToken.String, s, updateIndex: false);
throw JsonReaderException.Create(this, "Could not convert string to double: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
}
public virtual bool? ReadAsBoolean()
{
JsonToken contentToken = GetContentToken();
switch (contentToken)
{
case JsonToken.None:
case JsonToken.Null:
case JsonToken.EndArray:
return null;
case JsonToken.Integer:
case JsonToken.Float:
{
bool flag = ((!(Value is BigInteger bigInteger)) ? Convert.ToBoolean(Value, CultureInfo.InvariantCulture) : (bigInteger != 0L));
SetToken(JsonToken.Boolean, flag, updateIndex: false);
return flag;
}
case JsonToken.String:
return ReadBooleanString((string)Value);
case JsonToken.Boolean:
return (bool)Value;
default:
throw JsonReaderException.Create(this, "Error reading boolean. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
}
}
internal bool? ReadBooleanString(string? s)
{
if (StringUtils.IsNullOrEmpty(s))
{
SetToken(JsonToken.Null, null, updateIndex: false);
return null;
}
if (bool.TryParse(s, out var result))
{
SetToken(JsonToken.Boolean, result, updateIndex: false);
return result;
}
SetToken(JsonToken.String, s, updateIndex: false);
throw JsonReaderException.Create(this, "Could not convert string to boolean: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
}
public virtual decimal? ReadAsDecimal()
{
JsonToken contentToken = GetContentToken();
switch (contentToken)
{
case JsonToken.None:
case JsonToken.Null:
case JsonToken.EndArray:
return null;
case JsonToken.Integer:
case JsonToken.Float:
{
object value = Value;
if (value is decimal)
{
return (decimal)value;
}
decimal num;
if (value is BigInteger bigInteger)
{
num = (decimal)bigInteger;
}
else
{
try
{
num = Convert.ToDecimal(value, CultureInfo.InvariantCulture);
}
catch (Exception ex)
{
throw JsonReaderException.Create(this, "Could not convert to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, value), ex);
}
}
SetToken(JsonToken.Float, num, updateIndex: false);
return num;
}
case JsonToken.String:
return ReadDecimalString((string)Value);
default:
throw JsonReaderException.Create(this, "Error reading decimal. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
}
}
internal decimal? ReadDecimalString(string? s)
{
if (StringUtils.IsNullOrEmpty(s))
{
SetToken(JsonToken.Null, null, updateIndex: false);
return null;
}
if (decimal.TryParse(s, NumberStyles.Number, Culture, out var result))
{
SetToken(JsonToken.Float, result, updateIndex: false);
return result;
}
if (ConvertUtils.DecimalTryParse(s.ToCharArray(), 0, s.Length, out result) == ParseResult.Success)
{
SetToken(JsonToken.Float, result, updateIndex: false);
return result;
}
SetToken(JsonToken.String, s, updateIndex: false);
throw JsonReaderException.Create(this, "Could not convert string to decimal: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
}
public virtual DateTime? ReadAsDateTime()
{
switch (GetContentToken())
{
case JsonToken.None:
case JsonToken.Null:
case JsonToken.EndArray:
return null;
case JsonToken.Date:
if (Value is DateTimeOffset dateTimeOffset)
{
SetToken(JsonToken.Date, dateTimeOffset.DateTime, updateIndex: false);
}
return (DateTime)Value;
case JsonToken.String:
return ReadDateTimeString((string)Value);
default:
throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType));
}
}
internal DateTime? ReadDateTimeString(string? s)
{
if (StringUtils.IsNullOrEmpty(s))
{
SetToken(JsonToken.Null, null, updateIndex: false);
return null;
}
if (DateTimeUtils.TryParseDateTime(s, DateTimeZoneHandling, _dateFormatString, Culture, out var dt))
{
dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
SetToken(JsonToken.Date, dt, updateIndex: false);
return dt;
}
if (DateTime.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
{
dt = DateTimeUtils.EnsureDateTime(dt, DateTimeZoneHandling);
SetToken(JsonToken.Date, dt, updateIndex: false);
return dt;
}
throw JsonReaderException.Create(this, "Could not convert string to DateTime: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
}
public virtual DateTimeOffset? ReadAsDateTimeOffset()
{
JsonToken contentToken = GetContentToken();
switch (contentToken)
{
case JsonToken.None:
case JsonToken.Null:
case JsonToken.EndArray:
return null;
case JsonToken.Date:
if (Value is DateTime dateTime)
{
SetToken(JsonToken.Date, new DateTimeOffset(dateTime), updateIndex: false);
}
return (DateTimeOffset)Value;
case JsonToken.String:
{
string s = (string)Value;
return ReadDateTimeOffsetString(s);
}
default:
throw JsonReaderException.Create(this, "Error reading date. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, contentToken));
}
}
internal DateTimeOffset? ReadDateTimeOffsetString(string? s)
{
if (StringUtils.IsNullOrEmpty(s))
{
SetToken(JsonToken.Null, null, updateIndex: false);
return null;
}
if (DateTimeUtils.TryParseDateTimeOffset(s, _dateFormatString, Culture, out var dt))
{
SetToken(JsonToken.Date, dt, updateIndex: false);
return dt;
}
if (DateTimeOffset.TryParse(s, Culture, DateTimeStyles.RoundtripKind, out dt))
{
SetToken(JsonToken.Date, dt, updateIndex: false);
return dt;
}
SetToken(JsonToken.String, s, updateIndex: false);
throw JsonReaderException.Create(this, "Could not convert string to DateTimeOffset: {0}.".FormatWith(CultureInfo.InvariantCulture, s));
}
internal void ReaderReadAndAssert()
{
if (!Read())
{
throw CreateUnexpectedEndException();
}
}
internal JsonReaderException CreateUnexpectedEndException()
{
return JsonReaderException.Create(this, "Unexpected end when reading JSON.");
}
internal void ReadIntoWrappedTypeObject()
{
ReaderReadAndAssert();
if (Value != null && Value.ToString() == "$type")
{
ReaderReadAndAssert();
if (Value != null && Value.ToString().StartsWith("System.Byte[]", StringComparison.Ordinal))
{
ReaderReadAndAssert();
if (Value.ToString() == "$value")
{
return;
}
}
}
throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, JsonToken.StartObject));
}
public void Skip()
{
if (TokenType == JsonToken.PropertyName)
{
Read();
}
if (JsonTokenUtils.IsStartToken(TokenType))
{
int depth = Depth;
while (Read() && depth < Depth)
{
}
}
}
protected void SetToken(JsonToken newToken)
{
SetToken(newToken, null, updateIndex: true);
}
protected void SetToken(JsonToken newToken, object? value)
{
SetToken(newToken, value, updateIndex: true);
}
protected void SetToken(JsonToken newToken, object? value, bool updateIndex)
{
_tokenType = newToken;
_value = value;
switch (newToken)
{
case JsonToken.StartObject:
_currentState = State.ObjectStart;
Push(JsonContainerType.Object);
break;
case JsonToken.StartArray:
_currentState = State.ArrayStart;
Push(JsonContainerType.Array);
break;
case JsonToken.StartConstructor:
_currentState = State.ConstructorStart;
Push(JsonContainerType.Constructor);
break;
case JsonToken.EndObject:
ValidateEnd(JsonToken.EndObject);
break;
case JsonToken.EndArray:
ValidateEnd(JsonToken.EndArray);
break;
case JsonToken.EndConstructor:
ValidateEnd(JsonToken.EndConstructor);
break;
case JsonToken.PropertyName:
_currentState = State.Property;
_currentPosition.PropertyName = (string)value;
break;
case JsonToken.Raw:
case JsonToken.Integer:
case JsonToken.Float:
case JsonToken.String:
case JsonToken.Boolean:
case JsonToken.Null:
case JsonToken.Undefined:
case JsonToken.Date:
case JsonToken.Bytes:
SetPostValueState(updateIndex);
break;
case JsonToken.Comment:
break;
}
}
internal void SetPostValueState(bool updateIndex)
{
if (Peek() != 0 || SupportMultipleContent)
{
_currentState = State.PostValue;
}
else
{
SetFinished();
}
if (updateIndex)
{
UpdateScopeWithFinishedValue();
}
}
private void UpdateScopeWithFinishedValue()
{
if (_currentPosition.HasIndex)
{
_currentPosition.Position++;
}
}
private void ValidateEnd(JsonToken endToken)
{
JsonContainerType jsonContainerType = Pop();
if (GetTypeForCloseToken(endToken) != jsonContainerType)
{
throw JsonReaderException.Create(this, "JsonToken {0} is not valid for closing JsonType {1}.".FormatWith(CultureInfo.InvariantCulture, endToken, jsonContainerType));
}
if (Peek() != 0 || SupportMultipleContent)
{
_currentState = State.PostValue;
}
else
{
SetFinished();
}
}
protected void SetStateBasedOnCurrent()
{
JsonContainerType jsonContainerType = Peek();
switch (jsonContainerType)
{
case JsonContainerType.Object:
_currentState = State.Object;
break;
case JsonContainerType.Array:
_currentState = State.Array;
break;
case JsonContainerType.Constructor:
_currentState = State.Constructor;
break;
case JsonContainerType.None:
SetFinished();
break;
default:
throw JsonReaderException.Create(this, "While setting the reader state back to current object an unexpected JsonType was encountered: {0}".FormatWith(CultureInfo.InvariantCulture, jsonContainerType));
}
}
private void SetFinished()
{
_currentState = ((!SupportMultipleContent) ? State.Finished : State.Start);
}
private JsonContainerType GetTypeForCloseToken(JsonToken token)
{
return token switch
{
JsonToken.EndObject => JsonContainerType.Object,
JsonToken.EndArray => JsonContainerType.Array,
JsonToken.EndConstructor => JsonContainerType.Constructor,
_ => throw JsonReaderException.Create(this, "Not a valid close JsonToken: {0}".FormatWith(CultureInfo.InvariantCulture, token)),
};
}
void IDisposable.Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_currentState != State.Closed && disposing)
{
Close();
}
}
public virtual void Close()
{
_currentState = State.Closed;
_tokenType = JsonToken.None;
_value = null;
}
internal void ReadAndAssert()
{
if (!Read())
{
throw JsonSerializationException.Create(this, "Unexpected end when reading JSON.");
}
}
internal void ReadForTypeAndAssert(JsonContract? contract, bool hasConverter)
{
if (!ReadForType(contract, hasConverter))
{
throw JsonSerializationException.Create(this, "Unexpected end when reading JSON.");
}
}
internal bool ReadForType(JsonContract? contract, bool hasConverter)
{
if (hasConverter)
{
return Read();
}
switch (contract?.InternalReadType ?? ReadType.Read)
{
case ReadType.Read:
return ReadAndMoveToContent();
case ReadType.ReadAsInt32:
ReadAsInt32();
break;
case ReadType.ReadAsInt64:
{
bool result = ReadAndMoveToContent();
if (TokenType == JsonToken.Undefined)
{
throw JsonReaderException.Create(this, "An undefined token is not a valid {0}.".FormatWith(CultureInfo.InvariantCulture, contract?.UnderlyingType ?? typeof(long)));
}
return result;
}
case ReadType.ReadAsDecimal:
ReadAsDecimal();
break;
case ReadType.ReadAsDouble:
ReadAsDouble();
break;
case ReadType.ReadAsBytes:
ReadAsBytes();
break;
case ReadType.ReadAsBoolean:
ReadAsBoolean();
break;
case ReadType.ReadAsString:
ReadAsString();
break;
case ReadType.ReadAsDateTime:
ReadAsDateTime();
break;
case ReadType.ReadAsDateTimeOffset:
ReadAsDateTimeOffset();
break;
default:
throw new ArgumentOutOfRangeException();
}
return TokenType != JsonToken.None;
}
internal bool ReadAndMoveToContent()
{
if (Read())
{
return MoveToContent();
}
return false;
}
internal bool MoveToContent()
{
JsonToken tokenType = TokenType;
while (tokenType == JsonToken.None || tokenType == JsonToken.Comment)
{
if (!Read())
{
return false;
}
tokenType = TokenType;
}
return true;
}
private JsonToken GetContentToken()
{
JsonToken tokenType;
do
{
if (!Read())
{
SetToken(JsonToken.None);
return JsonToken.None;
}
tokenType = TokenType;
}
while (tokenType == JsonToken.Comment);
return tokenType;
}
}
[Serializable]
public class JsonReaderException : JsonException
{
public int LineNumber { get; }
public int LinePosition { get; }
public string? Path { get; }
public JsonReaderException()
{
}
public JsonReaderException(string message)
: base(message)
{
}
public JsonReaderException(string message, Exception innerException)
: base(message, innerException)
{
}
public JsonReaderException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
public JsonReaderException(string message, string path, int lineNumber, int linePosition, Exception? innerException)
: base(message, innerException)
{
Path = path;
LineNumber = lineNumber;
LinePosition = linePosition;
}
internal static JsonReaderException Create(JsonReader reader, string message)
{
return Create(reader, message, null);
}
internal static JsonReaderException Create(JsonReader reader, string message, Exception? ex)
{
return Create(reader as IJsonLineInfo, reader.Path, message, ex);
}
internal static JsonReaderException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex)
{
message = JsonPosition.FormatMessage(lineInfo, path, message);
int lineNumber;
int linePosition;
if (lineInfo != null && lineInfo.HasLineInfo())
{
lineNumber = lineInfo.LineNumber;
linePosition = lineInfo.LinePosition;
}
else
{
lineNumber = 0;
linePosition = 0;
}
return new JsonReaderException(message, path, lineNumber, linePosition, ex);
}
}
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)]
public sealed class JsonRequiredAttribute : Attribute
{
}
[Serializable]
public class JsonSerializationException : JsonException
{
public int LineNumber { get; }
public int LinePosition { get; }
public string? Path { get; }
public JsonSerializationException()
{
}
public JsonSerializationException(string message)
: base(message)
{
}
public JsonSerializationException(string message, Exception innerException)
: base(message, innerException)
{
}
public JsonSerializationException(SerializationInfo info, StreamingContext context)
: base(info, context)
{
}
public JsonSerializationException(string message, string path, int lineNumber, int linePosition, Exception? innerException)
: base(message, innerException)
{
Path = path;
LineNumber = lineNumber;
LinePosition = linePosition;
}
internal static JsonSerializationException Create(JsonReader reader, string message)
{
return Create(reader, message, null);
}
internal static JsonSerializationException Create(JsonReader reader, string message, Exception? ex)
{
return Create(reader as IJsonLineInfo, reader.Path, message, ex);
}
internal static JsonSerializationException Create(IJsonLineInfo? lineInfo, string path, string message, Exception? ex)
{
message = JsonPosition.FormatMessage(lineInfo, path, message);
int lineNumber;
int linePosition;
if (lineInfo != null && lineInfo.HasLineInfo())
{
lineNumber = lineInfo.LineNumber;
linePosition = lineInfo.LinePosition;
}
else
{
lineNumber = 0;
linePosition = 0;
}
return new JsonSerializationException(message, path, lineNumber, linePosition, ex);
}
}
[RequiresUnreferencedCode("Newtonsoft.Json relies on reflection over types that may be removed when trimming.")]
[RequiresDynamicCode("Newtonsoft.Json relies on dynamically creating types that may not be available with Ahead of Time compilation.")]
public class JsonSerializer
{
internal TypeNameHandling _typeNameHandling;
internal TypeNameAssemblyFormatHandling _typeNameAssemblyFormatHandling;
internal PreserveReferencesHandling _preserveReferencesHandling;
internal ReferenceLoopHandling _referenceLoopHandling;
internal MissingMemberHandling _missingMemberHandling;
internal ObjectCreationHandling _objectCreationHandling;
internal NullValueHandling _nullValueHandling;
internal DefaultValueHandling _defaultValueHandling;
internal ConstructorHandling _constructorHandling;
internal MetadataPropertyHandling _metadataPropertyHandling;
internal JsonConverterCollection? _converters;
internal IContractResolver _contractResolver;
internal ITraceWriter? _traceWriter;
internal IEqualityComparer? _equalityComparer;
internal ISerializationBinder _serializationBinder;
internal StreamingContext _context;
private IReferenceResolver? _referenceResolver;
private Formatting? _formatting;
private DateFormatHandling? _dateFormatHandling;
private DateTimeZoneHandling? _dateTimeZoneHandling;
private DateParseHandling? _dateParseHandling;
private FloatFormatHandling? _floatFormatHandling;
private FloatParseHandling? _floatParseHandling;
private StringEscapeHandling? _stringEscapeHandling;
private CultureInfo _culture;
private int? _maxDepth;
private bool _maxDepthSet;
private bool? _checkAdditionalContent;
private string? _dateFormatString;
private bool _dateFormatStringSet;
public virtual IReferenceResolver? ReferenceResolver
{
get
{
return GetReferenceResolver();
}
set
{
if (value == null)
{
throw new ArgumentNullException("value", "Reference resolver cannot be null.");
}
_referenceResolver = value;
}
}
[Obsolete("Binder is obsolete. Use SerializationBinder instead.")]
public virtual SerializationBinder Binder
{
get
{
if (_serializationBinder is SerializationBinder result)
{
return result;
}
if (_serializationBinder is SerializationBinderAdapter serializationBinderAdapter)
{
return serializationBinderAdapter.SerializationBinder;
}
throw new InvalidOperationException("Cannot get SerializationBinder because an ISerializationBinder was previously set.");
}
set
{
if (value == null)
{
throw new ArgumentNullException("value", "Serialization binder cannot be null.");
}
_serializationBinder = (value as ISerializationBinder) ?? new SerializationBinderAdapter(value);
}
}
public virtual ISerializationBinder SerializationBinder
{
get
{
return _serializationBinder;
}
set
{
if (value == null)
{
throw new ArgumentNullException("value", "Serialization binder cannot be null.");
}
_serializationBinder = value;
}
}
public virtual ITraceWriter? TraceWriter
{
get
{
return _traceWriter;
}
set
{
_traceWriter = value;
}
}
public virtual IEqualityComparer? EqualityComparer
{
get
{
return _equalityComparer;
}
set
{
_equalityComparer = value;
}
}
public virtual TypeNameHandling TypeNameHandling
{
get
{
return _typeNameHandling;
}
set
{
if (value < TypeNameHandling.None || value > TypeNameHandling.Auto)
{
throw new ArgumentOutOfRangeException("value");
}
_typeNameHandling = value;
}
}
[Obsolete("TypeNameAssemblyFormat is obsolete. Use TypeNameAssemblyFormatHandling instead.")]
public virtual FormatterAssemblyStyle TypeNameAssemblyFormat
{
get
{
return (FormatterAssemblyStyle)_typeNameAssemblyFormatHandling;
}
set
{
if (value < FormatterAssemblyStyle.Simple || value > FormatterAssemblyStyle.Full)
{
throw new ArgumentOutOfRangeException("value");
}
_typeNameAssemblyFormatHandling = (TypeNameAssemblyFormatHandling)value;
}
}
public virtual TypeNameAssemblyFormatHandling TypeNameAssemblyFormatHandling
{
get
{
return _typeNameAssemblyFormatHandling;
}
set
{
if (value < TypeNameAssemblyFormatHandling.Simple || value > TypeNameAssemblyFormatHandling.Full)
{
throw new ArgumentOutOfRangeException("value");
}
_typeNameAssemblyFormatHandling = value;
}
}
public virtual PreserveReferencesHandling PreserveReferencesHandling
{
get
{
return _preserveReferencesHandling;
}
set
{
if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All)
{
throw new ArgumentOutOfRangeException("value");
}
_preserveReferencesHandling = value;
}
}
public virtual ReferenceLoopHandling ReferenceLoopHandling
{
get
{
return _referenceLoopHandling;
}
set
{
if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize)
{
throw new ArgumentOutOfRangeException("value");
}
_referenceLoopHandling = value;
}
}
public virtual MissingMemberHandling MissingMemberHandling
{
get
{
return _missingMemberHandling;
}
set
{
if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error)
{
throw new ArgumentOutOfRangeException("value");
}
_missingMemberHandling = value;
}
}
public virtual NullValueHandling NullValueHandling
{
get
{
return _nullValueHandling;
}
set
{
if (value < NullValueHandling.Include || value > NullValueHandling.Ignore)
{
throw new ArgumentOutOfRangeException("value");
}
_nullValueHandling = value;
}
}
public virtual DefaultValueHandling DefaultValueHandling
{
get
{
return _defaultValueHandling;
}
set
{
if (value < DefaultValueHandling.Include || value > DefaultValueHandling.IgnoreAndPopulate)
{
throw new ArgumentOutOfRangeException("value");
}
_defaultValueHandling = value;
}
}
public virtual ObjectCreationHandling ObjectCreationHandling
{
get
{
return _objectCreationHandling;
}
set
{
if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace)
{
throw new ArgumentOutOfRangeException("value");
}
_objectCreationHandling = value;
}
}
public virtual ConstructorHandling ConstructorHandling
{
get
{
return _constructorHandling;
}
set
{
if (value < ConstructorHandling.Default || value > ConstructorHandling.AllowNonPublicDefaultConstructor)
{
throw new ArgumentOutOfRangeException("value");
}
_constructorHandling = value;
}
}
public virtual MetadataPropertyHandling MetadataPropertyHandling
{
get
{
return _metadataPropertyHandling;
}
set
{
if (value < MetadataPropertyHandling.Default || value > MetadataPropertyHandling.Ignore)
{
throw new ArgumentOutOfRangeException("value");
}
_metadataPropertyHandling = value;
}
}
public virtual JsonConverterCollection Converters
{
get
{
if (_converters == null)
{
_converters = new JsonConverterCollection();
}
return _converters;
}
}
public virtual IContractResolver ContractResolver
{
get
{
return _contractResolver;
}
set
{
_contractResolver = value ?? DefaultContractResolver.Instance;
}
}
public virtual StreamingContext Context
{
get
{
return _context;
}
set
{
_context = value;
}
}
public virtual Formatting Formatting
{
get
{
return _formatting.GetValueOrDefault();
}
set
{
_formatting = value;
}
}
public virtual DateFormatHandling DateFormatHandling
{
get
{
return _dateFormatHandling.GetValueOrDefault();
}
set
{
_dateFormatHandling = value;
}
}
public virtual DateTimeZoneHandling DateTimeZoneHandling
{
get
{
return _dateTimeZoneHandling.GetValueOrDefault(DateTimeZoneHandling.RoundtripKind);
}
set
{
_dateTimeZoneHandling = value;
}
}
public virtual DateParseHandling DateParseHandling
{
get
{
return _dateParseHandling.GetValueOrDefault(DateParseHandling.DateTime);
}
set
{
_dateParseHandling = value;
}
}
public virtual FloatParseHandling FloatParseHandling
{
get
{
return _floatParseHandling.GetValueOrDefault();
}
set
{
_floatParseHandling = value;
}
}
public virtual FloatFormatHandling FloatFormatHandling
{
get
{
return _floatFormatHandling.GetValueOrDefault();
}
set
{
_floatFormatHandling = value;
}
}
public virtual StringEscapeHandling StringEscapeHandling
{
get
{
return _stringEscapeHandling.GetValueOrDefault();
}
set
{
_stringEscapeHandling = value;
}
}
public virtual string DateFormatString
{
get
{
return _dateFormatString ?? "yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFFK";
}
set
{
_dateFormatString = value;
_dateFormatStringSet = true;
}
}
public virtual CultureInfo Culture
{
get
{
return _culture ?? JsonSerializerSettings.DefaultCulture;
}
set
{
_culture = value;
}
}
public virtual int? MaxDepth
{
get
{
return _maxDepth;
}
set
{
if (value <= 0)
{
throw new ArgumentException("Value must be positive.", "value");
}
_maxDepth = value;
_maxDepthSet = true;
}
}
public virtual bool CheckAdditionalContent
{
get
{
return _checkAdditionalContent.GetValueOrDefault();
}
set
{
_checkAdditionalContent = value;
}
}
public virtual event EventHandler<Newtonsoft.Json.Serialization.ErrorEventArgs>? Error;
internal bool IsCheckAdditionalContentSet()
{
return _checkAdditionalContent.HasValue;
}
public JsonSerializer()
{
_referenceLoopHandling = ReferenceLoopHandling.Error;
_missingMemberHandling = MissingMemberHandling.Ignore;
_nullValueHandling = NullValueHandling.Include;
_defaultValueHandling = DefaultValueHandling.Include;
_objectCreationHandling = ObjectCreationHandling.Auto;
_preserveReferencesHandling = PreserveReferencesHandling.None;
_constructorHandling = ConstructorHandling.Default;
_typeNameHandling = TypeNameHandling.None;
_metadataPropertyHandling = MetadataPropertyHandling.Default;
_context = JsonSerializerSettings.DefaultContext;
_serializationBinder = DefaultSerializationBinder.Instance;
_culture = JsonSerializerSettings.DefaultCulture;
_contractResolver = DefaultContractResolver.Instance;
}
public static JsonSerializer Create()
{
return new JsonSerializer();
}
public static JsonSerializer Create(JsonSerializerSettings? settings)
{
JsonSerializer jsonSerializer = Create();
if (settings != null)
{
ApplySerializerSettings(jsonSerializer, settings);
}
return jsonSerializer;
}
public static JsonSerializer CreateDefault()
{
return Create(JsonConvert.DefaultSettings?.Invoke());
}
public static JsonSerializer CreateDefault(JsonSerializerSettings? settings)
{
JsonSerializer jsonSerializer = CreateDefault();
if (settings != null)
{
ApplySerializerSettings(jsonSerializer, settings);
}
return jsonSerializer;
}
private static void ApplySerializerSettings(JsonSerializer serializer, JsonSerializerSettings settings)
{
if (!CollectionUtils.IsNullOrEmpty(settings.Converters))
{
for (int i = 0; i < settings.Converters.Count; i++)
{
serializer.Converters.Insert(i, settings.Converters[i]);
}
}
if (settings._typeNameHandling.HasValue)
{
serializer.TypeNameHandling = settings.TypeNameHandling;
}
if (settings._metadataPropertyHandling.HasValue)
{
serializer.MetadataPropertyHandling = settings.MetadataPropertyHandling;
}
if (settings._typeNameAssemblyFormatHandling.HasValue)
{
serializer.TypeNameAssemblyFormatHandling = settings.TypeNameAssemblyFormatHandling;
}
if (settings._preserveReferencesHandling.HasValue)
{
serializer.PreserveReferencesHandling = settings.PreserveReferencesHandling;
}
if (settings._referenceLoopHandling.HasValue)
{
serializer.ReferenceLoopHandling = settings.ReferenceLoopHandling;
}
if (settings._missingMemberHandling.HasValue)
{
serializer.MissingMemberHandling = settings.MissingMemberHandling;
}
if (settings._objectCreationHandling.HasValue)
{
serializer.ObjectCreationHandling = settings.ObjectCreationHandling;
}
if (settings._nullValueHandling.HasValue)
{
serializer.NullValueHandling = settings.NullValueHandling;
}
if (settings._defaultValueHandling.HasValue)
{
serializer.DefaultValueHandling = settings.DefaultValueHandling;
}
if (settings._constructorHandling.HasValue)
{
serializer.ConstructorHandling = settings.ConstructorHandling;
}
if (settings._context.HasValue)
{
serializer.Context = settings.Context;
}
if (settings._checkAdditionalContent.HasValue)
{
serializer._checkAdditionalContent = settings._checkAdditionalContent;
}
if (settings.Error != null)
{
serializer.Error += settings.Error;
}
if (settings.ContractResolver != null)
{
serializer.ContractResolver = settings.ContractResolver;
}
if (settings.ReferenceResolverProvider != null)
{
serializer.ReferenceResolver = settings.ReferenceResolverProvider();
}
if (settings.TraceWriter != null)
{
serializer.TraceWriter = settings.TraceWriter;
}
if (settings.EqualityComparer != null)
{
serializer.EqualityComparer = settings.EqualityComparer;
}
if (settings.SerializationBinder != null)
{
serializer.SerializationBinder = settings.SerializationBinder;
}
if (settings._formatting.HasValue)
{
serializer._formatting = settings._formatting;
}
if (settings._dateFormatHandling.HasValue)
{
serializer._dateFormatHandling = settings._dateFormatHandling;
}
if (settings._dateTimeZoneHandling.HasValue)
{
serializer._dateTimeZoneHandling = settings._dateTimeZoneHandling;
}
if (settings._dateParseHandling.HasValue)
{
serializer._dateParseHandling = settings._dateParseHandling;
}
if (settings._dateFormatStringSet)
{
serializer._dateFormatString = settings._dateFormatString;
serializer._dateFormatStringSet = settings._dateFormatStringSet;
}
if (settings._floatFormatHandling.HasValue)
{
serializer._floatFormatHandling = settings._floatFormatHandling;
}
if (settings._floatParseHandling.HasValue)
{
serializer._floatParseHandling = settings._floatParseHandling;
}
if (settings._stringEscapeHandling.HasValue)
{
serializer._stringEscapeHandling = settings._stringEscapeHandling;
}
if (settings._culture != null)
{
serializer._culture = settings._culture;
}
if (settings._maxDepthSet)
{
serializer._maxDepth = settings._maxDepth;
serializer._maxDepthSet = settings._maxDepthSet;
}
}
[DebuggerStepThrough]
public void Populate(TextReader reader, object target)
{
Populate(new JsonTextReader(reader), target);
}
[DebuggerStepThrough]
public void Populate(JsonReader reader, object target)
{
PopulateInternal(reader, target);
}
internal virtual void PopulateInternal(JsonReader reader, object target)
{
ValidationUtils.ArgumentNotNull(reader, "reader");
ValidationUtils.ArgumentNotNull(target, "target");
SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString);
TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null);
new JsonSerializerInternalReader(this).Populate(traceJsonReader ?? reader, target);
if (traceJsonReader != null)
{
TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
}
ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
}
[DebuggerStepThrough]
public object? Deserialize(JsonReader reader)
{
return Deserialize(reader, null);
}
[DebuggerStepThrough]
public object? Deserialize(TextReader reader, Type objectType)
{
return Deserialize(new JsonTextReader(reader), objectType);
}
[DebuggerStepThrough]
public T? Deserialize<T>(JsonReader reader)
{
return (T)Deserialize(reader, typeof(T));
}
[DebuggerStepThrough]
public object? Deserialize(JsonReader reader, Type? objectType)
{
return DeserializeInternal(reader, objectType);
}
internal virtual object? DeserializeInternal(JsonReader reader, Type? objectType)
{
ValidationUtils.ArgumentNotNull(reader, "reader");
SetupReader(reader, out CultureInfo previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string previousDateFormatString);
TraceJsonReader traceJsonReader = ((TraceWriter != null && TraceWriter.LevelFilter >= TraceLevel.Verbose) ? CreateTraceJsonReader(reader) : null);
object? result = new JsonSerializerInternalReader(this).Deserialize(traceJsonReader ?? reader, objectType, CheckAdditionalContent);
if (traceJsonReader != null)
{
TraceWriter.Trace(TraceLevel.Verbose, traceJsonReader.GetDeserializedJsonMessage(), null);
}
ResetReader(reader, previousCulture, previousDateTimeZoneHandling, previousDateParseHandling, previousFloatParseHandling, previousMaxDepth, previousDateFormatString);
return result;
}
internal void SetupReader(JsonReader reader, out CultureInfo? previousCulture, out DateTimeZoneHandling? previousDateTimeZoneHandling, out DateParseHandling? previousDateParseHandling, out FloatParseHandling? previousFloatParseHandling, out int? previousMaxDepth, out string? previousDateFormatString)
{
if (_culture != null && !_culture.Equals(reader.Culture))
{
previousCulture = reader.Culture;
reader.Culture = _cultureusing System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Logging;
using HG;
using Newtonsoft.Json;
using On.RoR2;
using RoR2;
using UnityEngine;
using WebSocketSharp;
using WebSocketSharp.Server;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("RoR2ItemSync")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("RoR2ItemSync")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("5a5f01ec-7173-4476-bc0d-defab8273628")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace RoR2ItemSync;
[BepInPlugin("com.turne.ror2itemsync", "RoR2ItemSync", "1.1.1")]
public class Plugin : BaseUnityPlugin
{
[Serializable]
[CompilerGenerated]
private sealed class <>c
{
public static readonly <>c <>9 = new <>c();
public static hook_Awake <>9__30_0;
public static hook_Start <>9__30_1;
public static hook_Start <>9__30_2;
public static hook_Start <>9__30_3;
public static hook_Awake <>9__30_4;
internal void <Awake>b__30_0(orig_Awake orig, ChestBehavior self)
{
orig.Invoke(self);
_trackedChests[self] = ((Component)self).GetComponent<PurchaseInteraction>();
}
internal void <Awake>b__30_1(orig_Start orig, MultiShopController self)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
orig.Invoke(self);
List<(ShopTerminalBehavior, PurchaseInteraction)> list = new List<(ShopTerminalBehavior, PurchaseInteraction)>();
Enumerator<GameObject> enumerator = self.terminalGameObjectsList.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
GameObject current = enumerator.Current;
if (!((Object)(object)current == (Object)null))
{
list.Add((current.GetComponent<ShopTerminalBehavior>(), current.GetComponent<PurchaseInteraction>()));
}
}
}
finally
{
((IDisposable)enumerator).Dispose();
}
_trackedMultiShops[self] = list;
}
internal void <Awake>b__30_2(orig_Start orig, ShopTerminalBehavior self)
{
orig.Invoke(self);
_trackedShopTerminals[self] = ((Component)self).GetComponent<PurchaseInteraction>();
}
internal void <Awake>b__30_3(orig_Start orig, GenericPickupController self)
{
orig.Invoke(self);
_trackedPickups.Add(self);
}
internal void <Awake>b__30_4(orig_Awake orig, PickupPickerController self)
{
orig.Invoke(self);
_trackedPickers.Add(self);
}
}
[CompilerGenerated]
private sealed class <InventoryPollLoop>d__32 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public Plugin <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <InventoryPollLoop>d__32(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_010a: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
int num = <>1__state;
Plugin plugin = <>4__this;
if (num != 0)
{
if (num != 1)
{
return false;
}
<>1__state = -1;
try
{
SyncBehavior result;
while (ChallengeRequests.TryDequeue(out result))
{
try
{
plugin.SendChallengesTo(result);
}
catch (Exception ex)
{
Log.LogWarning((object)("[Challenges] Failed to send: " + ex.Message));
}
}
if (!((Object)(object)Run.instance == (Object)null) && plugin._server.SessionCount != 0)
{
List<object> list = new List<object>();
foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
{
CharacterMaster val = ((instance != null) ? instance.master : null);
if ((Object)(object)val == (Object)null)
{
continue;
}
CharacterBody body = val.GetBody();
if ((Object)(object)body == (Object)null)
{
continue;
}
Inventory inventory = val.inventory;
if (!((Object)(object)inventory == (Object)null))
{
string text;
if (!((Object)(object)instance.networkUser != (Object)null))
{
text = body.GetDisplayName();
}
else
{
NetworkPlayerName networkPlayerName = instance.networkUser.GetNetworkPlayerName();
text = ((NetworkPlayerName)(ref networkPlayerName)).GetResolvedName();
}
string playerName = text;
list.Add(plugin.BuildPlayerData(playerName, inventory, body));
}
}
if (list.Count == 0)
{
Log.LogDebug((object)"[Poll] Run active but no valid player body found");
}
else
{
plugin.BroadcastAllPlayers(list);
}
}
}
catch (Exception arg)
{
Log.LogError((object)$"[Poll] Error during inventory poll: {arg}");
}
}
else
{
<>1__state = -1;
}
<>2__current = _waitOneSecond;
<>1__state = 1;
return true;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
public const string PluginGUID = "com.turne.ror2itemsync";
public const string PluginName = "RoR2ItemSync";
public const string PluginVersion = "1.1.1";
private const float WorldScanInterval = 5f;
internal static ManualLogSource Log;
private SyncServer _server;
internal static string LastBroadcast = null;
internal static readonly ConcurrentQueue<SyncBehavior> ChallengeRequests = new ConcurrentQueue<SyncBehavior>();
private float _lastWorldScanTime;
private int _cachedChestsRemaining;
private int _cachedEquipmentBarrelsRemaining;
private int _cachedShopsRemaining;
private readonly List<object> _cachedShopItems = new List<object>();
private readonly List<object> _cachedPrinterItems = new List<object>();
private readonly List<object> _cachedCommandItems = new List<object>();
private readonly HashSet<ShopTerminalBehavior> _multiShopTerminalSet = new HashSet<ShopTerminalBehavior>();
private readonly ConcurrentQueue<object> _broadcastQueue = new ConcurrentQueue<object>();
private Thread _serializeThread;
private volatile bool _threadRunning;
private static readonly Dictionary<ChestBehavior, PurchaseInteraction> _trackedChests = new Dictionary<ChestBehavior, PurchaseInteraction>();
private static readonly Dictionary<MultiShopController, List<(ShopTerminalBehavior terminal, PurchaseInteraction purchase)>> _trackedMultiShops = new Dictionary<MultiShopController, List<(ShopTerminalBehavior, PurchaseInteraction)>>();
private static readonly Dictionary<ShopTerminalBehavior, PurchaseInteraction> _trackedShopTerminals = new Dictionary<ShopTerminalBehavior, PurchaseInteraction>();
private static readonly HashSet<GenericPickupController> _trackedPickups = new HashSet<GenericPickupController>();
private static readonly HashSet<PickupPickerController> _trackedPickers = new HashSet<PickupPickerController>();
private readonly List<object> _reusableGroundItems = new List<object>();
private readonly List<object> _reusableItems = new List<object>();
private int _cachedArtifactStage = -1;
private List<string> _cachedArtifacts = new List<string>();
private static readonly WaitForSecondsRealtime _waitOneSecond = new WaitForSecondsRealtime(1f);
private static readonly Dictionary<ItemTier, string> _tierNameCache = new Dictionary<ItemTier, string>();
private void Awake()
{
//IL_006c: Unknown result type (might be due to invalid IL or missing references)
//IL_0071: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Expected O, but got Unknown
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Expected O, but got Unknown
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Expected O, but got Unknown
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_0107: Expected O, but got Unknown
Log = ((BaseUnityPlugin)this).Logger;
_server = new SyncServer();
_server.Start("1.1.1");
_threadRunning = true;
_serializeThread = new Thread(SerializeAndBroadcastLoop)
{
IsBackground = true
};
_serializeThread.Start();
object obj = <>c.<>9__30_0;
if (obj == null)
{
hook_Awake val = delegate(orig_Awake orig, ChestBehavior self)
{
orig.Invoke(self);
_trackedChests[self] = ((Component)self).GetComponent<PurchaseInteraction>();
};
<>c.<>9__30_0 = val;
obj = (object)val;
}
ChestBehavior.Awake += (hook_Awake)obj;
object obj2 = <>c.<>9__30_1;
if (obj2 == null)
{
hook_Start val2 = delegate(orig_Start orig, MultiShopController self)
{
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
orig.Invoke(self);
List<(ShopTerminalBehavior, PurchaseInteraction)> list = new List<(ShopTerminalBehavior, PurchaseInteraction)>();
Enumerator<GameObject> enumerator = self.terminalGameObjectsList.GetEnumerator();
try
{
while (enumerator.MoveNext())
{
GameObject current = enumerator.Current;
if (!((Object)(object)current == (Object)null))
{
list.Add((current.GetComponent<ShopTerminalBehavior>(), current.GetComponent<PurchaseInteraction>()));
}
}
}
finally
{
((IDisposable)enumerator).Dispose();
}
_trackedMultiShops[self] = list;
};
<>c.<>9__30_1 = val2;
obj2 = (object)val2;
}
MultiShopController.Start += (hook_Start)obj2;
object obj3 = <>c.<>9__30_2;
if (obj3 == null)
{
hook_Start val3 = delegate(orig_Start orig, ShopTerminalBehavior self)
{
orig.Invoke(self);
_trackedShopTerminals[self] = ((Component)self).GetComponent<PurchaseInteraction>();
};
<>c.<>9__30_2 = val3;
obj3 = (object)val3;
}
ShopTerminalBehavior.Start += (hook_Start)obj3;
object obj4 = <>c.<>9__30_3;
if (obj4 == null)
{
hook_Start val4 = delegate(orig_Start orig, GenericPickupController self)
{
orig.Invoke(self);
_trackedPickups.Add(self);
};
<>c.<>9__30_3 = val4;
obj4 = (object)val4;
}
GenericPickupController.Start += (hook_Start)obj4;
object obj5 = <>c.<>9__30_4;
if (obj5 == null)
{
hook_Awake val5 = delegate(orig_Awake orig, PickupPickerController self)
{
orig.Invoke(self);
_trackedPickers.Add(self);
};
<>c.<>9__30_4 = val5;
obj5 = (object)val5;
}
PickupPickerController.Awake += (hook_Awake)obj5;
Run.onRunDestroyGlobal += OnRunEnd;
((MonoBehaviour)this).StartCoroutine(InventoryPollLoop());
Log.LogInfo((object)"RoR2ItemSync v1.1.1 loaded.");
}
private void OnRunEnd(Run _)
{
try
{
Log.LogInfo((object)"[Run] Run ended, notifying clients");
LastBroadcast = null;
_cachedArtifactStage = -1;
ClearTrackedInstances();
string message = JsonConvert.SerializeObject((object)new
{
type = "run_ended"
});
if (_server.SessionCount > 0)
{
_server.Broadcast(message);
}
}
catch (Exception arg)
{
Log.LogError((object)$"[Run] Error during run end: {arg}");
}
}
[IteratorStateMachine(typeof(<InventoryPollLoop>d__32))]
private IEnumerator InventoryPollLoop()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <InventoryPollLoop>d__32(0)
{
<>4__this = this
};
}
private void SerializeAndBroadcastLoop()
{
while (_threadRunning)
{
object obj = null;
object result;
while (_broadcastQueue.TryDequeue(out result))
{
obj = result;
}
if (obj != null)
{
try
{
string text = JsonConvert.SerializeObject(obj);
if (text != LastBroadcast)
{
LastBroadcast = text;
int sessionCount = _server.SessionCount;
if (sessionCount > 0)
{
_server.Broadcast(text);
Log.LogInfo((object)$"[Broadcast] -> {sessionCount} client(s): {text}");
}
}
}
catch (Exception arg)
{
Log.LogError((object)$"[Broadcast] Serialization error: {arg}");
}
}
Thread.Sleep(50);
}
}
private static string GetTierName(ItemTier tier)
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
if (!_tierNameCache.TryGetValue(tier, out var value))
{
value = ((object)(ItemTier)(ref tier)).ToString();
_tierNameCache[tier] = value;
}
return value;
}
private void ClearTrackedInstances()
{
_trackedChests.Clear();
_trackedMultiShops.Clear();
_trackedShopTerminals.Clear();
_trackedPickups.Clear();
_trackedPickers.Clear();
_multiShopTerminalSet.Clear();
}
private void ScanWorldState()
{
//IL_0391: Unknown result type (might be due to invalid IL or missing references)
//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
//IL_02c4: Unknown result type (might be due to invalid IL or missing references)
//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
//IL_03a9: Unknown result type (might be due to invalid IL or missing references)
//IL_02d4: Unknown result type (might be due to invalid IL or missing references)
//IL_02f5: Unknown result type (might be due to invalid IL or missing references)
//IL_0195: Unknown result type (might be due to invalid IL or missing references)
//IL_019a: Unknown result type (might be due to invalid IL or missing references)
//IL_019f: Unknown result type (might be due to invalid IL or missing references)
//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
//IL_01db: Unknown result type (might be due to invalid IL or missing references)
_cachedChestsRemaining = 0;
_cachedEquipmentBarrelsRemaining = 0;
try
{
foreach (KeyValuePair<ChestBehavior, PurchaseInteraction> trackedChest in _trackedChests)
{
ChestBehavior key = trackedChest.Key;
PurchaseInteraction value = trackedChest.Value;
if (!((Object)(object)key == (Object)null) && !((Object)(object)value == (Object)null) && value.available)
{
if ((Object)(object)key.dropTable != (Object)null && ((Object)key.dropTable).name != null && ((Object)key.dropTable).name.Contains("Equipment"))
{
_cachedEquipmentBarrelsRemaining++;
}
else
{
_cachedChestsRemaining++;
}
}
}
}
catch (Exception ex)
{
Log.LogWarning((object)("[Scan] Error scanning chests: " + ex.Message));
}
_cachedShopsRemaining = 0;
_cachedShopItems.Clear();
_multiShopTerminalSet.Clear();
try
{
foreach (KeyValuePair<MultiShopController, List<(ShopTerminalBehavior, PurchaseInteraction)>> trackedMultiShop in _trackedMultiShops)
{
if ((Object)(object)trackedMultiShop.Key == (Object)null)
{
continue;
}
bool flag = false;
foreach (var (val, val2) in trackedMultiShop.Value)
{
if ((Object)(object)val != (Object)null)
{
_multiShopTerminalSet.Add(val);
}
if ((Object)(object)val2 == (Object)null || !val2.available)
{
continue;
}
flag = true;
if ((Object)(object)val == (Object)null || val.NetworkhasBeenPurchased)
{
continue;
}
PickupIndex pickupIndex = val.CurrentPickup().pickupIndex;
if (((PickupIndex)(ref pickupIndex)).isValid)
{
PickupDef pickupDef = PickupCatalog.GetPickupDef(pickupIndex);
if (pickupDef != null)
{
_cachedShopItems.Add(new
{
name = (val.Networkhidden ? "???" : Language.GetString(pickupDef.nameToken)),
tier = GetTierName(pickupDef.itemTier)
});
}
}
}
if (flag)
{
_cachedShopsRemaining++;
}
}
}
catch (Exception ex2)
{
Log.LogWarning((object)("[Scan] Error scanning shops: " + ex2.Message));
}
_cachedPrinterItems.Clear();
try
{
foreach (KeyValuePair<ShopTerminalBehavior, PurchaseInteraction> trackedShopTerminal in _trackedShopTerminals)
{
ShopTerminalBehavior key2 = trackedShopTerminal.Key;
PurchaseInteraction value2 = trackedShopTerminal.Value;
if ((Object)(object)key2 == (Object)null || _multiShopTerminalSet.Contains(key2) || (Object)(object)value2 == (Object)null || !value2.available)
{
continue;
}
PickupIndex pickupIndex2 = key2.CurrentPickup().pickupIndex;
if (((PickupIndex)(ref pickupIndex2)).isValid)
{
PickupDef pickupDef2 = PickupCatalog.GetPickupDef(pickupIndex2);
if (pickupDef2 != null)
{
_cachedPrinterItems.Add(new
{
name = Language.GetString(pickupDef2.nameToken),
tier = GetTierName(pickupDef2.itemTier)
});
}
}
}
}
catch (Exception ex3)
{
Log.LogWarning((object)("[Scan] Error scanning printers: " + ex3.Message));
}
_cachedCommandItems.Clear();
try
{
foreach (PickupPickerController trackedPicker in _trackedPickers)
{
if ((Object)(object)trackedPicker == (Object)null)
{
continue;
}
Option[] options = trackedPicker.options;
if (options != null && options.Length != 0)
{
PickupDef pickupDef3 = PickupCatalog.GetPickupDef(options[0].pickup.pickupIndex);
if (pickupDef3 != null)
{
_cachedCommandItems.Add(new
{
tier = GetTierName(pickupDef3.itemTier)
});
}
}
}
}
catch (Exception ex4)
{
Log.LogWarning((object)("[Scan] Error scanning command items: " + ex4.Message));
}
}
private void SendChallengesTo(SyncBehavior session)
{
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
LocalUser firstLocalUser = LocalUserManager.GetFirstLocalUser();
UserProfile val = ((firstLocalUser != null) ? firstLocalUser.userProfile : null);
List<object> list = new List<object>();
GenericStaticEnumerable<AchievementDef, Enumerator> allAchievementDefs = AchievementManager.allAchievementDefs;
Enumerator enumerator = allAchievementDefs.GetEnumerator();
try
{
while (((Enumerator)(ref enumerator)).MoveNext())
{
AchievementDef current = ((Enumerator)(ref enumerator)).Current;
if (current != null)
{
list.Add(new
{
id = current.identifier,
name = Language.GetString(current.nameToken),
description = Language.GetString(current.descriptionToken),
unlocked = (val != null && val.HasAchievement(current.identifier))
});
}
}
}
finally
{
((IDisposable)(Enumerator)(ref enumerator)).Dispose();
}
var anon = new
{
type = "challenges",
challenges = list
};
session.SendJson(JsonConvert.SerializeObject((object)anon));
Log.LogInfo((object)$"[Challenges] Sent {list.Count} challenges to {((WebSocketBehavior)session).Context.UserEndPoint}");
}
private object BuildPlayerData(string playerName, Inventory inventory, CharacterBody body)
{
//IL_0010: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Expected I4, but got Unknown
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0087: Expected I4, but got Unknown
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Invalid comparison between Unknown and I4
//IL_0093: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Invalid comparison between Unknown and I4
//IL_003f: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Expected I4, but got Unknown
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00e2: Expected I4, but got Unknown
_reusableItems.Clear();
for (int i = 0; i < ItemCatalog.itemCount; i++)
{
ItemIndex val = (ItemIndex)i;
int itemCountPermanent = inventory.GetItemCountPermanent(val);
if (itemCountPermanent > 0)
{
ItemDef itemDef = ItemCatalog.GetItemDef(val);
if (!((Object)(object)itemDef == (Object)null) && (int)itemDef.tier != 5)
{
_reusableItems.Add(new
{
id = (int)val,
name = Language.GetString(itemDef.nameToken),
count = itemCountPermanent,
tier = GetTierName(itemDef.tier)
});
}
}
}
EquipmentIndex[] array = (EquipmentIndex[])(object)new EquipmentIndex[2]
{
(EquipmentIndex)(int)inventory.currentEquipmentIndex,
(EquipmentIndex)(int)inventory.alternateEquipmentIndex
};
foreach (EquipmentIndex val2 in array)
{
if ((int)val2 != -1)
{
EquipmentDef equipmentDef = EquipmentCatalog.GetEquipmentDef(val2);
if (!((Object)(object)equipmentDef == (Object)null))
{
_reusableItems.Add(new
{
id = val2 + 100000,
name = Language.GetString(equipmentDef.nameToken),
count = 1,
tier = (equipmentDef.isLunar ? "Lunar Equipment" : "Equipment")
});
}
}
}
var stats = new { body.maxHealth, body.regen, body.maxShield, body.armor, body.damage, body.attackSpeed, body.crit, body.critMultiplier, body.moveSpeed, body.level };
return new
{
name = playerName,
survivor = body.GetDisplayName(),
stats = stats,
items = new List<object>(_reusableItems)
};
}
private void BroadcastAllPlayers(List<object> players)
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: Unknown result type (might be due to invalid IL or missing references)
//IL_0164: Unknown result type (might be due to invalid IL or missing references)
int num = (((Object)(object)Run.instance != (Object)null) ? (Run.instance.stageClearCount + 1) : 0);
SceneDef sceneDefForCurrentScene = SceneCatalog.GetSceneDefForCurrentScene();
string stageName = (((Object)(object)sceneDefForCurrentScene != (Object)null) ? Language.GetString(sceneDefForCurrentScene.nameToken) : "");
DifficultyDef difficultyDef = DifficultyCatalog.GetDifficultyDef(Run.instance.selectedDifficulty);
string difficulty = ((difficultyDef != null) ? Language.GetString(difficultyDef.nameToken) : "");
if (Time.unscaledTime - _lastWorldScanTime >= 5f)
{
_lastWorldScanTime = Time.unscaledTime;
ScanWorldState();
}
if (_cachedArtifactStage != num)
{
_cachedArtifactStage = num;
_cachedArtifacts = new List<string>();
try
{
for (int i = 0; i < ArtifactCatalog.artifactCount; i++)
{
ArtifactDef artifactDef = ArtifactCatalog.GetArtifactDef((ArtifactIndex)i);
if ((Object)(object)artifactDef != (Object)null && RunArtifactManager.instance.IsArtifactEnabled(artifactDef))
{
_cachedArtifacts.Add(Language.GetString(artifactDef.nameToken));
}
}
}
catch (Exception ex)
{
Log.LogWarning((object)("[Broadcast] Error scanning artifacts: " + ex.Message));
}
}
_reusableGroundItems.Clear();
try
{
foreach (GenericPickupController trackedPickup in _trackedPickups)
{
if (!((Object)(object)trackedPickup == (Object)null))
{
PickupDef pickupDef = PickupCatalog.GetPickupDef(trackedPickup.pickupIndex);
if (pickupDef != null)
{
_reusableGroundItems.Add(new
{
name = Language.GetString(pickupDef.nameToken),
tier = GetTierName(pickupDef.itemTier)
});
}
}
}
}
catch (Exception ex2)
{
Log.LogWarning((object)("[Scan] Error scanning ground items: " + ex2.Message));
}
var item = new
{
type = "inventory_update",
players = players,
stage = num,
stageName = stageName,
difficulty = difficulty,
chestsRemaining = _cachedChestsRemaining,
shopsRemaining = _cachedShopsRemaining,
equipmentBarrelsRemaining = _cachedEquipmentBarrelsRemaining,
shopItems = _cachedShopItems,
printerItems = _cachedPrinterItems,
groundItems = _reusableGroundItems,
commandItems = _cachedCommandItems,
artifacts = _cachedArtifacts
};
_broadcastQueue.Enqueue(item);
}
private void OnDestroy()
{
_threadRunning = false;
Run.onRunDestroyGlobal -= OnRunEnd;
_server?.Stop();
}
}
public class SyncServer
{
private WebSocketServer _wss;
private Thread _broadcastThread;
private Thread _listenerThread;
private volatile bool _running;
private const int WsPort = 11420;
private const int UdpPort = 11421;
private const string MulticastGroup = "239.255.255.250";
private string _version;
public int SessionCount
{
get
{
WebSocketServer wss = _wss;
int? obj;
if (wss == null)
{
obj = null;
}
else
{
WebSocketServiceHost obj2 = wss.WebSocketServices["/"];
if (obj2 == null)
{
obj = null;
}
else
{
WebSocketSessionManager sessions = obj2.Sessions;
obj = ((sessions != null) ? new int?(sessions.Count) : null);
}
}
int? num = obj;
return num.GetValueOrDefault();
}
}
public void Start(string version)
{
//IL_000d: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
_version = version;
_wss = new WebSocketServer(11420);
_wss.AddWebSocketService<SyncBehavior>("/");
_wss.Start();
_running = true;
_broadcastThread = new Thread(BroadcastLoop)
{
IsBackground = true
};
_broadcastThread.Start();
_listenerThread = new Thread(ListenerLoop)
{
IsBackground = true
};
_listenerThread.Start();
string localIp = GetLocalIp();
Plugin.Log.LogInfo((object)$"[Server] WebSocket on port {11420}, UDP on port {11421}, local IP: {localIp}");
}
public void Stop()
{
_running = false;
WebSocketServer wss = _wss;
if (wss != null)
{
wss.Stop();
}
Plugin.Log.LogInfo((object)"WebSocket server stopped.");
}
public void Broadcast(string message)
{
try
{
WebSocketServer wss = _wss;
if (wss == null)
{
return;
}
WebSocketServiceHost obj = wss.WebSocketServices["/"];
if (obj != null)
{
WebSocketSessionManager sessions = obj.Sessions;
if (sessions != null)
{
sessions.Broadcast(message);
}
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("[Broadcast] Error: " + ex.Message));
}
}
private void BroadcastLoop()
{
using UdpClient udpClient = new UdpClient();
udpClient.EnableBroadcast = true;
try
{
udpClient.JoinMulticastGroup(IPAddress.Parse("239.255.255.250"));
}
catch
{
}
while (_running)
{
try
{
string localIp = GetLocalIp();
string s = $"ROR2SYNC:{localIp}:{11420}:{_version}";
byte[] bytes = Encoding.UTF8.GetBytes(s);
udpClient.Send(bytes, bytes.Length, new IPEndPoint(IPAddress.Parse("239.255.255.250"), 11421));
try
{
IPAddress subnetBroadcast = GetSubnetBroadcast(localIp);
udpClient.Send(bytes, bytes.Length, new IPEndPoint(subnetBroadcast, 11421));
}
catch
{
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("UDP broadcast error: " + ex.Message));
}
Thread.Sleep(2000);
}
}
private void ListenerLoop()
{
try
{
using UdpClient udpClient = new UdpClient();
udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, optionValue: true);
udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, 11421));
try
{
udpClient.JoinMulticastGroup(IPAddress.Parse("239.255.255.250"));
}
catch
{
}
udpClient.Client.ReceiveTimeout = 1000;
while (_running)
{
try
{
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Any, 0);
byte[] bytes = udpClient.Receive(ref remoteEP);
if (Encoding.UTF8.GetString(bytes).Trim() == "DISCOVER")
{
string localIp = GetLocalIp();
byte[] bytes2 = Encoding.UTF8.GetBytes($"ROR2SYNC:{localIp}:{11420}:{_version}");
udpClient.Send(bytes2, bytes2.Length, remoteEP);
Plugin.Log.LogInfo((object)$"Discovery response sent to {remoteEP}");
}
}
catch (SocketException)
{
}
}
}
catch (Exception ex2)
{
Plugin.Log.LogWarning((object)("UDP listener error: " + ex2.Message));
}
}
private static string GetLocalIp()
{
using Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
socket.Connect("8.8.8.8", 80);
return ((IPEndPoint)socket.LocalEndPoint).Address.ToString();
}
private static IPAddress GetSubnetBroadcast(string localIp)
{
IPAddress iPAddress = IPAddress.Parse(localIp);
NetworkInterface[] allNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
for (int i = 0; i < allNetworkInterfaces.Length; i++)
{
foreach (UnicastIPAddressInformation unicastAddress in allNetworkInterfaces[i].GetIPProperties().UnicastAddresses)
{
if (unicastAddress.Address.Equals(iPAddress))
{
byte[] addressBytes = unicastAddress.IPv4Mask.GetAddressBytes();
byte[] addressBytes2 = iPAddress.GetAddressBytes();
byte[] array = new byte[4];
for (int j = 0; j < 4; j++)
{
array[j] = (byte)(addressBytes2[j] | ~addressBytes[j]);
}
return new IPAddress(array);
}
}
}
return IPAddress.Broadcast;
}
}
public class SyncBehavior : WebSocketBehavior
{
private class InboundMessage
{
public string type;
}
public void SendJson(string json)
{
((WebSocketBehavior)this).Send(json);
}
protected override void OnOpen()
{
Plugin.Log.LogInfo((object)$"[WS] Client connected: {((WebSocketBehavior)this).Context.UserEndPoint}, sessions: {((WebSocketBehavior)this).Sessions.Count}");
string lastBroadcast = Plugin.LastBroadcast;
if (lastBroadcast != null)
{
((WebSocketBehavior)this).SendAsync(lastBroadcast, (Action<bool>)null);
}
}
protected override void OnClose(CloseEventArgs e)
{
Plugin.Log.LogInfo((object)$"[WS] Client disconnected: code={e.Code} reason='{e.Reason}'");
}
protected override void OnMessage(MessageEventArgs e)
{
if (!e.IsText)
{
return;
}
try
{
if (JsonConvert.DeserializeObject<InboundMessage>(e.Data)?.type == "request_challenges")
{
Plugin.ChallengeRequests.Enqueue(this);
}
}
catch (Exception ex)
{
Plugin.Log.LogWarning((object)("[WS] Bad inbound message: " + ex.Message));
}
}
protected override void OnError(ErrorEventArgs e)
{
Plugin.Log.LogWarning((object)$"[WS] Error: {e.Message} | {e.Exception}");
}
}using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Net.Security;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Security.Authentication;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Permissions;
using System.Security.Principal;
using System.Text;
using System.Threading;
using System.Timers;
using WebSocketSharp.Net;
using WebSocketSharp.Net.WebSockets;
using WebSocketSharp.Server;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("websocket-sharp")]
[assembly: AssemblyDescription("A C# implementation of the WebSocket protocol client and server")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("websocket-sharp.dll")]
[assembly: AssemblyCopyright("sta.blockhead")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyVersion("1.0.4.0")]
namespace WebSocketSharp
{
public static class Ext
{
private static readonly byte[] _last = new byte[1];
private static readonly int _retry = 5;
private const string _tspecials = "()<>@,;:\\\"/[]?={} \t";
private static byte[] compress(this byte[] data)
{
if (data.LongLength == 0)
{
return data;
}
using MemoryStream stream = new MemoryStream(data);
return stream.compressToArray();
}
private static MemoryStream compress(this Stream stream)
{
MemoryStream memoryStream = new MemoryStream();
if (stream.Length == 0)
{
return memoryStream;
}
stream.Position = 0L;
using DeflateStream deflateStream = new DeflateStream(memoryStream, CompressionMode.Compress, leaveOpen: true);
CopyTo(stream, deflateStream, 1024);
deflateStream.Close();
memoryStream.Write(_last, 0, 1);
memoryStream.Position = 0L;
return memoryStream;
}
private static byte[] compressToArray(this Stream stream)
{
using MemoryStream memoryStream = stream.compress();
memoryStream.Close();
return memoryStream.ToArray();
}
private static byte[] decompress(this byte[] data)
{
if (data.LongLength == 0)
{
return data;
}
using MemoryStream stream = new MemoryStream(data);
return stream.decompressToArray();
}
private static MemoryStream decompress(this Stream stream)
{
MemoryStream memoryStream = new MemoryStream();
if (stream.Length == 0)
{
return memoryStream;
}
stream.Position = 0L;
using DeflateStream source = new DeflateStream(stream, CompressionMode.Decompress, leaveOpen: true);
CopyTo(source, memoryStream, 1024);
memoryStream.Position = 0L;
return memoryStream;
}
private static byte[] decompressToArray(this Stream stream)
{
using MemoryStream memoryStream = stream.decompress();
memoryStream.Close();
return memoryStream.ToArray();
}
private static void times(this ulong n, Action action)
{
for (ulong num = 0uL; num < n; num++)
{
action();
}
}
internal static byte[] Append(this ushort code, string reason)
{
byte[] array = code.InternalToByteArray(ByteOrder.Big);
if (reason != null && reason.Length > 0)
{
List<byte> list = new List<byte>(array);
list.AddRange(Encoding.UTF8.GetBytes(reason));
array = list.ToArray();
}
return array;
}
internal static string CheckIfAvailable(this ServerState state, bool ready, bool start, bool shutting)
{
return ((!ready && (state == ServerState.Ready || state == ServerState.Stop)) || (!start && state == ServerState.Start) || (!shutting && state == ServerState.ShuttingDown)) ? ("This operation isn't available in: " + state.ToString().ToLower()) : null;
}
internal static string CheckIfAvailable(this WebSocketState state, bool connecting, bool open, bool closing, bool closed)
{
return ((!connecting && state == WebSocketState.Connecting) || (!open && state == WebSocketState.Open) || (!closing && state == WebSocketState.Closing) || (!closed && state == WebSocketState.Closed)) ? ("This operation isn't available in: " + state.ToString().ToLower()) : null;
}
internal static string CheckIfValidProtocols(this string[] protocols)
{
return protocols.Contains((string protocol) => protocol == null || protocol.Length == 0 || !protocol.IsToken()) ? "Contains an invalid value." : (protocols.ContainsTwice() ? "Contains a value twice." : null);
}
internal static string CheckIfValidServicePath(this string path)
{
return (path == null || path.Length == 0) ? "'path' is null or empty." : ((path[0] != '/') ? "'path' isn't an absolute path." : ((path.IndexOfAny(new char[2] { '?', '#' }) > -1) ? "'path' includes either or both query and fragment components." : null));
}
internal static string CheckIfValidSessionID(this string id)
{
return (id == null || id.Length == 0) ? "'id' is null or empty." : null;
}
internal static string CheckIfValidWaitTime(this TimeSpan time)
{
return (time <= TimeSpan.Zero) ? "A wait time is zero or less." : null;
}
internal static bool CheckWaitTime(this TimeSpan time, out string message)
{
message = null;
if (time <= TimeSpan.Zero)
{
message = "A wait time is zero or less.";
return false;
}
return true;
}
internal static void Close(this WebSocketSharp.Net.HttpListenerResponse response, WebSocketSharp.Net.HttpStatusCode code)
{
response.StatusCode = (int)code;
response.OutputStream.Close();
}
internal static void CloseWithAuthChallenge(this WebSocketSharp.Net.HttpListenerResponse response, string challenge)
{
response.Headers.InternalSet("WWW-Authenticate", challenge, response: true);
response.Close(WebSocketSharp.Net.HttpStatusCode.Unauthorized);
}
internal static byte[] Compress(this byte[] data, CompressionMethod method)
{
return (method == CompressionMethod.Deflate) ? data.compress() : data;
}
internal static Stream Compress(this Stream stream, CompressionMethod method)
{
return (method == CompressionMethod.Deflate) ? stream.compress() : stream;
}
internal static byte[] CompressToArray(this Stream stream, CompressionMethod method)
{
return (method == CompressionMethod.Deflate) ? stream.compressToArray() : stream.ToByteArray();
}
internal static bool Contains<T>(this IEnumerable<T> source, Func<T, bool> condition)
{
foreach (T item in source)
{
if (condition(item))
{
return true;
}
}
return false;
}
internal static bool ContainsTwice(this string[] values)
{
int len = values.Length;
Func<int, bool> contains = null;
contains = delegate(int idx)
{
if (idx < len - 1)
{
for (int i = idx + 1; i < len; i++)
{
if (values[i] == values[idx])
{
return true;
}
}
return contains(++idx);
}
return false;
};
return contains(0);
}
internal static T[] Copy<T>(this T[] source, long length)
{
T[] array = new T[length];
Array.Copy(source, 0L, array, 0L, length);
return array;
}
internal static void CopyTo(this Stream source, Stream destination, int bufferLength)
{
byte[] buffer = new byte[bufferLength];
int num = 0;
while ((num = source.Read(buffer, 0, bufferLength)) > 0)
{
destination.Write(buffer, 0, num);
}
}
internal static void CopyToAsync(this Stream source, Stream destination, int bufferLength, Action completed, Action<Exception> error)
{
byte[] buff = new byte[bufferLength];
AsyncCallback callback = null;
callback = delegate(IAsyncResult ar)
{
try
{
int num = source.EndRead(ar);
if (num <= 0)
{
if (completed != null)
{
completed();
}
}
else
{
destination.Write(buff, 0, num);
source.BeginRead(buff, 0, bufferLength, callback, null);
}
}
catch (Exception obj2)
{
if (error != null)
{
error(obj2);
}
}
};
try
{
source.BeginRead(buff, 0, bufferLength, callback, null);
}
catch (Exception obj)
{
if (error != null)
{
error(obj);
}
}
}
internal static byte[] Decompress(this byte[] data, CompressionMethod method)
{
return (method == CompressionMethod.Deflate) ? data.decompress() : data;
}
internal static Stream Decompress(this Stream stream, CompressionMethod method)
{
return (method == CompressionMethod.Deflate) ? stream.decompress() : stream;
}
internal static byte[] DecompressToArray(this Stream stream, CompressionMethod method)
{
return (method == CompressionMethod.Deflate) ? stream.decompressToArray() : stream.ToByteArray();
}
internal static bool EqualsWith(this int value, char c, Action<int> action)
{
action(value);
return value == c;
}
internal static string GetAbsolutePath(this Uri uri)
{
if (uri.IsAbsoluteUri)
{
return uri.AbsolutePath;
}
string originalString = uri.OriginalString;
if (originalString[0] != '/')
{
return null;
}
int num = originalString.IndexOfAny(new char[2] { '?', '#' });
return (num > 0) ? originalString.Substring(0, num) : originalString;
}
internal static string GetMessage(this CloseStatusCode code)
{
return code switch
{
CloseStatusCode.TlsHandshakeFailure => "An error has occurred during a TLS handshake.",
CloseStatusCode.ServerError => "WebSocket server got an internal error.",
CloseStatusCode.MandatoryExtension => "WebSocket client didn't receive expected extension(s).",
CloseStatusCode.TooBig => "A too big message has been received.",
CloseStatusCode.PolicyViolation => "A policy violation has occurred.",
CloseStatusCode.InvalidData => "Invalid data has been received.",
CloseStatusCode.Abnormal => "An exception has occurred.",
CloseStatusCode.UnsupportedData => "Unsupported data has been received.",
CloseStatusCode.ProtocolError => "A WebSocket protocol error has occurred.",
_ => string.Empty,
};
}
internal static string GetName(this string nameAndValue, char separator)
{
int num = nameAndValue.IndexOf(separator);
return (num > 0) ? nameAndValue.Substring(0, num).Trim() : null;
}
internal static string GetValue(this string nameAndValue, char separator)
{
int num = nameAndValue.IndexOf(separator);
return (num > -1 && num < nameAndValue.Length - 1) ? nameAndValue.Substring(num + 1).Trim() : null;
}
internal static string GetValue(this string nameAndValue, char separator, bool unquote)
{
int num = nameAndValue.IndexOf(separator);
if (num < 0 || num == nameAndValue.Length - 1)
{
return null;
}
string text = nameAndValue.Substring(num + 1).Trim();
return unquote ? text.Unquote() : text;
}
internal static TcpListenerWebSocketContext GetWebSocketContext(this TcpClient tcpClient, string protocol, bool secure, ServerSslConfiguration sslConfig, Logger logger)
{
return new TcpListenerWebSocketContext(tcpClient, protocol, secure, sslConfig, logger);
}
internal static byte[] InternalToByteArray(this ushort value, ByteOrder order)
{
byte[] bytes = BitConverter.GetBytes(value);
if (!order.IsHostOrder())
{
Array.Reverse((Array)bytes);
}
return bytes;
}
internal static byte[] InternalToByteArray(this ulong value, ByteOrder order)
{
byte[] bytes = BitConverter.GetBytes(value);
if (!order.IsHostOrder())
{
Array.Reverse((Array)bytes);
}
return bytes;
}
internal static bool IsCompressionExtension(this string value, CompressionMethod method)
{
return value.StartsWith(method.ToExtensionString());
}
internal static bool IsControl(this byte opcode)
{
return opcode > 7 && opcode < 16;
}
internal static bool IsControl(this Opcode opcode)
{
return (int)opcode >= 8;
}
internal static bool IsData(this byte opcode)
{
return opcode == 1 || opcode == 2;
}
internal static bool IsData(this Opcode opcode)
{
return opcode == Opcode.Text || opcode == Opcode.Binary;
}
internal static bool IsPortNumber(this int value)
{
return value > 0 && value < 65536;
}
internal static bool IsReserved(this ushort code)
{
return code == 1004 || code == 1005 || code == 1006 || code == 1015;
}
internal static bool IsReserved(this CloseStatusCode code)
{
return code == CloseStatusCode.Undefined || code == CloseStatusCode.NoStatus || code == CloseStatusCode.Abnormal || code == CloseStatusCode.TlsHandshakeFailure;
}
internal static bool IsSupported(this byte opcode)
{
return Enum.IsDefined(typeof(Opcode), opcode);
}
internal static bool IsText(this string value)
{
int length = value.Length;
for (int i = 0; i < length; i++)
{
char c = value[i];
if (c < ' ' && !Contains("\r\n\t", c))
{
return false;
}
switch (c)
{
case '\u007f':
return false;
case '\n':
if (++i < length)
{
c = value[i];
if (!Contains(" \t", c))
{
return false;
}
}
break;
}
}
return true;
}
internal static bool IsToken(this string value)
{
foreach (char c in value)
{
if (c < ' ' || c >= '\u007f' || Contains("()<>@,;:\\\"/[]?={} \t", c))
{
return false;
}
}
return true;
}
internal static string Quote(this string value)
{
return string.Format("\"{0}\"", value.Replace("\"", "\\\""));
}
internal static byte[] ReadBytes(this Stream stream, int length)
{
byte[] array = new byte[length];
int num = 0;
try
{
int num2 = 0;
while (length > 0)
{
num2 = stream.Read(array, num, length);
if (num2 == 0)
{
break;
}
num += num2;
length -= num2;
}
}
catch
{
}
return array.SubArray(0, num);
}
internal static byte[] ReadBytes(this Stream stream, long length, int bufferLength)
{
using MemoryStream memoryStream = new MemoryStream();
try
{
byte[] buffer = new byte[bufferLength];
int num = 0;
while (length > 0)
{
if (length < bufferLength)
{
bufferLength = (int)length;
}
num = stream.Read(buffer, 0, bufferLength);
if (num == 0)
{
break;
}
memoryStream.Write(buffer, 0, num);
length -= num;
}
}
catch
{
}
memoryStream.Close();
return memoryStream.ToArray();
}
internal static void ReadBytesAsync(this Stream stream, int length, Action<byte[]> completed, Action<Exception> error)
{
byte[] buff = new byte[length];
int offset = 0;
int retry = 0;
AsyncCallback callback = null;
callback = delegate(IAsyncResult ar)
{
try
{
int num = stream.EndRead(ar);
if (num == 0 && retry < _retry)
{
retry++;
stream.BeginRead(buff, offset, length, callback, null);
}
else if (num == 0 || num == length)
{
if (completed != null)
{
completed(buff.SubArray(0, offset + num));
}
}
else
{
retry = 0;
offset += num;
length -= num;
stream.BeginRead(buff, offset, length, callback, null);
}
}
catch (Exception obj2)
{
if (error != null)
{
error(obj2);
}
}
};
try
{
stream.BeginRead(buff, offset, length, callback, null);
}
catch (Exception obj)
{
if (error != null)
{
error(obj);
}
}
}
internal static void ReadBytesAsync(this Stream stream, long length, int bufferLength, Action<byte[]> completed, Action<Exception> error)
{
MemoryStream dest = new MemoryStream();
byte[] buff = new byte[bufferLength];
int retry = 0;
Action<long> read = null;
read = delegate(long len)
{
if (len < bufferLength)
{
bufferLength = (int)len;
}
stream.BeginRead(buff, 0, bufferLength, delegate(IAsyncResult ar)
{
try
{
int num = stream.EndRead(ar);
if (num > 0)
{
dest.Write(buff, 0, num);
}
if (num == 0 && retry < _retry)
{
int num2 = retry;
retry = num2 + 1;
read(len);
}
else if (num == 0 || num == len)
{
if (completed != null)
{
dest.Close();
completed(dest.ToArray());
}
dest.Dispose();
}
else
{
retry = 0;
read(len - num);
}
}
catch (Exception obj2)
{
dest.Dispose();
if (error != null)
{
error(obj2);
}
}
}, null);
};
try
{
read(length);
}
catch (Exception obj)
{
dest.Dispose();
if (error != null)
{
error(obj);
}
}
}
internal static string RemovePrefix(this string value, params string[] prefixes)
{
int num = 0;
foreach (string text in prefixes)
{
if (value.StartsWith(text))
{
num = text.Length;
break;
}
}
return (num > 0) ? value.Substring(num) : value;
}
internal static T[] Reverse<T>(this T[] array)
{
int num = array.Length;
T[] array2 = new T[num];
int num2 = num - 1;
for (int i = 0; i <= num2; i++)
{
array2[i] = array[num2 - i];
}
return array2;
}
internal static IEnumerable<string> SplitHeaderValue(this string value, params char[] separators)
{
int len = value.Length;
string seps = new string(separators);
StringBuilder buff = new StringBuilder(32);
bool escaped = false;
bool quoted = false;
for (int i = 0; i < len; i++)
{
char c = value[i];
switch (c)
{
case '"':
if (escaped)
{
escaped = !escaped;
}
else
{
quoted = !quoted;
}
break;
case '\\':
if (i < len - 1 && value[i + 1] == '"')
{
escaped = true;
}
break;
default:
if (Contains(seps, c) && !quoted)
{
yield return buff.ToString();
buff.Length = 0;
continue;
}
break;
}
buff.Append(c);
}
if (buff.Length > 0)
{
yield return buff.ToString();
}
}
internal static byte[] ToByteArray(this Stream stream)
{
using MemoryStream memoryStream = new MemoryStream();
stream.Position = 0L;
CopyTo(stream, memoryStream, 1024);
memoryStream.Close();
return memoryStream.ToArray();
}
internal static CompressionMethod ToCompressionMethod(this string value)
{
foreach (CompressionMethod value2 in Enum.GetValues(typeof(CompressionMethod)))
{
if (value2.ToExtensionString() == value)
{
return value2;
}
}
return CompressionMethod.None;
}
internal static string ToExtensionString(this CompressionMethod method, params string[] parameters)
{
if (method == CompressionMethod.None)
{
return string.Empty;
}
string text = $"permessage-{method.ToString().ToLower()}";
if (parameters == null || parameters.Length == 0)
{
return text;
}
return string.Format("{0}; {1}", text, parameters.ToString("; "));
}
internal static IPAddress ToIPAddress(this string hostnameOrAddress)
{
if (IPAddress.TryParse(hostnameOrAddress, out IPAddress address))
{
return address;
}
try
{
return Dns.GetHostAddresses(hostnameOrAddress)[0];
}
catch
{
return null;
}
}
internal static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
{
return new List<TSource>(source);
}
internal static ushort ToUInt16(this byte[] source, ByteOrder sourceOrder)
{
return BitConverter.ToUInt16(source.ToHostOrder(sourceOrder), 0);
}
internal static ulong ToUInt64(this byte[] source, ByteOrder sourceOrder)
{
return BitConverter.ToUInt64(source.ToHostOrder(sourceOrder), 0);
}
internal static string TrimEndSlash(this string value)
{
value = value.TrimEnd(new char[1] { '/' });
return (value.Length > 0) ? value : "/";
}
internal static bool TryCreateWebSocketUri(this string uriString, out Uri result, out string message)
{
result = null;
Uri uri = uriString.ToUri();
if (uri == null)
{
message = "An invalid URI string: " + uriString;
return false;
}
if (!uri.IsAbsoluteUri)
{
message = "Not an absolute URI: " + uriString;
return false;
}
string scheme = uri.Scheme;
if (!(scheme == "ws") && !(scheme == "wss"))
{
message = "The scheme part isn't 'ws' or 'wss': " + uriString;
return false;
}
if (uri.Fragment.Length > 0)
{
message = "Includes the fragment component: " + uriString;
return false;
}
int port = uri.Port;
if (port == 0)
{
message = "The port part is zero: " + uriString;
return false;
}
result = ((port != -1) ? uri : new Uri(string.Format("{0}://{1}:{2}{3}", scheme, uri.Host, (scheme == "ws") ? 80 : 443, uri.PathAndQuery)));
message = string.Empty;
return true;
}
internal static string Unquote(this string value)
{
int num = value.IndexOf('"');
if (num < 0)
{
return value;
}
int num2 = value.LastIndexOf('"');
int num3 = num2 - num - 1;
return (num3 < 0) ? value : ((num3 == 0) ? string.Empty : value.Substring(num + 1, num3).Replace("\\\"", "\""));
}
internal static string UTF8Decode(this byte[] bytes)
{
try
{
return Encoding.UTF8.GetString(bytes);
}
catch
{
return null;
}
}
internal static byte[] UTF8Encode(this string s)
{
return Encoding.UTF8.GetBytes(s);
}
internal static void WriteBytes(this Stream stream, byte[] bytes, int bufferLength)
{
using MemoryStream source = new MemoryStream(bytes);
CopyTo(source, stream, bufferLength);
}
internal static void WriteBytesAsync(this Stream stream, byte[] bytes, int bufferLength, Action completed, Action<Exception> error)
{
MemoryStream input = new MemoryStream(bytes);
input.CopyToAsync(stream, bufferLength, delegate
{
if (completed != null)
{
completed();
}
input.Dispose();
}, delegate(Exception ex)
{
input.Dispose();
if (error != null)
{
error(ex);
}
});
}
public static bool Contains(this string value, params char[] chars)
{
return chars == null || chars.Length == 0 || (value != null && value.Length != 0 && value.IndexOfAny(chars) > -1);
}
public static bool Contains(this NameValueCollection collection, string name)
{
return collection != null && collection.Count > 0 && collection[name] != null;
}
public static bool Contains(this NameValueCollection collection, string name, string value)
{
if (collection == null || collection.Count == 0)
{
return false;
}
string text = collection[name];
if (text == null)
{
return false;
}
string[] array = text.Split(new char[1] { ',' });
foreach (string text2 in array)
{
if (text2.Trim().Equals(value, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
public static void Emit(this EventHandler eventHandler, object sender, EventArgs e)
{
eventHandler?.Invoke(sender, e);
}
public static void Emit<TEventArgs>(this EventHandler<TEventArgs> eventHandler, object sender, TEventArgs e) where TEventArgs : EventArgs
{
eventHandler?.Invoke(sender, e);
}
public static WebSocketSharp.Net.CookieCollection GetCookies(this NameValueCollection headers, bool response)
{
string name = (response ? "Set-Cookie" : "Cookie");
return (headers != null && headers.Contains(name)) ? WebSocketSharp.Net.CookieCollection.Parse(headers[name], response) : new WebSocketSharp.Net.CookieCollection();
}
public static string GetDescription(this WebSocketSharp.Net.HttpStatusCode code)
{
return ((int)code).GetStatusDescription();
}
public static string GetStatusDescription(this int code)
{
return code switch
{
100 => "Continue",
101 => "Switching Protocols",
102 => "Processing",
200 => "OK",
201 => "Created",
202 => "Accepted",
203 => "Non-Authoritative Information",
204 => "No Content",
205 => "Reset Content",
206 => "Partial Content",
207 => "Multi-Status",
300 => "Multiple Choices",
301 => "Moved Permanently",
302 => "Found",
303 => "See Other",
304 => "Not Modified",
305 => "Use Proxy",
307 => "Temporary Redirect",
400 => "Bad Request",
401 => "Unauthorized",
402 => "Payment Required",
403 => "Forbidden",
404 => "Not Found",
405 => "Method Not Allowed",
406 => "Not Acceptable",
407 => "Proxy Authentication Required",
408 => "Request Timeout",
409 => "Conflict",
410 => "Gone",
411 => "Length Required",
412 => "Precondition Failed",
413 => "Request Entity Too Large",
414 => "Request-Uri Too Long",
415 => "Unsupported Media Type",
416 => "Requested Range Not Satisfiable",
417 => "Expectation Failed",
422 => "Unprocessable Entity",
423 => "Locked",
424 => "Failed Dependency",
500 => "Internal Server Error",
501 => "Not Implemented",
502 => "Bad Gateway",
503 => "Service Unavailable",
504 => "Gateway Timeout",
505 => "Http Version Not Supported",
507 => "Insufficient Storage",
_ => string.Empty,
};
}
public static bool IsCloseStatusCode(this ushort value)
{
return value > 999 && value < 5000;
}
public static bool IsEnclosedIn(this string value, char c)
{
return value != null && value.Length > 1 && value[0] == c && value[value.Length - 1] == c;
}
public static bool IsHostOrder(this ByteOrder order)
{
return BitConverter.IsLittleEndian == (order == ByteOrder.Little);
}
public static bool IsLocal(this IPAddress address)
{
if (address == null)
{
return false;
}
if (address.Equals(IPAddress.Any))
{
return true;
}
if (address.Equals(IPAddress.Loopback))
{
return true;
}
if (Socket.OSSupportsIPv6)
{
if (address.Equals(IPAddress.IPv6Any))
{
return true;
}
if (address.Equals(IPAddress.IPv6Loopback))
{
return true;
}
}
string hostName = Dns.GetHostName();
IPAddress[] hostAddresses = Dns.GetHostAddresses(hostName);
IPAddress[] array = hostAddresses;
foreach (IPAddress obj in array)
{
if (address.Equals(obj))
{
return true;
}
}
return false;
}
public static bool IsNullOrEmpty(this string value)
{
return value == null || value.Length == 0;
}
public static bool IsPredefinedScheme(this string value)
{
if (value == null || value.Length < 2)
{
return false;
}
char c = value[0];
if (c == 'h')
{
return value == "http" || value == "https";
}
if (c == 'w')
{
return value == "ws" || value == "wss";
}
if (c == 'f')
{
return value == "file" || value == "ftp";
}
if (c == 'n')
{
c = value[1];
return (c != 'e') ? (value == "nntp") : (value == "news" || value == "net.pipe" || value == "net.tcp");
}
return (c == 'g' && value == "gopher") || (c == 'm' && value == "mailto");
}
public static bool IsUpgradeTo(this WebSocketSharp.Net.HttpListenerRequest request, string protocol)
{
if (request == null)
{
throw new ArgumentNullException("request");
}
if (protocol == null)
{
throw new ArgumentNullException("protocol");
}
if (protocol.Length == 0)
{
throw new ArgumentException("An empty string.", "protocol");
}
return request.Headers.Contains("Upgrade", protocol) && request.Headers.Contains("Connection", "Upgrade");
}
public static bool MaybeUri(this string value)
{
if (value == null || value.Length == 0)
{
return false;
}
int num = value.IndexOf(':');
if (num == -1)
{
return false;
}
if (num >= 10)
{
return false;
}
return value.Substring(0, num).IsPredefinedScheme();
}
public static T[] SubArray<T>(this T[] array, int startIndex, int length)
{
int num;
if (array == null || (num = array.Length) == 0)
{
return new T[0];
}
if (startIndex < 0 || length <= 0 || startIndex + length > num)
{
return new T[0];
}
if (startIndex == 0 && length == num)
{
return array;
}
T[] array2 = new T[length];
Array.Copy(array, startIndex, array2, 0, length);
return array2;
}
public static T[] SubArray<T>(this T[] array, long startIndex, long length)
{
long num;
if (array == null || (num = array.LongLength) == 0)
{
return new T[0];
}
if (startIndex < 0 || length <= 0 || startIndex + length > num)
{
return new T[0];
}
if (startIndex == 0L && length == num)
{
return array;
}
T[] array2 = new T[length];
Array.Copy(array, startIndex, array2, 0L, length);
return array2;
}
public static void Times(this int n, Action action)
{
if (n > 0 && action != null)
{
((ulong)n).times(action);
}
}
public static void Times(this long n, Action action)
{
if (n > 0 && action != null)
{
((ulong)n).times(action);
}
}
public static void Times(this uint n, Action action)
{
if (n != 0 && action != null)
{
times(n, action);
}
}
public static void Times(this ulong n, Action action)
{
if (n != 0 && action != null)
{
n.times(action);
}
}
public static void Times(this int n, Action<int> action)
{
if (n > 0 && action != null)
{
for (int i = 0; i < n; i++)
{
action(i);
}
}
}
public static void Times(this long n, Action<long> action)
{
if (n > 0 && action != null)
{
for (long num = 0L; num < n; num++)
{
action(num);
}
}
}
public static void Times(this uint n, Action<uint> action)
{
if (n != 0 && action != null)
{
for (uint num = 0u; num < n; num++)
{
action(num);
}
}
}
public static void Times(this ulong n, Action<ulong> action)
{
if (n != 0 && action != null)
{
for (ulong num = 0uL; num < n; num++)
{
action(num);
}
}
}
public static T To<T>(this byte[] source, ByteOrder sourceOrder) where T : struct
{
if (source == null)
{
throw new ArgumentNullException("source");
}
if (source.Length == 0)
{
return default(T);
}
Type typeFromHandle = typeof(T);
byte[] value = source.ToHostOrder(sourceOrder);
return ((object)typeFromHandle == typeof(bool)) ? ((T)(object)BitConverter.ToBoolean(value, 0)) : (((object)typeFromHandle == typeof(char)) ? ((T)(object)BitConverter.ToChar(value, 0)) : (((object)typeFromHandle == typeof(double)) ? ((T)(object)BitConverter.ToDouble(value, 0)) : (((object)typeFromHandle == typeof(short)) ? ((T)(object)BitConverter.ToInt16(value, 0)) : (((object)typeFromHandle == typeof(int)) ? ((T)(object)BitConverter.ToInt32(value, 0)) : (((object)typeFromHandle == typeof(long)) ? ((T)(object)BitConverter.ToInt64(value, 0)) : (((object)typeFromHandle == typeof(float)) ? ((T)(object)BitConverter.ToSingle(value, 0)) : (((object)typeFromHandle == typeof(ushort)) ? ((T)(object)BitConverter.ToUInt16(value, 0)) : (((object)typeFromHandle == typeof(uint)) ? ((T)(object)BitConverter.ToUInt32(value, 0)) : (((object)typeFromHandle == typeof(ulong)) ? ((T)(object)BitConverter.ToUInt64(value, 0)) : default(T))))))))));
}
public static byte[] ToByteArray<T>(this T value, ByteOrder order) where T : struct
{
Type typeFromHandle = typeof(T);
byte[] array = (((object)typeFromHandle == typeof(bool)) ? BitConverter.GetBytes((bool)(object)value) : (((object)typeFromHandle != typeof(byte)) ? (((object)typeFromHandle == typeof(char)) ? BitConverter.GetBytes((char)(object)value) : (((object)typeFromHandle == typeof(double)) ? BitConverter.GetBytes((double)(object)value) : (((object)typeFromHandle == typeof(short)) ? BitConverter.GetBytes((short)(object)value) : (((object)typeFromHandle == typeof(int)) ? BitConverter.GetBytes((int)(object)value) : (((object)typeFromHandle == typeof(long)) ? BitConverter.GetBytes((long)(object)value) : (((object)typeFromHandle == typeof(float)) ? BitConverter.GetBytes((float)(object)value) : (((object)typeFromHandle == typeof(ushort)) ? BitConverter.GetBytes((ushort)(object)value) : (((object)typeFromHandle == typeof(uint)) ? BitConverter.GetBytes((uint)(object)value) : (((object)typeFromHandle == typeof(ulong)) ? BitConverter.GetBytes((ulong)(object)value) : WebSocket.EmptyBytes))))))))) : new byte[1] { (byte)(object)value }));
if (array.Length > 1 && !order.IsHostOrder())
{
Array.Reverse((Array)array);
}
return array;
}
public static byte[] ToHostOrder(this byte[] source, ByteOrder sourceOrder)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
return (source.Length > 1 && !sourceOrder.IsHostOrder()) ? source.Reverse() : source;
}
public static string ToString<T>(this T[] array, string separator)
{
if (array == null)
{
throw new ArgumentNullException("array");
}
int num = array.Length;
if (num == 0)
{
return string.Empty;
}
if (separator == null)
{
separator = string.Empty;
}
StringBuilder buff = new StringBuilder(64);
(num - 1).Times(delegate(int i)
{
buff.AppendFormat("{0}{1}", array[i].ToString(), separator);
});
buff.Append(array[num - 1].ToString());
return buff.ToString();
}
public static Uri ToUri(this string uriString)
{
Uri.TryCreate(uriString, uriString.MaybeUri() ? UriKind.Absolute : UriKind.Relative, out Uri result);
return result;
}
public static string UrlDecode(this string value)
{
return (value != null && value.Length > 0) ? HttpUtility.UrlDecode(value) : value;
}
public static string UrlEncode(this string value)
{
return (value != null && value.Length > 0) ? HttpUtility.UrlEncode(value) : value;
}
public static void WriteContent(this WebSocketSharp.Net.HttpListenerResponse response, byte[] content)
{
if (response == null)
{
throw new ArgumentNullException("response");
}
if (content == null)
{
throw new ArgumentNullException("content");
}
long num = content.LongLength;
if (num == 0)
{
response.Close();
return;
}
response.ContentLength64 = num;
Stream outputStream = response.OutputStream;
if (num <= int.MaxValue)
{
outputStream.Write(content, 0, (int)num);
}
else
{
outputStream.WriteBytes(content, 1024);
}
outputStream.Close();
}
}
public class MessageEventArgs : EventArgs
{
private string _data;
private bool _dataSet;
private Opcode _opcode;
private byte[] _rawData;
internal Opcode Opcode => _opcode;
public string Data
{
get
{
if (!_dataSet)
{
_data = ((_opcode != Opcode.Binary) ? _rawData.UTF8Decode() : BitConverter.ToString(_rawData));
_dataSet = true;
}
return _data;
}
}
public bool IsBinary => _opcode == Opcode.Binary;
public bool IsPing => _opcode == Opcode.Ping;
public bool IsText => _opcode == Opcode.Text;
public bool IsClose => _opcode == Opcode.Close;
public byte[] RawData => _rawData;
internal MessageEventArgs(WebSocketFrame frame)
{
_opcode = frame.Opcode;
_rawData = frame.PayloadData.ApplicationData;
}
internal MessageEventArgs(Opcode opcode, byte[] rawData)
{
if ((ulong)rawData.LongLength > PayloadData.MaxLength)
{
throw new WebSocketException(CloseStatusCode.TooBig);
}
_opcode = opcode;
_rawData = rawData;
}
}
public class CloseEventArgs : EventArgs
{
private bool _clean;
private PayloadData _payloadData;
internal PayloadData PayloadData => _payloadData;
public ushort Code => _payloadData.Code;
public string Reason => _payloadData.Reason ?? string.Empty;
public bool WasClean
{
get
{
return _clean;
}
internal set
{
_clean = value;
}
}
internal CloseEventArgs()
{
_payloadData = PayloadData.Empty;
}
internal CloseEventArgs(ushort code)
: this(code, null)
{
}
internal CloseEventArgs(CloseStatusCode code)
: this((ushort)code, null)
{
}
internal CloseEventArgs(PayloadData payloadData)
{
_payloadData = payloadData;
}
internal CloseEventArgs(ushort code, string reason)
{
_payloadData = new PayloadData(code, reason);
}
internal CloseEventArgs(CloseStatusCode code, string reason)
: this((ushort)code, reason)
{
}
}
public enum ByteOrder
{
Little,
Big
}
public class ErrorEventArgs : EventArgs
{
private Exception _exception;
private string _message;
public Exception Exception => _exception;
public string Message => _message;
internal ErrorEventArgs(string message)
: this(message, null)
{
}
internal ErrorEventArgs(string message, Exception exception)
{
_message = message;
_exception = exception;
}
}
public class WebSocket : IDisposable
{
private AuthenticationChallenge _authChallenge;
private string _base64Key;
private bool _client;
private Action _closeContext;
private CompressionMethod _compression;
private WebSocketContext _context;
private WebSocketSharp.Net.CookieCollection _cookies;
private WebSocketSharp.Net.NetworkCredential _credentials;
private bool _emitOnPing;
private bool _enableRedirection;
private AutoResetEvent _exitReceiving;
private string _extensions;
private bool _extensionsRequested;
private object _forMessageEventQueue;
private object _forSend;
private object _forState;
private MemoryStream _fragmentsBuffer;
private bool _fragmentsCompressed;
private Opcode _fragmentsOpcode;
private const string _guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
private Func<WebSocketContext, string> _handshakeRequestChecker;
private bool _ignoreExtensions;
private bool _inContinuation;
private volatile bool _inMessage;
private volatile Logger _logger;
private Action<MessageEventArgs> _message;
private Queue<MessageEventArgs> _messageEventQueue;
private uint _nonceCount;
private string _origin;
private bool _preAuth;
private string _protocol;
private string[] _protocols;
private bool _protocolsRequested;
private WebSocketSharp.Net.NetworkCredential _proxyCredentials;
private Uri _proxyUri;
private volatile WebSocketState _readyState;
private AutoResetEvent _receivePong;
private bool _secure;
private ClientSslConfiguration _sslConfig;
private Stream _stream;
private TcpClient _tcpClient;
private Uri _uri;
private const string _version = "13";
private TimeSpan _waitTime;
internal static readonly byte[] EmptyBytes;
internal static readonly int FragmentLength;
internal static readonly RandomNumberGenerator RandomNumber;
internal WebSocketSharp.Net.CookieCollection CookieCollection => _cookies;
internal Func<WebSocketContext, string> CustomHandshakeRequestChecker
{
get
{
return _handshakeRequestChecker;
}
set
{
_handshakeRequestChecker = value;
}
}
internal bool HasMessage
{
get
{
lock (_forMessageEventQueue)
{
return _messageEventQueue.Count > 0;
}
}
}
internal bool IgnoreExtensions
{
get
{
return _ignoreExtensions;
}
set
{
_ignoreExtensions = value;
}
}
internal bool IsConnected => _readyState == WebSocketState.Open || _readyState == WebSocketState.Closing;
public CompressionMethod Compression
{
get
{
return _compression;
}
set
{
lock (_forState)
{
if (!checkIfAvailable(client: true, server: false, connecting: true, open: false, closing: false, closed: true, out var text))
{
_logger.Error(text);
error("An error has occurred in setting the compression.", null);
}
else
{
_compression = value;
}
}
}
}
public IEnumerable<WebSocketSharp.Net.Cookie> Cookies
{
get
{
lock (_cookies.SyncRoot)
{
foreach (WebSocketSharp.Net.Cookie cookie in _cookies)
{
yield return cookie;
}
}
}
}
public WebSocketSharp.Net.NetworkCredential Credentials => _credentials;
public bool EmitOnPing
{
get
{
return _emitOnPing;
}
set
{
_emitOnPing = value;
}
}
public bool EnableRedirection
{
get
{
return _enableRedirection;
}
set
{
lock (_forState)
{
if (!checkIfAvailable(client: true, server: false, connecting: true, open: false, closing: false, closed: true, out var text))
{
_logger.Error(text);
error("An error has occurred in setting the enable redirection.", null);
}
else
{
_enableRedirection = value;
}
}
}
}
public string Extensions => _extensions ?? string.Empty;
public bool IsAlive => Ping();
public bool IsSecure => _secure;
public Logger Log
{
get
{
return _logger;
}
internal set
{
_logger = value;
}
}
public string Origin
{
get
{
return _origin;
}
set
{
lock (_forState)
{
Uri result;
if (!checkIfAvailable(client: true, server: false, connecting: true, open: false, closing: false, closed: true, out var text))
{
_logger.Error(text);
error("An error has occurred in setting the origin.", null);
}
else if (value.IsNullOrEmpty())
{
_origin = value;
}
else if (!Uri.TryCreate(value, UriKind.Absolute, out result) || result.Segments.Length > 1)
{
_logger.Error("The syntax of an origin must be '<scheme>://<host>[:<port>]'.");
error("An error has occurred in setting the origin.", null);
}
else
{
_origin = value.TrimEnd(new char[1] { '/' });
}
}
}
}
public string Protocol
{
get
{
return _protocol ?? string.Empty;
}
internal set
{
_protocol = value;
}
}
public WebSocketState ReadyState => _readyState;
public ClientSslConfiguration SslConfiguration
{
get
{
return _client ? (_sslConfig ?? (_sslConfig = new ClientSslConfiguration(_uri.DnsSafeHost))) : null;
}
set
{
lock (_forState)
{
if (!checkIfAvailable(client: true, server: false, connecting: true, open: false, closing: false, closed: true, out var text))
{
_logger.Error(text);
error("An error has occurred in setting the ssl configuration.", null);
}
else
{
_sslConfig = value;
}
}
}
}
public Uri Url => _client ? _uri : _context.RequestUri;
public TimeSpan WaitTime
{
get
{
return _waitTime;
}
set
{
lock (_forState)
{
if (!checkIfAvailable(client: true, server: true, connecting: true, open: false, closing: false, closed: true, out var text) || !value.CheckWaitTime(out text))
{
_logger.Error(text);
error("An error has occurred in setting the wait time.", null);
}
else
{
_waitTime = value;
}
}
}
}
public event EventHandler<CloseEventArgs> OnClose;
public event EventHandler<ErrorEventArgs> OnError;
public event EventHandler<MessageEventArgs> OnMessage;
public event EventHandler OnOpen;
static WebSocket()
{
EmptyBytes = new byte[0];
FragmentLength = 1016;
RandomNumber = new RNGCryptoServiceProvider();
}
internal WebSocket(HttpListenerWebSocketContext context, string protocol)
{
_context = context;
_protocol = protocol;
_closeContext = context.Close;
_logger = context.Log;
_message = messages;
_secure = context.IsSecureConnection;
_stream = context.Stream;
_waitTime = TimeSpan.FromSeconds(1.0);
init();
}
internal WebSocket(TcpListenerWebSocketContext context, string protocol)
{
_context = context;
_protocol = protocol;
_closeContext = context.Close;
_logger = context.Log;
_message = messages;
_secure = context.IsSecureConnection;
_stream = context.Stream;
_waitTime = TimeSpan.FromSeconds(1.0);
init();
}
public WebSocket(string url, params string[] protocols)
{
if (url == null)
{
throw new ArgumentNullException("url");
}
if (url.Length == 0)
{
throw new ArgumentException("An empty string.", "url");
}
if (!url.TryCreateWebSocketUri(out _uri, out var text))
{
throw new ArgumentException(text, "url");
}
if (protocols != null && protocols.Length != 0)
{
text = protocols.CheckIfValidProtocols();
if (text != null)
{
throw new ArgumentException(text, "protocols");
}
_protocols = protocols;
}
_base64Key = CreateBase64Key();
_client = true;
_logger = new Logger();
_message = messagec;
_secure = _uri.Scheme == "wss";
_waitTime = TimeSpan.FromSeconds(5.0);
init();
}
private bool accept()
{
lock (_forState)
{
if (!checkIfAvailable(connecting: true, open: false, closing: false, closed: false, out var text))
{
_logger.Error(text);
error("An error has occurred in accepting.", null);
return false;
}
try
{
if (!acceptHandshake())
{
return false;
}
_readyState = WebSocketState.Open;
}
catch (Exception ex)
{
_logger.Fatal(ex.ToString());
fatal("An exception has occurred while accepting.", ex);
return false;
}
return true;
}
}
private bool acceptHandshake()
{
_logger.Debug($"A request from {_context.UserEndPoint}:\n{_context}");
if (!checkHandshakeRequest(_context, out var text))
{
sendHttpResponse(createHandshakeFailureResponse(WebSocketSharp.Net.HttpStatusCode.BadRequest));
_logger.Fatal(text);
fatal("An error has occurred while accepting.", CloseStatusCode.ProtocolError);
return false;
}
if (!customCheckHandshakeRequest(_context, out text))
{
sendHttpResponse(createHandshakeFailureResponse(WebSocketSharp.Net.HttpStatusCode.BadRequest));
_logger.Fatal(text);
fatal("An error has occurred while accepting.", CloseStatusCode.PolicyViolation);
return false;
}
_base64Key = _context.Headers["Sec-WebSocket-Key"];
if (_protocol != null)
{
processSecWebSocketProtocolHeader(_context.SecWebSocketProtocols);
}
if (!_ignoreExtensions)
{
processSecWebSocketExtensionsClientHeader(_context.Headers["Sec-WebSocket-Extensions"]);
}
return sendHttpResponse(createHandshakeResponse());
}
private bool checkHandshakeRequest(WebSocketContext context, out string message)
{
message = null;
if (context.RequestUri == null)
{
message = "Specifies an invalid Request-URI.";
return false;
}
if (!context.IsWebSocketRequest)
{
message = "Not a WebSocket handshake request.";
return false;
}
NameValueCollection headers = context.Headers;
if (!validateSecWebSocketKeyHeader(headers["Sec-WebSocket-Key"]))
{
message = "Includes no Sec-WebSocket-Key header, or it has an invalid value.";
return false;
}
if (!validateSecWebSocketVersionClientHeader(headers["Sec-WebSocket-Version"]))
{
message = "Includes no Sec-WebSocket-Version header, or it has an invalid value.";
return false;
}
if (!validateSecWebSocketProtocolClientHeader(headers["Sec-WebSocket-Protocol"]))
{
message = "Includes an invalid Sec-WebSocket-Protocol header.";
return false;
}
if (!_ignoreExtensions && !validateSecWebSocketExtensionsClientHeader(headers["Sec-WebSocket-Extensions"]))
{
message = "Includes an invalid Sec-WebSocket-Extensions header.";
return false;
}
return true;
}
private bool checkHandshakeResponse(HttpResponse response, out string message)
{
message = null;
if (response.IsRedirect)
{
message = "Indicates the redirection.";
return false;
}
if (response.IsUnauthorized)
{
message = "Requires the authentication.";
return false;
}
if (!response.IsWebSocketResponse)
{
message = "Not a WebSocket handshake response.";
return false;
}
NameValueCollection headers = response.Headers;
if (!validateSecWebSocketAcceptHeader(headers["Sec-WebSocket-Accept"]))
{
message = "Includes no Sec-WebSocket-Accept header, or it has an invalid value.";
return false;
}
if (!validateSecWebSocketProtocolServerHeader(headers["Sec-WebSocket-Protocol"]))
{
message = "Includes no Sec-WebSocket-Protocol header, or it has an invalid value.";
return false;
}
if (!validateSecWebSocketExtensionsServerHeader(headers["Sec-WebSocket-Extensions"]))
{
message = "Includes an invalid Sec-WebSocket-Extensions header.";
return false;
}
if (!validateSecWebSocketVersionServerHeader(headers["Sec-WebSocket-Version"]))
{
message = "Includes an invalid Sec-WebSocket-Version header.";
return false;
}
return true;
}
private bool checkIfAvailable(bool connecting, bool open, bool closing, bool closed, out string message)
{
message = null;
if (!connecting && _readyState == WebSocketState.Connecting)
{
message = "This operation is not available in: connecting";
return false;
}
if (!open && _readyState == WebSocketState.Open)
{
message = "This operation is not available in: open";
return false;
}
if (!closing && _readyState == WebSocketState.Closing)
{
message = "This operation is not available in: closing";
return false;
}
if (!closed && _readyState == WebSocketState.Closed)
{
message = "This operation is not available in: closed";
return false;
}
return true;
}
private bool checkIfAvailable(bool client, bool server, bool connecting, bool open, bool closing, bool closed, out string message)
{
message = null;
if (!client && _client)
{
message = "This operation is not available in: client";
return false;
}
if (!server && !_client)
{
message = "This operation is not available in: server";
return false;
}
return checkIfAvailable(connecting, open, closing, closed, out message);
}
private static bool checkParametersForSetCredentials(string username, string password, out string message)
{
message = null;
if (username.IsNullOrEmpty())
{
return true;
}
if (Ext.Contains(username, ':') || !username.IsText())
{
message = "'username' contains an invalid character.";
return false;
}
if (password.IsNullOrEmpty())
{
return true;
}
if (!password.IsText())
{
message = "'password' contains an invalid character.";
return false;
}
return true;
}
private static bool checkParametersForSetProxy(string url, string username, string password, out string message)
{
message = null;
if (url.IsNullOrEmpty())
{
return true;
}
if (!Uri.TryCreate(url, UriKind.Absolute, out Uri result) || result.Scheme != "http" || result.Segments.Length > 1)
{
message = "'url' is an invalid URL.";
return false;
}
if (username.IsNullOrEmpty())
{
return true;
}
if (Ext.Contains(username, ':') || !username.IsText())
{
message = "'username' contains an invalid character.";
return false;
}
if (password.IsNullOrEmpty())
{
return true;
}
if (!password.IsText())
{
message = "'password' contains an invalid character.";
return false;
}
return true;
}
private bool checkReceivedFrame(WebSocketFrame frame, out string message)
{
message = null;
bool isMasked = frame.IsMasked;
if (_client && isMasked)
{
message = "A frame from the server is masked.";
return false;
}
if (!_client && !isMasked)
{
message = "A frame from a client is not masked.";
return false;
}
if (_inContinuation && frame.IsData)
{
message = "A data frame has been received while receiving continuation frames.";
return false;
}
if (frame.IsCompressed && _compression == CompressionMethod.None)
{
message = "A compressed frame has been received without any agreement for it.";
return false;
}
if (frame.Rsv2 == Rsv.On)
{
message = "The RSV2 of a frame is non-zero without any negotiation for it.";
return false;
}
if (frame.Rsv3 == Rsv.On)
{
message = "The RSV3 of a frame is non-zero without any negotiation for it.";
return false;
}
return true;
}
private void close(ushort code, string reason)
{
if (code == 1005)
{
close(new CloseEventArgs(), send: true, receive: true, received: false);
return;
}
bool receive = !code.IsReserved();
close(new CloseEventArgs(code, reason), receive, receive, received: false);
}
private void close(CloseEventArgs e, bool send, bool receive, bool received)
{
lock (_forState)
{
if (_readyState == WebSocketState.Closing)
{
_logger.Info("The closing is already in progress.");
return;
}
if (_readyState == WebSocketState.Closed)
{
_logger.Info("The connection has been closed.");
return;
}
send = send && _readyState == WebSocketState.Open;
receive = receive && send;
_readyState = WebSocketState.Closing;
}
_logger.Trace("Begin closing the connection.");
byte[] frameAsBytes = (send ? WebSocketFrame.CreateCloseFrame(e.PayloadData, _client).ToArray() : null);
e.WasClean = closeHandshake(frameAsBytes, receive, received);
releaseResources();
_logger.Trace("End closing the connection.");
_readyState = WebSocketState.Closed;
try
{
this.OnClose.Emit(this, e);
}
catch (Exception ex)
{
_logger.Error(ex.ToString());
error("An exception has occurred during the OnClose event.", ex);
}
}
private void closeAsync(ushort code, string reason)
{
if (code == 1005)
{
closeAsync(new CloseEventArgs(), send: true, receive: true, received: false);
return;
}
bool receive = !code.IsReserved();
closeAsync(new CloseEventArgs(code, reason), receive, receive, received: false);
}
private void closeAsync(CloseEventArgs e, bool send, bool receive, bool received)
{
Action<CloseEventArgs, bool, bool, bool> closer = close;
closer.BeginInvoke(e, send, receive, received, delegate(IAsyncResult ar)
{
closer.EndInvoke(ar);
}, null);
}
private bool closeHandshake(byte[] frameAsBytes, bool receive, bool received)
{
bool flag = frameAsBytes != null && sendBytes(frameAsBytes);
received = received || (receive && flag && _exitReceiving != null && _exitReceiving.WaitOne(_waitTime));
bool flag2 = flag && received;
_logger.Debug($"Was clean?: {flag2}\n sent: {flag}\n received: {received}");
return flag2;
}
private bool connect()
{
lock (_forState)
{
if (!checkIfAvailable(connecting: true, open: false, closing: false, closed: true, out var text))
{
_logger.Error(text);
error("An error has occurred in connecting.", null);
return false;
}
try
{
_readyState = WebSocketState.Connecting;
if (!doHandshake())
{
return false;
}
_readyState = WebSocketState.Open;
}
catch (Exception ex)
{
_logger.Fatal(ex.ToString());
fatal("An exception has occurred while connecting.", ex);
return false;
}
return true;
}
}
private string createExtensions()
{
StringBuilder stringBuilder = new StringBuilder(80);
if (_compression != 0)
{
string arg = _compression.ToExtensionString("server_no_context_takeover", "client_no_context_takeover");
stringBuilder.AppendFormat("{0}, ", arg);
}
int length = stringBuilder.Length;
if (length > 2)
{
stringBuilder.Length = length - 2;
return stringBuilder.ToString();
}
return null;
}
private HttpResponse createHandshakeFailureResponse(WebSocketSharp.Net.HttpStatusCode code)
{
HttpResponse httpResponse = HttpResponse.CreateCloseResponse(code);
httpResponse.Headers["Sec-WebSocket-Version"] = "13";
return httpResponse;
}
private HttpRequest createHandshakeRequest()
{
HttpRequest httpRequest = HttpRequest.CreateWebSocketRequest(_uri);
NameValueCollection headers = httpRequest.Headers;
if (!_origin.IsNullOrEmpty())
{
headers["Origin"] = _origin;
}
headers["Sec-WebSocket-Key"] = _base64Key;
_protocolsRequested = _protocols != null;
if (_protocolsRequested)
{
headers["Sec-WebSocket-Protocol"] = _protocols.ToString(", ");
}
_extensionsRequested = _compression != CompressionMethod.None;
if (_extensionsRequested)
{
headers["Sec-WebSocket-Extensions"] = createExtensions();
}
headers["Sec-WebSocket-Version"] = "13";
AuthenticationResponse authenticationResponse = null;
if (_authChallenge != null && _credentials != null)
{
authenticationResponse = new AuthenticationResponse(_authChallenge, _credentials, _nonceCount);
_nonceCount = authenticationResponse.NonceCount;
}
else if (_preAuth)
{
authenticationResponse = new AuthenticationResponse(_credentials);
}
if (authenticationResponse != null)
{
headers["Authorization"] = authenticationResponse.ToString();
}
if (_cookies.Count > 0)
{
httpRequest.SetCookies(_cookies);
}
return httpRequest;
}
private HttpResponse createHandshakeResponse()
{
HttpResponse httpResponse = HttpResponse.CreateWebSocketResponse();
NameValueCollection headers = httpResponse.Headers;
headers["Sec-WebSocket-Accept"] = CreateResponseKey(_base64Key);
if (_protocol != null)
{
headers["Sec-WebSocket-Protocol"] = _protocol;
}
if (_extensions != null)
{
headers["Sec-WebSocket-Extensions"] = _extensions;
}
if (_cookies.Count > 0)
{
httpResponse.SetCookies(_cookies);
}
return httpResponse;
}
private bool customCheckHandshakeRequest(WebSocketContext context, out string message)
{
message = null;
return _handshakeRequestChecker == null || (message = _handshakeRequestChecker(context)) == null;
}
private MessageEventArgs dequeueFromMessageEventQueue()
{
lock (_forMessageEventQueue)
{
return (_messageEventQueue.Count > 0) ? _messageEventQueue.Dequeue() : null;
}
}
private bool doHandshake()
{
setClientStream();
HttpResponse httpResponse = sendHandshakeRequest();
if (!checkHandshakeResponse(httpResponse, out var text))
{
_logger.Fatal(text);
fatal("An error has occurred while connecting.", CloseStatusCode.ProtocolError);
return false;
}
if (_protocolsRequested)
{
_protocol = httpResponse.Headers["Sec-WebSocket-Protocol"];
}
if (_extensionsRequested)
{
processSecWebSocketExtensionsServerHeader(httpResponse.Headers["Sec-WebSocket-Extensions"]);
}
processCookies(httpResponse.Cookies);
return true;
}
private void enqueueToMessageEventQueue(MessageEventArgs e)
{
lock (_forMessageEventQueue)
{
_messageEventQueue.Enqueue(e);
}
}
private void error(string message, Exception exception)
{
try
{
this.OnError.Emit(this, new ErrorEventArgs(message, exception));
}
catch (Exception ex)
{
_logger.Error(ex.ToString());
}
}
private void fatal(string message, Exception exception)
{
CloseStatusCode code = ((exception is WebSocketException) ? ((WebSocketException)exception).Code : CloseStatusCode.Abnormal);
fatal(message, code);
}
private void fatal(string message, CloseStatusCode code)
{
close(new CloseEventArgs(code, message), !code.IsReserved(), receive: false, received: false);
}
private void init()
{
_compression = CompressionMethod.None;
_cookies = new WebSocketSharp.Net.CookieCollection();
_forSend = new object();
_forState = new object();
_messageEventQueue = new Queue<MessageEventArgs>();
_forMessageEventQueue = ((ICollection)_messageEventQueue).SyncRoot;
_readyState = WebSocketState.Connecting;
}
private void message()
{
MessageEventArgs obj = null;
lock (_forMessageEventQueue)
{
if (_inMessage || _messageEventQueue.Count == 0 || _readyState != WebSocketState.Open)
{
return;
}
_inMessage = true;
obj = _messageEventQueue.Dequeue();
}
_message(obj);
}
private void messagec(MessageEventArgs e)
{
while (true)
{
try
{
this.OnMessage.Emit(this, e);
}
catch (Exception ex)
{
_logger.Error(ex.ToString());
error("An exception has occurred during an OnMessage event.", ex);
}
lock (_forMessageEventQueue)
{
if (_messageEventQueue.Count == 0 || _readyState != WebSocketState.Open)
{
_inMessage = false;
break;
}
e = _messageEventQueue.Dequeue();
}
bool flag = true;
}
}
private void messages(MessageEventArgs e)
{
try
{
this.OnMessage.Emit(this, e);
}
catch (Exception ex)
{
_logger.Error(ex.ToString());
error("An exception has occurred during an OnMessage event.", ex);
}
lock (_forMessageEventQueue)
{
if (_messageEventQueue.Count == 0 || _readyState != WebSocketState.Open)
{
_inMessage = false;
return;
}
e = _messageEventQueue.Dequeue();
}
ThreadPool.QueueUserWorkItem(delegate
{
messages(e);
});
}
private void open()
{
_inMessage = true;
startReceiving();
try
{
this.OnOpen.Emit(this, EventArgs.Empty);
}
catch (Exception ex)
{
_logger.Error(ex.ToString());
error("An exception has occurred during the OnOpen event.", ex);
}
MessageEventArgs obj = null;
lock (_forMessageEventQueue)
{
if (_messageEventQueue.Count == 0 || _readyState != WebSocketState.Open)
{
_inMessage = false;
return;
}
obj = _messageEventQueue.Dequeue();
}
_message.BeginInvoke(obj, delegate(IAsyncResult ar)
{
_message.EndInvoke(ar);
}, null);
}
private bool processCloseFrame(WebSocketFrame frame)
{
PayloadData payloadData = frame.PayloadData;
close(new CloseEventArgs(payloadData), !payloadData.HasReservedCode, receive: false, received: true);
return false;
}
private void processCookies(WebSocketSharp.Net.CookieCollection cookies)
{
if (cookies.Count != 0)
{
_cookies.SetOrRemove(cookies);
}
}
private bool processDataFrame(WebSocketFrame frame)
{
enqueueToMessageEventQueue(frame.IsCompressed ? new MessageEventArgs(frame.Opcode, frame.PayloadData.ApplicationData.Decompress(_compression)) : new MessageEventArgs(frame));
return true;
}
private bool processFragmentFrame(WebSocketFrame frame)
{
if (!_inContinuation)
{
if (frame.IsContinuation)
{
return true;
}
_fragmentsOpcode = frame.Opcode;
_fragmentsCompressed = frame.IsCompressed;
_fragmentsBuffer = new MemoryStream();
_inContinuation = true;
}
_fragmentsBuffer.WriteBytes(frame.PayloadData.ApplicationData, 1024);
if (frame.IsFinal)
{
using (_fragmentsBuffer)
{
byte[] rawData = (_fragmentsCompressed ? _fragmentsBuffer.DecompressToArray(_compression) : _fragmentsBuffer.ToArray());
enqueueToMessageEventQueue(new MessageEventArgs(_fragmentsOpcode, rawData));
}
_fragmentsBuffer = null;
_inContinuation = false;
}
return true;
}
private bool processPingFrame(WebSocketFrame frame)
{
if (send(new WebSocketFrame(Opcode.Pong, frame.PayloadData, _client).ToArray()))
{
_logger.Trace("Returned a pong.");
}
if (_emitOnPing)
{
enqueueToMessageEventQueue(new MessageEventArgs(frame));
}
return true;
}
private bool processPongFrame(WebSocketFrame frame)
{
_receivePong.Set();
_logger.Trace("Received a pong.");
return true;
}
private bool processReceivedFrame(WebSocketFrame frame)
{
if (!checkReceivedFrame(frame, out var text))
{
throw new WebSocketException(CloseStatusCode.ProtocolError, text);
}
frame.Unmask();
return frame.IsFragment ? processFragmentFrame(frame) : (frame.IsData ? processDataFrame(frame) : (frame.IsPing ? processPingFrame(frame) : (frame.IsPong ? processPongFrame(frame) : (frame.IsClose ? processCloseFrame(frame) : processUnsupportedFrame(frame)))));
}
private void processSecWebSocketExtensionsClientHeader(string value)
{
if (value == null)
{
return;
}
StringBuilder stringBuilder = new StringBuilder(80);
bool flag = false;
foreach (string item in value.SplitHeaderValue(','))
{
string value2 = item.Trim();
if (!flag && value2.IsCompressionExtension(CompressionMethod.Deflate))
{
_compression = CompressionMethod.Deflate;
stringBuilder.AppendFormat("{0}, ", _compression.ToExtensionString("client_no_context_takeover", "server_no_context_takeover"));
flag = true;
}
}
int length = stringBuilder.Length;
if (length > 2)
{
stringBuilder.Length = length - 2;
_extensions = stringBuilder.ToString();
}
}
private void processSecWebSocketExtensionsServerHeader(string value)
{
if (value == null)
{
_compression = CompressionMethod.None;
}
else
{
_extensions = value;
}
}
private void processSecWebSocketProtocolHeader(IEnumerable<string> values)
{
if (!values.Contains((string p) => p == _protocol))
{
_protocol = null;
}
}
private bool processUnsupportedFrame(WebSocketFrame frame)
{
_logger.Fatal("An unsupported frame:" + frame.PrintToString(dumped: false));
fatal("There is no way to handle it.", CloseStatusCode.PolicyViolation);
return false;
}
private void releaseClientResources()
{
if (_stream != null)
{
_stream.Dispose();
_stream = null;
}
if (_tcpClient != null)
{
_tcpClient.Close();
_tcpClient = null;
}
}
private void releaseCommonResources()
{
if (_fragmentsBuffer != null)
{
_fragmentsBuffer.Dispose();
_fragmentsBuffer = null;
_inContinuation = false;
}
if (_receivePong != null)
{
_receivePong.Close();
_receivePong = null;
}
if (_exitReceiving != null)
{
_exitReceiving.Close();
_exitReceiving = null;
}
}
private void releaseResources()
{
if (_client)
{
releaseClientResources();
}
else
{
releaseServerResources();
}
releaseCommonResources();
}
private void releaseServerResources()
{
if (_closeContext != null)
{
_closeContext();
_closeContext = null;
_stream = null;
_context = null;
}
}
private bool send(byte[] frameAsBytes)
{
lock (_forState)
{
if (_readyState != WebSocketState.Open)
{
_logger.Error("The sending has been interrupted.");
return false;
}
return sendBytes(frameAsBytes);
}
}
private bool send(Opcode opcode, Stream stream)
{
lock (_forSend)
{
Stream stream2 = stream;
bool flag = false;
bool flag2 = false;
try
{
if (_compression != 0)
{
stream = stream.Compress(_compression);
flag = true;
}
flag2 = send(opcode, stream, flag);
if (!flag2)
{
error("The sending has been interrupted.", null);
}
}
catch (Exception ex)
{
_logger.Error(ex.ToString());
error("An exception has occurred while sending data.", ex);
}
finally
{
if (flag)
{
stream.Dispose();
}
stream2.Dispose();
}
return flag2;
}
}
private bool send(Opcode opcode, Stream stream, bool compressed)
{
long length = stream.Length;
if (length == 0)
{
return send(Fin.Final, opcode, EmptyBytes, compressed);
}
long num = length / FragmentLength;
int num2 = (int)(length % FragmentLength);
byte[] array = null;
if (num == 0)
{
array = new byte[num2];
return stream.Read(array, 0, num2) == num2 && send(Fin.Final, opcode, array, compressed);
}
array = new byte[FragmentLength];
if (num == 1 && num2 == 0)
{
return stream.Read(array, 0, FragmentLength) == FragmentLength && send(Fin.Final, opcode, array, compressed);
}
if (stream.Read(array, 0, FragmentLength) != FragmentLength || !send(Fin.More, opcode, array, compressed))
{
return false;
}
long num3 = ((num2 == 0) ? (num - 2) : (num - 1));
for (long num4 = 0L; num4 < num3; num4++)
{
if (stream.Read(array, 0, FragmentLength) != FragmentLength || !send(Fin.More, Opcode.Cont, array, compressed))
{
return false;
}
}
if (num2 == 0)
{
num2 = FragmentLength;
}
else
{
array = new byte[num2];
}
return stream.Read(array, 0, num2) == num2 && send(Fin.Final, Opcode.Cont, array, compressed);
}
private bool send(Fin fin, Opcode opcode, byte[] data, bool compressed)
{
lock (_forState)
{
if (_readyState != WebSocketState.Open)
{
_logger.Error("The sending has been interrupted.");
return false;
}
return sendBytes(new WebSocketFrame(fin, opcode, data, compressed, _client).ToArray());
}
}
private void sendAsync(Opcode opcode, Stream stream, Action<bool> completed)
{
Func<Opcode, Stream, bool> sender = send;
sender.BeginInvoke(opcode, stream, delegate(IAsyncResult ar)
{
try
{
bool obj = sender.EndInvoke(ar);
if (completed != null)
{
completed(obj);
}
}
catch (Exception ex)
{
_logger.Error(ex.ToString());
error("An exception has occurred during a send callback.", ex);
}
}, null);
}
private bool sendBytes(byte[] bytes)
{
try
{
_stream.Write(bytes, 0, bytes.Length);
return true;
}
catch (Exception ex)
{
_logger.Error(ex.ToString());
return false;
}
}
private HttpResponse sendHandshakeRequest()
{
HttpRequest httpRequest = createHandshakeRequest();
HttpResponse httpResponse = sendHttpRequest(httpRequest, 90000);
if (httpResponse.IsUnauthorized)
{
string text = httpResponse.Headers["WWW-Authenticate"];
_logger.Warn($"Received an authentication requirement for '{text}'.");
if (text.IsNullOrEmpty())
{
_logger.Error("No authentication challenge is specified.");
return httpResponse;
}
_authChallenge = AuthenticationChallenge.Parse(text);
if (_authChallenge == null)
{
_logger.Error("An invalid authentication challenge is specified.");
return httpResponse;
}
if (_credentials != null && (!_preAuth || _authChallenge.Scheme == WebSocketSharp.Net.AuthenticationSchemes.Digest))
{
if (httpResponse.HasConnectionClose)
{
releaseClientResources();
setClientStream();
}
AuthenticationResponse authenticationResponse = new AuthenticationResponse(_authChallenge, _credentials, _nonceCount);
_nonceCount = authenticationResponse.NonceCount;
httpRequest.Headers["Authorization"] = authenticationResponse.ToString();
httpResponse = sendHttpRequest(httpRequest, 15000);
}
}
if (httpResponse.IsRedirect)
{
string text2 = httpResponse.Headers["Location"];
_logger.Warn($"Received a redirection to '{text2}'.");
if (_enableRedirection)
{
if (text2.IsNullOrEmpty())
{
_logger.Error("No url to redirect is located.");
return httpResponse;
}
if (!text2.TryCreateWebSocketUri(out var result, out var text3))
{
_logger.Error("An invalid url to redirect is located: " + text3);
return httpResponse;
}
releaseClientResources();
_uri = result;
_secure = result.Scheme == "wss";
setClientStream();
return sendHandshakeRequest();
}
}
return httpResponse;
}
private HttpResponse sendHttpRequest(HttpRequest request, int millisecondsTimeout)
{
_logger.Debug("A request to the server:\n" + request.ToString());
HttpResponse response = request.GetResponse(_stream, millisecondsTimeout);
_logger.Debug("A response to this request:\n" + response.ToString());
return response;
}
private bool sendHttpResponse(HttpResponse response)
{
_logger.Debug("A response to this request:\n" + response.ToString());
return sendBytes(response.ToByteArray());
}
private void sendProxyConnectRequest()
{
HttpRequest httpRequest = HttpRequest.CreateConnectRequest(_uri);
HttpResponse httpResponse = sendHttpRequest(httpRequest, 90000);
if (httpResponse.IsProxyAuthenticationRequired)
{
string text = httpResponse.Headers["Proxy-Authenticate"];
_logger.Warn($"Received a proxy authentication requirement for '{text}'.");
if (text.IsNullOrEmpty())
{
throw new WebSocketException("No proxy authentication challenge is specified.");
}
AuthenticationChallenge authenticationChallenge = AuthenticationChallenge.Parse(text);
if (authenticationChallenge == null)
{
throw new WebSocketException("An invalid proxy authentication challenge is specified.");
}
if (_proxyCredentials != null)
{
if (httpResponse.HasConnectionClose)
{
releaseClientResources();
_tcpClient = new TcpClient(_proxyUri.DnsSafeHost, _proxyUri.Port);
_stream = _tcpClient.GetStream();
}
AuthenticationResponse authenticationResponse = new AuthenticationResponse(authenticationChallenge, _proxyCredentials, 0u);
httpRequest.Headers["Proxy-Authorization"] = authenticationResponse.ToString();
httpResponse = sendHttpRequest(httpRequest, 15000);
}
if (httpResponse.IsProxyAuthenticationRequired)
{
throw new WebSocketException("A proxy authentication is required.");
}
}
if (httpResponse.StatusCode[0] != '2')
{
throw new WebSocketException("The proxy has failed a connection to the requested host and port.");
}
}
private void setClientStream()
{
if (_proxyUri != null)
{
_tcpClient = new TcpClient(_proxyUri.DnsSafeHost, _proxyUri.Port);
_stream = _tcpClient.GetStream();
sendProxyConnectRequest();
}
else
{
_tcpClient = new TcpClient(_uri.DnsSafeHost, _uri.Port);
_stream = _tcpClient.GetStream();
}
if (_secure)
{
ClientSslConfiguration sslConfiguration = SslConfiguration;
string targetHost = sslConfiguration.TargetHost;
if (targetHost != _uri.DnsSafeHost)
{
throw new WebSocketException(CloseStatusCode.TlsHandshakeFailure, "An invalid host name is specified.");
}
try
{
SslStream sslStream = new SslStream(_stream, leaveInnerStreamOpen: false, sslConfiguration.ServerCertificateValidationCallback, sslConfiguration.ClientCertificateSelectionCallback);
sslStream.AuthenticateAsClient(targetHost, sslConfiguration.ClientCertificates, sslConfiguration.EnabledSslProtocols, sslConfiguration.CheckCertificateRevocation);
_stream = sslStream;
}
catch (Exception innerException)
{
throw new WebSocketException(CloseStatusCode.TlsHandshakeFailure, innerException);
}
}
}
private void startReceiving()
{
if (_messageEventQueue.Count > 0)
{
_messageEventQueue.Clear();
}
_exitReceiving = new AutoResetEvent(initialState: false);
_receivePong = new AutoResetEvent(initialState: false);
Action receive = null;
receive = delegate
{
WebSocketFrame.ReadFrameAsync(_stream, unmask: false, delegate(WebSocketFrame frame)
{
if (!processReceivedFrame(frame) || _readyState == WebSocketState.Closed)
{
_exitReceiving?.Set();
}
else
{
receive();
if (!_inMessage && HasMessage && _readyState == WebSocketState.Open)
{
message();
}
}
}, delegate(Exception ex)
{
_logger.Fatal(ex.ToString());
fatal("An exception has occurred while receiving.", ex);
});
};
receive();
}
private bool validateSecWebSocketAcceptHeader(string value)
{
return value != null && value == CreateResponseKey(_base64Key);
}
private bool validateSecWebSocketExtensionsClientHeader(string value)
{
return value == null || value.Length > 0;
}
private bool validateSecWebSocketExtensionsServerHeader(string value)
{
if (value == null)
{
return true;
}
if (value.Length == 0)
{
return false;
}
if (!_extensionsRequested)
{
return false;
}
bool flag = _compression != CompressionMethod.None;
foreach (string item in value.SplitHeaderValue(','))
{
string text = item.Trim();
if (flag && text.IsCompressionExtension(_compression))
{
if (!text.Contains("server_no_context_takeover"))
{
_logger.Error("The server hasn't sent back 'server_no_context_takeover'.");
return false;
}
if (!text.Contains("client_no_context_takeover"))
{
_logger.Warn("The server hasn't sent back 'client_no_context_takeover'.");
}
string method = _compression.ToExtensionString();
if (text.SplitHeaderValue(';').Contains(delegate(string t)
{
t = t.Trim();
return t != method && t != "server_no_context_takeover" && t != "client_no_context_takeover";
}))
{
return false;
}
continue;
}
return false;
}
return true;
}
private bool validateSecWebSocketKeyHeader(string value)
{
return value != null && value.Length > 0;
}
private bool validateSecWebSocketProtocolClientHeader(string value)
{
return value == null || value.Length > 0;
}
private bool validateSecWebSocketProtocolServerHeader(string value)
{
if (value == null)
{
return !_protocolsRequested;
}
if (value.Length == 0)
{
return false;
}
return _protocolsRequested && _protocols.Contains((string p) => p == value);
}
private bool validateSecWebSocketVersionClientHeader(string value)
{
return value != null && value == "13";
}
private bool validateSecWebSocketVersionServerHeader(string value)
{
return value == null || value == "13";
}
internal static bool CheckParametersForClose(ushort code, string reason, bool client, out string message)
{
message = null;
if (!code.IsCloseStatusCode())
{
message = "'code' is an invalid status code.";
return false;
}
if (code == 1005 && !reason.IsNullOrEmpty())
{
message = "'code' cannot have a reason.";
return false;
}
if (code == 1010 && !client)
{
message = "'code' cannot be used by a server.";
return false;
}
if (code == 1011 && client)
{
message = "'code' cannot be used by a client.";
return false;
}
if (!reason.IsNullOrEmpty() && reason.UTF8Encode().Length > 123)
{
message = "The size of 'reason' is greater than the allowable max size.";
return false;
}
return true;
}
internal static bool CheckParametersForClose(CloseStatusCode code, string reason, bool client, out string message)
{
message = null;
if (code == CloseStatusCode.NoStatus && !reason.IsNullOrEmpty())
{
message = "'code' cannot have a reason.";
return false;
}
if (code == CloseStatusCode.MandatoryExtension && !client)
{
message = "'code' cannot be used by a server.";
return false;
}
if (code == CloseStatusCode.ServerError && client)
{
message = "'code' cannot be used by a client.";
return false;
}
if (!reason.IsNullOrEmpty() && reason.UTF8Encode().Length > 123)
{
message = "The size of 'reason' is greater than the allowable max size.";
return false;
}
return true;
}
internal static string CheckPingParameter(string message, out byte[] bytes)
{
bytes = message.UTF8Encode();
return (bytes.Length > 125) ? "A message has greater than the allowable max size." : null;
}
internal static string CheckSendParameter(byte[] data)
{
return (data == null) ? "'data' is null." : null;
}
internal static string CheckSendParameter(FileInfo file)
{
return (file == null) ? "'file' is null." : null;
}
internal static string CheckSendParameter(string data)
{
return (data == null) ? "'data' is null." : null;
}
internal static string CheckSendParameters(Stream stream, int length)
{
return (stream == null) ? "'stream' is null." : ((!stream.CanRead) ? "'stream' cannot be read." : ((length < 1) ? "'length' is less than 1." : null));
}
internal void Close(HttpResponse response)
{
_readyState = WebSocketState.Closing;
sendHttpResponse(response);
releaseServerResources();
_readyState = WebSocketState.Closed;
}
internal void Close(WebSocketSharp.Net.HttpStatusCode code)
{
Close(createHandshakeFailureResponse(code));
}
internal void Close(CloseEventArgs e, byte[] frameAsBytes, bool receive)
{
lock (_forState)
{
if (_readyState == WebSocketState.Closing)
{
_logger.Info("The closing is already in progress.");
return;
}
if (_readyState == WebSocketState.Closed)
{
_logger.Info("The connection has been closed.");
return;
}
_readyState = WebSocketState.Closing;
}
e.WasClean = closeHandshake(frameAsBytes, receive, received: false);
releaseServerResources();
releaseCommonResources();
_readyState = WebSocketState.Closed;
try
{
this.OnClose.Emit(this, e);
}
catch (Exception ex)
{
_logger.Error(ex.ToString());
}
}
internal static string CreateBase64Key()
{
byte[] array = new byte[16];
RandomNumber.GetBytes(array);
return Convert.ToBase64String(array);
}
internal static string CreateResponseKey(string base64Key)
{
StringBuilder stringBuilder = new StringBuilder(base64Key, 64);
stringBuilder.Append("258EAFA5-E914-47DA-95CA-C5AB0DC85B11");
SHA1 sHA = new SHA1CryptoServiceProvider();
byte[] inArray = sHA.ComputeHash(stringBuilder.ToString().UTF8Encode());
return Convert.ToBase64String(inArray);
}
internal void InternalAccept()
{
try
{
if (!acceptHandshake())
{
return;
}
_readyState = WebSocketState.Open;
}
catch (Exception ex)
{
_logger.Fatal(ex.ToString());
fatal("An exception has occurred while accepting.", ex);
return;
}
open();
}
internal bool Ping(byte[] frameAsBytes, TimeSpan timeout)
{
if (_readyState != WebSocketState.Open)
{
return false;
}
if (!send(frameAsBytes))
{
return false;
}
return _receivePong?.WaitOne(timeout) ?? false;
}
internal void Send(Opcode opcode, byte[] data, Dictionary<CompressionMethod, byte[]> cache)
{
lock (_forSend)
{
lock (_forState)
{
if (_readyState != WebSocketState.Open)
{
_logger.Error("The sending has been interrupted.");
return;
}
try
{
if (!cache.TryGetValue(_compression, out var value))
{
value = new WebSocketFrame(Fin.Final, opcode, data.Compress(_compression), _compression != CompressionMethod.None, mask: false).ToArray();
cache.Add(_compression, value);
}
sendBytes(value);
}
catch (Exception ex)
{
_logger.Error(ex.ToString());
}
}
}
}
internal void Send(Opcode opcode, Stream stream, Dictionary<CompressionMethod, Stream> cache)
{
lock (_forSend)
{
try
{
if (!cache.TryGetValue(_compression, out var value))
{
value = stream.Compress(_compression);
cache.Add(_compression, value);
}
else
{
value.Position = 0L;
}
send(opcode, value, _compression != CompressionMethod.None);
}
catch (Exception ex)
{
_logger.Error(ex.ToString());
}
}
}
public void Accept()
{
if (!checkIfAvailable(client: false, server: true, connecting: true, open: false, closing: false, closed: false, out var text))
{
_logger.Error(text);
error("An error has occurred in accepting.", null);
}
else if (accept())
{
open();
}
}
public void AcceptAsync()
{
if (!checkIfAvailable(client: false, server: true, connecting: true, open: false, closing: false, closed: false, out var text))
{
_logger.Error(text);
error("An error has occurred in accepting.", null);
return;
}
Func<bool> acceptor = accept;
acceptor.BeginInvoke(delegate(IAsyncResult ar)
{
if (acceptor.EndInvoke(ar))
{
open();
}
}, null);
}
public void Close()
{
if (!checkIfAvailable(connecting: true, open: true, closing: false, closed: false, out var text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else
{
close(new CloseEventArgs(), send: true, receive: true, received: false);
}
}
public void Close(ushort code)
{
if (!checkIfAvailable(connecting: true, open: true, closing: false, closed: false, out var text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else if (!CheckParametersForClose(code, null, _client, out text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else
{
close(code, null);
}
}
public void Close(CloseStatusCode code)
{
if (!checkIfAvailable(connecting: true, open: true, closing: false, closed: false, out var text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else if (!CheckParametersForClose(code, null, _client, out text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else
{
close((ushort)code, null);
}
}
public void Close(ushort code, string reason)
{
if (!checkIfAvailable(connecting: true, open: true, closing: false, closed: false, out var text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else if (!CheckParametersForClose(code, reason, _client, out text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else
{
close(code, reason);
}
}
public void Close(CloseStatusCode code, string reason)
{
if (!checkIfAvailable(connecting: true, open: true, closing: false, closed: false, out var text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else if (!CheckParametersForClose(code, reason, _client, out text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else
{
close((ushort)code, reason);
}
}
public void CloseAsync()
{
if (!checkIfAvailable(connecting: true, open: true, closing: false, closed: false, out var text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else
{
closeAsync(new CloseEventArgs(), send: true, receive: true, received: false);
}
}
public void CloseAsync(ushort code)
{
if (!checkIfAvailable(connecting: true, open: true, closing: false, closed: false, out var text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else if (!CheckParametersForClose(code, null, _client, out text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else
{
closeAsync(code, null);
}
}
public void CloseAsync(CloseStatusCode code)
{
if (!checkIfAvailable(connecting: true, open: true, closing: false, closed: false, out var text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else if (!CheckParametersForClose(code, null, _client, out text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else
{
closeAsync((ushort)code, null);
}
}
public void CloseAsync(ushort code, string reason)
{
if (!checkIfAvailable(connecting: true, open: true, closing: false, closed: false, out var text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else if (!CheckParametersForClose(code, reason, _client, out text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else
{
closeAsync(code, reason);
}
}
public void CloseAsync(CloseStatusCode code, string reason)
{
if (!checkIfAvailable(connecting: true, open: true, closing: false, closed: false, out var text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else if (!CheckParametersForClose(code, reason, _client, out text))
{
_logger.Error(text);
error("An error has occurred in closing the connection.", null);
}
else
{
closeAsync((ushort)code, reason);
}
}
public void Connect()
{
if (!checkIfAvailable(client: true, server: false, connecting: true, open: false, closing: false, closed: true, out var text))
{
_logger.Error(text);
error("An error has occurred in connecting.", null);
}
else if (connect())
{
open();
}
}
public void ConnectAsync()
{
if (!checkIfAvailable(client: true, server: false, connecting: true, open: false, closing: false, closed: true, out var text))
{
_logger.Error(text);
error("An error has occurred in connecting.", null);
return;
}
Func<bool> connector = connect;
connector.BeginInvoke(delegate(IAsyncResult ar)
{
if (connector.EndInvoke(ar))
{
open();
}
}, null);
}
public bool Ping()
{
byte[] frameAsBytes = (_client ? WebSocketFrame.CreatePingFrame(mask: true).ToArray() : WebSocketFrame.EmptyPingBytes);
return Ping(frameAsBytes, _waitTime);
}
public bool Ping(string message)
{
if (message == null || message.Length == 0)
{
return Ping();
}
byte[] bytes;
string text = CheckPingParameter(message, out bytes);
if (text != null)
{
_logger.Error(text);
error("An error has occurred in sending a ping.", null);
return false;
}
return Ping(WebSocketFrame.CreatePingFrame(bytes, _client).ToArray(), _waitTime);
}
public void Send(byte[] data)
{
string text = _readyState.CheckIfAvailable(connecting: false, open: true, closing: false, closed: false) ?? CheckSendParameter(data);
if (text != null)
{
_logger.Error(text);
error("An error has occurred in sending data.", null);
}
else
{
send(Opcode.Binary, new MemoryStream(data));
}
}
public void Send(FileInfo file)
{
string text = _readyState.CheckIfAvailable(connecting: false, open: true, closing: false, closed: false) ?? CheckSendParameter(file);
if (text != null)
{
_logger.Error(text);
error("An error has occurred in sending data.", null);
}
else
{
send(Opcode.Binary, file.OpenRead());
}
}
public void Send(string data)
{
string text = _readyState.CheckIfAvailable(connecting: false, open: true, closing: false, closed: false) ?? CheckSendParameter(data);
if (text != null)
{
_logger.Error(text);
error("An error has occurred in sending data.", null);
}
else
{
send(Opcode.Text, new MemoryStream(data.UTF8Encode()));
}
}
public void SendAsync(byte[] data, Action<bool> completed)
{
string text = _readyState.CheckIfAvailable(connecting: false, open: true, closing: false, closed: false) ?? CheckSendParameter(data);
if (text != null)
{
_logger.Error(text);
error("An error has occurred in sending data.", null);
}
else
{
sendAsync(Opcode.Binary, new MemoryStream(data), completed);
}
}
public void SendAsync(FileInfo file, Action<bool> completed)
{
string text = _readyState.CheckIfAvailable(connecting: false, open: true, closing: false, closed: false) ?? CheckSendParameter(file);
if (text != null)
{
_logger.Error(text);
error("An error has occurred in sending data.", null);
}
else
{
sendAsync(Opcode.Binary, file.OpenRead(), completed);
}
}
public void SendAsync(string data, Action<bool> completed)
{
string text = _readyState.CheckIfAvailable(connecting: false, open: true, closing: false, closed: false) ?? CheckSendParameter(data);
if (text != null)
{
_logger.Error(text);
error("An error has occurred in sending data.", null);
}
else
{
sendAsync(Opcode.Text, new MemoryStream(data.UTF8Encode()), completed);
}
}
public void SendAsync(Stream stream, int length, Action<bool> completed)
{
string text = _readyState.CheckIfAvailable(connecting: false, open: true, closing: false, closed: false) ?? CheckSendParameters(stream, length);
if (text != null)
{
_logger.Error(text);
error("An error has occurred in sending data.", null);
return;
}
stream.ReadBytesAsync(length, delegate(byte[] data)
{
int num = data.Length;
if (num == 0)
{
_logger.Error("The data cannot be read from 'stream'.");
error("An error has occurred in sending data.", null);
}
else
{
if (num < length)
{
_logger.Warn($"The length of the data is less than 'length':\n expected: {length}\n actual: {num}");
}
bool obj = send(Opcode.Binary, new MemoryStream(data));
if (completed != null)
{
completed(obj);
}
}
}, delegate(Exception ex)
{
_logger.Error(ex.ToString());
error("An exception has occurred while sending data.", ex);
});
}
public void SetCookie(WebSocketSharp.Net.Cookie cookie)
{
if (!checkIfAvailable(client: true, server: false, connecting: true, open: false, closing: false, closed: true, out var text))
{
_logger.Error(text);
error("An error has occurred in setting a cookie.", null);
return;
}
if (cookie == null)
{
_logger.Error("'cookie' is null.");
error("An error has occurred in setting a cookie.", null);
return;
}
lock (_forState)
{
if (!checkIfAvailable(connecting: true, open: false, closing: false, closed: true, out text))
{
_logger.Error(text);
error("An error has occurred in setting a cookie.", null);
return;
}
lock (_cookies.SyncRoot)
{
_cookies.SetOrRemove(cookie);
}
}
}
public void SetCredentials(string username, string password, bool preAuth)
{
if (!checkIfAvailable(client: true, server: false, connecting: true, open: false, closing: false, closed: true, out var text))
{
_logger.Error(text);
error("An error has occurred in setting the credentials.", null);
return;
}
if (!checkParametersForSetCredentials(username, password, out text))
{
_logger.Error(text);
error("An error has occurred in setting the credentials.", null);
return;
}
lock (_forState)
{
if (!checkIfAvailable(connecting: true, open: false, closing: false, closed: true, out text))
{
_logger.Error(text);
error("An error has occurred in setting the credentials.", null);
}
else if (username.IsNullOrEmpty())
{
_logger.Warn("The credentials are initialized.");
_credentials = null;
_preAuth = false;
}
else
{
_credentials = new WebSocketSharp.Net.NetworkCredential(username, password, _uri.PathAndQuery);
_preAuth = preAuth;
}
}
}
public void SetProxy(string url, string username, string password)
{
if (!checkIfAvailable(client: true, server: false, connecting: true, open: false, closing: false, closed: true, out var text))
{
_logger.Error(text);
error("An error has occurred in setting the proxy.", null);
return;
}
if (!checkParametersForSetProxy(url, username, password, out text))
{
_logger.Error(text);
error("An error has occurred in setting the proxy.", null);
return;
}
lock (_forState)
{
if (!checkIfAvailable(connecting: true, open: false, closing: false, closed: true, out text))
{
_logger.Error(text);
error("An error has occurred in setting the proxy.", null);
return;
}
if (url.IsNullOrEmpty())
{
_logger.Warn("The url and credentials for the proxy are initialized.");
_proxyUri = null;
_proxyCredentials = null;
return;
}
_proxyUri = new Uri(url);
if (username.IsNullOrEmpty())
{
_logger.Warn("The credentials for the proxy are initialized.");
_proxyCredentials = null;
}
else
{
_proxyCredentials = new WebSocketSharp.Net.NetworkCredential(username, password, $"{_uri.DnsSafeHost}:{_uri.Port}");
}
}
}
void IDisposable.Dispose()
{
close(new CloseEventArgs(1001), send: true, receive: true, received: false);
}
}
public enum CloseStatusCode : ushort
{
Normal = 1000,
Away = 1001,
ProtocolError = 1002,
UnsupportedData = 1003,
Undefined = 1004,
NoStatus = 1005,
Abnormal = 1006,
InvalidData = 1007,
PolicyViolation = 1008,
TooBig = 1009,
MandatoryExtension = 1010,
ServerError = 1011,
TlsHandshakeFailure = 1015
}
internal enum Fin : byte
{
More,
Final
}
internal enum Mask : byte
{
Off,
On
}
public enum Opcode : byte
{
Cont = 0,
Text = 1,
Binary = 2,
Close = 8,
Ping = 9,
Pong = 10
}
internal class PayloadData : IEnumerable<byte>, IEnumerable
{
private ushort _code;
private bool _codeSet;
private byte[] _data;
private long _extDataLength;
private long _length;
private string _reason;
private bool _reasonSet;
public static readonly PayloadData Empty;
public static readonly ulong MaxLength;
internal ushort Code
{
get
{
if (!_codeSet)
{
_code = (ushort)((_length > 1) ? _data.SubArray(0, 2).ToUInt16(ByteOrder.Big) : 1005);
_codeSet = true;
}
return _code;
}
}
internal long ExtensionDataLength
{
get
{
return _extDataLength;
}
set
{
_extDataLength = value;
}
}
internal bool HasReservedCode => _length > 1 && Code.IsReserved();
internal string Reason
{
get
{
if (!_reasonSet)
{
_reason = ((_length > 2) ? _data.SubArray(2L, _length - 2).UTF8Decode() : string.Empty);
_reasonSet = true;
}
return _reason;
}
}
public byte[] ApplicationData => (_extDataLength > 0) ? _data.SubArray(_extDataLength, _length - _extDataLength) : _data;
public byte[] ExtensionData => (_extDataLength > 0) ? _data.SubArray(0L, _extDataLength) : WebSocket.EmptyBytes;
public ulong Length => (ulong)_length;
static PayloadData()
{
Empty = new PayloadData();
MaxLength = 9223372036854775807uL;
}
internal PayloadData()
{
_code = 1005;
_reason = string.Empty;
_data = WebSocket.EmptyBytes;
_codeSet = true;
_reasonSet = true;
}
internal PayloadData(byte[] data)
: this(data, data.LongLength)
{
}
internal PayloadData(byte[] data, long length)
{
_data = data;
_length = length;
}
internal PayloadData(ushort code, string reason)
{
_code = code;
_reason = reason ?? string.Empty;
_data = code.Append(reason);
_length = _data.LongLength;
_codeSet = true;
_reasonSet = true;
}
internal void Mask(byte[] key)
{
for (long num = 0L; num < _length; num++)
{
_data[num] ^= key[num % 4];
}
}
public IEnumerator<byte> GetEnumerator()
{
byte[] data = _data;
for (int i = 0; i < data.Length; i++)
{
yield return data[i];
}
}
public byte[] ToArray()
{
return _data;
}
public override string ToString()
{
return BitConverter.ToString(_data);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
internal enum Rsv : byte
{
Off,
On
}
public enum CompressionMethod : byte
{
None,
Deflate
}
public class WebSocketException : Exception
{
private CloseStatusCode _code;
public CloseStatusCode Code => _code;
internal WebSocketException()
: this(CloseStatusCode.Abnormal, null, null)
{
}
internal WebSocketException(Exception innerException)
: this(CloseStatusCode.Abnormal, null, innerException)
{
}
internal WebSocketException(string message)
: this(CloseStatusCode.Abnormal, message, null)
{
}
internal WebSocketException(CloseStatusCode code)
: this(code, null, null)
{
}
internal WebSocketException(string message, Exception innerException)
: this(CloseStatusCode.Abnormal, message, innerException)
{
}
internal WebSocketException(CloseStatusCode code, Exception innerException)
: this(code, null, innerException)
{
}
internal WebSocketException(CloseStatusCode code, string message)
: this(code, message, null)
{
}
internal WebSocketException(CloseStatusCode code, string message, Exception innerException)
: base(message ?? code.GetMessage(), innerException)
{
_code = code;
}
}
public class LogData
{
private StackFrame _caller;
private DateTime _date;
private LogLevel _level;
private string _message;
public StackFrame Caller => _caller;
public DateTime Date => _date;
public LogLevel Level => _level;
public string Message => _message;
internal LogData(LogLevel level, StackFrame caller, string message)
{
_level = level;
_caller = caller;
_message = message ?? string.Empty;
_date = DateTime.Now;
}
public override string ToString()
{
string text = $"{_date}|{_level,-5}|";
MethodBase method = _caller.GetMethod();
Type declaringType = method.DeclaringType;
string arg = $"{text}{declaringType.Name}.{method.Name}|";
string[] array = _message.Replace("\r\n", "\n").TrimEnd(new char[1] { '\n' }).Split(new char[1] { '\n' });
if (array.Length <= 1)
{
return $"{arg}{_message}";
}
StringBuilder stringBuilder = new StringBuilder($"{arg}{array[0]}\n", 64);
string format = $"{{0,{text.Length}}}{{1}}\n";
for (int i = 1; i < array.Length; i++)
{
stringBuilder.AppendFormat(format, "", array[i]);
}
stringBuilder.Length--;
return stringBuilder.ToString();
}
}
public enum LogLevel
{
Trace,
Debug,
Info,
Warn,
Error,