Decompiled source of MirrorWeapons v1.0.0

MirrorWeapons.dll

Decompiled 2 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using GameData;
using Gear;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Player;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("MirrorWeapons")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+a8dd714ade3ff91767c6472ee28d4757660e0dcb")]
[assembly: AssemblyProduct("MirrorWeapons")]
[assembly: AssemblyTitle("MirrorWeapons")]
[assembly: AssemblyVersion("1.0.0.0")]
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 MirrorWeapons
{
	internal static class Configuration
	{
		public static uint Offset { get; private set; } = 0u;


		public static bool LockDuplicate { get; private set; } = true;


		public static void Init()
		{
			//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)
			ConfigFile val = new ConfigFile(Path.Combine(Paths.ConfigPath, "MirrorWeapons.cfg"), true);
			string text = "Developer Settings";
			Offset = val.Bind<uint>(text, "ID Offset", Offset, "Offset from the original ID to create copied blocks at.\nIf there is an ID conflict, it is given the next consecutive ID after the last block instead.").Value;
			LockDuplicate = val.Bind<bool>(text, "Lock Duplicate", LockDuplicate, "If a weapon is picked, its copy cannot be picked.\nDoesn't work properly for bots.").Value;
		}
	}
	[HarmonyPatch]
	internal static class CopyAndLockPatches
	{
		private static readonly Dictionary<uint, uint> _offlineCopies = new Dictionary<uint, uint>();

		private static readonly Dictionary<InventorySlot, (int pos, GearIDRange range)> _blockedGearRanges = new Dictionary<InventorySlot, (int, GearIDRange)>();

		[HarmonyPatch(typeof(GameDataInit), "Initialize")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_Initialize()
		{
			//IL_0071: 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_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Invalid comparison between Unknown and I4
			//IL_0088: 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_0080: Invalid comparison between Unknown and I4
			//IL_008d: 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)
			_blockedGearRanges.Clear();
			_offlineCopies.Clear();
			Dictionary<uint, uint> dictionary = new Dictionary<uint, uint>();
			Dictionary<uint, uint> dictionary2 = new Dictionary<uint, uint>();
			foreach (PlayerOfflineGearDataBlock allBlock in GameDataBlockBase<PlayerOfflineGearDataBlock>.GetAllBlocks())
			{
				if (!TryGetComp<ItemDataBlock>(allBlock.GearJSON, (eGearComponent)3, out ItemDataBlock block) || !TryGetComp<GearCategoryDataBlock>(allBlock.GearJSON, (eGearComponent)2, out GearCategoryDataBlock block2))
				{
					continue;
				}
				uint persistentID = ((GameDataBlockBase<ItemDataBlock>)(object)block).persistentID;
				uint persistentID2 = ((GameDataBlockBase<GearCategoryDataBlock>)(object)block2).persistentID;
				InventorySlot inventorySlot = block.inventorySlot;
				InventorySlot inventorySlot2;
				if ((int)inventorySlot != 1)
				{
					if ((int)inventorySlot != 2)
					{
						continue;
					}
					inventorySlot2 = (InventorySlot)1;
				}
				else
				{
					inventorySlot2 = (InventorySlot)2;
				}
				if (!dictionary.TryGetValue(persistentID, out var value))
				{
					ItemDataBlock val = GameDataBlockBase<ItemDataBlock>.CreateNewCopy(block);
					val.inventorySlot = inventorySlot2;
					TrySetIDOffset<ItemDataBlock>(val, persistentID);
					dictionary.Add(persistentID, value = ((GameDataBlockBase<ItemDataBlock>)(object)val).persistentID);
				}
				if (!dictionary2.TryGetValue(persistentID2, out var value2))
				{
					GearCategoryDataBlock val2 = GameDataBlockBase<GearCategoryDataBlock>.CreateNewCopy(block2);
					val2.BaseItem = value;
					TrySetIDOffset<GearCategoryDataBlock>(val2, persistentID2);
					dictionary2.Add(persistentID2, value2 = ((GameDataBlockBase<GearCategoryDataBlock>)(object)val2).persistentID);
				}
				PlayerOfflineGearDataBlock val3 = GameDataBlockBase<PlayerOfflineGearDataBlock>.CreateNewCopy(allBlock);
				string compString = GetCompString((eGearComponent)3);
				string compString2 = GetCompString((eGearComponent)2);
				val3.GearJSON = val3.GearJSON.Replace(compString + persistentID, compString + value);
				val3.GearJSON = val3.GearJSON.Replace(compString2 + persistentID2, compString2 + value2);
				TrySetIDOffset<PlayerOfflineGearDataBlock>(val3, ((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)allBlock).persistentID);
				_offlineCopies.Add(((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)allBlock).persistentID, ((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)val3).persistentID);
				_offlineCopies.Add(((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)val3).persistentID, ((GameDataBlockBase<PlayerOfflineGearDataBlock>)(object)allBlock).persistentID);
			}
		}

		private static bool TryGetComp<T>(string gearJSON, eGearComponent comp, out T block) where T : GameDataBlockBase<T>
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			string compString = GetCompString(comp);
			int num = gearJSON.IndexOf(compString) + compString.Length;
			if (num >= 0)
			{
				int num2 = gearJSON.IndexOf('}', num);
				int num3 = num;
				if (uint.TryParse(gearJSON.Substring(num3, num2 - num3), out var result) && GameDataBlockBase<T>.HasBlock(result))
				{
					block = GameDataBlockBase<T>.GetBlock(result);
					return true;
				}
			}
			block = default(T);
			return false;
		}

		private static string GetCompString(eGearComponent comp)
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected I4, but got Unknown
			return $"\"c\":{(int)comp},\"v\":";
		}

		private static void TrySetIDOffset<T>(T block, uint origID) where T : GameDataBlockBase<T>
		{
			if (Configuration.Offset != 0)
			{
				uint num = origID + Configuration.Offset;
				if (GameDataBlockBase<T>.HasBlock(num))
				{
					DinoLogger.Warning($"Failed to give ID {num} in {GameDataBlockBase<T>.m_fileNameNoExt}! Using {((GameDataBlockBase<T>)block).persistentID} instead.");
				}
				else
				{
					GameDataBlockBase<T>.s_dirtyBlocks.RemoveAt(GameDataBlockBase<T>.s_dirtyBlocks.Count - 1);
					GameDataBlockBase<T>.s_dirtyBlocks.Add(num);
					GameDataBlockBase<T>.s_blockIDByName[((GameDataBlockBase<T>)block).name] = num;
					GameDataBlockBase<T>.s_blockByID.Remove(((GameDataBlockBase<T>)block).persistentID);
					GameDataBlockBase<T>.s_blockByID.Add(num, block);
					((GameDataBlockBase<T>)block).persistentID = num;
				}
			}
		}

		[HarmonyPatch(typeof(PlayerBackpackManager), "EquipLocalGear")]
		[HarmonyWrapSafe]
		[HarmonyPostfix]
		private static void Post_Equip(GearIDRange gearSetup)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: 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_0024: Invalid comparison between Unknown and I4
			//IL_0030: 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_0029: Invalid comparison between Unknown and I4
			//IL_002c: 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_00b3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b9: Expected I4, but got Unknown
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Expected I4, but got Unknown
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			if (!Configuration.LockDuplicate)
			{
				return;
			}
			ItemDataBlock block = GameDataBlockBase<ItemDataBlock>.GetBlock(gearSetup.GetCompID((eGearComponent)3));
			if (block == null)
			{
				return;
			}
			InventorySlot inventorySlot = block.inventorySlot;
			InventorySlot val;
			if ((int)inventorySlot != 1)
			{
				if ((int)inventorySlot != 2)
				{
					return;
				}
				val = (InventorySlot)1;
			}
			else
			{
				val = (InventorySlot)2;
			}
			if (!TryGetOfflineID(gearSetup, out var offlineID))
			{
				return;
			}
			uint value;
			bool flag = _offlineCopies.TryGetValue(offlineID, out value);
			if (_blockedGearRanges.TryGetValue(val, out (int, GearIDRange) value2))
			{
				if (flag && TryGetOfflineID(value2.Item2, out var offlineID2) && offlineID2 == value)
				{
					return;
				}
				((Il2CppArrayBase<List<GearIDRange>>)(object)GearManager.Current.m_gearPerSlot)[(int)val].Insert(value2.Item1, value2.Item2);
				_blockedGearRanges.Remove(val);
			}
			if (!flag)
			{
				return;
			}
			List<GearIDRange> val2 = ((Il2CppArrayBase<List<GearIDRange>>)(object)GearManager.Current.m_gearPerSlot)[(int)val];
			for (int i = 0; i < val2.Count; i++)
			{
				GearIDRange val3 = val2[i];
				if (TryGetOfflineID(val3, out var offlineID3) && offlineID3 == value)
				{
					_blockedGearRanges[val] = (i, val3);
					val2.RemoveAt(i);
					break;
				}
			}
		}

		private static bool TryGetOfflineID(GearIDRange range, out uint offlineID)
		{
			string playfabItemInstanceId = range.PlayfabItemInstanceId;
			int length = "OfflineGear_ID_".Length;
			if (!uint.TryParse(playfabItemInstanceId.Substring(length, playfabItemInstanceId.Length - length), out offlineID))
			{
				return false;
			}
			return true;
		}
	}
	internal static class DinoLogger
	{
		private static ManualLogSource logger = Logger.CreateLogSource("MirrorWeapons");

		public static void Log(string format, params object[] args)
		{
			Log(string.Format(format, args));
		}

		public static void Log(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)8, (object)str);
			}
		}

		public static void Warning(string format, params object[] args)
		{
			Warning(string.Format(format, args));
		}

		public static void Warning(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)4, (object)str);
			}
		}

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

		public static void Error(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)2, (object)str);
			}
		}

		public static void Debug(string format, params object[] args)
		{
			Debug(string.Format(format, args));
		}

		public static void Debug(string str)
		{
			if (logger != null)
			{
				logger.Log((LogLevel)32, (object)str);
			}
		}
	}
	[BepInPlugin("Dinorush.MirrorWeapons", "MirrorWeapons", "1.0.0")]
	internal sealed class EntryPoint : BasePlugin
	{
		public const string MODNAME = "MirrorWeapons";

		public override void Load()
		{
			//IL_000a: Unknown result type (might be due to invalid IL or missing references)
			Configuration.Init();
			new Harmony("MirrorWeapons").PatchAll();
			((BasePlugin)this).Log.LogMessage((object)"Loaded MirrorWeapons");
		}
	}
}