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
{
}
}