Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of EasySync v0.0.2
EasySync.dll
Decompiled 2 years agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using Microsoft.CodeAnalysis; using Unity.Collections; using Unity.Netcode; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("EasySync")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("My first plugin")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("EasySync")] [assembly: AssemblyTitle("EasySync")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 EasySync { [BepInPlugin("EasySync", "EasySync", "0.0.2")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class EasySyncPlugin : BaseUnityPlugin { public const string MOD_ID = "EasySync"; public const string MOD_NAME = "EasySync"; public const string MOD_VERSION = "0.0.2"; private static readonly Harmony _harmony = new Harmony("EasySync"); public static EasySyncPlugin instance; private ManualLogSource logSource => ((BaseUnityPlugin)this).Logger; private void Awake() { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin EasySync is loaded!"); instance = this; _harmony.PatchAll(typeof(Patches)); } internal static bool ConditionLog(string message, bool condition = true, LogLevel logLevel = 16) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) if (condition) { instance.logSource.Log(logLevel, (object)message); } return condition; } } public class Patches { [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] [HarmonyPostfix] private static void PlayerControllerBConnectClientToPlayerObjectPostFix(PlayerControllerB __instance) { SyncManager.SyncAllInstances(); } [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")] private static void GameNetworkManagerStartDisconnectPostFix() { SyncManager.RevertSyncAllInstances(); } } public static class SyncManager { public readonly struct SyncedInstanceContainer { private readonly object instance; private readonly string GUID; private readonly MethodInfo initInstanceMethod; private readonly MethodInfo revertSyncMethod; private readonly MethodInfo serializeToBytesMethod; private readonly MethodInfo syncInstanceMethod; private readonly PropertyInfo instanceProperty; private readonly PropertyInfo defaultProperty; private readonly PropertyInfo intSizeProperty; private readonly PropertyInfo messageManagerProperty; private readonly PropertyInfo isClientProperty; private readonly PropertyInfo isHostProperty; private readonly FieldInfo syncedField; internal readonly bool isValid; public object Instance => instanceProperty.GetValue(null); public object Default => defaultProperty.GetValue(null); public int IntSize => (int)intSizeProperty.GetValue(null); public CustomMessagingManager MessageManager => (CustomMessagingManager)messageManagerProperty.GetValue(null); public bool IsClient => (bool)isClientProperty.GetValue(null); public bool IsHost => (bool)isHostProperty.GetValue(null); internal bool Synced { get { return (bool)syncedField.GetValue(null); } set { syncedField.SetValue(null, value); } } internal SyncedInstanceContainer(object instance, string GUID) { this.instance = instance; Type baseType = instance.GetType().BaseType; this.GUID = GUID; BindingFlags bindingAttr = BindingFlags.Static | BindingFlags.Public; int i = 0; instanceProperty = baseType.GetProperty("Instance", bindingAttr); defaultProperty = baseType.GetProperty("Default", bindingAttr); initInstanceMethod = baseType.GetMethod("InitInstance", BindingFlags.Instance | BindingFlags.Public); revertSyncMethod = baseType.GetMethod("RevertSync", bindingAttr); serializeToBytesMethod = baseType.BaseType.GetMethod("SerializeToBytes", bindingAttr); syncInstanceMethod = baseType.GetMethod("SyncInstance", bindingAttr); intSizeProperty = baseType.BaseType.GetProperty("IntSize", bindingAttr); messageManagerProperty = baseType.GetProperty("MessageManager", bindingAttr); isClientProperty = baseType.GetProperty("IsClient", bindingAttr); isHostProperty = baseType.GetProperty("IsHost", bindingAttr); syncedField = baseType.GetField("Synced", bindingAttr); ScreamIfNull(instanceProperty); ScreamIfNull(defaultProperty); ScreamIfNull(initInstanceMethod); ScreamIfNull(revertSyncMethod); ScreamIfNull(serializeToBytesMethod); ScreamIfNull(syncInstanceMethod); ScreamIfNull(intSizeProperty); ScreamIfNull(messageManagerProperty); ScreamIfNull(isClientProperty); ScreamIfNull(isHostProperty); ScreamIfNull(syncedField); isValid = instanceProperty != null && defaultProperty != null && initInstanceMethod != null && revertSyncMethod != null && intSizeProperty != null && messageManagerProperty != null && isClientProperty != null && isHostProperty != null && syncedField != null; void ScreamIfNull(object obj) { i++; EasySyncPlugin.ConditionLog($"VARIABLE AT INDEX {i} IS NULL!!!", obj == null, (LogLevel)2); } } internal void InitInstance() { initInstanceMethod.Invoke(instance, new object[1] { instance }); } public void RevertSync() { revertSyncMethod.Invoke(null, null); } private byte[] SerializeToBytes(object inst) { return (byte[])serializeToBytesMethod.Invoke(null, new object[1] { inst }); } private void SyncInstance(byte[] data) { syncInstanceMethod.Invoke(null, new object[1] { data }); } internal void BeginSync() { //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown if (IsHost) { MessageManager.RegisterNamedMessageHandler(GUID + "_OnRequestConfigSync", new HandleNamedMessageDelegate(OnRequestSync)); Synced = true; } else { Synced = false; MessageManager.RegisterNamedMessageHandler(GUID + "_OnReceiveConfigSync", new HandleNamedMessageDelegate(OnReceiveSync)); RequestSync(); } } public void RequestSync() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) if (!IsClient) { return; } FastBufferWriter stream = default(FastBufferWriter); ((FastBufferWriter)(ref stream))..ctor(IntSize, (Allocator)2, -1); try { SendMessage(stream, GUID + "_OnRequestConfigSync", 0uL); } finally { ((IDisposable)(FastBufferWriter)(ref stream)).Dispose(); } } private void OnRequestSync(ulong clientId, FastBufferReader _) { //IL_003c: 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_0055: Unknown result type (might be due to invalid IL or missing references) if (!IsHost) { return; } byte[] array = SerializeToBytes(Instance); int num = array.Length; FastBufferWriter stream = default(FastBufferWriter); ((FastBufferWriter)(ref stream))..ctor(num + IntSize, (Allocator)2, -1); try { ((FastBufferWriter)(ref stream)).WriteValueSafe<int>(ref num, default(ForPrimitives)); ((FastBufferWriter)(ref stream)).WriteBytesSafe(array, -1, 0); SendMessage(stream, GUID + "_OnReceiveConfigSync", clientId); } catch (Exception arg) { EasySyncPlugin.ConditionLog($"Error occurred syncing config with client: {clientId}\n{arg}", condition: true, (LogLevel)2); } finally { ((IDisposable)(FastBufferWriter)(ref stream)).Dispose(); } } private void OnReceiveSync(ulong _, FastBufferReader reader) { //IL_002b: 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 (!((FastBufferReader)(ref reader)).TryBeginRead(IntSize)) { EasySyncPlugin.ConditionLog("Config sync error: Could not begin reading buffer.", condition: true, (LogLevel)2); return; } int num = default(int); ((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives)); if (!((FastBufferReader)(ref reader)).TryBeginRead(num)) { EasySyncPlugin.ConditionLog("Config sync error: Host could not sync.", condition: true, (LogLevel)2); return; } byte[] data = new byte[num]; ((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0); try { SyncInstance(data); } catch (Exception arg) { EasySyncPlugin.ConditionLog($"Error syncing config instance!\n{arg}", condition: true, (LogLevel)2); } } } private static readonly Dictionary<string, SyncedInstanceContainer> instancesToSync = new Dictionary<string, SyncedInstanceContainer>(); public static SyncedInstanceContainer? RegisterForSyncing(object instance, string GUID) { if (EasySyncPlugin.ConditionLog("Cannot register a null instance for syncing!", instance == null, (LogLevel)2)) { return null; } SyncedInstanceContainer value = new SyncedInstanceContainer(instance, GUID); if (EasySyncPlugin.ConditionLog($"Could not register instance ({instance}) of type ({instance.GetType().Name}) for syncing! Does it inherit from SyncedInstance from CSync?", !value.isValid, (LogLevel)2)) { return null; } if (instancesToSync.TryGetValue(GUID, out var _)) { EasySyncPlugin.ConditionLog("An instance with GUID " + GUID + " was already registered!", condition: true, (LogLevel)4); return null; } value.InitInstance(); instancesToSync.Add(GUID, value); return value; } public static void UnregisterFromSyncing(string GUID) { if (instancesToSync.ContainsKey(GUID)) { instancesToSync.Remove(GUID); } } internal static void SyncAllInstances() { foreach (SyncedInstanceContainer value in instancesToSync.Values) { value.BeginSync(); } } internal static void RevertSyncAllInstances() { foreach (SyncedInstanceContainer value in instancesToSync.Values) { value.RevertSync(); } } private static void SendMessage(FastBufferWriter stream, string label, ulong clientId = 0uL) { //IL_001b: 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_0029: Unknown result type (might be due to invalid IL or missing references) NetworkDelivery val = (NetworkDelivery)((((FastBufferWriter)(ref stream)).Capacity > 1300) ? 4 : 2); NetworkManager.Singleton.CustomMessagingManager.SendNamedMessage(label, clientId, stream, val); } } public static class PluginInfo { public const string PLUGIN_GUID = "EasySync"; public const string PLUGIN_NAME = "EasySync"; public const string PLUGIN_VERSION = "1.0.0"; } }