Decompiled source of UnemploymentMonitor v1.4.1

UnemploymentMonitor/UnemploymentMonitor.dll

Decompiled 10 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 Colossal.Collections;
using Colossal.Serialization.Entities;
using Colossal.UI.Binding;
using Game;
using Game.Citizens;
using Game.Common;
using Game.Companies;
using Game.SceneFlow;
using Game.Simulation;
using Game.Tools;
using Game.UI;
using HarmonyLib;
using HookUILib.Core;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using UnemploymentMonitor.ComponentTypes;
using UnemploymentMonitor.Configuration;
using UnemploymentMonitor.Systems;
using Unity.Burst;
using Unity.Burst.Intrinsics;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Scripting;

[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("UnemploymentMonitor")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyDescription("Unemployment monitor")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+4d3a0bacb7b0b409e0efecfbd2ce2d6b6f5436bb")]
[assembly: AssemblyProduct("UnemploymentMonitor")]
[assembly: AssemblyTitle("UnemploymentMonitor")]
[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 UnemploymentMonitor
{
	[BepInPlugin("UnemploymentMonitor", "UnemploymentMonitor", "1.0.0")]
	public class Plugin : BaseUnityPlugin
	{
		private void Awake()
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Expected O, but got Unknown
			((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin UnemploymentMonitor is loaded!");
			Harmony val = new Harmony("UnemploymentMonitor");
			val.PatchAll();
		}
	}
	public class UnemploymentUIExtension : UIExtension
	{
		public readonly string extensionID = "cities2modding.unemploymentmonitor";

		public readonly string extensionContent;

		public readonly ExtensionType extensionType = (ExtensionType)6;

		public UnemploymentUIExtension()
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			extensionContent = ((UIExtension)this).LoadEmbeddedResource("UnemploymentMonitor.Resources.ui.js");
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "UnemploymentMonitor";

		public const string PLUGIN_NAME = "UnemploymentMonitor";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace UnemploymentMonitor.Systems
{
	public class UnemploymentMonitorSystem : GameSystemBase
	{
		[BurstCompile]
		private struct CalculateUnderemploymentJob : IJobChunk
		{
			public EntityTypeHandle m_EntityType;

			public ComponentTypeHandle<Worker> m_WorkerType;

			public ComponentTypeHandle<Citizen> m_CitizenType;

			[ReadOnly]
			public ComponentLookup<Worker> m_Workers;

			[ReadOnly]
			public ComponentLookup<Citizen> m_Citizens;

			public ComponentLookup<UnderemployedWorker> m_UnderemployedWorkers;

			[ReadOnly]
			public SharedComponentTypeHandle<UpdateFrame> m_UpdateFrameType;

			public uint m_UpdateFrameIndex;

			public ParallelWriter m_CommandBuffer;

			public void Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
			{
				//IL_0003: 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_0029: Unknown result type (might be due to invalid IL or missing references)
				//IL_002e: Unknown result type (might be due to invalid IL or missing references)
				//IL_0033: Unknown result type (might be due to invalid IL or missing references)
				//IL_003b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0040: Unknown result type (might be due to invalid IL or missing references)
				//IL_0048: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: Unknown result type (might be due to invalid IL or missing references)
				//IL_0066: Unknown result type (might be due to invalid IL or missing references)
				//IL_006b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0071: Unknown result type (might be due to invalid IL or missing references)
				//IL_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_007f: Unknown result type (might be due to invalid IL or missing references)
				//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
				//IL_0096: Unknown result type (might be due to invalid IL or missing references)
				//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
				//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
				if (((ArchetypeChunk)(ref chunk)).GetSharedComponent<UpdateFrame>(m_UpdateFrameType).m_Index != m_UpdateFrameIndex)
				{
					return;
				}
				NativeArray<Entity> nativeArray = ((ArchetypeChunk)(ref chunk)).GetNativeArray(m_EntityType);
				NativeArray<Worker> nativeArray2 = ((ArchetypeChunk)(ref chunk)).GetNativeArray<Worker>(ref m_WorkerType);
				NativeArray<Citizen> nativeArray3 = ((ArchetypeChunk)(ref chunk)).GetNativeArray<Citizen>(ref m_CitizenType);
				for (int i = 0; i < nativeArray.Length; i++)
				{
					Entity val = nativeArray[i];
					Worker val2 = nativeArray2[i];
					Citizen val3 = nativeArray3[i];
					if (((Citizen)(ref val3)).GetEducationLevel() > val2.m_Level)
					{
						((ParallelWriter)(ref m_CommandBuffer)).AddComponent<UnderemployedWorker>(unfilteredChunkIndex, val, new UnderemployedWorker
						{
							m_EducationLevel = ((Citizen)(ref val3)).GetEducationLevel(),
							m_JobLevel = val2.m_Level
						});
					}
					else if (m_UnderemployedWorkers.HasComponent(val))
					{
						((ParallelWriter)(ref m_CommandBuffer)).RemoveComponent<UnderemployedWorker>(unfilteredChunkIndex, val);
					}
				}
			}

			void IJobChunk.Execute(in ArchetypeChunk chunk, int unfilteredChunkIndex, bool useEnabledMask, in v128 chunkEnabledMask)
			{
				Execute(in chunk, unfilteredChunkIndex, useEnabledMask, in chunkEnabledMask);
			}
		}

		private struct TypeHandle
		{
			public EntityTypeHandle __Unity_Entities_Entity_TypeHandle;

			[ReadOnly]
			public ComponentTypeHandle<Citizen> __Game_Citizens_Citizen_RO_ComponentTypeHandle;

			[ReadOnly]
			public ComponentTypeHandle<Worker> __Game_Citizens_Worker_RO_ComponentTypeHandle;

			[ReadOnly]
			public ComponentLookup<Worker> __Game_Citizens_Worker_RO_ComponentLookup;

			[ReadOnly]
			public ComponentLookup<Citizen> __Game_Citizens_Citizen_RO_ComponentLookup;

			public ComponentLookup<UnderemployedWorker> __UnemploymentMonitor_UnderemployedWorker_RW_ComponentLookup;

			public SharedComponentTypeHandle<UpdateFrame> __Game_Simulation_UpdateFrame_SharedComponentTypeHandle;

			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public void __AssignHandles(ref SystemState state)
			{
				//IL_0003: 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_0010: Unknown result type (might be due to invalid IL or missing references)
				//IL_0015: Unknown result type (might be due to invalid IL or missing references)
				//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_002a: Unknown result type (might be due to invalid IL or missing references)
				//IL_002f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0037: Unknown result type (might be due to invalid IL or missing references)
				//IL_003c: Unknown result type (might be due to invalid IL or missing references)
				//IL_0044: Unknown result type (might be due to invalid IL or missing references)
				//IL_0049: Unknown result type (might be due to invalid IL or missing references)
				//IL_0050: Unknown result type (might be due to invalid IL or missing references)
				//IL_0055: Unknown result type (might be due to invalid IL or missing references)
				__Unity_Entities_Entity_TypeHandle = ((SystemState)(ref state)).GetEntityTypeHandle();
				__Game_Citizens_Citizen_RO_ComponentTypeHandle = ((SystemState)(ref state)).GetComponentTypeHandle<Citizen>(true);
				__Game_Citizens_Worker_RO_ComponentTypeHandle = ((SystemState)(ref state)).GetComponentTypeHandle<Worker>(true);
				__Game_Citizens_Worker_RO_ComponentLookup = ((SystemState)(ref state)).GetComponentLookup<Worker>(true);
				__Game_Citizens_Citizen_RO_ComponentLookup = ((SystemState)(ref state)).GetComponentLookup<Citizen>(true);
				__UnemploymentMonitor_UnderemployedWorker_RW_ComponentLookup = ((SystemState)(ref state)).GetComponentLookup<UnderemployedWorker>(false);
				__Game_Simulation_UpdateFrame_SharedComponentTypeHandle = ((SystemState)(ref state)).GetSharedComponentTypeHandle<UpdateFrame>();
			}
		}

		private EntityQuery m_CreatedGroup;

		private ManualLogSource logger = new ManualLogSource("UnderemploymentSystem");

		public static readonly int kUpdatesPerDay = 16;

		private EndFrameBarrier m_EndFrameBarrier;

		private SimulationSystem m_SimulationSystem;

		private TypeHandle __TypeHandle;

		public int GetUnderemployedCount()
		{
			//IL_0003: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Expected O, but got Unknown
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_002f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			int num = 0;
			EntityQueryDesc val = new EntityQueryDesc();
			val.All = (ComponentType[])(object)new ComponentType[1] { ComponentType.ReadOnly<UnderemployedWorker>() };
			val.None = (ComponentType[])(object)new ComponentType[3]
			{
				ComponentType.ReadOnly<Deleted>(),
				ComponentType.ReadOnly<Destroyed>(),
				ComponentType.ReadOnly<Temp>()
			};
			EntityQueryDesc val2 = val;
			EntityQuery entityQuery = ((ComponentSystemBase)this).GetEntityQuery((EntityQueryDesc[])(object)new EntityQueryDesc[1] { val2 });
			return ((EntityQuery)(ref entityQuery)).CalculateEntityCount();
		}

		public override int GetUpdateInterval(SystemUpdatePhase phase)
		{
			return 262144 / (kUpdatesPerDay * 16);
		}

		[Preserve]
		protected override void OnCreate()
		{
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			//IL_004a: 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_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: 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_007a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			((GameSystemBase)this).OnCreate();
			Logger.Sources.Add((ILogSource)(object)logger);
			m_EndFrameBarrier = ((ComponentSystemBase)this).World.GetOrCreateSystemManaged<EndFrameBarrier>();
			m_SimulationSystem = ((ComponentSystemBase)this).World.GetOrCreateSystemManaged<SimulationSystem>();
			EntityQueryDesc val = new EntityQueryDesc();
			val.All = (ComponentType[])(object)new ComponentType[2]
			{
				ComponentType.ReadOnly<Worker>(),
				ComponentType.ReadOnly<Citizen>()
			};
			val.None = (ComponentType[])(object)new ComponentType[3]
			{
				ComponentType.ReadOnly<Deleted>(),
				ComponentType.ReadOnly<Destroyed>(),
				ComponentType.ReadOnly<Temp>()
			};
			EntityQueryDesc val2 = val;
			m_CreatedGroup = ((ComponentSystemBase)this).GetEntityQuery((EntityQueryDesc[])(object)new EntityQueryDesc[1] { val2 });
			((ComponentSystemBase)this).RequireForUpdate(m_CreatedGroup);
		}

		protected override void OnCreateForCompiler()
		{
			((ComponentSystemBase)this).OnCreateForCompiler();
			__AssignQueries(ref ((SystemBase)this).CheckedStateRef);
			__TypeHandle.__AssignHandles(ref ((SystemBase)this).CheckedStateRef);
		}

		[Preserve]
		protected override void OnUpdate()
		{
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0097: Unknown result type (might be due to invalid IL or missing references)
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0118: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_012b: Unknown result type (might be due to invalid IL or missing references)
			uint updateFrame = SimulationUtils.GetUpdateFrame(m_SimulationSystem.frameIndex, kUpdatesPerDay, 16);
			__TypeHandle.__Game_Citizens_Citizen_RO_ComponentLookup.Update(ref ((SystemBase)this).CheckedStateRef);
			__TypeHandle.__Game_Citizens_Worker_RO_ComponentLookup.Update(ref ((SystemBase)this).CheckedStateRef);
			__TypeHandle.__UnemploymentMonitor_UnderemployedWorker_RW_ComponentLookup.Update(ref ((SystemBase)this).CheckedStateRef);
			((EntityTypeHandle)(ref __TypeHandle.__Unity_Entities_Entity_TypeHandle)).Update(ref ((SystemBase)this).CheckedStateRef);
			CalculateUnderemploymentJob calculateUnderemploymentJob = default(CalculateUnderemploymentJob);
			calculateUnderemploymentJob.m_Citizens = __TypeHandle.__Game_Citizens_Citizen_RO_ComponentLookup;
			calculateUnderemploymentJob.m_Workers = __TypeHandle.__Game_Citizens_Worker_RO_ComponentLookup;
			calculateUnderemploymentJob.m_EntityType = __TypeHandle.__Unity_Entities_Entity_TypeHandle;
			calculateUnderemploymentJob.m_CitizenType = __TypeHandle.__Game_Citizens_Citizen_RO_ComponentTypeHandle;
			calculateUnderemploymentJob.m_WorkerType = __TypeHandle.__Game_Citizens_Worker_RO_ComponentTypeHandle;
			calculateUnderemploymentJob.m_UnderemployedWorkers = __TypeHandle.__UnemploymentMonitor_UnderemployedWorker_RW_ComponentLookup;
			EntityCommandBuffer val = ((SafeCommandBufferSystem)m_EndFrameBarrier).CreateCommandBuffer();
			calculateUnderemploymentJob.m_CommandBuffer = ((EntityCommandBuffer)(ref val)).AsParallelWriter();
			calculateUnderemploymentJob.m_UpdateFrameIndex = updateFrame;
			calculateUnderemploymentJob.m_UpdateFrameType = __TypeHandle.__Game_Simulation_UpdateFrame_SharedComponentTypeHandle;
			((SystemBase)this).Dependency = JobChunkExtensions.ScheduleParallel<CalculateUnderemploymentJob>(calculateUnderemploymentJob, m_CreatedGroup, ((SystemBase)this).Dependency);
		}

		[Preserve]
		protected override void OnDestroy()
		{
			((GameSystemBase)this).OnDestroy();
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		private void __AssignQueries(ref SystemState state)
		{
		}

		[Preserve]
		public UnemploymentMonitorSystem()
		{
		}//IL_0006: Unknown result type (might be due to invalid IL or missing references)
		//IL_0010: Expected O, but got Unknown

	}
	public class UnemploymentMonitorUISystem : UISystemBase
	{
		private const string kGroup = "unemploymentInfo";

		private CountEmploymentSystem m_CountEmploymentSystem;

		private UnemploymentMonitorSystem m_UnderemploymentSystem;

		private NativeArray<int> m_Results = new NativeArray<int>(5, (Allocator)4, (NativeArrayOptions)1);

		private EntityQuery m_HomelessHouseholdQuery;

		private EntityQuery m_EmployeesQuery;

		private readonly UnemploymentMonitorConfig _config = UnemploymentMonitorConfig.Load();

		private bool hasReloaded = false;

		private static FieldInfo m_Unemployed = typeof(CountEmploymentSystem).GetField("m_Unemployed", BindingFlags.Instance | BindingFlags.NonPublic);

		private static FieldInfo m_Adults = typeof(CountEmploymentSystem).GetField("m_Adults", BindingFlags.Instance | BindingFlags.NonPublic);

		private MonitoringData _currentData = default(MonitoringData);

		private MonitoringData _difference = default(MonitoringData);

		private float _lastResultClear;

		private float _lastResultTick;

		private List<MonitoringData> _results = new List<MonitoringData>(60);

		private bool hasNeverCapturedAverage = true;

		[Preserve]
		protected override void OnCreate()
		{
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Expected O, but got Unknown
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0172: Expected O, but got Unknown
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_0187: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_019f: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e6: Expected O, but got Unknown
			//IL_01ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0200: Unknown result type (might be due to invalid IL or missing references)
			//IL_0213: Unknown result type (might be due to invalid IL or missing references)
			//IL_0218: Unknown result type (might be due to invalid IL or missing references)
			//IL_021f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0224: Unknown result type (might be due to invalid IL or missing references)
			//IL_022b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0248: Unknown result type (might be due to invalid IL or missing references)
			//IL_024d: Unknown result type (might be due to invalid IL or missing references)
			//IL_025e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0263: Unknown result type (might be due to invalid IL or missing references)
			//IL_0422: Unknown result type (might be due to invalid IL or missing references)
			//IL_0428: Expected O, but got Unknown
			//IL_0430: Unknown result type (might be due to invalid IL or missing references)
			//IL_0435: Unknown result type (might be due to invalid IL or missing references)
			//IL_0445: Unknown result type (might be due to invalid IL or missing references)
			//IL_044a: Unknown result type (might be due to invalid IL or missing references)
			//IL_045a: Unknown result type (might be due to invalid IL or missing references)
			m_CountEmploymentSystem = ((ComponentSystemBase)this).World.GetOrCreateSystemManaged<CountEmploymentSystem>();
			m_UnderemploymentSystem = ((ComponentSystemBase)this).World.GetOrCreateSystemManaged<UnemploymentMonitorSystem>();
			((UISystemBase)this).OnCreate();
			JobHandle val11 = default(JobHandle);
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<int>("unemploymentInfo", "unemploymentTotal", (Func<int>)(() => m_CountEmploymentSystem.GetUnemployment(ref val11).value), (IWriter<int>)null, (EqualityComparer<int>)null));
			JobHandle val10 = default(JobHandle);
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<int>("unemploymentInfo", "unemploymentEducation0", (Func<int>)(() => m_CountEmploymentSystem.GetUnemploymentByEducation(ref val10)[0]), (IWriter<int>)null, (EqualityComparer<int>)null));
			JobHandle val9 = default(JobHandle);
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<int>("unemploymentInfo", "unemploymentEducation1", (Func<int>)(() => m_CountEmploymentSystem.GetUnemploymentByEducation(ref val9)[1]), (IWriter<int>)null, (EqualityComparer<int>)null));
			JobHandle val8 = default(JobHandle);
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<int>("unemploymentInfo", "unemploymentEducation2", (Func<int>)(() => m_CountEmploymentSystem.GetUnemploymentByEducation(ref val8)[2]), (IWriter<int>)null, (EqualityComparer<int>)null));
			JobHandle val7 = default(JobHandle);
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<int>("unemploymentInfo", "unemploymentEducation3", (Func<int>)(() => m_CountEmploymentSystem.GetUnemploymentByEducation(ref val7)[3]), (IWriter<int>)null, (EqualityComparer<int>)null));
			JobHandle val6 = default(JobHandle);
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<int>("unemploymentInfo", "unemploymentEducation4", (Func<int>)(() => m_CountEmploymentSystem.GetUnemploymentByEducation(ref val6)[4]), (IWriter<int>)null, (EqualityComparer<int>)null));
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<Vector2>("unemploymentInfo", "windowPos", (Func<Vector2>)(() => new Vector2((float)_config.X, (float)_config.Y)), (IWriter<Vector2>)null, (EqualityComparer<Vector2>)null));
			((UISystemBase)this).AddBinding((IBinding)(object)new TriggerBinding<double, double>("unemploymentInfo", "updateWindow", (Action<double, double>)delegate(double x, double y)
			{
				_config.X = (decimal)x;
				_config.Y = (decimal)y;
			}, (IReader<double>)null, (IReader<double>)null));
			((UISystemBase)this).AddBinding((IBinding)new TriggerBinding("unemploymentInfo", "saveConfig", (Action)delegate
			{
				_config.Save();
			}));
			EntityQueryDesc val = new EntityQueryDesc();
			val.All = (ComponentType[])(object)new ComponentType[2]
			{
				ComponentType.ReadOnly<Household>(),
				ComponentType.ReadOnly<HomelessHousehold>()
			};
			val.None = (ComponentType[])(object)new ComponentType[5]
			{
				ComponentType.ReadOnly<Deleted>(),
				ComponentType.ReadOnly<Destroyed>(),
				ComponentType.ReadOnly<Temp>(),
				ComponentType.ReadOnly<TouristHousehold>(),
				ComponentType.ReadOnly<CommuterHousehold>()
			};
			EntityQueryDesc val2 = val;
			val = new EntityQueryDesc();
			val.All = (ComponentType[])(object)new ComponentType[2]
			{
				ComponentType.ReadOnly<Employee>(),
				ComponentType.ReadOnly<Worker>()
			};
			val.None = (ComponentType[])(object)new ComponentType[3]
			{
				ComponentType.ReadOnly<Deleted>(),
				ComponentType.ReadOnly<Destroyed>(),
				ComponentType.ReadOnly<Temp>()
			};
			EntityQueryDesc val3 = val;
			m_HomelessHouseholdQuery = ((ComponentSystemBase)this).GetEntityQuery((EntityQueryDesc[])(object)new EntityQueryDesc[1] { val2 });
			m_EmployeesQuery = ((ComponentSystemBase)this).GetEntityQuery((EntityQueryDesc[])(object)new EntityQueryDesc[1] { val3 });
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<string>("unemploymentInfo", "homelessHouseholds", (Func<string>)(() => GetValueString(_currentData.HomelessHouseholds)), (IWriter<string>)null, (EqualityComparer<string>)null));
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<string>("unemploymentInfo", "underEmployed", (Func<string>)(() => GetValueString(_currentData.UnderEmployed)), (IWriter<string>)null, (EqualityComparer<string>)null));
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<string>("unemploymentInfo", "employable", (Func<string>)(() => GetValueString(_currentData.Employable)), (IWriter<string>)null, (EqualityComparer<string>)null));
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<string>("unemploymentInfo", "unemployed", (Func<string>)(() => GetValueString(_currentData.Unemployed)), (IWriter<string>)null, (EqualityComparer<string>)null));
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<string>("unemploymentInfo", "homelessHouseholdsDiff", (Func<string>)(() => GetDiffString(_difference.HomelessHouseholds)), (IWriter<string>)null, (EqualityComparer<string>)null));
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<string>("unemploymentInfo", "underEmployedDiff", (Func<string>)(() => GetDiffString(_difference.UnderEmployed)), (IWriter<string>)null, (EqualityComparer<string>)null));
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<string>("unemploymentInfo", "employableDiff", (Func<string>)(() => GetDiffString(_difference.Employable)), (IWriter<string>)null, (EqualityComparer<string>)null));
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<string>("unemploymentInfo", "unemployedDiff", (Func<string>)(() => GetDiffString(_difference.Unemployed)), (IWriter<string>)null, (EqualityComparer<string>)null));
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<int>("unemploymentInfo", "homelessHouseholdsVector", (Func<int>)(() => GetValueVector(_difference.HomelessHouseholds)), (IWriter<int>)null, (EqualityComparer<int>)null));
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<int>("unemploymentInfo", "underEmployedVector", (Func<int>)(() => GetValueVector(_difference.UnderEmployed)), (IWriter<int>)null, (EqualityComparer<int>)null));
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<int>("unemploymentInfo", "employableVector", (Func<int>)(() => GetValueVector(_difference.Employable)), (IWriter<int>)null, (EqualityComparer<int>)null));
			((UISystemBase)this).AddUpdateBinding((IUpdateBinding)(object)new GetterValueBinding<int>("unemploymentInfo", "unemployedVector", (Func<int>)(() => GetValueVector(_difference.Unemployed)), (IWriter<int>)null, (EqualityComparer<int>)null));
			InputAction val4 = new InputAction("UnemploymentMonitor_Toggle", (InputActionType)0, (string)null, (string)null, (string)null, (string)null);
			CompositeSyntax val5 = InputActionSetupExtensions.AddCompositeBinding(val4, "ButtonWithOneModifier", (string)null, (string)null);
			val5 = ((CompositeSyntax)(ref val5)).With("Modifier", "<Keyboard>/shift", (string)null, (string)null);
			((CompositeSyntax)(ref val5)).With("Button", "<Keyboard>/e", (string)null, (string)null);
			val4.performed += delegate
			{
				GameManager.instance.userInterface.view.View.ExecuteScript("window.dispatchEvent(new CustomEvent(\"hookui\", { detail: { type: \"toggle_visibility\", id: \"cities2modding.unemploymentmonitor\"}}));");
			};
			val4.Enable();
		}

		private void Capture()
		{
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: 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)
			_currentData.HomelessHouseholds = ((EntityQuery)(ref m_HomelessHouseholdQuery)).CalculateEntityCount();
			_currentData.UnderEmployed = m_UnderemploymentSystem.GetUnderemployedCount();
			_currentData.Employable = ((NativeValue<int>)m_Adults.GetValue(m_CountEmploymentSystem)).value;
			_currentData.Unemployed = ((NativeValue<int>)m_Unemployed.GetValue(m_CountEmploymentSystem)).value;
		}

		protected override void OnUpdate()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			((UISystemBase)this).OnUpdate();
			if (!GameModeExtensions.IsGame(((UISystemBase)this).gameMode))
			{
				return;
			}
			if (hasNeverCapturedAverage)
			{
				hasNeverCapturedAverage = false;
				Capture();
				_difference = default(MonitoringData);
			}
			if (!(Time.time >= _lastResultTick + 1f))
			{
				return;
			}
			_lastResultTick = Time.time;
			MonitoringData currentData = _currentData;
			Capture();
			_results.Add(CalculateDiff(_currentData, currentData));
			if (Time.time >= _lastResultClear + 15f)
			{
				_lastResultClear = Time.time;
				_difference = new MonitoringData
				{
					HomelessHouseholds = _results.Sum((MonitoringData r) => r.HomelessHouseholds),
					UnderEmployed = _results.Sum((MonitoringData r) => r.UnderEmployed),
					Employable = _results.Sum((MonitoringData r) => r.Employable),
					Unemployed = _results.Sum((MonitoringData r) => r.Unemployed)
				};
				_results.Clear();
			}
		}

		private MonitoringData CalculateDiff(MonitoringData a, MonitoringData b)
		{
			MonitoringData result = default(MonitoringData);
			result.HomelessHouseholds = a.HomelessHouseholds - b.HomelessHouseholds;
			result.Employable = a.Employable - b.Employable;
			result.UnderEmployed = a.UnderEmployed - b.UnderEmployed;
			result.Unemployed = a.Unemployed - b.Unemployed;
			return result;
		}

		private int GetValueVector(int diff)
		{
			return (diff > 0) ? 1 : ((diff < 0) ? (-1) : 0);
		}

		private string GetDiffString(int diff)
		{
			if (diff == 0)
			{
				return string.Empty;
			}
			string text = $"{diff:N0}";
			if (diff >= 1000000)
			{
				text = $"{diff / 1000000:N0}m";
			}
			if (diff >= 1000)
			{
				text = $"{diff / 1000:N0}k";
			}
			return (diff > 0) ? ("+" + text) : (text ?? "");
		}

		private string GetValueString(int value)
		{
			if (value == 0)
			{
				return string.Empty;
			}
			string result = $"{value:N0}";
			if (value >= 1000000)
			{
				decimal num = (decimal)value / 1000000m;
				result = ((num == (decimal)(int)num) ? num.ToString() : $"{num:N1}") + "m";
			}
			else if (value >= 1000)
			{
				decimal num2 = (decimal)value / 1000m;
				result = ((num2 == (decimal)(int)num2) ? num2.ToString() : $"{num2:N1}") + "k";
			}
			return result;
		}

		[Preserve]
		protected override void OnDestroy()
		{
			m_Results.Dispose();
			((UISystemBase)this).OnDestroy();
		}
	}
	public struct MonitoringData
	{
		public int HomelessHouseholds { get; set; }

		public int UnderEmployed { get; set; }

		public int Employable { get; set; }

		public int Unemployed { get; set; }
	}
}
namespace UnemploymentMonitor.Patches
{
	[HarmonyPatch]
	internal class Patches
	{
		[HarmonyPatch(typeof(SystemOrder))]
		public static class SystemOrderPatch
		{
			[HarmonyPatch("Initialize")]
			[HarmonyPostfix]
			public static void Postfix(UpdateSystem updateSystem)
			{
				updateSystem.UpdateAt<UnemploymentMonitorSystem>((SystemUpdatePhase)12);
				updateSystem.UpdateAt<UnemploymentMonitorUISystem>((SystemUpdatePhase)22);
			}
		}
	}
}
namespace UnemploymentMonitor.Configuration
{
	public abstract class ConfigBase
	{
		private static readonly JsonSerializerSettings _serializerSettings = new JsonSerializerSettings
		{
			NullValueHandling = (NullValueHandling)1,
			Formatting = (Formatting)1
		};

		protected abstract string ConfigFileName { get; }

		public virtual void Save()
		{
			string contents = JsonConvert.SerializeObject((object)this, _serializerSettings);
			string path = Path.Combine(GetAssemblyDirectory(), ConfigFileName);
			File.WriteAllText(path, contents);
		}

		public static T Load<T>() where T : ConfigBase, new()
		{
			T val = new T();
			string path = Path.Combine(GetAssemblyDirectory(), val.ConfigFileName);
			string text = "";
			if (File.Exists(path))
			{
				text = File.ReadAllText(path);
				return (T)JsonConvert.DeserializeObject(text, typeof(T), _serializerSettings);
			}
			return new T();
		}

		protected static string GetAssemblyDirectory()
		{
			return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
		}
	}
	public class UnemploymentMonitorConfig : ConfigBase
	{
		public decimal X { get; set; } = -1m;


		public decimal Y { get; set; } = -1m;


		protected override string ConfigFileName => "config.json";

		public static UnemploymentMonitorConfig Load()
		{
			UnemploymentMonitorConfig unemploymentMonitorConfig = ConfigBase.Load<UnemploymentMonitorConfig>();
			if (unemploymentMonitorConfig.X < 0m || unemploymentMonitorConfig.X > (decimal)Screen.width)
			{
				unemploymentMonitorConfig.X = Screen.width / 4;
			}
			if (unemploymentMonitorConfig.Y < 0m || unemploymentMonitorConfig.X > (decimal)Screen.height)
			{
				unemploymentMonitorConfig.Y = Screen.height / 4;
			}
			unemploymentMonitorConfig.Save();
			return unemploymentMonitorConfig;
		}
	}
}
namespace UnemploymentMonitor.ComponentTypes
{
	public struct UnderemployedWorker : IComponentData, IQueryTypeParameter, ISerializable
	{
		public int m_EducationLevel;

		public int m_JobLevel;

		public UnderemployedWorker(int educationLevel, int jobLevel)
		{
			m_EducationLevel = educationLevel;
			m_JobLevel = jobLevel;
		}

		public void Deserialize<TReader>(TReader reader) where TReader : IReader
		{
			((IReader)reader).Read(ref m_EducationLevel);
			((IReader)reader).Read(ref m_JobLevel);
		}

		public void Serialize<TWriter>(TWriter writer) where TWriter : IWriter
		{
			((IWriter)writer).Write(m_EducationLevel);
			((IWriter)writer).Write(m_JobLevel);
		}
	}
}