Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of RoR2ItemSync v2.0.0
plugins/RoR2ItemSync.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.IO; using System.Linq; 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.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HG; using MonoMod.RuntimeDetour; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using On.RoR2; using RoR2; using RoR2.ContentManagement; using RoR2.Skills; using RoR2.Stats; using RoR2ItemSync.Dump; using UnityEngine; using UnityEngine.Networking; using WebSocketSharp; using WebSocketSharp.Net.WebSockets; 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("2.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("2.0.0.0")] namespace RoR2ItemSync { [BepInPlugin("com.turne.ror2itemsync", "RoR2ItemSync", "2.0.0")] public class Plugin : BaseUnityPlugin { private sealed class PayloadBatch { public readonly List<object> Messages; public PayloadBatch(List<object> messages) { Messages = messages; } } private sealed class PickupAttempt { public CharacterMaster Master; public PickupIndex Pickup; public bool Notified; } private delegate void PickupNotificationOrig(CharacterMaster master, UniquePickup pickup); private delegate void PickupNotificationDetour(PickupNotificationOrig orig, CharacterMaster master, UniquePickup pickup); private sealed class PendingChestOpen { public Dictionary<string, object> Player; public string SourceId; public string Kind; public string Tier; public int Cost; public float OpenedAtRealtime; public object BalancesAfter; public PickupIndex RolledPickup; } private struct RecentChestDrop { public string SourceId; public int PickupValue; public float DropAtRealtime; } internal class RunJournalRequest { public string RequestId; public long? SinceSequence; public int? Limit; public string[] Severities; public string[] EventTypes; public int? StageNumber; public bool? IncludeSnapshots; } private static class EnumName<T> where T : struct { private static readonly Dictionary<T, string> _names = new Dictionary<T, string>(); public static string Of(T value) { if (!_names.TryGetValue(value, out var value2)) { value2 = value.ToString(); _names[value] = value2; } return value2; } } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static hook_AttemptGrant <>9__108_1; public static hook_GiveItem_ItemIndex_int <>9__108_2; public static Action<TryTransformResult> <>9__108_4; public static Action<CharacterBody> <>9__108_5; public static Action<Dictionary<string, object>> <>9__108_40; public static Action<Dictionary<string, object>> <>9__108_42; public static Action <>9__108_41; public static Action<TeleporterInteraction> <>9__108_7; public static Action<Dictionary<string, object>> <>9__108_44; public static Action <>9__108_43; public static Action<TeleporterInteraction> <>9__108_8; public static hook_AddShrineStack <>9__108_9; public static hook_ItemDrop <>9__108_11; public static hook_CreatePickupDroplet <>9__108_12; public static hook_AddShrineStack <>9__108_13; public static hook_AddShrineStack <>9__108_14; public static hook_AddShrineStack <>9__108_15; public static hook_AddShrineStack <>9__108_16; public static hook_AddShrineStack <>9__108_17; public static hook_OnDefeatedServer <>9__108_18; public static hook_Awake <>9__108_19; public static hook_Start <>9__108_20; public static hook_Start <>9__108_21; public static hook_Start <>9__108_22; public static hook_Awake <>9__108_23; public static Comparison<string> <>9__169_0; public static Predicate<GenericPickupController> <>9__185_0; public static Predicate<PickupPickerController> <>9__185_1; public static Func<KeyValuePair<string, (string name, int count)>, string> <>9__210_0; public static Action<string> <>9__230_1; internal void <Awake>b__108_1(orig_AttemptGrant orig, GenericPickupController self, CharacterBody recipientBody) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Invalid comparison between Unknown and I4 //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) <>c__DisplayClass108_1 CS$<>8__locals67 = new <>c__DisplayClass108_1 { recipientBody = recipientBody, self = self }; if (!_pluginAlive) { orig.Invoke(CS$<>8__locals67.self, CS$<>8__locals67.recipientBody); return; } CS$<>8__locals67.grantedIndex = PickupIndex.none; try { CS$<>8__locals67.grantedIndex = CS$<>8__locals67.self.pickupIndex; } catch { } CS$<>8__locals67.grantInv = null; CS$<>8__locals67.grantItemIndex = (ItemIndex)(-1); CS$<>8__locals67.gPermBefore = 0; CS$<>8__locals67.gTempBefore = 0; CS$<>8__locals67.gChanBefore = 0; CS$<>8__locals67.equipmentBefore = EquipmentState.empty; CS$<>8__locals67.consumedBefore = ReadBoolField(_pickupConsumedField, CS$<>8__locals67.self); try { PickupDef val = (((PickupIndex)(ref CS$<>8__locals67.grantedIndex)).isValid ? PickupCatalog.GetPickupDef(CS$<>8__locals67.grantedIndex) : null); if (val != null && (Object)(object)CS$<>8__locals67.recipientBody != (Object)null) { CS$<>8__locals67.grantInv = CS$<>8__locals67.recipientBody.inventory; if ((Object)(object)CS$<>8__locals67.grantInv != (Object)null) { CS$<>8__locals67.equipmentBefore = CS$<>8__locals67.grantInv.currentEquipmentState; CS$<>8__locals67.grantItemIndex = val.itemIndex; if ((int)CS$<>8__locals67.grantItemIndex != -1) { CS$<>8__locals67.gPermBefore = CS$<>8__locals67.grantInv.GetItemCountPermanent(CS$<>8__locals67.grantItemIndex); CS$<>8__locals67.gTempBefore = CS$<>8__locals67.grantInv.GetItemCountTemp(CS$<>8__locals67.grantItemIndex); CS$<>8__locals67.gChanBefore = CS$<>8__locals67.grantInv.GetItemCountChanneled(CS$<>8__locals67.grantItemIndex); } } } } catch { CS$<>8__locals67.grantInv = null; } bool inAttemptGrant = _inAttemptGrant; PickupAttempt activePickupAttempt = _activePickupAttempt; CS$<>8__locals67.attempt = new PickupAttempt { Master = (((Object)(object)CS$<>8__locals67.recipientBody != (Object)null) ? CS$<>8__locals67.recipientBody.master : null), Pickup = CS$<>8__locals67.grantedIndex }; _activePickupAttempt = CS$<>8__locals67.attempt; _inAttemptGrant = true; try { orig.Invoke(CS$<>8__locals67.self, CS$<>8__locals67.recipientBody); } finally { _inAttemptGrant = inAttemptGrant; _activePickupAttempt = activePickupAttempt; } WrapHook("pickup_granted", delegate { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Invalid comparison between Unknown and I4 //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Invalid comparison between Unknown and I4 //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Invalid comparison between Unknown and I4 //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Invalid comparison between Unknown and I4 <>c__DisplayClass108_2 CS$<>8__locals86 = new <>c__DisplayClass108_2 { CS$<>8__locals1 = CS$<>8__locals67 }; Interlocked.Increment(ref _diagPickupGrantedCount); if (((PickupIndex)(ref CS$<>8__locals67.grantedIndex)).isValid && !((Object)(object)CS$<>8__locals67.recipientBody == (Object)null)) { CS$<>8__locals86.pickupDef = PickupCatalog.GetPickupDef(CS$<>8__locals67.grantedIndex); if (CS$<>8__locals86.pickupDef != null) { bool flag = CS$<>8__locals67.attempt.Notified || (!CS$<>8__locals67.consumedBefore && ReadBoolField(_pickupConsumedField, CS$<>8__locals67.self)); if (!flag && (Object)(object)CS$<>8__locals67.grantInv != (Object)null) { if ((int)CS$<>8__locals67.grantItemIndex != -1) { flag = CS$<>8__locals67.grantInv.GetItemCountPermanent(CS$<>8__locals67.grantItemIndex) > CS$<>8__locals67.gPermBefore || CS$<>8__locals67.grantInv.GetItemCountTemp(CS$<>8__locals67.grantItemIndex) > CS$<>8__locals67.gTempBefore || CS$<>8__locals67.grantInv.GetItemCountChanneled(CS$<>8__locals67.grantItemIndex) > CS$<>8__locals67.gChanBefore; } else if ((int)CS$<>8__locals86.pickupDef.equipmentIndex != -1) { EquipmentState currentEquipmentState = CS$<>8__locals67.grantInv.currentEquipmentState; flag = !((EquipmentState)(ref currentEquipmentState)).Equals(CS$<>8__locals67.equipmentBefore) && CS$<>8__locals67.grantInv.currentEquipmentIndex == CS$<>8__locals86.pickupDef.equipmentIndex; } } if (flag) { CharacterBody obj3 = CS$<>8__locals67.recipientBody; CS$<>8__locals86.master = ((obj3 != null) ? obj3.master : null); CharacterMaster obj4 = CS$<>8__locals86.master; PlayerCharacterMasterController val2 = ((obj4 != null) ? obj4.playerCharacterMasterController : null); CS$<>8__locals86.netUser = ((val2 != null) ? val2.networkUser : null); bool flag2 = false; CS$<>8__locals86.highlightReason = null; try { if ((int)CS$<>8__locals86.pickupDef.itemIndex != -1) { ItemDef itemDef = ItemCatalog.GetItemDef(CS$<>8__locals86.pickupDef.itemIndex); if ((Object)(object)itemDef != (Object)null && (int)itemDef.tier == 2) { flag2 = true; CS$<>8__locals86.highlightReason = "legendary_pickup"; } } } catch { } EmitRunEvent("pickup_granted", flag2 ? "major" : "minor", delegate(Dictionary<string, object> payload) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) payload["source"] = "pickup"; payload["player"] = BuildPlayerBlock(CS$<>8__locals86.CS$<>8__locals1.recipientBody, CS$<>8__locals86.master, CS$<>8__locals86.netUser); payload["item"] = BuildGrantItemRef(CS$<>8__locals86.pickupDef, 1, CS$<>8__locals86.CS$<>8__locals1.grantInv, CS$<>8__locals86.CS$<>8__locals1.grantItemIndex, CS$<>8__locals86.CS$<>8__locals1.gPermBefore, CS$<>8__locals86.CS$<>8__locals1.gTempBefore, CS$<>8__locals86.CS$<>8__locals1.gChanBefore); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); if (CS$<>8__locals86.highlightReason != null) { payload["highlight_reason"] = CS$<>8__locals86.highlightReason; } string text = TryConsumeChestSourceId(CS$<>8__locals86.CS$<>8__locals1.grantedIndex); if (text != null) { payload["source_id"] = text; } }); } } } }); } internal void <Awake>b__108_2(orig_GiveItem_ItemIndex_int orig, Inventory self, ItemIndex itemIndex, int count) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 <>c__DisplayClass108_3 CS$<>8__locals47 = new <>c__DisplayClass108_3 { self = self, itemIndex = itemIndex, count = count, giveMaster = null, givePcmc = null }; if (_pluginAlive && !_inAttemptGrant && CS$<>8__locals47.count > 0 && (int)CS$<>8__locals47.itemIndex != -1 && (Object)(object)CS$<>8__locals47.self != (Object)null) { try { CS$<>8__locals47.giveMaster = ((Component)CS$<>8__locals47.self).GetComponent<CharacterMaster>(); CharacterMaster obj = CS$<>8__locals47.giveMaster; CS$<>8__locals47.givePcmc = ((obj != null) ? obj.playerCharacterMasterController : null); } catch { CS$<>8__locals47.givePcmc = null; } } if ((Object)(object)CS$<>8__locals47.givePcmc == (Object)null) { orig.Invoke(CS$<>8__locals47.self, CS$<>8__locals47.itemIndex, CS$<>8__locals47.count); return; } CS$<>8__locals47.gPermBefore = 0; CS$<>8__locals47.gTempBefore = 0; CS$<>8__locals47.gChanBefore = 0; CS$<>8__locals47.haveBefore = false; try { CS$<>8__locals47.gPermBefore = CS$<>8__locals47.self.GetItemCountPermanent(CS$<>8__locals47.itemIndex); CS$<>8__locals47.gTempBefore = CS$<>8__locals47.self.GetItemCountTemp(CS$<>8__locals47.itemIndex); CS$<>8__locals47.gChanBefore = CS$<>8__locals47.self.GetItemCountChanneled(CS$<>8__locals47.itemIndex); CS$<>8__locals47.haveBefore = true; } catch { CS$<>8__locals47.haveBefore = false; } orig.Invoke(CS$<>8__locals47.self, CS$<>8__locals47.itemIndex, CS$<>8__locals47.count); WrapHook("pickup_granted:give_item", delegate { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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: Invalid comparison between Unknown and I4 //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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: Invalid comparison between Unknown and I4 <>c__DisplayClass108_4 CS$<>8__locals68 = new <>c__DisplayClass108_4 { CS$<>8__locals2 = CS$<>8__locals47 }; Interlocked.Increment(ref _diagPickupGrantedCount); if (CS$<>8__locals47.haveBefore && (CS$<>8__locals47.self.GetItemCountPermanent(CS$<>8__locals47.itemIndex) > CS$<>8__locals47.gPermBefore || CS$<>8__locals47.self.GetItemCountTemp(CS$<>8__locals47.itemIndex) > CS$<>8__locals47.gTempBefore || CS$<>8__locals47.self.GetItemCountChanneled(CS$<>8__locals47.itemIndex) > CS$<>8__locals47.gChanBefore)) { CS$<>8__locals68.master = CS$<>8__locals47.giveMaster; PlayerCharacterMasterController val = CS$<>8__locals47.givePcmc; ItemDef itemDef = ItemCatalog.GetItemDef(CS$<>8__locals47.itemIndex); if (!((Object)(object)itemDef == (Object)null) && (int)itemDef.tier != 5) { PickupIndex val2 = PickupCatalog.FindPickupIndex(CS$<>8__locals47.itemIndex); CS$<>8__locals68.pickupDef = PickupCatalog.GetPickupDef(val2); if (CS$<>8__locals68.pickupDef != null) { CS$<>8__locals68.body = CS$<>8__locals68.master.GetBody(); CS$<>8__locals68.netUser = val.networkUser; bool flag = (int)itemDef.tier == 2; CS$<>8__locals68.highlightReason = (flag ? "legendary_pickup" : null); EmitRunEvent("pickup_granted", flag ? "major" : "minor", delegate(Dictionary<string, object> payload) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) payload["source"] = "give_item"; payload["player"] = BuildPlayerBlock(CS$<>8__locals68.body, CS$<>8__locals68.master, CS$<>8__locals68.netUser); payload["item"] = (CS$<>8__locals68.CS$<>8__locals2.haveBefore ? BuildGrantItemRef(CS$<>8__locals68.pickupDef, CS$<>8__locals68.CS$<>8__locals2.count, CS$<>8__locals68.CS$<>8__locals2.self, CS$<>8__locals68.CS$<>8__locals2.itemIndex, CS$<>8__locals68.CS$<>8__locals2.gPermBefore, CS$<>8__locals68.CS$<>8__locals2.gTempBefore, CS$<>8__locals68.CS$<>8__locals2.gChanBefore) : BuildPickupRef(CS$<>8__locals68.pickupDef, CS$<>8__locals68.CS$<>8__locals2.count, hidden: false)); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); if (CS$<>8__locals68.highlightReason != null) { payload["highlight_reason"] = CS$<>8__locals68.highlightReason; } }); } } } }); } internal void <Awake>b__108_4(TryTransformResult result) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) WrapHook("item_transformed", new <>c__DisplayClass108_7 { result = result }.<Awake>b__34); } internal void <Awake>b__108_5(CharacterBody newBody) { <>c__DisplayClass108_10 CS$<>8__locals5 = new <>c__DisplayClass108_10 { newBody = newBody }; if (_deadPlayerMasters.Count == 0) { return; } WrapHook("player_respawned", delegate { <>c__DisplayClass108_11 CS$<>8__locals12 = new <>c__DisplayClass108_11 { CS$<>8__locals4 = CS$<>8__locals5 }; if (!((Object)(object)Run.instance == (Object)null) && !((Object)(object)CS$<>8__locals5.newBody == (Object)null)) { CS$<>8__locals12.master = CS$<>8__locals5.newBody.master; if (!((Object)(object)CS$<>8__locals12.master == (Object)null) && _deadPlayerMasters.Remove(CS$<>8__locals12.master)) { PlayerCharacterMasterController playerCharacterMasterController = CS$<>8__locals12.master.playerCharacterMasterController; CS$<>8__locals12.netUser = (((Object)(object)playerCharacterMasterController != (Object)null) ? playerCharacterMasterController.networkUser : null); EmitRunEvent("player_respawned", "major", delegate(Dictionary<string, object> payload) { payload["player"] = BuildPlayerBlock(CS$<>8__locals12.CS$<>8__locals4.newBody, CS$<>8__locals12.master, CS$<>8__locals12.netUser); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); }); } } }); } internal void <Awake>b__108_40(Dictionary<string, object> payload) { payload["stage"] = BuildStageBlock(); payload["timer"] = BuildTimerBlock(); } internal void <Awake>b__108_7(TeleporterInteraction _) { WrapHook("teleporter_activated", delegate { EmitRunEvent("teleporter_activated", "major", delegate(Dictionary<string, object> payload) { payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); }); }); } internal void <Awake>b__108_41() { EmitRunEvent("teleporter_activated", "major", delegate(Dictionary<string, object> payload) { payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); }); } internal void <Awake>b__108_42(Dictionary<string, object> payload) { payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); } internal void <Awake>b__108_8(TeleporterInteraction _) { WrapHook("teleporter_charged", delegate { EmitRunEvent("teleporter_charged", "major", delegate(Dictionary<string, object> payload) { payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); }); }); } internal void <Awake>b__108_43() { EmitRunEvent("teleporter_charged", "major", delegate(Dictionary<string, object> payload) { payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); }); } internal void <Awake>b__108_44(Dictionary<string, object> payload) { payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); } internal void <Awake>b__108_9(orig_AddShrineStack orig, ShrineBossBehavior self, Interactor interactor) { <>c__DisplayClass108_12 CS$<>8__locals13 = new <>c__DisplayClass108_12(); CS$<>8__locals13.self = self; CS$<>8__locals13.interactor = interactor; CS$<>8__locals13.prevCount = ReadShrineBossPurchaseCount(CS$<>8__locals13.self); orig.Invoke(CS$<>8__locals13.self, CS$<>8__locals13.interactor); WrapHook("shrine_mountain_activated", delegate { <>c__DisplayClass108_13 CS$<>8__locals21 = new <>c__DisplayClass108_13 { stackCount = ReadShrineBossPurchaseCount(CS$<>8__locals13.self) }; if (CS$<>8__locals21.stackCount != CS$<>8__locals13.prevCount) { CS$<>8__locals21.body = (((Object)(object)CS$<>8__locals13.interactor != (Object)null) ? ((Component)CS$<>8__locals13.interactor).GetComponent<CharacterBody>() : null); CharacterBody obj = CS$<>8__locals21.body; CS$<>8__locals21.master = ((obj != null) ? obj.master : null); CharacterMaster obj2 = CS$<>8__locals21.master; object netUser; if (obj2 == null) { netUser = null; } else { PlayerCharacterMasterController playerCharacterMasterController = obj2.playerCharacterMasterController; netUser = ((playerCharacterMasterController != null) ? playerCharacterMasterController.networkUser : null); } CS$<>8__locals21.netUser = (NetworkUser)netUser; EmitRunEvent("shrine_mountain_activated", "major", delegate(Dictionary<string, object> payload) { payload["player"] = BuildPlayerBlock(CS$<>8__locals21.body, CS$<>8__locals21.master, CS$<>8__locals21.netUser); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); payload["stack_count"] = CS$<>8__locals21.stackCount; }); } }); } internal void <Awake>b__108_11(orig_ItemDrop orig, ChestBehavior self) { <>c__DisplayClass108_16 CS$<>8__locals16 = new <>c__DisplayClass108_16 { self = self }; orig.Invoke(CS$<>8__locals16.self); WrapHook("chest_opened", delegate { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_011a: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) <>c__DisplayClass108_17 CS$<>8__locals32 = new <>c__DisplayClass108_17(); if (!((Object)(object)CS$<>8__locals16.self == (Object)null)) { CS$<>8__locals32.ctx = null; lock (_chestLock) { if (_pendingChests.TryGetValue(CS$<>8__locals16.self, out CS$<>8__locals32.ctx)) { _pendingChests.Remove(CS$<>8__locals16.self); } } CS$<>8__locals32.dropPickup = ((CS$<>8__locals32.ctx != null) ? CS$<>8__locals32.ctx.RolledPickup : PickupIndex.none); if (!((PickupIndex)(ref CS$<>8__locals32.dropPickup)).isValid) { try { CS$<>8__locals32.dropPickup = CS$<>8__locals16.self.currentPickup.pickupIndex; } catch { } } CS$<>8__locals32.sourceId = CS$<>8__locals32.ctx?.SourceId ?? ("chest:" + ((Object)((Component)CS$<>8__locals16.self).gameObject).GetInstanceID()); if (((PickupIndex)(ref CS$<>8__locals32.dropPickup)).isValid) { RecordChestDrop(CS$<>8__locals32.sourceId, CS$<>8__locals32.dropPickup); } CS$<>8__locals32.pickup = null; if (((PickupIndex)(ref CS$<>8__locals32.dropPickup)).isValid) { try { PickupDef pickupDef = PickupCatalog.GetPickupDef(CS$<>8__locals32.dropPickup); if (pickupDef != null) { CS$<>8__locals32.pickup = BuildPickupRef(pickupDef, 1, hidden: false); } } catch { } } EmitRunEvent("chest_opened", "minor", delegate(Dictionary<string, object> payload) { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) payload["player"] = CS$<>8__locals32.ctx?.Player; payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); payload["source_id"] = CS$<>8__locals32.sourceId; payload["chest"] = new Dictionary<string, object>(StringComparer.Ordinal) { ["kind"] = CS$<>8__locals32.ctx?.Kind ?? "unknown", ["cost"] = CS$<>8__locals32.ctx?.Cost ?? 0, ["tier"] = CS$<>8__locals32.ctx?.Tier ?? (((PickupIndex)(ref CS$<>8__locals32.dropPickup)).isValid ? SafePickupTier(CS$<>8__locals32.dropPickup) : "Tier1") }; payload["balances_after"] = CS$<>8__locals32.ctx?.BalancesAfter; payload["pickup"] = CS$<>8__locals32.pickup; }); } }); } internal void <Awake>b__108_12(orig_CreatePickupDroplet orig, PickupIndex pickupIndex, Vector3 position, Vector3 velocity) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) orig.Invoke(pickupIndex, position, velocity); if (!_inShrineChanceDrop) { return; } try { if (((PickupIndex)(ref pickupIndex)).isValid) { if (!((PickupIndex)(ref _shrineChanceRolledPickup)).isValid) { _shrineChanceRolledPickup = pickupIndex; } if (_shrineChanceSourceId != null) { RecordChestDrop(_shrineChanceSourceId, pickupIndex); } } } catch { } } internal void <Awake>b__108_13(orig_AddShrineStack orig, ShrineChanceBehavior self, Interactor interactor) { //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: 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) <>c__DisplayClass108_18 CS$<>8__locals19 = new <>c__DisplayClass108_18(); CS$<>8__locals19.self = self; CS$<>8__locals19.interactor = interactor; CS$<>8__locals19.prevCount = ReadIntField(_shrineChanceSuccessCountField, CS$<>8__locals19.self); CS$<>8__locals19.shrineSourceId = null; try { if ((Object)(object)CS$<>8__locals19.self != (Object)null) { CS$<>8__locals19.shrineSourceId = "shrine:" + ((Object)((Component)CS$<>8__locals19.self).gameObject).GetInstanceID(); } } catch { } bool inShrineChanceDrop = _inShrineChanceDrop; string shrineChanceSourceId = _shrineChanceSourceId; _inShrineChanceDrop = true; _shrineChanceSourceId = CS$<>8__locals19.shrineSourceId; _shrineChanceRolledPickup = PickupIndex.none; try { orig.Invoke(CS$<>8__locals19.self, CS$<>8__locals19.interactor); } finally { _inShrineChanceDrop = inShrineChanceDrop; _shrineChanceSourceId = shrineChanceSourceId; } CS$<>8__locals19.rolled = _shrineChanceRolledPickup; WrapHook("shrine_used:chance", delegate { //IL_0060: Unknown result type (might be due to invalid IL or missing references) bool num = ReadIntField(_shrineChanceSuccessCountField, CS$<>8__locals19.self) > CS$<>8__locals19.prevCount; bool flag = ReadBoolField(_shrineChanceDollWinField, CS$<>8__locals19.self); string outcome = (num ? "success" : (flag ? "success" : "fail")); EmitShrineUsed(((Component)CS$<>8__locals19.self).GetComponent<PurchaseInteraction>(), CS$<>8__locals19.interactor, "chance", outcome, CS$<>8__locals19.shrineSourceId, CS$<>8__locals19.rolled); }); } internal void <Awake>b__108_14(orig_AddShrineStack orig, ShrineCombatBehavior self, Interactor interactor) { <>c__DisplayClass108_19 CS$<>8__locals10 = new <>c__DisplayClass108_19(); CS$<>8__locals10.self = self; CS$<>8__locals10.interactor = interactor; CS$<>8__locals10.prevCount = ReadIntField(_shrineCombatPurchaseCountField, CS$<>8__locals10.self); orig.Invoke(CS$<>8__locals10.self, CS$<>8__locals10.interactor); WrapHook("shrine_used:combat", delegate { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (ReadIntField(_shrineCombatPurchaseCountField, CS$<>8__locals10.self) != CS$<>8__locals10.prevCount) { EmitShrineUsed(((Component)CS$<>8__locals10.self).GetComponent<PurchaseInteraction>(), CS$<>8__locals10.interactor, "combat", "success"); } }); } internal void <Awake>b__108_15(orig_AddShrineStack orig, ShrineBloodBehavior self, Interactor interactor) { <>c__DisplayClass108_20 CS$<>8__locals10 = new <>c__DisplayClass108_20(); CS$<>8__locals10.self = self; CS$<>8__locals10.interactor = interactor; CS$<>8__locals10.prevCount = ReadIntField(_shrineBloodPurchaseCountField, CS$<>8__locals10.self); orig.Invoke(CS$<>8__locals10.self, CS$<>8__locals10.interactor); WrapHook("shrine_used:blood", delegate { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (ReadIntField(_shrineBloodPurchaseCountField, CS$<>8__locals10.self) != CS$<>8__locals10.prevCount) { EmitShrineUsed(((Component)CS$<>8__locals10.self).GetComponent<PurchaseInteraction>(), CS$<>8__locals10.interactor, "blood", "success"); } }); } internal void <Awake>b__108_16(orig_AddShrineStack orig, ShrineRestackBehavior self, Interactor interactor) { <>c__DisplayClass108_21 CS$<>8__locals10 = new <>c__DisplayClass108_21(); CS$<>8__locals10.self = self; CS$<>8__locals10.interactor = interactor; CS$<>8__locals10.prevCount = ReadIntField(_shrineRestackPurchaseCountField, CS$<>8__locals10.self); orig.Invoke(CS$<>8__locals10.self, CS$<>8__locals10.interactor); WrapHook("shrine_used:order", delegate { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (ReadIntField(_shrineRestackPurchaseCountField, CS$<>8__locals10.self) != CS$<>8__locals10.prevCount) { EmitShrineUsed(((Component)CS$<>8__locals10.self).GetComponent<PurchaseInteraction>(), CS$<>8__locals10.interactor, "order", "success"); } }); } internal void <Awake>b__108_17(orig_AddShrineStack orig, ShrineHealingBehavior self, Interactor interactor) { <>c__DisplayClass108_22 CS$<>8__locals10 = new <>c__DisplayClass108_22(); CS$<>8__locals10.self = self; CS$<>8__locals10.interactor = interactor; CS$<>8__locals10.prevCount = ReadIntField(_shrineHealingPurchaseCountField, CS$<>8__locals10.self); orig.Invoke(CS$<>8__locals10.self, CS$<>8__locals10.interactor); WrapHook("shrine_used:woods", delegate { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (ReadIntField(_shrineHealingPurchaseCountField, CS$<>8__locals10.self) != CS$<>8__locals10.prevCount) { EmitShrineUsed(((Component)CS$<>8__locals10.self).GetComponent<PurchaseInteraction>(), CS$<>8__locals10.interactor, "woods", "success"); } }); } internal void <Awake>b__108_18(orig_OnDefeatedServer orig, BossGroup self) { <>c__DisplayClass108_23 CS$<>8__locals2 = new <>c__DisplayClass108_23 { self = self }; orig.Invoke(CS$<>8__locals2.self); WrapHook("boss_defeated", delegate { EmitRunEvent("boss_defeated", "major", new <>c__DisplayClass108_24 { bosses = BuildBossesArray(CS$<>8__locals2.self) }.<Awake>b__60); }); } internal void <Awake>b__108_19(orig_Awake orig, ChestBehavior self) { <>c__DisplayClass108_25 CS$<>8__locals4 = new <>c__DisplayClass108_25 { self = self }; orig.Invoke(CS$<>8__locals4.self); WrapHook("track_chest", delegate { if (!((Object)(object)CS$<>8__locals4.self == (Object)null)) { _trackedChests[CS$<>8__locals4.self] = ((Component)CS$<>8__locals4.self).GetComponent<PurchaseInteraction>(); } }); } internal void <Awake>b__108_20(orig_Start orig, MultiShopController self) { <>c__DisplayClass108_26 CS$<>8__locals4 = new <>c__DisplayClass108_26 { self = self }; orig.Invoke(CS$<>8__locals4.self); WrapHook("track_multishop", delegate { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)CS$<>8__locals4.self == (Object)null)) { List<(ShopTerminalBehavior, PurchaseInteraction)> list = new List<(ShopTerminalBehavior, PurchaseInteraction)>(); Enumerator<GameObject> enumerator = CS$<>8__locals4.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/*cast due to .constrained prefix*/).Dispose(); } _trackedMultiShops[CS$<>8__locals4.self] = list; } }); } internal void <Awake>b__108_21(orig_Start orig, ShopTerminalBehavior self) { <>c__DisplayClass108_27 CS$<>8__locals4 = new <>c__DisplayClass108_27 { self = self }; orig.Invoke(CS$<>8__locals4.self); WrapHook("track_shopterm", delegate { if (!((Object)(object)CS$<>8__locals4.self == (Object)null)) { _trackedShopTerminals[CS$<>8__locals4.self] = ((Component)CS$<>8__locals4.self).GetComponent<PurchaseInteraction>(); } }); } internal void <Awake>b__108_22(orig_Start orig, GenericPickupController self) { <>c__DisplayClass108_28 CS$<>8__locals3 = new <>c__DisplayClass108_28 { self = self }; orig.Invoke(CS$<>8__locals3.self); WrapHook("track_pickup", delegate { if (!((Object)(object)CS$<>8__locals3.self == (Object)null)) { _trackedPickups.Add(CS$<>8__locals3.self); } }); } internal void <Awake>b__108_23(orig_Awake orig, PickupPickerController self) { <>c__DisplayClass108_29 CS$<>8__locals3 = new <>c__DisplayClass108_29 { self = self }; orig.Invoke(CS$<>8__locals3.self); WrapHook("track_picker", delegate { if (!((Object)(object)CS$<>8__locals3.self == (Object)null)) { _trackedPickers.Add(CS$<>8__locals3.self); } }); } internal int <PruneExportedJournals>b__169_0(string a, string b) { return File.GetLastWriteTimeUtc(b).CompareTo(File.GetLastWriteTimeUtc(a)); } internal bool <PruneTrackedInstances>b__185_0(GenericPickupController p) { return (Object)(object)p == (Object)null; } internal bool <PruneTrackedInstances>b__185_1(PickupPickerController p) { return (Object)(object)p == (Object)null; } internal string <AggregateMods>b__210_0(KeyValuePair<string, (string name, int count)> k) { return k.Key; } internal void <InitializeRunHandoff>b__230_1(string message) { Log.LogWarning((object)("[Archive] " + message)); } } [CompilerGenerated] private sealed class <>c__DisplayClass108_1 { public PickupIndex grantedIndex; public CharacterBody recipientBody; public PickupAttempt attempt; public bool consumedBefore; public GenericPickupController self; public Inventory grantInv; public ItemIndex grantItemIndex; public int gPermBefore; public int gTempBefore; public int gChanBefore; public EquipmentState equipmentBefore; internal void <Awake>b__28() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Invalid comparison between Unknown and I4 //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Invalid comparison between Unknown and I4 //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Invalid comparison between Unknown and I4 //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Invalid comparison between Unknown and I4 <>c__DisplayClass108_2 CS$<>8__locals23 = new <>c__DisplayClass108_2 { CS$<>8__locals1 = this }; Interlocked.Increment(ref _diagPickupGrantedCount); if (!((PickupIndex)(ref grantedIndex)).isValid || (Object)(object)recipientBody == (Object)null) { return; } CS$<>8__locals23.pickupDef = PickupCatalog.GetPickupDef(grantedIndex); if (CS$<>8__locals23.pickupDef == null) { return; } bool flag = attempt.Notified || (!consumedBefore && ReadBoolField(_pickupConsumedField, self)); if (!flag && (Object)(object)grantInv != (Object)null) { if ((int)grantItemIndex != -1) { flag = grantInv.GetItemCountPermanent(grantItemIndex) > gPermBefore || grantInv.GetItemCountTemp(grantItemIndex) > gTempBefore || grantInv.GetItemCountChanneled(grantItemIndex) > gChanBefore; } else if ((int)CS$<>8__locals23.pickupDef.equipmentIndex != -1) { EquipmentState currentEquipmentState = grantInv.currentEquipmentState; flag = !((EquipmentState)(ref currentEquipmentState)).Equals(equipmentBefore) && grantInv.currentEquipmentIndex == CS$<>8__locals23.pickupDef.equipmentIndex; } } if (!flag) { return; } CharacterBody obj = recipientBody; CS$<>8__locals23.master = ((obj != null) ? obj.master : null); CharacterMaster obj2 = CS$<>8__locals23.master; PlayerCharacterMasterController val = ((obj2 != null) ? obj2.playerCharacterMasterController : null); CS$<>8__locals23.netUser = ((val != null) ? val.networkUser : null); bool flag2 = false; CS$<>8__locals23.highlightReason = null; try { if ((int)CS$<>8__locals23.pickupDef.itemIndex != -1) { ItemDef itemDef = ItemCatalog.GetItemDef(CS$<>8__locals23.pickupDef.itemIndex); if ((Object)(object)itemDef != (Object)null && (int)itemDef.tier == 2) { flag2 = true; CS$<>8__locals23.highlightReason = "legendary_pickup"; } } } catch { } EmitRunEvent("pickup_granted", flag2 ? "major" : "minor", delegate(Dictionary<string, object> payload) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) payload["source"] = "pickup"; payload["player"] = BuildPlayerBlock(CS$<>8__locals23.CS$<>8__locals1.recipientBody, CS$<>8__locals23.master, CS$<>8__locals23.netUser); payload["item"] = BuildGrantItemRef(CS$<>8__locals23.pickupDef, 1, CS$<>8__locals23.CS$<>8__locals1.grantInv, CS$<>8__locals23.CS$<>8__locals1.grantItemIndex, CS$<>8__locals23.CS$<>8__locals1.gPermBefore, CS$<>8__locals23.CS$<>8__locals1.gTempBefore, CS$<>8__locals23.CS$<>8__locals1.gChanBefore); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); if (CS$<>8__locals23.highlightReason != null) { payload["highlight_reason"] = CS$<>8__locals23.highlightReason; } string text = TryConsumeChestSourceId(CS$<>8__locals23.CS$<>8__locals1.grantedIndex); if (text != null) { payload["source_id"] = text; } }); } } [CompilerGenerated] private sealed class <>c__DisplayClass108_10 { public CharacterBody newBody; internal void <Awake>b__37() { <>c__DisplayClass108_11 CS$<>8__locals8 = new <>c__DisplayClass108_11 { CS$<>8__locals4 = this }; if ((Object)(object)Run.instance == (Object)null || (Object)(object)newBody == (Object)null) { return; } CS$<>8__locals8.master = newBody.master; if (!((Object)(object)CS$<>8__locals8.master == (Object)null) && _deadPlayerMasters.Remove(CS$<>8__locals8.master)) { PlayerCharacterMasterController playerCharacterMasterController = CS$<>8__locals8.master.playerCharacterMasterController; CS$<>8__locals8.netUser = (((Object)(object)playerCharacterMasterController != (Object)null) ? playerCharacterMasterController.networkUser : null); EmitRunEvent("player_respawned", "major", delegate(Dictionary<string, object> payload) { payload["player"] = BuildPlayerBlock(CS$<>8__locals8.CS$<>8__locals4.newBody, CS$<>8__locals8.master, CS$<>8__locals8.netUser); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); }); } } } [CompilerGenerated] private sealed class <>c__DisplayClass108_11 { public CharacterMaster master; public NetworkUser netUser; public <>c__DisplayClass108_10 CS$<>8__locals4; internal void <Awake>b__38(Dictionary<string, object> payload) { payload["player"] = BuildPlayerBlock(CS$<>8__locals4.newBody, master, netUser); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); } } [CompilerGenerated] private sealed class <>c__DisplayClass108_12 { public ShrineBossBehavior self; public int prevCount; public Interactor interactor; internal void <Awake>b__45() { <>c__DisplayClass108_13 CS$<>8__locals10 = new <>c__DisplayClass108_13 { stackCount = ReadShrineBossPurchaseCount(self) }; if (CS$<>8__locals10.stackCount != prevCount) { CS$<>8__locals10.body = (((Object)(object)interactor != (Object)null) ? ((Component)interactor).GetComponent<CharacterBody>() : null); CharacterBody obj = CS$<>8__locals10.body; CS$<>8__locals10.master = ((obj != null) ? obj.master : null); CharacterMaster obj2 = CS$<>8__locals10.master; object netUser; if (obj2 == null) { netUser = null; } else { PlayerCharacterMasterController playerCharacterMasterController = obj2.playerCharacterMasterController; netUser = ((playerCharacterMasterController != null) ? playerCharacterMasterController.networkUser : null); } CS$<>8__locals10.netUser = (NetworkUser)netUser; EmitRunEvent("shrine_mountain_activated", "major", delegate(Dictionary<string, object> payload) { payload["player"] = BuildPlayerBlock(CS$<>8__locals10.body, CS$<>8__locals10.master, CS$<>8__locals10.netUser); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); payload["stack_count"] = CS$<>8__locals10.stackCount; }); } } } [CompilerGenerated] private sealed class <>c__DisplayClass108_13 { public CharacterBody body; public CharacterMaster master; public NetworkUser netUser; public int stackCount; internal void <Awake>b__46(Dictionary<string, object> payload) { payload["player"] = BuildPlayerBlock(body, master, netUser); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); payload["stack_count"] = stackCount; } } [CompilerGenerated] private sealed class <>c__DisplayClass108_16 { public ChestBehavior self; internal void <Awake>b__52() { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_011a: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) <>c__DisplayClass108_17 CS$<>8__locals25 = new <>c__DisplayClass108_17(); if ((Object)(object)self == (Object)null) { return; } CS$<>8__locals25.ctx = null; lock (_chestLock) { if (_pendingChests.TryGetValue(self, out CS$<>8__locals25.ctx)) { _pendingChests.Remove(self); } } CS$<>8__locals25.dropPickup = ((CS$<>8__locals25.ctx != null) ? CS$<>8__locals25.ctx.RolledPickup : PickupIndex.none); if (!((PickupIndex)(ref CS$<>8__locals25.dropPickup)).isValid) { try { CS$<>8__locals25.dropPickup = self.currentPickup.pickupIndex; } catch { } } CS$<>8__locals25.sourceId = CS$<>8__locals25.ctx?.SourceId ?? ("chest:" + ((Object)((Component)self).gameObject).GetInstanceID()); if (((PickupIndex)(ref CS$<>8__locals25.dropPickup)).isValid) { RecordChestDrop(CS$<>8__locals25.sourceId, CS$<>8__locals25.dropPickup); } CS$<>8__locals25.pickup = null; if (((PickupIndex)(ref CS$<>8__locals25.dropPickup)).isValid) { try { PickupDef pickupDef = PickupCatalog.GetPickupDef(CS$<>8__locals25.dropPickup); if (pickupDef != null) { CS$<>8__locals25.pickup = BuildPickupRef(pickupDef, 1, hidden: false); } } catch { } } EmitRunEvent("chest_opened", "minor", delegate(Dictionary<string, object> payload) { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) payload["player"] = CS$<>8__locals25.ctx?.Player; payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); payload["source_id"] = CS$<>8__locals25.sourceId; payload["chest"] = new Dictionary<string, object>(StringComparer.Ordinal) { ["kind"] = CS$<>8__locals25.ctx?.Kind ?? "unknown", ["cost"] = CS$<>8__locals25.ctx?.Cost ?? 0, ["tier"] = CS$<>8__locals25.ctx?.Tier ?? (((PickupIndex)(ref CS$<>8__locals25.dropPickup)).isValid ? SafePickupTier(CS$<>8__locals25.dropPickup) : "Tier1") }; payload["balances_after"] = CS$<>8__locals25.ctx?.BalancesAfter; payload["pickup"] = CS$<>8__locals25.pickup; }); } } [CompilerGenerated] private sealed class <>c__DisplayClass108_17 { public PendingChestOpen ctx; public string sourceId; public PickupIndex dropPickup; public object pickup; internal void <Awake>b__53(Dictionary<string, object> payload) { //IL_00d7: Unknown result type (might be due to invalid IL or missing references) payload["player"] = ctx?.Player; payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); payload["source_id"] = sourceId; payload["chest"] = new Dictionary<string, object>(StringComparer.Ordinal) { ["kind"] = ctx?.Kind ?? "unknown", ["cost"] = ctx?.Cost ?? 0, ["tier"] = ctx?.Tier ?? (((PickupIndex)(ref dropPickup)).isValid ? SafePickupTier(dropPickup) : "Tier1") }; payload["balances_after"] = ctx?.BalancesAfter; payload["pickup"] = pickup; } } [CompilerGenerated] private sealed class <>c__DisplayClass108_18 { public ShrineChanceBehavior self; public int prevCount; public Interactor interactor; public string shrineSourceId; public PickupIndex rolled; internal void <Awake>b__54() { //IL_0060: Unknown result type (might be due to invalid IL or missing references) bool num = ReadIntField(_shrineChanceSuccessCountField, self) > prevCount; bool flag = ReadBoolField(_shrineChanceDollWinField, self); string outcome = (num ? "success" : (flag ? "success" : "fail")); EmitShrineUsed(((Component)self).GetComponent<PurchaseInteraction>(), interactor, "chance", outcome, shrineSourceId, rolled); } } [CompilerGenerated] private sealed class <>c__DisplayClass108_19 { public ShrineCombatBehavior self; public int prevCount; public Interactor interactor; internal void <Awake>b__55() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (ReadIntField(_shrineCombatPurchaseCountField, self) != prevCount) { EmitShrineUsed(((Component)self).GetComponent<PurchaseInteraction>(), interactor, "combat", "success"); } } } [CompilerGenerated] private sealed class <>c__DisplayClass108_2 { public CharacterMaster master; public NetworkUser netUser; public PickupDef pickupDef; public string highlightReason; public <>c__DisplayClass108_1 CS$<>8__locals1; internal void <Awake>b__29(Dictionary<string, object> payload) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) payload["source"] = "pickup"; payload["player"] = BuildPlayerBlock(CS$<>8__locals1.recipientBody, master, netUser); payload["item"] = BuildGrantItemRef(pickupDef, 1, CS$<>8__locals1.grantInv, CS$<>8__locals1.grantItemIndex, CS$<>8__locals1.gPermBefore, CS$<>8__locals1.gTempBefore, CS$<>8__locals1.gChanBefore); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); if (highlightReason != null) { payload["highlight_reason"] = highlightReason; } string text = TryConsumeChestSourceId(CS$<>8__locals1.grantedIndex); if (text != null) { payload["source_id"] = text; } } } [CompilerGenerated] private sealed class <>c__DisplayClass108_20 { public ShrineBloodBehavior self; public int prevCount; public Interactor interactor; internal void <Awake>b__56() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (ReadIntField(_shrineBloodPurchaseCountField, self) != prevCount) { EmitShrineUsed(((Component)self).GetComponent<PurchaseInteraction>(), interactor, "blood", "success"); } } } [CompilerGenerated] private sealed class <>c__DisplayClass108_21 { public ShrineRestackBehavior self; public int prevCount; public Interactor interactor; internal void <Awake>b__57() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (ReadIntField(_shrineRestackPurchaseCountField, self) != prevCount) { EmitShrineUsed(((Component)self).GetComponent<PurchaseInteraction>(), interactor, "order", "success"); } } } [CompilerGenerated] private sealed class <>c__DisplayClass108_22 { public ShrineHealingBehavior self; public int prevCount; public Interactor interactor; internal void <Awake>b__58() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) if (ReadIntField(_shrineHealingPurchaseCountField, self) != prevCount) { EmitShrineUsed(((Component)self).GetComponent<PurchaseInteraction>(), interactor, "woods", "success"); } } } [CompilerGenerated] private sealed class <>c__DisplayClass108_23 { public BossGroup self; internal void <Awake>b__59() { EmitRunEvent("boss_defeated", "major", new <>c__DisplayClass108_24 { bosses = BuildBossesArray(self) }.<Awake>b__60); } } [CompilerGenerated] private sealed class <>c__DisplayClass108_24 { public List<Dictionary<string, object>> bosses; internal void <Awake>b__60(Dictionary<string, object> payload) { payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); payload["bosses"] = bosses; } } [CompilerGenerated] private sealed class <>c__DisplayClass108_25 { public ChestBehavior self; internal void <Awake>b__61() { if (!((Object)(object)self == (Object)null)) { _trackedChests[self] = ((Component)self).GetComponent<PurchaseInteraction>(); } } } [CompilerGenerated] private sealed class <>c__DisplayClass108_26 { public MultiShopController self; internal void <Awake>b__62() { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)self == (Object)null) { return; } 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/*cast due to .constrained prefix*/).Dispose(); } _trackedMultiShops[self] = list; } } [CompilerGenerated] private sealed class <>c__DisplayClass108_27 { public ShopTerminalBehavior self; internal void <Awake>b__63() { if (!((Object)(object)self == (Object)null)) { _trackedShopTerminals[self] = ((Component)self).GetComponent<PurchaseInteraction>(); } } } [CompilerGenerated] private sealed class <>c__DisplayClass108_28 { public GenericPickupController self; internal void <Awake>b__64() { if (!((Object)(object)self == (Object)null)) { _trackedPickups.Add(self); } } } [CompilerGenerated] private sealed class <>c__DisplayClass108_29 { public PickupPickerController self; internal void <Awake>b__65() { if (!((Object)(object)self == (Object)null)) { _trackedPickers.Add(self); } } } [CompilerGenerated] private sealed class <>c__DisplayClass108_3 { public bool haveBefore; public Inventory self; public ItemIndex itemIndex; public int gPermBefore; public int gTempBefore; public int gChanBefore; public CharacterMaster giveMaster; public PlayerCharacterMasterController givePcmc; public int count; internal void <Awake>b__30() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0040: 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: Invalid comparison between Unknown and I4 //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: 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: Invalid comparison between Unknown and I4 <>c__DisplayClass108_4 CS$<>8__locals22 = new <>c__DisplayClass108_4 { CS$<>8__locals2 = this }; Interlocked.Increment(ref _diagPickupGrantedCount); if (!haveBefore || (self.GetItemCountPermanent(itemIndex) <= gPermBefore && self.GetItemCountTemp(itemIndex) <= gTempBefore && self.GetItemCountChanneled(itemIndex) <= gChanBefore)) { return; } CS$<>8__locals22.master = giveMaster; PlayerCharacterMasterController val = givePcmc; ItemDef itemDef = ItemCatalog.GetItemDef(itemIndex); if ((Object)(object)itemDef == (Object)null || (int)itemDef.tier == 5) { return; } PickupIndex val2 = PickupCatalog.FindPickupIndex(itemIndex); CS$<>8__locals22.pickupDef = PickupCatalog.GetPickupDef(val2); if (CS$<>8__locals22.pickupDef == null) { return; } CS$<>8__locals22.body = CS$<>8__locals22.master.GetBody(); CS$<>8__locals22.netUser = val.networkUser; bool flag = (int)itemDef.tier == 2; CS$<>8__locals22.highlightReason = (flag ? "legendary_pickup" : null); EmitRunEvent("pickup_granted", flag ? "major" : "minor", delegate(Dictionary<string, object> payload) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) payload["source"] = "give_item"; payload["player"] = BuildPlayerBlock(CS$<>8__locals22.body, CS$<>8__locals22.master, CS$<>8__locals22.netUser); payload["item"] = (CS$<>8__locals22.CS$<>8__locals2.haveBefore ? BuildGrantItemRef(CS$<>8__locals22.pickupDef, CS$<>8__locals22.CS$<>8__locals2.count, CS$<>8__locals22.CS$<>8__locals2.self, CS$<>8__locals22.CS$<>8__locals2.itemIndex, CS$<>8__locals22.CS$<>8__locals2.gPermBefore, CS$<>8__locals22.CS$<>8__locals2.gTempBefore, CS$<>8__locals22.CS$<>8__locals2.gChanBefore) : BuildPickupRef(CS$<>8__locals22.pickupDef, CS$<>8__locals22.CS$<>8__locals2.count, hidden: false)); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); if (CS$<>8__locals22.highlightReason != null) { payload["highlight_reason"] = CS$<>8__locals22.highlightReason; } }); } } [CompilerGenerated] private sealed class <>c__DisplayClass108_4 { public CharacterBody body; public CharacterMaster master; public NetworkUser netUser; public PickupDef pickupDef; public string highlightReason; public <>c__DisplayClass108_3 CS$<>8__locals2; internal void <Awake>b__31(Dictionary<string, object> payload) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) payload["source"] = "give_item"; payload["player"] = BuildPlayerBlock(body, master, netUser); payload["item"] = (CS$<>8__locals2.haveBefore ? BuildGrantItemRef(pickupDef, CS$<>8__locals2.count, CS$<>8__locals2.self, CS$<>8__locals2.itemIndex, CS$<>8__locals2.gPermBefore, CS$<>8__locals2.gTempBefore, CS$<>8__locals2.gChanBefore) : BuildPickupRef(pickupDef, CS$<>8__locals2.count, hidden: false)); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); if (highlightReason != null) { payload["highlight_reason"] = highlightReason; } } } [CompilerGenerated] private sealed class <>c__DisplayClass108_7 { public TryTransformResult result; internal unsafe void <Awake>b__34() { //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Expected I4, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Invalid comparison between Unknown and I4 //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) <>c__DisplayClass108_8 CS$<>8__locals24 = new <>c__DisplayClass108_8(); if ((Object)(object)Run.instance == (Object)null) { return; } Inventory inventory = result.inventory; CS$<>8__locals24.master = (((Object)(object)inventory != (Object)null) ? ((Component)inventory).GetComponent<CharacterMaster>() : null); PlayerCharacterMasterController val = (((Object)(object)CS$<>8__locals24.master != (Object)null) ? CS$<>8__locals24.master.playerCharacterMasterController : null); if ((Object)(object)val == (Object)null) { return; } CS$<>8__locals24.body = CS$<>8__locals24.master.GetBody(); if ((Object)(object)CS$<>8__locals24.body == (Object)null) { return; } CS$<>8__locals24.netUser = val.networkUser; CS$<>8__locals24.takenDef = ItemCatalog.GetItemDef(result.takenItem.itemIndex); CS$<>8__locals24.givenDef = ItemCatalog.GetItemDef(result.givenItem.itemIndex); if ((Object)(object)CS$<>8__locals24.takenDef == (Object)null || (Object)(object)CS$<>8__locals24.givenDef == (Object)null) { return; } CS$<>8__locals24.takenCount = Math.Max(result.takenItem.stackValues.totalStacks, 1); CS$<>8__locals24.givenCount = Math.Max(result.givenItem.stackValues.totalStacks, 1); if ((int)result.transformationType < 0) { EmitRunEvent("scrapper_used", "minor", delegate(Dictionary<string, object> payload) { payload["player"] = BuildPlayerBlock(CS$<>8__locals24.body, CS$<>8__locals24.master, CS$<>8__locals24.netUser); payload["item"] = BuildItemRef(CS$<>8__locals24.takenDef, CS$<>8__locals24.takenCount); payload["scrap"] = BuildItemRef(CS$<>8__locals24.givenDef, CS$<>8__locals24.givenCount); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); }); return; } <>c__DisplayClass108_9 CS$<>8__locals32 = new <>c__DisplayClass108_9 { CS$<>8__locals3 = CS$<>8__locals24 }; try { TransformationType transformationType = (TransformationType)result.transformationType; CS$<>8__locals32.transformType = ((object)(*(TransformationType*)(&transformationType))/*cast due to .constrained prefix*/).ToString(); } catch { CS$<>8__locals32.transformType = ((int)result.transformationType).ToString(); } EmitRunEvent("item_transformed", "minor", delegate(Dictionary<string, object> payload) { payload["transform_type"] = CS$<>8__locals32.transformType; payload["player"] = BuildPlayerBlock(CS$<>8__locals32.CS$<>8__locals3.body, CS$<>8__locals32.CS$<>8__locals3.master, CS$<>8__locals32.CS$<>8__locals3.netUser); payload["taken_item"] = BuildItemRef(CS$<>8__locals32.CS$<>8__locals3.takenDef, CS$<>8__locals32.CS$<>8__locals3.takenCount); payload["given_item"] = BuildItemRef(CS$<>8__locals32.CS$<>8__locals3.givenDef, CS$<>8__locals32.CS$<>8__locals3.givenCount); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); }); } } [CompilerGenerated] private sealed class <>c__DisplayClass108_8 { public CharacterBody body; public CharacterMaster master; public NetworkUser netUser; public ItemDef takenDef; public int takenCount; public ItemDef givenDef; public int givenCount; internal void <Awake>b__35(Dictionary<string, object> payload) { payload["player"] = BuildPlayerBlock(body, master, netUser); payload["item"] = BuildItemRef(takenDef, takenCount); payload["scrap"] = BuildItemRef(givenDef, givenCount); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); } } [CompilerGenerated] private sealed class <>c__DisplayClass108_9 { public string transformType; public <>c__DisplayClass108_8 CS$<>8__locals3; internal void <Awake>b__36(Dictionary<string, object> payload) { payload["transform_type"] = transformType; payload["player"] = BuildPlayerBlock(CS$<>8__locals3.body, CS$<>8__locals3.master, CS$<>8__locals3.netUser); payload["taken_item"] = BuildItemRef(CS$<>8__locals3.takenDef, CS$<>8__locals3.takenCount); payload["given_item"] = BuildItemRef(CS$<>8__locals3.givenDef, CS$<>8__locals3.givenCount); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); } } public const string PluginGUID = "com.turne.ror2itemsync"; public const string PluginName = "RoR2ItemSync"; public const string PluginVersion = "2.0.0"; public const int LiveSchemaVersion = 2; private static ConfigEntry<bool> _logBroadcastJsonConfig; private static ConfigEntry<int> _broadcastIntervalConfig; private static ConfigEntry<string> _bindModeConfig; private static ConfigEntry<int> _wsPortConfig; private static ConfigEntry<int> _udpPortConfig; private static ConfigEntry<bool> _enableDiscoveryConfig; private static ConfigEntry<bool> _journalExportConfig; private static ConfigEntry<string> _journalExportDirConfig; private static ConfigEntry<int> _journalRetainRunsConfig; private static ConfigEntry<int> _journalSnapshotIntervalConfig; private const float WorldScanInterval = 5f; internal static ManualLogSource Log; private SyncServer _server; internal static volatile string LastBroadcast = null; private static readonly BoundedQueue<(SyncBehavior session, string type, RunJournalRequest journal)> _requests = new BoundedQueue<(SyncBehavior, string, RunJournalRequest)>(128); 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 List<object> _cachedMinions = new List<object>(); private int _cachedMinionTotal; private static readonly ConcurrentQueue<object> _broadcastQueue = new ConcurrentQueue<object>(); private Thread _serializeThread; private volatile bool _threadRunning; private static readonly BoundedQueue<(SyncBehavior session, object payload)> _callerSendQueue = new BoundedQueue<(SyncBehavior, object)>(32); private static readonly AutoResetEvent _serializeSignal = new AutoResetEvent(initialState: false); private static volatile bool _pluginAlive = true; 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<object> _cachedArtifacts = new List<object>(); private static long _broadcastSequence; private static volatile string _currentRunId = ""; private static float _stageStartRunSeconds; private static bool _inAttemptGrant; [ThreadStatic] private static PickupAttempt _activePickupAttempt; private Hook _pickupNotificationHook; private const int MaxJournalEntries = 10000; private static readonly Queue<Dictionary<string, object>> _runJournal = new Queue<Dictionary<string, object>>(256); private static int _journalDroppedCount; private static bool _journalHistoryTruncated; private static long _journalOldestSequence = -1L; private static long _journalNewestSequence = -1L; private static string _journalRunId = ""; private static readonly object _journalLock = new object(); private static readonly ConcurrentQueue<(string runId, Dictionary<string, object> entry)> _journalStreamQueue = new ConcurrentQueue<(string, Dictionary<string, object>)>(); private static readonly AutoResetEvent _journalStreamSignal = new AutoResetEvent(initialState: false); private static volatile bool _journalStreamRunning; private static Thread _journalStreamThread; private float _lastJournalSnapshotTime; private static Dictionary<string, object> _lastGoodRunSummary; private static Dictionary<string, object> _lastGoodSnapshot; private static object _lastGoodTimer; private static string _runOutcome; private static string _runEndingName; private static string _runEndingText; private static bool _runEndingIsWin; private static int _mainThreadId; private static volatile string _cachedGameState = "menu"; private static string _cachedRoR2Version = ""; private static readonly HashSet<CharacterMaster> _deadPlayerMasters = new HashSet<CharacterMaster>(); private static readonly Dictionary<ChestBehavior, PendingChestOpen> _pendingChests = new Dictionary<ChestBehavior, PendingChestOpen>(); private const float ChestPendingTimeoutSeconds = 4f; private static readonly List<RecentChestDrop> _recentChestDrops = new List<RecentChestDrop>(); private const float ChestDropEchoWindowSeconds = 15f; private const int MaxRecentChestDrops = 32; private static readonly object _chestLock = new object(); [ThreadStatic] private static bool _inShrineChanceDrop; [ThreadStatic] private static string _shrineChanceSourceId; [ThreadStatic] private static PickupIndex _shrineChanceRolledPickup; private static long _diagPurchaseInteractionCount; private static long _diagEmitRunEventCount; private static long _diagPickupGrantedCount; private static long _diagDeathHookCount; private static long _diagDeepCopyTotalTicks; private static long _diagDeepCopyMaxTicks; private static long _diagSlowEmitCount; private static long _diagPollTickTotalTicks; private static long _diagPollTickMaxTicks; private static long _diagSlowPollTickCount; private const long SlowEmitTicksThreshold = 100000L; private const long SlowPollTickTicksThreshold = 160000L; private static readonly Dictionary<string, int> _playerDeathCount = new Dictionary<string, int>(StringComparer.Ordinal); private static readonly Dictionary<ItemIndex, string> _itemPackIdCache = new Dictionary<ItemIndex, string>(); private static readonly Dictionary<EquipmentIndex, string> _equipmentPackIdCache = new Dictionary<EquipmentIndex, string>(); private static int BroadcastIntervalMs = 500; private static WaitForSecondsRealtime _broadcastWait = new WaitForSecondsRealtime((float)BroadcastIntervalMs / 1000f); private static readonly Stopwatch _throttleClock = Stopwatch.StartNew(); private static readonly Dictionary<string, double> _throttleLastFire = new Dictionary<string, double>(); private static readonly BindingFlags _privInst = BindingFlags.Instance | BindingFlags.NonPublic; private static readonly FieldInfo _pickupConsumedField = typeof(GenericPickupController).GetField("consumed", _privInst); private static readonly FieldInfo _shrineBossPurchaseCountField = typeof(ShrineBossBehavior).GetField("purchaseCount", _privInst); private static readonly FieldInfo _shrineCombatPurchaseCountField = typeof(ShrineCombatBehavior).GetField("purchaseCount", _privInst); private static readonly FieldInfo _shrineBloodPurchaseCountField = typeof(ShrineBloodBehavior).GetField("purchaseCount", _privInst); private static readonly FieldInfo _shrineRestackPurchaseCountField = typeof(ShrineRestackBehavior).GetField("purchaseCount", _privInst); private static readonly FieldInfo _shrineHealingPurchaseCountField = typeof(ShrineHealingBehavior).GetField("<purchaseCount>k__BackingField", _privInst); private static readonly FieldInfo _shrineChanceSuccessCountField = typeof(ShrineChanceBehavior).GetField("successfulPurchaseCount", _privInst); private static readonly FieldInfo _shrineChanceDollWinField = typeof(ShrineChanceBehavior).GetField("chanceDollWin", _privInst); private static readonly FieldInfo _bossGroupMemoriesField = typeof(BossGroup).GetField("bossMemories", _privInst); private static readonly FieldInfo _bossGroupMemoryCountField = typeof(BossGroup).GetField("bossMemoryCount", _privInst); private static readonly FieldInfo _activeBuffsListField = typeof(CharacterBody).GetField("activeBuffsList", _privInst); private static readonly FieldInfo _activeBuffsListCountField = typeof(CharacterBody).GetField("activeBuffsListCount", _privInst); private static float _pausePrevRunSeconds = -1f; private static float _pausePrevRealtime = -1f; private static bool _pauseCached = false; private const int RunJournalMaxLimit = 2000; private const int RunJournalDefaultLimit = 2000; internal static RunArchiveStore Archives; private ConfigEntry<int> _handoffWaitConfig; private int _handoffRevision; private float _lastHandoffCaptureTime = float.NegativeInfinity; private RunArchiveTicket _lastHandoffTicket; private bool _handoffQuitting; private bool HandoffCaptureDue { get { if (Archives != null) { return Time.unscaledTime - _lastHandoffCaptureTime >= 5f; } return false; } } private static void ObservePickupNotification(PickupNotificationOrig orig, CharacterMaster master, UniquePickup pickup) { //IL_003c: 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) //IL_0027: Unknown result type (might be due to invalid IL or missing references) PickupAttempt activePickupAttempt = _activePickupAttempt; if (_pluginAlive && activePickupAttempt != null && (Object)(object)activePickupAttempt.Master == (Object)(object)master && activePickupAttempt.Pickup == pickup.pickupIndex) { activePickupAttempt.Notified = true; } orig(master, pickup); } private unsafe void Awake() { //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Expected O, but got Unknown //IL_0377: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Expected O, but got Unknown //IL_039b: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Expected O, but got Unknown //IL_0488: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Expected O, but got Unknown //IL_0471: Unknown result type (might be due to invalid IL or missing references) //IL_0476: Unknown result type (might be due to invalid IL or missing references) //IL_047c: Expected O, but got Unknown //IL_04a6: Unknown result type (might be due to invalid IL or missing references) //IL_04ab: Unknown result type (might be due to invalid IL or missing references) //IL_04b1: Expected O, but got Unknown //IL_04ca: Unknown result type (might be due to invalid IL or missing references) //IL_04cf: Unknown result type (might be due to invalid IL or missing references) //IL_04d5: Expected O, but got Unknown //IL_04ee: Unknown result type (might be due to invalid IL or missing references) //IL_04f3: Unknown result type (might be due to invalid IL or missing references) //IL_04f9: Expected O, but got Unknown //IL_0512: Unknown result type (might be due to invalid IL or missing references) //IL_0517: Unknown result type (might be due to invalid IL or missing references) //IL_051d: Expected O, but got Unknown //IL_0536: Unknown result type (might be due to invalid IL or missing references) //IL_053b: Unknown result type (might be due to invalid IL or missing references) //IL_0541: Expected O, but got Unknown //IL_055a: Unknown result type (might be due to invalid IL or missing references) //IL_055f: Unknown result type (might be due to invalid IL or missing references) //IL_0565: Expected O, but got Unknown //IL_057e: Unknown result type (might be due to invalid IL or missing references) //IL_0583: Unknown result type (might be due to invalid IL or missing references) //IL_0589: Expected O, but got Unknown //IL_05a2: Unknown result type (might be due to invalid IL or missing references) //IL_05a7: Unknown result type (might be due to invalid IL or missing references) //IL_05ad: Expected O, but got Unknown //IL_0638: Unknown result type (might be due to invalid IL or missing references) //IL_063d: Unknown result type (might be due to invalid IL or missing references) //IL_0643: Expected O, but got Unknown //IL_065c: Unknown result type (might be due to invalid IL or missing references) //IL_0661: Unknown result type (might be due to invalid IL or missing references) //IL_0667: Expected O, but got Unknown //IL_0680: Unknown result type (might be due to invalid IL or missing references) //IL_0685: Unknown result type (might be due to invalid IL or missing references) //IL_068b: Expected O, but got Unknown //IL_06a4: Unknown result type (might be due to invalid IL or missing references) //IL_06a9: Unknown result type (might be due to invalid IL or missing references) //IL_06af: Expected O, but got Unknown //IL_06c8: Unknown result type (might be due to invalid IL or missing references) //IL_06cd: Unknown result type (might be due to invalid IL or missing references) //IL_06d3: Expected O, but got Unknown Log = ((BaseUnityPlugin)this).Logger; try { MethodInfo method = typeof(GenericPickupController).GetMethod("SendPickupMessage", new Type[2] { typeof(CharacterMaster), typeof(UniquePickup) }); if (method == null) { throw new MissingMethodException("SendPickupMessage"); } _pickupNotificationHook = new Hook((MethodBase)method, (Delegate)new PickupNotificationDetour(ObservePickupNotification)); } catch (Exception ex) { Log.LogWarning((object)("[Pickup] Success notification hook unavailable; using inventory/consumption evidence: " + ex.Message)); } _mainThreadId = Thread.CurrentThread.ManagedThreadId; try { _cachedRoR2Version = Application.version ?? ""; } catch { _cachedRoR2Version = ""; } _logBroadcastJsonConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "log_broadcast_json", false, "If true, log every outgoing broadcast JSON payload at LogInfo level. Default false. Enable only for short local debugging sessions — at the broadcast cadence this writes several KB/sec to disk and contributes significant felt lag."); _broadcastIntervalConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Broadcasting", "inventory_update_ms", 500, "How often the full inventory_update snapshot is broadcast, in milliseconds. Lower = fresher data and a smoother timer, but more CPU/bandwidth; higher = lighter. Clamped to 100-5000. Apps read the active value from hello.broadcast_intervals.inventory_update_ms, so changing this stays compatible."); BroadcastIntervalMs = Mathf.Clamp(_broadcastIntervalConfig.Value, 100, 5000); _broadcastWait = new WaitForSecondsRealtime((float)BroadcastIntervalMs / 1000f); _bindModeConfig = ((BaseUnityPlugin)this).Config.Bind<string>("Network", "bind_mode", "lan", "Which interfaces the WebSocket + UDP discovery bind to. 'lan' = reachable from other devices on your local network (phone overlays, a second PC). 'localhost' = this machine only. Any value other than 'localhost' is treated as 'lan'. There is no authentication, so only use 'lan' on networks you trust."); _wsPortConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Network", "websocket_port", 11420, "TCP port for the WebSocket server. Change if 11420 conflicts with another app."); _udpPortConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Network", "udp_port", 11421, "UDP port for auto-discovery (the beacon and DISCOVER replies)."); _enableDiscoveryConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Network", "enable_udp_discovery", true, "Broadcast a UDP discovery beacon every 2s and answer DISCOVER packets so companion apps can find the server automatically. Disable to stay silent on the network (apps must then connect by IP:port directly). Has no effect when bind_mode = localhost."); _journalExportConfig = ((BaseUnityPlugin)this).Config.Bind<bool>("Run Journal", "export_to_disk", true, "Stream every journal entry (run events, loadout, state snapshots, run_summary) to a .jsonl file AS IT HAPPENS — one file per run, one JSON object per line. Lines are flushed as they are written, so a crash mid-run keeps everything up to the crash. Default on: journals are plain text and small, so this is a cheap hard log of every run."); _journalExportDirConfig = ((BaseUnityPlugin)this).Config.Bind<string>("Run Journal", "export_directory", "", "Folder for run journal files. Blank = a 'RunJournals' folder next to the mod DLL."); _journalRetainRunsConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Run Journal", "retain_runs", 0, "How many of the most recent run journal files to keep on disk. Older files are deleted when a run's file is closed. 0 = keep all (default). Clamped 0-100."); _journalSnapshotIntervalConfig = ((BaseUnityPlugin)this).Config.Bind<int>("Run Journal", "snapshot_interval_seconds", 30, "Every N seconds during a run, append a full inventory_update state snapshot to the journal (tagged severity \"snapshot\") — player inventories/stats/buffs, world state, minions — so journals capture how the run evolved, not just its discrete events. Each snapshot tick also appends a run_summary stat sheet (kills/damage/deaths so far, same severity) and refreshes the fallback captured for run end, so a quit or game close still yields real final stats. Boundary snapshots ride the same switch: one at each stage start and a final one at run end (the exact final build). Snapshots are journal-only (never re-broadcast) and are excluded from request_run_journal responses unless the request opts in via include_snapshots. 0 = off. Clamped 5-600."); bool flag = string.Equals(_bindModeConfig.Value, "localhost", StringComparison.OrdinalIgnoreCase); Log.LogInfo((object)(string.Format("[Config] cadence={0}ms, bind={1}, ", BroadcastIntervalMs, flag ? "localhost" : "lan") + $"ws_port={_wsPortConfig.Value}, udp_port={_udpPortConfig.Value}, " + $"discovery={_enableDiscoveryConfig.Value}, journal_export={_journalExportConfig.Value}")); _server = new SyncServer(); InitializeRunHandoff(); try { _server.Start("2.0.0", flag, _wsPortConfig.Value, _udpPortConfig.Value, _enableDiscoveryConfig.Value); } catch (Exception ex2) { Log.LogError((object)($"[Server] Failed to start (ws_port={_wsPortConfig.Value} in use? networking blocked?): {ex2.Message}. " + "Companion-app sync is unavailable this session; the rest of the mod continues normally.")); } Run.onRunStartGlobal += delegate { _currentRunId = Guid.NewGuid().ToString("N"); _handoffRevision = 0; _lastHandoffCaptureTime = float.NegativeInfinity; _playerDeathCount.Clear(); _deadPlayerMasters.Clear(); _lastJournalSnapshotTime = Time.unscaledTime; _lastGoodRunSummary = null; _lastGoodSnapshot = null; _lastGoodTimer = null; _runOutcome = null; _runEndingName = null; _runEndingText = null; _runEndingIsWin = false; ClearJournal(); PrewarmPackCaches(); WrapHook("run_started", delegate { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_0097: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Invalid comparison between Unknown and I4 //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Expected I4, but got Unknown string seed = ""; try { if ((Object)(object)Run.instance != (Object)null) { seed = Run.instance.seed.ToString(); } } catch { } string gameMode = ""; try { if ((Object)(object)Run.instance != (Object)null) { gameMode = GameModeCatalog.GetGameModeName(Run.instance.gameModeIndex) ?? ""; } } catch { } int eclipseLevel = 0; try { if ((Object)(object)Run.instance != (Object)null) { DifficultyIndex selectedDifficulty = Run.instance.selectedDifficulty; if ((int)selectedDifficulty >= 3 && (int)selectedDifficulty <= 10) { eclipseLevel = selectedDifficulty - 3 + 1; } } } catch { } int playerCount = 0; try { playerCount = PlayerCharacterMasterController.instances.Count; } catch { } EmitRunEvent("run_started", "major", delegate(Dictionary<string, object> payload) { payload["seed"] = seed; payload["game_mode"] = gameMode; payload["difficulty"] = BuildDifficultyBlock(); payload["eclipse_level"] = eclipseLevel; payload["artifacts"] = BuildEnabledArtifactsList(); payload["player_count"] = playerCount; }); Log.LogInfo((object)$"[Run] Run started, notifying {_server?.SessionCount ?? 0} client(s) (run_id={_currentRunId})"); }); try { ((MonoBehaviour)this).StartCoroutine(JournalLoadoutWhenReady(_currentRunId)); } catch (Exception ex3) { Log.LogWarning((object)("[Journal] loadout coroutine failed to start: " + ex3.Message)); } }; object obj2 = <>c.<>9__108_1; if (obj2 == null) { hook_AttemptGrant val = delegate(orig_AttemptGrant orig, GenericPickupController self, CharacterBody recipientBody) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Invalid comparison between Unknown and I4 //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) if (!_pluginAlive) { orig.Invoke(self, recipientBody); } else { PickupIndex grantedIndex = PickupIndex.none; try { grantedIndex = self.pickupIndex; } catch { } Inventory grantInv = null; ItemIndex grantItemIndex = (ItemIndex)(-1); int gPermBefore = 0; int gTempBefore = 0; int gChanBefore = 0; EquipmentState equipmentBefore = EquipmentState.empty; bool consumedBefore = ReadBoolField(_pickupConsumedField, self); try { PickupDef val17 = (((PickupIndex)(ref grantedIndex)).isValid ? PickupCatalog.GetPickupDef(grantedIndex) : null); if (val17 != null && (Object)(object)recipientBody != (Object)null) { grantInv = recipientBody.inventory; if ((Object)(object)grantInv != (Object)null) { equipmentBefore = grantInv.currentEquipmentState; grantItemIndex = val17.itemIndex; if ((int)grantItemIndex != -1) { gPermBefore = grantInv.GetItemCountPermanent(grantItemIndex); gTempBefore = grantInv.GetItemCountTemp(grantItemIndex); gChanBefore = grantInv.GetItemCountChanneled(grantItemIndex); } } } } catch { grantInv = null; } bool inAttemptGrant = _inAttemptGrant; PickupAttempt activePickupAttempt = _activePickupAttempt; PickupAttempt attempt = new PickupAttempt { Master = (((Object)(object)recipientBody != (Object)null) ? recipientBody.master : null), Pickup = grantedIndex }; _activePickupAttempt = attempt; _inAttemptGrant = true; try { orig.Invoke(self, recipientBody); } finally { _inAttemptGrant = inAttemptGrant; _activePickupAttempt = activePickupAttempt; } WrapHook("pickup_granted", delegate { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Invalid comparison between Unknown and I4 //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Invalid comparison between Unknown and I4 //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Invalid comparison between Unknown and I4 //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Invalid comparison between Unknown and I4 Interlocked.Increment(ref _diagPickupGrantedCount); if (((PickupIndex)(ref grantedIndex)).isValid && !((Object)(object)recipientBody == (Object)null)) { PickupDef pickupDef = PickupCatalog.GetPickupDef(grantedIndex); if (pickupDef != null) { bool flag2 = attempt.Notified || (!consumedBefore && ReadBoolField(_pickupConsumedField, self)); if (!flag2 && (Object)(object)grantInv != (Object)null) { if ((int)grantItemIndex != -1) { flag2 = grantInv.GetItemCountPermanent(grantItemIndex) > gPermBefore || grantInv.GetItemCountTemp(grantItemIndex) > gTempBefore || grantInv.GetItemCountChanneled(grantItemIndex) > gChanBefore; } else if ((int)pickupDef.equipmentIndex != -1) { EquipmentState currentEquipmentState = grantInv.currentEquipmentState; flag2 = !((EquipmentState)(ref currentEquipmentState)).Equals(equipmentBefore) && grantInv.currentEquipmentIndex == pickupDef.equipmentIndex; } } if (flag2) { CharacterBody obj20 = recipientBody; CharacterMaster master = ((obj20 != null) ? obj20.master : null); CharacterMaster obj21 = master; PlayerCharacterMasterController val18 = ((obj21 != null) ? obj21.playerCharacterMasterController : null); NetworkUser netUser = ((val18 != null) ? val18.networkUser : null); bool flag3 = false; string highlightReason = null; try { if ((int)pickupDef.itemIndex != -1) { ItemDef itemDef = ItemCatalog.GetItemDef(pickupDef.itemIndex); if ((Object)(object)itemDef != (Object)null && (int)itemDef.tier == 2) { flag3 = true; highlightReason = "legendary_pickup"; } } } catch { } EmitRunEvent("pickup_granted", flag3 ? "major" : "minor", delegate(Dictionary<string, object> payload) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) payload["source"] = "pickup"; payload["player"] = BuildPlayerBlock(recipientBody, master, netUser); payload["item"] = BuildGrantItemRef(pickupDef, 1, grantInv, grantItemIndex, gPermBefore, gTempBefore, gChanBefore); payload["timer"] = BuildTimerBlock(); payload["stage"] = BuildStageBlock(); if (highlightReason != null) { payload["highlight_reason"] = highlightReason; } string text = TryConsumeChestSourceId(grantedIndex); if (text != null) { payload["source_id"] = text; } }); } } } }); } }; <>c.<>9__108_1 = val; obj2 = (object)val; } GenericPickupController.AttemptGrant += (hook_AttemptGrant)obj2; object obj3 = <>c.<>9__108_2; if (obj3 == null) { hook_GiveItem_ItemIndex_int val2 = delegate(orig_GiveItem_ItemIndex_int orig, Inventory self, ItemIndex itemIndex, int count) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Invalid comparison between Unknown and I4 CharacterMaster giveMaster = null; PlayerCharacterMasterController givePcmc = null; if (_pluginAlive && !_inAttemptGrant && count > 0 && (int)itemIndex != -1 && (Object)(object)self != (Object)null) { try { giveMaster = ((Component)self).GetComponent<CharacterMaster>(); CharacterMaster obj18 = giveMaster; givePcmc = ((obj18 != null) ? obj18.playerCharacterMasterController : null); } catch { givePcmc = null; } } if ((Object)(object)givePcmc == (Object)null) { orig.Invoke(self, itemIndex, count); } else { int gPermBefore = 0; int gTempBefore = 0; int gChanBefore = 0; bool haveBefore = false; try { gPermBefore = self.GetItemCountPermanent(itemIndex)
plugins/Newtonsoft.Json.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
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 = _culture
plugins/websocket-sharp.dll
Decompiled a week ago
The result has been truncated due to the large size, download it to view full contents!
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,