Decompiled source of Netstat v1.0.6

Netstat.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Globals;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Netstat.Config;
using Netstat.Grapher;
using Netstat.Telemetry;
using Netstat.UI;
using Player;
using SNetwork;
using Steamworks;
using TMPro;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("Netstat")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("Netstat")]
[assembly: AssemblyTitle("Netstat")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
}
namespace Netstat
{
	public class CuteBehaviour : MonoBehaviour
	{
		public CuteBehaviour(IntPtr ptr)
			: base(ptr)
		{
		}
	}
	internal static class Logger
	{
		private static ManualLogSource _mLogSource;

		public static bool Ready => _mLogSource != null;

		public static void Setup()
		{
			_mLogSource = Logger.CreateLogSource("food.randomuser.gtfo.Netstat");
		}

		public static void SetupFromInit(ManualLogSource logSource)
		{
			_mLogSource = logSource;
		}

		private static string Format(object data)
		{
			return data.ToString();
		}

		public static void Debug(object msg)
		{
			if (ConfigMgr.Debug)
			{
				_mLogSource.LogInfo((object)(" [DEBUG] " + Format(msg)));
			}
		}

		public static void Debug(string fmt, params object[] args)
		{
			if (ConfigMgr.Debug)
			{
				_mLogSource.LogInfo((object)("[DEBUG] " + Format(string.Format(fmt, args))));
			}
			else
			{
				_mLogSource.LogDebug((object)Format(string.Format(fmt, args)));
			}
		}

		public static void Info(object msg)
		{
			_mLogSource.LogInfo((object)Format(msg));
		}

		public static void Info(string fmt, params object[] args)
		{
			_mLogSource.LogInfo((object)Format(string.Format(fmt, args)));
		}

		public static void Warn(object msg)
		{
			_mLogSource.LogWarning((object)Format(msg));
		}

		public static void Warn(string fmt, params object[] args)
		{
			_mLogSource.LogWarning((object)Format(string.Format(fmt, args)));
		}

		public static void Error(object msg)
		{
			_mLogSource.LogError((object)Format(msg));
		}

		public static void Error(string fmt, params object[] args)
		{
			_mLogSource.LogError((object)Format(string.Format(fmt, args)));
		}

		public static void Fatal(object msg)
		{
			_mLogSource.LogFatal((object)Format(msg));
		}

		public static void Fatal(string fmt, params object[] args)
		{
			_mLogSource.LogFatal((object)Format(string.Format(fmt, args)));
		}
	}
	public static class NetstatAPI
	{
		public enum PingerTypeEnum
		{
			Chat,
			Marker
		}

		public static PingerTypeEnum PingerType => ConfigMgr.PingerType;

		public static float Ping
		{
			get
			{
				if (PingerType != 0)
				{
					return MarkerPinger.Ping;
				}
				return ChatPinger.Ping;
			}
		}

		public static float RawPing
		{
			get
			{
				if (PingerType != 0)
				{
					return MarkerPinger.RawPing;
				}
				return ChatPinger.RawPing;
			}
		}

		public static int PingMs => (int)(Ping * 1000f);

		public static int RawPingMs => (int)(RawPing * 1000f);

		public static float Jitter
		{
			get
			{
				if (PingerType != 0)
				{
					return MarkerPinger.Jitter;
				}
				return ChatPinger.Jitter;
			}
		}

		public static float RawJitter
		{
			get
			{
				if (PingerType != 0)
				{
					return MarkerPinger.RawJitter;
				}
				return ChatPinger.RawJitter;
			}
		}

		public static float JitterMs => (int)(Jitter * 1000f);

		public static float RawJitterMs => (int)(RawJitter * 1000f);

		public static bool IsPingerActive
		{
			get
			{
				if (PingerType != 0)
				{
					return MarkerPinger.IsMeasuring;
				}
				return true;
			}
		}

		public static bool IsDesynced
		{
			get
			{
				if (PingerType != 0)
				{
					return MarkerPinger.IsDesynced;
				}
				return ChatPinger.IsDesynced;
			}
		}

		public static ReadOnlySpan<ChannelStats> Channels => SteamP2P.Channels;

		public static uint BytesReceived => SteamP2P.BytesReceived;

		public static uint PacketsReceived => SteamP2P.PacketsReceived;

		public static uint BytesSent => SteamP2P.BytesSent;

		public static uint PacketsSent => SteamP2P.PacketsSent;

		public static int BytesQueuedForSend => SteamP2P.BytesQueuedForSend;

		public static int PacketsQueuedForSend => SteamP2P.PacketsQueuedForSend;

		public static TickStats GetTickStat(ulong steamId)
		{
			return TickTimer.GetTickStat(steamId);
		}
	}
	[BepInPlugin("food.randomuser.gtfo.Netstat", "Netstat", "1.0.6")]
	public class Plugin : BasePlugin
	{
		public const string NAME = "Netstat";

		public const string GUID = "food.randomuser.gtfo.Netstat";

		public const string VERSION = "1.0.6";

		private GameObject _netstatObj;

		public event Action? OnManagersSetup;

		public override void Load()
		{
			//IL_0019: 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_00a2: Expected O, but got Unknown
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Expected O, but got Unknown
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Expected O, but got Unknown
			//IL_00d3: Expected O, but got Unknown
			Logger.Setup();
			Logger.Info("Netstat [food.randomuser.gtfo.Netstat @ 1.0.6]");
			Harmony val = new Harmony("food.randomuser.gtfo.Netstat");
			ConfigMgr.Init();
			ClassInjector.RegisterTypeInIl2Cpp<UIManager>();
			ClassInjector.RegisterTypeInIl2Cpp<StatGraph>();
			ClassInjector.RegisterTypeInIl2Cpp<ChatPinger>();
			ClassInjector.RegisterTypeInIl2Cpp<MarkerPinger>();
			ClassInjector.RegisterTypeInIl2Cpp<SteamP2P>();
			ClassInjector.RegisterTypeInIl2Cpp<TickTimer>();
			ClassInjector.RegisterTypeInIl2Cpp<Plotter>();
			ClassInjector.RegisterTypeInIl2Cpp<CuteBehaviour>();
			OnManagersSetup += Initialize;
			Global.OnAllManagersSetup += Action.op_Implicit(this.OnManagersSetup);
			Logger.Info("Patching...");
			RundownManager.OnExpeditionGameplayStarted += Action.op_Implicit((Action)MarkerPinger.Start);
			ApplyPatch<MarkerPinger>(val);
			ApplyPatch<ChatPinger>(val);
			ApplyPatch<SteamP2P>(val);
			RundownManager.OnExpeditionGameplayStarted += Action.op_Implicit((Action)TickTimer.Start);
			ApplyPatch<TickTimer>(val);
			Logger.Info("Finished Patching");
		}

		private static void ApplyPatch<T>(Harmony h)
		{
			h.PatchAll(typeof(T));
		}

		private void Initialize()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			_netstatObj = new GameObject("food.randomuser.gtfo.Netstat");
			Object.DontDestroyOnLoad((Object)(object)_netstatObj);
			_netstatObj.AddComponent<ChatPinger>();
			_netstatObj.AddComponent<MarkerPinger>();
			_netstatObj.AddComponent<SteamP2P>();
			_netstatObj.AddComponent<TickTimer>();
			_netstatObj.AddComponent<UIManager>();
			_netstatObj.AddComponent<CuteBehaviour>();
		}

		public override bool Unload()
		{
			return true;
		}
	}
	public static class Util
	{
		private static readonly string[] _siAbbrs = new string[7] { "", "K", "M", "G", "T", "P", "E" };

		public static Vector3 Extend(this Vector2 v, float z = 0f)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			return new Vector3(v.x, v.y, z);
		}

		public static int TrueMod(int n, int m)
		{
			return (n % m + m) % m;
		}

		public static string Value2SIAbbrStr(float value, bool includeOneDecimalWhenValueLessThan10 = true)
		{
			bool flag = value < 1000f;
			int num = 0;
			while (value >= 1000f && num < _siAbbrs.Length - 1)
			{
				value /= 1000f;
				num++;
			}
			string text = ((!flag && includeOneDecimalWhenValueLessThan10 && value < 10f) ? "0.0" : "0");
			return value.ToString(text) + _siAbbrs[num];
		}
	}
}
namespace Netstat.UI
{
	[Flags]
	public enum eNetstatData
	{
		Ping = 1,
		Rx = 2,
		Tx = 4,
		CTT = 8,
		STT = 0x10
	}
	[Flags]
	public enum eNetstatGraph
	{
		Ping = 1,
		RxTx = 2,
		RxChan = 4,
		TxChan = 8,
		CSTT = 0x10
	}
	public class StatConfigLib
	{
		public static readonly StatGraphConfig Ping = new StatGraphConfig
		{
			Sources = StatSourceLib.WPing,
			Unit = "ms",
			PlotMin = 0f,
			PlotMax = 500f,
			PlotAutoScale = true,
			PlotAutoScaleIncrement = 50f,
			AbbreviateWithSIPrefix = false,
			SampleRate = 2f,
			Precision = 0u
		};

		public static readonly StatGraphConfig RxTx = new StatGraphConfig
		{
			Sources = StatSourceLib.WRxTx,
			Unit = "B/s",
			PlotMin = 0f,
			PlotMax = 1000f,
			PlotAutoScale = true,
			PlotAutoScaleIncrement = 500f,
			AbbreviateWithSIPrefix = true,
			SampleRate = 2f,
			Precision = 0u
		};

		public static readonly StatGraphConfig RxChannelsShort = new StatGraphConfig
		{
			Sources = StatSourceLib.WRxChannelsShort,
			Unit = "B/s",
			PlotMin = 0f,
			PlotMax = 1000f,
			PlotAutoScale = true,
			PlotAutoScaleIncrement = 500f,
			AbbreviateWithSIPrefix = true,
			SampleRate = 2f,
			Precision = 0u
		};

		public static readonly StatGraphConfig TxChannelsShort = new StatGraphConfig
		{
			Sources = StatSourceLib.WTxChannelsShort,
			Unit = "B/s",
			PlotMin = 0f,
			PlotMax = 1000f,
			PlotAutoScale = true,
			PlotAutoScaleIncrement = 500f,
			AbbreviateWithSIPrefix = true,
			SampleRate = 2f,
			Precision = 0u
		};

		public static readonly StatGraphConfig CSTT = new StatGraphConfig
		{
			Sources = StatSourceLib.WCSTT,
			Unit = "ms",
			PlotMin = 0f,
			PlotMax = 200f,
			PlotAutoScale = true,
			PlotAutoScaleIncrement = 50f,
			AbbreviateWithSIPrefix = false,
			SampleRate = 2f,
			Precision = 0u
		};

		public static eNetstatGraph Str2GraphType(string key)
		{
			return key switch
			{
				"ping" => eNetstatGraph.Ping, 
				"rxtx" => eNetstatGraph.RxTx, 
				"rxchan" => eNetstatGraph.RxChan, 
				"txchan" => eNetstatGraph.TxChan, 
				"cstt" => eNetstatGraph.CSTT, 
				_ => (eNetstatGraph)0, 
			};
		}

		public static bool TryGet(string key, out StatGraphConfig conf)
		{
			return TryGet(Str2GraphType(key), out conf);
		}

		public static bool TryGet(eNetstatGraph type, out StatGraphConfig conf)
		{
			switch (type)
			{
			case eNetstatGraph.Ping:
				conf = Ping;
				break;
			case eNetstatGraph.RxTx:
				conf = RxTx;
				break;
			case eNetstatGraph.RxChan:
				conf = RxChannelsShort;
				break;
			case eNetstatGraph.TxChan:
				conf = TxChannelsShort;
				break;
			case eNetstatGraph.CSTT:
				conf = CSTT;
				break;
			default:
				conf = default(StatGraphConfig);
				return false;
			}
			return true;
		}
	}
	public class StatGraph : MonoBehaviour
	{
		public struct DataSource
		{
			public string Label;

			public Func<float> ValueProvider;

			public Color? Color;
		}

		private RectTransform? _rt;

		private bool _dirty;

		private DataSource[] _dataSources = Array.Empty<DataSource>();

		private static readonly List<Color> PlotLineColors = new List<Color>
		{
			new Color(0.12f, 0.47f, 0.71f),
			new Color(1f, 0.5f, 0.05f),
			new Color(0.17f, 0.63f, 0.17f),
			new Color(0.84f, 0.15f, 0.16f),
			new Color(0.58f, 0.4f, 0.74f),
			new Color(0.55f, 0.34f, 0.29f)
		};

		private Color32 _textColor = new Color32((byte)227, (byte)227, (byte)227, (byte)227);

		private readonly List<TextMeshProUGUI?> _labelTexts = new List<TextMeshProUGUI>();

		private readonly List<TextMeshProUGUI?> _valueTexts = new List<TextMeshProUGUI>();

		private TextMeshProUGUI? _graphMaxText;

		private TextMeshProUGUI? _graphMinText;

		private TextMeshProUGUI? _graphTimeText;

		private Plotter? _plot;

		private const float BlockHeight = 12f;

		private const float ElementSpacing = 4f;

		private float _sampleRate = 2f;

		private float _sampleInterval = 0.5f;

		private float _timeSinceLastSample;

		public RectTransform RT
		{
			get
			{
				if ((Object)(object)_rt == (Object)null)
				{
					_rt = ((Component)this).GetComponent<RectTransform>();
				}
				return _rt;
			}
		}

		public Vector2 Size => RT.sizeDelta;

		public Vector2 PlotSize
		{
			get
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				return Plot.PlotSize;
			}
			set
			{
				//IL_0006: Unknown result type (might be due to invalid IL or missing references)
				Plot.PlotSize = value;
			}
		}

		public Plotter Plot => _plot ?? throw new NullReferenceException("StatGraph[" + ((Object)this).name + "] No plotter assigned.");

		private float DesiredClearance => (float)_dataSources.Length * 16f;

		public Color32 TextColor
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _textColor;
			}
			set
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				_textColor = value;
				_dirty = true;
			}
		}

		public string Unit { get; set; }

		public uint Precision { get; set; } = 1u;


		public bool AbbreviateWithSIUnit { get; set; }

		public float SampleRate
		{
			get
			{
				return _sampleRate;
			}
			set
			{
				_sampleRate = value;
				_sampleInterval = 1f / _sampleRate;
			}
		}

		public StatGraph(IntPtr ptr)
			: base(ptr)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			Unit = "";
		}

		public static StatGraph Create(Transform parent, Vector2 graphSize, StatGraphConfig config)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			return Create(parent, config.Sources, config.Unit, graphSize, config.PlotMin, config.PlotMax, config.PlotAutoScale, config.PlotAutoScaleIncrement, config.ObjectName, config.AbbreviateWithSIPrefix, config.SampleRate, config.Precision);
		}

		public static StatGraph Create(Transform parent, DataSource[] sources, string unit, Vector2 plotSize, float min = 0f, float max = 1f, bool autoScale = true, float autoScaleInc = -1f, string objName = "", bool abbrValWithSI = false, float sampleRate = 2f, uint precision = 0u)
		{
			//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_00b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0124: Unknown result type (might be due to invalid IL or missing references)
			//IL_0139: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject((objName == "") ? ("StatGraph." + sources.Select((DataSource s) => s.Label).Aggregate((string str0, string str1) => str0 + "_" + str1)) : objName);
			RectTransform val2 = val.AddComponent<RectTransform>();
			((Transform)val2).SetParent(parent, false);
			StatGraph statGraph = val.AddComponent<StatGraph>();
			statGraph._rt = val2;
			statGraph._dataSources = sources;
			statGraph.Unit = unit;
			statGraph.AbbreviateWithSIUnit = abbrValWithSI;
			statGraph.SampleRate = sampleRate;
			statGraph.Precision = precision;
			Plotter plotter = ((Component)statGraph).gameObject.AddComponent<Plotter>();
			plotter.PlotSize = plotSize;
			plotter.SetAutoScale(autoScale);
			plotter.SetGraphMinMax(min, max);
			plotter.SetAutoScaleIncrement(autoScaleInc);
			plotter.AfterPopulateMesh += statGraph.DrawLegendIdentifiers;
			plotter.AfterPopulateMesh += statGraph.DrawMaxTick;
			statGraph._plot = plotter;
			val2.anchorMin = new Vector2(0.5f, 0.5f);
			val2.anchorMax = new Vector2(0.5f, 0.5f);
			val2.pivot = new Vector2(1f, 0f);
			val2.anchoredPosition3D = Vector3.zero;
			statGraph.Recreate();
			if (TMPUtil.CreateTMPUGUI("GraphMax", (Transform?)(object)statGraph.RT, out TextMeshProUGUI tp))
			{
				statGraph._graphMaxText = tp;
			}
			if (TMPUtil.CreateTMPUGUI("GraphMin", (Transform?)(object)statGraph.RT, out TextMeshProUGUI tp2))
			{
				statGraph._graphMinText = tp2;
			}
			if (TMPUtil.CreateTMPUGUI("Time", (Transform?)(object)statGraph.RT, out TextMeshProUGUI tp3))
			{
				statGraph._graphTimeText = tp3;
			}
			statGraph.Reconfigure();
			return statGraph;
		}

		public void UpdateSources(DataSource[] sources)
		{
			if (sources.Length != _dataSources.Length)
			{
				_dataSources = sources;
				Recreate();
				Reconfigure();
			}
			else
			{
				_dataSources = sources;
				Reconfigure();
			}
		}

		private void Recreate()
		{
			foreach (TextMeshProUGUI labelText in _labelTexts)
			{
				if ((Object)(object)labelText != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)labelText).gameObject);
				}
			}
			foreach (TextMeshProUGUI valueText in _valueTexts)
			{
				if ((Object)(object)valueText != (Object)null)
				{
					Object.Destroy((Object)(object)((Component)valueText).gameObject);
				}
			}
			_labelTexts.Clear();
			_valueTexts.Clear();
			for (int i = 0; i < _dataSources.Length; i++)
			{
				if (TMPUtil.CreateTMPUGUI($"Label.C{i}", (Transform?)(object)RT, out TextMeshProUGUI tp))
				{
					((TMP_Text)tp).text = _dataSources[i].Label;
					_labelTexts.Add(tp);
				}
				if (TMPUtil.CreateTMPUGUI($"Value.C{i}", (Transform?)(object)RT, out TextMeshProUGUI tp2))
				{
					_valueTexts.Add(tp2);
				}
			}
		}

		private void Reconfigure()
		{
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0116: Unknown result type (might be due to invalid IL or missing references)
			//IL_0123: Unknown result type (might be due to invalid IL or missing references)
			//IL_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0177: Unknown result type (might be due to invalid IL or missing references)
			//IL_0188: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_03aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_03bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0409: Unknown result type (might be due to invalid IL or missing references)
			//IL_0411: Unknown result type (might be due to invalid IL or missing references)
			//IL_0419: Unknown result type (might be due to invalid IL or missing references)
			//IL_0427: Unknown result type (might be due to invalid IL or missing references)
			//IL_0436: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_044f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0451: Unknown result type (might be due to invalid IL or missing references)
			//IL_0456: Unknown result type (might be due to invalid IL or missing references)
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0464: Unknown result type (might be due to invalid IL or missing references)
			//IL_0469: Unknown result type (might be due to invalid IL or missing references)
			//IL_046b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0472: Unknown result type (might be due to invalid IL or missing references)
			//IL_025d: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_02be: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02de: Unknown result type (might be due to invalid IL or missing references)
			//IL_030a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0311: Unknown result type (might be due to invalid IL or missing references)
			//IL_04db: Unknown result type (might be due to invalid IL or missing references)
			//IL_04ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_053a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0542: Unknown result type (might be due to invalid IL or missing references)
			//IL_054a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0558: Unknown result type (might be due to invalid IL or missing references)
			//IL_0567: Unknown result type (might be due to invalid IL or missing references)
			//IL_058a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0591: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_060b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0659: Unknown result type (might be due to invalid IL or missing references)
			//IL_0661: Unknown result type (might be due to invalid IL or missing references)
			//IL_0669: Unknown result type (might be due to invalid IL or missing references)
			//IL_0677: Unknown result type (might be due to invalid IL or missing references)
			//IL_0686: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_06a8: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_plot == (Object)null)
			{
				Logger.Error("StatGraph[" + ((Object)this).name + "] No plotter assigned.");
				return;
			}
			_plot.SetClearance(DesiredClearance);
			_plot.AllocateChannels(_dataSources.Length);
			for (int i = 0; i < _dataSources.Length; i++)
			{
				Color c = (Color)(((??)_dataSources[i].Color) ?? PlotLineColors[i]);
				_plot.SetColor(Plotter.PlotComponent.Line, c, i);
			}
			string fmt = "StatGraph[" + ((Object)this).name + "]->{0} UI reconfigure failed, is null.";
			Vector2 val2 = default(Vector2);
			Vector2 v = default(Vector2);
			Vector2 val4 = default(Vector2);
			Vector2 v2 = default(Vector2);
			for (int j = 0; j < _dataSources.Length; j++)
			{
				TextMeshProUGUI val = _labelTexts[j];
				if ((Object)(object)val != (Object)null)
				{
					((TMP_Text)val).SetText(_dataSources[j].Label, true);
					((Vector2)(ref val2))..ctor(0f, 1f);
					((TMP_Text)val).alignment = (TextAlignmentOptions)513;
					((Graphic)val).color = Color.white;
					((TMP_Text)val).faceColor = TextColor;
					((TMP_Text)val).autoSizeTextContainer = false;
					((TMP_Text)val).enableAutoSizing = true;
					((TMP_Text)val).fontSizeMax = 20f;
					((TMP_Text)val).fontSizeMin = 16f;
					RectTransform rectTransform = ((TMP_Text)val).rectTransform;
					rectTransform.anchorMax = val2;
					rectTransform.anchorMin = val2;
					rectTransform.pivot = new Vector2(0f, 0.5f);
					rectTransform.sizeDelta = new Vector2(_plot.Size.x - 12f - 4f, 12f);
					((Vector2)(ref v))..ctor(16f, 0f - ((float)j * 16f + 4f + 6f));
					rectTransform.anchoredPosition3D = v.Extend();
				}
				else
				{
					Logger.Warn(fmt, $"C{j}:Label");
				}
				TextMeshProUGUI val3 = _valueTexts[j];
				if ((Object)(object)val3 != (Object)null)
				{
					((Vector2)(ref val4))..ctor(1f, 1f);
					((TMP_Text)val3).alignment = (TextAlignmentOptions)516;
					((Graphic)val3).color = Color.white;
					((TMP_Text)val3).faceColor = TextColor;
					((TMP_Text)val3).autoSizeTextContainer = false;
					((TMP_Text)val3).enableAutoSizing = true;
					((TMP_Text)val3).fontSizeMax = 20f;
					((TMP_Text)val3).fontSizeMin = 16f;
					RectTransform rectTransform2 = ((TMP_Text)val3).rectTransform;
					rectTransform2.anchorMax = val4;
					rectTransform2.anchorMin = val4;
					rectTransform2.pivot = new Vector2(1f, 0.5f);
					rectTransform2.sizeDelta = new Vector2(_plot.Size.x, 12f);
					((Vector2)(ref v2))..ctor(-4f, 0f - ((float)j * 16f + 4f + 6f));
					rectTransform2.anchoredPosition3D = v2.Extend();
				}
				else
				{
					Logger.Warn(fmt, $"C{j}:Value");
				}
			}
			if ((Object)(object)_graphTimeText != (Object)null)
			{
				Vector2 val5 = default(Vector2);
				((Vector2)(ref val5))..ctor(0f, 0f);
				((TMP_Text)_graphTimeText).alignment = (TextAlignmentOptions)1025;
				((Graphic)_graphTimeText).color = Color.white;
				((TMP_Text)_graphTimeText).faceColor = TextColor;
				((TMP_Text)_graphTimeText).autoSizeTextContainer = false;
				((TMP_Text)_graphTimeText).enableAutoSizing = true;
				((TMP_Text)_graphTimeText).fontSizeMax = 20f;
				((TMP_Text)_graphTimeText).fontSizeMin = 16f;
				RectTransform rectTransform3 = ((TMP_Text)_graphTimeText).rectTransform;
				rectTransform3.anchorMax = val5;
				rectTransform3.anchorMin = val5;
				rectTransform3.pivot = val5;
				rectTransform3.sizeDelta = new Vector2(_plot.Size.x, 12f);
				Vector2 val6 = new Vector2(0.5f, 0.5f) - val5;
				Vector2 v3 = ((Vector2)(ref val6)).normalized * 4f;
				rectTransform3.anchoredPosition3D = v3.Extend();
			}
			else
			{
				Logger.Warn(fmt, "GraphTime");
			}
			if ((Object)(object)_graphMaxText != (Object)null)
			{
				Vector2 val7 = default(Vector2);
				((Vector2)(ref val7))..ctor(0f, 1f);
				Vector2 pivot = default(Vector2);
				((Vector2)(ref pivot))..ctor(1f, 1f);
				((TMP_Text)_graphMaxText).alignment = (TextAlignmentOptions)516;
				((Graphic)_graphMaxText).color = Color.white;
				((TMP_Text)_graphMaxText).faceColor = TextColor;
				((TMP_Text)_graphMaxText).autoSizeTextContainer = false;
				((TMP_Text)_graphMaxText).enableAutoSizing = true;
				((TMP_Text)_graphMaxText).fontSizeMax = 20f;
				((TMP_Text)_graphMaxText).fontSizeMin = 16f;
				RectTransform rectTransform4 = ((TMP_Text)_graphMaxText).rectTransform;
				rectTransform4.anchorMax = val7;
				rectTransform4.anchorMin = val7;
				rectTransform4.pivot = pivot;
				rectTransform4.sizeDelta = new Vector2(_plot.Size.x, 12f);
				Vector2 v4 = default(Vector2);
				((Vector2)(ref v4))..ctor(-4f, 0f - (DesiredClearance - 6f));
				rectTransform4.anchoredPosition3D = v4.Extend();
			}
			else
			{
				Logger.Warn(fmt, "GraphMax");
			}
			if ((Object)(object)_graphMinText != (Object)null)
			{
				Vector2 val8 = default(Vector2);
				((Vector2)(ref val8))..ctor(0f, 0f);
				Vector2 pivot2 = default(Vector2);
				((Vector2)(ref pivot2))..ctor(1f, 0f);
				((TMP_Text)_graphMinText).alignment = (TextAlignmentOptions)1028;
				((Graphic)_graphMinText).color = Color.white;
				((TMP_Text)_graphMinText).faceColor = TextColor;
				((TMP_Text)_graphMinText).autoSizeTextContainer = false;
				((TMP_Text)_graphMinText).enableAutoSizing = true;
				((TMP_Text)_graphMinText).fontSizeMax = 20f;
				((TMP_Text)_graphMinText).fontSizeMin = 16f;
				RectTransform rectTransform5 = ((TMP_Text)_graphMinText).rectTransform;
				rectTransform5.anchorMax = val8;
				rectTransform5.anchorMin = val8;
				rectTransform5.pivot = pivot2;
				rectTransform5.sizeDelta = new Vector2(_plot.Size.x, 12f);
				Vector2 v5 = default(Vector2);
				((Vector2)(ref v5))..ctor(-4f, 0f);
				rectTransform5.anchoredPosition3D = v5.Extend();
			}
			else
			{
				Logger.Warn(fmt, "GraphMin");
			}
			_dirty = false;
		}

		private void Update()
		{
			if ((Object)(object)_plot == (Object)null)
			{
				Logger.Error("StatGraph[" + ((Object)this).name + "] No plotter assigned.");
				return;
			}
			_timeSinceLastSample += Time.deltaTime;
			if (_timeSinceLastSample >= _sampleInterval)
			{
				for (int i = 0; i < _dataSources.Length; i++)
				{
					float value = _dataSources[i].ValueProvider();
					_plot.PushSample(value, i);
					if ((Object)(object)_valueTexts[i] != (Object)null)
					{
						string text = (AbbreviateWithSIUnit ? Util.Value2SIAbbrStr(value) : value.ToString($"F{Precision}"));
						((TMP_Text)_valueTexts[i]).text = text + Unit;
					}
				}
				_timeSinceLastSample = 0f;
			}
			TextMeshProUGUI? graphMinText = _graphMinText;
			if (graphMinText != null)
			{
				((TMP_Text)graphMinText).SetText(AbbreviateWithSIUnit ? Util.Value2SIAbbrStr(_plot.MinY) : _plot.MinY.ToString($"F{Precision}"), true);
			}
			TextMeshProUGUI? graphMaxText = _graphMaxText;
			if (graphMaxText != null)
			{
				((TMP_Text)graphMaxText).SetText(AbbreviateWithSIUnit ? Util.Value2SIAbbrStr(_plot.DisplayMaxY) : _plot.DisplayMaxY.ToString($"F{Precision}"), true);
			}
			TextMeshProUGUI? graphTimeText = _graphTimeText;
			if (graphTimeText != null)
			{
				((TMP_Text)graphTimeText).SetText($"{(float)_plot.Capacity * _sampleInterval:F0}s", true);
			}
			if (_dirty)
			{
				Reconfigure();
			}
		}

		private void DrawLegendIdentifiers(Graphic graphic, VertexHelper vh)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			Rect pixelAdjustedRect = graphic.GetPixelAdjustedRect();
			Vector2 val = default(Vector2);
			Rect r = default(Rect);
			for (int i = 0; i < _dataSources.Length; i++)
			{
				Color c = (Color)(((??)_dataSources[i].Color) ?? PlotLineColors[i]);
				float num = Mathf.Floor(6f);
				float num2 = (12f - num) / 2f;
				((Vector2)(ref val))..ctor(((Rect)(ref pixelAdjustedRect)).xMin + 4f + num2, ((Rect)(ref pixelAdjustedRect)).yMax - (float)(i + 1) * 16f + num2);
				((Rect)(ref r))..ctor(val, new Vector2(num, num));
				Plotter.AddRect(vh, r, c);
			}
		}

		private void DrawMaxTick(Graphic graphic, VertexHelper vh)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: 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_004d: Unknown result type (might be due to invalid IL or missing references)
			Rect pixelAdjustedRect = graphic.GetPixelAdjustedRect();
			Rect r = default(Rect);
			((Rect)(ref r))..ctor(((Rect)(ref pixelAdjustedRect)).xMin, ((Rect)(ref pixelAdjustedRect)).yMax - DesiredClearance, 4f, 1f);
			Plotter.AddRect(vh, r, (Color)(((??)_plot?.BorderColor) ?? new Color(1f, 1f, 1f, 0.35f)));
		}
	}
	public struct StatGraphConfig
	{
		public StatGraph.DataSource[] Sources;

		public string Unit;

		public float PlotMin;

		public float PlotMax;

		public bool PlotAutoScale;

		public float PlotAutoScaleIncrement;

		public string ObjectName;

		public uint Precision;

		public float SampleRate;

		public bool AbbreviateWithSIPrefix;

		public StatGraphConfig()
		{
			Sources = new StatGraph.DataSource[0];
			Unit = "";
			PlotMin = 0f;
			PlotMax = 1f;
			PlotAutoScale = true;
			PlotAutoScaleIncrement = -1f;
			ObjectName = "";
			Precision = 0u;
			SampleRate = 2f;
			AbbreviateWithSIPrefix = false;
		}
	}
	public static class StatSourceLib
	{
		public static readonly StatGraph.DataSource Ping = new StatGraph.DataSource
		{
			Label = "Ping",
			ValueProvider = () => NetstatAPI.PingMs
		};

		public static readonly StatGraph.DataSource Rx = new StatGraph.DataSource
		{
			Label = "Rx",
			ValueProvider = () => NetstatAPI.BytesReceived
		};

		public static readonly StatGraph.DataSource Tx = new StatGraph.DataSource
		{
			Label = "Tx",
			ValueProvider = () => NetstatAPI.BytesSent
		};

		public static readonly StatGraph.DataSource CTT = new StatGraph.DataSource
		{
			Label = "CTT",
			ValueProvider = () => ((Object)(object)SNet.LocalPlayer != (Object)null) ? (NetstatAPI.GetTickStat(SNet.LocalPlayer.Lookup).TickTime * 1000f) : 0f
		};

		public static readonly StatGraph.DataSource STT = new StatGraph.DataSource
		{
			Label = "STT",
			ValueProvider = () => ((Object)(object)SNet.Master != (Object)null) ? (NetstatAPI.GetTickStat(SNet.Master.Lookup).TickTime * 1000f) : 0f
		};

		public static readonly StatGraph.DataSource[] WPing = new StatGraph.DataSource[1]
		{
			new StatGraph.DataSource
			{
				Label = "Ping",
				ValueProvider = () => NetstatAPI.PingMs
			}
		};

		public static readonly StatGraph.DataSource[] WRxTx = new StatGraph.DataSource[2]
		{
			new StatGraph.DataSource
			{
				Label = "Rx",
				ValueProvider = () => NetstatAPI.BytesReceived
			},
			new StatGraph.DataSource
			{
				Label = "Tx",
				ValueProvider = () => NetstatAPI.BytesSent
			}
		};

		public static readonly StatGraph.DataSource[] WRxChannels = Array.ConvertAll((SNet_ChannelType[])Enum.GetValues(typeof(SNet_ChannelType)), delegate(SNet_ChannelType value)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			StatGraph.DataSource result4 = default(StatGraph.DataSource);
			result4.Label = "Tx " + SteamP2P.SNetChannelType2Str(value);
			result4.ValueProvider = () => NetstatAPI.Channels[(int)value].BytesSent;
			return result4;
		});

		public static readonly StatGraph.DataSource[] WTxChannels = Array.ConvertAll((SNet_ChannelType[])Enum.GetValues(typeof(SNet_ChannelType)), delegate(SNet_ChannelType value)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			StatGraph.DataSource result3 = default(StatGraph.DataSource);
			result3.Label = "Rx " + SteamP2P.SNetChannelType2Str(value);
			result3.ValueProvider = () => NetstatAPI.Channels[(int)value].BytesReceived;
			return result3;
		});

		public static readonly StatGraph.DataSource[] WRxChannelsShort = Array.ConvertAll((SNet_ChannelType[])Enum.GetValues(typeof(SNet_ChannelType)), delegate(SNet_ChannelType value)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			StatGraph.DataSource result2 = default(StatGraph.DataSource);
			result2.Label = "Tx " + SteamP2P.SNetChannelType2StrShort(value);
			result2.ValueProvider = () => NetstatAPI.Channels[(int)value].BytesSent;
			return result2;
		});

		public static readonly StatGraph.DataSource[] WTxChannelsShort = Array.ConvertAll((SNet_ChannelType[])Enum.GetValues(typeof(SNet_ChannelType)), delegate(SNet_ChannelType value)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			StatGraph.DataSource result = default(StatGraph.DataSource);
			result.Label = "Rx " + SteamP2P.SNetChannelType2StrShort(value);
			result.ValueProvider = () => NetstatAPI.Channels[(int)value].BytesReceived;
			return result;
		});

		public static readonly StatGraph.DataSource[] WCSTT = new StatGraph.DataSource[2]
		{
			new StatGraph.DataSource
			{
				Label = "CTT",
				ValueProvider = () => ((Object)(object)SNet.LocalPlayer != (Object)null) ? (NetstatAPI.GetTickStat(SNet.LocalPlayer.Lookup).TickTime * 1000f) : 0f
			},
			new StatGraph.DataSource
			{
				Label = "STT",
				ValueProvider = () => ((Object)(object)SNet.Master != (Object)null) ? (NetstatAPI.GetTickStat(SNet.Master.Lookup).TickTime * 1000f) : 0f
			}
		};
	}
	public static class TMPUtil
	{
		public static bool CreateTMP(string name, Transform? parent, [NotNullWhen(true)] out TextMeshPro? tp)
		{
			//IL_0058: 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_008e: 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_00ce: Unknown result type (might be due to invalid IL or missing references)
			WatermarkGuiLayer watermarkLayer = GuiManager.WatermarkLayer;
			object obj;
			if (watermarkLayer == null)
			{
				obj = null;
			}
			else
			{
				PUI_Watermark watermark = watermarkLayer.m_watermark;
				obj = ((watermark != null) ? watermark.m_fpsText : null);
			}
			TextMeshPro val = (TextMeshPro)obj;
			if ((Object)(object)parent == (Object)null || (Object)(object)val == (Object)null)
			{
				tp = null;
				return false;
			}
			tp = Object.Instantiate<TextMeshPro>(val, parent, false);
			((Object)tp).name = name;
			((TMP_Text)tp).rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
			((TMP_Text)tp).rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
			((TMP_Text)tp).rectTransform.pivot = new Vector2(1f, 0f);
			((TMP_Text)tp).rectTransform.anchoredPosition3D = new Vector3(0f, 2f, 0f);
			((Transform)((TMP_Text)tp).rectTransform).localRotation = Quaternion.Euler(0f, 0f, 0f);
			((TMP_Text)tp).enableAutoSizing = false;
			((TMP_Text)tp).overflowMode = (TextOverflowModes)0;
			((TMP_Text)tp).alignment = (TextAlignmentOptions)513;
			((TMP_Text)tp).fontSize = 16f;
			return true;
		}

		public static bool CreateTMPUGUI(string name, Transform? parent, [NotNullWhen(true)] out TextMeshProUGUI? tp)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: 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)
			WatermarkGuiLayer watermarkLayer = GuiManager.WatermarkLayer;
			object obj;
			if (watermarkLayer == null)
			{
				obj = null;
			}
			else
			{
				PUI_Watermark watermark = watermarkLayer.m_watermark;
				obj = ((watermark != null) ? watermark.m_fpsText : null);
			}
			TextMeshPro val = (TextMeshPro)obj;
			GameObject val2 = new GameObject();
			val2.transform.SetParent(parent, false);
			tp = val2.AddComponent<TextMeshProUGUI>();
			((Object)tp).name = name;
			((TMP_Text)tp).rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
			((TMP_Text)tp).rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
			((TMP_Text)tp).rectTransform.pivot = new Vector2(1f, 0f);
			((TMP_Text)tp).rectTransform.anchoredPosition3D = new Vector3(0f, 2f, 0f);
			((Transform)((TMP_Text)tp).rectTransform).localRotation = Quaternion.Euler(0f, 0f, 0f);
			((TMP_Text)tp).enableAutoSizing = false;
			((TMP_Text)tp).overflowMode = (TextOverflowModes)0;
			((TMP_Text)tp).alignment = (TextAlignmentOptions)513;
			((TMP_Text)tp).fontSize = 16f;
			if ((Object)(object)val != (Object)null)
			{
				((TMP_Text)tp).font = ((TMP_Text)val).font;
				((TMP_Text)tp).fontSharedMaterial = ((TMP_Text)val).fontSharedMaterial;
			}
			return true;
		}
	}
	public class UIManager : MonoBehaviour
	{
		private Canvas _canvas;

		private CanvasScaler _canvasScaler;

		private const float ElementSpacing = 4f;

		private static readonly Vector2 ReferenceResolution = new Vector2(2560f, 1440f);

		private static readonly Vector2 GraphSize = new Vector2(200f, 100f);

		public readonly Vector2 Pivot = new Vector2(0.5f, 0.5f);

		private bool _dirty;

		private GameObject? _uiRoot;

		private RectTransform? _graphLayerTrans;

		private readonly Dictionary<eNetstatGraph, StatGraph> _graphDict = new Dictionary<eNetstatGraph, StatGraph>();

		private List<StatGraph> _graphStack = new List<StatGraph>();

		private TextMeshProUGUI? _detailsText;

		private readonly Vector3 _detailsBarOffset = new Vector3(-340f, -12f, 0f);

		private TextMeshPro? _detailsBar;

		public static UIManager? Instance { get; private set; }

		public Vector2 Size { get; set; } = new Vector2(GraphSize.x, 100f);


		public Vector2 Anchor => ConfigMgr.UIAnchor;

		public Vector2 AnchorOffset => ConfigMgr.UIAnchorOffset;

		public bool Active => ConfigMgr.EnableGraphs;

		public void SetDirty()
		{
			_dirty = true;
		}

		private void Awake()
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Instance != (Object)null)
			{
				Object.Destroy((Object)(object)this);
				return;
			}
			Instance = this;
			_canvas = ((Component)this).gameObject.AddComponent<Canvas>();
			_canvas.renderMode = (RenderMode)0;
			_canvas.sortingOrder = 1000;
			_canvasScaler = ((Component)this).gameObject.AddComponent<CanvasScaler>();
			_canvasScaler.uiScaleMode = (ScaleMode)1;
			_canvasScaler.referenceResolution = ReferenceResolution;
			_canvasScaler.m_MatchWidthOrHeight = 1f;
			CreateUI();
		}

		private void Update()
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Invalid comparison between Unknown and I4
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Invalid comparison between Unknown and I4
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Invalid comparison between Unknown and I4
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if ((int)FocusStateManager.Current.m_currentState != 5 && (int)FocusStateManager.Current.m_currentState != 6 && (int)FocusStateManager.Current.m_currentState != 8 && (int)FocusStateManager.Current.m_currentState != 14 && !PlayerChatManager.InChatMode && Input.GetKeyDown(ConfigMgr.GraphToggleKey))
			{
				ConfigMgr.EnableGraphs = !ConfigMgr.EnableGraphs;
			}
			if ((Object)(object)_graphLayerTrans != (Object)null && Active != ((Component)_graphLayerTrans).gameObject.activeSelf)
			{
				((Component)_graphLayerTrans).gameObject.SetActive(Active);
			}
			if ((Object)(object)_detailsBar != (Object)null && ((UIBehaviour)_detailsBar).IsActive() != ConfigMgr.DetailsBarEnabled)
			{
				TextMeshPro? detailsBar = _detailsBar;
				if (detailsBar != null)
				{
					((Component)detailsBar).gameObject.SetActive(ConfigMgr.DetailsBarEnabled);
				}
			}
			if (_dirty)
			{
				_dirty = false;
				UpdateConfigurableValues();
				RefreshGraphStack();
			}
			UpdateTextDisplays();
		}

		private void OnDestroy()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
		}

		private void UpdateConfigurableValues()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_graphLayerTrans == (Object)null)
			{
				return;
			}
			_graphLayerTrans.anchorMin = Anchor;
			_graphLayerTrans.anchorMax = Anchor;
			_graphLayerTrans.anchoredPosition3D = AnchorOffset.Extend();
			foreach (StatGraph value in _graphDict.Values)
			{
				value.PlotSize = ConfigMgr.GraphSize;
			}
		}

		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_003d: 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_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: 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_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0135: 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)
			//IL_0155: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01de: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f7: Unknown result type (might be due to invalid IL or missing references)
			_uiRoot = new GameObject("food.randomuser.gtfo.Netstat.UI");
			_graphLayerTrans = _uiRoot.AddComponent<RectTransform>();
			((Transform)_graphLayerTrans).SetParent(((Component)this).gameObject.transform);
			((Transform)_graphLayerTrans).localScale = Vector3.one;
			_graphLayerTrans.anchorMin = Anchor;
			_graphLayerTrans.anchorMax = Anchor;
			_graphLayerTrans.pivot = Pivot;
			_graphLayerTrans.anchoredPosition3D = AnchorOffset.Extend();
			_uiRoot.SetActive(true);
			GenerateGraphs();
			if (TMPUtil.CreateTMP("food.randomuser.gtfo.Netstat.UI.DetailsBar", ((Component)GuiManager.PlayerLayer.m_playerStatus).transform, out TextMeshPro tp))
			{
				((TMP_Text)tp).alignment = (TextAlignmentOptions)513;
				((TMP_Text)tp).enableAutoSizing = true;
				((TMP_Text)tp).fontSize = 16f;
				((TMP_Text)tp).fontSizeMin = 12f;
				((TMP_Text)tp).fontSizeMax = 20f;
				RectTransform rectTransform = ((TMP_Text)tp).rectTransform;
				rectTransform.anchorMax = new Vector2(0.5f, 0.5f);
				rectTransform.anchorMin = new Vector2(0.5f, 0.5f);
				rectTransform.pivot = new Vector2(0f, 1f);
				rectTransform.sizeDelta = new Vector2(400f, 16f);
				rectTransform.anchoredPosition3D = _detailsBarOffset;
			}
			_detailsBar = tp;
			if (TMPUtil.CreateTMPUGUI("food.randomuser.gtfo.Netstat.UI.Details", (Transform?)(object)_graphLayerTrans, out TextMeshProUGUI tp2))
			{
				((TMP_Text)tp2).alignment = (TextAlignmentOptions)257;
				RectTransform rectTransform2 = ((TMP_Text)tp2).rectTransform;
				rectTransform2.anchorMax = new Vector2(0.5f, 0.5f);
				rectTransform2.anchorMin = new Vector2(0.5f, 0.5f);
				rectTransform2.pivot = new Vector2(1f, 1f);
				rectTransform2.sizeDelta = new Vector2(Size.x, 12f);
				rectTransform2.anchoredPosition3D = new Vector3(0f, -4f, 0f);
			}
			_detailsText = tp2;
		}

		public void UpdateTextDisplays()
		{
			if ((Object)(object)_detailsText != (Object)null)
			{
				string text = "";
				text += (NetstatAPI.IsDesynced ? $"<#AF0000{(uint)((Mathf.Sin(Time.time * (float)Math.PI / 2f) + 1f) * 127f):X2}>DESYNCED</color>" : "\n");
				((TMP_Text)_detailsText).SetText(text.Trim(), true);
			}
			if (!((Object)(object)_detailsBar != (Object)null))
			{
				return;
			}
			List<string> list = new List<string>();
			if (ConfigMgr.DetailsBarData.HasFlag(eNetstatData.Ping))
			{
				list.Add($"Ping {NetstatAPI.PingMs}ms");
			}
			if (ConfigMgr.DetailsBarData.HasFlag(eNetstatData.Rx))
			{
				list.Add("Rx " + Util.Value2SIAbbrStr(NetstatAPI.BytesReceived) + "B/s");
			}
			if (ConfigMgr.DetailsBarData.HasFlag(eNetstatData.Tx))
			{
				list.Add("Tx " + Util.Value2SIAbbrStr(NetstatAPI.BytesSent) + "B/s");
			}
			if (ConfigMgr.DetailsBarData.HasFlag(eNetstatData.STT))
			{
				string text2 = "?";
				if ((Object)(object)SNet.Master != (Object)null)
				{
					text2 = ((int)(NetstatAPI.GetTickStat(SNet.Master.Lookup).TickTime * 1000f)).ToString();
				}
				list.Add("STT " + text2 + "ms");
			}
			if (ConfigMgr.DetailsBarData.HasFlag(eNetstatData.CTT))
			{
				string text3 = "?";
				if ((Object)(object)SNet.LocalPlayer != (Object)null)
				{
					text3 = ((int)(NetstatAPI.GetTickStat(SNet.LocalPlayer.Lookup).TickTime * 1000f)).ToString();
				}
				list.Add("CTT " + text3 + "ms");
			}
			string text4 = string.Join(" | ", list);
			TextMeshPro? detailsBar = _detailsBar;
			if (detailsBar != null)
			{
				((TMP_Text)detailsBar).SetText(text4, true);
			}
		}

		private void GenerateGraphs()
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_graphLayerTrans == (Object)null)
			{
				return;
			}
			foreach (StatGraph item in _graphStack)
			{
				Object.Destroy((Object)(object)((Component)item).gameObject);
			}
			eNetstatGraph[] values = Enum.GetValues<eNetstatGraph>();
			foreach (eNetstatGraph eNetstatGraph2 in values)
			{
				if (StatConfigLib.TryGet(eNetstatGraph2, out var conf))
				{
					_graphDict[eNetstatGraph2] = StatGraph.Create((Transform)(object)_graphLayerTrans, ConfigMgr.GraphSize, conf);
				}
			}
			RefreshGraphStack();
		}

		private void RefreshGraphStack()
		{
			_graphStack.Clear();
			foreach (eNetstatGraph item in ConfigMgr.GraphsInOrder)
			{
				if (_graphDict.TryGetValue(item, out StatGraph value))
				{
					if (ConfigMgr.EnabledGraphs.HasFlag(item))
					{
						((Component)value).gameObject.SetActive(true);
						_graphStack.Add(value);
					}
					else
					{
						((Component)value).gameObject.SetActive(false);
					}
				}
			}
			AlignGraphsVertical();
		}

		private void AlignGraphsVertical()
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			for (int i = 0; i < _graphStack.Count; i++)
			{
				_graphStack[i].RT.anchoredPosition = new Vector2(0f, num);
				num += _graphStack[i].Size.y + 4f;
			}
		}
	}
}
namespace Netstat.Telemetry
{
	internal interface IPinger
	{
		static bool IsDesynced { get; }

		static float Ping { get; }
	}
	internal struct PingInfo
	{
		public float SendTime;

		public float RecvTime;

		public uint SeqNumber;

		public bool Ackd;
	}
	[HarmonyPatch]
	internal class ChatPinger : MonoBehaviour, IPinger
	{
		private const ulong MAGIC_NUMBER = 11474180236421424882uL;

		private static uint BUFFER_SIZE = 10u;

		private static PingInfo[] _buffer = new PingInfo[BUFFER_SIZE];

		private static uint _seqNumber = 0u;

		private static float _lastPingReceived = 0f;

		private static float _ping = 0f;

		private static float _rawPing = 0f;

		private static float _jitter = 0f;

		private static float _rawJitter = 0f;

		private static bool _running = false;

		private static float _nextPingSendTime;

		public static float Ping
		{
			get
			{
				if (!((Object)(object)SNet.Master == (Object)null) && !SNet.IsMaster)
				{
					return _ping;
				}
				return 0f;
			}
		}

		public static float RawPing
		{
			get
			{
				if (!((Object)(object)SNet.Master == (Object)null) && !SNet.IsMaster)
				{
					return _rawPing;
				}
				return 0f;
			}
		}

		public static float Jitter
		{
			get
			{
				if (!((Object)(object)SNet.Master == (Object)null) && !SNet.IsMaster)
				{
					return _jitter;
				}
				return 0f;
			}
		}

		public static float RawJitter
		{
			get
			{
				if (!((Object)(object)SNet.Master == (Object)null) && !SNet.IsMaster)
				{
					return _rawJitter;
				}
				return 0f;
			}
		}

		public static bool IsDesynced { get; private set; }

		public static void Start()
		{
			_seqNumber = 0u;
			ref PingInfo reference = ref _buffer[_seqNumber];
			reference.SeqNumber = _seqNumber;
			reference.Ackd = false;
			_running = true;
		}

		private static void Pause()
		{
			_running = false;
		}

		[HarmonyPatch(typeof(SNet_SessionHub), "OnJoinedLobby")]
		[HarmonyPrefix]
		private static void SNet_SessionHub_OnJoinedLobby()
		{
			Start();
		}

		[HarmonyPatch(typeof(SNet_SessionHub), "LeaveHub")]
		[HarmonyPrefix]
		private static void SNet_SessionHub_LeaveHub()
		{
			Pause();
		}

		private unsafe void Update()
		{
			PlayerChatManager current = PlayerChatManager.Current;
			if ((Object)(object)current == (Object)null)
			{
				return;
			}
			((SNet_SyncedAction<pChatMessage>)(object)current.m_sendChatMessage).m_channelType = (SNet_ChannelType)0;
			if (ConfigMgr.PingerType != 0 || !_running || SNet.IsMaster || (Object)(object)SNet.Master == (Object)null)
			{
				return;
			}
			PlayerAgent localPlayerAgent = PlayerManager.GetLocalPlayerAgent();
			if ((Object)(object)localPlayerAgent == (Object)null)
			{
				return;
			}
			_ = localPlayerAgent.Owner.Lookup;
			float now = SystemTime.Now;
			if (now > _nextPingSendTime)
			{
				_nextPingSendTime = now + 0.5f;
				if (now - _lastPingReceived > 1f)
				{
					IsDesynced = true;
				}
				ref PingInfo reference = ref _buffer[_seqNumber++ % BUFFER_SIZE];
				reference.SendTime = now;
				reference.Ackd = false;
				_buffer[_seqNumber % BUFFER_SIZE].SeqNumber = _seqNumber;
				string text;
				fixed (uint* value = &reference.SeqNumber)
				{
					text = new string((char*)value, 0, 2);
				}
				SNet_Player owner = localPlayerAgent.Owner;
				owner.Lookup ^= 0x9F3C7A21D8B4E6F2uL;
				PlayerChatManager.WantToSentTextMessage(localPlayerAgent, text, (PlayerAgent)null);
				SNet_Player owner2 = localPlayerAgent.Owner;
				owner2.Lookup ^= 0x9F3C7A21D8B4E6F2uL;
			}
		}

		[HarmonyPatch(typeof(PlayerChatManager), "DoSendChatMessage")]
		[HarmonyPrefix]
		private unsafe static bool OnPingReceive(PlayerChatManager __instance, pChatMessage data)
		{
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (!_running || SNet.IsMaster || (Object)(object)SNet.Master == (Object)null || (Object)(object)SNet.LocalPlayer == (Object)null || (data.fromPlayer.lookup ^ 0x9F3C7A21D8B4E6F2uL) != SNet.LocalPlayer.Lookup)
			{
				SNet_Core_STEAM val = ((Il2CppObjectBase)SNet.Core).TryCast<SNet_Core_STEAM>();
				if ((Object)(object)val == (Object)null)
				{
					return true;
				}
				return val.m_playerLookup.ContainsKey(data.fromPlayer.lookup);
			}
			float now = SystemTime.Now;
			uint num;
			fixed (char* ptr = data.message.m_data)
			{
				num = *(uint*)ptr;
			}
			if (_buffer[_seqNumber % BUFFER_SIZE].SeqNumber - num >= BUFFER_SIZE)
			{
				return false;
			}
			PingInfo pingInfo = _buffer[num % BUFFER_SIZE];
			if (pingInfo.Ackd)
			{
				return false;
			}
			pingInfo.Ackd = true;
			pingInfo.RecvTime = now;
			float num2 = Mathf.Clamp(pingInfo.RecvTime - pingInfo.SendTime, 0f, 1f);
			_rawJitter = Mathf.Abs(num2 - _rawPing);
			_rawPing = num2;
			_jitter += (_rawJitter - _jitter) / 16f;
			_ping = 0.5f * _ping + 0.5f * _rawPing;
			_lastPingReceived = now;
			IsDesynced = false;
			return false;
		}
	}
	[HarmonyPatch]
	internal class MarkerPinger : MonoBehaviour, IPinger
	{
		private const uint MAGIC_NUMBER = 2882400175u;

		private static uint BUFFER_SIZE = 10u;

		private static PingInfo[] _buffer = new PingInfo[BUFFER_SIZE];

		private static uint _seqNumber = 0u;

		private static float _lastPingReceived = 0f;

		private static float _ping = 0f;

		private static float _rawPing = 0f;

		private static float _jitter = 0f;

		private static float _rawJitter = 0f;

		private static bool _running = false;

		private static int _localPlayerSlotIndex = -1;

		private static SyncedNavMarkerWrapper? _localPlayerNavMarker = null;

		private static pNavMarkerState _cachedNavMarkerState = default(pNavMarkerState);

		private static float _markerAutoHideTime = 0f;

		private static bool _shouldMarkerBeVisible = false;

		private static float _nextPingSendTime = 0f;

		public static float Ping
		{
			get
			{
				if (!((Object)(object)SNet.Master == (Object)null) && !SNet.IsMaster)
				{
					return _ping;
				}
				return 0f;
			}
		}

		public static float RawPing
		{
			get
			{
				if (!((Object)(object)SNet.Master == (Object)null) && !SNet.IsMaster)
				{
					return _rawPing;
				}
				return 0f;
			}
		}

		public static float Jitter
		{
			get
			{
				if (!((Object)(object)SNet.Master == (Object)null) && !SNet.IsMaster)
				{
					return _jitter;
				}
				return 0f;
			}
		}

		public static float RawJitter
		{
			get
			{
				if (!((Object)(object)SNet.Master == (Object)null) && !SNet.IsMaster)
				{
					return _rawJitter;
				}
				return 0f;
			}
		}

		public static bool IsMeasuring
		{
			get
			{
				if (_running)
				{
					return SystemTime.Now > _markerAutoHideTime;
				}
				return false;
			}
		}

		public static bool IsDesynced { get; private set; }

		public static void Start()
		{
			_seqNumber = 0u;
			ref PingInfo reference = ref _buffer[_seqNumber];
			reference.SeqNumber = _seqNumber;
			reference.Ackd = false;
			_markerAutoHideTime = 0f;
			_nextPingSendTime = 0f;
			_running = true;
		}

		private static void Pause()
		{
			_running = false;
			_localPlayerSlotIndex = -1;
			_localPlayerNavMarker = null;
		}

		[HarmonyPatch(typeof(RundownManager), "EndGameSession")]
		[HarmonyPrefix]
		private static void RundownManager_EndGameSession()
		{
			Pause();
		}

		[HarmonyPatch(typeof(SNet_SessionHub), "LeaveHub")]
		[HarmonyPrefix]
		private static void SNet_SessionHub_LeaveHub()
		{
			Pause();
		}

		[HarmonyPatch(typeof(GuiManager), "AttemptSetPlayerPingStatus")]
		[HarmonyPrefix]
		private static void GuiManager_AttemptSetPlayerPingStatus(PlayerAgent sourceAgent, bool visible, Vector3 worldPos, eNavMarkerStyle style)
		{
			if (!visible)
			{
				_markerAutoHideTime = 0f;
			}
			else
			{
				_shouldMarkerBeVisible = false;
			}
		}

		private void Update()
		{
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: 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_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0150: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: 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_015d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_017e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_0197: Unknown result type (might be due to invalid IL or missing references)
			if (ConfigMgr.PingerType != NetstatAPI.PingerTypeEnum.Marker || SNet.IsMaster || (Object)(object)SNet.Master == (Object)null || (Object)(object)SNet.LocalPlayer == (Object)null)
			{
				return;
			}
			_localPlayerSlotIndex = SNet.LocalPlayer.PlayerSlotIndex();
			GuiManager current = GuiManager.Current;
			_localPlayerNavMarker = ((current == null) ? null : ((Il2CppArrayBase<SyncedNavMarkerWrapper>)(object)current.m_playerPings)?[_localPlayerSlotIndex]);
			if ((Object)(object)_localPlayerNavMarker == (Object)null || !_running)
			{
				return;
			}
			float now = SystemTime.Now;
			if (now > _markerAutoHideTime)
			{
				if (now > _nextPingSendTime)
				{
					_nextPingSendTime = now + 0.5f;
					if (now - _lastPingReceived > 1f)
					{
						IsDesynced = true;
					}
					ref PingInfo reference = ref _buffer[_seqNumber++ % BUFFER_SIZE];
					reference.SendTime = now;
					reference.Ackd = false;
					_buffer[_seqNumber % BUFFER_SIZE].SeqNumber = _seqNumber;
					pNavMarkerInteraction val = default(pNavMarkerInteraction);
					val.type = (eNavMarkerInteractionType)1;
					val.worldPos.x = BitConverter.UInt32BitsToSingle(2882400175u);
					val.worldPos.y = Unsafe.As<uint, float>(ref reference.SeqNumber);
					pNavMarkerState val2 = default(pNavMarkerState);
					val2.status = (eNavMarkerStatus)1;
					val2.worldPos = val.worldPos;
					val2.terminalItemId = val.terminalItemId;
					SNet_StateReplicator<pNavMarkerState, pNavMarkerInteraction> stateReplicator = _localPlayerNavMarker.m_stateReplicator;
					stateReplicator.m_statePacket_Recall.Send(val2, stateReplicator.m_channelType, SNet.Master);
					stateReplicator.m_interactionPacket.Send(val, stateReplicator.m_channelType, SNet.Master);
				}
			}
			else
			{
				_lastPingReceived = now;
			}
		}

		[HarmonyPatch(typeof(SyncedNavMarkerWrapper), "OnStateChange")]
		[HarmonyPrefix]
		private static void OnRecievePingStatus(SyncedNavMarkerWrapper __instance, pNavMarkerState oldState, pNavMarkerState newState, bool isDropinState)
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: 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_0077: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Invalid comparison between Unknown and I4
			//IL_004d: 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_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			if (SNet.IsMaster || (Object)(object)SNet.Master == (Object)null || isDropinState || !_running || __instance.m_playerIndex != _localPlayerSlotIndex)
			{
				return;
			}
			float now = SystemTime.Now;
			if (!_shouldMarkerBeVisible && now > _markerAutoHideTime && (int)newState.status == 0)
			{
				_cachedNavMarkerState = newState;
				_markerAutoHideTime = now + __instance.AutoHideDelay;
				_shouldMarkerBeVisible = true;
			}
			else if (_shouldMarkerBeVisible && now <= _markerAutoHideTime && (int)newState.status == 1 && (int)_cachedNavMarkerState.status == 0)
			{
				pNavMarkerInteraction val = default(pNavMarkerInteraction);
				val.type = (eNavMarkerInteractionType)0;
				val.style = _cachedNavMarkerState.style;
				val.worldPos = _cachedNavMarkerState.worldPos;
				val.terminalItemId = _cachedNavMarkerState.terminalItemId;
				__instance.m_stateReplicator.AttemptInteract(val);
			}
			else
			{
				if (Unsafe.As<float, uint>(ref newState.worldPos.x) != 2882400175u)
				{
					return;
				}
				uint num = Unsafe.As<float, uint>(ref newState.worldPos.y);
				if (_buffer[_seqNumber % BUFFER_SIZE].SeqNumber - num < BUFFER_SIZE)
				{
					PingInfo pingInfo = _buffer[num % BUFFER_SIZE];
					if (!pingInfo.Ackd)
					{
						pingInfo.Ackd = true;
						pingInfo.RecvTime = now;
						float num2 = Mathf.Clamp(pingInfo.RecvTime - pingInfo.SendTime, 0f, 1f);
						_rawJitter = Mathf.Abs(num2 - _rawPing);
						_rawPing = num2;
						_jitter += (_rawJitter - _jitter) / 16f;
						_ping = 0.5f * _ping + 0.5f * _rawPing;
						_lastPingReceived = now;
						IsDesynced = false;
					}
				}
			}
		}
	}
	public struct ChannelStats
	{
		public uint _accumulatedBytesReceived;

		public uint BytesReceived;

		public uint _accumulatedPacketsReceived;

		public uint PacketsReceived;

		public uint _accumulatedBytesSent;

		public uint BytesSent;

		public uint _accumulatedPacketsSent;

		public uint PacketsSent;

		public ChannelStats()
		{
			_accumulatedBytesReceived = 0u;
			BytesReceived = 0u;
			_accumulatedPacketsReceived = 0u;
			PacketsReceived = 0u;
			_accumulatedBytesSent = 0u;
			BytesSent = 0u;
			_accumulatedPacketsSent = 0u;
			PacketsSent = 0u;
		}
	}
	[HarmonyPatch]
	internal class SteamP2P : MonoBehaviour
	{
		private static float _nextPollTimestamp = 0f;

		private static ChannelStats[] _channels = new ChannelStats[Enum.GetValues(typeof(SNet_ChannelType)).Length];

		public static ReadOnlySpan<ChannelStats> Channels => _channels;

		public static uint BytesReceived { get; private set; }

		public static uint PacketsReceived { get; private set; }

		public static uint BytesSent { get; private set; }

		public static uint PacketsSent { get; private set; }

		public static int BytesQueuedForSend { get; private set; }

		public static int PacketsQueuedForSend { get; private set; }

		[HarmonyPatch(/*Could not decode attribute arguments.*/)]
		[HarmonyPrefix]
		private static void SteamNetworking_ReadP2PPacket(Il2CppStructArray<byte> pubDest, uint cubDest, uint pcubMsgSize, CSteamID psteamIDRemote, int nChannel)
		{
			if (nChannel >= 0 && nChannel < _channels.Length)
			{
				ref ChannelStats reference = ref _channels[nChannel];
				reference._accumulatedBytesReceived += pcubMsgSize;
				reference._accumulatedPacketsReceived++;
			}
		}

		[HarmonyPatch(typeof(SteamNetworking), "SendP2PPacket")]
		[HarmonyPrefix]
		private static void SteamNetworking_SendP2PPacket(CSteamID steamIDRemote, Il2CppStructArray<byte> pubData, uint cubData, EP2PSend eP2PSendType, int nChannel)
		{
			if (nChannel >= 0 && nChannel < _channels.Length)
			{
				ref ChannelStats reference = ref _channels[nChannel];
				reference._accumulatedBytesSent += cubData;
				reference._accumulatedPacketsSent++;
			}
		}

		private void Update()
		{
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: 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)
			BytesQueuedForSend = 0;
			PacketsQueuedForSend = 0;
			Enumerator<SNet_Player> enumerator = SNet.LobbyPlayers.GetEnumerator();
			P2PSessionState_t val = default(P2PSessionState_t);
			while (enumerator.MoveNext())
			{
				SNet_Player current = enumerator.Current;
				if (!current.IsLocal && !current.IsBot)
				{
					SteamNetworking.GetP2PSessionState(new CSteamID(current.Lookup), ref val);
					BytesQueuedForSend += val.m_nBytesQueuedForSend;
					PacketsQueuedForSend += val.m_nPacketsQueuedForSend;
				}
			}
			float now = SystemTime.Now;
			if (now > _nextPollTimestamp)
			{
				_nextPollTimestamp = now + 1f;
				BytesReceived = 0u;
				PacketsReceived = 0u;
				BytesSent = 0u;
				PacketsSent = 0u;
				for (int i = 0; i < _channels.Length; i++)
				{
					ref ChannelStats reference = ref _channels[i];
					reference.BytesReceived = (uint)((float)reference._accumulatedBytesReceived * 1f);
					reference._accumulatedBytesReceived = 0u;
					reference.PacketsReceived = (uint)((float)reference._accumulatedPacketsReceived * 1f);
					reference._accumulatedPacketsReceived = 0u;
					reference.BytesSent = (uint)((float)reference._accumulatedBytesSent * 1f);
					reference._accumulatedBytesSent = 0u;
					reference.PacketsSent = (uint)((float)reference._accumulatedPacketsSent * 1f);
					reference._accumulatedPacketsSent = 0u;
					BytesReceived += reference.BytesReceived;
					PacketsReceived += reference.PacketsReceived;
					BytesSent += reference.BytesSent;
					PacketsSent += reference.PacketsSent;
				}
			}
		}

		public static string SNetChannelType2Str(SNet_ChannelType t)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected I4, but got Unknown
			return (int)t switch
			{
				5 => "BotCmds", 
				4 => "NonCrit", 
				2 => "Crit", 
				3 => "RecvCrit", 
				1 => "SessMig", 
				0 => "SessCrit", 
				_ => "???", 
			};
		}

		public static string SNetChannelType2StrShort(SNet_ChannelType t)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected I4, but got Unknown
			return (int)t switch
			{
				5 => "BC", 
				4 => "NC", 
				2 => "CR", 
				3 => "RC", 
				1 => "SM", 
				0 => "SC", 
				_ => "???", 
			};
		}
	}
	internal class SystemTime
	{
		private static long _startTimestamp = _unixMs;

		private static long _unixMs => ((DateTimeOffset)DateTime.Now).ToUnixTimeMilliseconds();

		public static float Now => (float)(_unixMs - _startTimestamp) / 1000f;
	}
	public struct TickStats
	{
		public ulong SteamId;

		public float _lastTickTimestamp;

		public float TickTime;

		public float RawTickTime;

		public bool IsMeasuring;

		public TickStats(ulong steamId)
		{
			SteamId = 0uL;
			_lastTickTimestamp = 0f;
			TickTime = 0f;
			RawTickTime = 0f;
			IsMeasuring = false;
			SteamId = steamId;
		}
	}
	[HarmonyPatch]
	internal class TickTimer : MonoBehaviour
	{
		private static Dictionary<ulong, TickStats> _playerTicks = new Dictionary<ulong, TickStats>();

		private static void Measure(ref TickStats info)
		{
			float now = SystemTime.Now;
			if (info.IsMeasuring)
			{
				info.RawTickTime = now - info._lastTickTimestamp;
				info.TickTime = 0.5f * info.TickTime + 0.5f * info.RawTickTime;
			}
			info.IsMeasuring = true;
			info._lastTickTimestamp = now;
		}

		[HarmonyPatch(typeof(PlayerSync), "IncomingLocomotion")]
		[HarmonyPrefix]
		private static void PlayerSync_IncomingLocomotion(PlayerSync __instance, pPlayerLocomotion data)
		{
			SNet_Player owner = __instance.m_agent.Owner;
			if (!owner.IsBot && !owner.IsLocal)
			{
				ulong lookup = owner.Lookup;
				TickStats info = GetTickStat(lookup);
				float num = ((SFloat8)(ref data.VelRight)).Get(10f);
				float num2 = ((SFloat8)(ref data.VelFwd)).Get(10f);
				if (num * num + num2 * num2 < 1f)
				{
					info.IsMeasuring = false;
					_playerTicks[lookup] = info;
				}
				else
				{
					Measure(ref info);
					_playerTicks[lookup] = info;
				}
			}
		}

		[HarmonyPatch(typeof(PlayerSync), "SendLocomotion")]
		[HarmonyPrefix]
		private static void PlayerSync_SendLocomotion(PlayerSync __instance, PLOC_State state, Vector3 pos, Vector3 lookDir, float velFwd, float velRight)
		{
			SNet_Player owner = __instance.m_agent.Owner;
			if (!owner.IsBot && owner.IsLocal)
			{
				ulong lookup = owner.Lookup;
				TickStats info = GetTickStat(lookup);
				Measure(ref info);
				_playerTicks[lookup] = info;
			}
		}

		[HarmonyPatch(typeof(PLOC_ClimbLadder), "Exit")]
		[HarmonyPrefix]
		private static void PLOC_ClimbLadder_Exit(PLOC_ClimbLadder __instance)
		{
			CommonLadderExit(__instance);
		}

		[HarmonyPatch(typeof(PLOC_ClimbLadder), "SyncExit")]
		[HarmonyPrefix]
		private static void PLOC_ClimbLadder_SyncExit(PLOC_ClimbLadder __instance)
		{
			CommonLadderExit(__instance);
		}

		private static void CommonLadderExit(PLOC_ClimbLadder __instance)
		{
			SNet_Player owner = ((PLOC_Base)__instance).m_owner.Owner;
			if (!owner.IsBot && owner.IsLocal)
			{
				ulong lookup = owner.Lookup;
				TickStats tickStat = GetTickStat(lookup);
				tickStat.IsMeasuring = false;
				_playerTicks[lookup] = tickStat;
			}
		}

		public static TickStats GetTickStat(ulong steamId)
		{
			if (!_playerTicks.ContainsKey(steamId))
			{
				_playerTicks.Add(steamId, new TickStats(steamId));
			}
			return _playerTicks[steamId];
		}

		public static void Start()
		{
			_playerTicks.Clear();
		}

		private static void Pause()
		{
			_playerTicks.Clear();
		}

		[HarmonyPatch(typeof(RundownManager), "EndGameSession")]
		[HarmonyPrefix]
		private static void RundownManager_EndGameSession()
		{
			Pause();
		}

		[HarmonyPatch(typeof(SNet_SessionHub), "LeaveHub")]
		[HarmonyPrefix]
		private static void SNet_SessionHub_LeaveHub()
		{
			Pause();
		}
	}
}
namespace Netstat.Grapher
{
	public sealed class Plotter : Graphic
	{
		[Flags]
		public enum PlotComponent
		{
			None = 0,
			Line = 1,
			Fill = 2,
			Background = 4,
			Border = 8,
			Standard = 0xF,
			StandardNoBorder = 7,
			StandardNoFill = 0xD
		}

		private struct ChannelStyle
		{
			public bool DrawLine;

			public float LineThickness;

			public Color LineColor;

			public bool DrawFill;

			public float FillChunkWidth;

			public Color FillColor;

			public ChannelStyle()
			{
				//IL_0027: 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_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)
				DrawLine = true;
				LineThickness = 2f;
				LineColor = new Color(0.85f, 0.85f, 0.85f, 1f);
				DrawFill = false;
				FillChunkWidth = 3f;
				FillColor = new Color(1f, 1f, 1f, 0.25f);
			}
		}

		private int _capacity = 120;

		private float _minY;

		private float _maxY;

		private bool _autoScale;

		private float _autoscaleInc = -1f;

		private float _autoScaleLerp = 0.35f;

		private bool _logScale;

		private Vector2 _plotSize = new Vector2(200f, 100f);

		private bool _drawBackground = true;

		private bool _drawBorder = true;

		private float _borderThickness = 1f;

		private int _channelCount = 1;

		private ChannelStyle[] _styles = new ChannelStyle[0];

		private float[,] _samples = new float[0, 0];

		private int[] _heads = new int[0];

		private int[] _counts = new int[0];

		private float[] _maxObserved = new float[0];

		private bool _dirty;

		private int _lineResolution = 4;

		private float _clearance;

		private float _dispMax;

		public Vector2 PlotSize
		{
			get
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				return _plotSize;
			}
			set
			{
				//IL_0001: Unknown result type (might be due to invalid IL or missing references)
				//IL_0002: Unknown result type (might be due to invalid IL or missing references)
				//IL_002a: Unknown result type (might be due to invalid IL or missing references)
				_plotSize = value;
				((Graphic)this).rectTransform.sizeDelta = new Vector2(_plotSize.x, _plotSize.y + _clearance);
				MarkDirty();
			}
		}

		public Vector2 Size => ((Graphic)this).rectTransform.sizeDelta;

		public Color BgColor { get; private set; } = new Color(0f, 0f, 0f, 0.35f);


		public Color BorderColor { get; private set; } = new Color(1f, 1f, 1f, 0.35f);


		public int Capacity => _capacity;

		public float MinY
		{
			get
			{
				return _minY;
			}
			set
			{
				_minY = value;
				MarkDirty();
			}
		}

		public float MaxY
		{
			get
			{
				return _maxY;
			}
			set
			{
				_maxY = value;
				_dispMax = value;
				MarkDirty();
			}
		}

		public float DisplayMaxY => _dispMax;

		public event Action<Graphic, VertexHelper>? AfterPopulateMesh;

		public override void Awake()
		{
			EnsureBuffer();
			_dispMax = _maxY;
		}

		public void SetStyle(PlotComponent style, int channel = 0)
		{
			_styles[channel].DrawLine = style.HasFlag(PlotComponent.Line);
			_styles[channel].DrawFill = style.HasFlag(PlotComponent.Fill);
			_drawBackground = style.HasFlag(PlotComponent.Background);
			_drawBorder = style.HasFlag(PlotComponent.Border);
			MarkDirty();
		}

		public void SetColor(PlotComponent comp, Color c, int channel = 0)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			if (comp.HasFlag(PlotComponent.Line))
			{
				_styles[channel].LineColor = c;
			}
			if (comp.HasFlag(PlotComponent.Fill))
			{
				_styles[channel].FillColor = c;
			}
			if (comp.HasFlag(PlotComponent.Background))
			{
				BgColor = c;
			}
			if (comp.HasFlag(PlotComponent.Border))
			{
				BorderColor = c;
			}
			MarkDirty();
		}

		public void SetThickness(PlotComponent comp, float thickness, int channel = 0)
		{
			if (comp.HasFlag(PlotComponent.Line))
			{
				_styles[channel].LineThickness = Mathf.Max(1f, thickness);
			}
			if (comp.HasFlag(PlotComponent.Fill))
			{
				_styles[channel].FillChunkWidth = Mathf.Max(0f, thickness);
			}
			if (comp.HasFlag(PlotComponent.Border))
			{
				_borderThickness = Mathf.Max(0f, thickness);
			}
			MarkDirty();
		}

		public void SetGraphMinMax(float min, float max)
		{
			_minY = min;
			_maxY = max;
			_dispMax = max;
			MarkDirty();
		}

		public void SetLogScale(bool enable)
		{
			_logScale = enable;
			MarkDirty();
		}

		public void SetSampleCapacity(int capacity)
		{
			_capacity = Mathf.Max(8, capacity);
			EnsureBuffer();
			MarkDirty();
		}

		public void SetAutoScale(bool enable)
		{
			_autoScale = enable;
			MarkDirty();
		}

		public void SetAutoScaleIncrement(float increment)
		{
			_autoscaleInc = increment;
			MarkDirty();
		}

		public void SetAutoScaleLerp(float lerp)
		{
			_autoScaleLerp = Mathf.Clamp01(lerp);
			MarkDirty();
		}

		public void SetClearance(float clearance)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			_clearance = clearance;
			((Graphic)this).rectTransform.sizeDelta = new Vector2(_plotSize.x, _plotSize.y + _clearance);
			MarkDirty();
		}

		public void SetLineResolution(int resolution)
		{
			_lineResolution = Mathf.Max(1, resolution);
			MarkDirty();
		}

		public void AllocateChannels(int channelCount)
		{
			_channelCount = Mathf.Max(1, channelCount);
			EnsureBuffer();
		}

		private void EnsureBuffer()
		{
			if (_styles.Length != _channelCount || _samples.Length != _capacity * _channelCount)
			{
				_styles = new ChannelStyle[_channelCount];
				for (int i = 0; i < _styles.Length; i++)
				{
					_styles[i] = new ChannelStyle();
				}
				_samples = new float[_channelCount, _capacity];
				_heads = new int[_channelCount];
				Array.Fill(_heads, _capacity - 1);
				_counts = new int[_channelCount];
				_maxObserved = new float[_channelCount];
				_dirty = true;
			}
		}

		public void PushSample(float value, int channel = 0)
		{
			EnsureBuffer();
			_heads[channel] = (_heads[channel] + 1) % _capacity;
			_samples[channel, _heads[channel]] = value;
			if (_counts[channel] < _capacity)
			{
				_counts[channel]++;
			}
			if (_autoScale)
			{
				float num = _minY + 0.0001f;
				for (int i = 0; i < _counts[channel]; i++)
				{
					float sampleReverse = GetSampleReverse(i, channel);
					if (sampleReverse > num)
					{
						num = sampleReverse;
					}
				}
				_maxObserved[channel] = Mathf.Max(num, _minY + 0.0001f);
				float num2 = _minY + 0.0001f;
				for (int j = 0; j < _channelCount; j++)
				{
					if (_maxObserved[j] > num2)
					{
						num2 = _maxObserved[j];
					}
				}
				float num3 = num2;
				if (_autoscaleInc > 0f)
				{
					num3 = Mathf.Ceil((num2 - _minY) / _autoscaleInc) * _autoscaleInc + _minY;
				}
				_dispMax = Mathf.Lerp(_dispMax, num3, _autoScaleLerp);
				_dispMax = Mathf.Max(Mathf.Max(_dispMax, _minY + 0.0001f), _maxY);
			}
			MarkDirty();
		}

		public void Clear()
		{
			Array.Clear(_samples);
			for (int i = 0; i < _channelCount; i++)
			{
				_heads[i] = _capacity - 1;
				_counts[i] = 0;
				_maxObserved[i] = _minY;
			}
			MarkDirty();
		}

		private void MarkDirty()
		{
			if (!_dirty)
			{
				_dirty = true;
				((Graphic)this).SetVerticesDirty();
			}
		}

		private float GetSample(int i, int channel = 0)
		{
			int n = _heads[channel] + 1 + i;
			n = Util.TrueMod(n, _capacity);
			if (!_logScale)
			{
				return _samples[channel, n];
			}
			return Mathf.Log(_samples[channel, n]);
		}

		private float GetSampleReverse(int i, int channel = 0)
		{
			int n = _heads[channel] - i;
			n = Util.TrueMod(n, _capacity);
			if (!_logScale)
			{
				return _samples[channel, n];
			}
			return Mathf.Log(_samples[channel, n]);
		}

		public override void OnPopulateMesh(VertexHelper vh)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_0267: Unknown result type (might be due to invalid IL or missing references)
			//IL_026f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0151: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_022e: 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_01e7: 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)
			//IL_01ed: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0205: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_020d: Unknown result type (might be due to invalid IL or missing references)
			//IL_020f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0214: Unknown result type (might be due to invalid IL or missing references)
			vh.Clear();
			_dirty = false;
			Rect pixelAdjustedRect = ((Graphic)this).GetPixelAdjustedRect();
			if (((Rect)(ref pixelAdjustedRect)).width <= 1f || ((Rect)(ref pixelAdjustedRect)).height <= 1f)
			{
				return;
			}
			if (_drawBackground)
			{
				AddRect(vh, pixelAdjustedRect, BgColor);
			}
			Vector2 val2 = default(Vector2);
			for (int i = 0; i < _channelCount; i++)
			{
				ChannelStyle channelStyle = _styles[i];
				if (_counts[i] <= 1)
				{
					continue;
				}
				float num = (_autoScale ? _dispMax : _maxY);
				num = Mathf.Max(num, _minY + 0.0001f);
				float xMin = ((Rect)(ref pixelAdjustedRect)).xMin;
				float xMax = ((Rect)(ref pixelAdjustedRect)).xMax;
				float yMin = ((Rect)(ref pixelAdjustedRect)).yMin;
				float num2 = ((Rect)(ref pixelAdjustedRect)).yMax - _clearance;
				int capacity = _capacity;
				float num3 = (xMax - xMin) / (float)(capacity - 1);
				float num4 = 1f / (num - _minY);
				if (channelStyle.DrawFill)
				{
					float num5 = Mathf.Min(channelStyle.FillChunkWidth * 0.5f, num3 * 0.5f);
					for (int j = 0; j < capacity; j++)
					{
						float num6 = Mathf.Clamp01((GetSample(j, i) - _minY) * num4);
						float num7 = xMin + num3 * (float)j;
						float num8 = Mathf.Lerp(yMin, num2, num6);
						Rect r = Rect.MinMaxRect(num7 - num5, yMin, num7 + num5, num8);
						AddRect(vh, r, channelStyle.FillColor);
					}
				}
				if (!channelStyle.DrawLine)
				{
					continue;
				}
				float halfThickness = channelStyle.LineThickness * 0.5f;
				Vector2 val = default(Vector2);
				for (int k = 0; k < capacity; k++)
				{
					float num9 = Mathf.Clamp01((GetSample(k, i) - _minY) * num4);
					float num10 = xMin + num3 * (float)k;
					float num11 = Mathf.Lerp(yMin, num2, num9);
					((Vector2)(ref val2))..ctor(num10, num11);
					if (k > 0)
					{
						for (int l = 1; l <= _lineResolution; l++)
						{
							float num12 = (float)l / (float)_lineResolution;
							Vector2 b = Vector2.Lerp(val, val2, num12);
							Vector2 a = Vector2.Lerp(val, val2, (float)(l - 1) / (float)_lineResolution);
							AddThickSegment(vh, a, b, halfThickness, channelStyle.LineColor);
						}
					}
					val = val2;
				}
			}
			if (_drawBorder && _borderThickness > 0f)
			{
				AddBorder(vh, pixelAdjustedRect, _borderThickness, BorderColor);
			}
			this.AfterPopulateMesh?.Invoke((Graphic)(object)this, vh);
		}

		public static void AddRect(VertexHelper vh, Rect r, Color c)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: 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_0050: 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)
			//IL_005a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: 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_007b: 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_0086: 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_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			int currentVertCount = vh.currentVertCount;
			UIVertex simpleVert = UIVertex.simpleVert;
			simpleVert.color = Color32.op_Implicit(c);
			simpleVert.position = Vector2.op_Implicit(new Vector2(((Rect)(ref r)).xMin, ((Rect)(ref r)).yMin));
			vh.AddVert(simpleVert);
			simpleVert.position = Vector2.op_Implicit(new Vector2(((Rect)(ref r)).xMin, ((Rect)(ref r)).yMax));
			vh.AddVert(simpleVert);
			simpleVert.position = Vector2.op_Implicit(new Vector2(((Rect)(ref r)).xMax, ((Rect)(ref r)).yMax));
			vh.AddVert(simpleVert);
			simpleVert.position = Vector2.op_Implicit(new Vector2(((Rect)(ref r)).xMax, ((Rect)(ref r)).yMin));
			vh.AddVert(simpleVert);
			vh.AddTriangle(currentVertCount, currentVertCount + 1, currentVertCount + 2);
			vh.AddTriangle(currentVertCount + 2, currentVertCount + 3, currentVertCount);
		}

		private static void AddBorder(VertexHelper vh, Rect r, float thickness, Color c)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			AddRect(vh, Rect.MinMaxRect(((Rect)(ref r)).xMin, ((Rect)(ref r)).yMax - thickness, ((Rect)(ref r)).xMax, ((Rect)(ref r)).yMax), c);
			AddRect(vh, Rect.MinMaxRect(((Rect)(ref r)).xMin, ((Rect)(ref r)).yMin, ((Rect)(ref r)).xMax, ((Rect)(ref r)).yMin + thickness), c);
			AddRect(vh, Rect.MinMaxRect(((Rect)(ref r)).xMin, ((Rect)(ref r)).yMin, ((Rect)(ref r)).xMin + thickness, ((Rect)(ref r)).yMax), c);
			AddRect(vh, Rect.MinMaxRect(((Rect)(ref r)).xMax - thickness, ((Rect)(ref r)).yMin, ((Rect)(ref r)).xMax, ((Rect)(ref r)).yMax), c);
		}

		private static void AddThickSegment(VertexHelper vh, Vector2 a, Vector2 b, float halfThickness, Color c)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: 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_003b: 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_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: 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_0055: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: 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_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_006e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0075: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: 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_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0088: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			Vector2 val = b - a;
			float magnitude = ((Vector2)(ref val)).magnitude;
			if (!(magnitude < 0.0001f))
			{
				val /= magnitude;
				Vector2 val2 = new Vector2(0f - val.y, val.x) * halfThickness;
				Vector2 val3 = a - val2;
				Vector2 val4 = a + val2;
				Vector2 val5 = b + val2;
				Vector2 val6 = b - val2;
				int currentVertCount = vh.currentVertCount;
				UIVertex simpleVert = UIVertex.simpleVert;
				simpleVert.color = Color32.op_Implicit(c);
				simpleVert.position = Vector2.op_Implicit(val3);
				vh.AddVert(simpleVert);
				simpleVert.position = Vector2.op_Implicit(val4);
				vh.AddVert(simpleVert);
				simpleVert.position = Vector2.op_Implicit(val5);
				vh.AddVert(simpleVert);
				simpleVert.position = Vector2.op_Implicit(val6);
				vh.AddVert(simpleVert);
				vh.AddTriangle(currentVertCount, currentVertCount + 1, currentVertCount + 2);
				vh.AddTriangle(currentVertCount + 2, currentVertCount + 3, currentVertCount);
			}
		}
	}
}
namespace Netstat.Config
{
	public enum ConfigEntryRule
	{
		Min,
		Max
	}
	public class ConfigEntryExtended<T>
	{
		private Dictionary<ConfigEntryRule, T> _rules = new Dictionary<ConfigEntryRule, T>();

		private ConfigEntry<T> _entry;

		public T Value
		{
			get
			{
				return _entry.Value;
			}
			set
			{
				_entry.Value = Enforce(value);
			}
		}

		public object BoxedValue
		{
			get
			{
				return ((ConfigEntryBase)_entry).BoxedValue;
			}
			set
			{
				((ConfigEntryBase)_entry).BoxedValue = Enforce((T)value);
			}
		}

		public ConfigEntryExtended(ConfigEntry<T> entry)
		{
			_entry = entry;
		}

		public bool AddRule(ConfigEntryRule rule, T ruleValue)
		{
			if (_rules.TryAdd(rule, ruleValue))
			{
				Enforce(rule);
				return true;
			}
			return false;
		}

		private void Enforce()
		{
			T val = Enforce(_entry.Value);
			if (val != null && !val.Equals(_entry.Value))
			{
				_entry.Value = val;
			}
		}

		private T Enforce(T val)
		{
			foreach (var (configEntryRule2, val3) in _rules)
			{
				switch (configEntryRule2)
				{
				case ConfigEntryRule.Min:
					if (Comparer<T>.Default.Compare(val, val3) < 0)
					{
						val = val3;
					}
					break;
				case ConfigEntryRule.Max:
					if (Comparer<T>.Default.Compare(val, val3) > 0)
					{
						val = val3;
					}
					break;
				}
			}
			return val;
		}

		private void Enforce(ConfigEntryRule rule)
		{
			T value = _entry.Value;
			value = Enforce(value, rule);
			if (value != null && !value.Equals(_entry.Value))
			{
				_entry.Value = value;
			}
		}

		private T Enforce(T val, ConfigEntryRule rule)
		{
			if (!_rules.TryGetValue(rule, out var value))
			{
				return val;
			}
			switch (rule)
			{
			case ConfigEntryRule.Min:
				if (Comparer<T>.Default.Compare(val, value) < 0)
				{
					val = value;
				}
				break;
			case ConfigEntryRule.Max:
				if (Comparer<T>.Default.Compare(val, value) > 0)
				{
					val = value;
				}
				break;
			}
			return val;
		}

		public static implicit operator ConfigEntryExtended<T>(ConfigEntry<T> entry)
		{
			return new ConfigEntryExtended<T>(entry);
		}
	}
	internal static class ConfigMgr
	{
		private static readonly ConfigFile Conf;

		private static readonly FileSystemWatcher? ConfigWatcher;

		private static readonly ConfigEntryExtended<bool> DebugConf;

		private static readonly ConfigEntryExtended<NetstatAPI.PingerTypeEnum> PingerTypeConf;

		private static readonly ConfigEntryExtended<float> UIAnchorXConf;

		private static readonly ConfigEntryExtended<float> UIAnchorYConf;

		private static readonly ConfigEntryExtended<float> UIAnchorOffsetXConf;

		private static readonly ConfigEntryExtended<float> UIAnchorOffsetYConf;

		private static readonly ConfigEntryExtended<bool> GraphEnabledConf;

		private static readonly ConfigEntryExtended<KeyCode> GraphToggleKeyConf;

		private static readonly ConfigEntryExtended<float> GraphSizeXConf;

		private static readonly ConfigEntryExtended<float> GraphSizeYConf;

		private static readonly ConfigEntryExtended<eNetstatGraph> EnabledGraphsConf;

		private static readonly ConfigEntryExtended<string> GraphsOrderConf;

		private static readonly ConfigEntryExtended<bool> DetailsBarEnabledConf;

		private static readonly ConfigEntryExtended<eNetstatData> DetailsBarDataConf;

		public static bool Processed { get; private set; }

		public static bool Debug => DebugConf.Value;

		public static NetstatAPI.PingerTypeEnum PingerType => PingerTypeConf.Value;

		public static Vector2 UIAnchor => new Vector2(UIAnchorXConf.Value, UIAnchorYConf.Value);

		public static Vector2 UIAnchorOffset => new Vector2(UIAnchorOffsetXConf.Value, UIAnchorOffsetYConf.Value);

		public static bool EnableGraphs
		{
			get
			{
				return GraphEnabledConf.Value;
			}
			set
			{
				GraphEnabledConf.Value = value;
			}
		}

		public static KeyCode GraphToggleKey => GraphToggleKeyConf.Value;

		public static Vector2 GraphSize => new Vector2(GraphSizeXConf.Value, GraphSizeYConf.Value);

		public static eNetstatGraph EnabledGraphs => EnabledGraphsConf.Value;

		public static List<eNetstatGraph> GraphsInOrder { get; }

		public static bool DetailsBarEnabled => DetailsBarEnabledConf.Value;

		public static eNetstatData DetailsBarData => DetailsBarDataConf.Value;

		public static void Init()
		{
			Logger.Info($"debug={Debug}");
			Process();
		}

		public static void Process()
		{
			GraphsInOrder.Clear();
			eNetstatGraph[] array = GraphsOrderConf.Value.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries).Select(StatConfigLib.Str2GraphType).ToArray();
			foreach (eNetstatGraph eNetstatGraph in array)
			{
				if (!Enum.IsDefined(eNetstatGraph))
				{
					Logger.Warn($"Invalid graph type in Graphs Order config: {eNetstatGraph}");
				}
				else if (!GraphsInOrder.Contain