Decompiled source of Idle Worker Alerts v1.0.1

IdleNotify.dll

Decompiled 2 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 Eremite;
using Eremite.Buildings;
using Eremite.Characters;
using Eremite.Services;
using Eremite.Services.Monitors;
using HarmonyLib;
using UniRx;

[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.0", FrameworkDisplayName = "")]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyCompany("IdleNotify")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Idle Worker Notification Mod for Against The Storm")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("IdleNotify")]
[assembly: AssemblyTitle("IdleNotify")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.1.0")]
[module: UnverifiableCode]
namespace IdleNotify
{
	internal class IdleBuildingMonitor : GameMonitor
	{
		private Dictionary<ProductionBuilding, MonitorAlert> current = new Dictionary<ProductionBuilding, MonitorAlert>();

		private Dictionary<ProductionBuilding, float> queue = new Dictionary<ProductionBuilding, float>();

		public override bool IsEnabled()
		{
			return true;
		}

		public override void OnInit()
		{
			DisposableExtensions.AddTo<IDisposable>(ObservableExtensions.Subscribe<Building>(Observable.Where<Building>((IObservable<Building>)Serviceable.GameBlackboardService.FinishedBuildingRemoved, (Func<Building, bool>)((Building building) => building is ProductionBuilding)), (Action<Building>)ProductionBuildingRemoved), (ICollection<IDisposable>)base.disposables);
		}

		private void ProductionBuildingRemoved(Building building)
		{
			ProductionBuilding building2 = (ProductionBuilding)(object)((building is ProductionBuilding) ? building : null);
			if (IsShowing(building2))
			{
				HideAlert(building2);
			}
		}

		public override void OnSlowUpdate()
		{
			foreach (ProductionBuilding productionBuilding in Serviceable.BuildingsService.ProductionBuildings)
			{
				if (((Building)productionBuilding).IsFinished())
				{
					UpdateBuilding(productionBuilding);
				}
			}
		}

		private void UpdateBuilding(ProductionBuilding building)
		{
			CheckForDequeue(building);
			CheckForQueue(building);
			CheckForHiding(building);
			CheckForShowing(building);
		}

		private void CheckForDequeue(ProductionBuilding building)
		{
			if (IsQueued(building) && !IsBuildingIdle(building))
			{
				queue.Remove(building);
			}
		}

		private void CheckForQueue(ProductionBuilding building)
		{
			if (!IsShowing(building) && !IsQueued(building) && IsBuildingIdle(building))
			{
				queue.Add(building, Serviceable.GameTime);
			}
		}

		private void CheckForHiding(ProductionBuilding building)
		{
			if (IsShowing(building) && (!((GameMonitor)this).IsEnabled() || !IsBuildingIdle(building)))
			{
				HideAlert(building);
			}
		}

		private void CheckForShowing(ProductionBuilding building)
		{
			if (!IsShowing(building) && IsQueued(building) && ((GameMonitor)this).IsEnabled() && ShouldShow(building))
			{
				ShowAlert(building, CreateAlert(building));
			}
		}

		private void ShowAlert(ProductionBuilding building, MonitorAlert alert)
		{
			current.Add(building, alert);
			((GameMonitor)this).AddAlert(alert);
		}

		private void HideAlert(ProductionBuilding building)
		{
			((GameMonitor)this).RemoveAlert(current[building]);
			current.Remove(building);
		}

		private MonitorAlert CreateAlert(ProductionBuilding building)
		{
			//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_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			return new MonitorAlert
			{
				severity = (AlertSeverity)2,
				text = $"Worker idle in {((Building)building).BuildingModel.displayName}",
				description = $"At least one worker is idle in your {((Building)building).BuildingModel.displayName}. Click here to go to it.",
				showTime = ((GameMonitor)this).GetShowTime(),
				clickCallback = OnAlertClicked
			};
		}

		private void OnAlertClicked(MonitorAlert alert)
		{
			Focus(current.First((KeyValuePair<ProductionBuilding, MonitorAlert> a) => a.Value == alert).Key);
		}

		private void Focus(ProductionBuilding building)
		{
			Serviceable.GameInputService.Focus((IMapObject)(object)building, true);
		}

		private bool IsShowing(ProductionBuilding building)
		{
			return current.ContainsKey(building);
		}

		private bool IsBuildingIdle(ProductionBuilding building)
		{
			return building.IsBuildingIdle();
		}

		private bool IsQueued(ProductionBuilding building)
		{
			return queue.ContainsKey(building);
		}

		private bool ShouldShow(ProductionBuilding building)
		{
			return Serviceable.GameTime - queue[building] >= 0f;
		}
	}
	[BepInPlugin("IdleNotify", "IdleNotify", "1.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		public static Plugin Instance;

		private Harmony harmony;

		public static void Log(string str)
		{
			((BaseUnityPlugin)Instance).Logger.LogInfo((object)str);
		}

		private void Awake()
		{
			Instance = this;
			harmony = Harmony.CreateAndPatchAll(typeof(Plugin), (string)null);
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin IdleNotify is loaded!");
		}

		[HarmonyPatch(typeof(MonitorsService), "CreateMonitors")]
		[HarmonyPostfix]
		private static void MonitorsService_CreateMonitors_Postfix(MonitorsService __instance)
		{
			__instance.monitors = __instance.monitors.Concat((IEnumerable<GameMonitor>)(object)new GameMonitor[1]
			{
				new IdleBuildingMonitor()
			}).ToArray();
		}

		[HarmonyPatch(typeof(ProductionBuilding), "IsBuildingIdle")]
		[HarmonyPrefix]
		private static bool ProductionBuilding_IsBuildingIdle_Prefix(ProductionBuilding __instance, ref bool __result)
		{
			bool flag = false;
			int[] workers = __instance.Workers;
			foreach (int num in workers)
			{
				if (GameMB.ActorsService.HasActor(num))
				{
					Actor actor = GameMB.ActorsService.GetActor(num);
					if (!actor.IsBoundToWorkplace && !actor.ActorState.isWorking)
					{
						flag = true;
						break;
					}
				}
			}
			if (!flag)
			{
				__instance.ProductionBuildingState.idleTime = 0f;
				__result = false;
				return false;
			}
			ProductionBuildingState productionBuildingState = __instance.ProductionBuildingState;
			productionBuildingState.idleTime += ((Building)__instance).GetSlowDeltaTime();
			__result = __instance.ProductionBuildingState.idleTime > 0.2f;
			return false;
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "IdleNotify";

		public const string PLUGIN_NAME = "IdleNotify";

		public const string PLUGIN_VERSION = "1.0.1";
	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
}