Decompiled source of SyncDrones v1.1.1

plugins/DroneItemShare.dll

Decompiled a day ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using RoR2;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("DroneItemShare")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("DroneItemShare")]
[assembly: AssemblyCopyright("Copyright ©  2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("54b48e6f-c9e3-4e99-83e3-6de5420f7bf9")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace SyncDrones;

[BepInPlugin("nikatname.ror2.syncdrones", "SyncDrones", "1.1.0")]
public class SyncDronesPlugin : BaseUnityPlugin
{
	private class SyncedMarker : MonoBehaviour
	{
	}

	private class MirrorLink : MonoBehaviour
	{
		private Inventory ownerInv;

		private Inventory droneInv;

		private Action mirror;

		public void Init(Inventory o, Inventory d, Action m)
		{
			ownerInv = o;
			droneInv = d;
			mirror = m;
			if ((Object)(object)ownerInv != (Object)null)
			{
				ownerInv.onInventoryChanged += OnOwnerChanged;
			}
		}

		private void OnOwnerChanged()
		{
			if (IsServer() && !((Object)(object)ownerInv == (Object)null) && !((Object)(object)droneInv == (Object)null))
			{
				mirror?.Invoke();
			}
		}

		private void OnDestroy()
		{
			if ((Object)(object)ownerInv != (Object)null)
			{
				ownerInv.onInventoryChanged -= OnOwnerChanged;
			}
		}
	}

	[CompilerGenerated]
	private sealed class <>c__DisplayClass7_0
	{
		public Inventory ownerInv;

		public Inventory droneInv;

		internal void <DeferredLink>b__0()
		{
			MirrorOnce(ownerInv, droneInv);
		}
	}

	[CompilerGenerated]
	private sealed class <DeferredLink>d__7 : IEnumerator<object>, IDisposable, IEnumerator
	{
		private int <>1__state;

		private object <>2__current;

		public CharacterBody body;

		private <>c__DisplayClass7_0 <>8__1;

		object IEnumerator<object>.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		object IEnumerator.Current
		{
			[DebuggerHidden]
			get
			{
				return <>2__current;
			}
		}

		[DebuggerHidden]
		public <DeferredLink>d__7(int <>1__state)
		{
			this.<>1__state = <>1__state;
		}

		[DebuggerHidden]
		void IDisposable.Dispose()
		{
			<>8__1 = null;
			<>1__state = -2;
		}

		private bool MoveNext()
		{
			switch (<>1__state)
			{
			default:
				return false;
			case 0:
				<>1__state = -1;
				<>8__1 = new <>c__DisplayClass7_0();
				<>2__current = null;
				<>1__state = 1;
				return true;
			case 1:
			{
				<>1__state = -1;
				CharacterMaster master = body.master;
				MinionOwnership obj = ((master != null) ? ((Component)master).GetComponent<MinionOwnership>() : null);
				CharacterMaster val = ((obj != null) ? obj.ownerMaster : null);
				<>8__1.ownerInv = ((val != null) ? val.inventory : null);
				<>8__1.droneInv = body.inventory;
				if ((Object)(object)<>8__1.ownerInv == (Object)null || (Object)(object)<>8__1.droneInv == (Object)null)
				{
					return false;
				}
				MirrorOnce(<>8__1.ownerInv, <>8__1.droneInv);
				((Component)body).gameObject.AddComponent<SyncedMarker>();
				((Component)body).gameObject.AddComponent<MirrorLink>().Init(<>8__1.ownerInv, <>8__1.droneInv, delegate
				{
					MirrorOnce(<>8__1.ownerInv, <>8__1.droneInv);
				});
				PlayerCharacterMasterController component = ((Component)val).GetComponent<PlayerCharacterMasterController>();
				string text = ((component == null) ? null : component.networkUser?.userName) ?? "Player";
				Chat.AddMessage("<color=#92E66E>[SyncDrones]</color> Linked <b>" + body.GetDisplayName() + "</b> to " + text + ".");
				return false;
			}
			}
		}

		bool IEnumerator.MoveNext()
		{
			//ILSpy generated this explicit interface implementation from .override directive in MoveNext
			return this.MoveNext();
		}

		[DebuggerHidden]
		void IEnumerator.Reset()
		{
			throw new NotSupportedException();
		}
	}

	public const string PluginGuid = "nikatname.ror2.syncdrones";

	public const string PluginName = "SyncDrones";

	public const string PluginVersion = "1.1.0";

	public static ConfigEntry<string> BlacklistConfig;

	private void Awake()
	{
		BlacklistConfig = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Blacklist", "", "Comma-separated list of in-game item names (e.g. \"Soldier's Syringe, 57 Leaf Clover, Shaped Glass\") to NOT mirror to drones.");
		CharacterBody.onBodyStartGlobal += OnBodyStartGlobal;
		((BaseUnityPlugin)this).Logger.LogInfo((object)"SyncDrones 1.1.0 loaded.");
	}

	private void OnDestroy()
	{
		CharacterBody.onBodyStartGlobal -= OnBodyStartGlobal;
	}

	private void OnBodyStartGlobal(CharacterBody body)
	{
		//IL_002c: Unknown result type (might be due to invalid IL or missing references)
		//IL_0032: Unknown result type (might be due to invalid IL or missing references)
		if (IsServer() && Object.op_Implicit((Object)(object)body) && Object.op_Implicit((Object)(object)body.master) && Object.op_Implicit((Object)(object)body.inventory) && (body.bodyFlags & 2) != 0)
		{
			MinionOwnership component = ((Component)body.master).GetComponent<MinionOwnership>();
			if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.ownerMaster) && !((Object)(object)component.ownerMaster.playerCharacterMasterController == (Object)null) && !Object.op_Implicit((Object)(object)((Component)body).GetComponent<SyncedMarker>()))
			{
				((MonoBehaviour)this).StartCoroutine(DeferredLink(body));
			}
		}
	}

	[IteratorStateMachine(typeof(<DeferredLink>d__7))]
	private IEnumerator DeferredLink(CharacterBody body)
	{
		//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
		return new <DeferredLink>d__7(0)
		{
			body = body
		};
	}

	private static void MirrorOnce(Inventory ownerInv, Inventory droneInv)
	{
		//IL_005a: 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_0062: Unknown result type (might be due to invalid IL or missing references)
		//IL_0067: Unknown result type (might be due to invalid IL or missing references)
		//IL_006f: Unknown result type (might be due to invalid IL or missing references)
		//IL_0074: 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_009a: Unknown result type (might be due to invalid IL or missing references)
		//IL_00a0: Invalid comparison between Unknown and I4
		//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
		//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
		//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
		HashSet<string> hashSet = new HashSet<string>(from x in (BlacklistConfig?.Value ?? "").Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries)
			select x.Trim(), StringComparer.OrdinalIgnoreCase);
		GenericStaticEnumerable<ItemIndex, AllItemsEnumerator> allItems = ItemCatalog.allItems;
		AllItemsEnumerator enumerator = allItems.GetEnumerator();
		try
		{
			while (((AllItemsEnumerator)(ref enumerator)).MoveNext())
			{
				ItemIndex current = ((AllItemsEnumerator)(ref enumerator)).Current;
				ItemDef itemDef = ItemCatalog.GetItemDef(current);
				if ((Object)(object)itemDef == (Object)null)
				{
					continue;
				}
				string @string = Language.GetString(itemDef.nameToken);
				if ((int)itemDef.tier == 5 || IsDeprecated(itemDef) || HasTagName(itemDef, "AIBlacklist") || hashSet.Contains(@string))
				{
					continue;
				}
				int itemCount = ownerInv.GetItemCount(current);
				int itemCount2 = droneInv.GetItemCount(current);
				if (itemCount > itemCount2)
				{
					droneInv.GiveItem(current, itemCount - itemCount2);
				}
				else if (itemCount2 > itemCount)
				{
					int num = itemCount2 - itemCount;
					for (int i = 0; i < num; i++)
					{
						droneInv.RemoveItem(current, 1);
					}
				}
			}
		}
		finally
		{
			((IDisposable)(AllItemsEnumerator)(ref enumerator)).Dispose();
		}
	}

	private static bool HasTagName(ItemDef def, string tagName)
	{
		ItemTag[] tags = def.tags;
		if (tags == null)
		{
			return false;
		}
		for (int i = 0; i < tags.Length; i++)
		{
			if (((object)(ItemTag)(ref tags[i])).ToString() == tagName)
			{
				return true;
			}
		}
		return false;
	}

	private static bool IsDeprecated(ItemDef def)
	{
		try
		{
			FieldInfo field = typeof(ItemDef).GetField("deprecated", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
			if (field != null && field.FieldType == typeof(bool))
			{
				return (bool)field.GetValue(def);
			}
		}
		catch
		{
		}
		return HasTagName(def, "Deprecated");
	}

	private static bool IsServer()
	{
		PropertyInfo propertyInfo = Type.GetType("UnityEngine.Networking.NetworkServer, com.unity.multiplayer-hlapi.Runtime")?.GetProperty("active", BindingFlags.Static | BindingFlags.Public);
		if (propertyInfo != null)
		{
			try
			{
				return (bool)propertyInfo.GetValue(null, null);
			}
			catch
			{
			}
		}
		PropertyInfo propertyInfo2 = Type.GetType("RoR2.Networking.NetworkManagerSystem, RoR2")?.GetProperty("isServer", BindingFlags.Static | BindingFlags.Public);
		if (propertyInfo2 != null)
		{
			try
			{
				return (bool)propertyInfo2.GetValue(null, null);
			}
			catch
			{
			}
		}
		return true;
	}
}