Decompiled source of CSync v5.0.1

BepInEx/plugins/CSync/com.sigurd.csync.dll

Decompiled 6 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Cryptography;
using System.Security.Permissions;
using System.Text;
using System.Threading;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CSync.Extensions;
using CSync.Lib;
using CSync.Util;
using HarmonyLib;
using JetBrains.Annotations;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
using com.sigurd.csync.NetcodePatcher;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: IgnoresAccessChecksTo("ClientNetworkTransform")]
[assembly: IgnoresAccessChecksTo("DissonanceVoip")]
[assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")]
[assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")]
[assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")]
[assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")]
[assembly: IgnoresAccessChecksTo("Unity.Burst")]
[assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")]
[assembly: IgnoresAccessChecksTo("Unity.Collections")]
[assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem")]
[assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")]
[assembly: IgnoresAccessChecksTo("Unity.Jobs")]
[assembly: IgnoresAccessChecksTo("Unity.Mathematics")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")]
[assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")]
[assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")]
[assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")]
[assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")]
[assembly: IgnoresAccessChecksTo("Unity.Services.QoS")]
[assembly: IgnoresAccessChecksTo("Unity.Services.Relay")]
[assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")]
[assembly: IgnoresAccessChecksTo("Unity.Timeline")]
[assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")]
[assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")]
[assembly: IgnoresAccessChecksTo("UnityEngine.UI")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("Sigurd Team")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Configuration file syncing library for BepInEx.\n            Allows serialization of a ConfigEntry with a drop in replacement.\n\n            A usage guide can be found on the Thunderstore wiki.\n            https://thunderstore.io/c/lethal-company/p/Sigurd/CSync/wiki/\n        ")]
[assembly: AssemblyFileVersion("5.0.1.0")]
[assembly: AssemblyInformationalVersion("5.0.1+3ddfccad9bb0ff70bf3b3b9061a60ae274a5b0a5")]
[assembly: AssemblyProduct("CSync")]
[assembly: AssemblyTitle("com.sigurd.csync")]
[assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/lc-sigurd/CSync")]
[assembly: NeutralResourcesLanguage("en-GB")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("5.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
[module: NetcodePatchedAssembly]
internal class <Module>
{
	static <Module>()
	{
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedByMemcpy<bool>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<bool>();
		NetworkVariableSerializationTypes.InitializeSerializer_UnmanagedINetworkSerializable<SyncedEntryDelta>();
		NetworkVariableSerializationTypes.InitializeEqualityChecker_UnmanagedIEquatable<SyncedEntryDelta>();
	}
}
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class IsUnmanagedAttribute : Attribute
	{
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

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

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

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace Unity.Netcode
{
	internal class ListierNetworkList<T> : NetworkList<T>, IList<T>, ICollection<T>, IEnumerable<T>, IEnumerable where T : unmanaged, IEquatable<T>
	{
		public bool IsReadOnly => false;

		IEnumerator IEnumerable.GetEnumerator()
		{
			return base.GetEnumerator();
		}

		public void CopyTo(T[] array, int arrayIndex)
		{
			throw new NotSupportedException();
		}

		T IList<T>.get_Item(int index)
		{
			return base[index];
		}

		void IList<T>.set_Item(int index, T value)
		{
			base[index] = value;
		}

		int IList<T>.IndexOf(T item)
		{
			return base.IndexOf(item);
		}

		void IList<T>.Insert(int index, T item)
		{
			base.Insert(index, item);
		}

		void IList<T>.RemoveAt(int index)
		{
			base.RemoveAt(index);
		}

		int ICollection<T>.get_Count()
		{
			return base.Count;
		}

		void ICollection<T>.Add(T item)
		{
			base.Add(item);
		}

		void ICollection<T>.Clear()
		{
			base.Clear();
		}

		bool ICollection<T>.Contains(T item)
		{
			return base.Contains(item);
		}

		bool ICollection<T>.Remove(T item)
		{
			return base.Remove(item);
		}

		IEnumerator<T> IEnumerable<T>.GetEnumerator()
		{
			return base.GetEnumerator();
		}
	}
}
namespace CSync
{
	[BepInPlugin("com.sigurd.csync", "CSync", "5.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		internal static Harmony Patcher;

		internal static ManualLogSource Logger { get; private set; }

		private void Awake()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			try
			{
				Patcher = new Harmony("com.sigurd.csync");
				Patcher.PatchAll();
				Logger.LogInfo((object)"CSync successfully applied patches.");
			}
			catch (Exception ex)
			{
				Logger.LogError((object)ex);
			}
		}
	}
	internal static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "com.sigurd.csync";

		public const string PLUGIN_NAME = "CSync";

		public const string PLUGIN_VERSION = "5.0.1";
	}
}
namespace CSync.Util
{
	[Obsolete]
	public class ByteSerializer<T>
	{
	}
	[Obsolete("Use SyncedBindingExtensions instead.")]
	public static class Extensions
	{
		[Obsolete("Use SyncedBindingExtensions instead.")]
		public static SyncedEntry<T> BindSyncedEntry<T>(this ConfigFile configFile, string section, string key, T defaultValue, string description)
		{
			return SyncedBindingExtensions.BindSyncedEntry(configFile, section, key, defaultValue, description);
		}

		[Obsolete("Use SyncedBindingExtensions instead.")]
		public static SyncedEntry<T> BindSyncedEntry<T>(this ConfigFile configFile, string section, string key, T defaultValue, ConfigDescription? description = null)
		{
			return SyncedBindingExtensions.BindSyncedEntry(configFile, section, key, defaultValue, description);
		}

		[Obsolete("Use SyncedBindingExtensions instead.")]
		public static SyncedEntry<T> BindSyncedEntry<T>(this ConfigFile configFile, ConfigDefinition definition, T defaultValue, string description)
		{
			return SyncedBindingExtensions.BindSyncedEntry(configFile, definition, defaultValue, description);
		}

		[Obsolete("Use SyncedBindingExtensions instead.")]
		public static SyncedEntry<T> BindSyncedEntry<T>(this ConfigFile configFile, ConfigDefinition definition, T defaultValue, ConfigDescription? description = null)
		{
			return SyncedBindingExtensions.BindSyncedEntry(configFile, definition, defaultValue, description);
		}

		[Obsolete("Use SyncedBindingExtensions instead.")]
		public static SyncedEntry<T> ToSyncedEntry<T>(this ConfigEntry<T> entry)
		{
			return SyncedBindingExtensions.ToSyncedEntry<T>(entry);
		}
	}
}
namespace CSync.Patches
{
	[HarmonyPatch(typeof(GameNetworkManager))]
	public static class GameNetworkManagerPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void OnNetworkManagerStart(GameNetworkManager __instance)
		{
			ConfigManager.PopulateEntries();
			if (!NetworkManager.Singleton.NetworkConfig.Prefabs.Contains(ConfigManager.Prefab))
			{
				NetworkManager.Singleton.AddNetworkPrefab(ConfigManager.Prefab);
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound))]
	public static class StartOfRoundPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPostfix]
		public static void OnSessionStart(StartOfRound __instance)
		{
			if (!((NetworkBehaviour)__instance).IsOwner)
			{
				return;
			}
			try
			{
				GameObject obj = Object.Instantiate<GameObject>(ConfigManager.Prefab, ((Component)__instance).transform);
				((Object)obj).hideFlags = (HideFlags)0;
				obj.GetComponent<NetworkObject>().Spawn(false);
			}
			catch (Exception arg)
			{
				Plugin.Logger.LogError((object)$"Failed to instantiate config sync behaviours:\n{arg}");
			}
		}
	}
}
namespace CSync.Lib
{
	[PublicAPI]
	public static class ConfigManager
	{
		[Serializable]
		[UsedImplicitly]
		public record struct InstanceKey
		{
			public string Guid => _guid;

			public string AssemblyQualifiedName => _assemblyQualifiedName;

			[SerializeField]
			private string _guid;

			[SerializeField]
			private string _assemblyQualifiedName;

			public InstanceKey(string guid, string assemblyQualifiedName)
			{
				_guid = guid;
				_assemblyQualifiedName = assemblyQualifiedName;
			}

			[CompilerGenerated]
			private bool PrintMembers(StringBuilder builder)
			{
				builder.Append("Guid = ");
				builder.Append((object?)Guid);
				builder.Append(", AssemblyQualifiedName = ");
				builder.Append((object?)AssemblyQualifiedName);
				return true;
			}
		}

		internal static readonly Dictionary<string, ConfigFile> FileCache;

		internal static readonly Dictionary<InstanceKey, ISyncedConfig> Instances;

		internal static readonly Dictionary<InstanceKey, EventHandler> InitialSyncHandlers;

		private static readonly Lazy<GameObject> LazyPrefab;

		internal static GameObject Prefab => LazyPrefab.Value;

		private static event Action? OnPopulateEntriesRequested;

		internal static void PopulateEntries()
		{
			ConfigManager.OnPopulateEntriesRequested?.Invoke();
		}

		static ConfigManager()
		{
			FileCache = new Dictionary<string, ConfigFile>();
			Instances = new Dictionary<InstanceKey, ISyncedConfig>();
			InitialSyncHandlers = new Dictionary<InstanceKey, EventHandler>();
			LazyPrefab = new Lazy<GameObject>((Func<GameObject>)delegate
			{
				//IL_0005: Unknown result type (might be due to invalid IL or missing references)
				//IL_000a: Unknown result type (might be due to invalid IL or missing references)
				//IL_0013: Expected O, but got Unknown
				//IL_0025: 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_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_006c: Expected O, but got Unknown
				GameObject val = new GameObject("CSyncPrefabContainer")
				{
					hideFlags = (HideFlags)61
				};
				val.SetActive(false);
				Object.DontDestroyOnLoad((Object)(object)val);
				GameObject val2 = new GameObject("ConfigSyncHolder");
				val2.transform.SetParent(val.transform);
				NetworkObject obj = val2.AddComponent<NetworkObject>();
				byte[] array = MD5.Create().ComputeHash(Encoding.UTF8.GetBytes("com.sigurd.csync:ConfigSyncHolder"));
				obj.GlobalObjectIdHash = BitConverter.ToUInt32(array);
				return val2;
			});
		}

		internal static void AddToFileCache(ConfigFile configFile)
		{
			FileCache.TryAdd(configFile.GetConfigFileRelativePath(), configFile);
		}

		internal static ConfigFile GetConfigFile(string relativePath)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Expected O, but got Unknown
			if (FileCache.TryGetValue(relativePath, out ConfigFile value))
			{
				return value;
			}
			value = new ConfigFile(Path.GetFullPath(Path.Combine(Paths.BepInExRootPath, relativePath)), false);
			FileCache.Add(relativePath, value);
			return value;
		}

		[Obsolete("Obsolete, use SyncedConfig2")]
		public static void Register<T>(T config) where T : SyncedConfig<T>
		{
			Register((SyncedConfig<T>)config);
		}

		[Obsolete("Obsolete, use SyncedConfig2")]
		public static void Register<T>(SyncedConfig<T> config) where T : SyncedConfig<T>
		{
			if (config == null)
			{
				throw new ArgumentNullException("config", "Config instance is null, cannot register.");
			}
			if (!(config is T))
			{
				throw new ArgumentException(string.Format("{0} declares it extends {1}<{2}>. It should be declared to extend {3}<{4}>.", config.GetType(), "SyncedConfig", typeof(T), "SyncedConfig", config.GetType()), "config");
			}
			string assemblyQualifiedName = typeof(T).AssemblyQualifiedName ?? throw new ArgumentException("config");
			InstanceKey instanceKey = new InstanceKey(config.GUID, assemblyQualifiedName);
			try
			{
				Instances.Add(instanceKey, config);
				InitialSyncHandlers.Add(instanceKey, config.OnInitialSyncCompleted);
			}
			catch (ArgumentException innerException)
			{
				throw new InvalidOperationException($"Attempted to register config instance of type `{typeof(T)}`, but an instance has already been registered with key {instanceKey}.", innerException);
			}
			Plugin.Logger.LogDebug((object)$"Successfully registered config instance {instanceKey}.");
			SyncedInstance<T>.Instance = (T)config;
			SyncedInstance<T>.Default = (T)config;
			OnPopulateEntriesRequested += config.PopulateEntryContainer;
			Prefab.AddComponent<ConfigSyncBehaviour>().ConfigInstanceKey = instanceKey;
		}

		public static void Register<T>(SyncedConfig2<T> config) where T : SyncedConfig2<T>
		{
			if (config == null)
			{
				throw new ArgumentNullException("config", "Config instance is null, cannot register.");
			}
			if (!(config is T))
			{
				throw new ArgumentException(string.Format("{0} declares it extends {1}<{2}>. It should be declared to extend {3}<{4}>.", config.GetType(), "SyncedConfig2", typeof(T), "SyncedConfig2", config.GetType()), "config");
			}
			string assemblyQualifiedName = typeof(T).AssemblyQualifiedName ?? throw new ArgumentException("config");
			InstanceKey instanceKey = new InstanceKey(config.GUID, assemblyQualifiedName);
			try
			{
				Instances.Add(instanceKey, config);
				InitialSyncHandlers.Add(instanceKey, config.OnInitialSyncCompleted);
			}
			catch (ArgumentException innerException)
			{
				throw new InvalidOperationException($"Attempted to register config instance of type `{typeof(T)}`, but an instance has already been registered with key {instanceKey}.", innerException);
			}
			config.PopulateEntryContainer();
			Plugin.Logger.LogDebug((object)$"Successfully registered config instance {instanceKey}.");
			Prefab.AddComponent<ConfigSyncBehaviour>().ConfigInstanceKey = instanceKey;
		}
	}
	public class ConfigSyncBehaviour : NetworkBehaviour
	{
		private ISyncedEntryContainer? _entryContainer;

		private readonly NetworkVariable<bool> _syncEnabled = new NetworkVariable<bool>(false, (NetworkVariableReadPermission)0, (NetworkVariableWritePermission)0);

		private NetworkList<SyncedEntryDelta> _deltas;

		[field: SerializeField]
		public ConfigManager.InstanceKey ConfigInstanceKey { get; internal set; }

		private ISyncedConfig? Config
		{
			get
			{
				if (!ConfigManager.Instances.TryGetValue(ConfigInstanceKey, out ISyncedConfig value))
				{
					return null;
				}
				return value;
			}
		}

		private EventHandler? InitialSyncCompletedHandler
		{
			get
			{
				if (!ConfigManager.InitialSyncHandlers.TryGetValue(ConfigInstanceKey, out EventHandler value))
				{
					return null;
				}
				return value;
			}
		}

		internal ISyncedEntryContainer? EntryContainer => _entryContainer ?? (_entryContainer = Config?.EntryContainer);

		public bool SyncEnabled
		{
			get
			{
				return _syncEnabled.Value;
			}
			set
			{
				_syncEnabled.Value = value;
			}
		}

		[MemberNotNull("EntryContainer")]
		private void EnsureEntryContainer()
		{
			if (EntryContainer != null)
			{
				return;
			}
			throw new InvalidOperationException("Entry container has not been assigned.");
		}

		private void Awake()
		{
			EnsureEntryContainer();
			_deltas = new NetworkList<SyncedEntryDelta>();
		}

		public override void OnNetworkSpawn()
		{
			EnsureEntryContainer();
			if (((NetworkBehaviour)this).IsServer)
			{
				_syncEnabled.Value = true;
				foreach (SyncedEntryBase syncedEntryBase in EntryContainer.Values)
				{
					int currentIndex = _deltas.Count;
					_deltas.Add(syncedEntryBase.ToDelta());
					syncedEntryBase.BoxedEntry.ConfigFile.SettingChanged += delegate(object _, SettingChangedEventArgs args)
					{
						if (syncedEntryBase.BoxedEntry == args.ChangedSetting)
						{
							_deltas[currentIndex] = syncedEntryBase.ToDelta();
						}
					};
					syncedEntryBase.SyncEnabledChanged += delegate
					{
						_deltas[currentIndex] = syncedEntryBase.ToDelta();
					};
				}
				InitialSyncCompletedHandler?.Invoke(this, EventArgs.Empty);
			}
			else
			{
				if (!((NetworkBehaviour)this).IsClient)
				{
					return;
				}
				NetworkVariable<bool> syncEnabled = _syncEnabled;
				syncEnabled.OnValueChanged = (OnValueChangedDelegate<bool>)(object)Delegate.Combine((Delegate?)(object)syncEnabled.OnValueChanged, (Delegate?)(object)new OnValueChangedDelegate<bool>(OnSyncEnabledChanged));
				_deltas.OnListChanged += OnClientDeltaListChanged;
				foreach (SyncedEntryDelta delta in _deltas)
				{
					UpdateOverrideValue(delta);
				}
				if (_syncEnabled.Value)
				{
					EnableOverrides();
				}
				InitialSyncCompletedHandler?.Invoke(this, EventArgs.Empty);
			}
		}

		public override void OnDestroy()
		{
			DisableOverrides();
			foreach (SyncedEntryDelta delta in _deltas)
			{
				ResetOverrideValue(delta);
			}
			((NetworkBehaviour)this).OnDestroy();
		}

		private void OnSyncEnabledChanged(bool previousValue, bool newValue)
		{
			if (previousValue != newValue)
			{
				if (newValue)
				{
					EnableOverrides();
				}
				else
				{
					DisableOverrides();
				}
			}
		}

		private void OnClientDeltaListChanged(NetworkListEvent<SyncedEntryDelta> args)
		{
			//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_0006: 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_0029: Expected I4, but got Unknown
			//IL_0039: 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)
			EventType<SyncedEntryDelta> type = args.Type;
			switch ((int)type)
			{
			case 2:
			case 3:
				ResetOverrideValue(args.PreviousValue);
				break;
			case 0:
			case 1:
			case 4:
				UpdateOverrideValue(args.Value);
				break;
			case 5:
			{
				foreach (SyncedEntryDelta delta in _deltas)
				{
					ResetOverrideValue(delta);
				}
				break;
			}
			case 6:
			{
				foreach (SyncedEntryDelta delta2 in _deltas)
				{
					UpdateOverrideValue(delta2);
				}
				break;
			}
			default:
				throw new ArgumentOutOfRangeException();
			}
		}

		private void ResetOverrideValue(SyncedEntryDelta delta)
		{
			EnsureEntryContainer();
			try
			{
				SyncedEntryBase syncedEntryBase = EntryContainer[delta.SyncedEntryIdentifier];
				syncedEntryBase.BoxedValueOverride = syncedEntryBase.BoxedEntry.DefaultValue;
			}
			catch (KeyNotFoundException)
			{
			}
		}

		private void UpdateOverrideValue(SyncedEntryDelta delta)
		{
			EnsureEntryContainer();
			try
			{
				SyncedEntryBase syncedEntryBase = EntryContainer[delta.SyncedEntryIdentifier];
				syncedEntryBase.SetSerializedValueOverride(((FixedString512Bytes)(ref delta.SerializedValue)).Value);
				syncedEntryBase.ValueOverridden = delta.SyncEnabled && SyncEnabled;
			}
			catch (KeyNotFoundException)
			{
				Plugin.Logger.Log((LogLevel)4, (object)$"Setting \"{delta.Definition}\" could not be found, so its synced value override will be ignored.");
			}
			catch (Exception ex2)
			{
				Plugin.Logger.Log((LogLevel)4, (object)$"Synced value override of setting \"{delta.Definition}\" could not be parsed and will be ignored. Reason: {ex2.Message}; Value: {((FixedString512Bytes)(ref delta.SerializedValue)).Value}");
			}
		}

		private void EnableOverrides()
		{
			EnsureEntryContainer();
			foreach (SyncedEntryDelta delta in _deltas)
			{
				try
				{
					EntryContainer[delta.SyncedEntryIdentifier].ValueOverridden = delta.SyncEnabled;
				}
				catch (KeyNotFoundException)
				{
					Plugin.Logger.Log((LogLevel)4, (object)$"Setting \"{delta.Definition}\" could not be found, so its value override could not be enabled.");
				}
			}
		}

		private void DisableOverrides()
		{
			EnsureEntryContainer();
			foreach (SyncedEntryBase value in EntryContainer.Values)
			{
				value.ValueOverridden = false;
			}
		}

		protected override void __initializeVariables()
		{
			if (_syncEnabled == null)
			{
				throw new Exception("ConfigSyncBehaviour._syncEnabled cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)_syncEnabled).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_syncEnabled, "_syncEnabled");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)_syncEnabled);
			if (_deltas == null)
			{
				throw new Exception("ConfigSyncBehaviour._deltas cannot be null. All NetworkVariableBase instances must be initialized.");
			}
			((NetworkVariableBase)_deltas).Initialize((NetworkBehaviour)(object)this);
			((NetworkBehaviour)this).__nameNetworkVariable((NetworkVariableBase)(object)_deltas, "_deltas");
			base.NetworkVariableFields.Add((NetworkVariableBase)(object)_deltas);
			((NetworkBehaviour)this).__initializeVariables();
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		protected internal override string? __getTypeName()
		{
			return "ConfigSyncBehaviour";
		}
	}
	public interface ISyncedConfig
	{
		string GUID { get; }

		ISyncedEntryContainer EntryContainer { get; }
	}
	public interface ISyncedEntryContainer : IDictionary<(string ConfigFileRelativePath, SyncedConfigDefinition Definition), SyncedEntryBase>, ICollection<KeyValuePair<(string ConfigFileRelativePath, SyncedConfigDefinition Definition), SyncedEntryBase>>, IEnumerable<KeyValuePair<(string ConfigFileRelativePath, SyncedConfigDefinition Definition), SyncedEntryBase>>, IEnumerable
	{
	}
	[PublicAPI]
	[Obsolete("Obsolete, use SyncedConfig2")]
	public class SyncedConfig<T> : SyncedInstance<T>, ISyncedConfig where T : SyncedConfig<T>
	{
		private int _entryContainerPopulated;

		private static Lazy<FieldInfo[]> SyncedEntryFields = new Lazy<FieldInfo[]>(() => (from field in AccessTools.GetDeclaredFields(typeof(T))
			where field.GetCustomAttribute<DataMemberAttribute>() != null
			where typeof(SyncedEntryBase).IsAssignableFrom(field.FieldType)
			select field).ToArray());

		public ISyncedEntryContainer EntryContainer { get; } = new SyncedEntryContainer();


		public string GUID { get; }

		public event EventHandler? InitialSyncCompleted;

		public SyncedConfig(string guid)
		{
			GUID = guid;
		}

		internal void PopulateEntryContainer()
		{
			if (Interlocked.Exchange(ref _entryContainerPopulated, 1) == 0)
			{
				FieldInfo[] value = SyncedEntryFields.Value;
				for (int i = 0; i < value.Length; i++)
				{
					SyncedEntryBase syncedEntryBase = (SyncedEntryBase)value[i].GetValue(this);
					EntryContainer.Add(syncedEntryBase.BoxedEntry.ToSyncedEntryIdentifier(), syncedEntryBase);
				}
			}
		}

		internal void OnInitialSyncCompleted(object sender, EventArgs e)
		{
			this.InitialSyncCompleted?.Invoke(sender, e);
		}
	}
	[PublicAPI]
	public class SyncedConfig2<T> : ISyncedConfig where T : SyncedConfig2<T>
	{
		private int _entryContainerPopulated;

		private static Lazy<FieldInfo[]> SyncedEntryFields = new Lazy<FieldInfo[]>(() => (from field in AccessTools.GetDeclaredFields(typeof(T))
			where field.GetCustomAttribute<SyncedEntryFieldAttribute>() != null
			where typeof(SyncedEntryBase).IsAssignableFrom(field.FieldType)
			select field).ToArray());

		public ISyncedEntryContainer EntryContainer { get; } = new SyncedEntryContainer();


		public string GUID { get; }

		public event EventHandler? InitialSyncCompleted;

		public SyncedConfig2(string guid)
		{
			GUID = guid;
		}

		internal void PopulateEntryContainer()
		{
			if (Interlocked.Exchange(ref _entryContainerPopulated, 1) == 0)
			{
				FieldInfo[] value = SyncedEntryFields.Value;
				for (int i = 0; i < value.Length; i++)
				{
					SyncedEntryBase syncedEntryBase = (SyncedEntryBase)value[i].GetValue(this);
					EntryContainer.Add(syncedEntryBase.BoxedEntry.ToSyncedEntryIdentifier(), syncedEntryBase);
				}
			}
		}

		internal void OnInitialSyncCompleted(object sender, EventArgs e)
		{
			this.InitialSyncCompleted?.Invoke(sender, e);
		}
	}
	public struct SyncedConfigDefinition : INetworkSerializable, IEquatable<SyncedConfigDefinition>
	{
		public FixedString128Bytes Section;

		public FixedString128Bytes Key;

		public SyncedConfigDefinition(FixedString128Bytes section, FixedString128Bytes key)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			Section = section;
			Key = key;
		}

		public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
		{
			//IL_0040: 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_0050: 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_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: 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_001b: 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_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			if (serializer.IsReader)
			{
				FastBufferReader fastBufferReader = serializer.GetFastBufferReader();
				((FastBufferReader)(ref fastBufferReader)).ReadValueSafe<FixedString128Bytes>(ref Section, default(ForFixedStrings));
				((FastBufferReader)(ref fastBufferReader)).ReadValueSafe<FixedString128Bytes>(ref Key, default(ForFixedStrings));
			}
			else
			{
				FastBufferWriter fastBufferWriter = serializer.GetFastBufferWriter();
				((FastBufferWriter)(ref fastBufferWriter)).WriteValueSafe<FixedString128Bytes>(ref Section, default(ForFixedStrings));
				((FastBufferWriter)(ref fastBufferWriter)).WriteValueSafe<FixedString128Bytes>(ref Key, default(ForFixedStrings));
			}
		}

		public bool Equals(SyncedConfigDefinition other)
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			if (((FixedString128Bytes)(ref Section)).Equals(other.Section))
			{
				return ((FixedString128Bytes)(ref Key)).Equals(other.Key);
			}
			return false;
		}

		public override bool Equals(object? obj)
		{
			if (obj is SyncedConfigDefinition other)
			{
				return Equals(other);
			}
			return false;
		}

		public override int GetHashCode()
		{
			//IL_0001: 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)
			return HashCode.Combine<FixedString128Bytes, FixedString128Bytes>(Section, Key);
		}
	}
	[PublicAPI]
	public sealed class SyncedEntry<T> : SyncedEntryBase
	{
		private ConfigEntry<T> _entry;

		private T _lastLocalValue;

		private T _typedValueOverride;

		public ConfigEntry<T> Entry
		{
			get
			{
				return _entry;
			}
			init
			{
				_entry = value;
				_lastLocalValue = _entry.Value;
				Entry.SettingChanged += OnLocalSettingChanged;
			}
		}

		public override ConfigEntryBase BoxedEntry
		{
			get
			{
				return (ConfigEntryBase)(object)Entry;
			}
			protected init
			{
				Entry = (ConfigEntry<T>)(object)value;
			}
		}

		public override bool ValueOverridden
		{
			get
			{
				return base.ValueOverridden;
			}
			internal set
			{
				if (value != base.ValueOverridden)
				{
					T value2 = Value;
					base.ValueOverridden = value;
					OnValueOverriddenChanged(this, value2);
				}
			}
		}

		public T LocalValue
		{
			get
			{
				return Entry.Value;
			}
			set
			{
				Entry.Value = value;
			}
		}

		public override object? BoxedValueOverride
		{
			get
			{
				return _typedValueOverride;
			}
			set
			{
				T value2 = Value;
				_typedValueOverride = (T)value;
				OnValueOverrideChanged(this, value2);
			}
		}

		public T Value
		{
			get
			{
				if (ValueOverridden)
				{
					return _typedValueOverride;
				}
				return LocalValue;
			}
		}

		public event EventHandler<SyncedSettingChangedEventArgs<T>>? Changed;

		private void OnLocalSettingChanged(object sender, EventArgs e)
		{
			object sender2 = sender;
			InvokeChangedIfNecessary();
			_lastLocalValue = LocalValue;
			void InvokeChangedIfNecessary()
			{
				if (!ValueOverridden && !object.Equals(_lastLocalValue, LocalValue))
				{
					SyncedSettingChangedEventArgs<T> e2 = new SyncedSettingChangedEventArgs<T>
					{
						OldValue = _lastLocalValue,
						NewValue = LocalValue,
						ChangedEntry = this
					};
					this.Changed?.Invoke(sender2, e2);
				}
			}
		}

		private void OnValueOverrideChanged(object sender, T oldValue)
		{
			if (ValueOverridden && !object.Equals(oldValue, _typedValueOverride))
			{
				SyncedSettingChangedEventArgs<T> e = new SyncedSettingChangedEventArgs<T>
				{
					OldValue = oldValue,
					NewValue = _typedValueOverride,
					ChangedEntry = this
				};
				this.Changed?.Invoke(sender, e);
			}
		}

		private void OnValueOverriddenChanged(object sender, T oldValue)
		{
			if (!object.Equals(Value, oldValue))
			{
				SyncedSettingChangedEventArgs<T> e = new SyncedSettingChangedEventArgs<T>
				{
					OldValue = oldValue,
					NewValue = Value,
					ChangedEntry = this
				};
				this.Changed?.Invoke(sender, e);
			}
		}

		public static implicit operator T(SyncedEntry<T> e)
		{
			return e.Value;
		}

		public SyncedEntry(ConfigEntry<T> entry)
			: base((ConfigEntryBase)(object)entry)
		{
		}

		public override string ToString()
		{
			return $"Key: {((ConfigEntryBase)Entry).Definition.Key}\nLocal Value: {LocalValue}\nCurrent Value: {Value}";
		}
	}
	public abstract class SyncedEntryBase
	{
		private bool _syncEnabled = true;

		public abstract ConfigEntryBase BoxedEntry { get; protected init; }

		public abstract object? BoxedValueOverride { get; set; }

		public bool SyncEnabled
		{
			get
			{
				return _syncEnabled;
			}
			set
			{
				if (value != _syncEnabled)
				{
					_syncEnabled = value;
					this.SyncEnabledChanged?.Invoke(this, EventArgs.Empty);
				}
			}
		}

		public virtual bool ValueOverridden { get; internal set; }

		internal event EventHandler? SyncEnabledChanged;

		internal SyncedEntryBase(ConfigEntryBase configEntry)
		{
			BoxedEntry = configEntry ?? throw new ArgumentNullException("configEntry");
			BoxedValueOverride = configEntry.DefaultValue;
		}

		public void SetSerializedValueOverride(string value)
		{
			BoxedValueOverride = TomlTypeConverter.ConvertToValue(value, BoxedEntry.SettingType);
		}

		internal SyncedEntryDelta ToDelta()
		{
			//IL_0010: 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)
			return new SyncedEntryDelta(FixedString128Bytes.op_Implicit(BoxedEntry.ConfigFile.GetConfigFileRelativePath()), BoxedEntry.Definition.ToSynced(), FixedString512Bytes.op_Implicit(BoxedEntry.GetSerializedValue()), SyncEnabled);
		}
	}
	public class SyncedEntryContainer : Dictionary<(string ConfigFileRelativePath, SyncedConfigDefinition Definition), SyncedEntryBase>, ISyncedEntryContainer, IDictionary<(string ConfigFileRelativePath, SyncedConfigDefinition Definition), SyncedEntryBase>, ICollection<KeyValuePair<(string ConfigFileRelativePath, SyncedConfigDefinition Definition), SyncedEntryBase>>, IEnumerable<KeyValuePair<(string ConfigFileRelativePath, SyncedConfigDefinition Definition), SyncedEntryBase>>, IEnumerable
	{
		public bool TryGetEntry<T>(string configFileRelativePath, SyncedConfigDefinition configDefinition, [MaybeNullWhen(false)] out SyncedEntry<T> entry)
		{
			if (TryGetValue((configFileRelativePath, configDefinition), out SyncedEntryBase value))
			{
				entry = (SyncedEntry<T>)value;
				return true;
			}
			entry = null;
			return false;
		}

		public bool TryGetEntry<T>(string configFileRelativePath, string section, string key, [MaybeNullWhen(false)] out SyncedEntry<T> entry)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			return TryGetEntry(configFileRelativePath, new SyncedConfigDefinition(FixedString128Bytes.op_Implicit(section), FixedString128Bytes.op_Implicit(key)), out entry);
		}
	}
	internal struct SyncedEntryDelta : INetworkSerializable, IEquatable<SyncedEntryDelta>
	{
		public SyncedConfigDefinition Definition;

		public FixedString128Bytes ConfigFileRelativePath;

		public FixedString512Bytes SerializedValue;

		public bool SyncEnabled;

		public (string ConfigFileRelativePath, SyncedConfigDefinition Definition) SyncedEntryIdentifier => (((FixedString128Bytes)(ref ConfigFileRelativePath)).Value, Definition);

		public SyncedEntryDelta(FixedString128Bytes configFileRelativePath, SyncedConfigDefinition definition, FixedString512Bytes serializedValue, bool syncEnabled)
		{
			//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_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)
			ConfigFileRelativePath = configFileRelativePath;
			Definition = definition;
			SerializedValue = serializedValue;
			SyncEnabled = syncEnabled;
		}

		public unsafe void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_0099: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: 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_00c5: 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_0019: Unknown result type (might be due to invalid IL or missing references)
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			if (serializer.IsReader)
			{
				((BufferSerializer<SyncedConfigDefinition>*)(&serializer))->SerializeValue<SyncedConfigDefinition>(ref Definition, default(ForNetworkSerializable));
				FastBufferReader fastBufferReader = serializer.GetFastBufferReader();
				((FastBufferReader)(ref fastBufferReader)).ReadValueSafe<FixedString128Bytes>(ref ConfigFileRelativePath, default(ForFixedStrings));
				((FastBufferReader)(ref fastBufferReader)).ReadValueSafe<FixedString512Bytes>(ref SerializedValue, default(ForFixedStrings));
				((FastBufferReader)(ref fastBufferReader)).ReadValueSafe<bool>(ref SyncEnabled, default(ForPrimitives));
			}
			else
			{
				((BufferSerializer<SyncedConfigDefinition>*)(&serializer))->SerializeValue<SyncedConfigDefinition>(ref Definition, default(ForNetworkSerializable));
				FastBufferWriter fastBufferWriter = serializer.GetFastBufferWriter();
				((FastBufferWriter)(ref fastBufferWriter)).WriteValueSafe<FixedString128Bytes>(ref ConfigFileRelativePath, default(ForFixedStrings));
				((FastBufferWriter)(ref fastBufferWriter)).WriteValueSafe<FixedString512Bytes>(ref SerializedValue, default(ForFixedStrings));
				((FastBufferWriter)(ref fastBufferWriter)).WriteValue<bool>(ref SyncEnabled, default(ForPrimitives));
			}
		}

		public bool Equals(SyncedEntryDelta other)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			if (!Definition.Equals(other.Definition))
			{
				return false;
			}
			if (!((FixedString128Bytes)(ref ConfigFileRelativePath)).Equals(other.ConfigFileRelativePath))
			{
				return false;
			}
			if (!((FixedString512Bytes)(ref SerializedValue)).Equals(other.SerializedValue))
			{
				return false;
			}
			if (!SyncEnabled.Equals(other.SyncEnabled))
			{
				return false;
			}
			return true;
		}

		public override bool Equals(object? obj)
		{
			if (obj is SyncedEntryDelta other)
			{
				return Equals(other);
			}
			return false;
		}

		public override int GetHashCode()
		{
			//IL_0007: 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 HashCode.Combine<SyncedConfigDefinition, FixedString128Bytes, FixedString512Bytes, bool>(Definition, ConfigFileRelativePath, SerializedValue, SyncEnabled);
		}
	}
	[AttributeUsage(AttributeTargets.Field)]
	public class SyncedEntryFieldAttribute : Attribute
	{
	}
	public class SyncedInstance<T> : ByteSerializer<T> where T : class
	{
		[Obsolete]
		public static T? Instance { get; internal set; }

		[Obsolete("This will never actually hold the local configured values. Use SyncedEntry.LocalValue instead.")]
		public static T? Default { get; internal set; }
	}
	[PublicAPI]
	public sealed class SyncedSettingChangedEventArgs<T> : EventArgs
	{
		public required SyncedEntry<T> ChangedEntry { get; init; }

		public required T OldValue { get; init; }

		public required T NewValue { get; init; }
	}
}
namespace CSync.Extensions
{
	internal static class ConfigDefinitionExtensions
	{
		public static SyncedConfigDefinition ToSynced(this ConfigDefinition definition)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			return new SyncedConfigDefinition(FixedString128Bytes.op_Implicit(definition.Section), FixedString128Bytes.op_Implicit(definition.Key));
		}
	}
	internal static class ConfigEntryExtensions
	{
		public static (string ConfigFileRelativePath, SyncedConfigDefinition Definition) ToSyncedEntryIdentifier(this ConfigEntryBase entry)
		{
			return (entry.ConfigFile.GetConfigFileRelativePath(), entry.Definition.ToSynced());
		}
	}
	internal static class ConfigFileExtensions
	{
		public static string GetConfigFileRelativePath(this ConfigFile configFile)
		{
			return Path.GetRelativePath(Paths.BepInExRootPath, configFile.ConfigFilePath);
		}
	}
	public static class SyncedBindingExtensions
	{
		public static SyncedEntry<T> BindSyncedEntry<T>(this ConfigFile configFile, string section, string key, T defaultVal, string description)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_001b: Expected O, but got Unknown
			//IL_001b: Expected O, but got Unknown
			return configFile.BindSyncedEntry(new ConfigDefinition(section, key), defaultVal, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}

		public static SyncedEntry<T> BindSyncedEntry<T>(this ConfigFile configFile, string section, string key, T defaultValue, ConfigDescription? desc = null)
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			return configFile.BindSyncedEntry(new ConfigDefinition(section, key), defaultValue, desc);
		}

		public static SyncedEntry<T> BindSyncedEntry<T>(this ConfigFile configFile, ConfigDefinition definition, T defaultValue, string description)
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Expected O, but got Unknown
			return configFile.BindSyncedEntry(definition, defaultValue, new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()));
		}

		public static SyncedEntry<T> BindSyncedEntry<T>(this ConfigFile configFile, ConfigDefinition definition, T defaultValue, ConfigDescription? description = null)
		{
			ConfigManager.AddToFileCache(configFile);
			return configFile.Bind<T>(definition, defaultValue, description).ToSyncedEntry<T>();
		}

		public static SyncedEntry<T> ToSyncedEntry<T>(this ConfigEntry<T> entry)
		{
			return new SyncedEntry<T>(entry);
		}
	}
}
namespace System.Diagnostics.CodeAnalysis
{
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ExperimentalAttribute : Attribute
	{
		public string DiagnosticId { get; }

		public string? UrlFormat { get; set; }

		public ExperimentalAttribute(string diagnosticId)
		{
			DiagnosticId = diagnosticId;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullAttribute : Attribute
	{
		public string[] Members { get; }

		public MemberNotNullAttribute(string member)
		{
			Members = new string[1] { member };
		}

		public MemberNotNullAttribute(params string[] members)
		{
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, Inherited = false, AllowMultiple = true)]
	[ExcludeFromCodeCoverage]
	internal sealed class MemberNotNullWhenAttribute : Attribute
	{
		public bool ReturnValue { get; }

		public string[] Members { get; }

		public MemberNotNullWhenAttribute(bool returnValue, string member)
		{
			ReturnValue = returnValue;
			Members = new string[1] { member };
		}

		public MemberNotNullWhenAttribute(bool returnValue, params string[] members)
		{
			ReturnValue = returnValue;
			Members = members;
		}
	}
	[AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SetsRequiredMembersAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class StringSyntaxAttribute : Attribute
	{
		public const string CompositeFormat = "CompositeFormat";

		public const string DateOnlyFormat = "DateOnlyFormat";

		public const string DateTimeFormat = "DateTimeFormat";

		public const string EnumFormat = "EnumFormat";

		public const string GuidFormat = "GuidFormat";

		public const string Json = "Json";

		public const string NumericFormat = "NumericFormat";

		public const string Regex = "Regex";

		public const string TimeOnlyFormat = "TimeOnlyFormat";

		public const string TimeSpanFormat = "TimeSpanFormat";

		public const string Uri = "Uri";

		public const string Xml = "Xml";

		public string Syntax { get; }

		public object?[] Arguments { get; }

		public StringSyntaxAttribute(string syntax)
		{
			Syntax = syntax;
			Arguments = new object[0];
		}

		public StringSyntaxAttribute(string syntax, params object?[] arguments)
		{
			Syntax = syntax;
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class UnscopedRefAttribute : Attribute
	{
	}
}
namespace System.Runtime.Versioning
{
	[AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresPreviewFeaturesAttribute : Attribute
	{
		public string? Message { get; }

		public string? Url { get; set; }

		public RequiresPreviewFeaturesAttribute()
		{
		}

		public RequiresPreviewFeaturesAttribute(string? message)
		{
			Message = message;
		}
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CallerArgumentExpressionAttribute : Attribute
	{
		public string ParameterName { get; }

		public CallerArgumentExpressionAttribute(string parameterName)
		{
			ParameterName = parameterName;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CollectionBuilderAttribute : Attribute
	{
		public Type BuilderType { get; }

		public string MethodName { get; }

		public CollectionBuilderAttribute(Type builderType, string methodName)
		{
			BuilderType = builderType;
			MethodName = methodName;
		}
	}
	[AttributeUsage(AttributeTargets.All, AllowMultiple = true, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class CompilerFeatureRequiredAttribute : Attribute
	{
		public const string RefStructs = "RefStructs";

		public const string RequiredMembers = "RequiredMembers";

		public string FeatureName { get; }

		public bool IsOptional { get; set; }

		public CompilerFeatureRequiredAttribute(string featureName)
		{
			FeatureName = featureName;
		}
	}
	[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerArgumentAttribute : Attribute
	{
		public string[] Arguments { get; }

		public InterpolatedStringHandlerArgumentAttribute(string argument)
		{
			Arguments = new string[1] { argument };
		}

		public InterpolatedStringHandlerArgumentAttribute(params string[] arguments)
		{
			Arguments = arguments;
		}
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class InterpolatedStringHandlerAttribute : Attribute
	{
	}
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal static class IsExternalInit
	{
	}
	[AttributeUsage(AttributeTargets.Method, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class ModuleInitializerAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiredMemberAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Parameter, Inherited = false)]
	[EditorBrowsable(EditorBrowsableState.Never)]
	[ExcludeFromCodeCoverage]
	internal sealed class RequiresLocationAttribute : Attribute
	{
	}
	[AttributeUsage(AttributeTargets.Module | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Event | AttributeTargets.Interface, Inherited = false)]
	[ExcludeFromCodeCoverage]
	internal sealed class SkipLocalsInitAttribute : Attribute
	{
	}
}
namespace com.sigurd.csync.NetcodePatcher
{
	[AttributeUsage(AttributeTargets.Module)]
	internal class NetcodePatchedAssemblyAttribute : Attribute
	{
	}
}