Decompiled source of Artifact Of Sharing v1.0.1

ArtifactOfSharing.dll

Decompiled a year ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
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 ArtifactOfSharing.Artifact;
using ArtifactOfSharing.Utils;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using R2API;
using R2API.ScriptableObjects;
using R2API.Utils;
using RiskOfOptions;
using RiskOfOptions.OptionConfigs;
using RiskOfOptions.Options;
using RoR2;
using RoR2.Achievements.Artifacts;
using RoR2.ContentManagement;
using RoR2.Networking;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")]
[assembly: AssemblyCompany("ArtifactOfSharing")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ArtifactOfSharing")]
[assembly: AssemblyTitle("ArtifactOfSharing")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace ArtifactOfSharing
{
	public class SetInventoryMessage : ArtifactMessageBase
	{
		private Inventory inventory;

		private Dictionary<ItemDef, uint> itemCounts;

		private Dictionary<uint, EquipmentIndex> equipments;

		public SetInventoryMessage()
		{
		}

		public SetInventoryMessage(Inventory inventory, Inventory invToSet)
		{
			this.inventory = inventory;
			itemCounts = invToSet.FilterCountNotZero(ContentManager.itemDefs);
			equipments = EquipmentData(invToSet);
		}

		public static Dictionary<uint, EquipmentIndex> EquipmentData(Inventory invToSet)
		{
			//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)
			Dictionary<uint, EquipmentIndex> dictionary = new Dictionary<uint, EquipmentIndex>();
			for (uint num = 0u; num < invToSet.GetEquipmentSlotCount(); num++)
			{
				dictionary.Add(num, invToSet.GetEquipment(num).equipmentIndex);
			}
			return dictionary;
		}

		public SetInventoryMessage(Inventory inventory, Dictionary<ItemDef, int> itemCounts, Dictionary<uint, EquipmentIndex> equipments)
		{
			this.inventory = inventory;
			this.itemCounts = itemCounts.ToDictionary((KeyValuePair<ItemDef, int> x) => x.Key, (KeyValuePair<ItemDef, int> x) => (uint)x.Value);
			this.equipments = equipments.ToDictionary((KeyValuePair<uint, EquipmentIndex> x) => x.Key, (KeyValuePair<uint, EquipmentIndex> x) => x.Value);
		}

		public override void Serialize(NetworkWriter writer)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			((MessageBase)this).Serialize(writer);
			writer.Write(((NetworkBehaviour)inventory).netId);
			writer.Write(itemCounts);
			writer.Write(equipments);
		}

		public override void Deserialize(NetworkReader reader)
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			((MessageBase)this).Deserialize(reader);
			GameObject obj = Util.FindNetworkObject(reader.ReadNetworkId());
			inventory = ((obj != null) ? obj.GetComponent<Inventory>() : null);
			itemCounts = reader.ReadItemAmounts();
			equipments = reader.ReadEquipmentIndices();
		}

		public override void Handle()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			base.Handle();
			ItemDef[] itemDefs = ContentManager.itemDefs;
			foreach (ItemDef val in itemDefs)
			{
				int itemCount = inventory.GetItemCount(val);
				int num = (int)(itemCounts.ContainsKey(val) ? itemCounts[val] : 0);
				if (itemCount > num)
				{
					inventory.RemoveItem(val, itemCount - num);
				}
				else if (num > itemCount)
				{
					inventory.GiveItem(val, num - itemCount);
				}
			}
			foreach (KeyValuePair<uint, EquipmentIndex> equipment in equipments)
			{
				inventory.SetEquipmentIndexForSlot(equipment.Value, equipment.Key);
			}
		}
	}
	[RegisterAchievement("ObtainArtifactSharing", "Artifacts.Sharing", null, null)]
	public class ArtifactOfSharingAchievement : BaseObtainArtifactAchievement
	{
		public override ArtifactDef artifactDef => ArtifactBase<ArtifactOfSharing.Artifact.ArtifactOfSharing>.instance.ArtifactDef;
	}
	[BepInPlugin("com.amrothabet.ArtifactOfSharing", "Artifact Of Sharing", "0.0.1")]
	[BepInDependency("com.bepis.r2api", "4.4.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[R2APISubmoduleDependency(new string[] { "ArtifactCodeAPI", "LanguageAPI" })]
	public class Main : BaseUnityPlugin
	{
		public const string ModGuid = "com.amrothabet.ArtifactOfSharing";

		public const string ModName = "Artifact Of Sharing";

		public const string ModVer = "0.0.1";

		public static AssetBundle MainAssets;

		public List<ArtifactBase> Artifacts = new List<ArtifactBase>();

		public static ManualLogSource ModLogger;

		private void Awake()
		{
			ModLogger = ((BaseUnityPlugin)this).Logger;
			ModLogger.LogInfo((object)"ARTIFACT MAIN");
			LanguageAPI.Add("ACHIEVEMENT_OBTAINARTIFACTSHARING_NAME", "Trial of Sharing");
			LanguageAPI.Add("ACHIEVEMENT_OBTAINARTIFACTSHARING_DESCRIPTION", "Complete the Trial of Sharing.");
			using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ArtifactOfSharing.artifactofsharingbundle"))
			{
				MainAssets = AssetBundle.LoadFromStream(stream);
			}
			ModLogger.LogInfo((object)"LOADED ASSETS");
			ModSettingsManager.SetModDescription("Adds Artifact of Sharing which swaps players' inventories (items & equipment) every stage");
			ModSettingsManager.SetModIcon(MainAssets.LoadAsset<Sprite>("aosenabled.png"));
			foreach (Type item in from type in Assembly.GetExecutingAssembly().GetTypes()
				where !type.IsAbstract && type.IsSubclassOf(typeof(ArtifactBase))
				select type)
			{
				ArtifactBase artifactBase = (ArtifactBase)Activator.CreateInstance(item);
				if (ValidateArtifact(artifactBase, Artifacts))
				{
					artifactBase.Init(((BaseUnityPlugin)this).Config);
					AddUnlockable(artifactBase.ArtifactDef, artifactBase.ArtifactUnlockableName);
				}
			}
			ModLogger.LogInfo((object)"SETUP ARTIFACT");
		}

		public static void AddUnlockable(ArtifactDef def, string name)
		{
			//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_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Expected O, but got Unknown
			Sprite achievementIcon = MainAssets.LoadAsset<Sprite>("aosenabled.png");
			UnlockableDef val = ScriptableObject.CreateInstance<UnlockableDef>();
			val.cachedName = "Artifacts." + name;
			val.nameToken = def.nameToken;
			val.achievementIcon = achievementIcon;
			ContentAddition.AddUnlockableDef(val);
			def.unlockableDef = val;
			PickupDef pickupDef = PickupCatalog.GetPickupDef(PickupCatalog.FindPickupIndex(def.artifactIndex));
			if (pickupDef != null)
			{
				pickupDef.unlockableDef = val;
			}
			RuleDef val2 = RuleCatalog.FindRuleDef("Artifacts." + def.cachedName);
			if (val2 == null)
			{
				val2 = new RuleDef("Artifacts." + def.cachedName, def.descriptionToken);
				val2.AddChoice("On", (object)null, false);
				val2.FindChoice("On").requiredUnlockable = val;
				RuleCatalog.AddRule(val2);
			}
			else
			{
				val2.FindChoice("On").requiredUnlockable = val;
			}
		}

		public bool ValidateArtifact(ArtifactBase artifact, List<ArtifactBase> artifactList)
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Expected O, but got Unknown
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Expected O, but got Unknown
			ModLogger.LogInfo((object)("ValidateArtifact " + artifact.ArtifactName));
			ConfigEntry<bool> obj = ((BaseUnityPlugin)this).Config.Bind<bool>("Artifact: " + artifact.ArtifactName, "Enable Artifact?", true, "Should this artifact appear for selection?");
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(obj));
			ModSettingsManager.AddOption((BaseOption)new GenericButtonOption("Force Enable/Disable", "Artifact: " + artifact.ArtifactName, "Enable/Disable the artifact without needing to unlock it by code.", "Toggle", new UnityAction(ToggleUnlock)));
			if (obj.Value)
			{
				artifactList.Add(artifact);
			}
			return obj.Value;
		}

		public UserProfile GetUserProfile()
		{
			LocalUser? obj = ((IEnumerable<LocalUser>)LocalUserManager.readOnlyLocalUsersList).FirstOrDefault((Func<LocalUser, bool>)((LocalUser v) => v != null));
			if (obj == null)
			{
				return null;
			}
			return obj.userProfile;
		}

		private void ToggleUnlock()
		{
			//IL_0069: 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_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_0090: Unknown result type (might be due to invalid IL or missing references)
			UserProfile userProfile = GetUserProfile();
			UnlockableDef unlockableDef = ArtifactBase<ArtifactOfSharing.Artifact.ArtifactOfSharing>.instance.ArtifactDef.unlockableDef;
			string achievementName = "ACHIEVEMENT_OBTAINARTIFACTSHARING_NAME";
			AchievementDef val = AchievementManager.achievementDefs.Where((AchievementDef x) => x.nameToken.Equals(achievementName)).FirstOrDefault();
			bool flag = val != null && userProfile.HasAchievement(val.identifier);
			bool num = userProfile.HasUnlockable(unlockableDef);
			PickupIndex val2 = PickupCatalog.FindPickupIndex(ArtifactBase<ArtifactOfSharing.Artifact.ArtifactOfSharing>.instance.ArtifactDef.artifactIndex);
			if (!num)
			{
				if (!flag)
				{
					userProfile.AddAchievement(val.identifier, true);
				}
				userProfile.GrantUnlockable(unlockableDef);
				userProfile.SetPickupDiscovered(val2, true);
				userProfile.RequestEventualSave();
			}
			else
			{
				if (flag)
				{
					userProfile.RevokeAchievement(val.identifier);
				}
				userProfile.RevokeUnlockable(unlockableDef);
				userProfile.SetPickupDiscovered(val2, false);
				userProfile.RequestEventualSave();
			}
		}
	}
}
namespace ArtifactOfSharing.Utils
{
	public static class Extensions
	{
		public static void Write(this NetworkWriter writer, Dictionary<ItemDef, uint> itemCounts)
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Expected I4, but got Unknown
			writer.WritePackedUInt32((uint)itemCounts.Count);
			foreach (KeyValuePair<ItemDef, uint> itemCount in itemCounts)
			{
				writer.WritePackedUInt32((uint)(int)itemCount.Key.itemIndex);
				writer.WritePackedUInt32(itemCount.Value);
			}
		}

		public static void Write(this NetworkWriter writer, Dictionary<uint, EquipmentIndex> equipments)
		{
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Expected I4, but got Unknown
			writer.WritePackedUInt32((uint)equipments.Count);
			foreach (KeyValuePair<uint, EquipmentIndex> equipment in equipments)
			{
				writer.WritePackedUInt32(equipment.Key);
				writer.WritePackedUInt32((uint)(int)equipment.Value);
			}
		}

		public static Dictionary<ItemDef, uint> ReadItemAmounts(this NetworkReader reader)
		{
			Dictionary<ItemDef, uint> dictionary = new Dictionary<ItemDef, uint>();
			uint num = reader.ReadPackedUInt32();
			for (int i = 0; i < num; i++)
			{
				ItemDef itemDef = ItemCatalog.GetItemDef((ItemIndex)reader.ReadPackedUInt32());
				dictionary.Add(itemDef, reader.ReadPackedUInt32());
			}
			return dictionary;
		}

		public static Dictionary<uint, EquipmentIndex> ReadEquipmentIndices(this NetworkReader reader)
		{
			Dictionary<uint, EquipmentIndex> dictionary = new Dictionary<uint, EquipmentIndex>();
			uint num = reader.ReadPackedUInt32();
			for (int i = 0; i < num; i++)
			{
				dictionary.Add(reader.ReadPackedUInt32(), (EquipmentIndex)reader.ReadPackedUInt32());
			}
			return dictionary;
		}

		public static Dictionary<ItemDef, uint> FilterCountNotZero(this Inventory invToSet, ItemDef[] defs)
		{
			Dictionary<ItemDef, uint> dictionary = new Dictionary<ItemDef, uint>();
			foreach (ItemDef val in defs)
			{
				int itemCount = invToSet.GetItemCount(val);
				if (itemCount > 0)
				{
					dictionary.Add(val, (uint)itemCount);
				}
			}
			return dictionary;
		}

		public static T GetField<T>(string fieldName, BindingFlags bindingFlags)
		{
			try
			{
				return (T)(typeof(ServerAuthManager).GetField("fieldName", bindingFlags)?.GetValue(null));
			}
			catch (Exception ex)
			{
				Debug.LogException(ex);
			}
			return default(T);
		}
	}
	public static class NetworkManager
	{
		public static Type[] RegisteredMessages;

		public static void Initialize()
		{
			NetworkManagerSystem.onStartServerGlobal += RegisterMessages;
			NetworkManagerSystem.onStartClientGlobal += RegisterMessages;
			RegisteredMessages = (from x in typeof(ArtifactMessageBase).Assembly.GetTypes()
				where typeof(ArtifactMessageBase).IsAssignableFrom(x) && x != typeof(ArtifactMessageBase)
				select x).ToArray();
		}

		private static void RegisterMessages()
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Expected O, but got Unknown
			NetworkServer.RegisterHandler((short)2004, new NetworkMessageDelegate(HandleMessage));
		}

		public static void RegisterMessages(NetworkClient client)
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Expected O, but got Unknown
			client.RegisterHandler((short)2004, new NetworkMessageDelegate(HandleMessage));
		}

		private static void HandleMessage(NetworkMessage netmsg)
		{
			ArtifactMessage artifactMessage = netmsg.ReadMessage<ArtifactMessage>();
			if (artifactMessage.message is BroadcastMessage broadcastMessage)
			{
				broadcastMessage.fromConnection = netmsg.conn;
			}
			artifactMessage.message.Handle();
		}

		public static void Send<T>(this NetworkConnection connection, T message) where T : ArtifactMessageBase
		{
			ArtifactMessage artifactMessage = new ArtifactMessage(message);
			connection.Send((short)2004, (MessageBase)(object)artifactMessage);
		}
	}
	public class ArtifactMessageBase : MessageBase
	{
		public virtual void Handle()
		{
		}

		public void SendToServer()
		{
			if (!NetworkServer.active)
			{
				ClientScene.readyConnection.Send(this);
			}
			else
			{
				Handle();
			}
		}

		public void SendToEveryone()
		{
			Handle();
			new BroadcastMessage(this).SendToServer();
		}

		public void SendToAuthority(NetworkIdentity identity)
		{
			if (!Util.HasEffectiveAuthority(identity) && NetworkServer.active)
			{
				identity.clientAuthorityOwner.Send(this);
			}
			else if (!NetworkServer.active)
			{
				new NewAuthMessage(identity, this).SendToServer();
			}
			else
			{
				Handle();
			}
		}

		public void SendToAuthority(NetworkUser user)
		{
			SendToAuthority(((NetworkBehaviour)user).netIdentity);
		}

		public void SendToAuthority(CharacterMaster master)
		{
			SendToAuthority(master.networkIdentity);
		}

		public void SendToAuthority(CharacterBody body)
		{
			SendToAuthority(body.networkIdentity);
		}
	}
	public class BroadcastMessage : ArtifactMessageBase
	{
		public NetworkConnection fromConnection;

		private ArtifactMessageBase message;

		public BroadcastMessage()
		{
		}

		public BroadcastMessage(ArtifactMessageBase artifactMessageBase)
		{
			message = artifactMessageBase;
		}

		public override void Handle()
		{
			base.Handle();
			foreach (NetworkConnection connection in NetworkServer.connections)
			{
				if (connection != fromConnection && connection.isConnected)
				{
					connection.Send(message);
				}
			}
			message.Handle();
		}

		public override void Deserialize(NetworkReader reader)
		{
			((MessageBase)this).Deserialize(reader);
			message = reader.ReadMessage<ArtifactMessage>().message;
		}

		public override void Serialize(NetworkWriter writer)
		{
			((MessageBase)this).Serialize(writer);
			writer.Write((MessageBase)(object)new ArtifactMessage(message));
		}
	}
	public class NewAuthMessage : ArtifactMessageBase
	{
		private ArtifactMessageBase message;

		private NetworkIdentity target;

		public NewAuthMessage()
		{
		}

		public NewAuthMessage(NetworkIdentity identity, ArtifactMessageBase artifactMessageBase)
		{
			target = identity;
			message = artifactMessageBase;
		}

		public override void Handle()
		{
			base.Handle();
			message.SendToAuthority(target);
		}

		public override void Deserialize(NetworkReader reader)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			((MessageBase)this).Deserialize(reader);
			GameObject val = Util.FindNetworkObject(reader.ReadNetworkId());
			if (Object.op_Implicit((Object)(object)val))
			{
				target = val.GetComponent<NetworkIdentity>();
			}
			message = reader.ReadMessage<ArtifactMessage>().message;
		}

		public override void Serialize(NetworkWriter writer)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			((MessageBase)this).Serialize(writer);
			writer.Write(target.netId);
			writer.Write((MessageBase)(object)new ArtifactMessage(message));
		}
	}
	internal class ArtifactMessage : MessageBase
	{
		public ArtifactMessageBase message;

		public uint Type;

		public ArtifactMessage()
		{
		}

		public ArtifactMessage(ArtifactMessageBase artifactMessageBase)
		{
			message = artifactMessageBase;
			Type = (uint)Array.IndexOf(NetworkManager.RegisteredMessages, ((object)message).GetType());
		}

		public override void Serialize(NetworkWriter writer)
		{
			((MessageBase)this).Serialize(writer);
			writer.WritePackedUInt32(Type);
			writer.Write((MessageBase)(object)message);
		}

		public override void Deserialize(NetworkReader reader)
		{
			((MessageBase)this).Deserialize(reader);
			Type = reader.ReadPackedUInt32();
			ArtifactMessageBase artifactMessageBase = (ArtifactMessageBase)Activator.CreateInstance(NetworkManager.RegisteredMessages[Type]);
			((MessageBase)artifactMessageBase).Deserialize(reader);
			message = artifactMessageBase;
		}
	}
}
namespace ArtifactOfSharing.Artifact
{
	public abstract class ArtifactBase<T> : ArtifactBase where T : ArtifactBase<T>
	{
		public static T instance { get; private set; }

		public ArtifactBase()
		{
			if (instance != null)
			{
				throw new InvalidOperationException("Singleton class \"" + typeof(T).Name + "\" inheriting ArtifactBase was instantiated twice");
			}
			instance = this as T;
		}
	}
	public abstract class ArtifactBase
	{
		public ArtifactCode ArtifactCode;

		public ArtifactDef ArtifactDef;

		public abstract string ArtifactName { get; }

		public abstract string ArtifactLangTokenName { get; }

		public abstract string ArtifactUnlockableName { get; }

		public abstract string ArtifactDescription { get; }

		public abstract Sprite ArtifactEnabledIcon { get; }

		public abstract Sprite ArtifactDisabledIcon { get; }

		public bool ArtifactEnabled => RunArtifactManager.instance.IsArtifactEnabled(ArtifactDef);

		public abstract void Init(ConfigFile config);

		protected void CreateLang()
		{
			LanguageAPI.Add("ARTIFACT_" + ArtifactLangTokenName + "_NAME", ArtifactName);
			LanguageAPI.Add("ARTIFACT_" + ArtifactLangTokenName + "_DESCRIPTION", ArtifactDescription);
		}

		protected void CreateArtifact()
		{
			ArtifactDef = ScriptableObject.CreateInstance<ArtifactDef>();
			ArtifactDef.cachedName = "ARTIFACT_" + ArtifactLangTokenName;
			ArtifactDef.nameToken = "ARTIFACT_" + ArtifactLangTokenName + "_NAME";
			ArtifactDef.descriptionToken = "ARTIFACT_" + ArtifactLangTokenName + "_DESCRIPTION";
			ArtifactDef.smallIconSelectedSprite = ArtifactEnabledIcon;
			ArtifactDef.smallIconDeselectedSprite = ArtifactDisabledIcon;
			ContentAddition.AddArtifactDef(ArtifactDef);
		}

		public abstract void Hooks();
	}
	internal enum SharingType
	{
		Swap_Full_Inventories,
		Swap_Partial_Inventories
	}
	internal class ArtifactOfSharing : ArtifactBase<ArtifactOfSharing>
	{
		public static ConfigEntry<bool> ChangeSinglePlayerInventory;

		public static ConfigEntry<SharingType> MultiPlayerSharingType;

		public static ConfigEntry<int> Threshold;

		public HashSet<NetworkUser> users;

		public override string ArtifactName => "Artifact of Sharing";

		public override string ArtifactUnlockableName => "Sharing";

		public override string ArtifactLangTokenName => "ARTIFACT_OF_SHARING";

		public override string ArtifactDescription => "When enabled, swaps players' equipment and items every stage among themselves.";

		public override Sprite ArtifactEnabledIcon => Main.MainAssets.LoadAsset<Sprite>("aosenabled.png");

		public override Sprite ArtifactDisabledIcon => Main.MainAssets.LoadAsset<Sprite>("aosdisabled.png");

		public override void Init(ConfigFile config)
		{
			Main.ModLogger.LogInfo((object)"INITIALIZING ARTIFACT");
			users = new HashSet<NetworkUser>();
			CreateConfig(config);
			CreateLang();
			CreateArtifact();
			CreateCode();
			Hooks();
		}

		private void CreateCode()
		{
			//IL_0014: 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_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_003a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			ArtifactCode = ScriptableObject.CreateInstance<ArtifactCode>();
			ArtifactCode.topRow = new Vector3Int(7, 5, 7);
			ArtifactCode.middleRow = new Vector3Int(1, 7, 1);
			ArtifactCode.bottomRow = new Vector3Int(3, 5, 3);
			ArtifactCodeAPI.AddCode(ArtifactDef, ArtifactCode);
		}

		private void CreateConfig(ConfigFile config)
		{
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_0091: Expected O, but got Unknown
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Expected O, but got Unknown
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Expected O, but got Unknown
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Expected O, but got Unknown
			ChangeSinglePlayerInventory = config.Bind<bool>("Artifact: " + ArtifactName, "Customize single player items", false, "Customize player's items if only 1 player?");
			MultiPlayerSharingType = config.Bind<SharingType>("Artifact: " + ArtifactName, "Multi-player sharing method", SharingType.Swap_Full_Inventories, "Sharing method can either be set to partial inventory sharing or full inventory sharing.\n\nSwap Partial Inventories: Partial Inventory Sharing works by rolling a chance roll for every item and if the roll exceeds the threshold set, the item will be moved to the next player in the list.\n\nSwap Full Inventories: Full inventory sharing works by passing on the player's entire inventory (items + equipment) over to the next player in the list.");
			Threshold = config.Bind<int>("Artifact: " + ArtifactName, "Partial Sharing Threshold", 50, "Threshold needed to exceed in order to shift item over to the next player");
			ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ChangeSinglePlayerInventory));
			ModSettingsManager.AddOption((BaseOption)new ChoiceOption((ConfigEntryBase)(object)MultiPlayerSharingType));
			ModSettingsManager.AddOption((BaseOption)new IntSliderOption(Threshold, new IntSliderConfig
			{
				min = 1,
				max = 99,
				checkIfDisabled = new IsDisabledDelegate(IsThresholdDisabled),
				formatString = "{0}%"
			}));
		}

		private bool IsThresholdDisabled()
		{
			return MultiPlayerSharingType.Value != SharingType.Swap_Partial_Inventories;
		}

		public override void Hooks()
		{
			Stage.onServerStageBegin += onServerStageBegin;
		}

		private void onServerStageBegin(Stage stage)
		{
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Invalid comparison between Unknown and I4
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Expected O, but got Unknown
			//IL_04d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_04d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_04da: Unknown result type (might be due to invalid IL or missing references)
			//IL_04de: Unknown result type (might be due to invalid IL or missing references)
			//IL_050a: 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_0547: Unknown result type (might be due to invalid IL or missing references)
			//IL_054c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0553: Unknown result type (might be due to invalid IL or missing references)
			//IL_066c: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active || !base.ArtifactEnabled)
			{
				return;
			}
			Main.ModLogger.LogInfo((object)("SERVER STAGE BEGAN: " + ((object)stage).ToString() + " - " + ((object)stage.sceneDef).ToString()));
			SceneDef sceneDefForCurrentScene = SceneCatalog.GetSceneDefForCurrentScene();
			if (!Object.op_Implicit((Object)(object)sceneDefForCurrentScene) || sceneDefForCurrentScene.isFinalStage || (int)sceneDefForCurrentScene.sceneType != 1 || Run.instance.stageClearCount <= 0)
			{
				return;
			}
			List<NetworkUser> instancesList = NetworkUser.instancesList;
			if (instancesList.Count > 1)
			{
				List<Inventory> list = new List<Inventory>();
				foreach (NetworkUser item in instancesList)
				{
					if (Object.op_Implicit((Object)(object)item.master))
					{
						Inventory inventory = item.master.inventory;
						Inventory val = new Inventory();
						val.CopyEquipmentFrom(inventory);
						val.CopyItemsFrom(inventory);
						list.Add(val);
					}
				}
				if (MultiPlayerSharingType.Value != SharingType.Swap_Partial_Inventories)
				{
					int num = 0;
					{
						foreach (NetworkUser item2 in instancesList)
						{
							if (!Object.op_Implicit((Object)(object)item2.master))
							{
								num++;
								continue;
							}
							int index = ((num != instancesList.Count - 1) ? (num + 1) : 0);
							new SetInventoryMessage(item2.master.inventory, list[index]).SendToServer();
							num++;
						}
						return;
					}
				}
				Dictionary<NetworkUser, Dictionary<ItemDef, int>> dictionary = new Dictionary<NetworkUser, Dictionary<ItemDef, int>>();
				Dictionary<NetworkUser, Dictionary<uint, EquipmentIndex>> dictionary2 = new Dictionary<NetworkUser, Dictionary<uint, EquipmentIndex>>();
				int num2 = Math.Max(Math.Min(Threshold.Value, 99), 1);
				for (int i = 0; i < instancesList.Count; i++)
				{
					NetworkUser val2 = instancesList[i];
					if ((Object)(object)val2.master == (Object)null)
					{
						continue;
					}
					int index2 = ((i != instancesList.Count - 1) ? (i + 1) : 0);
					Dictionary<ItemDef, int> dictionary3 = new Dictionary<ItemDef, int>();
					Inventory invToSet = list[index2];
					Dictionary<ItemDef, uint> dictionary4 = invToSet.FilterCountNotZero(ContentManager.itemDefs);
					foreach (ItemDef item3 in new List<ItemDef>(dictionary4.Keys))
					{
						uint num3 = dictionary4[item3];
						int num4 = 0;
						for (int j = 0; j < num3; j++)
						{
							if (Random.Range(1, 99) > num2)
							{
								num4++;
							}
						}
						dictionary3[item3] = num4;
					}
					dictionary4 = dictionary4.Where((KeyValuePair<ItemDef, uint> keyPair) => keyPair.Value != 0).ToDictionary((KeyValuePair<ItemDef, uint> x) => x.Key, (KeyValuePair<ItemDef, uint> x) => x.Value);
					dictionary.Add(val2, dictionary3);
					dictionary2.Add(val2, SetInventoryMessage.EquipmentData(invToSet));
				}
				for (int k = 0; k < dictionary.Count; k++)
				{
					NetworkUser val3 = instancesList[k];
					if ((Object)(object)val3.master == (Object)null)
					{
						continue;
					}
					int index3 = ((k == 0) ? (instancesList.Count - 1) : (k - 1));
					Dictionary<ItemDef, int> dictionary5 = dictionary[instancesList[index3]];
					Dictionary<ItemDef, int> dictionary6 = dictionary[instancesList[k]];
					Dictionary<ItemDef, uint> dictionary7 = list[k].FilterCountNotZero(ContentManager.itemDefs);
					List<ItemDef> list2 = new List<ItemDef>(dictionary7.Keys);
					list2.AddRange(dictionary6.Keys);
					Dictionary<ItemDef, int> dictionary8 = new Dictionary<ItemDef, int>();
					foreach (ItemDef item4 in list2.Distinct())
					{
						uint num5 = (dictionary7.ContainsKey(item4) ? dictionary7[item4] : 0u);
						int num6 = (dictionary5.ContainsKey(item4) ? dictionary5[item4] : 0);
						int num7 = (dictionary6.ContainsKey(item4) ? dictionary6[item4] : 0);
						dictionary8.Add(item4, (int)num5 - num6 + num7);
					}
					new SetInventoryMessage(val3.master.inventory, dictionary8, dictionary2[val3]).SendToServer();
				}
			}
			else
			{
				if (instancesList.Count != 1 || !ChangeSinglePlayerInventory.Value)
				{
					return;
				}
				NetworkUser val4 = instancesList.First();
				if (!Object.op_Implicit((Object)(object)val4.master))
				{
					return;
				}
				Inventory inventory2 = val4.master.inventory;
				int equipmentSlotCount = inventory2.GetEquipmentSlotCount();
				Dictionary<ItemTier, int> dictionary9 = new Dictionary<ItemTier, int>();
				foreach (ItemTier value in Enum.GetValues(typeof(ItemTier)))
				{
					dictionary9[value] = inventory2.GetTotalItemCountOfTier(value);
				}
				new Inventory();
				Dictionary<uint, EquipmentIndex> randomEquipment = GetRandomEquipment(inventory2, equipmentSlotCount);
				Dictionary<ItemDef, int> dictionary10 = new Dictionary<ItemDef, int>();
				foreach (ItemTier value2 in Enum.GetValues(typeof(ItemTier)))
				{
					foreach (KeyValuePair<ItemDef, int> randomItem in GetRandomItems(dictionary9[value2], value2))
					{
						dictionary10.Add(randomItem.Key, randomItem.Value);
					}
				}
				ItemDef[] itemDefs = ContentManager.itemDefs;
				foreach (ItemDef val7 in itemDefs)
				{
					int itemCount = val4.master.inventory.GetItemCount(val7);
					int num8 = (dictionary10.ContainsKey(val7) ? dictionary10[val7] : 0);
					if (itemCount > num8)
					{
						val4.master.inventory.RemoveItem(val7, itemCount - num8);
					}
					else if (num8 > itemCount)
					{
						val4.master.inventory.GiveItem(val7, num8 - itemCount);
					}
				}
				foreach (KeyValuePair<uint, EquipmentIndex> item5 in randomEquipment)
				{
					val4.master.inventory.SetEquipmentIndexForSlot(item5.Value, item5.Key);
				}
			}
		}

		public Dictionary<uint, EquipmentIndex> GetRandomEquipment(Inventory playerInventory, int count)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Invalid comparison between Unknown and I4
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<uint, EquipmentIndex> dictionary = new Dictionary<uint, EquipmentIndex>();
			if (count < 1)
			{
				return dictionary;
			}
			List<EquipmentDef> list = new List<EquipmentDef>(ContentManager.equipmentDefs);
			for (uint num = 0u; num < count; num++)
			{
				if ((int)playerInventory.GetEquipment(num).equipmentIndex != -1)
				{
					int index = Random.Range(0, list.Count - 1);
					EquipmentDef val = list[index];
					dictionary.Add(num, val.equipmentIndex);
					list.RemoveAt(index);
				}
			}
			return dictionary;
		}

		public Dictionary<ItemDef, int> GetRandomItems(int count, ItemTier tier)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			Dictionary<ItemDef, int> dictionary = new Dictionary<ItemDef, int>();
			for (int i = 0; i < count; i++)
			{
				List<ItemDef> list = FilterTierItems(ContentManager.itemDefs, tier);
				ItemDef val = list[Random.Range(0, list.Count - 1)];
				if (!((Object)(object)val == (Object)null))
				{
					if (dictionary.ContainsKey(val))
					{
						dictionary[val]++;
					}
					else
					{
						dictionary.Add(val, 1);
					}
				}
			}
			return dictionary;
		}

		private List<ItemDef> FilterTierItems(ItemDef[] itemDefs, ItemTier tier)
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			List<ItemDef> list = new List<ItemDef>();
			foreach (ItemDef val in itemDefs)
			{
				if (val.tier == tier)
				{
					list.Add(val);
				}
			}
			return list;
		}
	}
}