Decompiled source of VmailAttachments v1.0.0

plugins/VmailAttachments.dll

Decompiled a year 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 System.Security;
using System.Security.Permissions;
using System.Text.Json;
using System.Threading.Tasks;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppSystem;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using SOD.Common;
using SOD.Common.BepInEx;
using SOD.Common.Helpers;
using TMPro;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("VmailAttachments")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("My first plugin")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("VmailAttachments")]
[assembly: AssemblyTitle("VmailAttachments")]
[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 VmailAttachments
{
	public class AttachmentButton : MonoBehaviour
	{
		private VMailApp _app;

		private AttachmentButtonHandler _handler;

		private Button _button;

		private TextMeshProUGUI _label;

		private bool _currentAttachmentExists = false;

		private string _currentAttachmentInteractablePresetName = string.Empty;

		private int _currentAttachmentWriterID = -1;

		private int _currentAttachmentReceiverID = -1;

		private void Awake()
		{
			NukeAutoTextController();
			SetupLabel();
			SetupButton();
		}

		private void OnEnable()
		{
			AddButtonListeners();
		}

		private void OnDisable()
		{
			RemoveButtonListeners();
		}

		public void Initialize(VMailApp app, Component handlerComponent)
		{
			_app = app;
			if (handlerComponent is AttachmentButtonHandler handler)
			{
				_handler = handler;
			}
			SetCurrentAttachment(exists: false);
		}

		private void NukeAutoTextController()
		{
			ComputerAutoTextController componentInChildren = ((Component)this).gameObject.GetComponentInChildren<ComputerAutoTextController>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				Object.DestroyImmediate((Object)(object)componentInChildren);
			}
			else
			{
				Utilities.Log("AttachmentButton.NukeAutoTextController: Expected autoTextController but it was null.", (LogLevel)32);
			}
		}

		private void SetupLabel()
		{
			_label = ((Component)this).gameObject.GetComponentInChildren<TextMeshProUGUI>();
			if ((Object)(object)_label != (Object)null)
			{
				((TMP_Text)_label).text = "Attached";
				((TMP_Text)_label).overflowMode = (TextOverflowModes)0;
				((TMP_Text)_label).enableWordWrapping = false;
			}
			else
			{
				Utilities.Log("AttachmentButton.SetupLabel: Expected textMeshPro but it was null.", (LogLevel)32);
			}
		}

		private void SetupButton()
		{
			_button = ((Component)this).gameObject.GetComponentInChildren<Button>();
			if ((Object)(object)_button == (Object)null)
			{
				Utilities.Log("AttachmentButton.SetupButton: Expected attachmentButton but it was null.", (LogLevel)32);
			}
		}

		private void RemoveButtonListeners()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Expected O, but got Unknown
			if ((Object)(object)_button != (Object)null)
			{
				_button.onClick = new ButtonClickedEvent();
			}
		}

		private void AddButtonListeners()
		{
			RemoveButtonListeners();
			if ((Object)(object)_button != (Object)null)
			{
				Action action = OnAttachmentButtonClicked;
				((UnityEvent)_button.onClick).AddListener(UnityAction.op_Implicit(action));
			}
		}

		private void OnAttachmentButtonClicked()
		{
			VMailApp app = _app;
			PrintCurrentDatabaseEntry((app != null) ? ((CruncherAppContent)app).controller : null);
		}

		private void PrintCurrentDatabaseEntry(ComputerController currentCruncher)
		{
			//IL_016d: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			if (_currentAttachmentExists)
			{
				if ((Object)(object)currentCruncher == (Object)null)
				{
					Utilities.Log("AttachmentButton.PrintCurrentDatabaseEntry: Tried to print an attachment, but not at a computer!", (LogLevel)32);
				}
				else if (currentCruncher.printedDocument == null && currentCruncher.printTimer <= 0f)
				{
					currentCruncher.printTimer = 1f;
					Vector3 localPosition = currentCruncher.printerParent.localPosition;
					currentCruncher.printerParent.localPosition = new Vector3(localPosition.x, localPosition.y, -0.05f);
					AudioController.Instance.PlayWorldOneShot(AudioControls.Instance.computerPrint, (Actor)(object)Player.Instance, currentCruncher.ic.interactable.node, currentCruncher.ic.interactable.wPos, (Interactable)null, (List<FMODParam>)null, 1f, (List<NewNode>)null, false, (SoundMaterialOverride)null, false);
					currentCruncher.printedDocument = CreateAttachmentDocument(currentCruncher.printerParent.position, ((Component)currentCruncher.ic).transform.eulerAngles);
					Action action = ((CruncherAppContent)_app).OnPlayerTakePrint;
					Interactable printedDocument = currentCruncher.printedDocument;
					printedDocument.OnRemovedFromWorld += RemovedFromWorld.op_Implicit(action);
					Utilities.Log("AttachmentButton.PrintCurrentDatabaseEntry: Successfully printed an attachment!", (LogLevel)32);
				}
				else
				{
					AudioController.Instance.PlayWorldOneShot(AudioControls.Instance.computerInvalidPasscode, (Actor)(object)Player.Instance, currentCruncher.ic.interactable.node, currentCruncher.ic.interactable.wPos, (Interactable)null, (List<FMODParam>)null, 1f, (List<NewNode>)null, false, (SoundMaterialOverride)null, false);
					Utilities.Log("AttachmentButton.PrintCurrentDatabaseEntry: Tried to print an attachment, but the print cooldown isn't done!", (LogLevel)32);
				}
			}
		}

		public void SetCurrentAttachment(bool exists, string interactablePresetName = "", int writerID = -1, int receiverID = -1)
		{
			_currentAttachmentExists = exists;
			_currentAttachmentInteractablePresetName = interactablePresetName;
			_currentAttachmentWriterID = writerID;
			_currentAttachmentReceiverID = receiverID;
		}

		private InteractablePreset GetInteractablePreset()
		{
			return Toolbox.Instance.GetInteractablePreset(_currentAttachmentInteractablePresetName);
		}

		private Human GetWriterHuman()
		{
			return (Human)(object)CityData.Instance.citizenDirectory.Find(Predicate<Citizen>.op_Implicit((Func<Citizen, bool>)FindWriterPredicate));
		}

		private Human GetReceiverHuman()
		{
			return (Human)(object)CityData.Instance.citizenDirectory.Find(Predicate<Citizen>.op_Implicit((Func<Citizen, bool>)FindReceiverPredicate));
		}

		private bool FindWriterPredicate(Citizen item)
		{
			return ((Human)item).humanID == _currentAttachmentWriterID;
		}

		private bool FindReceiverPredicate(Citizen item)
		{
			return ((Human)item).humanID == _currentAttachmentReceiverID;
		}

		private Interactable CreateAttachmentDocument(Vector3 worldPosition, Vector3 worldRotation)
		{
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			Interactable val = InteractableCreator.Instance.CreateWorldInteractable(GetInteractablePreset(), (Human)(object)Player.Instance, GetWriterHuman(), GetReceiverHuman(), worldPosition, worldRotation, (List<Passed>)null, (Object)null, "");
			if (val != null)
			{
				val.MarkAsTrash(true, false, 0f);
			}
			return val;
		}
	}
	public class AttachmentButtonHandler : MonoBehaviour
	{
		public static Action<VMailApp, MessageThreadSave> OnVmailSelected;

		private VMailApp _app;

		private AttachmentButton _button;

		private void OnEnable()
		{
			RefreshCurrentAppState();
			OnVmailSelected = (Action<VMailApp, MessageThreadSave>)Delegate.Remove(OnVmailSelected, new Action<VMailApp, MessageThreadSave>(OnVmailSelection));
			OnVmailSelected = (Action<VMailApp, MessageThreadSave>)Delegate.Combine(OnVmailSelected, new Action<VMailApp, MessageThreadSave>(OnVmailSelection));
		}

		private void OnDisable()
		{
			OnVmailSelected = (Action<VMailApp, MessageThreadSave>)Delegate.Remove(OnVmailSelected, new Action<VMailApp, MessageThreadSave>(OnVmailSelection));
		}

		public void Initialize(VMailApp app)
		{
			_app = app;
			_button = FindOrCreateButton();
			_button.Initialize(app, (Component)(object)this);
			RefreshCurrentAppState();
		}

		private void RefreshCurrentAppState()
		{
			if ((Object)(object)_app != (Object)null)
			{
				VMailApp app = _app;
				VMailApp app2 = _app;
				OnVmailSelection(app, (app2 != null) ? app2.selectedThread : null);
			}
		}

		private void OnVmailSelection(VMailApp app, MessageThreadSave vmail)
		{
			if ((Object)(object)app == (Object)(object)_app)
			{
				CheckButtonVisibility(vmail);
			}
		}

		private void CheckButtonVisibility(MessageThreadSave vmail)
		{
			AttachmentDatabaseEntry attachment;
			if (vmail == null)
			{
				_button.SetCurrentAttachment(exists: false);
				((Component)_button).gameObject.SetActive(false);
			}
			else if (VmailAttachmentsPlugin.TryGetAttachment(vmail.threadID, out attachment))
			{
				_button.SetCurrentAttachment(exists: true, attachment.InteractablePresetName, attachment.WriterID, attachment.ReceiverID);
				((Component)_button).gameObject.SetActive(true);
			}
			else
			{
				_button.SetCurrentAttachment(exists: false);
				((Component)_button).gameObject.SetActive(false);
			}
		}

		private AttachmentButton FindOrCreateButton()
		{
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
			AttachmentButton componentInChildren = ((Component)this).gameObject.GetComponentInChildren<AttachmentButton>();
			if ((Object)(object)componentInChildren != (Object)null)
			{
				return componentInChildren;
			}
			Button val = null;
			foreach (Button componentsInChild in ((Component)this).gameObject.GetComponentsInChildren<Button>())
			{
				if (((Object)((Component)componentsInChild).gameObject).name != "Print")
				{
					continue;
				}
				val = componentsInChild;
				break;
			}
			if ((Object)(object)val == (Object)null)
			{
				Utilities.Log("AttachmentButtonHandler.FindOrCreateButton: Needed to create attachment button but print button doesn't exist!", (LogLevel)32);
				return null;
			}
			GameObject gameObject = ((Component)val).gameObject;
			GameObject val2 = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent);
			Vector3 localPosition = val2.transform.localPosition;
			val2.transform.localPosition = new Vector3(localPosition.x, localPosition.y + 0.06f, localPosition.z);
			return val2.AddComponent<AttachmentButton>();
		}
	}
	[HarmonyPatch]
	public class VmailSelectionPatch
	{
		[HarmonyPatch(typeof(VMailApp), "SetSelectedVmail")]
		private static void Postfix(VMailApp __instance)
		{
			Utilities.Log("VmailSelectionPatch.Postfix: Triggered!", (LogLevel)32);
			AttachmentButtonHandler.OnVmailSelected?.Invoke(__instance, (__instance != null) ? __instance.selectedThread : null);
		}
	}
	[HarmonyPatch]
	public class VmailSetupPatch
	{
		[HarmonyPatch(typeof(VMailApp), "OnSetup")]
		private static void Postfix(VMailApp __instance)
		{
			Utilities.Log("VmailSetupPatch.Postfix: Triggered!", (LogLevel)32);
			GameObject gameObject = ((Component)__instance).gameObject;
			AttachmentButtonHandler attachmentButtonHandler = gameObject.GetComponent<AttachmentButtonHandler>() ?? gameObject.AddComponent<AttachmentButtonHandler>();
			attachmentButtonHandler.Initialize(__instance);
		}
	}
	[Serializable]
	public class AttachmentDatabase
	{
		public Dictionary<int, AttachmentDatabaseEntry> Database = new Dictionary<int, AttachmentDatabaseEntry>();
	}
	[Serializable]
	public class AttachmentDatabaseEntry
	{
		public string InteractablePresetName;

		public int WriterID;

		public int ReceiverID;

		public override string ToString()
		{
			return $"AttachmentDatabaseEntry: {InteractablePresetName}, {WriterID}, {ReceiverID}";
		}
	}
	public static class Utilities
	{
		public const bool DEBUG_BUILD = false;

		public static void Log(string message, LogLevel level = 16)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0004: Invalid comparison between Unknown and I4
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			if ((int)level == 32)
			{
				bool flag = false;
			}
			else
			{
				PluginController<VmailAttachmentsPlugin, IEmptyBindings>.Log.Log(level, (object)message);
			}
		}
	}
	[BepInPlugin("VmailAttachments", "VmailAttachments", "1.0.0")]
	public class VmailAttachmentsPlugin : PluginController<VmailAttachmentsPlugin>
	{
		private static AttachmentDatabase _db = new AttachmentDatabase();

		public override void Load()
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			Utilities.Log("Plugin VmailAttachments is loaded!", (LogLevel)16);
			Harmony val = new Harmony("VmailAttachments");
			val.PatchAll();
			Utilities.Log("Plugin VmailAttachments is patched!", (LogLevel)16);
			ClassInjector.RegisterTypeInIl2Cpp<AttachmentButton>();
			ClassInjector.RegisterTypeInIl2Cpp<AttachmentButtonHandler>();
			Utilities.Log("Plugin VmailAttachments has added custom types!", (LogLevel)16);
			Lib.SaveGame.OnAfterSave -= OnAfterSave;
			Lib.SaveGame.OnAfterSave += OnAfterSave;
			Lib.SaveGame.OnAfterLoad -= OnAfterLoad;
			Lib.SaveGame.OnAfterLoad += OnAfterLoad;
			Lib.SaveGame.OnAfterNewGame -= OnAfterNewGame;
			Lib.SaveGame.OnAfterNewGame += OnAfterNewGame;
		}

		public override bool Unload()
		{
			Lib.SaveGame.OnAfterSave -= OnAfterSave;
			Lib.SaveGame.OnAfterLoad -= OnAfterLoad;
			Lib.SaveGame.OnAfterNewGame -= OnAfterNewGame;
			return ((PluginController<VmailAttachmentsPlugin, IEmptyBindings>)(object)this).Unload();
		}

		public static void AddAttachment(int vmailID, string preset, int writer, int receiver)
		{
			AttachmentDatabaseEntry attachmentDatabaseEntry = new AttachmentDatabaseEntry
			{
				InteractablePresetName = preset,
				WriterID = writer,
				ReceiverID = receiver
			};
			_db.Database[vmailID] = attachmentDatabaseEntry;
			Utilities.Log($"VmailAttachmentsPlugin.AddAttachment: Added {attachmentDatabaseEntry.ToString()} to vmail {vmailID}!", (LogLevel)32);
		}

		public static void AddAttachment(MessageThreadSave vmail, InteractablePreset preset, Human writer, Human receiver)
		{
			AddAttachment(vmail.threadID, ((SoCustomComparison)preset).presetName, writer.humanID, receiver.humanID);
		}

		public static bool TryGetAttachment(int vmailID, out AttachmentDatabaseEntry attachment)
		{
			bool result = _db.Database.TryGetValue(vmailID, out attachment);
			if (attachment != null)
			{
				Utilities.Log($"VmailAttachmentsPlugin.TryGetAttachment: Vmail {vmailID}...found {attachment.ToString()}!", (LogLevel)32);
			}
			else
			{
				Utilities.Log($"VmailAttachmentsPlugin.TryGetAttachment: Vmail {vmailID}...found NULL!", (LogLevel)32);
			}
			return result;
		}

		private void OnAfterSave(object sender, SaveGameArgs args)
		{
			SaveToJsonAsync(args.FilePath);
		}

		private void OnAfterLoad(object sender, SaveGameArgs args)
		{
			LoadFromJsonAsync(args.FilePath);
		}

		private void OnAfterNewGame(object sender, EventArgs args)
		{
			_db = new AttachmentDatabase();
			Utilities.Log("VmailAttachmentsPlugin.OnAfterNewGame: Initializing new attachment database!", (LogLevel)16);
		}

		private static string GetPluginSavePath(string savePath)
		{
			string uniqueString = Lib.SaveGame.GetUniqueString(savePath);
			string text = "VmailAttachments_" + uniqueString + ".json";
			return Lib.SaveGame.GetSavestoreDirectoryPath(Assembly.GetExecutingAssembly(), text);
		}

		private async Task SaveToJsonAsync(string savePath)
		{
			if (_db == null)
			{
				Utilities.Log("VmailAttachmentsPlugin.OnAfterSave: Cannot save a null map.", (LogLevel)2);
				return;
			}
			string pluginPath = GetPluginSavePath(savePath);
			try
			{
				string json = JsonSerializer.Serialize(options: new JsonSerializerOptions
				{
					IncludeFields = true
				}, value: _db);
				await File.WriteAllTextAsync(pluginPath, json);
				Utilities.Log($"VmailAttachmentsPlugin.OnAfterSave: Successfully saved {_db.Database.Count} attachments to database at {pluginPath}!", (LogLevel)16);
			}
			catch (Exception e)
			{
				Utilities.Log("VmailAttachmentsPlugin.OnAfterSave: " + e.Message, (LogLevel)2);
			}
		}

		private async Task LoadFromJsonAsync(string savePath)
		{
			string pluginPath = GetPluginSavePath(savePath);
			try
			{
				_db = JsonSerializer.Deserialize<AttachmentDatabase>(options: new JsonSerializerOptions
				{
					IncludeFields = true
				}, json: await File.ReadAllTextAsync(pluginPath));
				Utilities.Log($"VmailAttachmentsPlugin.OnAfterLoad: Successfully loaded {_db.Database.Count} attachments from database at {pluginPath}!", (LogLevel)16);
			}
			catch (Exception ex)
			{
				Exception e = ex;
				_db = new AttachmentDatabase();
				Utilities.Log("VmailAttachmentsPlugin.OnAfterLoad: " + e.Message, (LogLevel)2);
			}
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "VmailAttachments";

		public const string PLUGIN_NAME = "VmailAttachments";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}