Decompiled source of CripplegaGang v1.3.0

BepInEx/plugins/Boombox/BoomboxSyncFix.dll

Decompiled 6 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using BoomboxSyncFix.Patches;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("BoomboxSyncFix")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("A mod to fix the base game bug of the Boombox not being synced between users.")]
[assembly: AssemblyFileVersion("1.1.0.0")]
[assembly: AssemblyInformationalVersion("1.1.0+71645702ebc3ea437c29afaa8432d4398a219be3")]
[assembly: AssemblyProduct("BoomboxSyncFix")]
[assembly: AssemblyTitle("BoomboxSyncFix")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.1.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 BoomboxSyncFix
{
	[BepInPlugin("BoomboxSyncFix", "BoomboxSyncFix", "1.1.0")]
	public class BoomboxSyncFixPlugin : BaseUnityPlugin
	{
		private readonly Harmony harmony = new Harmony("BoomboxSyncFix");

		public static BoomboxSyncFixPlugin Instance;

		internal ManualLogSource logger;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
			}
			logger = Logger.CreateLogSource("BoomboxSyncFix");
			logger.LogInfo((object)"Plugin BoomboxSyncFix has loaded!");
			harmony.PatchAll(typeof(BoomboxSyncFixPlugin));
			harmony.PatchAll(typeof(BoomboxItemStartMusicPatch));
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "BoomboxSyncFix";

		public const string PLUGIN_NAME = "BoomboxSyncFix";

		public const string PLUGIN_VERSION = "1.1.0";
	}
}
namespace BoomboxSyncFix.Patches
{
	[HarmonyPatch]
	internal class BoomboxItemStartMusicPatch
	{
		private static Dictionary<BoomboxItem, bool> seedSyncDictionary = new Dictionary<BoomboxItem, bool>();

		private static FieldInfo playersManagerField = AccessTools.Field(typeof(BoomboxItem), "playersManager");

		[HarmonyPatch(typeof(BoomboxItem), "StartMusic")]
		[HarmonyPrefix]
		public static void StartMusicPatch(BoomboxItem __instance)
		{
			//IL_000b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			StartOfRound val = (StartOfRound)playersManagerField.GetValue(__instance);
			if ((!seedSyncDictionary.TryGetValue(__instance, out var value) || !value) && (Object)(object)val != (Object)null && val.randomMapSeed > 0)
			{
				int num = val.randomMapSeed - 10;
				__instance.musicRandomizer = new Random(num);
				BoomboxSyncFixPlugin.Instance.logger.LogInfo((object)$"Musicrandomizer variable has been synced with seed: {num}");
				seedSyncDictionary[__instance] = true;
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "OnPlayerConnectedClientRpc")]
		[HarmonyPrefix]
		public static void OnPlayerConnectedPatch(StartOfRound __instance)
		{
			BoomboxSyncFixPlugin.Instance.logger.LogInfo((object)"Another client joined -- forcing everyone to reintialize musicRandomizer.");
			forceReinitialize(seedSyncDictionary);
		}

		[HarmonyPatch(typeof(StartOfRound), "openingDoorsSequence")]
		[HarmonyPrefix]
		public static void openingDoorsSequencePatch(StartOfRound __instance)
		{
			BoomboxSyncFixPlugin.Instance.logger.LogInfo((object)"Round has loaded for all -- forcing everyone to reinitialize musicRandomizer.");
			forceReinitialize(seedSyncDictionary);
		}

		private static void forceReinitialize(Dictionary<BoomboxItem, bool> seedSyncDictionary)
		{
			foreach (BoomboxItem item in seedSyncDictionary.Keys.ToList())
			{
				seedSyncDictionary[item] = false;
			}
		}
	}
}

BepInEx/plugins/Boombox/CustomBoomboxFix.dll

Decompiled 6 months 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 BepInEx;
using Microsoft.CodeAnalysis;

[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("CustomBoomboxFix")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CustomBoomboxFix")]
[assembly: AssemblyTitle("CustomBoomboxFix")]
[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 CustomBoomboxFix
{
	[BepInPlugin("CustomBoomboxFix", "CustomBoomboxFix", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private string CustomSongsPluginPath => Path.Combine(Paths.PluginPath, "Custom Songs");

		private string TargetPath => Path.Combine(Paths.BepInExRootPath, "Custom Songs", "Boombox Music");

		private void Awake()
		{
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin CustomBoomboxFix is loaded!");
			CreatePluginCustomSongsFolder();
			DeleteAllFilesInTargetPath();
			SearchAndCopyCustomSongs();
			CopyMusicFiles();
		}

		private void CreatePluginCustomSongsFolder()
		{
			if (!Directory.Exists(CustomSongsPluginPath))
			{
				Directory.CreateDirectory(CustomSongsPluginPath);
				((BaseUnityPlugin)this).Logger.LogInfo((object)"Created 'Custom Songs' folder in plugin directory.");
			}
		}

		private void CopyMusicFiles()
		{
			if (!Directory.Exists(TargetPath))
			{
				Directory.CreateDirectory(TargetPath);
			}
			IEnumerable<string> enumerable = Directory.GetFiles(CustomSongsPluginPath, "*.mp3").Concat(Directory.GetFiles(CustomSongsPluginPath, "*.wav"));
			foreach (string item in enumerable)
			{
				string fileName = Path.GetFileName(item);
				string text = Path.Combine(TargetPath, fileName);
				if (!File.Exists(text))
				{
					File.Copy(item, text);
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Copied " + fileName + " to Boombox Music folder."));
				}
			}
		}

		private void DeleteAllFilesInTargetPath()
		{
			try
			{
				if (Directory.Exists(TargetPath))
				{
					string[] files = Directory.GetFiles(TargetPath);
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Deleting files in '" + TargetPath + "'..."));
					string[] array = files;
					foreach (string path in array)
					{
						File.Delete(path);
					}
					((BaseUnityPlugin)this).Logger.LogInfo((object)("Deleted files in '" + TargetPath + "'"));
				}
				else
				{
					((BaseUnityPlugin)this).Logger.LogWarning((object)("Target path '" + TargetPath + "' does not exist."));
				}
			}
			catch (Exception ex)
			{
				((BaseUnityPlugin)this).Logger.LogError((object)("An error occurred while trying to delete files: " + ex.Message));
			}
		}

		private void SearchAndCopyCustomSongs()
		{
			string[] directories = Directory.GetDirectories(Paths.PluginPath);
			string[] array = directories;
			foreach (string path in array)
			{
				string text = Path.Combine(path, "Custom Songs");
				if (!Directory.Exists(text))
				{
					continue;
				}
				IEnumerable<string> enumerable = Directory.GetFiles(text, "*.mp3").Concat(Directory.GetFiles(text, "*.wav"));
				foreach (string item in enumerable)
				{
					string fileName = Path.GetFileName(item);
					string text2 = Path.Combine(TargetPath, fileName);
					if (!File.Exists(text2))
					{
						File.Copy(item, text2);
						((BaseUnityPlugin)this).Logger.LogInfo((object)("Copied " + fileName + " from " + text + " to Boombox Music folder."));
					}
				}
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "CustomBoomboxFix";

		public const string PLUGIN_NAME = "CustomBoomboxFix";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}

BepInEx/plugins/Boombox/CustomBoomboxTracks.dll

Decompiled 6 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using CustomBoomboxTracks.Configuration;
using CustomBoomboxTracks.Managers;
using CustomBoomboxTracks.Utilities;
using HarmonyLib;
using UnityEngine;
using UnityEngine.Networking;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("CustomBoomboxTracks")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.4.0.0")]
[assembly: AssemblyInformationalVersion("1.4.0")]
[assembly: AssemblyProduct("CustomBoomboxTracks")]
[assembly: AssemblyTitle("CustomBoomboxTracks")]
[assembly: AssemblyVersion("1.4.0.0")]
namespace CustomBoomboxTracks
{
	[BepInPlugin("com.steven.lethalcompany.boomboxmusic", "Custom Boombox Music", "1.4.0")]
	public class BoomboxPlugin : BaseUnityPlugin
	{
		private const string GUID = "com.steven.lethalcompany.boomboxmusic";

		private const string NAME = "Custom Boombox Music";

		private const string VERSION = "1.4.0";

		private static BoomboxPlugin Instance;

		private void Awake()
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			Instance = this;
			LogInfo("Loading...");
			AudioManager.GenerateFolders();
			Config.Init();
			new Harmony("com.steven.lethalcompany.boomboxmusic").PatchAll();
			LogInfo("Loading Complete!");
		}

		internal static void LogDebug(string message)
		{
			Instance.Log(message, (LogLevel)32);
		}

		internal static void LogInfo(string message)
		{
			Instance.Log(message, (LogLevel)16);
		}

		internal static void LogWarning(string message)
		{
			Instance.Log(message, (LogLevel)4);
		}

		internal static void LogError(string message)
		{
			Instance.Log(message, (LogLevel)2);
		}

		internal static void LogError(Exception ex)
		{
			Instance.Log(ex.Message + "\n" + ex.StackTrace, (LogLevel)2);
		}

		private void Log(string message, LogLevel logLevel)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			((BaseUnityPlugin)this).Logger.Log(logLevel, (object)message);
		}
	}
}
namespace CustomBoomboxTracks.Utilities
{
	public class SharedCoroutineStarter : MonoBehaviour
	{
		private static SharedCoroutineStarter _instance;

		public static Coroutine StartCoroutine(IEnumerator routine)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)_instance == (Object)null)
			{
				_instance = new GameObject("Shared Coroutine Starter").AddComponent<SharedCoroutineStarter>();
				Object.DontDestroyOnLoad((Object)(object)_instance);
			}
			return ((MonoBehaviour)_instance).StartCoroutine(routine);
		}
	}
}
namespace CustomBoomboxTracks.Patches
{
	[HarmonyPatch(typeof(BoomboxItem), "PocketItem")]
	internal class BoomboxItem_PocketItem
	{
		private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
		{
			List<CodeInstruction> list = instructions.ToList();
			bool flag = false;
			for (int i = 0; i < list.Count; i++)
			{
				if (!flag)
				{
					if (list[i].opcode == OpCodes.Call)
					{
						flag = true;
					}
					continue;
				}
				if (list[i].opcode == OpCodes.Ret)
				{
					break;
				}
				list[i].opcode = OpCodes.Nop;
			}
			return list;
		}
	}
	[HarmonyPatch(typeof(BoomboxItem), "Start")]
	internal class BoomboxItem_Start
	{
		private static void Postfix(BoomboxItem __instance)
		{
			if (AudioManager.FinishedLoading)
			{
				AudioManager.ApplyClips(__instance);
				return;
			}
			AudioManager.OnAllSongsLoaded += delegate
			{
				AudioManager.ApplyClips(__instance);
			};
		}
	}
	[HarmonyPatch(typeof(BoomboxItem), "StartMusic")]
	internal class BoomboxItem_StartMusic
	{
		private static void Postfix(BoomboxItem __instance, bool startMusic)
		{
			if (startMusic)
			{
				BoomboxPlugin.LogInfo("Playing " + ((Object)__instance.boomboxAudio.clip).name);
			}
		}
	}
	[HarmonyPatch(typeof(StartOfRound), "Awake")]
	internal class StartOfRound_Awake
	{
		private static void Prefix()
		{
			AudioManager.Load();
		}
	}
}
namespace CustomBoomboxTracks.Managers
{
	internal static class AudioManager
	{
		private static string[] allSongPaths;

		private static List<AudioClip> clips = new List<AudioClip>();

		private static bool firstRun = true;

		private static bool finishedLoading = false;

		private static readonly string directory = Path.Combine(Paths.BepInExRootPath, "Custom Songs", "Boombox Music");

		public static bool FinishedLoading => finishedLoading;

		public static bool HasNoSongs => allSongPaths.Length == 0;

		public static event Action OnAllSongsLoaded;

		public static void GenerateFolders()
		{
			Directory.CreateDirectory(directory);
			BoomboxPlugin.LogInfo("Created directory at " + directory);
		}

		public static void Load()
		{
			if (!firstRun)
			{
				return;
			}
			firstRun = false;
			allSongPaths = Directory.GetFiles(directory);
			if (allSongPaths.Length == 0)
			{
				BoomboxPlugin.LogWarning("No songs found!");
				return;
			}
			BoomboxPlugin.LogInfo("Preparing to load AudioClips...");
			List<Coroutine> list = new List<Coroutine>();
			string[] array = allSongPaths;
			for (int i = 0; i < array.Length; i++)
			{
				Coroutine item = SharedCoroutineStarter.StartCoroutine(LoadAudioClip(array[i]));
				list.Add(item);
			}
			SharedCoroutineStarter.StartCoroutine(WaitForAllClips(list));
		}

		private static IEnumerator LoadAudioClip(string filePath)
		{
			BoomboxPlugin.LogInfo("Loading " + filePath + "!");
			if ((int)GetAudioType(filePath) == 0)
			{
				BoomboxPlugin.LogError("Failed to load AudioClip from " + filePath + "\nUnsupported file extension!");
				yield break;
			}
			UnityWebRequest loader = UnityWebRequestMultimedia.GetAudioClip(filePath, GetAudioType(filePath));
			if (Config.StreamFromDisk)
			{
				DownloadHandler downloadHandler = loader.downloadHandler;
				((DownloadHandlerAudioClip)((downloadHandler is DownloadHandlerAudioClip) ? downloadHandler : null)).streamAudio = true;
			}
			loader.SendWebRequest();
			while (!loader.isDone)
			{
				yield return null;
			}
			if (loader.error != null)
			{
				BoomboxPlugin.LogError("Error loading clip from path: " + filePath + "\n" + loader.error);
				BoomboxPlugin.LogError(loader.error);
				yield break;
			}
			AudioClip content = DownloadHandlerAudioClip.GetContent(loader);
			if (Object.op_Implicit((Object)(object)content) && (int)content.loadState == 2)
			{
				BoomboxPlugin.LogInfo("Loaded " + filePath);
				((Object)content).name = Path.GetFileName(filePath);
				clips.Add(content);
			}
			else
			{
				BoomboxPlugin.LogError("Failed to load clip at: " + filePath + "\nThis might be due to an mismatch between the audio codec and the file extension!");
			}
		}

		private static IEnumerator WaitForAllClips(List<Coroutine> coroutines)
		{
			foreach (Coroutine coroutine in coroutines)
			{
				yield return coroutine;
			}
			clips.Sort((AudioClip first, AudioClip second) => ((Object)first).name.CompareTo(((Object)second).name));
			finishedLoading = true;
			AudioManager.OnAllSongsLoaded?.Invoke();
			AudioManager.OnAllSongsLoaded = null;
		}

		public static void ApplyClips(BoomboxItem __instance)
		{
			BoomboxPlugin.LogInfo("Applying clips!");
			if (Config.UseDefaultSongs)
			{
				__instance.musicAudios = __instance.musicAudios.Concat(clips).ToArray();
			}
			else
			{
				__instance.musicAudios = clips.ToArray();
			}
			BoomboxPlugin.LogInfo($"Total Clip Count: {__instance.musicAudios.Length}");
		}

		private static AudioType GetAudioType(string path)
		{
			string text = Path.GetExtension(path).ToLower();
			switch (text)
			{
			case ".wav":
				return (AudioType)20;
			case ".ogg":
				return (AudioType)14;
			case ".mp3":
				return (AudioType)13;
			default:
				BoomboxPlugin.LogError("Unsupported extension type: " + text);
				return (AudioType)0;
			}
		}
	}
}
namespace CustomBoomboxTracks.Configuration
{
	internal static class Config
	{
		private const string CONFIG_FILE_NAME = "boombox.cfg";

		private static ConfigFile _config;

		private static ConfigEntry<bool> _useDefaultSongs;

		private static ConfigEntry<bool> _streamAudioFromDisk;

		public static bool UseDefaultSongs
		{
			get
			{
				if (!_useDefaultSongs.Value)
				{
					return AudioManager.HasNoSongs;
				}
				return true;
			}
		}

		public static bool StreamFromDisk => _streamAudioFromDisk.Value;

		public static void Init()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			BoomboxPlugin.LogInfo("Initializing config...");
			_config = new ConfigFile(Path.Combine(Paths.ConfigPath, "boombox.cfg"), true);
			_useDefaultSongs = _config.Bind<bool>("Config", "Use Default Songs", false, "Include the default songs in the rotation.");
			_streamAudioFromDisk = _config.Bind<bool>("Config", "Stream Audio From Disk", false, "Requires less memory and takes less time to load, but prevents playing the same song twice at once.");
			BoomboxPlugin.LogInfo("Config initialized!");
		}

		private static void PrintConfig()
		{
			BoomboxPlugin.LogInfo($"Use Default Songs: {_useDefaultSongs.Value}");
			BoomboxPlugin.LogInfo($"Stream From Disk: {_streamAudioFromDisk}");
		}
	}
}

BepInEx/plugins/CustomX/LethalPaintings.dll

Decompiled 6 months 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 BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7", FrameworkDisplayName = ".NET Framework 4.7")]
[assembly: AssemblyCompany("LethalPaintings")]
[assembly: AssemblyConfiguration("release")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LethalPaintings")]
[assembly: AssemblyTitle("LethalPaintings")]
[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 LethalPaintings
{
	internal class Patches
	{
		private static ManualLogSource Logger { get; set; }

		public static void Init(ManualLogSource logger)
		{
			Logger = logger;
		}

		[HarmonyPatch(typeof(GrabbableObject), "SetScrapValue")]
		[HarmonyPostfix]
		private static void SetScrapValuePatch(GrabbableObject __instance)
		{
			if (__instance.itemProperties.itemName == "Painting")
			{
				UpdateTexture(Plugin.PaintingFiles, __instance.itemProperties.materialVariants[0]);
				UpdateTexture(Plugin.PaintingFiles, __instance.itemProperties.materialVariants[1]);
			}
		}

		private static void UpdateTexture(IReadOnlyList<string> files, Material material)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			if (files.Count != 0)
			{
				int index = Plugin.Rand.Next(files.Count);
				Texture2D val = new Texture2D(2, 2);
				Logger.LogInfo((object)("Patching " + ((Object)material).name + " with " + files[index]));
				ImageConversion.LoadImage(val, File.ReadAllBytes(files[index]));
				material.mainTexture = (Texture)(object)val;
			}
		}
	}
	[BepInPlugin("LethalPaintings", "LethalPaintings", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private static List<string> PosterFolders = new List<string>();

		public static readonly List<string> PaintingFiles = new List<string>();

		public static Random Rand = new Random();

		private void Awake()
		{
			//IL_0096: Unknown result type (might be due to invalid IL or missing references)
			PosterFolders = Directory.GetDirectories(Paths.PluginPath, "LethalPaintings", SearchOption.AllDirectories).ToList();
			foreach (string posterFolder in PosterFolders)
			{
				string[] files = Directory.GetFiles(Path.Combine(posterFolder, "paintings"));
				foreach (string text in files)
				{
					if (Path.GetExtension(text) != ".old")
					{
						PaintingFiles.Add(text);
					}
				}
			}
			Patches.Init(((BaseUnityPlugin)this).Logger);
			new Harmony("LethalPaintings").PatchAll(typeof(Patches));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin LethalPaintings is loaded!");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LethalPaintings";

		public const string PLUGIN_NAME = "LethalPaintings";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}

BepInEx/plugins/CustomX/LethalPosters.dll

Decompiled 6 months 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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7", FrameworkDisplayName = ".NET Framework 4.7")]
[assembly: AssemblyCompany("LethalPosters")]
[assembly: AssemblyConfiguration("release")]
[assembly: AssemblyDescription("LethalCopmany posters API")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("LethalPosters")]
[assembly: AssemblyTitle("LethalPosters")]
[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 LethalPosters
{
	internal class Config
	{
		private static ConfigFile ConfigFile { get; set; }

		static Config()
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Expected O, but got Unknown
			ConfigFile = new ConfigFile(Paths.ConfigPath + "\\LethalPosters.cfg", true);
			foreach (string posterFolder in Plugin.PosterFolders)
			{
				int num = posterFolder.IndexOf("plugins\\", StringComparison.Ordinal) + "plugins\\".Length;
				int num2 = posterFolder.IndexOf("\\LethalPosters", num, StringComparison.Ordinal);
				string text = posterFolder.Substring(num, num2 - num);
				if (!ConfigFile.Bind<bool>(text, "Enabled", true, "Enable or disable " + text).Value)
				{
					Directory.Move(posterFolder, posterFolder + ".Disabled");
				}
			}
		}
	}
	internal class Patches
	{
		private static ManualLogSource Logger { get; set; }

		public static void Init(ManualLogSource logger)
		{
			Logger = logger;
		}

		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPostfix]
		private static void StartPatch()
		{
			Logger.LogInfo((object)"Patching Start in StartOfRound");
			UpdateMaterials(0);
		}

		[HarmonyPatch(typeof(RoundManager), "GenerateNewLevelClientRpc")]
		[HarmonyPostfix]
		private static void GenerateNewLevelClientRpcPatch(int randomSeed)
		{
			Logger.LogInfo((object)"Patching GenerateNewLevelClientRpc in RoundManager");
			UpdateMaterials(randomSeed);
		}

		private static void UpdateMaterials(int seed)
		{
			Logger.LogInfo((object)"Patching the textures");
			Plugin.Rand = new Random(seed);
			Material[] materials = ((Renderer)GameObject.Find("HangarShip/Plane.001").GetComponent<MeshRenderer>()).materials;
			UpdateTexture(Plugin.PosterFiles, materials[0]);
			UpdateTexture(Plugin.TipFiles, materials[1]);
		}

		private static void UpdateTexture(IReadOnlyList<string> files, Material material)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			if (files.Count != 0)
			{
				int index = Plugin.Rand.Next(files.Count);
				Texture2D val = new Texture2D(2, 2);
				Logger.LogInfo((object)("Patching " + ((Object)material).name + " with " + files[index]));
				ImageConversion.LoadImage(val, File.ReadAllBytes(files[index]));
				material.mainTexture = (Texture)(object)val;
			}
		}
	}
	[BepInPlugin("LethalPosters", "LethalPosters", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		public static List<string> PosterFolders = new List<string>();

		public static readonly List<string> PosterFiles = new List<string>();

		public static readonly List<string> TipFiles = new List<string>();

		public static Random Rand = new Random();

		private void Awake()
		{
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			PosterFolders = Directory.GetDirectories(Paths.PluginPath, "LethalPosters", SearchOption.AllDirectories).ToList();
			foreach (string posterFolder in PosterFolders)
			{
				string[] files = Directory.GetFiles(Path.Combine(posterFolder, "posters"));
				foreach (string text in files)
				{
					if (Path.GetExtension(text) != ".old")
					{
						PosterFiles.Add(text);
					}
				}
				files = Directory.GetFiles(Path.Combine(posterFolder, "tips"));
				foreach (string text2 in files)
				{
					if (Path.GetExtension(text2) != ".old")
					{
						TipFiles.Add(text2);
					}
				}
			}
			Patches.Init(((BaseUnityPlugin)this).Logger);
			new Harmony("LethalPosters").PatchAll(typeof(Patches));
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin LethalPosters (1.0.0) is loaded!");
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "LethalPosters";

		public const string PLUGIN_NAME = "LethalPosters";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}

BepInEx/plugins/TV/TVLoader.dll

Decompiled 6 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using TVLoader.Utils;
using UnityEngine;
using UnityEngine.Video;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("TVLoader")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("TVLoader")]
[assembly: AssemblyCopyright("Copyright ©  2023")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e59845a7-f2f7-4416-9a61-ca1939ce6e2d")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace TVLoader
{
	[BepInPlugin("rattenbonkers.TVLoader", "TVLoader", "1.1.1")]
	public class TVLoaderPlugin : BaseUnityPlugin
	{
		private const string MyGUID = "rattenbonkers.TVLoader";

		private const string PluginName = "TVLoader";

		private const string VersionString = "1.1.1";

		private static readonly Harmony Harmony = new Harmony("rattenbonkers.TVLoader");

		public static ManualLogSource Log = new ManualLogSource("TVLoader");

		private void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			Harmony.PatchAll();
			VideoManager.Load();
			((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("PluginName: {0}, VersionString: {1} is loaded. Video Count: {2}", "TVLoader", "1.1.1", VideoManager.Videos.Count));
		}
	}
}
namespace TVLoader.Utils
{
	internal static class VideoManager
	{
		public static List<string> Videos = new List<string>();

		public static void Load()
		{
			string[] directories = Directory.GetDirectories(Paths.PluginPath);
			foreach (string text in directories)
			{
				string path = Path.Combine(Paths.PluginPath, text, "Television Videos");
				if (Directory.Exists(path))
				{
					string[] files = Directory.GetFiles(path, "*.mp4");
					Videos.AddRange(files);
					TVLoaderPlugin.Log.LogInfo((object)$"{text} has {files.Length} videos.");
				}
			}
			string path2 = Path.Combine(Paths.PluginPath, "Television Videos");
			if (!Directory.Exists(path2))
			{
				Directory.CreateDirectory(path2);
			}
			string[] files2 = Directory.GetFiles(path2, "*.mp4");
			Videos.AddRange(files2);
			TVLoaderPlugin.Log.LogInfo((object)$"Global has {files2.Length} videos.");
			TVLoaderPlugin.Log.LogInfo((object)$"Loaded {Videos.Count} total.");
		}
	}
}
namespace TVLoader.Patches
{
	[HarmonyPatch(typeof(TVScript))]
	internal class TVScriptPatches
	{
		[Serializable]
		[CompilerGenerated]
		private sealed class <>c
		{
			public static readonly <>c <>9 = new <>c();

			public static EventHandler <>9__13_0;

			internal void <PrepareVideo>b__13_0(VideoPlayer source)
			{
				TVLoaderPlugin.Log.LogInfo((object)"Prepared next video!");
			}
		}

		private static FieldInfo currentClipProperty = typeof(TVScript).GetField("currentClip", BindingFlags.Instance | BindingFlags.NonPublic);

		private static FieldInfo currentTimeProperty = typeof(TVScript).GetField("currentClipTime", BindingFlags.Instance | BindingFlags.NonPublic);

		private static FieldInfo wasTvOnLastFrameProp = typeof(TVScript).GetField("wasTvOnLastFrame", BindingFlags.Instance | BindingFlags.NonPublic);

		private static FieldInfo timeSinceTurningOffTVProp = typeof(TVScript).GetField("timeSinceTurningOffTV", BindingFlags.Instance | BindingFlags.NonPublic);

		private static MethodInfo setMatMethod = typeof(TVScript).GetMethod("SetTVScreenMaterial", BindingFlags.Instance | BindingFlags.NonPublic);

		private static MethodInfo onEnableMethod = typeof(TVScript).GetMethod("OnEnable", BindingFlags.Instance | BindingFlags.NonPublic);

		private static bool tvHasPlayedBefore = false;

		private static RenderTexture renderTexture;

		private static VideoPlayer currentVideoPlayer;

		private static VideoPlayer nextVideoPlayer;

		[HarmonyPrefix]
		[HarmonyPatch("Update")]
		public static bool Update(TVScript __instance)
		{
			if ((Object)(object)currentVideoPlayer == (Object)null)
			{
				currentVideoPlayer = ((Component)__instance).GetComponent<VideoPlayer>();
				renderTexture = currentVideoPlayer.targetTexture;
				if (VideoManager.Videos.Count > 0)
				{
					PrepareVideo(__instance, 0);
				}
			}
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("TurnTVOnOff")]
		public static bool TurnTVOnOff(TVScript __instance, bool on)
		{
			TVLoaderPlugin.Log.LogInfo((object)$"TVOnOff: {on}");
			if (VideoManager.Videos.Count == 0)
			{
				return false;
			}
			int num = (int)currentClipProperty.GetValue(__instance);
			if (on && tvHasPlayedBefore)
			{
				num = (num + 1) % VideoManager.Videos.Count;
				currentClipProperty.SetValue(__instance, num);
			}
			__instance.tvOn = on;
			if (on)
			{
				PlayVideo(__instance);
				__instance.tvSFX.PlayOneShot(__instance.switchTVOn);
				WalkieTalkie.TransmitOneShotAudio(__instance.tvSFX, __instance.switchTVOn, 1f);
			}
			else
			{
				__instance.video.Stop();
				__instance.tvSFX.PlayOneShot(__instance.switchTVOff);
				WalkieTalkie.TransmitOneShotAudio(__instance.tvSFX, __instance.switchTVOff, 1f);
			}
			setMatMethod.Invoke(__instance, new object[1] { on });
			return false;
		}

		[HarmonyPrefix]
		[HarmonyPatch("TVFinishedClip")]
		public static bool TVFinishedClip(TVScript __instance, VideoPlayer source)
		{
			if (!__instance.tvOn || GameNetworkManager.Instance.localPlayerController.isInsideFactory)
			{
				return false;
			}
			TVLoaderPlugin.Log.LogInfo((object)"TVFinishedClip");
			int num = (int)currentClipProperty.GetValue(__instance);
			if (VideoManager.Videos.Count > 0)
			{
				num = (num + 1) % VideoManager.Videos.Count;
			}
			currentTimeProperty.SetValue(__instance, 0f);
			currentClipProperty.SetValue(__instance, num);
			PlayVideo(__instance);
			return false;
		}

		private static void PrepareVideo(TVScript instance, int index = -1)
		{
			//IL_00e5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f0: Expected O, but got Unknown
			if (index == -1)
			{
				index = (int)currentClipProperty.GetValue(instance) + 1;
			}
			if ((Object)(object)nextVideoPlayer != (Object)null && ((Component)nextVideoPlayer).gameObject.activeInHierarchy)
			{
				Object.Destroy((Object)(object)nextVideoPlayer);
			}
			nextVideoPlayer = ((Component)instance).gameObject.AddComponent<VideoPlayer>();
			nextVideoPlayer.playOnAwake = false;
			nextVideoPlayer.isLooping = false;
			nextVideoPlayer.source = (VideoSource)1;
			nextVideoPlayer.controlledAudioTrackCount = 1;
			nextVideoPlayer.audioOutputMode = (VideoAudioOutputMode)1;
			nextVideoPlayer.SetTargetAudioSource((ushort)0, instance.tvSFX);
			nextVideoPlayer.url = "file://" + VideoManager.Videos[index % VideoManager.Videos.Count];
			nextVideoPlayer.Prepare();
			VideoPlayer obj = nextVideoPlayer;
			object obj2 = <>c.<>9__13_0;
			if (obj2 == null)
			{
				EventHandler val = delegate
				{
					TVLoaderPlugin.Log.LogInfo((object)"Prepared next video!");
				};
				<>c.<>9__13_0 = val;
				obj2 = (object)val;
			}
			obj.prepareCompleted += (EventHandler)obj2;
		}

		private static void PlayVideo(TVScript instance)
		{
			tvHasPlayedBefore = true;
			if (VideoManager.Videos.Count != 0)
			{
				if ((Object)(object)nextVideoPlayer != (Object)null)
				{
					VideoPlayer val = currentVideoPlayer;
					instance.video = (currentVideoPlayer = nextVideoPlayer);
					nextVideoPlayer = null;
					TVLoaderPlugin.Log.LogInfo((object)$"Destroy {val}");
					Object.Destroy((Object)(object)val);
					onEnableMethod.Invoke(instance, new object[0]);
				}
				currentTimeProperty.SetValue(instance, 0f);
				instance.video.targetTexture = renderTexture;
				instance.video.Play();
				PrepareVideo(instance);
			}
		}
	}
}

BepInEx/plugins/x753-More_Suits/MoreSuits.dll

Decompiled 6 months 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 BepInEx;
using HarmonyLib;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = "")]
[assembly: AssemblyCompany("MoreSuits")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("A mod that adds more suit options to Lethal Company")]
[assembly: AssemblyFileVersion("1.4.1.0")]
[assembly: AssemblyInformationalVersion("1.4.1")]
[assembly: AssemblyProduct("MoreSuits")]
[assembly: AssemblyTitle("MoreSuits")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.4.1.0")]
[module: UnverifiableCode]
namespace MoreSuits;

[BepInPlugin("x753.More_Suits", "More Suits", "1.4.1")]
public class MoreSuitsMod : BaseUnityPlugin
{
	[HarmonyPatch(typeof(StartOfRound))]
	internal class StartOfRoundPatch
	{
		[HarmonyPatch("Start")]
		[HarmonyPrefix]
		private static void StartPatch(ref StartOfRound __instance)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			//IL_067c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0681: Unknown result type (might be due to invalid IL or missing references)
			//IL_0687: Unknown result type (might be due to invalid IL or missing references)
			//IL_068c: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0400: Expected O, but got Unknown
			//IL_0310: Unknown result type (might be due to invalid IL or missing references)
			//IL_0317: Expected O, but got Unknown
			//IL_0598: Unknown result type (might be due to invalid IL or missing references)
			//IL_0204: Unknown result type (might be due to invalid IL or missing references)
			//IL_020b: Expected O, but got Unknown
			try
			{
				if (SuitsAdded)
				{
					return;
				}
				int count = __instance.unlockablesList.unlockables.Count;
				UnlockableItem val = new UnlockableItem();
				int num = 0;
				for (int i = 0; i < __instance.unlockablesList.unlockables.Count; i++)
				{
					UnlockableItem val2 = __instance.unlockablesList.unlockables[i];
					if (!((Object)(object)val2.suitMaterial != (Object)null) || !val2.alreadyUnlocked)
					{
						continue;
					}
					val = val2;
					List<string> list = Directory.GetDirectories(Paths.PluginPath, "moresuits", SearchOption.AllDirectories).ToList();
					List<string> list2 = new List<string>();
					List<string> list3 = new List<string>();
					List<string> list4 = DisabledSuits.ToLower().Replace(".png", "").Split(',')
						.ToList();
					List<string> list5 = new List<string>();
					if (!LoadAllSuits)
					{
						foreach (string item2 in list)
						{
							if (File.Exists(Path.Combine(item2, "!less-suits.txt")))
							{
								string[] collection = new string[9] { "glow", "kirby", "knuckles", "luigi", "mario", "minion", "skeleton", "slayer", "smile" };
								list5.AddRange(collection);
								break;
							}
						}
					}
					foreach (string item3 in list)
					{
						if (item3 != "")
						{
							string[] files = Directory.GetFiles(item3, "*.png");
							string[] files2 = Directory.GetFiles(item3, "*.matbundle");
							list2.AddRange(files);
							list3.AddRange(files2);
						}
					}
					list3.Sort();
					list2.Sort();
					try
					{
						foreach (string item4 in list3)
						{
							Object[] array = AssetBundle.LoadFromFile(item4).LoadAllAssets();
							foreach (Object val3 in array)
							{
								if (val3 is Material)
								{
									Material item = (Material)val3;
									customMaterials.Add(item);
								}
							}
						}
					}
					catch (Exception ex)
					{
						Debug.Log((object)("Something went wrong with More Suits! Could not load materials from asset bundle(s). Error: " + ex));
					}
					foreach (string item5 in list2)
					{
						if (list4.Contains(Path.GetFileNameWithoutExtension(item5).ToLower()))
						{
							continue;
						}
						string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
						if (list5.Contains(Path.GetFileNameWithoutExtension(item5).ToLower()) && item5.Contains(directoryName))
						{
							continue;
						}
						UnlockableItem val4;
						Material val5;
						if (Path.GetFileNameWithoutExtension(item5).ToLower() == "default")
						{
							val4 = val;
							val5 = val4.suitMaterial;
						}
						else
						{
							val4 = JsonUtility.FromJson<UnlockableItem>(JsonUtility.ToJson((object)val));
							val5 = Object.Instantiate<Material>(val4.suitMaterial);
						}
						byte[] array2 = File.ReadAllBytes(item5);
						Texture2D val6 = new Texture2D(2, 2);
						ImageConversion.LoadImage(val6, array2);
						val5.mainTexture = (Texture)(object)val6;
						val4.unlockableName = Path.GetFileNameWithoutExtension(item5);
						try
						{
							string path = Path.Combine(Path.GetDirectoryName(item5), "advanced", val4.unlockableName + ".json");
							if (File.Exists(path))
							{
								string[] array3 = File.ReadAllLines(path);
								for (int j = 0; j < array3.Length; j++)
								{
									string[] array4 = array3[j].Trim().Split(':');
									if (array4.Length != 2)
									{
										continue;
									}
									string text = array4[0].Trim('"', ' ', ',');
									string text2 = array4[1].Trim('"', ' ', ',');
									if (text2.Contains(".png"))
									{
										byte[] array5 = File.ReadAllBytes(Path.Combine(Path.GetDirectoryName(item5), "advanced", text2));
										Texture2D val7 = new Texture2D(2, 2);
										ImageConversion.LoadImage(val7, array5);
										val5.SetTexture(text, (Texture)(object)val7);
										continue;
									}
									if (text == "PRICE" && int.TryParse(text2, out var result))
									{
										try
										{
											val4 = AddToRotatingShop(val4, result, __instance.unlockablesList.unlockables.Count);
										}
										catch (Exception ex2)
										{
											Debug.Log((object)("Something went wrong with More Suits! Could not add a suit to the rotating shop. Error: " + ex2));
										}
										continue;
									}
									switch (text2)
									{
									case "KEYWORD":
										val5.EnableKeyword(text);
										continue;
									case "DISABLEKEYWORD":
										val5.DisableKeyword(text);
										continue;
									case "SHADERPASS":
										val5.SetShaderPassEnabled(text, true);
										continue;
									case "DISABLESHADERPASS":
										val5.SetShaderPassEnabled(text, false);
										continue;
									}
									float result2;
									Vector4 vector;
									if (text == "SHADER")
									{
										Shader shader = Shader.Find(text2);
										val5.shader = shader;
									}
									else if (text == "MATERIAL")
									{
										foreach (Material customMaterial in customMaterials)
										{
											if (((Object)customMaterial).name == text2)
											{
												val5 = Object.Instantiate<Material>(customMaterial);
												val5.mainTexture = (Texture)(object)val6;
												break;
											}
										}
									}
									else if (float.TryParse(text2, out result2))
									{
										val5.SetFloat(text, result2);
									}
									else if (TryParseVector4(text2, out vector))
									{
										val5.SetVector(text, vector);
									}
								}
							}
						}
						catch (Exception ex3)
						{
							Debug.Log((object)("Something went wrong with More Suits! Error: " + ex3));
						}
						val4.suitMaterial = val5;
						if (val4.unlockableName.ToLower() != "default")
						{
							if (num == MaxSuits)
							{
								Debug.Log((object)"Attempted to add a suit, but you've already reached the max number of suits! Modify the config if you want more.");
								continue;
							}
							__instance.unlockablesList.unlockables.Add(val4);
							num++;
						}
					}
					SuitsAdded = true;
					break;
				}
				UnlockableItem val8 = JsonUtility.FromJson<UnlockableItem>(JsonUtility.ToJson((object)val));
				val8.alreadyUnlocked = false;
				val8.hasBeenMoved = false;
				val8.placedPosition = Vector3.zero;
				val8.placedRotation = Vector3.zero;
				val8.unlockableType = 753;
				while (__instance.unlockablesList.unlockables.Count < count + MaxSuits)
				{
					__instance.unlockablesList.unlockables.Add(val8);
				}
			}
			catch (Exception ex4)
			{
				Debug.Log((object)("Something went wrong with More Suits! Error: " + ex4));
			}
		}

		[HarmonyPatch("PositionSuitsOnRack")]
		[HarmonyPrefix]
		private static bool PositionSuitsOnRackPatch(ref StartOfRound __instance)
		{
			//IL_009a: 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)
			//IL_00ac: 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_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			List<UnlockableSuit> source = Object.FindObjectsOfType<UnlockableSuit>().ToList();
			source = source.OrderBy((UnlockableSuit suit) => suit.syncedSuitID.Value).ToList();
			int num = 0;
			foreach (UnlockableSuit item in source)
			{
				AutoParentToShip component = ((Component)item).gameObject.GetComponent<AutoParentToShip>();
				component.overrideOffset = true;
				float num2 = 0.18f;
				if (MakeSuitsFitOnRack && source.Count > 13)
				{
					num2 /= (float)Math.Min(source.Count, 20) / 12f;
				}
				component.positionOffset = new Vector3(-2.45f, 2.75f, -8.41f) + __instance.rightmostSuitPosition.forward * num2 * (float)num;
				component.rotationOffset = new Vector3(0f, 90f, 0f);
				num++;
			}
			return false;
		}
	}

	private const string modGUID = "x753.More_Suits";

	private const string modName = "More Suits";

	private const string modVersion = "1.4.1";

	private readonly Harmony harmony = new Harmony("x753.More_Suits");

	private static MoreSuitsMod Instance;

	public static bool SuitsAdded = false;

	public static string DisabledSuits;

	public static bool LoadAllSuits;

	public static bool MakeSuitsFitOnRack;

	public static int MaxSuits;

	public static List<Material> customMaterials = new List<Material>();

	private static TerminalNode cancelPurchase;

	private static TerminalKeyword buyKeyword;

	private void Awake()
	{
		if ((Object)(object)Instance == (Object)null)
		{
			Instance = this;
		}
		DisabledSuits = ((BaseUnityPlugin)this).Config.Bind<string>("General", "Disabled Suit List", "UglySuit751.png,UglySuit752.png,UglySuit753.png", "Comma-separated list of suits that shouldn't be loaded").Value;
		LoadAllSuits = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Ignore !less-suits.txt", false, "If true, ignores the !less-suits.txt file and will attempt to load every suit, except those in the disabled list. This should be true if you're not worried about having too many suits.").Value;
		MakeSuitsFitOnRack = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Make Suits Fit on Rack", true, "If true, squishes the suits together so more can fit on the rack.").Value;
		MaxSuits = ((BaseUnityPlugin)this).Config.Bind<int>("General", "Max Suits", 100, "The maximum number of suits to load. If you have more, some will be ignored.").Value;
		harmony.PatchAll();
		((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin More Suits is loaded!");
	}

	private static UnlockableItem AddToRotatingShop(UnlockableItem newSuit, int price, int unlockableID)
	{
		//IL_0065: Unknown result type (might be due to invalid IL or missing references)
		//IL_006a: Unknown result type (might be due to invalid IL or missing references)
		//IL_0070: 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_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0111: Expected O, but got Unknown
		//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
		//IL_01d4: Expected O, but got Unknown
		//IL_0298: Unknown result type (might be due to invalid IL or missing references)
		//IL_029f: Expected O, but got Unknown
		Terminal val = Object.FindObjectOfType<Terminal>();
		for (int i = 0; i < val.terminalNodes.allKeywords.Length; i++)
		{
			if (((Object)val.terminalNodes.allKeywords[i]).name == "Buy")
			{
				buyKeyword = val.terminalNodes.allKeywords[i];
				break;
			}
		}
		newSuit.alreadyUnlocked = false;
		newSuit.hasBeenMoved = false;
		newSuit.placedPosition = Vector3.zero;
		newSuit.placedRotation = Vector3.zero;
		newSuit.shopSelectionNode = ScriptableObject.CreateInstance<TerminalNode>();
		((Object)newSuit.shopSelectionNode).name = newSuit.unlockableName + "SuitBuy1";
		newSuit.shopSelectionNode.creatureName = newSuit.unlockableName + " suit";
		newSuit.shopSelectionNode.displayText = "You have requested to order " + newSuit.unlockableName + " suits.\nTotal cost of item: [totalCost].\n\nPlease CONFIRM or DENY.\n\n";
		newSuit.shopSelectionNode.clearPreviousText = true;
		newSuit.shopSelectionNode.shipUnlockableID = unlockableID;
		newSuit.shopSelectionNode.itemCost = price;
		newSuit.shopSelectionNode.overrideOptions = true;
		CompatibleNoun val2 = new CompatibleNoun();
		val2.noun = ScriptableObject.CreateInstance<TerminalKeyword>();
		val2.noun.word = "confirm";
		val2.noun.isVerb = true;
		val2.result = ScriptableObject.CreateInstance<TerminalNode>();
		((Object)val2.result).name = newSuit.unlockableName + "SuitBuyConfirm";
		val2.result.creatureName = "";
		val2.result.displayText = "Ordered " + newSuit.unlockableName + " suits! Your new balance is [playerCredits].\n\n";
		val2.result.clearPreviousText = true;
		val2.result.shipUnlockableID = unlockableID;
		val2.result.buyUnlockable = true;
		val2.result.itemCost = price;
		val2.result.terminalEvent = "";
		CompatibleNoun val3 = new CompatibleNoun();
		val3.noun = ScriptableObject.CreateInstance<TerminalKeyword>();
		val3.noun.word = "deny";
		val3.noun.isVerb = true;
		if ((Object)(object)cancelPurchase == (Object)null)
		{
			cancelPurchase = ScriptableObject.CreateInstance<TerminalNode>();
		}
		val3.result = cancelPurchase;
		((Object)val3.result).name = "MoreSuitsCancelPurchase";
		val3.result.displayText = "Cancelled order.\n";
		newSuit.shopSelectionNode.terminalOptions = (CompatibleNoun[])(object)new CompatibleNoun[2] { val2, val3 };
		TerminalKeyword val4 = ScriptableObject.CreateInstance<TerminalKeyword>();
		((Object)val4).name = newSuit.unlockableName + "Suit";
		val4.word = newSuit.unlockableName.ToLower() + " suit";
		val4.defaultVerb = buyKeyword;
		CompatibleNoun val5 = new CompatibleNoun();
		val5.noun = val4;
		val5.result = newSuit.shopSelectionNode;
		List<CompatibleNoun> list = buyKeyword.compatibleNouns.ToList();
		list.Add(val5);
		buyKeyword.compatibleNouns = list.ToArray();
		List<TerminalKeyword> list2 = val.terminalNodes.allKeywords.ToList();
		list2.Add(val4);
		list2.Add(val2.noun);
		list2.Add(val3.noun);
		val.terminalNodes.allKeywords = list2.ToArray();
		return newSuit;
	}

	public static bool TryParseVector4(string input, out Vector4 vector)
	{
		//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_0051: 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)
		vector = Vector4.zero;
		string[] array = input.Split(',');
		if (array.Length == 4 && float.TryParse(array[0], out var result) && float.TryParse(array[1], out var result2) && float.TryParse(array[2], out var result3) && float.TryParse(array[3], out var result4))
		{
			vector = new Vector4(result, result2, result3, result4);
			return true;
		}
		return false;
	}
}