Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SurvivalBonus v1.0.2
SurvivalBonus.dll
Decompiled 2 years agousing 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 { } }