Decompiled source of LethalScanCommand v1.0.0

baer1.LethalScanCommand.dll

Decompiled a week 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.Configuration;
using BepInEx.Logging;
using ChatCommandAPI;
using GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Unity.Netcode;
using UnityEngine;

[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("baer1.LethalScanCommand")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+35ff2fe81b2e3ae681d50b380938229fbdfffc10")]
[assembly: AssemblyProduct("LethalScanCommand")]
[assembly: AssemblyTitle("baer1.LethalScanCommand")]
[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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableAttribute : Attribute
	{
		public readonly byte[] NullableFlags;

		public NullableAttribute(byte P_0)
		{
			NullableFlags = new byte[1] { P_0 };
		}

		public NullableAttribute(byte[] P_0)
		{
			NullableFlags = P_0;
		}
	}
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
	internal sealed class NullableContextAttribute : Attribute
	{
		public readonly byte Flag;

		public NullableContextAttribute(byte P_0)
		{
			Flag = P_0;
		}
	}
	[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 LethalScanCommand
{
	[BepInPlugin("baer1.LethalScanCommand", "LethalScanCommand", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class LethalScanCommand : BaseUnityPlugin
	{
		public enum ApproximateValueOnCruiserOptions
		{
			Never,
			UnMagneted,
			Always
		}

		[HarmonyPatch(typeof(StartOfRound), "openingDoorsSequence")]
		internal class AutoAnnouncePatch
		{
			private static void Postfix(ref StartOfRound __instance)
			{
				Logger.LogDebug((object)$">> AutoAnnouncePatch({__instance}) IsServer:{((NetworkBehaviour)__instance).IsServer} AutoAnnounceOutside:{AutoAnnounceOutside}");
				if (!((NetworkBehaviour)__instance).IsServer || !AutoAnnounceOutside)
				{
					return;
				}
				if (ScanCommand.Countitems(out string error, out int _, out int _, out int _, out int _, out int _, out int _, out int _, out int _, out int _, out int outsideShip, out int outsideShipBees, out int _, out bool _))
				{
					Logger.LogInfo((object)$"{outsideShip} {outsideShipBees}");
					if (outsideShip > 0 || outsideShipBees > 0)
					{
						HUDManager.Instance.AddTextMessageServerRpc($"<color=#00ff00>{outsideShip} {outsideShipBees}</color>");
					}
				}
				else
				{
					Logger.LogError((object)("Error while counting items: " + error));
					HUDManager.Instance.AddTextMessageServerRpc("<color=#ff0000>Error while counting items: " + error + "</color>");
				}
			}
		}

		private ConfigEntry<bool>? approximateValueInShip;

		private ConfigEntry<bool>? approximateValueOnShip;

		private ConfigEntry<ApproximateValueOnCruiserOptions>? approximateValueOnCruiser;

		private ConfigEntry<bool>? approximateValueOutsideShip;

		private ConfigEntry<bool>? compactResponse;

		private ConfigEntry<bool>? autoAnnounceOutside;

		public static LethalScanCommand Instance { get; private set; }

		internal static ManualLogSource Logger { get; private set; }

		internal static Harmony? Harmony { get; set; }

		public static bool ApproximateValueInShip => (Object)(object)Instance != (Object)null && (Instance.approximateValueInShip?.Value ?? false);

		public static bool ApproximateValueOnShip => (Object)(object)Instance != (Object)null && (Instance.approximateValueOnShip?.Value ?? false);

		public static ApproximateValueOnCruiserOptions ApproximateValueOnCruiser => ((Object)(object)Instance == (Object)null || Instance.approximateValueOnCruiser == null) ? ApproximateValueOnCruiserOptions.UnMagneted : Instance.approximateValueOnCruiser.Value;

		public static bool ApproximateValueOutsideShip
		{
			get
			{
				bool flag = (Object)(object)Instance == (Object)null;
				bool flag2 = flag;
				if (!flag2)
				{
					ConfigEntry<bool> val = Instance.approximateValueOutsideShip;
					bool flag3 = ((val == null || val.Value) ? true : false);
					flag2 = flag3;
				}
				return flag2;
			}
		}

		public static bool CompactResponse
		{
			get
			{
				bool flag = (Object)(object)Instance == (Object)null;
				bool flag2 = flag;
				if (!flag2)
				{
					ConfigEntry<bool> val = Instance.compactResponse;
					bool flag3 = ((val == null || val.Value) ? true : false);
					flag2 = flag3;
				}
				return flag2;
			}
		}

		public static bool AutoAnnounceOutside => (Object)(object)Instance != (Object)null && (Instance.autoAnnounceOutside?.Value ?? false);

		private void Awake()
		{
			//IL_00ec: 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_00f7: Expected O, but got Unknown
			Logger = ((BaseUnityPlugin)this).Logger;
			Instance = this;
			approximateValueInShip = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ApproximateValueInShip", false, "Whether to approximate the value of the items inside the ship");
			approximateValueOnShip = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ApproximateValueOnShip", false, "Whether to approximate the value of the items on the ship (not collected)");
			approximateValueOnCruiser = ((BaseUnityPlugin)this).Config.Bind<ApproximateValueOnCruiserOptions>("General", "ApproximateValueOnCruiser", ApproximateValueOnCruiserOptions.UnMagneted, "When to approximate the value of the items on the company cruiser");
			approximateValueOutsideShip = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "ApproximateValueOutsideShip", true, "Whether to approximate the value of the items outside the ship (not collected)");
			compactResponse = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "CompactResponse", true, "Whether to reply with a short summary or a complete sentence");
			autoAnnounceOutside = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AutoAnnounceOutside", false, "Automatically announces the amount of items and beehives outside when a round starts");
			new ScanCommand();
			if (Harmony == null)
			{
				Harmony = new Harmony("baer1.LethalScanCommand");
			}
			Logger.LogDebug((object)"Patching...");
			Harmony.PatchAll();
			Logger.LogDebug((object)"Finished patching!");
			Logger.LogInfo((object)"baer1.LethalScanCommand v1.0.0 has loaded!");
		}
	}
	public class ScanCommand : ServerCommand
	{
		public override string[] Commands => new string[2]
		{
			"scan",
			((ServerCommand)this).Name
		};

		public override string Description => "Scans for items in- or outside the ship";

		public override bool Invoke(ref PlayerControllerB? caller, string[] args, Dictionary<string, string> kwargs, out string? error)
		{
			error = "caller is null";
			if ((Object)(object)caller == (Object)null || !GetString(out string text, out error, LethalScanCommand.CompactResponse))
			{
				return false;
			}
			ChatCommandAPI.Print(caller, text);
			return true;
		}

		public static bool GetString(out string text, out string? error, bool compact = true)
		{
			text = string.Empty;
			LethalScanCommand.Logger.LogDebug((object)$">> GetString(compact:{compact})");
			if (!Countitems(out error, out var inShip, out var inShipBees, out var inShipValue, out var onShip, out var onShipBees, out var onShipValue, out var onCruiser, out var onCruiserBees, out var onCruiserValue, out var outsideShip, out var outsideShipBees, out var outsideShipValue, out var carValueApproximated))
			{
				LethalScanCommand.Logger.LogDebug((object)("<< CountItems returned false error:" + error));
				return false;
			}
			if (compact)
			{
				List<string> list2 = new List<string>();
				if (inShip > 0 || inShipBees > 0)
				{
					list2.Add($"In ship: {inShip}/{inShipBees} items worth {c(LethalScanCommand.ApproximateValueInShip, inShipValue)}");
				}
				if (onShip > 0 || onShipBees > 0)
				{
					list2.Add($"On ship: {onShip}/{onShipBees} items worth {c(LethalScanCommand.ApproximateValueOnShip, onShipValue)}");
				}
				if (onCruiser > 0 || onCruiserBees > 0)
				{
					list2.Add($"On cruiser: {onCruiser}/{onCruiserBees} items worth {c(carValueApproximated, onCruiserValue)}");
				}
				if (!StartOfRound.Instance.inShipPhase)
				{
					list2.Add(string.Format("Outside ship: {0}/{1} items{2}", outsideShip, outsideShipBees, (outsideShip > 0 || outsideShipBees > 0) ? (" worth " + c(LethalScanCommand.ApproximateValueOutsideShip, outsideShipValue)) : string.Empty));
				}
				LethalScanCommand.Logger.LogDebug((object)("   lines:" + d(list2)));
				text = ((list2.Count == 0) ? "No items" : GeneralExtensions.Join<string>((IEnumerable<string>)list2, (Func<string, string>)null, "\n"));
			}
			else
			{
				List<string> list3 = new List<string>();
				int first2 = 0;
				if (inShip > 0 || inShipBees > 0)
				{
					list3.Add(a(inShip, inShipBees, ref first2, list3.Count == 0) + " worth " + c(LethalScanCommand.ApproximateValueInShip, inShipValue) + " in the ship");
				}
				if (onShip > 0 || onShipBees > 0)
				{
					list3.Add(a(onShip, onShipBees, ref first2, list3.Count == 0) + " worth " + c(LethalScanCommand.ApproximateValueOnShip, onShipValue) + " on the ship");
				}
				if (onCruiser > 0 || onCruiserBees > 0)
				{
					list3.Add(a(onCruiser, onCruiserBees, ref first2, list3.Count == 0) + " worth " + c(carValueApproximated, onCruiserValue) + " on the cruiser");
				}
				if (!StartOfRound.Instance.inShipPhase)
				{
					list3.Add(a(outsideShip, outsideShipBees, ref first2, list3.Count == 0) + ((outsideShip > 0) ? (" worth " + c(LethalScanCommand.ApproximateValueOutsideShip, outsideShipValue)) : string.Empty) + " outside the ship");
				}
				LethalScanCommand.Logger.LogDebug((object)("   strings:" + d(list3)));
				int count = list3.Count;
				if (1 == 0)
				{
				}
				string text2 = count switch
				{
					0 => "There are no items", 
					1 => "There " + f(first2) + " " + list3[0], 
					_ => "There " + f(first2) + " " + GeneralExtensions.Join<string>((IEnumerable<string>)list3.GetRange(0, list3.Count - 1), (Func<string, string>)null, ", ") + " and " + list3.Last(), 
				};
				if (1 == 0)
				{
				}
				text = text2;
			}
			return true;
			static string a(int items, int bees, ref int first, bool isFirst)
			{
				if (isFirst)
				{
					first = ((items > 0) ? items : bees);
				}
				return (items > 0) ? $"{items} item{e(items)}{b(bees)}" : $"{bees} beehive{e(bees)}";
			}
			static string b(int bees)
			{
				return (bees > 0) ? $" and {bees} beehive{e(bees)}" : string.Empty;
			}
			static string c(bool approx, int val)
			{
				return string.Format("{0}{1}$", approx ? "~" : string.Empty, val);
			}
			static string d(List<string> list)
			{
				return string.Format("List<string>[{0}]: [{1}]", list.Count, GeneralExtensions.Join<string>((IEnumerable<string>)list, (Func<string, string>)((string i) => "\"" + i + "\""), ", "));
			}
			static string e(int val)
			{
				return (val == 1) ? string.Empty : "s";
			}
			static string f(int first)
			{
				return (first == 1) ? "is" : "are";
			}
		}

		public static bool Countitems(out string? error, out int inShip, out int inShipBees, out int inShipValue, out int onShip, out int onShipBees, out int onShipValue, out int onCruiser, out int onCruiserBees, out int onCruiserValue, out int outsideShip, out int outsideShipBees, out int outsideShipValue, out bool carValueApproximated)
		{
			inShip = 0;
			inShipBees = 0;
			inShipValue = 0;
			onShip = 0;
			onShipBees = 0;
			onShipValue = 0;
			onCruiser = 0;
			onCruiserBees = 0;
			onCruiserValue = 0;
			outsideShip = 0;
			outsideShipBees = 0;
			outsideShipValue = 0;
			carValueApproximated = false;
			error = "items is null";
			GrabbableObject[] array = Object.FindObjectsOfType<GrabbableObject>();
			if (array == null)
			{
				return false;
			}
			error = "ship is null";
			GameObject val = GameObject.Find("Environment/HangarShip");
			if ((Object)(object)val == (Object)null)
			{
				return false;
			}
			error = "vehicles is null";
			VehicleController[] array2 = Object.FindObjectsOfType<VehicleController>();
			if (array2 == null)
			{
				return false;
			}
			carValueApproximated = b(LethalScanCommand.ApproximateValueOnCruiser, array2.Any((VehicleController i) => i.magnetedToShip));
			Random random = new Random(StartOfRound.Instance.randomMapSeed + 91);
			for (int j = 0; j < array.Length; j++)
			{
				GrabbableObject item2 = array[j];
				if (!item2.itemProperties.isScrap)
				{
					continue;
				}
				if (item2.isInShipRoom)
				{
					if (IsBees(item2))
					{
						inShipBees++;
					}
					else
					{
						inShip++;
					}
					inShipValue += a(LethalScanCommand.ApproximateValueInShip, item2, j);
				}
				else if (((Component)item2).transform.IsChildOf(val.transform))
				{
					if (IsBees(item2))
					{
						onShipBees++;
					}
					else
					{
						onShip++;
					}
					onShipValue += a(LethalScanCommand.ApproximateValueOnShip, item2, j);
				}
				else if (array2.Any((VehicleController _car) => ((Component)item2).transform.IsChildOf(((Component)_car).transform)))
				{
					if (IsBees(item2))
					{
						onCruiserBees++;
					}
					else
					{
						onCruiser++;
					}
					onCruiserValue += a(carValueApproximated, item2, j);
				}
				else
				{
					if (IsBees(item2))
					{
						outsideShipBees++;
					}
					else
					{
						outsideShip++;
					}
					outsideShipValue += a(LethalScanCommand.ApproximateValueOutsideShip, item2, j);
				}
			}
			return true;
			int a(bool randomize, GrabbableObject item, int i)
			{
				return randomize ? Mathf.Clamp(random.Next(item.itemProperties.minValue, item.itemProperties.maxValue), item.scrapValue - 6 * i, item.scrapValue + 9 * i) : item.scrapValue;
			}
			static bool b(LethalScanCommand.ApproximateValueOnCruiserOptions value, bool carMagnetedToShip)
			{
				if (1 == 0)
				{
				}
				bool result = value switch
				{
					LethalScanCommand.ApproximateValueOnCruiserOptions.Always => true, 
					LethalScanCommand.ApproximateValueOnCruiserOptions.Never => false, 
					_ => !carMagnetedToShip, 
				};
				if (1 == 0)
				{
				}
				return result;
			}
		}

		private static bool IsBees(GrabbableObject item)
		{
			LethalScanCommand.Logger.LogDebug((object)$">> IsBees({item}) name:{((Object)item).name}");
			return ((Object)item).name == "RedLocustHive(Clone)";
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "baer1.LethalScanCommand";

		public const string PLUGIN_NAME = "LethalScanCommand";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}