Decompiled source of FFSPeak v0.9.1
plugins/com.github.flonou.FFSPeak.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.IO.Compression; using System.Linq; using System.Net.WebSockets; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using FFSPeak; using FFSPeak.CameraSystem; using FFSPeak.Items; using FFSPeak.Network; using FFSPeak.Patches; using FFSPeak.PlayerState; using FFSPeak.PlayerState.Mobs; using FFSPeak.Protocol.Protobuf; using FFSPeak.RemotePlayers; using FFSPeak.RemotePlayers.Mobs; using FFSPeak.UI; using FFSPeak.UI.AdminCommand; using FFSPeak.UI.AdminCommand.Buttons; using FFSPeak.UI.AdminConsole; using FFSPeak.UI.AdminMessage; using FFSPeak.UI.EventFeed; using FFSPeak.UI.Toolbox; using FFSPeak.Utils; using Google.Protobuf; using Google.Protobuf.Collections; using Google.Protobuf.Reflection; using HarmonyLib; using ItemSpawnSync; using ItemSpawnSync.Data; using ItemSpawnSync.Patches; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Newtonsoft.Json.Serialization; using PEAKLib.UI; using PEAKLib.UI.Elements; using Peak.Afflictions; using Photon.Pun; using Photon.Realtime; using Photon.Voice.PUN; using Photon.Voice.Unity; using TMPro; using Unity.Mathematics; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.SceneManagement; using UnityEngine.UI; using UnityEngine.UIElements; using Zorro.Core; using Zorro.Settings; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("com.github.flonou.FFSPeak")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("0.9.1.0")] [assembly: AssemblyInformationalVersion("0.9.1+6438b3476f6a99e558599112683b6378c6297ecf")] [assembly: AssemblyProduct("com.github.flonou.FFSPeak")] [assembly: AssemblyTitle("FFSPeak")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.9.1.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class RequiresLocationAttribute : Attribute { } [CompilerGenerated] [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] [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; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public class DisableItems { public static void Disable(List<string> itemsToDisable) { if (itemsToDisable.Count == 0) { Plugin.Logger.LogMessage((object)"No GameObjects configured to be disabled."); return; } int num = 0; foreach (string item in itemsToDisable) { Item[] array = FindItemsByName(item); Item[] array2 = array; foreach (Item val in array2) { ((Component)val).gameObject.SetActive(false); num++; Plugin.Logger.LogInfo((object)("Disabled GameObject: " + ((Object)val).name)); } } Plugin.Logger.LogMessage((object)$"Successfully disabled {num} GameObject(s)."); } public static void DisableBackpacksPhysics() { Item[] array = (Item[])(object)Object.FindObjectsByType<Backpack>((FindObjectsInactive)1, (FindObjectsSortMode)0); Item[] array2 = array; if (Plugin.IsObserver) { for (int i = 1; i < array2.Length; i++) { array2[0].rig.detectCollisions = false; array2[0].rig.isKinematic = true; } } } public static Item[] FindItemsByName(string name) { return (from obj in Resources.FindObjectsOfTypeAll<Item>() where ((Object)obj).name == name select obj).ToArray(); } public static void RunDisableLogic() { Plugin.Logger.LogMessage((object)"Running DisableItems logic"); Disable(new List<string> { "Guidebook(Clone)", "Frisbee(Clone)", "BingBong(Clone)", "Shell Big(Clone)", "Flare(Clone)", "Bugle(Clone)", "Compass(Clone)", "GuidebookPageScroll(Clone)", "GuidebookPageScroll Variant(Clone)", "Binoculars(Clone)" }); DisableBackpacksPhysics(); Object.FindObjectsByType<TornadoSpawner>((FindObjectsInactive)1, (FindObjectsSortMode)0).ToList().ForEach(delegate(TornadoSpawner val) { ((Component)val).gameObject.SetActive(false); }); List<string> source = new List<string> { "Dynamite" }; PropSpawner[] array = Object.FindObjectsByType<PropSpawner>((FindObjectsInactive)1, (FindObjectsSortMode)0); foreach (PropSpawner spawner in array) { if (source.Any((string name) => ((Object)spawner).name.StartsWith(name))) { ((Component)spawner).gameObject.SetActive(false); Plugin.Logger.LogInfo((object)("Disabled GameObject: " + ((Object)spawner).name)); } } _ = Plugin.IsObserver; } public static void DisableLavaRiversOutsideCaldera() { //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) Biome[] array = Object.FindObjectsByType<Biome>((FindObjectsInactive)0, (FindObjectsSortMode)0); foreach (Biome val in array) { if (!((Object)val).name.StartsWith("Volcano")) { continue; } for (int j = 0; j < ((Component)val).transform.childCount; j++) { Transform child = ((Component)val).transform.GetChild(j); if (!((Object)child).name.StartsWith("Caldera")) { continue; } foreach (Transform item in child) { Transform val2 = item; if (!((Object)val2).name.StartsWith("LavaRivers")) { continue; } foreach (Transform item2 in val2) { Transform val3 = item2; if (((Component)val3).transform.position.z > 1850f || ((Component)val3).transform.position.y > 1150f) { ((Component)val3).gameObject.SetActive(false); Plugin.Logger.LogMessage((object)("Disabled GameObject: " + ((Object)val3).name + " in biome " + ((Object)val).name)); } } Plugin.Logger.LogMessage((object)("Disabled GameObject: " + ((Object)val2).name + " in biome " + ((Object)val).name)); } } } } } [Serializable] public class ResumeDTO : BaseDTO { public new string LobbyCode; public FFSPeak.Network.PlayerStateDTO PlayerState; public PlayerCustomizationDTO Customization; public JToken Items; public ResumeDTO(string playerName, string lobbyCode, FFSPeak.Network.PlayerStateDTO playerState, PlayerCustomizationDTO customization, JToken items) { PlayerName = playerName; LobbyCode = lobbyCode; PlayerState = playerState; Customization = customization; Items = items; } } [DefaultExecutionOrder(99999)] public class RemotePlayerRope : MonoBehaviour { private RopeBoneVisualizer ropeBoneVisualizer; private RopeSyncDTO ropeSyncLast; public Rope Rope { get; set; } public void HandleRopeSync(RopeSyncDTO ropeSync) { ropeSyncLast = ropeSync; UpdateRopeFromSync(); } public void Initialize(Rope ropeComponent, RopeAnchor ropeAnchor, int segmentCount) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) Rope = ropeComponent; Rope.creatorLeft = false; Rope.Segments = segmentCount; Rope.attachmenState = (ATTACHMENT)2; ropeBoneVisualizer = ((Component)this).GetComponentInChildren<RopeBoneVisualizer>(); ropeBoneVisualizer.StartTransform = ((Component)ropeAnchor.anchorPoint).transform; RemotePlayer.ViewIsMineProperty.SetValue(((MonoBehaviourPun)Rope).photonView, false); } public void UpdateRopeFromSync() { //IL_001e: 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_002a: Unknown result type (might be due to invalid IL or missing references) if (ropeSyncLast == null) { Plugin.Logger.LogWarning((object)"UpdateRopeFromSync: ropeSyncLast is null"); return; } RopeSyncData syncData = ropeSyncLast.ToRopeSyncData(); Rope.SetSyncData(syncData); } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class BepInAutoPluginAttribute : Attribute { public BepInAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)] [Conditional("CodeGeneration")] internal sealed class PatcherAutoPluginAttribute : Attribute { public PatcherAutoPluginAttribute(string? id = null, string? name = null, string? version = null) { } } } namespace FFSPeak { public class CampfireManager : Singleton<CampfireManager> { private List<Campfire> campfireComponents = new List<Campfire>(); private List<Transform> campfires = new List<Transform>(); private string lastSentCheckpointHash; private GameObject newCampfire; public int GetCampfireIndex(Campfire campfire) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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_0071: Unknown result type (might be due to invalid IL or missing references) int num = campfireComponents.IndexOf(campfire); if (num >= 0) { return num; } Vector3 position = ((Component)campfire).transform.position; float num2 = float.MaxValue; int result = -1; for (int i = 0; i < campfires.Count; i++) { if (!((Object)(object)campfires[i] == (Object)null)) { Vector3 val = campfires[i].position - position; float num3 = val.y * val.y + val.z * val.z; if (num3 < num2) { num2 = num3; result = i; } } } if (num2 < 5f) { return result; } Plugin.Logger.LogWarning((object)("GetCampfireIndex: '" + ((Object)campfire).name + "' not found and no nearby campfire within threshold. Returning -1.")); return -1; } public IEnumerable<Transform> GetCampfires() { if (campfires.Count == 0 && (Object)(object)Singleton<MapHandler>.Instance != (Object)null) { UpdateCampfires(); } return campfires; } public void UpdateCampfires() { //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) campfires.Clear(); campfireComponents.Clear(); MapHandler val = Singleton<MapHandler>.Instance; foreach (MapSegment item in val.segments.Where((MapSegment s) => (Object)(object)s.segmentCampfire != (Object)null)) { Campfire componentInChildren = item.segmentCampfire.GetComponentInChildren<Campfire>(); campfires.Add(((Component)componentInChildren).transform); campfireComponents.Add(componentInChildren); } Campfire val2 = campfireComponents[0]; campfires.Insert(0, ((Component)SpawnPoint.allSpawnPoints[0]).transform); campfireComponents.Insert(0, null); GameObject val3 = GameObject.Find("Flag_planted_seagull"); if ((Object)(object)val3 != (Object)null) { if ((Object)(object)newCampfire == (Object)null) { newCampfire = PhotonCloneUtils.CloneWithPhoton(((Component)val2).gameObject, val3.transform); if ((Object)(object)newCampfire == (Object)null) { Plugin.Logger.LogWarning((object)"Failed to clone campfire with Photon"); return; } newCampfire.transform.localPosition = Vector3.zero; newCampfire.transform.localRotation = Quaternion.identity; } Campfire componentInChildren2 = newCampfire.GetComponentInChildren<Campfire>(); campfires.Add(((Component)componentInChildren2).transform); campfireComponents.Add(componentInChildren2); } else { campfires.Add(Singleton<MountainProgressHandler>.Instance.progressPoints.Last().transform); campfireComponents.Add(null); } Plugin.Logger.LogInfo((object)string.Format("Updated campfires: {0}. Total campfires: {1}", string.Join(", ", campfires.Select((Transform c) => ((Object)c).name)), campfires.Count)); SendCheckpointPositionsIfChanged(); } private void SendCheckpointPositionsIfChanged() { try { CheckpointPositionsDTO.CheckpointEntry[] array = campfires.Select((Transform t, int i) => new CheckpointPositionsDTO.CheckpointEntry { Index = i, Position = (((Object)(object)t != (Object)null) ? t.position : Vector3.zero) }).ToArray(); string text = string.Join("|", array.Select((CheckpointPositionsDTO.CheckpointEntry e) => $"{Mathf.RoundToInt(e.Position.x)},{Mathf.RoundToInt(e.Position.y)},{Mathf.RoundToInt(e.Position.z)}")).GetHashCode().ToString("X8"); if (!(text == lastSentCheckpointHash)) { lastSentCheckpointHash = text; CheckpointPositionsDTO dto = new CheckpointPositionsDTO { Checkpoints = array, Hash = text }; if (Plugin.IsPlayer) { PlayerNetworkManager.SendCheckpointPositions(dto); } if (Plugin.IsObserver) { NetworkManager.ObserverNetworkManager?.SendCheckpointPositions(dto); } Plugin.Logger.LogMessage((object)$"Sent {array.Length} checkpoint positions to server (hash: {text})"); } } catch (Exception ex) { Plugin.Logger.LogWarning((object)("Failed to send checkpoint positions: " + ex.Message)); } } } public class InputManager : Singleton<InputManager> { public static bool IsFrozen = false; public static bool InputsEnabled = true; public static bool PlayersInputsEnabled = true; public static bool ShouldBeInvincible; protected bool willFreeze; protected Dictionary<BodypartType, Vector3> originalBodypartPositions = new Dictionary<BodypartType, Vector3>(); public void Freeze() { IsFrozen = true; originalBodypartPositions.Clear(); willFreeze = true; DisableInputs(); } public void Unfreeze() { IsFrozen = false; willFreeze = false; originalBodypartPositions.Clear(); if ((Object)(object)Character.localCharacter != (Object)null && (Object)(object)Character.localCharacter.refs.ragdoll != (Object)null && Character.localCharacter.refs.ragdoll.rigidbodies != null) { Character.localCharacter.refs.ragdoll.ToggleKinematic(false); } EnableInputs(); } public void DisableInputs() { InputsEnabled = false; PlayersInputsEnabled = false; if (Plugin.IsPlayer) { ShouldBeInvincible = true; ((MonoBehaviour)this).StartCoroutine(EnableInvincibility()); } Singleton<InputDisabledUI>.Instance.Show(); Plugin.Logger.LogMessage((object)"Inputs Disabled"); } public void DisableInputsTemporarily(float duration) { DisableInputs(); ((MonoBehaviour)this).Invoke("EnableInputs", duration); } public void ToggleInvincibility(bool enabled) { if (Plugin.IsPlayer) { if (enabled) { ShouldBeInvincible = true; ((MonoBehaviour)this).StartCoroutine(EnableInvincibility()); } else { ShouldBeInvincible = false; ((MonoBehaviour)this).StopCoroutine(EnableInvincibility()); } } } public void EnableInputs() { InputsEnabled = true; PlayersInputsEnabled = true; ShouldBeInvincible = false; ((MonoBehaviour)this).StopCoroutine(EnableInvincibility()); Singleton<InputDisabledUI>.Instance.Hide(); Plugin.Logger.LogMessage((object)"Inputs Enabled"); } public static void FreezePlayers() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) Singleton<EventFeedUIManager>.Instance?.ShowMessage(new SimpleEventMessage("Freezing players!", Color.red, 2f)); NetworkManager.ObserverNetworkManager?.SendAdminCommand("broadcast_message", new BroadcastMessageDTO { Message = "Freezing players!", Color = "#FF0000", Lifetime = 2f }); Plugin.Logger.LogMessage((object)"Sending freeze command"); int value = Singleton<AdminCommandUIManager>.Instance.LoadedLevelIndex.Value; NetworkManager.ObserverNetworkManager?.SendAdminCommand("load_level", new LoadLevelDTO { LevelIndex = value, Freeze = true }); Singleton<AdminCommandUIManager>.Instance.PlayersFrozen = true; } public void SetAfflictions() { //IL_0038: 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) //IL_004e: Expected O, but got Unknown //IL_0077: 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_008d: Expected O, but got Unknown if (ShouldBeInvincible && FFSPeak.PlayerState.PlayerState.IsInitialized) { Affliction val = default(Affliction); if (!Character.localCharacter.refs.afflictions.HasAfflictionType((AfflictionType)16, ref val)) { Character.localCharacter.refs.afflictions.AddAffliction((Affliction)new Affliction_Invincibility { totalTime = 0.5f }, false); } if (!Character.localCharacter.refs.afflictions.HasAfflictionType((AfflictionType)21, ref val)) { Character.localCharacter.refs.afflictions.AddAffliction((Affliction)new Affliction_NoHunger { totalTime = 0.5f }, false); } } } public static IEnumerator UnfreezeCountdown() { for (int i = 5; i >= 1; i--) { string message = $"Unfreezing in {i}..."; Singleton<EventFeedUIManager>.Instance?.ShowMessage(new SimpleEventMessage(message, Color.yellow, 1f)); NetworkManager.ObserverNetworkManager?.SendAdminCommand("broadcast_message", new BroadcastMessageDTO { Message = message, Color = "#FFFF00", Lifetime = 1f }); Plugin.Logger.LogMessage((object)$"Countdown: {i}"); yield return (object)new WaitForSeconds(1f); } Singleton<EventFeedUIManager>.Instance?.ShowMessage(new SimpleEventMessage("Unfreezing players!", Color.green, 2f)); NetworkManager.ObserverNetworkManager?.SendAdminCommand("broadcast_message", new BroadcastMessageDTO { Message = "Unfreezing players!", Color = "#00FF00", Lifetime = 2f }); Plugin.Logger.LogMessage((object)"Sending unfreeze command"); int value = Singleton<AdminCommandUIManager>.Instance.LoadedLevelIndex.Value; NetworkManager.ObserverNetworkManager?.SendAdminCommand("load_level", new LoadLevelDTO { LevelIndex = value, Freeze = false }); Singleton<AdminCommandUIManager>.Instance.PlayersFrozen = false; } public void Update() { if (Plugin.IsPlayer && ShouldBeInvincible) { SetAfflictions(); } } public void FixedUpdate() { //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: 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_00ed: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.IsPlayer || !Plugin.IsOnMapScene || !IsFrozen || !(Time.timeSinceLevelLoad > 15f)) { return; } if (willFreeze) { Plugin.Logger.LogMessage((object)"Freezing player character"); if (!((Object)(object)Character.localCharacter != (Object)null) || !((Object)(object)Character.localCharacter.refs.ragdoll != (Object)null) || Character.localCharacter.refs.ragdoll.rigidbodies == null) { return; } Character.localCharacter.refs.ragdoll.ToggleKinematic(true); foreach (Bodypart part in Character.localCharacter.refs.ragdoll.partList) { if (!originalBodypartPositions.ContainsKey(part.partType)) { originalBodypartPositions[part.partType] = ((Component)part.rig).transform.position; } } willFreeze = false; return; } Character.localCharacter.refs.ragdoll.ToggleKinematic(true); foreach (Bodypart part2 in Character.localCharacter.refs.ragdoll.partList) { if (originalBodypartPositions.TryGetValue(part2.partType, out var value) && value != Vector3.zero) { ((Component)part2.rig).transform.position = value; } } } protected override void Initialize() { Plugin.Logger.LogMessage((object)"InputManager initialized"); } private IEnumerator EnableInvincibility() { ShouldBeInvincible = true; yield return (object)new WaitUntil((Func<bool>)(() => FFSPeak.PlayerState.PlayerState.IsInitialized)); SetAfflictions(); Plugin.Logger.LogMessage((object)"Invincibility Enabled"); } } [BepInProcess("PEAK.exe")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.github.flonou.FFSPeak", "FFSPeak", "0.9.1")] public class Plugin : BaseUnityPlugin { private ConfigEntry<bool> autoLoadItems; private ConfigEntry<bool> autoOpenLuggages; private readonly Harmony harmony = new Harmony("com.zerator.ffspeak"); private ConfigEntry<bool> isObserver; private ConfigEntry<bool> isPlayer; private ConfigEntry<bool> loadFromFile; private ConfigEntry<bool> saveSpawnDataToLocalFile; private ConfigEntry<string> lobbyCode; private string observerKey; private ConfigEntry<string> observerKeyFile; private ConfigEntry<string> serverUrl; private ConfigEntry<bool> autoOpenAdminConsole; private ConfigEntry<KeyboardShortcut> adminConsoleShortcut; private ConfigEntry<bool> scoreLoggingEnabled; private ConfigEntry<string> scoreLoggingFolderPath; private ConfigEntry<float> scoreLoggingInterval; public const string Id = "com.github.flonou.FFSPeak"; public static bool AutoOpenLuggages => Instance.autoOpenLuggages.Value; public static AssetBundle FfsPeakAssets { get; private set; } public static Plugin Instance { get; private set; } public static bool IsInLobby { get; private set; } = false; public static bool IsObserver => Instance.isObserver.Value; public static bool IsOnMapScene { get; private set; } = false; public static bool IsPlayer => Instance.isPlayer.Value; public static int? LevelToLoad { get; set; } = null; public static bool LoadingLevel { get; set; } = false; public static string LobbyCode { get; set; } = "000000"; public static int? LobbyPlayerLimit { get; set; } = null; public static bool ShouldLoadItems { get { if (Instance.autoLoadItems.Value) { return LoadItemsOnNextMapLoad; } return false; } } public static bool LoadItemsOnNextMapLoad { get; set; } = true; public static bool ScoreLoggingEnabled => Instance.scoreLoggingEnabled.Value; public static string ScoreLoggingFolderPath => Instance.scoreLoggingFolderPath.Value; public static float ScoreLoggingInterval => Instance.scoreLoggingInterval.Value; public static string LocalPlayerName { get; private set; } = "UnknownPlayer" + Guid.NewGuid().ToString().Substring(0, 10); public static ManualLogSource Logger { get; set; } public static bool MapSceneReady { get; set; } = false; public static string SceneName { get; private set; } = null; public static bool AutoOpenAdminConsole => Instance.autoOpenAdminConsole.Value; public string ServerUrl => serverUrl.Value; public static string Name => "FFSPeak"; public static string Version => "0.9.1"; public static event Action<string> LevelLoaded; private static string TryGetArgValue(string[] args, params string[] names) { if (args == null || args.Length == 0 || names == null || names.Length == 0) { return null; } for (int i = 0; i < args.Length; i++) { string text = args[i]; if (string.IsNullOrEmpty(text)) { continue; } foreach (string text2 in names) { if (!string.IsNullOrEmpty(text2)) { if (string.Equals(text, text2, StringComparison.OrdinalIgnoreCase) && i + 1 < args.Length) { return args[i + 1]; } string text3 = text2 + "="; if (text.StartsWith(text3, StringComparison.OrdinalIgnoreCase)) { return text.Substring(text3.Length); } } } } return null; } public static string GetMapName() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (SceneName != null) { return SceneName; } for (int i = 0; i < SceneManager.sceneCount; i++) { Scene sceneAt = SceneManager.GetSceneAt(i); if (((Scene)(ref sceneAt)).name.Contains("Level_")) { SceneName = ((Scene)(ref sceneAt)).name; return ((Scene)(ref sceneAt)).name; } } return null; } public static void HandleLoadLevel(int levelIndex = -1, int? playerLimit = 50) { Logger.LogMessage((object)$"Received load level command from server: levelIndex={levelIndex}, playerLimit={playerLimit}"); LevelToLoad = levelIndex; LobbyPlayerLimit = playerLimit; if (levelIndex < 0) { Logger.LogMessage((object)"Level load cleared by server"); LevelToLoad = null; } else if (IsInLobby && !LoadingLevel) { LoadingLevel = true; ((MonoBehaviour)Instance).StartCoroutine(AutoStartGameInAirport(levelIndex)); if (IsObserver) { Singleton<AdminCommandUIManager>.Instance.LoadedLevelIndex = levelIndex; } } } public static IEnumerator TryCapturePlayerName() { while (PhotonNetwork.LocalPlayer == null || string.IsNullOrEmpty(PhotonNetwork.LocalPlayer.NickName)) { yield return null; } try { LocalPlayerName = PhotonNetwork.LocalPlayer.NickName; if (IsObserver && !IsPlayer) { LocalPlayerName += "_Obs"; } Logger.LogMessage((object)("Captured player name from Photon: " + LocalPlayerName)); } catch (Exception ex) { Logger.LogWarning((object)("Error capturing player name: " + ex.Message)); } } public void Update() { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) if (Input.GetKeyDown((KeyCode)289)) { Singleton<FPSUI>.Instance.ToggleShow(); } if (!IsObserver) { return; } if (Input.GetKeyDown((KeyCode)284)) { Singleton<RemotePlayerAdministrationUIManager>.Instance.Toggle(); } if (Input.GetKeyDown((KeyCode)285)) { Singleton<RemoteMessageUIManager>.Instance.Toggle(); } if (Input.GetKeyDown((KeyCode)290)) { Singleton<LobbyManagerUIManager>.Instance.Toggle(); } if (Input.GetKeyDown((KeyCode)291)) { Singleton<AdminCommandUIManager>.Instance.ToggleDisplay(); } if (Input.GetKeyDown((KeyCode)292)) { Singleton<ToolboxUIManager>.Instance.ToggleDisplay(); } KeyboardShortcut value = adminConsoleShortcut.Value; if (Input.GetKeyDown(((KeyboardShortcut)(ref value)).MainKey)) { value = adminConsoleShortcut.Value; if (((KeyboardShortcut)(ref value)).Modifiers != null) { value = adminConsoleShortcut.Value; if (!((KeyboardShortcut)(ref value)).Modifiers.All((KeyCode m) => Input.GetKey(m))) { goto IL_0100; } } Singleton<AdminConsoleUIManager>.Instance.Toggle(); } goto IL_0100; IL_0100: if (Input.GetKeyDown((KeyCode)115) && Input.GetKey((KeyCode)306)) { scoreLoggingEnabled.Value = !scoreLoggingEnabled.Value; if (scoreLoggingEnabled.Value) { Singleton<ScoreLogger>.Instance.LogScores(); } } } protected void Awake() { //IL_0166: Unknown result type (might be due to invalid IL or missing references) Instance = this; Logger = ((BaseUnityPlugin)this).Logger; isObserver = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsObserver", false, "Should this instance act as an observer?"); isPlayer = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "IsPlayer", true, "Should this instance act as a player?"); serverUrl = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ServerUrl", "ws://localhost:4000", "The WebSocket server URL to connect to."); lobbyCode = ((BaseUnityPlugin)this).Config.Bind<string>("General", "LobbyCode", "000000", "Lobby code (6 chars A-Z0-9) used to isolate instances. Same code = same lobby."); autoLoadItems = ((BaseUnityPlugin)this).Config.Bind<bool>("Items", "AutoLoadItems", true, "Should automatically load items when joining a map?"); loadFromFile = ((BaseUnityPlugin)this).Config.Bind<bool>("Items", "LoadFromFile", true, "Load item data from files"); saveSpawnDataToLocalFile = ((BaseUnityPlugin)this).Config.Bind<bool>("Items", "SaveSpawnDataToLocalFile", true, "Save spawn data to local file when saving through the shortcut"); autoOpenLuggages = ((BaseUnityPlugin)this).Config.Bind<bool>("AdminCommands", "AutoOpenLuggages", false, "Automatically open all luggages for observers when a level is loaded (for easier spectating)"); autoOpenAdminConsole = ((BaseUnityPlugin)this).Config.Bind<bool>("AdminCommands", "AutoOpenAdminConsole", false, "Automatically open the admin console when the game starts"); adminConsoleShortcut = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("AdminCommands", "AdminConsoleShortcut", new KeyboardShortcut((KeyCode)282, (KeyCode[])(object)new KeyCode[1] { (KeyCode)306 }), "Keyboard shortcut to open the admin console"); scoreLoggingEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("ScoreLogging", "ScoreLoggingEnabled", false, "Enable score logging to a file"); scoreLoggingFolderPath = ((BaseUnityPlugin)this).Config.Bind<string>("ScoreLogging", "ScoreLoggingFolderPath", "Scores", "File path for score logging (relative to the peak application)"); scoreLoggingInterval = ((BaseUnityPlugin)this).Config.Bind<float>("ScoreLogging", "ScoreLoggingInterval", 5f, "Interval in seconds for logging scores to the file"); string[] commandLineArgs = Environment.GetCommandLineArgs(); if (commandLineArgs.Contains("-observer")) { isObserver.Value = true; isPlayer.Value = false; } if (commandLineArgs.Contains("-player")) { isPlayer.Value = true; isObserver.Value = false; } string text = TryGetArgValue(commandLineArgs, "-serverurl", "--server-url", "--serverurl", "-url", "--url"); if (!string.IsNullOrWhiteSpace(text)) { serverUrl.Value = text.Trim(); Logger.LogMessage((object)("Overriding server URL from command line: " + serverUrl.Value)); } string text2 = TryGetArgValue(commandLineArgs, "-port", "--port", "-wsport", "--ws-port", "--wsport"); if (!string.IsNullOrWhiteSpace(text2)) { if (int.TryParse(text2, NumberStyles.Integer, CultureInfo.InvariantCulture, out var result) && result > 0 && result <= 65535) { try { Uri uri = new Uri(serverUrl.Value); UriBuilder uriBuilder = new UriBuilder(uri) { Port = result }; serverUrl.Value = uriBuilder.Uri.ToString().TrimEnd('/'); Logger.LogMessage((object)$"Overriding server port from command line: {result} -> {serverUrl.Value}"); } catch (Exception ex) { Logger.LogWarning((object)("Could not apply command line port override '" + text2 + "' to server URL '" + serverUrl.Value + "': " + ex.Message)); } } else { Logger.LogWarning((object)("Ignoring invalid port value from command line: '" + text2 + "'")); } } Logger.LogMessage((object)("Plugin " + Name + " is loaded!")); Logger.LogMessage((object)$"Network Mode - Player: {IsPlayer}, Observer: {IsObserver}"); harmony.PatchAll(Assembly.GetExecutingAssembly()); ItemActionBase_RunAction_Patch.ApplyPatches(harmony); ModChecker.Check(); ((MonoBehaviour)this).StartCoroutine(AutoLoadItems.LoadItemsFromFiles()); SceneManager.sceneLoaded += OnSceneLoaded; SceneManager.sceneUnloaded += OnSceneUnloaded; LobbyCode = lobbyCode.Value; observerKeyFile = ((BaseUnityPlugin)this).Config.Bind<string>("General", "ObserverKeyFile", "observer_key.txt", "Filename for the observer key (relative to config/FFSPeak/)"); if (IsObserver) { string path = Path.Combine(Paths.ConfigPath, "FFSPeak"); string text3 = observerKeyFile.Value; if (!Path.IsPathRooted(text3)) { text3 = Path.Combine(path, text3); } if (File.Exists(text3)) { observerKey = File.ReadAllText(text3).Trim(); Logger.LogMessage((object)("Loaded observer key from " + text3)); } else { Logger.LogWarning((object)("Observer key file not found: " + text3)); } if (scoreLoggingEnabled.Value) { Singleton<ScoreLogger>.Instance.LogScores(); } } if (IsPlayer) { ModChecker.StartCheckAsync(); } if (IsObserver) { SpawnerSpawnItemsPatch.OnItemsSpawned += delegate(List<PhotonView> photonViews) { foreach (PhotonView photonView in photonViews) { Item component = ((Component)photonView).GetComponent<Item>(); if ((Object)(object)component.rig != (Object)null) { component.rig.isKinematic = true; ((Behaviour)component).enabled = false; Logger.LogInfo((object)("Set item " + ((Object)component).name + " to kinematic for observer and disabled item script.")); } } }; } string text4 = Path.Combine(Paths.PluginPath, "FFSPeak", "ffspeak_assets.bundle"); FfsPeakAssets = AssetBundle.LoadFromFile(text4); Logger.LogMessage((object)$"Loaded asset bundle with name [ffspeak_assets.bundle]: success={(Object)(object)FfsPeakAssets != (Object)null}"); string[] allAssetNames = FfsPeakAssets.GetAllAssetNames(); Logger.LogMessage((object)("Assets in bundle: " + string.Join(", ", allAssetNames))); if (saveSpawnDataToLocalFile.Value) { Plugin.Instance.OnSpawnDataSaved += delegate(string text6) { string text5 = Path.GetFileName(text6); if (text5.StartsWith("Level_")) { int num = text5.IndexOf('_', 6); if (num > 0) { text5 = text5.Substring(0, num) + ".json"; } } else { text5 = Path.GetFileNameWithoutExtension(text5) + ".json"; } string text7 = Path.Combine(Paths.ConfigPath, "FFSPeak", text5); File.Copy(text6, text7, overwrite: true); Logger.LogMessage((object)("Copied spawn data file to " + text7)); ((MonoBehaviour)this).StartCoroutine(AutoLoadItems.LoadItemsFromFiles()); }; } if ((Object)(object)RemoteMessageHandler.Instance == (Object)null) { ((Component)this).gameObject.AddComponent<RemoteMessageHandler>(); } } private static IEnumerator AutoStartGameInAirport(int levelIndex) { yield return null; try { Logger.LogMessage((object)$"Auto-starting game with level index: {levelIndex} with {LobbyPlayerLimit} player limit"); while (LoadingScreenHandler.loading) { yield return null; } AirportCheckInKiosk kiosk = null; while ((Object)(object)kiosk == (Object)null) { kiosk = Object.FindFirstObjectByType<AirportCheckInKiosk>(); if ((Object)(object)kiosk == (Object)null) { yield return null; } } yield return null; string level = SingletonAsset<MapBaker>.Instance.GetLevel((levelIndex >= 0) ? levelIndex : Ascents.currentAscent); RunSettings.Init(); byte[] serializedRunSettings = RunSettings.GetSerializedRunSettings(); Logger.LogMessage((object)("Starting game with level parameter: " + level)); ((MonoBehaviourPun)kiosk).photonView.RPC("BeginIslandLoadRPC", (RpcTarget)0, new object[3] { level, 0, serializedRunSettings }); } finally { LoadingLevel = false; } } public static void ReturnToAirport() { Logger.LogMessage((object)"Returning to airport..."); Player.LeaveCurrentGame(); } private IEnumerator InitializeNetworkManager() { NetworkConnector connector = null; while ((Object)(object)connector == (Object)null) { connector = Object.FindFirstObjectByType<NetworkConnector>(); if ((Object)(object)connector == (Object)null || !((Behaviour)connector).enabled) { connector = null; yield return null; } } yield return null; _ = Singleton<RemotePlayerManager>.Instance; NetworkManager.Initialize(new NetworkConfig { ServerUrl = ServerUrl, LobbyCode = LobbyCode, EnableNetworking = true, IsPlayer = IsPlayer, IsObserver = IsObserver, TimeoutMs = 5000, ObserverKey = observerKey }); if (IsObserver) { ObserverNetworkManager.WsClient.WsClient.RegisterServerMessageHandler("lobby_join_result", OnLobbyJoined); ObserverNetworkManager.WsClient.WsClient.RegisterServerMessageHandler("message", OnServerMessage); } if (IsPlayer) { PlayerNetworkManager.WsClient.WsClient.RegisterServerMessageHandler("lobby_join_result", OnLobbyJoined); PlayerNetworkManager.WsClient.WsClient.RegisterServerMessageHandler("message", OnServerMessage); } } private void OnServerMessage(ServerMessageDTO dTO) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) Logger.LogMessage((object)("Received server message: subtype=" + dTO.Subtype + ", data=" + dTO.Data)); Singleton<EventFeedUIManager>.Instance?.ShowMessage(new SimpleEventMessage("Server: " + dTO.Data, Color.cyan, 5f)); } private bool IsSceneLoaded(string nameContains) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < SceneManager.sceneCount; i++) { Scene sceneAt = SceneManager.GetSceneAt(i); if (((Scene)(ref sceneAt)).name.Contains(nameContains)) { return true; } } return false; } private IEnumerator MapSceneLoaded() { while ((Object)(object)RunManager.Instance == (Object)null || RunManager.Instance.timeSinceRunStarted <= 0f) { yield return null; } Singleton<CampfireManager>.Instance.UpdateCampfires(); Singleton<RemotePlayerManager>.Instance.Clear(); HeightBarsUIManager.Instance.Reinitialize(); if (IsObserver) { Singleton<PlayerListUIManager>.Instance.Clear(); Singleton<PlayerListUIManager>.Instance.SetDisplay(show: true); ((Behaviour)Singleton<PlayerListUIManager>.Instance).enabled = true; Singleton<LobbyManagerUIManager>.Instance.Hide(); Singleton<RemotePlayerAdministrationUIManager>.Instance.Hide(); } if (IsPlayer) { ModChecker.StartCheckAsync(); Singleton<JoinLobbyUI>.Instance.Hide(); yield return FFSPeak.PlayerState.PlayerState.AddPlayerStateToCharacter(); ((Component)Character.localCharacter).gameObject.AddComponent<MobStateSender>(); } if (IsPlayer && CheckpointTeleportUI.Enabled) { _ = Singleton<CheckpointTeleportUI>.Instance; Singleton<CheckpointTeleportUI>.Instance.Refresh(); } FFSPeak.PlayerState.PlayerState.EnableCapturePlayerState = true; Logger.LogMessage((object)"Player state capture enabled on scene load."); if (ShouldLoadItems) { Logger.LogMessage((object)("Auto-loading items for map " + GetMapName())); AutoLoadItems.LoadItems(GetMapName()); } DisableItems.RunDisableLogic(); MapSceneReady = true; if (IsPlayer) { PlayerLeftOrJoinedDTO joined = new PlayerLeftOrJoinedDTO { PlayerName = LocalPlayerName, LevelName = GetMapName(), Joined = true }; PlayerNetworkManager.SendPlayerLeftJoined(joined); } if (IsObserver) { Singleton<FreeCam>.Instance.HandleSceneLoaded(); Singleton<FreeCam>.Instance.HandleMapLoaded(); Singleton<LevelPlayerCountUIManager>.Instance.SetCurrentLevel(GetMapName()); Singleton<LevelPlayerCountUIManager>.Instance.UpdateDisplay(); _ = Singleton<ToolboxUIManager>.Instance; if (!NetworkManager.ObserverNetworkManager.IsConnected()) { NetworkManager.ObserverNetworkManager.Connect(); } Lava[] array = Object.FindObjectsByType<Lava>((FindObjectsInactive)1, (FindObjectsSortMode)0); Lava[] array2 = array; foreach (Lava val in array2) { FieldInfo field = typeof(Lava).GetField("bounds", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { Bounds val2 = (Bounds)field.GetValue(val); Logger.LogInfo((object)$"Lava bounds for {((Object)val).name}: center={((Bounds)(ref val2)).center}, size={((Bounds)(ref val2)).size}, extents={((Bounds)(ref val2)).extents}"); } } } Plugin.LevelLoaded?.Invoke(GetMapName()); } private void OnLobbyJoined(ServerMessageDTO dTO) { LobbyCode = dTO.Data; Logger.LogMessage((object)("Joined lobby: " + LobbyCode)); } private void OnSceneLoaded(Scene arg0, LoadSceneMode arg1) { Logger.LogInfo((object)("Loaded scene : [" + ((Scene)(ref arg0)).name + "]")); if (IsSceneLoaded("Title")) { Singleton<InputManager>.Instance.EnableInputs(); ModChecker.Check(); if (ModChecker.UnauthorizedMods.Count > 0) { Singleton<ForbiddenModUI>.Instance.Show(ModChecker.UnauthorizedMods); } if (IsOnMapScene) { if (IsPlayer) { PlayerLeftOrJoinedDTO joined = new PlayerLeftOrJoinedDTO { PlayerName = LocalPlayerName, LevelName = string.Empty, Joined = false }; PlayerNetworkManager.SendPlayerLeftJoined(joined); ModChecker.StopCheckAsync(); Logger.LogMessage((object)"Sent player left notification to server on returning to main menu."); } PlayerNetworkManager.SendJoinLobby(new JoinLobbyDTO("000000")); } if (IsObserver) { Singleton<PlayerListUIManager>.Instance.Clear(); Singleton<PlayerListUIManager>.Instance.SetDisplay(show: false); ((Behaviour)Singleton<PlayerListUIManager>.Instance).enabled = false; Singleton<LobbyManagerUIManager>.Instance.Hide(); Singleton<RemotePlayerAdministrationUIManager>.Instance.Hide(); } } if (IsSceneLoaded("Airport")) { Singleton<InputManager>.Instance.EnableInputs(); SceneName = null; ModChecker.Check(); if (ModChecker.UnauthorizedMods.Count > 0) { return; } IsInLobby = true; _ = Singleton<InputDisabledUI>.Instance; _ = Singleton<InputManager>.Instance; ((MonoBehaviour)this).StartCoroutine(TryCapturePlayerName()); ((MonoBehaviour)this).StartCoroutine(InitializeNetworkManager()); HeightBarsUIManager.Instance.Initialize(); VersionString val = Object.FindFirstObjectByType<VersionString>(); if ((Object)(object)val != (Object)null) { ((Behaviour)val).enabled = false; } Singleton<FreeCam>.Instance.HandleSceneLoaded(); if (IsObserver) { _ = Singleton<AdminCommandUIManager>.Instance; _ = Singleton<RemotePlayerAdministrationUIManager>.Instance; Singleton<LobbyManagerUIManager>.Instance.Show(); Singleton<FreeCam>.Instance.ToggleFreeCam(forceEnable: true); LoadItemsOnNextMapLoad = true; } else { Singleton<JoinLobbyUI>.Instance.Show(); } if (IsOnMapScene && IsObserver && NetworkManager.ObserverNetworkManager.IsConnected()) { NetworkManager.ObserverNetworkManager.Disconnect(); Logger.LogInfo((object)"Remote observer disabled on returning to lobby."); } } else { IsInLobby = false; } if (IsSceneLoaded("Level_")) { if (!IsOnMapScene) { IsOnMapScene = true; ((MonoBehaviour)this).StartCoroutine(MapSceneLoaded()); } } else { IsOnMapScene = false; LoadingLevel = false; } } private void OnSceneUnloaded(Scene arg0) { Logger.LogInfo((object)("Unloaded scene : [" + ((Scene)(ref arg0)).name + "]")); if (!IsSceneLoaded("Level_")) { MapSceneReady = false; IsOnMapScene = false; Singleton<InputDisabledUI>.Instance.Hide(); FFSPeak.PlayerState.PlayerState.EnableCapturePlayerState = false; Logger.LogInfo((object)"Player state capture disabled on scene unload."); } if (!IsSceneLoaded("Airport")) { IsInLobby = false; } } } public abstract class Singleton<T> : MonoBehaviour where T : Singleton<T> { private static bool applicationIsQuitting = false; private static T instance; private bool isInitialized; private static readonly object @lock = new object(); public static T Instance { get { //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown if (applicationIsQuitting) { return null; } lock (@lock) { if ((Object)(object)instance == (Object)null) { instance = Object.FindFirstObjectByType<T>(); if ((Object)(object)instance == (Object)null) { GameObject val = new GameObject(typeof(T).Name); instance = val.AddComponent<T>(); Object.DontDestroyOnLoad((Object)(object)val); if (!instance.isInitialized) { instance.Initialize(); instance.isInitialized = true; } } } return instance; } } } protected virtual void Awake() { if ((Object)(object)instance != (Object)null && (Object)(object)instance != (Object)(object)this) { Object.Destroy((Object)(object)((Component)this).gameObject); return; } instance = (T)this; Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); if ((Object)(object)instance == (Object)(object)this && !isInitialized) { Initialize(); isInitialized = true; } } protected virtual void Initialize() { } protected virtual void OnApplicationQuit() { applicationIsQuitting = true; } protected virtual void OnDestroy() { if ((Object)(object)instance == (Object)(object)this) { instance = null; } } } } namespace FFSPeak.Utils { public static class ModChecker { public static readonly HashSet<string> AuthorizedGuids = new HashSet<string> { "com.github.flonou.FFSPeak", "com.github.flonou.Peak-ItemSpawnSync", "com.github.PEAKModding.PEAKLib.UI", "com.github.PEAKModding.PEAKLib.Core", "com.github.PEAKModding.SoftDependencyFix", "com.snosz.photoncustompropsutils", "com.turtledsr.peakversionbypass", "toastoverflow.EpilepsySafePEAK", "Linkoid.Peak.StableCamera" }; public static readonly HashSet<string> ForbiddenExternalMods = new HashSet<string> { "WeMod", "Wand", "Cheat Engine" }; public static List<string> UnauthorizedExternalModsDetected = new List<string>(); private static bool checkThreadRunning = false; private static Thread checkThread; private static AutoResetEvent checkThreadStopEvent = new AutoResetEvent(initialState: false); public static IReadOnlyList<PluginInfo> UnauthorizedMods { get; private set; } = Array.Empty<PluginInfo>(); public static void Check() { Plugin.Logger.LogMessage((object)"Running mod check against allowlist..."); Plugin.Logger.LogMessage((object)("Plugins currently loaded: " + string.Join(", ", Chainloader.PluginInfos.Values.Select((PluginInfo p) => $"{p.Metadata.GUID} v{p.Metadata.Version}")))); UnauthorizedMods = Chainloader.PluginInfos.Values.Where((PluginInfo p) => !AuthorizedGuids.Contains(p.Metadata.GUID)).ToList(); if (UnauthorizedMods.Count > 0) { Plugin.Logger.LogWarning((object)("[ModChecker] Unauthorized mod(s) detected: " + string.Join(", ", UnauthorizedMods.Select((PluginInfo p) => $"{p.Metadata.GUID} v{p.Metadata.Version}")))); } else { Plugin.Logger.LogMessage((object)"[ModChecker] All loaded mods are authorized."); } } public static void StartCheckAsync() { if (!checkThreadRunning) { checkThreadRunning = true; checkThread = new Thread(CheckLoop) { IsBackground = true }; checkThread.Start(); } } public static void StopCheckAsync() { if (checkThreadRunning) { checkThreadRunning = false; checkThreadStopEvent.Set(); try { checkThread.Join(500); } catch { } checkThread = null; } } public static void CheckLoop() { while (checkThreadRunning) { foreach (string forbiddenExternalMod in ForbiddenExternalMods) { if (Process.GetProcessesByName(forbiddenExternalMod).Length != 0) { UnauthorizedModDTO unauthorizedMod = CreateUnauthorizedModDTO(forbiddenExternalMod); PlayerNetworkManager.SendUnauthorizedModDetected(unauthorizedMod); } } checkThreadStopEvent.WaitOne(30000); } } public static UnauthorizedModDTO CreateUnauthorizedModDTO(string modName) { return new UnauthorizedModDTO { PlayerName = Plugin.LocalPlayerName, ModName = modName, LevelName = Plugin.GetMapName() }; } } public class PhotonCloneUtils : MonoBehaviourPun { private static PhotonCloneUtils instance; public static PhotonCloneUtils Instance { get { if ((Object)(object)instance == (Object)null) { if ((Object)(object)GameUtils.instance == (Object)null) { Plugin.Logger.LogWarning((object)"PhotonCloneUtils requires GameUtils.instance to exist"); return null; } GameObject gameObject = ((Component)GameUtils.instance).gameObject; instance = gameObject.GetComponent<PhotonCloneUtils>(); if ((Object)(object)instance == (Object)null) { instance = gameObject.AddComponent<PhotonCloneUtils>(); } } return instance; } } public static GameObject CloneWithPhoton(GameObject source, Transform parent) { if ((Object)(object)source == (Object)null) { Plugin.Logger.LogWarning((object)"CloneWithPhoton called with null source"); return null; } if ((Object)(object)Instance == (Object)null) { return null; } if (!Instance.EnsurePhotonViewValid()) { Plugin.Logger.LogWarning((object)"CloneWithPhoton requires a valid PhotonView on GameUtils (join a room first)"); return null; } return Instance.CloneLocalAndRpc(source, parent); } private GameObject CloneLocalAndRpc(GameObject source, Transform parent) { //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) PhotonView component = source.GetComponent<PhotonView>(); if ((Object)(object)component == (Object)null) { Plugin.Logger.LogWarning((object)"CloneWithPhoton requires a PhotonView on the source object"); return null; } int viewID = component.ViewID; int num = 0; if ((Object)(object)parent != (Object)null) { PhotonView component2 = ((Component)parent).GetComponent<PhotonView>(); if ((Object)(object)component2 != (Object)null) { num = component2.ViewID; } } List<string> photonViewPaths = GetPhotonViewPaths(source.transform); if (photonViewPaths.Count == 0) { Plugin.Logger.LogWarning((object)"CloneWithPhoton found no PhotonViews in source hierarchy"); } int[] array = AllocateViewIds(photonViewPaths.Count); int[] array2 = AllocateViewIds(photonViewPaths.Count); if (!EnsurePhotonViewValid()) { Plugin.Logger.LogWarning((object)"CloneWithPhoton requires a valid PhotonView on GameUtils (join a room first)"); return null; } ((MonoBehaviourPun)this).photonView.RPC("RpcCloneWithPhoton", (RpcTarget)1, new object[7] { viewID, num, source.transform.position, source.transform.rotation, photonViewPaths.ToArray(), array, array2 }); return CloneLocal(source, parent, photonViewPaths, array, array2); } [PunRPC] private void RpcCloneWithPhoton(int sourceViewId, int parentViewId, Vector3 position, Quaternion rotation, string[] viewPaths, int[] originalIds, int[] cloneIds) { //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) PhotonView val = PhotonView.Find(sourceViewId); if ((Object)(object)val == (Object)null) { Plugin.Logger.LogWarning((object)$"RpcCloneWithPhoton: source PhotonView {sourceViewId} not found"); return; } Transform parent = null; if (parentViewId != 0) { PhotonView val2 = PhotonView.Find(parentViewId); if ((Object)(object)val2 != (Object)null) { parent = ((Component)val2).transform; } } CloneLocal(((Component)val).gameObject, parent, new List<string>(viewPaths), originalIds, cloneIds, position, rotation); } private static GameObject CloneLocal(GameObject source, Transform parent, List<string> viewPaths, int[] originalIds, int[] cloneIds, Vector3? positionOverride = null, Quaternion? rotationOverride = null) { //IL_0031: 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) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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_005b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } DisablePhotonViews(source.transform); Vector3 val = (Vector3)(((??)positionOverride) ?? source.transform.position); Quaternion val2 = (Quaternion)(((??)rotationOverride) ?? source.transform.rotation); GameObject val3 = Object.Instantiate<GameObject>(source, val, val2); if ((Object)(object)parent != (Object)null) { val3.transform.SetParent(parent, true); } RecreatePhotonViewsWithIds(source.transform, viewPaths, originalIds); RecreatePhotonViewsWithIds(val3.transform, viewPaths, cloneIds); return val3; } private static void DisablePhotonViews(Transform root) { PhotonView component = ((Component)root).GetComponent<PhotonView>(); if ((Object)(object)component != (Object)null) { Plugin.Logger.LogInfo((object)$"Disabling existing PhotonView on root '{((Object)((Component)root).gameObject).name}' with ViewID {component.ViewID}"); component.ViewID = 0; } PhotonView[] componentsInChildren = ((Component)root).GetComponentsInChildren<PhotonView>(true); foreach (PhotonView val in componentsInChildren) { Plugin.Logger.LogInfo((object)$"Disabling existing PhotonView on '{((Object)((Component)val).gameObject).name}' with ViewID {val.ViewID}"); val.ViewID = 0; } } private static List<string> GetPhotonViewPaths(Transform root) { PhotonView[] componentsInChildren = ((Component)root).GetComponentsInChildren<PhotonView>(true); List<string> list = new List<string>(componentsInChildren.Length); PhotonView[] array = componentsInChildren; foreach (PhotonView val in array) { list.Add(GetRelativePath(root, ((Component)val).transform)); } return list; } private static string GetRelativePath(Transform root, Transform target) { if ((Object)(object)root == (Object)(object)target) { return string.Empty; } List<string> list = new List<string>(); Transform val = target; while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)root) { list.Add(((Object)val).name); val = val.parent; } if ((Object)(object)val != (Object)(object)root) { return string.Empty; } list.Reverse(); return string.Join("/", list); } private static Transform FindByRelativePath(Transform root, string path) { if (string.IsNullOrEmpty(path)) { return root; } return root.Find(path); } private static void RecreatePhotonViewsWithIds(Transform root, List<string> viewPaths, int[] viewIds) { DisablePhotonViews(root); if (viewIds == null || viewPaths.Count != viewIds.Length) { Plugin.Logger.LogWarning((object)"RecreatePhotonViewsWithIds: invalid mapping payload"); return; } for (int i = 0; i < viewPaths.Count; i++) { Transform val = FindByRelativePath(root, viewPaths[i]); if ((Object)(object)val == (Object)null) { Plugin.Logger.LogWarning((object)("RecreatePhotonViewsWithIds: missing target transform for path '" + viewPaths[i] + "'")); continue; } if (viewIds[i] == 0) { Plugin.Logger.LogWarning((object)("RecreatePhotonViewsWithIds: invalid ViewID for path '" + viewPaths[i] + "'")); continue; } PhotonView component = ((Component)val).gameObject.GetComponent<PhotonView>(); component.ViewID = viewIds[i]; Plugin.Logger.LogInfo((object)$"Recreated PhotonView on '{((Object)val).name}' with ViewID {viewIds[i]} at path '{viewPaths[i]}'"); } } private static int[] AllocateViewIds(int count) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown int[] array = new int[count]; if (!PhotonNetwork.InRoom) { Plugin.Logger.LogWarning((object)"AllocateViewIds requires PhotonNetwork.InRoom"); return array; } for (int i = 0; i < count; i++) { GameObject val = new GameObject("PhotonViewIdAllocator"); PhotonView val2 = val.AddComponent<PhotonView>(); bool flag = PhotonNetwork.AllocateViewID(val2); array[i] = (flag ? val2.ViewID : 0); Object.DestroyImmediate((Object)(object)val); } return array; } private bool EnsurePhotonViewValid() { if ((Object)(object)((MonoBehaviourPun)this).photonView == (Object)null) { return false; } if (PhotonNetwork.InRoom) { return ((MonoBehaviourPun)this).photonView.ViewID != 0; } return false; } } public class ScoreLogger : Singleton<ScoreLogger> { private float lastLogTime; public void LogScores() { if (!Plugin.ScoreLoggingEnabled || !Plugin.IsOnMapScene || (Object)(object)Singleton<RemotePlayerManager>.Instance == (Object)null || Singleton<RemotePlayerManager>.Instance.GetAllPlayers().Count() == 0) { return; } string text = Path.Combine(Plugin.ScoreLoggingFolderPath, "FFSPeak"); Directory.CreateDirectory(text); string text2 = Path.Combine(text, $"Scores_{Plugin.GetMapName()}_{DateTime.Now:yyyy-MM-dd_HH-mm-ss}.csv"); using (StreamWriter streamWriter = new StreamWriter(text2)) { streamWriter.WriteLine("Time; Player Name; State; Last Checkpoint; Max Score; Current Score; Finish Time"); foreach (RemotePlayerData allPlayer in Singleton<RemotePlayerManager>.Instance.GetAllPlayers()) { string text3 = (allPlayer.IsFinished ? "Finished" : (allPlayer.IsDead ? "Dead" : "In Progress")); streamWriter.WriteLine($" {DateTime.Now}; {allPlayer.PlayerName}; {text3}; {allPlayer.LastCheckpoint}; {allPlayer.MaxHeight.ToString(CultureInfo.InvariantCulture)}; {allPlayer.CurrentHeight.ToString(CultureInfo.InvariantCulture)} ; {allPlayer.FinishTime.ToString(CultureInfo.InvariantCulture)}"); } } Plugin.Logger.LogMessage((object)("Scores logged to " + text2)); } public void Update() { if (Plugin.ScoreLoggingEnabled && Plugin.IsOnMapScene && Time.time - lastLogTime >= Plugin.ScoreLoggingInterval) { LogScores(); lastLogTime = Time.time; } } } } namespace FFSPeak.UI { public class CheckpointTeleportUI : Singleton<CheckpointTeleportUI> { public static bool Enabled = false; private const KeyCode TOGGLE_KEY = (KeyCode)290; private const float SPAWN_HEIGHT_OFFSET = 1.5f; private static readonly KeyCode[] NumpadKeys; private static readonly FieldInfo IsInvincibleField; private ManualLogSource logger; private GameObject uiRoot; private Transform rowContainer; private readonly List<GameObject> rows = new List<GameObject>(); private TextMeshProUGUI invincibilityStatusText; private bool _isInvincible; private readonly List<Transform> _checkpoints = new List<Transform>(); public bool IsVisible { get { if ((Object)(object)uiRoot != (Object)null) { return uiRoot.activeSelf; } return false; } } protected override void Initialize() { logger = Plugin.Logger; BuildUI(); logger.LogMessage((object)string.Format("{0} initialized (toggle: {1})", "CheckpointTeleportUI", (object)(KeyCode)290)); } public void Refresh() { if (Enabled) { RebuildRows(); } } private void Update() { if (!Enabled) { return; } if (Input.GetKeyDown((KeyCode)290)) { Toggle(); } if (!Input.GetKey((KeyCode)306) && !Input.GetKey((KeyCode)305)) { return; } if (Input.GetKeyDown((KeyCode)271)) { ToggleInvincible(); } else { if (_checkpoints.Count == 0) { return; } for (int i = 0; i < NumpadKeys.Length && i < _checkpoints.Count; i++) { if (Input.GetKeyDown(NumpadKeys[i])) { TeleportTo(_checkpoints[i]); break; } } } } public void Show() { if ((Object)(object)uiRoot != (Object)null) { uiRoot.SetActive(true); } } public void Hide() { if ((Object)(object)uiRoot != (Object)null) { uiRoot.SetActive(false); } } public void Toggle() { if (!((Object)(object)uiRoot == (Object)null)) { bool flag = !uiRoot.activeSelf; uiRoot.SetActive(flag); if (flag) { RebuildRows(); } } } private void TeleportTo(Transform target) { //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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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) //IL_0059: Unknown result type (might be due to invalid IL or missing references) Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null) { logger.LogWarning((object)"[CheckpointTeleportUI] Cannot teleport: localCharacter is null."); return; } Vector3 val = target.position + Vector3.up * 1.5f; localCharacter.WarpPlayerRPC(val, true); logger.LogMessage((object)string.Format("[{0}] Teleported to {1} → {2}", "CheckpointTeleportUI", ((Object)target).name, val)); } private void ToggleInvincible() { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || IsInvincibleField == null) { logger.LogWarning((object)"[CheckpointTeleportUI] Cannot toggle invincibility: localCharacter or field is null."); return; } _isInvincible = !_isInvincible; IsInvincibleField.SetValue(localCharacter.data, _isInvincible); UpdateInvincibilityLabel(); logger.LogMessage((object)string.Format("[{0}] Invincibility: {1}", "CheckpointTeleportUI", _isInvincible)); } private void UpdateInvincibilityLabel() { if (!((Object)(object)invincibilityStatusText == (Object)null)) { ((TMP_Text)invincibilityStatusText).text = (_isInvincible ? "<color=#AAAAAA>[Ctrl+NumEnter]</color> God mode <color=#44FF44>ON</color>" : "<color=#AAAAAA>[Ctrl+NumEnter]</color> God mode <color=#888888>OFF</color>"); } } private void BuildUI() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Expected O, but got Unknown //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Expected O, but got Unknown //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Expected O, but got Unknown //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Expected O, but got Unknown //IL_0303: Unknown result type (might be due to invalid IL or missing references) //IL_030a: Expected O, but got Unknown //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Expected O, but got Unknown //IL_03b2: Unknown result type (might be due to invalid IL or missing references) uiRoot = new GameObject("CheckpointTeleportUI"); uiRoot.transform.SetParent(((Component)this).transform, false); Canvas val = uiRoot.AddComponent<Canvas>(); val.renderMode = (RenderMode)0; val.sortingOrder = 200; CanvasScaler val2 = uiRoot.AddComponent<CanvasScaler>(); val2.uiScaleMode = (ScaleMode)1; val2.referenceResolution = new Vector2(1920f, 1080f); val2.matchWidthOrHeight = 0.5f; GameObject val3 = new GameObject("Panel"); val3.transform.SetParent(uiRoot.transform, false); RectTransform val4 = val3.AddComponent<RectTransform>(); val4.anchorMin = new Vector2(1f, 1f); val4.anchorMax = new Vector2(1f, 1f); val4.pivot = new Vector2(1f, 1f); val4.anchoredPosition = new Vector2(-20f, -20f); val4.sizeDelta = new Vector2(300f, 0f); Image val5 = val3.AddComponent<Image>(); ((Graphic)val5).color = new Color(0f, 0f, 0f, 0.82f); VerticalLayoutGroup val6 = val3.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)val6).padding = new RectOffset(8, 8, 6, 8); ((HorizontalOrVerticalLayoutGroup)val6).spacing = 4f; ((HorizontalOrVerticalLayoutGroup)val6).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val6).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val6).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val6).childForceExpandHeight = false; ContentSizeFitter val7 = val3.AddComponent<ContentSizeFitter>(); val7.verticalFit = (FitMode)2; GameObject val8 = new GameObject("Header"); val8.transform.SetParent(val3.transform, false); HorizontalLayoutGroup val9 = val8.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val9).spacing = 6f; ((LayoutGroup)val9).childAlignment = (TextAnchor)3; ((HorizontalOrVerticalLayoutGroup)val9).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val9).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val9).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)val9).childForceExpandHeight = false; LayoutElement val10 = val8.AddComponent<LayoutElement>(); val10.preferredHeight = 22f; GameObject val11 = new GameObject("Title"); val11.transform.SetParent(val8.transform, false); LayoutElement val12 = val11.AddComponent<LayoutElement>(); val12.flexibleWidth = 1f; TextMeshProUGUI val13 = val11.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val13).text = $"=> Checkpoints [{(object)(KeyCode)290}]"; ((TMP_Text)val13).fontSize = 13f; ((TMP_Text)val13).fontStyle = (FontStyles)1; ((Graphic)val13).color = new Color(0.95f, 0.85f, 0.3f, 1f); ((Graphic)val13).raycastTarget = false; GameObject val14 = new GameObject("Rows"); val14.transform.SetParent(val3.transform, false); VerticalLayoutGroup val15 = val14.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val15).spacing = 3f; ((HorizontalOrVerticalLayoutGroup)val15).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val15).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val15).childForceExpandWidth = true; ((HorizontalOrVerticalLayoutGroup)val15).childForceExpandHeight = false; ContentSizeFitter val16 = val14.AddComponent<ContentSizeFitter>(); val16.verticalFit = (FitMode)2; rowContainer = val14.transform; GameObject val17 = new GameObject("Divider"); val17.transform.SetParent(val3.transform, false); LayoutElement val18 = val17.AddComponent<LayoutElement>(); val18.preferredHeight = 1f; Image val19 = val17.AddComponent<Image>(); ((Graphic)val19).color = new Color(0.5f, 0.5f, 0.5f, 0.4f); GameObject val20 = new GameObject("InvincibilityRow"); val20.transform.SetParent(val3.transform, false); LayoutElement val21 = val20.AddComponent<LayoutElement>(); val21.preferredHeight = 20f; invincibilityStatusText = val20.AddComponent<TextMeshProUGUI>(); ((TMP_Text)invincibilityStatusText).fontSize = 11f; ((Graphic)invincibilityStatusText).color = Color.white; ((Graphic)invincibilityStatusText).raycastTarget = false; UpdateInvincibilityLabel(); uiRoot.SetActive(false); Plugin.Logger.LogMessage((object)"[CheckpointTeleportUI] UI built"); } private void RebuildRows() { foreach (GameObject row in rows) { Object.Destroy((Object)(object)row); } rows.Clear(); _checkpoints.Clear(); if ((Object)(object)Singleton<CampfireManager>.Instance == (Object)null) { return; } Singleton<CampfireManager>.Instance.UpdateCampfires(); int num = 0; foreach (Transform campfire in Singleton<CampfireManager>.Instance.GetCampfires()) { if ((Object)(object)campfire == (Object)null) { num++; continue; } _checkpoints.Add(campfire); string labelText = BuildLabel(num, campfire); GameObject val = MakeRow(labelText); val.transform.SetParent(rowContainer, false); rows.Add(val); num++; } } private static string BuildLabel(int index, Transform cp) { string text = ((index == 0) ? "Spawn" : $"Camp {index}"); string text2 = ((index < NumpadKeys.Length) ? $"<color=#AAAAAA>[Ctrl+Num{index}]</color>" : ""); return text2 + " " + text + " <size=9><color=#666666>" + ((Object)cp).name + "</color></size>"; } private GameObject MakeRow(string labelText) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Row"); LayoutElement val2 = val.AddComponent<LayoutElement>(); val2.preferredHeight = 20f; RectTransform val3 = val.AddComponent<RectTransform>(); TextMeshProUGUI val4 = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val4).text = labelText; ((TMP_Text)val4).fontSize = 11f; ((Graphic)val4).color = Color.white; ((Graphic)val4).raycastTarget = false; ((TMP_Text)val4).overflowMode = (TextOverflowModes)1; return val; } static CheckpointTeleportUI() { KeyCode[] array = new KeyCode[10]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); NumpadKeys = (KeyCode[])(object)array; IsInvincibleField = typeof(CharacterData).GetField("isInvincible", BindingFlags.Instance | BindingFlags.NonPublic); } } public class ForbiddenModUI : Singleton<ForbiddenModUI> { private GameObject uiContainer; private TextMeshProUGUI modListText; public void Show(IReadOnlyList<PluginInfo> unauthorizedMods) { if ((Object)(object)modListText != (Object)null) { ((TMP_Text)modListText).text = string.Join("\n", unauthorizedMods.Select((PluginInfo p) => $"{p.Metadata.GUID} v{p.Metadata.Version}")); } GameObject obj = uiContainer; if (obj != null) { obj.SetActive(true); } } public void Show(IReadOnlyList<string> forbiddenMods) { if ((Object)(object)modListText != (Object)null) { ((TMP_Text)modListText).text = string.Join("\n", forbiddenMods); } GameObject obj = uiContainer; if (obj != null) { obj.SetActive(true); } } public void Hide() { GameObject obj = uiContainer; if (obj != null) { obj.SetActive(false); } } protected override void Initialize() { try { BuildUI(); Hide(); Plugin.Logger.LogMessage((object)"ForbiddenModUI initialized."); } catch (Exception ex) { Plugin.Logger.LogError((object)("[ForbiddenModUI] Init error: " + ex.Message + "\n" + ex.StackTrace)); } } private void BuildUI() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Expected O, but got Unknown //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) uiContainer = new GameObject("ForbiddenModUI"); uiContainer.transform.SetParent(((Component)this).transform, false); Canvas val = uiContainer.AddComponent<Canvas>(); val.renderMode = (RenderMode)0; val.sortingOrder = 600; CanvasScaler val2 = uiContainer.AddComponent<CanvasScaler>(); val2.uiScaleMode = (ScaleMode)1; val2.referenceResolution = new Vector2(1920f, 1080f); GameObject val3 = new GameObject("Panel"); val3.transform.SetParent(uiContainer.transform, false); RectTransform val4 = val3.AddComponent<RectTransform>(); val4.anchorMin = new Vector2(0.5f, 0.5f); val4.anchorMax = new Vector2(0.5f, 0.5f); val4.pivot = new Vector2(0.5f, 0.5f); val4.anchoredPosition = Vector2.zero; val4.sizeDelta = new Vector2(900f, 240f); Image val5 = val3.AddComponent<Image>(); ((Graphic)val5).color = new Color(0.1f, 0f, 0f, 0.88f); PeakText val6 = MenuAPI.CreateText("⚠ FORBIDDEN MOD(S) DETECTED ⚠"); ((TMP_Text)val6.TextMesh).emojiFallbackSupport = true; ((Component)val6).transform.SetParent(val3.transform, false); val6.SetColor(Color.red); val6.SetFontSize(28f); RectTransform component = ((Component)val6).GetComponent<RectTransform>(); component.anchorMin = new Vector2(0f, 1f); component.anchorMax = new Vector2(1f, 1f); component.pivot = new Vector2(0.5f, 1f); component.anchoredPosition = new Vector2(0f, -12f); component.sizeDelta = new Vector2(0f, 40f); GameObject val7 = new GameObject("ModList"); val7.transform.SetParent(val3.transform, false); RectTransform val8 = val7.AddComponent<RectTransform>(); val8.anchorMin = new Vector2(0.05f, 0.05f); val8.anchorMax = new Vector2(0.95f, 0.65f); val8.offsetMin = Vector2.zero; val8.offsetMax = Vector2.zero; modListText = val7.AddComponent<TextMeshProUGUI>(); ((TMP_Text)modListText).fontSize = 18f; ((Graphic)modListText).color = new Color(1f, 0.6f, 0.6f); ((TMP_Text)modListText).alignment = (TextAlignmentOptions)514; } } public class FPSUI : Singleton<FPSUI> { private float deltaTime; private TextMeshProUGUI fpsText; private float timeSinceLastUpdate; private GameObject uiContainer; private float updateInterval = 0.5f; public void Hide() { GameObject obj = uiContainer; if (obj != null) { obj.SetActive(false); } ((Behaviour)this).enabled = false; } public void Show() { GameObject obj = uiContainer; if (obj != null) { obj.SetActive(true); } ((Behaviour)this).enabled = true; } public void Show(bool state) { GameObject obj = uiContainer; if (obj != null) { obj.SetActive(state); } ((Behaviour)this).enabled = state; } public void ToggleShow() { Show(!((Behaviour)this).enabled); } protected override void Initialize() { CreateUI(); Plugin.Logger.LogMessage((object)"FPSUI initialized"); Hide(); } protected void Update() { deltaTime += (Time.unscaledDeltaTime - deltaTime) * 0.1f; timeSinceLastUpdate += Time.unscaledDeltaTime; if (timeSinceLastUpdate >= updateInterval) { float fps = 1f / deltaTime; UpdateFPSDisplay(fps); timeSinceLastUpdate = 0f; } } private void CreateUI() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_0079: 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_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) uiContainer = new GameObject("FPSUI"); uiContainer.transform.SetParent(((Component)this).transform, false); Canvas val = uiContainer.AddComponent<Canvas>(); val.renderMode = (RenderMode)0; val.sortingOrder = 1000; GameObject val2 = new GameObject("FPSText"); val2.transform.SetParent(uiContainer.transform, false); RectTransform val3 = val2.AddComponent<RectTransform>(); val3.anchorMin = new Vector2(0f, 1f); val3.anchorMax = new Vector2(0f, 1f); val3.pivot = new Vector2(0f, 1f); val3.anchoredPosition = new Vector2(10f, -10f); val3.sizeDelta = new Vector2(150f, 40f); fpsText = val2.AddComponent<TextMeshProUGUI>(); ((TMP_Text)fpsText).fontSize = 24f; ((TMP_Text)fpsText).fontStyle = (FontStyles)1; ((TMP_Text)fpsText).alignment = (TextAlignmentOptions)257; ((TMP_Text)fpsText).text = "FPS: --"; ((Graphic)fpsText).color = Color.white; ((TMP_Text)fpsText).outlineWidth = 0.2f; ((TMP_Text)fpsText).outlineColor = Color32.op_Implicit(Color.black); } private void UpdateFPSDisplay(float fps) { //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)fpsText != (Object)null) { float num = Mathf.Ceil(fps); ((TMP_Text)fpsText).text = $"FPS: {num}"; ((Graphic)fpsText).color = ((num >= 60f) ? new Color(0.3f, 1f, 0.3f) : ((num >= 30f) ? new Color(1f, 1f, 0.3f) : new Color(1f, 0.3f, 0.3f))); } } } public class HeightBarsUI : MonoBehaviour { public enum MarkerShape { Circle, Triangle } public Color barBorderColor = new Color(0.3f, 0.6f, 1f, 0.9f); public Color barBottomColor = new Color(0.1f, 0.2f, 0.4f, 0.8f); public Color barTopColor = new Color(0.2f, 0.4f, 0.8f, 0.8f); public Color markerColor = new Color(0.2f, 0.8f, 1f, 0.9f); public Color markerOutlineColor = new Color(1f, 1f, 1f, 1f); public MarkerShape markerShape; private ManualLogSource _logger; private RectTransform barBackground; private Transform labelsContainer; private GameObject markerPrefab; private Transform markersContainer; private float maxHeightScale = 400f; private Dictionary<string, PlayerHeightBar> playerMarkers = new Dictionary<string, PlayerHeightBar>(); private Transform scaleLabelsContainer; private float maxDisplayHeight; private float minDisplayHeight; private float heightRange; private GameObject timerObj; private TextMeshProUGUI timerLabel; private float currentTimeLimit = -1f; private bool isExpanded; private Image barBgImage; private Sprite bar1DSprite; private Sprite bar2DSprite; private float minDisplayX; private float maxDisplayX; private float xRange; private Transform xAxisLabelsContainer; private Transform scaleLabels2DContainer; private TextMeshProUGUI modeHintLabel; private PlayerHeightBar currentSelectedPlayerMarker; private List<float> heights; private List<PlayerHeightBar> _sortedMarkers = new List<PlayerHeightBar>(); private static readonly Comparison<PlayerHeightBar> _heightAscending = (PlayerHeightBar a, PlayerHeightBar b) => a.GetCurrentHeight().CompareTo(b.GetCurrentHeight()); private int cachedMinZone = -1; private int cachedMaxZone = -1; public bool IsExpanded => isExpanded; public void ClearAllBars() { foreach (PlayerHeightBar value in playerMarkers.Values) { if ((Object)(object)value != (Object)null) { Object.Destroy((Object)(object)((Component)value).gameObject); } } playerMarkers.Clear(); } public void Initialize(ManualLogSource logger) { _logger = logger; CreateUI(); } public void RegenerateScaleLabels(IEnumerable<Transform> heightObjects) { if ((Object)(object)labelsContainer == (Object)null) { _logger.LogWarning((object)"Cannot regenerate scale labels - bar not initialized"); return; } CreateScaleLabels(heightObjects); _logger.LogMessage((object)$"Regenerated scale labels from {heightObjects.Count()} objects"); } public void RemovePlayer(string playerName) { if (playerMarkers.ContainsKey(playerName)) { Object.Destroy((Object)(object)((Component)playerMarkers[playerName]).gameObject); playerMarkers.Remove(playerName); } } public void UpdateTimer(float remainingTime) { //IL_0093: Unknown result type (might be due to invalid IL or missing references) currentTimeLimit = Mathf.Max(0f, remainingTime); if (!((Object)(object)timerLabel != (Object)null)) { return; } if (currentTimeLimit < 0f || !Plugin.IsOnMapScene) { timerObj.SetActive(false); return; } TimeSpan timeSpan = TimeSpan.FromSeconds(currentTimeLimit); if (Plugin.IsPlayer) { float num = (((Object)(object)FFSPeak.PlayerState.PlayerState.PlayerCharacter != (Object)null && FFSPeak.PlayerState.PlayerState.CurrentPlayerState != null) ? RemotePlayerData.GetCurrentHeight(FFSPeak.PlayerState.PlayerState.PlayerCharacter.data.dead, FFSPeak.PlayerState.PlayerState.CurrentPlayerState.IsFinished, FFSPeak.PlayerState.PlayerState.CurrentPlayerState.Position, FFSPeak.PlayerState.PlayerState.CurrentPlayerState.LastCheckpoint) : 0f); ((TMP_Text)timerLabel).text = $"Time: {timeSpan.Hours:D2}:{timeSpan.Minutes:D2}:{timeSpan.Seconds:D2} - Score: {num:F1}"; } else { ((TMP_Text)timerLabel).text = $"Time: {timeSpan.Hours:D2}:{timeSpan.Minutes:D2}:{timeSpan.Seconds:D2}"; } if (!timerObj.activeSelf) { timerObj.SetActive(true); } } public void UpdatePlayer(RemotePlayerData playerData) { if (!playerMarkers.TryGetValue(playerData.PlayerName, out var value)) { if ((Object)(object)markerPrefab == (Object)null) { markerPrefab = CreateMarkerPrefab(); } GameObject val = Object.Instantiate<GameObject>(markerPrefab, markersContainer); value = val.GetComponent<PlayerHeightBar>(); value.Initialize(playerData); playerMarkers[playerData.PlayerName] = value; _logger.LogMessage((object)("Created marker for " + playerData.PlayerName)); } value.UpdateData(); } private void LateUpdate() { UpdateVisibleZoneRange(); UpdateMarkerPositions(); UpdateTimer(currentTimeLimit - Time.deltaTime); } private GameObject CreateMarkerPrefab() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_006b: 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_0095: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Expected O, but got Unknown //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_016c: 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_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Expected O, but got Unknown //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("PlayerMarker"); RectTransform val2 = val.AddComponent<RectTransform>(); val2.sizeDelta = new Vector2(200f, 30f); GameObject val3 = new GameObject("Background"); val3.transform.SetParent(val.transform, false); RectTransform val4 = val3.AddComponent<RectTransform>(); val4.anchorMin = new Vector2(0f, 0.5f); val4.anchorMax = new Vector2(0f, 0.5f); val4.pivot = new Vector2(0f, 0.5f); val4.anchoredPosition = new Vector2(-12f, 0f); val4.sizeDelta = new Vector2(32f, 32f); Image val5 = val3.AddComponent<Image>(); Texture2D val6 = GenerateMarkerTexture(32, markerShape); Sprite sprite = Sprite.Create(val6, new Rect(0f, 0f, (float)((Texture)val6).width, (float)((Texture)val6).height), new Vector2(0.5f, 0.5f)); val5.sprite = sprite; GameObject val7 = new GameObject("Checkpoint"); val7.transform.SetParent(val.transform, false); RectTransform val8 = val7.AddComponent<RectTransform>(); val8.anchorMin = new Vector2(0f, 0.5f); val8.anchorMax = new Vector2(0f, 0.5f); val8.pivot = new Vector2(0f, 0.5f); val8.anchoredPosition = new Vector2(0f, 0f); val8.sizeDelta = new Vector2(40f, 10f); TextMeshProUGUI val9 = val7.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val9).alignment = (TextAlignmentOptions)513; ((TMP_Text)val9).fontSize = 14f; ((Graphic)val9).color = Color.white; GameObject val10 = new GameObject("PlayerName"); val10.transform.SetParent(val.transform, false); RectTransform val11 = val10.AddComponent<RectTransform>(); val11.anchorMin = new Vector2(0f, 0.5f); val11.anchorMax = new Vector2(0f, 0.5f); val11.pivot = new Vector2(0f, 0.5f); val11.anchoredPosition = new Vector2(22f, 0f); val11.sizeDelta = new Vector2(200f, 0f); TextMeshProUGUI val12 = val10.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val12).alignment = (TextAlignmentOptions)513; ((TMP_Text)val12).fontSize = 14f; ((Graphic)val12).color = Color.white; ((TMP_Text)val12).fontStyle = (FontStyles)1; PlayerHeightBar playerHeightBar = val.AddComponent<PlayerHeightBar>(); playerHeightBar.playerNameText = val12; playerHeightBar.checkpointText = val9; playerHeightBar.markerImage = val5; return val; } private void CreateScaleLabels(IEnumerable<Transform> heightObjects) { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0065: 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_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_0083: Unknown result type (might be due to invalid IL or missing references) heights = new List<float>(); List<Transform> list = heightObjects.ToList(); float num = 0f; heights.Add(0f); for (int i = 1; i < list.Count; i++) { if ((Object)(object)list[i] != (Object)null && (Object)(object)list[i - 1] != (Object)null) { Vector3 position = list[i - 1].position; Vector3 position2 = list[i].position; float num2 = position2.y - position.y; float num3 = position2.z - position.z; num += Mathf.Sqrt(num2 * num2 + num3 * num3) * CharacterStats.unitsToMeters; } heights.Add(num); } if (heights.Count == 0) { heights.Add(0f); } minDisplayHeight = 0f; maxDisplayHeight = ((heights.Count > 0) ? heights.Max() : maxHeightScale); if (maxDisplayHeight < 1f) { maxDisplayHeight = maxHeightScale; } heightRange = maxDisplayHeight - minDisplayHeight; minDisplayX = -250f; maxDisplayX = 250f; xRange = maxDisplayX - minDisplayX; cachedMinZone = 0; cachedMaxZone = Mathf.Max(0, heights.Count - 2); RebuildScaleLabelDisplay(cachedMinZone, cachedMaxZone); Create2DYAxisLabels(); } private int GetZoneIndex(float height) { if (heights == null || heights.Count < 2) { return 0; } for (int num = heights.Count - 2; num >= 0; num--) { if (height >= heights[num]) { return num; } } return 0; } private (int minZone, int maxZone) ComputeVisibleZoneRange() { int item = Mathf.Max(0, (heights?.Count ?? 1) - 2); if (heights == null || heights.Count < 2 || playerMarkers.Count == 0) { return (minZone: 0, maxZone: item); } int num = int.MaxValue; int num2 = int.MinValue; foreach (PlayerHeightBar value in playerMarkers.Values) { int zoneIndex = GetZoneIndex(value.GetCurrentHeight()); if (zoneIndex < num) { num = zoneIndex; } if (zoneIndex > num2) { num2 = zoneIndex; } } if (num == int.MaxValue) { return (minZone: 0, maxZone: item); } return (minZone: num, maxZone: num2); } private void UpdateVisibleZoneRange() { if (heights != null && heights.Count >= 2) { var (num, num2) = ComputeVisibleZoneRange(); if (num != cachedMinZone || num2 != cachedMaxZone) { cachedMinZone = num; cachedMaxZone = num2; minDisplayHeight = heights[num]; maxDisplayHeight = heights[Mathf.Min(num2 + 1, heights.Count - 1)]; heightRange = Mathf.Max(0.01f, maxDisplayHeight - minDisplayHeight); RebuildScaleLabelDisplay(num, num2); Create2DYAxisLabels(); } } } private void RebuildScaleLabelDisplay(int visibleMinZone, int visibleMaxZone) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)labelsContainer == (Object)null) { return; } if ((Object)(object)scaleLabelsContainer != (Object)null) { Object.Destroy((Object)(object)((Component)scaleLabelsContainer).gameObject); } bool expanded = isExpanded; SetExpanded(expanded: false); GameObject val = new GameObject("ScaleLabels"); val.transform.SetParent(labelsContainer, false); RectTransform val2 = val.AddComponent<RectTransform>(); val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; scaleLabelsContainer = val.transform; if (heights != null && heights.Count != 0) { int num = Mathf.Clamp(visibleMinZone, 0, heights.Count - 1); int num2 = Mathf.Clamp(visibleMaxZone + 1, 0, heights.Count - 1); for (int i = num; i <= num2; i++) { float num3 = heights[i]; float num4 = ((heightRange > 0f) ? ((num3 - minDisplayHeight) / heightRange) : 0f); GameObject val3 = new GameObject($"Scale_{num3:F1}m"); val3.transform.SetParent(scaleLabelsContainer, false); RectTransform val4 = val3.AddComponent<RectTransform>(); val4.anchorMin = new Vector2(0f, num4); val4.anchorMax = new Vector2(1f, num4); val4.pivot = new Vector2(0.5f, 0.5f); val4.anchoredPosition = new Vector2(-40f, 0f); val4.sizeDelta = new Vector2(60f, 20f); TextMeshProUGUI val5 = val3.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val5).text = $"{num3:F0}m - {i}"; ((TMP_Text)val5).fontSize = 12f; ((Graphic)val5).color = Color.gray; ((TMP_Text)val5).alignment = (TextAlignmentOptions)514; } SetExpanded(expanded); } } private void CreateUI() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_008d: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Expected O, but got Unknown //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_0265: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Expected O, but got Unknown //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02ca: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Expected O, but got Unknown //IL_02ef: Unknown result type (might be due to invalid IL or missing references) //IL_02fb: Unknown result type (might be due to invalid IL or missing references) //IL_0307: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Expected O, but got Unknown //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0374: Unknown result type (might be due to invalid IL or missing references) //IL_038a: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) //IL_03ac: Unknown res
plugins/Google.Protobuf.dll
Decompiled 3 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Buffers; using System.Buffers.Binary; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; 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 Google.Protobuf.Collections; using Google.Protobuf.Reflection; using Google.Protobuf.WellKnownTypes; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AllowPartiallyTrustedCallers] [assembly: InternalsVisibleTo("Google.Protobuf.Test, PublicKey=002400000480000094000000060200000024000052534131000400000100010025800fbcfc63a17c66b303aae80b03a6beaa176bb6bef883be436f2a1579edd80ce23edf151a1f4ced97af83abcd981207041fd5b2da3b498346fcfcd94910d52f25537c4a43ce3fbe17dc7d43e6cbdb4d8f1242dcb6bd9b5906be74da8daa7d7280f97130f318a16c07baf118839b156299a48522f9fae2371c9665c5ae9cb6")] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = "")] [assembly: AssemblyMetadata("IsTrimmable", "True")] [assembly: AssemblyCompany("Google Inc.")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyCopyright("Copyright 2015, Google Inc.")] [assembly: AssemblyDescription("C# runtime library for Protocol Buffers - Google's data interchange format.")] [assembly: AssemblyFileVersion("3.27.4.0")] [assembly: AssemblyInformationalVersion("3.27.4+80d48ae92d3007caac5eab0a8f8ee4e57f3a921e")] [assembly: AssemblyProduct("Google.Protobuf")] [assembly: AssemblyTitle("Google Protocol Buffers")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/protocolbuffers/protobuf.git")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("3.27.4.0")] [module: UnverifiableCode] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] internal sealed class IsReadOnlyAttribute : Attribute { } [CompilerGenerated] [Embedded] internal sealed class IsByRefLikeAttribute : Attribute { } } 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.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 Google.Protobuf { internal static class ByteArray { private const int CopyThreshold = 12; internal static void Copy(byte[] src, int srcOffset, byte[] dst, int dstOffset, int count) { if (count > 12) { Buffer.BlockCopy(src, srcOffset, dst, dstOffset, count); return; } int num = srcOffset + count; for (int i = srcOffset; i < num; i++) { dst[dstOffset++] = src[i]; } } internal static void Reverse(byte[] bytes) { int num = 0; int num2 = bytes.Length - 1; while (num < num2) { byte b = bytes[num]; bytes[num] = bytes[num2]; bytes[num2] = b; num++; num2--; } } } [SecuritySafeCritical] [DebuggerDisplay("Length = {Length}")] [DebuggerTypeProxy(typeof(ByteStringDebugView))] public sealed class ByteString : IEnumerable<byte>, IEnumerable, IEquatable<ByteString> { private sealed class ByteStringDebugView { private readonly ByteString data; [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] public byte[] Items => data.bytes.ToArray(); public ByteStringDebugView(ByteString data) { this.data = data; } } private static readonly ByteString empty = new ByteString(new byte[0]); private readonly ReadOnlyMemory<byte> bytes; public static ByteString Empty => empty; public int Length => bytes.Length; public bool IsEmpty => Length == 0; public ReadOnlySpan<byte> Span => bytes.Span; public ReadOnlyMemory<byte> Memory => bytes; public byte this[int index] => bytes.Span[index]; internal static ByteString AttachBytes(ReadOnlyMemory<byte> bytes) { return new ByteString(bytes); } internal static ByteString AttachBytes(byte[] bytes) { return AttachBytes(bytes.AsMemory()); } private ByteString(ReadOnlyMemory<byte> bytes) { this.bytes = bytes; } public byte[] ToByteArray() { return bytes.ToArray(); } public string ToBase64() { if (MemoryMarshal.TryGetArray(bytes, out var segment)) { return Convert.ToBase64String(segment.Array, segment.Offset, segment.Count); } return Convert.ToBase64String(bytes.ToArray()); } public static ByteString FromBase64(string bytes) { if (!(bytes == "")) { return new ByteString(Convert.FromBase64String(bytes)); } return Empty; } public static ByteString FromStream(Stream stream) { ProtoPreconditions.CheckNotNull(stream, "stream"); MemoryStream memoryStream = new MemoryStream(stream.CanSeek ? checked((int)(stream.Length - stream.Position)) : 0); stream.CopyTo(memoryStream); return AttachBytes(memoryStream.ToArray()); } public static Task<ByteString> FromStreamAsync(Stream stream, CancellationToken cancellationToken = default(CancellationToken)) { ProtoPreconditions.CheckNotNull(stream, "stream"); return ByteStringAsync.FromStreamAsyncCore(stream, cancellationToken); } public static ByteString CopyFrom(params byte[] bytes) { return new ByteString((byte[])bytes.Clone()); } public static ByteString CopyFrom(byte[] bytes, int offset, int count) { byte[] array = new byte[count]; ByteArray.Copy(bytes, offset, array, 0, count); return new ByteString(array); } public static ByteString CopyFrom(ReadOnlySpan<byte> bytes) { return new ByteString(bytes.ToArray()); } public static ByteString CopyFrom(string text, Encoding encoding) { return new ByteString(encoding.GetBytes(text)); } public static ByteString CopyFromUtf8(string text) { return CopyFrom(text, Encoding.UTF8); } public string ToString(Encoding encoding) { if (MemoryMarshal.TryGetArray(bytes, out var segment)) { return encoding.GetString(segment.Array, segment.Offset, segment.Count); } byte[] array = bytes.ToArray(); return encoding.GetString(array, 0, array.Length); } public string ToStringUtf8() { return ToString(Encoding.UTF8); } [SecuritySafeCritical] public IEnumerator<byte> GetEnumerator() { return MemoryMarshal.ToEnumerable(bytes).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public CodedInputStream CreateCodedInput() { if (MemoryMarshal.TryGetArray(bytes, out var segment) && segment.Count == bytes.Length) { return new CodedInputStream(segment.Array, segment.Offset, segment.Count); } return new CodedInputStream(bytes.ToArray()); } public static bool operator ==(ByteString lhs, ByteString rhs) { if ((object)lhs == rhs) { return true; } if ((object)lhs == null || (object)rhs == null) { return false; } return lhs.bytes.Span.SequenceEqual(rhs.bytes.Span); } public static bool operator !=(ByteString lhs, ByteString rhs) { return !(lhs == rhs); } [SecuritySafeCritical] public override bool Equals(object obj) { return this == obj as ByteString; } [SecuritySafeCritical] public override int GetHashCode() { ReadOnlySpan<byte> span = bytes.Span; int num = 23; for (int i = 0; i < span.Length; i++) { num = num * 31 + span[i]; } return num; } public bool Equals(ByteString other) { return this == other; } public void CopyTo(byte[] array, int position) { bytes.CopyTo(array.AsMemory(position)); } public void WriteTo(Stream outputStream) { if (MemoryMarshal.TryGetArray(bytes, out var segment)) { outputStream.Write(segment.Array, segment.Offset, segment.Count); return; } byte[] array = bytes.ToArray(); outputStream.Write(array, 0, array.Length); } } internal static class ByteStringAsync { internal static async Task<ByteString> FromStreamAsyncCore(Stream stream, CancellationToken cancellationToken) { int capacity = (stream.CanSeek ? checked((int)(stream.Length - stream.Position)) : 0); MemoryStream memoryStream = new MemoryStream(capacity); await stream.CopyToAsync(memoryStream, 81920, cancellationToken); return ByteString.AttachBytes((memoryStream.Length == memoryStream.Capacity) ? memoryStream.GetBuffer() : memoryStream.ToArray()); } } [SecuritySafeCritical] public sealed class CodedInputStream : IDisposable { private readonly bool leaveOpen; private readonly byte[] buffer; private readonly Stream input; private ParserInternalState state; internal const int DefaultRecursionLimit = 100; internal const int DefaultSizeLimit = int.MaxValue; internal const int BufferSize = 4096; public long Position { get { if (input != null) { return input.Position - (state.bufferSize + state.bufferSizeAfterLimit - state.bufferPos); } return state.bufferPos; } } internal uint LastTag => state.lastTag; public int SizeLimit => state.sizeLimit; public int RecursionLimit => state.recursionLimit; internal bool DiscardUnknownFields { get { return state.DiscardUnknownFields; } set { state.DiscardUnknownFields = value; } } internal ExtensionRegistry ExtensionRegistry { get { return state.ExtensionRegistry; } set { state.ExtensionRegistry = value; } } internal byte[] InternalBuffer => buffer; internal Stream InternalInputStream => input; internal ref ParserInternalState InternalState => ref state; internal bool ReachedLimit => SegmentedBufferHelper.IsReachedLimit(ref state); public bool IsAtEnd { get { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(buffer); return SegmentedBufferHelper.IsAtEnd(ref readOnlySpan, ref state); } } public CodedInputStream(byte[] buffer) : this(null, ProtoPreconditions.CheckNotNull(buffer, "buffer"), 0, buffer.Length, leaveOpen: true) { } public CodedInputStream(byte[] buffer, int offset, int length) : this(null, ProtoPreconditions.CheckNotNull(buffer, "buffer"), offset, offset + length, leaveOpen: true) { if (offset < 0 || offset > buffer.Length) { throw new ArgumentOutOfRangeException("offset", "Offset must be within the buffer"); } if (length < 0 || offset + length > buffer.Length) { throw new ArgumentOutOfRangeException("length", "Length must be non-negative and within the buffer"); } } public CodedInputStream(Stream input) : this(input, leaveOpen: false) { } public CodedInputStream(Stream input, bool leaveOpen) : this(ProtoPreconditions.CheckNotNull(input, "input"), new byte[4096], 0, 0, leaveOpen) { } internal CodedInputStream(Stream input, byte[] buffer, int bufferPos, int bufferSize, bool leaveOpen) { this.input = input; this.buffer = buffer; state.bufferPos = bufferPos; state.bufferSize = bufferSize; state.sizeLimit = int.MaxValue; state.recursionLimit = 100; SegmentedBufferHelper.Initialize(this, out state.segmentedBufferHelper); this.leaveOpen = leaveOpen; state.currentLimit = int.MaxValue; } internal CodedInputStream(Stream input, byte[] buffer, int bufferPos, int bufferSize, int sizeLimit, int recursionLimit, bool leaveOpen) : this(input, buffer, bufferPos, bufferSize, leaveOpen) { if (sizeLimit <= 0) { throw new ArgumentOutOfRangeException("sizeLimit", "Size limit must be positive"); } if (recursionLimit <= 0) { throw new ArgumentOutOfRangeException("recursionLimit!", "Recursion limit must be positive"); } state.sizeLimit = sizeLimit; state.recursionLimit = recursionLimit; } public static CodedInputStream CreateWithLimits(Stream input, int sizeLimit, int recursionLimit) { return new CodedInputStream(input, new byte[4096], 0, 0, sizeLimit, recursionLimit, leaveOpen: false); } public void Dispose() { if (!leaveOpen) { input.Dispose(); } } internal void CheckReadEndOfStreamTag() { ParsingPrimitivesMessages.CheckReadEndOfStreamTag(ref state); } public uint PeekTag() { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(buffer); return ParsingPrimitives.PeekTag(ref readOnlySpan, ref state); } public uint ReadTag() { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(buffer); return ParsingPrimitives.ParseTag(ref readOnlySpan, ref state); } public void SkipLastField() { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(buffer); ParsingPrimitivesMessages.SkipLastField(ref readOnlySpan, ref state); } internal void SkipGroup(uint startGroupTag) { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(buffer); ParsingPrimitivesMessages.SkipGroup(ref readOnlySpan, ref state, startGroupTag); } public double ReadDouble() { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(buffer); return ParsingPrimitives.ParseDouble(ref readOnlySpan, ref state); } public float ReadFloat() { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(buffer); return ParsingPrimitives.ParseFloat(ref readOnlySpan, ref state); } public ulong ReadUInt64() { return ReadRawVarint64(); } public long ReadInt64() { return (long)ReadRawVarint64(); } public int ReadInt32() { return (int)ReadRawVarint32(); } public ulong ReadFixed64() { return ReadRawLittleEndian64(); } public uint ReadFixed32() { return ReadRawLittleEndian32(); } public bool ReadBool() { return ReadRawVarint64() != 0; } public string ReadString() { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(buffer); return ParsingPrimitives.ReadString(ref readOnlySpan, ref state); } public void ReadMessage(IMessage builder) { ParseContext.Initialize(buffer.AsSpan(), ref state, out var ctx); try { ParsingPrimitivesMessages.ReadMessage(ref ctx, builder); } finally { ctx.CopyStateTo(this); } } public void ReadGroup(IMessage builder) { ParseContext.Initialize(this, out var ctx); try { ParsingPrimitivesMessages.ReadGroup(ref ctx, builder); } finally { ctx.CopyStateTo(this); } } public ByteString ReadBytes() { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(buffer); return ParsingPrimitives.ReadBytes(ref readOnlySpan, ref state); } public uint ReadUInt32() { return ReadRawVarint32(); } public int ReadEnum() { return (int)ReadRawVarint32(); } public int ReadSFixed32() { return (int)ReadRawLittleEndian32(); } public long ReadSFixed64() { return (long)ReadRawLittleEndian64(); } public int ReadSInt32() { return ParsingPrimitives.DecodeZigZag32(ReadRawVarint32()); } public long ReadSInt64() { return ParsingPrimitives.DecodeZigZag64(ReadRawVarint64()); } public int ReadLength() { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(buffer); return ParsingPrimitives.ParseLength(ref readOnlySpan, ref state); } public bool MaybeConsumeTag(uint tag) { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(buffer); return ParsingPrimitives.MaybeConsumeTag(ref readOnlySpan, ref state, tag); } internal uint ReadRawVarint32() { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(buffer); return ParsingPrimitives.ParseRawVarint32(ref readOnlySpan, ref state); } internal static uint ReadRawVarint32(Stream input) { return ParsingPrimitives.ReadRawVarint32(input); } internal ulong ReadRawVarint64() { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(buffer); return ParsingPrimitives.ParseRawVarint64(ref readOnlySpan, ref state); } internal uint ReadRawLittleEndian32() { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(buffer); return ParsingPrimitives.ParseRawLittleEndian32(ref readOnlySpan, ref state); } internal ulong ReadRawLittleEndian64() { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(buffer); return ParsingPrimitives.ParseRawLittleEndian64(ref readOnlySpan, ref state); } internal int PushLimit(int byteLimit) { return SegmentedBufferHelper.PushLimit(ref state, byteLimit); } internal void PopLimit(int oldLimit) { SegmentedBufferHelper.PopLimit(ref state, oldLimit); } internal byte[] ReadRawBytes(int size) { ReadOnlySpan<byte> readOnlySpan = new ReadOnlySpan<byte>(buffer); return ParsingPrimitives.ReadRawBytes(ref readOnlySpan, ref state, size); } public void ReadRawMessage(IMessage message) { ParseContext.Initialize(this, out var ctx); try { ParsingPrimitivesMessages.ReadRawMessage(ref ctx, message); } finally { ctx.CopyStateTo(this); } } } [SecuritySafeCritical] public sealed class CodedOutputStream : IDisposable { public sealed class OutOfSpaceException : IOException { internal OutOfSpaceException() : base("CodedOutputStream was writing to a flat byte array and ran out of space.") { } } private const int LittleEndian64Size = 8; private const int LittleEndian32Size = 4; internal const int DoubleSize = 8; internal const int FloatSize = 4; internal const int BoolSize = 1; public static readonly int DefaultBufferSize = 4096; private readonly bool leaveOpen; private readonly byte[] buffer; private WriterInternalState state; private readonly Stream output; public long Position { get { if (output != null) { return output.Position + state.position; } return state.position; } } public bool Deterministic { get; set; } public int SpaceLeft => WriteBufferHelper.GetSpaceLeft(ref state); internal byte[] InternalBuffer => buffer; internal Stream InternalOutputStream => output; internal ref WriterInternalState InternalState => ref state; public static int ComputeDoubleSize(double value) { return 8; } public static int ComputeFloatSize(float value) { return 4; } public static int ComputeUInt64Size(ulong value) { return ComputeRawVarint64Size(value); } public static int ComputeInt64Size(long value) { return ComputeRawVarint64Size((ulong)value); } public static int ComputeInt32Size(int value) { if (value >= 0) { return ComputeRawVarint32Size((uint)value); } return 10; } public static int ComputeFixed64Size(ulong value) { return 8; } public static int ComputeFixed32Size(uint value) { return 4; } public static int ComputeBoolSize(bool value) { return 1; } public static int ComputeStringSize(string value) { int byteCount = WritingPrimitives.Utf8Encoding.GetByteCount(value); return ComputeLengthSize(byteCount) + byteCount; } public static int ComputeGroupSize(IMessage value) { return value.CalculateSize(); } public static int ComputeMessageSize(IMessage value) { int num = value.CalculateSize(); return ComputeLengthSize(num) + num; } public static int ComputeBytesSize(ByteString value) { return ComputeLengthSize(value.Length) + value.Length; } public static int ComputeUInt32Size(uint value) { return ComputeRawVarint32Size(value); } public static int ComputeEnumSize(int value) { return ComputeInt32Size(value); } public static int ComputeSFixed32Size(int value) { return 4; } public static int ComputeSFixed64Size(long value) { return 8; } public static int ComputeSInt32Size(int value) { return ComputeRawVarint32Size(WritingPrimitives.EncodeZigZag32(value)); } public static int ComputeSInt64Size(long value) { return ComputeRawVarint64Size(WritingPrimitives.EncodeZigZag64(value)); } public static int ComputeLengthSize(int length) { return ComputeRawVarint32Size((uint)length); } public static int ComputeRawVarint32Size(uint value) { if ((value & 0xFFFFFF80u) == 0) { return 1; } if ((value & 0xFFFFC000u) == 0) { return 2; } if ((value & 0xFFE00000u) == 0) { return 3; } if ((value & 0xF0000000u) == 0) { return 4; } return 5; } public static int ComputeRawVarint64Size(ulong value) { if ((value & 0xFFFFFFFFFFFFFF80uL) == 0L) { return 1; } if ((value & 0xFFFFFFFFFFFFC000uL) == 0L) { return 2; } if ((value & 0xFFFFFFFFFFE00000uL) == 0L) { return 3; } if ((value & 0xFFFFFFFFF0000000uL) == 0L) { return 4; } if ((value & 0xFFFFFFF800000000uL) == 0L) { return 5; } if ((value & 0xFFFFFC0000000000uL) == 0L) { return 6; } if ((value & 0xFFFE000000000000uL) == 0L) { return 7; } if ((value & 0xFF00000000000000uL) == 0L) { return 8; } if ((value & 0x8000000000000000uL) == 0L) { return 9; } return 10; } public static int ComputeTagSize(int fieldNumber) { return ComputeRawVarint32Size(WireFormat.MakeTag(fieldNumber, WireFormat.WireType.Varint)); } public CodedOutputStream(byte[] flatArray) : this(flatArray, 0, flatArray.Length) { } private CodedOutputStream(byte[] buffer, int offset, int length) { output = null; this.buffer = ProtoPreconditions.CheckNotNull(buffer, "buffer"); state.position = offset; state.limit = offset + length; WriteBufferHelper.Initialize(this, out state.writeBufferHelper); leaveOpen = true; } private CodedOutputStream(Stream output, byte[] buffer, bool leaveOpen) { this.output = ProtoPreconditions.CheckNotNull(output, "output"); this.buffer = buffer; state.position = 0; state.limit = buffer.Length; WriteBufferHelper.Initialize(this, out state.writeBufferHelper); this.leaveOpen = leaveOpen; } public CodedOutputStream(Stream output) : this(output, DefaultBufferSize, leaveOpen: false) { } public CodedOutputStream(Stream output, int bufferSize) : this(output, new byte[bufferSize], leaveOpen: false) { } public CodedOutputStream(Stream output, bool leaveOpen) : this(output, DefaultBufferSize, leaveOpen) { } public CodedOutputStream(Stream output, int bufferSize, bool leaveOpen) : this(output, new byte[bufferSize], leaveOpen) { } public void WriteDouble(double value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteDouble(ref span, ref state, value); } public void WriteFloat(float value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteFloat(ref span, ref state, value); } public void WriteUInt64(ulong value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteUInt64(ref span, ref state, value); } public void WriteInt64(long value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteInt64(ref span, ref state, value); } public void WriteInt32(int value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteInt32(ref span, ref state, value); } public void WriteFixed64(ulong value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteFixed64(ref span, ref state, value); } public void WriteFixed32(uint value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteFixed32(ref span, ref state, value); } public void WriteBool(bool value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteBool(ref span, ref state, value); } public void WriteString(string value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteString(ref span, ref state, value); } public void WriteMessage(IMessage value) { Span<byte> span = new Span<byte>(buffer); WriteContext.Initialize(ref span, ref state, out var ctx); try { WritingPrimitivesMessages.WriteMessage(ref ctx, value); } finally { ctx.CopyStateTo(this); } } public void WriteRawMessage(IMessage value) { Span<byte> span = new Span<byte>(buffer); WriteContext.Initialize(ref span, ref state, out var ctx); try { WritingPrimitivesMessages.WriteRawMessage(ref ctx, value); } finally { ctx.CopyStateTo(this); } } public void WriteGroup(IMessage value) { Span<byte> span = new Span<byte>(buffer); WriteContext.Initialize(ref span, ref state, out var ctx); try { WritingPrimitivesMessages.WriteGroup(ref ctx, value); } finally { ctx.CopyStateTo(this); } } public void WriteBytes(ByteString value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteBytes(ref span, ref state, value); } public void WriteUInt32(uint value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteUInt32(ref span, ref state, value); } public void WriteEnum(int value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteEnum(ref span, ref state, value); } public void WriteSFixed32(int value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteSFixed32(ref span, ref state, value); } public void WriteSFixed64(long value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteSFixed64(ref span, ref state, value); } public void WriteSInt32(int value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteSInt32(ref span, ref state, value); } public void WriteSInt64(long value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteSInt64(ref span, ref state, value); } public void WriteLength(int length) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteLength(ref span, ref state, length); } public void WriteTag(int fieldNumber, WireFormat.WireType type) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteTag(ref span, ref state, fieldNumber, type); } public void WriteTag(uint tag) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteTag(ref span, ref state, tag); } public void WriteRawTag(byte b1) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteRawTag(ref span, ref state, b1); } public void WriteRawTag(byte b1, byte b2) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2); } public void WriteRawTag(byte b1, byte b2, byte b3) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3); } public void WriteRawTag(byte b1, byte b2, byte b3, byte b4) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3, b4); } public void WriteRawTag(byte b1, byte b2, byte b3, byte b4, byte b5) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3, b4, b5); } internal void WriteRawVarint32(uint value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteRawVarint32(ref span, ref state, value); } internal void WriteRawVarint64(ulong value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteRawVarint64(ref span, ref state, value); } internal void WriteRawLittleEndian32(uint value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteRawLittleEndian32(ref span, ref state, value); } internal void WriteRawLittleEndian64(ulong value) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteRawLittleEndian64(ref span, ref state, value); } internal void WriteRawBytes(byte[] value) { WriteRawBytes(value, 0, value.Length); } internal void WriteRawBytes(byte[] value, int offset, int length) { Span<byte> span = new Span<byte>(buffer); WritingPrimitives.WriteRawBytes(ref span, ref state, value, offset, length); } public void Dispose() { Flush(); if (!leaveOpen) { output.Dispose(); } } public void Flush() { Span<byte> span = new Span<byte>(buffer); WriteBufferHelper.Flush(ref span, ref state); } public void CheckNoSpaceLeft() { WriteBufferHelper.CheckNoSpaceLeft(ref state); } } public abstract class Extension { internal abstract System.Type TargetType { get; } public int FieldNumber { get; } internal abstract bool IsRepeated { get; } protected Extension(int fieldNumber) { FieldNumber = fieldNumber; } internal abstract IExtensionValue CreateValue(); } public sealed class Extension<TTarget, TValue> : Extension where TTarget : IExtendableMessage<TTarget> { private readonly FieldCodec<TValue> codec; internal TValue DefaultValue { get { if (codec == null) { return default(TValue); } return codec.DefaultValue; } } internal override System.Type TargetType => typeof(TTarget); internal override bool IsRepeated => false; public Extension(int fieldNumber, FieldCodec<TValue> codec) : base(fieldNumber) { this.codec = codec; } internal override IExtensionValue CreateValue() { return new ExtensionValue<TValue>(codec); } } public sealed class RepeatedExtension<TTarget, TValue> : Extension where TTarget : IExtendableMessage<TTarget> { private readonly FieldCodec<TValue> codec; internal override System.Type TargetType => typeof(TTarget); internal override bool IsRepeated => true; public RepeatedExtension(int fieldNumber, FieldCodec<TValue> codec) : base(fieldNumber) { this.codec = codec; } internal override IExtensionValue CreateValue() { return new RepeatedExtensionValue<TValue>(codec); } } public sealed class ExtensionRegistry : ICollection<Extension>, IEnumerable<Extension>, IEnumerable, IDeepCloneable<ExtensionRegistry> { internal sealed class ExtensionComparer : IEqualityComparer<Extension> { internal static ExtensionComparer Instance = new ExtensionComparer(); public bool Equals(Extension a, Extension b) { return new ObjectIntPair<System.Type>(a.TargetType, a.FieldNumber).Equals(new ObjectIntPair<System.Type>(b.TargetType, b.FieldNumber)); } public int GetHashCode(Extension a) { return new ObjectIntPair<System.Type>(a.TargetType, a.FieldNumber).GetHashCode(); } } private readonly IDictionary<ObjectIntPair<System.Type>, Extension> extensions; public int Count => extensions.Count; bool ICollection<Extension>.IsReadOnly => false; public ExtensionRegistry() { extensions = new Dictionary<ObjectIntPair<System.Type>, Extension>(); } private ExtensionRegistry(IDictionary<ObjectIntPair<System.Type>, Extension> collection) { extensions = collection.ToDictionary((KeyValuePair<ObjectIntPair<System.Type>, Extension> k) => k.Key, (KeyValuePair<ObjectIntPair<System.Type>, Extension> v) => v.Value); } internal bool ContainsInputField(uint lastTag, System.Type target, out Extension extension) { return extensions.TryGetValue(new ObjectIntPair<System.Type>(target, WireFormat.GetTagFieldNumber(lastTag)), out extension); } public void Add(Extension extension) { ProtoPreconditions.CheckNotNull(extension, "extension"); extensions.Add(new ObjectIntPair<System.Type>(extension.TargetType, extension.FieldNumber), extension); } public void AddRange(IEnumerable<Extension> extensions) { ProtoPreconditions.CheckNotNull(extensions, "extensions"); foreach (Extension extension in extensions) { Add(extension); } } public void Clear() { extensions.Clear(); } public bool Contains(Extension item) { ProtoPreconditions.CheckNotNull(item, "item"); return extensions.ContainsKey(new ObjectIntPair<System.Type>(item.TargetType, item.FieldNumber)); } void ICollection<Extension>.CopyTo(Extension[] array, int arrayIndex) { ProtoPreconditions.CheckNotNull(array, "array"); if (arrayIndex < 0 || arrayIndex >= array.Length) { throw new ArgumentOutOfRangeException("arrayIndex"); } if (array.Length - arrayIndex < Count) { throw new ArgumentException("The provided array is shorter than the number of elements in the registry"); } foreach (Extension extension in array) { extensions.Add(new ObjectIntPair<System.Type>(extension.TargetType, extension.FieldNumber), extension); } } public IEnumerator<Extension> GetEnumerator() { return extensions.Values.GetEnumerator(); } public bool Remove(Extension item) { ProtoPreconditions.CheckNotNull(item, "item"); return extensions.Remove(new ObjectIntPair<System.Type>(item.TargetType, item.FieldNumber)); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public ExtensionRegistry Clone() { return new ExtensionRegistry(extensions); } } public static class ExtensionSet { private static bool TryGetValue<TTarget>(ref ExtensionSet<TTarget> set, Extension extension, out IExtensionValue value) where TTarget : IExtendableMessage<TTarget> { if (set == null) { value = null; return false; } return set.ValuesByNumber.TryGetValue(extension.FieldNumber, out value); } public static TValue Get<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget> { if (TryGetValue(ref set, extension, out var value)) { if (value is ExtensionValue<TValue> extensionValue) { return extensionValue.GetValue(); } object value2 = value.GetValue(); if (value2 is TValue) { return (TValue)value2; } TypeInfo typeInfo = value.GetType().GetTypeInfo(); if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(ExtensionValue<>)) { System.Type type = typeInfo.GenericTypeArguments[0]; throw new InvalidOperationException("The stored extension value has a type of '" + type.AssemblyQualifiedName + "'. This a different from the requested type of '" + typeof(TValue).AssemblyQualifiedName + "'."); } throw new InvalidOperationException("Unexpected extension value type: " + typeInfo.AssemblyQualifiedName); } return extension.DefaultValue; } public static RepeatedField<TValue> Get<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget> { if (TryGetValue(ref set, extension, out var value)) { if (value is RepeatedExtensionValue<TValue> repeatedExtensionValue) { return repeatedExtensionValue.GetValue(); } TypeInfo typeInfo = value.GetType().GetTypeInfo(); if (typeInfo.IsGenericType && typeInfo.GetGenericTypeDefinition() == typeof(RepeatedExtensionValue<>)) { System.Type type = typeInfo.GenericTypeArguments[0]; throw new InvalidOperationException("The stored extension value has a type of '" + type.AssemblyQualifiedName + "'. This a different from the requested type of '" + typeof(TValue).AssemblyQualifiedName + "'."); } throw new InvalidOperationException("Unexpected extension value type: " + typeInfo.AssemblyQualifiedName); } return null; } public static RepeatedField<TValue> GetOrInitialize<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget> { IExtensionValue value; if (set == null) { value = extension.CreateValue(); set = new ExtensionSet<TTarget>(); set.ValuesByNumber.Add(extension.FieldNumber, value); } else if (!set.ValuesByNumber.TryGetValue(extension.FieldNumber, out value)) { value = extension.CreateValue(); set.ValuesByNumber.Add(extension.FieldNumber, value); } return ((RepeatedExtensionValue<TValue>)value).GetValue(); } public static void Set<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension, TValue value) where TTarget : IExtendableMessage<TTarget> { ProtoPreconditions.CheckNotNullUnconstrained(value, "value"); IExtensionValue value2; if (set == null) { value2 = extension.CreateValue(); set = new ExtensionSet<TTarget>(); set.ValuesByNumber.Add(extension.FieldNumber, value2); } else if (!set.ValuesByNumber.TryGetValue(extension.FieldNumber, out value2)) { value2 = extension.CreateValue(); set.ValuesByNumber.Add(extension.FieldNumber, value2); } ((ExtensionValue<TValue>)value2).SetValue(value); } public static bool Has<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget> { IExtensionValue value; return TryGetValue(ref set, extension, out value); } public static void Clear<TTarget, TValue>(ref ExtensionSet<TTarget> set, Extension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget> { if (set != null) { set.ValuesByNumber.Remove(extension.FieldNumber); if (set.ValuesByNumber.Count == 0) { set = null; } } } public static void Clear<TTarget, TValue>(ref ExtensionSet<TTarget> set, RepeatedExtension<TTarget, TValue> extension) where TTarget : IExtendableMessage<TTarget> { if (set != null) { set.ValuesByNumber.Remove(extension.FieldNumber); if (set.ValuesByNumber.Count == 0) { set = null; } } } public static bool TryMergeFieldFrom<TTarget>(ref ExtensionSet<TTarget> set, CodedInputStream stream) where TTarget : IExtendableMessage<TTarget> { ParseContext.Initialize(stream, out var ctx); try { return TryMergeFieldFrom(ref set, ref ctx); } finally { ctx.CopyStateTo(stream); } } public static bool TryMergeFieldFrom<TTarget>(ref ExtensionSet<TTarget> set, ref ParseContext ctx) where TTarget : IExtendableMessage<TTarget> { int tagFieldNumber = WireFormat.GetTagFieldNumber(ctx.LastTag); if (set != null && set.ValuesByNumber.TryGetValue(tagFieldNumber, out var value)) { value.MergeFrom(ref ctx); return true; } if (ctx.ExtensionRegistry != null && ctx.ExtensionRegistry.ContainsInputField(ctx.LastTag, typeof(TTarget), out var extension)) { IExtensionValue extensionValue = extension.CreateValue(); extensionValue.MergeFrom(ref ctx); if (set == null) { set = new ExtensionSet<TTarget>(); } set.ValuesByNumber.Add(extension.FieldNumber, extensionValue); return true; } return false; } public static void MergeFrom<TTarget>(ref ExtensionSet<TTarget> first, ExtensionSet<TTarget> second) where TTarget : IExtendableMessage<TTarget> { if (second == null) { return; } if (first == null) { first = new ExtensionSet<TTarget>(); } foreach (KeyValuePair<int, IExtensionValue> item in second.ValuesByNumber) { if (first.ValuesByNumber.TryGetValue(item.Key, out var value)) { value.MergeFrom(item.Value); continue; } IExtensionValue value2 = item.Value.Clone(); first.ValuesByNumber[item.Key] = value2; } } public static ExtensionSet<TTarget> Clone<TTarget>(ExtensionSet<TTarget> set) where TTarget : IExtendableMessage<TTarget> { if (set == null) { return null; } ExtensionSet<TTarget> extensionSet = new ExtensionSet<TTarget>(); foreach (KeyValuePair<int, IExtensionValue> item in set.ValuesByNumber) { IExtensionValue value = item.Value.Clone(); extensionSet.ValuesByNumber[item.Key] = value; } return extensionSet; } } public sealed class ExtensionSet<TTarget> where TTarget : IExtendableMessage<TTarget> { internal Dictionary<int, IExtensionValue> ValuesByNumber { get; } = new Dictionary<int, IExtensionValue>(); public override int GetHashCode() { int num = typeof(TTarget).GetHashCode(); foreach (KeyValuePair<int, IExtensionValue> item in ValuesByNumber) { int num2 = item.Key.GetHashCode() ^ item.Value.GetHashCode(); num ^= num2; } return num; } public override bool Equals(object other) { if (this == other) { return true; } ExtensionSet<TTarget> extensionSet = other as ExtensionSet<TTarget>; if (ValuesByNumber.Count != extensionSet.ValuesByNumber.Count) { return false; } foreach (KeyValuePair<int, IExtensionValue> item in ValuesByNumber) { if (!extensionSet.ValuesByNumber.TryGetValue(item.Key, out var value)) { return false; } if (!item.Value.Equals(value)) { return false; } } return true; } public int CalculateSize() { int num = 0; foreach (IExtensionValue value in ValuesByNumber.Values) { num += value.CalculateSize(); } return num; } public void WriteTo(CodedOutputStream stream) { WriteContext.Initialize(stream, out var ctx); try { WriteTo(ref ctx); } finally { ctx.CopyStateTo(stream); } } [SecuritySafeCritical] public void WriteTo(ref WriteContext ctx) { foreach (IExtensionValue value in ValuesByNumber.Values) { value.WriteTo(ref ctx); } } internal bool IsInitialized() { return ValuesByNumber.Values.All((IExtensionValue v) => v.IsInitialized()); } } internal interface IExtensionValue : IEquatable<IExtensionValue>, IDeepCloneable<IExtensionValue> { void MergeFrom(ref ParseContext ctx); void MergeFrom(IExtensionValue value); void WriteTo(ref WriteContext ctx); int CalculateSize(); bool IsInitialized(); object GetValue(); } internal sealed class ExtensionValue<T> : IExtensionValue, IEquatable<IExtensionValue>, IDeepCloneable<IExtensionValue> { private T field; private readonly FieldCodec<T> codec; internal ExtensionValue(FieldCodec<T> codec) { this.codec = codec; field = codec.DefaultValue; } public int CalculateSize() { return codec.CalculateUnconditionalSizeWithTag(field); } public IExtensionValue Clone() { return new ExtensionValue<T>(codec) { field = ((field is IDeepCloneable<T>) ? (field as IDeepCloneable<T>).Clone() : field) }; } public bool Equals(IExtensionValue other) { if (this == other) { return true; } if (other is ExtensionValue<T> && codec.Equals((other as ExtensionValue<T>).codec)) { return object.Equals(field, (other as ExtensionValue<T>).field); } return false; } public override int GetHashCode() { return (17 * 31 + field.GetHashCode()) * 31 + codec.GetHashCode(); } public void MergeFrom(ref ParseContext ctx) { codec.ValueMerger(ref ctx, ref field); } public void MergeFrom(IExtensionValue value) { if (value is ExtensionValue<T>) { ExtensionValue<T> extensionValue = value as ExtensionValue<T>; codec.FieldMerger(ref field, extensionValue.field); } } public void WriteTo(ref WriteContext ctx) { ctx.WriteTag(codec.Tag); codec.ValueWriter(ref ctx, field); if (codec.EndTag != 0) { ctx.WriteTag(codec.EndTag); } } public T GetValue() { return field; } object IExtensionValue.GetValue() { return field; } public void SetValue(T value) { field = value; } public bool IsInitialized() { if (field is IMessage) { return (field as IMessage).IsInitialized(); } return true; } } internal sealed class RepeatedExtensionValue<T> : IExtensionValue, IEquatable<IExtensionValue>, IDeepCloneable<IExtensionValue> { private RepeatedField<T> field; private readonly FieldCodec<T> codec; internal RepeatedExtensionValue(FieldCodec<T> codec) { this.codec = codec; field = new RepeatedField<T>(); } public int CalculateSize() { return field.CalculateSize(codec); } public IExtensionValue Clone() { return new RepeatedExtensionValue<T>(codec) { field = field.Clone() }; } public bool Equals(IExtensionValue other) { if (this == other) { return true; } if (other is RepeatedExtensionValue<T> && field.Equals((other as RepeatedExtensionValue<T>).field)) { return codec.Equals((other as RepeatedExtensionValue<T>).codec); } return false; } public override int GetHashCode() { return (17 * 31 + field.GetHashCode()) * 31 + codec.GetHashCode(); } public void MergeFrom(ref ParseContext ctx) { field.AddEntriesFrom(ref ctx, codec); } public void MergeFrom(IExtensionValue value) { if (value is RepeatedExtensionValue<T>) { field.Add((value as RepeatedExtensionValue<T>).field); } } public void WriteTo(ref WriteContext ctx) { field.WriteTo(ref ctx, codec); } public RepeatedField<T> GetValue() { return field; } object IExtensionValue.GetValue() { return field; } public bool IsInitialized() { for (int i = 0; i < field.Count; i++) { T val = field[i]; if (!(val is IMessage)) { break; } if (!(val as IMessage).IsInitialized()) { return false; } } return true; } } public static class FieldCodec { private static class WrapperCodecs { private static readonly Dictionary<System.Type, object> Codecs = new Dictionary<System.Type, object> { { typeof(bool), ForBool(WireFormat.MakeTag(1, WireFormat.WireType.Varint)) }, { typeof(int), ForInt32(WireFormat.MakeTag(1, WireFormat.WireType.Varint)) }, { typeof(long), ForInt64(WireFormat.MakeTag(1, WireFormat.WireType.Varint)) }, { typeof(uint), ForUInt32(WireFormat.MakeTag(1, WireFormat.WireType.Varint)) }, { typeof(ulong), ForUInt64(WireFormat.MakeTag(1, WireFormat.WireType.Varint)) }, { typeof(float), ForFloat(WireFormat.MakeTag(1, WireFormat.WireType.Fixed32)) }, { typeof(double), ForDouble(WireFormat.MakeTag(1, WireFormat.WireType.Fixed64)) }, { typeof(string), ForString(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited)) }, { typeof(ByteString), ForBytes(WireFormat.MakeTag(1, WireFormat.WireType.LengthDelimited)) } }; private static readonly Dictionary<System.Type, object> Readers = new Dictionary<System.Type, object> { { typeof(bool), new ValueReader<bool?>(ParsingPrimitivesWrappers.ReadBoolWrapper) }, { typeof(int), new ValueReader<int?>(ParsingPrimitivesWrappers.ReadInt32Wrapper) }, { typeof(long), new ValueReader<long?>(ParsingPrimitivesWrappers.ReadInt64Wrapper) }, { typeof(uint), new ValueReader<uint?>(ParsingPrimitivesWrappers.ReadUInt32Wrapper) }, { typeof(ulong), new ValueReader<ulong?>(ParsingPrimitivesWrappers.ReadUInt64Wrapper) }, { typeof(float), BitConverter.IsLittleEndian ? new ValueReader<float?>(ParsingPrimitivesWrappers.ReadFloatWrapperLittleEndian) : new ValueReader<float?>(ParsingPrimitivesWrappers.ReadFloatWrapperSlow) }, { typeof(double), BitConverter.IsLittleEndian ? new ValueReader<double?>(ParsingPrimitivesWrappers.ReadDoubleWrapperLittleEndian) : new ValueReader<double?>(ParsingPrimitivesWrappers.ReadDoubleWrapperSlow) }, { typeof(string), null }, { typeof(ByteString), null } }; internal static FieldCodec<T> GetCodec<T>() { if (!Codecs.TryGetValue(typeof(T), out var value)) { throw new InvalidOperationException("Invalid type argument requested for wrapper codec: " + typeof(T)); } return (FieldCodec<T>)value; } internal static ValueReader<T?> GetReader<T>() where T : struct { if (!Readers.TryGetValue(typeof(T), out var value)) { throw new InvalidOperationException("Invalid type argument requested for wrapper reader: " + typeof(T)); } if (value == null) { FieldCodec<T> nestedCoded = GetCodec<T>(); return delegate(ref ParseContext ctx) { return Read(ref ctx, nestedCoded); }; } return (ValueReader<T?>)value; } [SecuritySafeCritical] internal static T Read<T>(ref ParseContext ctx, FieldCodec<T> codec) { int byteLimit = ctx.ReadLength(); int oldLimit = SegmentedBufferHelper.PushLimit(ref ctx.state, byteLimit); T result = codec.DefaultValue; uint num; while ((num = ctx.ReadTag()) != 0) { if (num == codec.Tag) { result = codec.Read(ref ctx); } else { ParsingPrimitivesMessages.SkipLastField(ref ctx.buffer, ref ctx.state); } } ParsingPrimitivesMessages.CheckReadEndOfStreamTag(ref ctx.state); SegmentedBufferHelper.PopLimit(ref ctx.state, oldLimit); return result; } internal static void Write<T>(ref WriteContext ctx, T value, FieldCodec<T> codec) { ctx.WriteLength(codec.CalculateSizeWithTag(value)); codec.WriteTagAndValue(ref ctx, value); } internal static int CalculateSize<T>(T value, FieldCodec<T> codec) { int num = codec.CalculateSizeWithTag(value); return CodedOutputStream.ComputeLengthSize(num) + num; } } public static FieldCodec<string> ForString(uint tag) { return ForString(tag, ""); } public static FieldCodec<ByteString> ForBytes(uint tag) { return ForBytes(tag, ByteString.Empty); } public static FieldCodec<bool> ForBool(uint tag) { return ForBool(tag, defaultValue: false); } public static FieldCodec<int> ForInt32(uint tag) { return ForInt32(tag, 0); } public static FieldCodec<int> ForSInt32(uint tag) { return ForSInt32(tag, 0); } public static FieldCodec<uint> ForFixed32(uint tag) { return ForFixed32(tag, 0u); } public static FieldCodec<int> ForSFixed32(uint tag) { return ForSFixed32(tag, 0); } public static FieldCodec<uint> ForUInt32(uint tag) { return ForUInt32(tag, 0u); } public static FieldCodec<long> ForInt64(uint tag) { return ForInt64(tag, 0L); } public static FieldCodec<long> ForSInt64(uint tag) { return ForSInt64(tag, 0L); } public static FieldCodec<ulong> ForFixed64(uint tag) { return ForFixed64(tag, 0uL); } public static FieldCodec<long> ForSFixed64(uint tag) { return ForSFixed64(tag, 0L); } public static FieldCodec<ulong> ForUInt64(uint tag) { return ForUInt64(tag, 0uL); } public static FieldCodec<float> ForFloat(uint tag) { return ForFloat(tag, 0f); } public static FieldCodec<double> ForDouble(uint tag) { return ForDouble(tag, 0.0); } public static FieldCodec<T> ForEnum<T>(uint tag, Func<T, int> toInt32, Func<int, T> fromInt32) { return ForEnum(tag, toInt32, fromInt32, default(T)); } public static FieldCodec<string> ForString(uint tag, string defaultValue) { return new FieldCodec<string>(delegate(ref ParseContext ctx) { return ctx.ReadString(); }, delegate(ref WriteContext ctx, string value) { ctx.WriteString(value); }, CodedOutputStream.ComputeStringSize, tag, defaultValue); } public static FieldCodec<ByteString> ForBytes(uint tag, ByteString defaultValue) { return new FieldCodec<ByteString>(delegate(ref ParseContext ctx) { return ctx.ReadBytes(); }, delegate(ref WriteContext ctx, ByteString value) { ctx.WriteBytes(value); }, CodedOutputStream.ComputeBytesSize, tag, defaultValue); } public static FieldCodec<bool> ForBool(uint tag, bool defaultValue) { return new FieldCodec<bool>(delegate(ref ParseContext ctx) { return ctx.ReadBool(); }, delegate(ref WriteContext ctx, bool value) { ctx.WriteBool(value); }, 1, tag, defaultValue); } public static FieldCodec<int> ForInt32(uint tag, int defaultValue) { return new FieldCodec<int>(delegate(ref ParseContext ctx) { return ctx.ReadInt32(); }, delegate(ref WriteContext output, int value) { output.WriteInt32(value); }, CodedOutputStream.ComputeInt32Size, tag, defaultValue); } public static FieldCodec<int> ForSInt32(uint tag, int defaultValue) { return new FieldCodec<int>(delegate(ref ParseContext ctx) { return ctx.ReadSInt32(); }, delegate(ref WriteContext output, int value) { output.WriteSInt32(value); }, CodedOutputStream.ComputeSInt32Size, tag, defaultValue); } public static FieldCodec<uint> ForFixed32(uint tag, uint defaultValue) { return new FieldCodec<uint>(delegate(ref ParseContext ctx) { return ctx.ReadFixed32(); }, delegate(ref WriteContext output, uint value) { output.WriteFixed32(value); }, 4, tag, defaultValue); } public static FieldCodec<int> ForSFixed32(uint tag, int defaultValue) { return new FieldCodec<int>(delegate(ref ParseContext ctx) { return ctx.ReadSFixed32(); }, delegate(ref WriteContext output, int value) { output.WriteSFixed32(value); }, 4, tag, defaultValue); } public static FieldCodec<uint> ForUInt32(uint tag, uint defaultValue) { return new FieldCodec<uint>(delegate(ref ParseContext ctx) { return ctx.ReadUInt32(); }, delegate(ref WriteContext output, uint value) { output.WriteUInt32(value); }, CodedOutputStream.ComputeUInt32Size, tag, defaultValue); } public static FieldCodec<long> ForInt64(uint tag, long defaultValue) { return new FieldCodec<long>(delegate(ref ParseContext ctx) { return ctx.ReadInt64(); }, delegate(ref WriteContext output, long value) { output.WriteInt64(value); }, CodedOutputStream.ComputeInt64Size, tag, defaultValue); } public static FieldCodec<long> ForSInt64(uint tag, long defaultValue) { return new FieldCodec<long>(delegate(ref ParseContext ctx) { return ctx.ReadSInt64(); }, delegate(ref WriteContext output, long value) { output.WriteSInt64(value); }, CodedOutputStream.ComputeSInt64Size, tag, defaultValue); } public static FieldCodec<ulong> ForFixed64(uint tag, ulong defaultValue) { return new FieldCodec<ulong>(delegate(ref ParseContext ctx) { return ctx.ReadFixed64(); }, delegate(ref WriteContext output, ulong value) { output.WriteFixed64(value); }, 8, tag, defaultValue); } public static FieldCodec<long> ForSFixed64(uint tag, long defaultValue) { return new FieldCodec<long>(delegate(ref ParseContext ctx) { return ctx.ReadSFixed64(); }, delegate(ref WriteContext output, long value) { output.WriteSFixed64(value); }, 8, tag, defaultValue); } public static FieldCodec<ulong> ForUInt64(uint tag, ulong defaultValue) { return new FieldCodec<ulong>(delegate(ref ParseContext ctx) { return ctx.ReadUInt64(); }, delegate(ref WriteContext output, ulong value) { output.WriteUInt64(value); }, CodedOutputStream.ComputeUInt64Size, tag, defaultValue); } public static FieldCodec<float> ForFloat(uint tag, float defaultValue) { return new FieldCodec<float>(delegate(ref ParseContext ctx) { return ctx.ReadFloat(); }, delegate(ref WriteContext output, float value) { output.WriteFloat(value); }, 4, tag, defaultValue); } public static FieldCodec<double> ForDouble(uint tag, double defaultValue) { return new FieldCodec<double>(delegate(ref ParseContext ctx) { return ctx.ReadDouble(); }, delegate(ref WriteContext output, double value) { output.WriteDouble(value); }, 8, tag, defaultValue); } public static FieldCodec<T> ForEnum<T>(uint tag, Func<T, int> toInt32, Func<int, T> fromInt32, T defaultValue) { return new FieldCodec<T>(delegate(ref ParseContext ctx) { return fromInt32(ctx.ReadEnum()); }, delegate(ref WriteContext output, T value) { output.WriteEnum(toInt32(value)); }, (T value) => CodedOutputStream.ComputeEnumSize(toInt32(value)), tag, defaultValue); } public static FieldCodec<T> ForMessage<T>(uint tag, MessageParser<T> parser) where T : class, IMessage<T> { return new FieldCodec<T>(delegate(ref ParseContext ctx) { T val = parser.CreateTemplate(); ctx.ReadMessage(val); return val; }, delegate(ref WriteContext output, T value) { output.WriteMessage(value); }, delegate(ref ParseContext ctx, ref T v) { if (v == null) { v = parser.CreateTemplate(); } ctx.ReadMessage(v); }, delegate(ref T v, T v2) { if (v2 == null) { return false; } if (v == null) { v = v2.Clone(); } else { v.MergeFrom(v2); } return true; }, (T message) => CodedOutputStream.ComputeMessageSize(message), tag); } public static FieldCodec<T> ForGroup<T>(uint startTag, uint endTag, MessageParser<T> parser) where T : class, IMessage<T> { return new FieldCodec<T>(delegate(ref ParseContext ctx) { T val = parser.CreateTemplate(); ctx.ReadGroup(val); return val; }, delegate(ref WriteContext output, T value) { output.WriteGroup(value); }, delegate(ref ParseContext ctx, ref T v) { if (v == null) { v = parser.CreateTemplate(); } ctx.ReadGroup(v); }, delegate(ref T v, T v2) { if (v2 == null) { return v == null; } if (v == null) { v = v2.Clone(); } else { v.MergeFrom(v2); } return true; }, (T message) => CodedOutputStream.ComputeGroupSize(message), startTag, endTag); } public static FieldCodec<T> ForClassWrapper<T>(uint tag) where T : class { FieldCodec<T> nestedCodec = WrapperCodecs.GetCodec<T>(); return new FieldCodec<T>(delegate(ref ParseContext ctx) { return WrapperCodecs.Read(ref ctx, nestedCodec); }, delegate(ref WriteContext output, T value) { WrapperCodecs.Write(ref output, value, nestedCodec); }, delegate(ref ParseContext ctx, ref T v) { v = WrapperCodecs.Read(ref ctx, nestedCodec); }, delegate(ref T v, T v2) { v = v2; return v == null; }, (T value) => WrapperCodecs.CalculateSize(value, nestedCodec), tag, 0u, null); } public static FieldCodec<T?> ForStructWrapper<T>(uint tag) where T : struct { FieldCodec<T> nestedCodec = WrapperCodecs.GetCodec<T>(); return new FieldCodec<T?>(WrapperCodecs.GetReader<T>(), delegate(ref WriteContext output, T? value) { WrapperCodecs.Write(ref output, value.Value, nestedCodec); }, delegate(ref ParseContext ctx, ref T? v) { v = WrapperCodecs.Read(ref ctx, nestedCodec); }, delegate(ref T? v, T? v2) { if (v2.HasValue) { v = v2; } return v.HasValue; }, (T? value) => value.HasValue ? WrapperCodecs.CalculateSize(value.Value, nestedCodec) : 0, tag, 0u, null); } } internal delegate TValue ValueReader<out TValue>(ref ParseContext ctx); internal delegate void ValueWriter<T>(ref WriteContext ctx, T value); public sealed class FieldCodec<T> { internal delegate void InputMerger(ref ParseContext ctx, ref T value); internal delegate bool ValuesMerger(ref T value, T other); private static readonly EqualityComparer<T> EqualityComparer; private static readonly T DefaultDefault; private static readonly bool TypeSupportsPacking; private readonly int tagSize; internal bool PackedRepeatedField { get; } internal ValueWriter<T> ValueWriter { get; } internal Func<T, int> ValueSizeCalculator { get; } internal ValueReader<T> ValueReader { get; } internal InputMerger ValueMerger { get; } internal ValuesMerger FieldMerger { get; } internal int FixedSize { get; } internal uint Tag { get; } internal uint EndTag { get; } internal T DefaultValue { get; } static FieldCodec() { EqualityComparer = ProtobufEqualityComparers.GetEqualityComparer<T>(); TypeSupportsPacking = default(T) != null; if (typeof(T) == typeof(string)) { DefaultDefault = (T)(object)""; } else if (typeof(T) == typeof(ByteString)) { DefaultDefault = (T)(object)ByteString.Empty; } } internal static bool IsPackedRepeatedField(uint tag) { if (TypeSupportsPacking) { return WireFormat.GetTagWireType(tag) == WireFormat.WireType.LengthDelimited; } return false; } internal FieldCodec(ValueReader<T> reader, ValueWriter<T> writer, int fixedSize, uint tag, T defaultValue) : this(reader, writer, (Func<T, int>)((T _) => fixedSize), tag, defaultValue) { FixedSize = fixedSize; } internal FieldCodec(ValueReader<T> reader, ValueWriter<T> writer, Func<T, int> sizeCalculator, uint tag, T defaultValue) : this(reader, writer, (InputMerger)delegate(ref ParseContext ctx, ref T v) { v = reader(ref ctx); }, (ValuesMerger)delegate(ref T v, T v2) { v = v2; return true; }, sizeCalculator, tag, 0u, defaultValue) { } internal FieldCodec(ValueReader<T> reader, ValueWriter<T> writer, InputMerger inputMerger, ValuesMerger valuesMerger, Func<T, int> sizeCalculator, uint tag, uint endTag = 0u) : this(reader, writer, inputMerger, valuesMerger, sizeCalculator, tag, endTag, DefaultDefault) { } internal FieldCodec(ValueReader<T> reader, ValueWriter<T> writer, InputMerger inputMerger, ValuesMerger valuesMerger, Func<T, int> sizeCalculator, uint tag, uint endTag, T defaultValue) { ValueReader = reader; ValueWriter = writer; ValueMerger = inputMerger; FieldMerger = valuesMerger; ValueSizeCalculator = sizeCalculator; FixedSize = 0; Tag = tag; EndTag = endTag; DefaultValue = defaultValue; tagSize = CodedOutputStream.ComputeRawVarint32Size(tag); if (endTag != 0) { tagSize += CodedOutputStream.ComputeRawVarint32Size(endTag); } PackedRepeatedField = IsPackedRepeatedField(tag); } public void WriteTagAndValue(CodedOutputStream output, T value) { WriteContext.Initialize(output, out var ctx); try { WriteTagAndValue(ref ctx, value); } finally { ctx.CopyStateTo(output); } } public void WriteTagAndValue(ref WriteContext ctx, T value) { if (!IsDefault(value)) { ctx.WriteTag(Tag); ValueWriter(ref ctx, value); if (EndTag != 0) { ctx.WriteTag(EndTag); } } } public T Read(CodedInputStream input) { ParseContext.Initialize(input, out var ctx); try { return ValueReader(ref ctx); } finally { ctx.CopyStateTo(input); } } public T Read(ref ParseContext ctx) { return ValueReader(ref ctx); } public int CalculateSizeWithTag(T value) { if (!IsDefault(value)) { return ValueSizeCalculator(value) + tagSize; } return 0; } internal int CalculateUnconditionalSizeWithTag(T value) { return ValueSizeCalculator(value) + tagSize; } private bool IsDefault(T value) { return EqualityComparer.Equals(value, DefaultValue); } } internal sealed class FieldMaskTree { internal sealed class Node { public Dictionary<string, Node> Children { get; } = new Dictionary<string, Node>(); } private const char FIELD_PATH_SEPARATOR = '.'; private readonly Node root = new Node(); public FieldMaskTree() { } public FieldMaskTree(FieldMask mask) { MergeFromFieldMask(mask); } public override string ToString() { return ToFieldMask().ToString(); } public FieldMaskTree AddFieldPath(string path) { string[] array = path.Split(new char[1] { '.' }); if (array.Length == 0) { return this; } Node node = root; bool flag = false; string[] array2 = array; foreach (string key in array2) { if (!flag && node != root && node.Children.Count == 0) { return this; } if (!node.Children.TryGetValue(key, out var value)) { flag = true; value = new Node(); node.Children.Add(key, value); } node = value; } node.Children.Clear(); return this; } public FieldMaskTree MergeFromFieldMask(FieldMask mask) { foreach (string path in mask.Paths) { AddFieldPath(path); } return this; } public FieldMask ToFieldMask() { FieldMask fieldMask = new FieldMask(); if (root.Children.Count != 0) { List<string> list = new List<string>(); GetFieldPaths(root, "", list); fieldMask.Paths.AddRange(list); } return fieldMask; } private void GetFieldPaths(Node node, string path, List<string> paths) { if (node.Children.Count == 0) { paths.Add(path); return; } foreach (KeyValuePair<string, Node> child in node.Children) { string path2 = ((path.Length == 0) ? child.Key : (path + "." + child.Key)); GetFieldPaths(child.Value, path2, paths); } } public void IntersectFieldPath(string path, FieldMaskTree output) { if (root.Children.Count == 0) { return; } string[] array = path.Split(new char[1] { '.' }); if (array.Length == 0) { return; } Node value = root; string[] array2 = array; foreach (string key in array2) { if (value != root && value.Children.Count == 0) { output.AddFieldPath(path); return; } if (!value.Children.TryGetValue(key, out value)) { return; } } List<string> list = new List<string>(); GetFieldPaths(value, path, list); foreach (string item in list) { output.AddFieldPath(item); } } public void Merge(IMessage source, IMessage destination, FieldMask.MergeOptions options) { if (source.Descriptor != destination.Descriptor) { throw new InvalidProtocolBufferException("Cannot merge messages of different types."); } if (root.Children.Count != 0) { Merge(root, "", source, destination, options); } } private void Merge(Node node, string path, IMessage source, IMessage destination, FieldMask.MergeOptions options) { if (source.Descriptor != destination.Descriptor) { throw new InvalidProtocolBufferException($"source ({source.Descriptor}) and destination ({destination.Descriptor}) descriptor must be equal"); } MessageDescriptor descriptor = source.Descriptor; foreach (KeyValuePair<string, Node> child in node.Children) { FieldDescriptor fieldDescriptor = descriptor.FindFieldByName(child.Key); if (fieldDescriptor == null) { continue; } if (child.Value.Children.Count != 0) { if (fieldDescriptor.IsRepeated || fieldDescriptor.FieldType != FieldType.Message) { continue; } object obj = fieldDescriptor.Accessor.GetValue(source); object obj2 = fieldDescriptor.Accessor.GetValue(destination); if (obj != null || obj2 != null) { if (obj2 == null) { obj2 = fieldDescriptor.MessageType.Parser.CreateTemplate(); fieldDescriptor.Accessor.SetValue(destination, obj2); } if (obj == null) { obj = fieldDescriptor.MessageType.Parser.CreateTemplate(); } string path2 = ((path.Length == 0) ? child.Key : (path + "." + child.Key)); Merge(child.Value, path2, (IMessage)obj, (IMessage)obj2, options); } continue; } if (fieldDescriptor.IsRepeated) { if (options.ReplaceRepeatedFields) { fieldDescriptor.Accessor.Clear(destination); } IList obj3 = (IList)fieldDescriptor.Accessor.GetValue(source); IList list = (IList)fieldDescriptor.Accessor.GetValue(destination); foreach (object item in obj3) { list.Add(item); } continue; } object value = fieldDescriptor.Accessor.GetValue(source); if (fieldDescriptor.FieldType == FieldType.Message) { if (options.ReplaceMessageFields) { if (value == null) { fieldDescriptor.Accessor.Clear(destination); } else { fieldDescriptor.Accessor.SetValue(destination, value); } } else { if (value == null) { continue; } if (fieldDescriptor.MessageType.IsWrapperType) { fieldDescriptor.Accessor.SetValue(destination, value); continue; } ByteString data = ((IMessage)value).ToByteString(); IMessage message = (IMessage)fieldDescriptor.Accessor.GetValue(destination); if (message != null) { message.MergeFrom(data); } else { fieldDescriptor.Accessor.SetValue(destination, fieldDescriptor.MessageType.Parser.ParseFrom(data)); } } } else if (value != null || !options.ReplacePrimitiveFields) { fieldDescriptor.Accessor.SetValue(destination, value); } else { fieldDescriptor.Accessor.Clear(destination); } } } } internal static class FrameworkPortability { internal static readonly RegexOptions CompiledRegexWhereAvailable = (System.Enum.IsDefined(typeof(RegexOptions), 8) ? RegexOptions.Compiled : RegexOptions.None); } public interface IBufferMessage : IMessage { void InternalMergeFrom(ref ParseContext ctx); void InternalWriteTo(ref WriteContext ctx); } public interface ICustomDiagnosticMessage : IMessage { string ToDiagnosticString(); } public interface IDeepCloneable<T> { T Clone(); } public interface IExtendableMessage<T> : IMessage<T>, IMessage, IEquatable<T>, IDeepCloneable<T> where T : IExtendableMessage<T> { TValue GetExtension<TValue>(Extension<T, TValue> extension); RepeatedField<TValue> GetExtension<TValue>(RepeatedExtension<T, TValue> extension); RepeatedField<TValue> GetOrInitializeExtension<TValue>(RepeatedExtension<T, TValue> extension); void SetExtension<TValue>(Extension<T, TValue> extension, TValue value); bool HasExtension<TValue>(Extension<T, TValue> extension); void ClearExtension<TValue>(Extension<T, TValue> extension); void ClearExtension<TValue>(RepeatedExtension<T, TValue> extension); } public interface IMessage { MessageDescriptor Descriptor { get; } void MergeFrom(CodedInputStream input); void WriteTo(CodedOutputStream output); int CalculateSize(); } public interface IMessage<T> : IMessage, IEquatable<T>, IDeepCloneable<T> where T : IMessage<T> { void MergeFrom(T message); } public sealed class InvalidJsonException : IOException { internal InvalidJsonException(string message) : base(message) { } } public sealed class InvalidProtocolBufferException : IOException { internal InvalidProtocolBufferException(string message) : base(message) { } internal InvalidProtocolBufferException(string message, Exception innerException) : base(message, innerException) { } internal static InvalidProtocolBufferException MoreDataAvailable() { return new InvalidProtocolBufferException("Completed reading a message while more data was available in the stream."); } internal static InvalidProtocolBufferException TruncatedMessage() { return new InvalidProtocolBufferException("While parsing a protocol message, the input ended unexpectedly in the middle of a field. This could mean either that the input has been truncated or that an embedded message misreported its own length."); } internal static InvalidProtocolBufferException NegativeSize() { return new InvalidProtocolBufferException("CodedInputStream encountered an embedded string or message which claimed to have negative size."); } internal static InvalidProtocolBufferException MalformedVarint() { return new InvalidProtocolBufferException("CodedInputStream encountered a malformed varint."); } internal static InvalidProtocolBufferException InvalidTag() { return new InvalidProtocolBufferException("Protocol message contained an invalid tag (zero)."); } internal static InvalidProtocolBufferException InvalidWireType() { return new InvalidProtocolBufferException("Protocol message contained a tag with an invalid wire type."); } internal static InvalidProtocolBufferException InvalidBase64(Exception innerException) { return new InvalidProtocolBufferException("Invalid base64 data", innerException); } internal static InvalidProtocolBufferException InvalidEndTag() { return new InvalidProtocolBufferException("Protocol message end-group tag did not match expected tag."); } internal static InvalidProtocolBufferException RecursionLimitExceeded() { return new InvalidProtocolBufferException("Protocol message had too many levels of nesting. May be malicious. Use CodedInputStream.SetRecursionLimit() to increase the depth limit."); } internal static InvalidProtocolBufferException JsonRecursionLimitExceeded() { return new InvalidProtocolBufferException("Protocol message had too many levels of nesting. May be malicious. Use JsonParser.Settings to increase the depth limit."); } internal static InvalidProtocolBufferException SizeLimitExceeded() { return new InvalidProtocolBufferException("Protocol message was too large. May be malicious. Use CodedInputStream.SetSizeLimit() to increase the size limit."); } internal static InvalidProtocolBufferException InvalidMessageStreamTag() { return new InvalidProtocolBufferException("Stream of protocol messages had invalid tag. Expected tag is length-delimited field 1."); } internal static InvalidProtocolBufferException MissingFields() { return new InvalidProtocolBufferException("Message was missing required fields"); } } public sealed class JsonFormatter { public sealed class Settings { public static Settings Default { get; } public bool FormatDefaultValues { get; } public TypeRegistry TypeRegistry { get; } public bool FormatEnumsAsIntegers { get; } public bool PreserveProtoFieldNames { get; } public string Indentation { get; } static Settings() { Default = new Settings(formatDefaultValues: false); } public Settings(bool formatDefaultValues) : this(formatDefaultValues, TypeRegistry.Empty) { } public Settings(bool formatDefaultValues, TypeRegistry typeRegistry) : this(formatDefaultValues, typeRegistry, formatEnumsAsIntegers: false, preserveProtoFieldNames: false) { } private Settings(bool formatDefaultValues, TypeRegistry typeRegistry, bool formatEnumsAsIntegers, bool preserveProtoFieldNames, string indentation = null) { FormatDefaultValues = formatDefaultValues; TypeRegistry = typeRegistry ?? TypeRegistry.Empty; FormatEnumsAsIntegers = formatEnumsAsIntegers; PreserveProtoFieldNames = preserveProtoFieldNames; Indentation = indentation; } public Settings WithFormatDefaultValues(bool formatDefaultValues) { return new Settings(formatDefaultValues, TypeRegistry, FormatEnumsAsIntegers, PreserveProtoFieldNames, Indentation); } public Settings WithTypeRegistry(TypeRegistry typeRegistry) { return new Settings(FormatDefaultValues, typeRegistry, FormatEnumsAsIntegers, PreserveProtoFieldNames, Indentation); } public Settings WithFormatEnumsAsIntegers(bool formatEnumsAsIntegers) { return new Settings(FormatDefaultValues, TypeRegistry, formatEnumsAsIntegers, PreserveProtoFieldNames, Indentation); } public Settings WithPreserveProtoFieldNames(bool preserveProtoFieldNames) { return new Settings(FormatDefaultValues, TypeRegistry, FormatEnumsAsIntegers, preserveProtoFieldNames, Indentation); } public Settings WithIndentation(string indentation = " ") { return new Settings(FormatDefaultValues, TypeRegistry, FormatEnumsAsIntegers, PreserveProtoFieldNames, indentation); } } private static class OriginalEnumValueHelper { private static readonly ConcurrentDictionary<System.Type, Dictionary<object, string>> dictionaries = new ConcurrentDictionary<System.Type, Dictionary<object, string>>(); [UnconditionalSuppressMessage("Trimming", "IL2072", Justification = "The field for the value must still be present. It will be returned by reflection, will be in this collection, and its name can be resolved.")] [UnconditionalSuppressMessage("Trimming", "IL2067", Justification = "The field for the value must still be present. It will be returned by reflection, will be in this collection, and its name can be resolved.")] internal static string GetOriginalName(object value) { dictionaries.GetOrAdd(value.GetType(), (System.Type t) => GetNameMapping(t)).TryGetValue(value, out var value2); return value2; } private static Dictionary<object, string> GetNameMapping([DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.NonPublicFields)] System.Type enumType) { return (from f in enumType.GetTypeInfo().DeclaredFields where f.IsStatic where f.GetCustomAttributes<OriginalNameAttribute>().FirstOrDefault()?.PreferredAlias ?? true select f).ToDictionary((FieldInfo f) => f.GetValue(null), (FieldInfo f) => f.GetCustomAttributes<OriginalNameAttribute>().FirstOrDefault()?.Name ?? f.Name); } } internal const string AnyTypeUrlField = "@type"; internal const string AnyDiagnosticValueField = "@value"; internal const string AnyWellKnownTypeValueField = "value"; private const string NameValueSeparator = ": "; private const string ValueSeparator = ", "; private const string MultilineValueSeparator = ","; private const char ObjectOpenBracket = '{'; private const char ObjectCloseBracket = '}'; private const char ListBracketOpen = '['; private const char ListBracketClose = ']'; private static readonly JsonFormatter diagnosticFormatter; private static readonly string[] CommonRepresentations; private readonly Settings settings; private const string Hex = "0123456789abcdef"; public static JsonFormatter Default { get; } private bool DiagnosticOnly => this == diagnosticFormatter; static JsonFormatter() { Default = new JsonFormatter(Settings.Default); diagnosticFormatter = new JsonFormatter(Settings.Default); CommonRepresentations = new string[160] { "\\u0000", "\\u0001", "\\u0002", "\\u0003", "\\u0004", "\\u0005", "\\u0006", "\\u0007", "\\b", "\\t", "\\n", "\\u000b", "\\f", "\\r", "\\u000e", "\\u000f", "\\u0010", "\\u0011", "\\u0012", "\\u0013", "\\u0014", "\\u0015", "\\u0016", "\\u0017", "\\u0018", "\\u0019", "\\u001a", "\\u001b", "\\u001c", "\\u001d", "\\u001e", "\\u001f", "", "", "\\\"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "\\u003c", "", "\\u003e", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "\\\\", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "\\u007f", "\\u0080", "\\u0081", "\\u0082", "\\u0083", "\\u0084", "\\u0085", "\\u0086", "\\u0087", "\\u0088", "\\u0089", "\\u008a", "\\u008b", "\\u008c", "\\u008d", "\\u008e", "\\u008f", "\\u0090", "\\u0091", "\\u0092", "\\u0093", "\\u0094", "\\u0095", "\\u0096", "\\u0097", "\\u0098", "\\u0099", "\\u009a", "\\u009b", "\\u009c", "\\u009d", "\\u009e", "\\u009f" }; for (int i = 0; i < CommonRepresentations.Length; i++) { if (CommonRepresentations[i] == "") { CommonRepresentations[i] = ((char)i).ToString(); } } } public JsonFormatter(Settings settings) { this.settings = ProtoPreconditions.CheckNotNull(settings, "settings"); } public string Format(IMessage message) { return Format(message, 0); } public string Format(IMessage message, int indentationLevel) { StringWriter stringWriter = new StringWriter(); Format(message, stringWriter, indentationLevel); return stringWriter.ToString(); } public void Format(IMessage message, TextWriter writer) { Format(message, writer, 0); } public void Format(IMessage message, TextWriter writer, int indentationLevel) { ProtoPreconditions.CheckNotNull(message, "message"); ProtoPreconditions.CheckNotNull(writer, "writer"); if (message.Descriptor.IsWellKnownType) { WriteWellKnownTypeValue(writer, message.Descriptor, message, indentationLevel); } else { WriteMessage(writer, message, indentationLevel); } } public static string ToDiagnosticString(IMessage message) { ProtoPreconditions.CheckNotNull(message, "message"); return diagnosticFormatter.Format(message); } private void WriteMessage(TextWriter writer, IMessage message, int indentationLevel) { if (message == null) { WriteNull(writer); return; } if (DiagnosticOnly && message is ICustomDiagnosticMessage customDiagnosticMessage) { writer.Write(customDiagnosticMessage.ToDiagnosticString()); return; } WriteBracketOpen(writer, '{'); bool hasFields = WriteMessageFields(writer, message, assumeFirstFieldWritten: false, indentationLevel + 1); WriteBracketClose(writer, '}', hasFields, indentationLevel); } private bool WriteMessageFields(TextWriter writer, IMessage message, bool assumeFirstFieldWritten, int indentationLevel) { MessageDescriptor.FieldCollection fields = message.Descriptor.Fields; bool flag = !assumeFirstFieldWritten; foreach (FieldDescriptor item in fields.InFieldNumberOrder()) { IFieldAccessor accessor = item.Accessor; object value = accessor.GetValue(message); if (ShouldFormatFieldValue(message, item, value)) { MaybeWriteValueSeparator(writer, flag); MaybeWriteValueWhitespace(writer, indentationLevel); if (settings.PreserveProtoFieldNames) { WriteString(writer, accessor.Descriptor.Name); } else { WriteString(writer, accessor.Descriptor.JsonName); } writer.Write(": "); WriteValue(writer, value, indentationLevel); flag = false; } } return !flag; } private void MaybeWriteValueSeparator(TextWriter writer, bool first) { if (!first) { writer.Write((settings.Indentation == null) ? ", " : ","); } } private bool ShouldFormatFieldValue(IMessage message, FieldDescriptor field, object value) { if (!field.HasPresence) { if (!settings.FormatDefaultValues) { return !IsDefaultValue(field, value); } return true; } return field.Accessor.HasValue(message); } internal static string ToJsonName(string name) { StringBuilder stringBuilder = new StringBuilder(name.Length); bool flag = false; foreach (char c in name) { if (c == '_') { flag = true; } else if (flag) { stringBuilder.Append(char.ToUpperInvariant(c)); flag = false; } else { stringBuilder.Append(c); } } return stringBuilder.ToString(); } internal static string FromJsonName(string name) { StringBuilder stringBuilder = new StringBuilder(name.Length); foreach (char c in name) { if (char.IsUpper(c)) { stringBuilder.Append('_'); stringBuilder.Append(char.ToLowerInvariant(c)); } else { stringBuilder.Append(c); } } return stringBuilder.ToString(); } private static void WriteNull(TextWriter writer) { writer.Write("null"); } private static bool IsDefaultValue(FieldDescriptor descriptor, object value) { if (descriptor.IsMap) { return ((IDictionary)value).Count == 0; } if (descriptor.IsRepeated) { return ((IList)value).Count == 0; } switch (descriptor.FieldType) { case FieldType.Bool: return !(bool)value; case FieldType.Bytes: return (ByteString)value == ByteString.Empty; case FieldType.String: return (string)value == ""; case FieldType.Double: return (double)value == 0.0; case FieldType.Int32: case FieldType.SFixed32: case FieldType.SInt32: case FieldType.Enum: return (int)value == 0; case FieldType.Fixed32: case FieldType.UInt32: return (uint)value == 0; case FieldType.UInt64: case FieldType.Fixed64: return (ulong)value == 0; case FieldType.Int64: case FieldType.SFixed64: case FieldType.SInt64: return (long)value == 0; case FieldType.Float: return (float)value == 0f; case FieldType.Group: case FieldType.Message: return value == null; default: throw new ArgumentException("Invalid field type"); } } public void WriteValue(TextWriter writer, object value) { WriteValue(writer, value, 0); } public void WriteValue(TextWriter writer, object value, int indentationLevel) { if (value == null || value is NullValue) { WriteNull(writer); } else if (value is bool flag) { writer.Write(flag ? "true" : "false"); } else if (value is ByteString byteString) { writer.Write('"'); writer.Write(byteString.ToBase64()); writer.Write('"'); } else if (value is string text) { WriteString(writer, text); } else if (value is IDictionary dictionary) { WriteDictionary(writer, dictionary, indentationLevel); } else if (value is IList list) { WriteList(writer, list, indentationLevel); } else if (value is int || value is uint) { IFormattable formattable = (IFormattable)value; writer.Write(formattable.ToString("d", CultureInfo.InvariantCulture)); } else if (value is long || value is ulong) { writer.Write('"'); IFormattable formattable2 = (IFormattable)value; writer.Write(formattable2.ToString("d", CultureInfo.InvariantCulture)); writer.Write('"'); } else if (value is System.Enum) { if (settings.FormatEnumsAsIntegers) { WriteValue(writer, (int)value); return; } string originalName = OriginalEnumValueHelper.GetOriginalName(value); if (originalName != null) { WriteString(writer, originalName); } else { WriteValue(writer, (int)value); } } else if (value is float || value is double) { string text2 = ((IFormattable)value).ToString("r", CultureInfo.InvariantCulture); switch (text2) { case "NaN": case "Infinity": case "-Infinity": writer.Write('"'); writer.Write(text2); writer.Write('"'); break; default: writer.Write(text2); break; } } else { if (!(value is IMessage message)) { throw new ArgumentException("Unable to format value of type " + value.GetType()); } Format(message, writer, indentationLevel); } } private void WriteWellKnownTypeValue(TextWriter writer, MessageDescriptor descriptor, object value, int indentationLevel) { if (value == null) { WriteNull(writer); } else if (descriptor.IsWrapperType) { if (value is IMessage message) { value = message.Descriptor.Fields[1].Accessor.GetValue(message); } WriteValue(writer, value); } else if (descriptor.FullName == Timestamp.Descriptor.FullName) { WriteTimestamp(writer, (IMessage)value); } else if (descriptor.FullName == Duration.Descriptor.FullName) { WriteDuration(writer, (IMessage)value); } else if (descriptor.FullName == FieldMask.Descriptor.FullName) { WriteFieldMask(writer, (IMessage)value); } else if (descriptor.FullName == Struct.Descriptor.FullName) { WriteStruct(writer, (IMessage)value, indentationLevel); } else if (descriptor.FullName == ListValue.Descriptor.FullName) { IFieldAccessor accessor = descriptor.Fields[1].Accessor; WriteList(writer, (IList)accessor.GetValue((IMessage)value), indentationLevel); } else if (descriptor.FullName == Value.Descriptor.FullName) { WriteStructFieldValue(writer, (IMessage)value, indentationLevel); } else if (descriptor.FullName == Any.Descriptor.FullName) { WriteAny(writer, (IMessage)value, indentationLevel); } else { WriteMessage(writer, (IMessage)value, indentationLevel); } } private void WriteTimestamp(TextWriter writer, IMessage value) { int nanoseconds = (int)value.Descriptor.Fields[2].Accessor.GetValue(value); long seconds = (long)value.Descriptor.Fields[1].Accessor.GetValue(value); writer.Write(Timestamp.ToJson(seconds, nanoseconds, DiagnosticOnly)); } private void WriteDuration(TextWriter writer, IMessage value) { int nanoseconds = (int)value.Descriptor.Fields[2].Accessor.GetValue(value); long seconds = (long)value.Descriptor.Fields[1].Accessor.GetValue(value); writer.Write(Duration.ToJson(seconds, nanoseconds, DiagnosticOnly)); } private void WriteFieldMask(TextWriter writer, IMessage value) { IList<string> paths = (IList<string>)value.Descriptor.Fields[1].Accessor.GetValue(value); writer.Write(FieldMask.ToJson(paths, DiagnosticOnly)); } private void WriteAny(TextWriter writer, IMessage value, int indentationLevel) { if (DiagnosticOnly) { WriteDiagnosticOnlyAny(writer, value); return; } string text = (string)value.Descriptor.Fields[1].Accessor.GetValue(value); ByteString data = (ByteString)value.Descriptor.Fields[2].Accessor.GetValue(value); string typeName = Any.GetTypeName(text); MessageDescriptor messageDescriptor = settings.TypeRegistry.Find(typeName); if (messageDescriptor == null) { throw new InvalidOperationException("Type registry has no descriptor for type name '" + typeName + "'"); } IMessage message = messageDescriptor.Parser.ParseFrom(data); WriteBracketOpen(writer, '{'); WriteString(writer, "@type"); writer.Write(": "); WriteString(writer, text); if (messageDescriptor.IsWellKnownType) { writer.Write(", "); WriteString(writer, "value"); writer.Write(": "); WriteWellKnownTypeValue(writer, messageDescriptor, message, indentationLevel); } else { WriteMessageFields(writer, message, assumeFirstFieldWritten: true, indentationLevel); } WriteBracketClose(writer, '}', hasFields: true, indentationLevel); } private void WriteDiagnosticOnlyAny(TextWriter writer, IMessage value) { string text = (string)value.Descriptor.Fields[1].Accessor.GetValue(value); ByteString byteString = (ByteString)value.Descriptor.Fields[2].Accessor.GetValue(value); writer.Write("{ "); WriteString(writer, "@type"); writer.Write(": "); WriteString(writer, text); writer.Write(", "); WriteString(writer, "@value"); writer.Write(": "); writer.Write('"'); writer.Write(byteString.ToBase64()); writer.Write('"'); writer.Write(" }"); } private void WriteStruct(TextWriter writer, IMessage message, int indentationLevel) { WriteBracketOpen(writer, '{'); IDictionary obj = (IDictionary)message.Descriptor.Fields[1].Accessor.GetValue(message); bool flag = true; foreach (DictionaryEntry item in obj) { string text = (string)item.Key; IMessage message2 = (IMessage)item.Value; if (string.IsNullOrEmpty(text) || message2 == null) { throw new InvalidOperationException("Struct fields cannot have an empty key or a null value."); } MaybeWriteValueSeparator(writer, flag); MaybeWriteValueWhitespace(writer, indentationLevel + 1); WriteString(writer, text); writer.Write(": "); WriteStructFieldValue(writer, message2, indentationLevel + 1); flag = false; } WriteBracketClose(writer, '}', !flag, indentationLevel); } private void WriteStructFieldValue(TextWriter writer, IMessage message, int indentationLevel) { FieldDescriptor caseFieldDescriptor = message.Descriptor.Oneofs[0].Accessor.GetCaseFieldDescriptor(message); if (caseFieldDescriptor == null) { throw new InvalidOperationException("Value message must contain a value for the oneof."); } object value = caseFieldDescriptor.Accessor.GetValue(message); switch (caseFieldDescriptor.FieldNumber) { case 2: case 3: case 4: WriteValue(writer, value); break; case 5: case 6: { IMessage message2 = (IMessage)caseFieldDescriptor.Accessor.GetValue(message); WriteWellKnownTypeValue(writer, message2.Descriptor, message2, indentationLevel); break; } case 1: WriteNull(writer); break; default: throw new InvalidOperationException("Unexpected case in struct field: " + caseFieldDescriptor.FieldNumber); } } internal void WriteList(TextWriter writer, IList list, int indentationLevel = 0) { WriteBracketOpen(writer, '['); bool flag = true; foreach (object item in list) { MaybeWriteValueSeparator(writer, flag); MaybeWriteValueWhitespace(writer, indentationLevel + 1); WriteValue(writer, item, indentationLevel + 1); flag = false; } WriteBracketClose(writer, ']', !flag, indentationLevel); } internal void WriteDictionary(TextWriter writer, IDictionary dictionary, int indentationLevel = 0) { WriteBracketOpen(writer, '{'); bool flag = true; foreach (DictionaryEntry item in dictionary) { string text2; if (item.Key is string text) { text2 = text; } else { object key = item.Key; if (key is bool) { text2 = (((bool)key) ? "true" : "false"); } else { if (!(item.Key is int) && !(item.Key is uint) && !(item.Key is long) && !(item.Key is ulong)) { if (item.Key == null) { throw new ArgumentException("Dictionary has entry with null key"); } throw new ArgumentException("Unhandled dictionary key type: " + item.Key.GetType()); } text2 = ((IFormattable)item.Key).ToString("d", CultureInfo.InvariantCulture); } } MaybeWriteValueSeparator(writer, flag); MaybeWriteValueWhitespace(writer, indentationLevel + 1); WriteString(writer, text2); writer.Write(": "); WriteValue(writer, item.Value, indentationLevel + 1); flag = false; } WriteBracketClose(writer, '}', !flag, indentationLevel); } internal static void WriteString(TextWriter writer, string text) { writer.Write('"'); for (int i = 0; i < text.Length; i++) { char c = text[i]; if (c < '\u00a0') { writer.Write(CommonRepresentations[(uint)c]); continue; } if (char.IsHighSurrogate(c)) { i++; if (i == text.Length || !char.IsLowSurrogate(text[i])) { throw new ArgumentException("String contains low surrogate not followed by high surrogate"); } HexEncodeUtf16CodeUnit(writer, c); HexEncodeUtf16CodeUnit(writer, text[i]); continue; } if (char.IsLowSurrogate(c)) { throw new ArgumentException("String contains high surrogate not preceded by low surrogate"); } switch (c) { case 173u: case 1757u: case 1807u: case 6068u: case 6069u: case 65279u: case 65529u: case 65530u: case 65531u: HexEncodeUtf16CodeUnit(writer, c); continue; } if ((c >= '\u0600' && c <= '\u0603') || (c >= '\u200b' && c <= '\u200f') || (c >= '\u2028' && c <= '\u202e') || (c >= '\u2060' && c <= '\u2064') || (c >= '\u206a' && c <= '\u206f')) { HexEncodeUtf16CodeUnit(writer, c); } else { writer.Write(c); } } writer.Write('"'); } private static void HexEncodeUtf16CodeUnit(TextWriter writer, char c) { writer.Write("\\u"); writer.Write("0123456789abcdef"[((int)c >> 12) & 0xF]); writer.Write("0123456789abcdef"[((int)c >> 8) & 0xF]); writer.Write("0123456789abcdef"[((int)c >> 4) & 0xF]); writer.Write("0123456789abcdef"[c & 0xF]); } private void WriteBracketOpen(TextWriter writer, char openChar) { writer.Write(openChar); if (settings.Indentation == null) { writer.Write(' '); } } private void WriteBracketClose(TextWriter writer, char closeChar, bool hasFields, int indentationLevel) { if (hasFields) { if (settings.Indentation != null) { writer.WriteLine(); WriteIndentation(writer, indentationLevel); } else { writer.Write(" "); } } writer.Write(closeChar); } private void MaybeWriteValueWhitespace(TextWriter writer, int indentationLevel) { if (settings.Indentation != null) { writer.WriteLine(); WriteIndentation(writer, indentationLevel); } } private void WriteIndentation(TextWriter writer, int indentationLevel) { for (int i = 0; i < indentationLevel; i++) { writer.Write(settings.Indentation); } } } public sealed class JsonParser { public sealed class Settings { public static Settings Default { get; } public int RecursionLimit { get; } public TypeRegistry TypeRegistry { get; } public bool IgnoreUnknownFields { get; } static Settings() { Default = new Settings(100); } private Settings(int recursionLimit, TypeRegistry typeRegistry, bool ignoreUnknownFields) { RecursionLimit = recursionLimit; TypeRegistry = ProtoPreconditions.CheckNotNull(typeRegistry, "typeRegistry"); IgnoreUnknownFields = ignoreUnknownFields; } public Settings(int recursionLimit) : this(recursionLimit, TypeRegistry.Empty) { } public Settings(int recursionLimit, TypeRegistry typeRegistry) : this(recursionLimit, typeRegistry, ignoreUnknownFields: false) { } public Settings WithIgnoreUnknownFields(bool ignoreUnknownFields) { return new Settings(RecursionLimit, TypeRegistry, ignoreUnknownFields); } public Settings WithRecursionLimit(int recursionLimit) { return new Settings(recursionLimit, TypeRegistry, IgnoreUnknownFields); } public Settings WithTypeRegistry(TypeRegistry typeRegistry) { return new Settings(RecursionLimit, ProtoPreconditions.CheckNotNull(typeRegistry, "typeRegistry"), IgnoreUnknownFields); } } private static readonly Regex TimestampRegex = new Regex("^(?<datetime>[0-9]{4}-[01][0-9]-[0-3][0-9]T[012][0-9]:[0-5][0-9]:[0-5][0-9])(?<subseconds>\\.[0-9]{1,9})?(?<offset>(Z|[+-][0-1][0-9]:[0-5][0-9]))$", FrameworkPortability.CompiledRegexWhereAvailable); private static readonly Regex DurationRegex = new Regex("^(?<sign>-)?(?<int>[0-9]{1,12})(?<subseconds>\\.[0-9]{1,9})?s$", FrameworkPortability.CompiledRegexWhereAvailable); private static readonly int[] SubsecondScalingFactors = new int[11] { 0, 100000000, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1 }; private static readonly char[] FieldMaskPathSeparators = new char[1] { ',' }; private static readonly EnumDescriptor NullValueDescriptor = StructReflection.Descriptor.EnumTypes.Single((EnumDescriptor ed) => ed.ClrType == typeof(NullValue)); private static readonly JsonParser defaultInstance = new JsonParser(Settings.Default); private static readonly Dictionary<string, Action<JsonParser, IMessage, JsonTokenizer>> WellKnownTypeHandlers = new Dictionary<string, Action<JsonParser, IMessage, JsonTokenizer>> { { Timestamp.Descriptor.FullName, delegate(JsonParser parser, IMessage message, JsonTokenizer tokenizer) { MergeTimestamp(message, tokenizer.Next()); } }, { Duration.Descriptor.FullName, delegate(JsonParser parser, IMessage message, JsonTokenizer tokenizer) { MergeDuration(message, tokenizer.Next()); } }, { Value.Descriptor.FullName, delegate(JsonParser parser, IMessage message, JsonTokenizer tokenizer) { parser.MergeStructValue(message, tokenizer); } }, { ListValue.Descriptor.FullName, delegate(JsonParser parser, IMessage message, JsonTokenizer tokenizer) { parser.MergeRepeatedField(message, message.Descriptor.Fields[1], tokenizer); } }, { Struct.Descriptor.FullName, delegate(JsonParser parser, IMessage message, JsonTokenizer tokenizer) { parser.MergeStruct(message, tokenizer); } }, { Any.Descriptor.FullName, delegate(JsonParser parser, IMessage message, JsonTokenizer tokenizer) { parser.MergeAny(message, tokenizer); } }, { FieldMask.Descriptor.FullName, delegate(JsonParser parser, IMessage message, JsonTokenizer tokenizer) { MergeFieldMask(message, tokenizer.Next()); } }, { Int32Value.Descriptor.FullName, MergeWrapperField }, { Int64Value.Descriptor.FullName, MergeWrapperField }, { UInt32Value.Descriptor.FullName, MergeWrapperField }, { UInt64Value.Descriptor.FullName, MergeWrapperField }, { FloatValue.Descriptor.FullName, MergeWrapperFi