Decompiled source of SurvivalBonus v1.0.2

SurvivalBonus.dll

Decompiled 8 months ago
using System;
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 GameNetcodeStuff;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using SurvivalBonus.Config;
using SurvivalBonus.Models;
using Unity.Netcode;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("SurvivalBonus")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+4999372cf6ad30259ef15e44bd8488c80f302ef6")]
[assembly: AssemblyProduct("SurvivalBonus")]
[assembly: AssemblyTitle("SurvivalBonus")]
[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 SurvivalBonus
{
	[BepInPlugin("aloslider.SurvivalBonus", "SurvivalBonus", "1.0.2")]
	internal class Plugin : BaseUnityPlugin
	{
		public const string Guid = "aloslider.SurvivalBonus";

		public const string Name = "SurvivalBonus";

		public const string Version = "1.0.2";

		private Harmony? _harmony;

		public static ManualLogSource Logger { get; private set; }

		public static SurvivalBonusCfg Config { get; private set; }

		private void Awake()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_0010: Expected O, but got Unknown
			_harmony = new Harmony("aloslider.SurvivalBonus");
			Logger = ((BaseUnityPlugin)this).Logger;
			Config = new SurvivalBonusCfg(((BaseUnityPlugin)this).Config);
			Logger.LogInfo((object)"Patching SurvivalBonusPatches...");
			_harmony.PatchAll(typeof(SurvivalBonusPatches));
			Logger.LogInfo((object)"Patched successfully.");
			Logger.LogInfo((object)"SurvivalBonus 1.0.2 is loaded successfully.");
		}
	}
	internal static class SurvivalBonusPatches
	{
		private const string SaveSectionKey = "SurvivalBonus_LastSurvivalState";

		private static readonly SurvivalBonusCfg _cfg;

		private static readonly ManualLogSource _logger;

		private static SurvivalState LastSurvivalState;

		static SurvivalBonusPatches()
		{
			_cfg = Plugin.Config;
			_logger = Plugin.Logger;
			LastSurvivalState = new None();
		}

		private static void ResetSurvivalState()
		{
			LastSurvivalState = new None();
		}

		[HarmonyPatch(typeof(StartOfRound), "Start")]
		[HarmonyPostfix]
		private static void LoadSaveValues()
		{
			if (_cfg.EnableBonus && ((NetworkBehaviour)StartOfRound.Instance).IsHost)
			{
				string currentSaveFileName = GameNetworkManager.Instance.currentSaveFileName;
				ResetSurvivalState();
				LastSurvivalState = ES3.Load<SurvivalState>("SurvivalBonus_LastSurvivalState", currentSaveFileName, LastSurvivalState);
				ManualLogSource logger = _logger;
				if (logger != null)
				{
					logger.LogInfo((object)string.Format("Loaded {0} value as {1} from {2}.", "LastSurvivalState", LastSurvivalState, currentSaveFileName));
				}
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "ResetSavedGameValues")]
		[HarmonyPostfix]
		private static void ResetSaveValues()
		{
			if (_cfg.EnableBonus && ((NetworkBehaviour)StartOfRound.Instance).IsHost)
			{
				string currentSaveFileName = GameNetworkManager.Instance.currentSaveFileName;
				ResetSurvivalState();
				ES3.Save<SurvivalState>("SurvivalBonus_LastSurvivalState", LastSurvivalState, currentSaveFileName);
				ManualLogSource logger = _logger;
				if (logger != null)
				{
					logger.LogInfo((object)string.Format("Reset {0} value to {1} in {2}.", "LastSurvivalState", LastSurvivalState, currentSaveFileName));
				}
			}
		}

		[HarmonyPatch(typeof(GameNetworkManager), "SaveGame")]
		[HarmonyPostfix]
		private static void SaveModState()
		{
			if (_cfg.EnableBonus && ((NetworkBehaviour)StartOfRound.Instance).IsHost)
			{
				string currentSaveFileName = GameNetworkManager.Instance.currentSaveFileName;
				ES3.Save<SurvivalState>("SurvivalBonus_LastSurvivalState", LastSurvivalState, currentSaveFileName);
				ManualLogSource logger = _logger;
				if (logger != null)
				{
					logger.LogInfo((object)string.Format("Saved {0} value as {1} to {2}.", "LastSurvivalState", LastSurvivalState, currentSaveFileName));
				}
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "EndOfGame")]
		[HarmonyPrefix]
		private static void UpdateSurvivalState()
		{
			if (_cfg.EnableBonus && ((NetworkBehaviour)StartOfRound.Instance).IsHost)
			{
				bool num = LevelNameExtensions.toLevelName(StartOfRound.Instance.currentLevel) == LevelName.CompanyBuilding;
				int playersCount = StartOfRound.Instance.connectedPlayersAmount + 1;
				int num2 = StartOfRound.Instance.allPlayerScripts.Where((PlayerControllerB p) => p.isPlayerControlled).Count((PlayerControllerB p) => !p.isPlayerDead && p.isInHangarShipRoom);
				bool flag = num2 > 0;
				LastSurvivalState = (num ? new LeftCompanyLevel(flag) : (flag ? ((SurvivalState)new SomeoneSurvived(num2, playersCount)) : ((SurvivalState)new AllDied())));
			}
		}

		[HarmonyPatch(typeof(StartOfRound), "PassTimeToNextDay")]
		[HarmonyPostfix]
		private static void ApplyAndDisplayBonus()
		{
			if (!_cfg.EnableBonus || !((NetworkBehaviour)StartOfRound.Instance).IsHost || TimeOfDay.Instance.timeUntilDeadline <= 0f)
			{
				return;
			}
			SurvivalState lastSurvivalState = LastSurvivalState;
			if (!(lastSurvivalState is SomeoneSurvived someoneSurvived))
			{
				if (lastSurvivalState is LeftCompanyLevel leftCompanyLevel)
				{
					if (leftCompanyLevel.AtLeastOneSurvived)
					{
						HUDManager.Instance.AddTextToChatOnServer("<size=13><color=white>Wow, you survived Company! No one cares.</color></size>", -1);
					}
					else
					{
						HUDManager.Instance.AddTextToChatOnServer("<size=13><color=red>You can't even survive Company, idiots!</color></size>", -1);
					}
					ManualLogSource logger = _logger;
					if (logger != null)
					{
						logger.LogInfo((object)"No bonus to apply for leaving the CompanyBuildingLevel.");
					}
				}
				else
				{
					HUDManager.Instance.AddTextToChatOnServer("<size=13><color=red>You ALL died, what bonus do you expect?!</color></size>", -1);
					ManualLogSource logger2 = _logger;
					if (logger2 != null)
					{
						logger2.LogInfo((object)"No bonus to apply: all players died.");
					}
				}
			}
			else if (_cfg.ApplyCondition == ApplyCondition.All && !someoneSurvived.AllSurvived)
			{
				HUDManager.Instance.AddTextToChatOnServer("<size=13><color=white>Someone died, so no bonus for you :(</color></size>", -1);
				ManualLogSource logger3 = _logger;
				if (logger3 != null)
				{
					logger3.LogInfo((object)$"No bonus to apply: not all players survived when condition is {_cfg.ApplyCondition}.");
				}
			}
			else
			{
				ApplyCondition applyCondition = _cfg.ApplyCondition;
				bool allSurvived = someoneSurvived.AllSurvived;
				int num = ((applyCondition != ApplyCondition.Split || allSurvived) ? _cfg.BonusAmount : (_cfg.BonusAmount * someoneSurvived.PlayersAlive / someoneSurvived.PlayersCount));
				int num2 = num;
				Terminal val = Object.FindObjectOfType<Terminal>();
				val.groupCredits += num2;
				val.SyncGroupCreditsServerRpc(val.groupCredits, val.numberOfItemsInDropship);
				HUDManager.Instance.AddTextToChatOnServer("<size=13><color=green>Nice job, here's your bonus: " + $"<size=13><color=yellow>{num2}</color></size>!" + "</color></size>", -1);
				ManualLogSource logger4 = _logger;
				if (logger4 != null)
				{
					logger4.LogInfo((object)$"Applied {num2} out of {_cfg.BonusAmount} credits.");
				}
			}
		}
	}
}
namespace SurvivalBonus.Models
{
	internal enum ApplyCondition
	{
		AtLeastOne,
		Split,
		All
	}
	internal enum LevelName
	{
		Experimentation,
		Assurance,
		Vow,
		CompanyBuilding,
		March,
		Rend,
		Dine,
		Offense,
		Titan,
		Other
	}
	internal static class LevelNameExtensions
	{
		public static LevelName toLevelName(SelectableLevel level)
		{
			int levelID = level.levelID;
			if (levelID < 0 || levelID > 8)
			{
				return LevelName.Other;
			}
			return (LevelName)level.levelID;
		}
	}
	internal abstract class SurvivalState
	{
	}
	internal class None : SurvivalState
	{
	}
	internal class LeftCompanyLevel : SurvivalState
	{
		[SerializeField]
		public bool AtLeastOneSurvived { get; set; }

		public LeftCompanyLevel(bool atLeastOneSurvived)
		{
			AtLeastOneSurvived = atLeastOneSurvived;
		}
	}
	internal class SomeoneSurvived : SurvivalState
	{
		[SerializeField]
		public int PlayersAlive { get; init; }

		[SerializeField]
		public int PlayersCount { get; init; }

		public bool AllSurvived => PlayersAlive == PlayersCount;

		public SomeoneSurvived(int playersAlive, int playersCount)
		{
			PlayersAlive = playersAlive;
			PlayersCount = playersCount;
		}
	}
	internal class AllDied : SurvivalState
	{
	}
}
namespace SurvivalBonus.Config
{
	internal class AcceptableMinValue<T> : AcceptableValueBase where T : IComparable
	{
		public T MinValue { get; }

		public AcceptableMinValue(T minValue)
			: base(typeof(T))
		{
			if (minValue == null)
			{
				throw new ArgumentNullException("minValue");
			}
			MinValue = minValue;
		}

		public override object Clamp(object value)
		{
			if (MinValue.CompareTo(value) > 0)
			{
				return MinValue;
			}
			return value;
		}

		public override bool IsValid(object value)
		{
			return MinValue.CompareTo(value) <= 0;
		}

		public override string ToDescriptionString()
		{
			return $"# Acceptable minimum value range: {MinValue}";
		}
	}
	internal class SurvivalBonusCfg
	{
		private const string SurvivingBonusSectionName = "Surviving bonus";

		private readonly ConfigEntry<bool> EnableBonusEntry = cfg.Bind<bool>("Surviving bonus", "Enable bonus", true, "Your crew will get bonus credits if survival condition is met.");

		private readonly ConfigEntry<ApplyCondition> ApplyConditionEntry = cfg.Bind<ApplyCondition>("Surviving bonus", "Bonus apply condition", ApplyCondition.AtLeastOne, "How bonus should be applied.");

		private readonly ConfigEntry<int> BonusAmountEntry = cfg.Bind<int>("Surviving bonus", "Bonus amount", 100, new ConfigDescription("How much bonus credits your crew get if survival condition is met.", (AcceptableValueBase)(object)new AcceptableMinValue<int>(0), Array.Empty<object>()));

		public bool EnableBonus => EnableBonusEntry.Value;

		public ApplyCondition ApplyCondition => ApplyConditionEntry.Value;

		public int BonusAmount => BonusAmountEntry.Value;

		public SurvivalBonusCfg(ConfigFile cfg)
		{
		}//IL_0056: Unknown result type (might be due to invalid IL or missing references)
		//IL_0060: Expected O, but got Unknown

	}
}
namespace System.Runtime.CompilerServices
{
	[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
	internal sealed class IgnoresAccessChecksToAttribute : Attribute
	{
		public IgnoresAccessChecksToAttribute(string assemblyName)
		{
		}
	}
	internal static class IsExternalInit
	{
	}
}