Please disclose if any significant portion of your mod was created 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 Extend Deadline v1.0.4
BepInEx/plugins/ExtendDeadline/ExtendDeadline.dll
Decompiled 3 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Serialization; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using CSync.Extensions; using CSync.Lib; using ExtendDeadline.Misc; using ExtendDeadline.Misc.UI.Application; using ExtendDeadline.NetcodePatcher; using ExtendDeadline.Patches.RoundComponents; using ExtendDeadline.Patches.TerminalComponents; using HarmonyLib; using InteractiveTerminalAPI.UI; using InteractiveTerminalAPI.UI.Application; using InteractiveTerminalAPI.UI.Cursor; using InteractiveTerminalAPI.UI.Screen; using LethalLib.Modules; 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: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] [module: NetcodePatchedAssembly] 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 ExtendDeadline { [BepInPlugin("com.github.WhiteSpike.ExtendDeadline", "Extend Deadline", "1.0.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { internal static readonly Harmony harmony = new Harmony("com.github.WhiteSpike.ExtendDeadline"); internal static readonly ManualLogSource mls = Logger.CreateLogSource("Extend Deadline"); public static PluginConfig Config; internal static GameObject networkPrefab; private void Awake() { Config = new PluginConfig(((BaseUnityPlugin)this).Config); IEnumerable<Type> enumerable; try { enumerable = Assembly.GetExecutingAssembly().GetTypes(); } catch (ReflectionTypeLoadException ex) { enumerable = ex.Types.Where((Type t) => t != null); } foreach (Type item in enumerable) { MethodInfo[] methods = item.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic); MethodInfo[] array = methods; foreach (MethodInfo methodInfo in array) { object[] customAttributes = methodInfo.GetCustomAttributes(typeof(RuntimeInitializeOnLoadMethodAttribute), inherit: false); if (customAttributes.Length != 0) { methodInfo.Invoke(null, null); } } } PatchMainVersion(); networkPrefab = NetworkPrefabs.CreateNetworkPrefab("Extend Deadline"); networkPrefab.AddComponent<ExtendDeadlineBehaviour>(); InteractiveTerminalManager.RegisterApplication<ExtendDeadlineApplication>("extend deadline", false); mls.LogInfo((object)"Extend Deadline 1.0.4 has been loaded successfully."); } internal static void PatchMainVersion() { PatchVitalComponents(); } private static void PatchVitalComponents() { harmony.PatchAll(typeof(TimeOfDayPatcher)); harmony.PatchAll(typeof(StartOfRoundPatcher)); harmony.PatchAll(typeof(RoundManagerPatcher)); harmony.PatchAll(typeof(TerminalPatcher)); mls.LogInfo((object)"Game managers have been patched"); } } public static class PluginInfo { public const string PLUGIN_GUID = "ExtendDeadline"; public const string PLUGIN_NAME = "ExtendDeadline"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace ExtendDeadline.Util { internal static class Tools { private static Terminal terminal; public static void FindCodeInstruction(ref int index, ref List<CodeInstruction> codes, object findValue, MethodInfo addCode, bool skip = false, bool requireInstance = false, bool notInstruction = false, bool andInstruction = false, bool orInstruction = false, string errorMessage = "Not found") { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown bool flag = false; while (index < codes.Count) { if (CheckCodeInstruction(codes[index], findValue)) { flag = true; if (!skip) { if (andInstruction) { codes.Insert(index + 1, new CodeInstruction(OpCodes.And, (object)null)); } if (!andInstruction && orInstruction) { codes.Insert(index + 1, new CodeInstruction(OpCodes.Or, (object)null)); } if (notInstruction) { codes.Insert(index + 1, new CodeInstruction(OpCodes.Not, (object)null)); } codes.Insert(index + 1, new CodeInstruction(OpCodes.Call, (object)addCode)); if (requireInstance) { codes.Insert(index + 1, new CodeInstruction(OpCodes.Ldarg_0, (object)null)); } } break; } index++; } if (!flag) { Plugin.mls.LogError((object)errorMessage); } index++; } public static int FindLocalField(int index, ref List<CodeInstruction> codes, int localIndex, object addCode, bool skip = false, bool store = false, bool requireInstance = false, string errorMessage = "Not found") { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown bool flag = false; while (index < codes.Count) { if (CheckCodeInstruction(codes[index], localIndex, store)) { flag = true; if (!skip) { codes.Insert(index + 1, new CodeInstruction(OpCodes.Call, addCode)); if (requireInstance) { codes.Insert(index + 1, new CodeInstruction(OpCodes.Ldarg_0, (object)null)); } } break; } index++; } if (!flag) { Plugin.mls.LogError((object)errorMessage); } return index + 1; } public static void FindString(ref int index, ref List<CodeInstruction> codes, string findValue, MethodInfo addCode = null, bool skip = false, bool notInstruction = false, bool andInstruction = false, bool orInstruction = false, bool requireInstance = false, string errorMessage = "Not found") { FindCodeInstruction(ref index, ref codes, findValue, addCode, skip, requireInstance, notInstruction, andInstruction, orInstruction, errorMessage); } public static void FindField(ref int index, ref List<CodeInstruction> codes, FieldInfo findField, MethodInfo addCode = null, bool skip = false, bool notInstruction = false, bool andInstruction = false, bool orInstruction = false, bool requireInstance = false, string errorMessage = "Not found") { FindCodeInstruction(ref index, ref codes, findField, addCode, skip, requireInstance, notInstruction, andInstruction, orInstruction, errorMessage); } public static void FindMethod(ref int index, ref List<CodeInstruction> codes, MethodInfo findMethod, MethodInfo addCode = null, bool skip = false, bool notInstruction = false, bool andInstruction = false, bool orInstruction = false, bool requireInstance = false, string errorMessage = "Not found") { FindCodeInstruction(ref index, ref codes, findMethod, addCode, skip, requireInstance, notInstruction, andInstruction, orInstruction, errorMessage); } public static void FindFloat(ref int index, ref List<CodeInstruction> codes, float findValue, MethodInfo addCode = null, bool skip = false, bool notInstruction = false, bool andInstruction = false, bool orInstruction = false, bool requireInstance = false, string errorMessage = "Not found") { FindCodeInstruction(ref index, ref codes, findValue, addCode, skip, requireInstance, notInstruction, andInstruction, orInstruction, errorMessage); } public static void FindInteger(ref int index, ref List<CodeInstruction> codes, sbyte findValue, MethodInfo addCode = null, bool skip = false, bool notInstruction = false, bool andInstruction = false, bool orInstruction = false, bool requireInstance = false, string errorMessage = "Not found") { FindCodeInstruction(ref index, ref codes, findValue, addCode, skip, requireInstance, notInstruction, andInstruction, orInstruction, errorMessage); } public static void FindSub(ref int index, ref List<CodeInstruction> codes, MethodInfo addCode = null, bool skip = false, bool notInstruction = false, bool andInstruction = false, bool orInstruction = false, bool requireInstance = false, string errorMessage = "Not found") { object findValue = OpCodes.Sub; bool notInstruction2 = notInstruction; bool andInstruction2 = andInstruction; bool orInstruction2 = orInstruction; FindCodeInstruction(ref index, ref codes, findValue, addCode, skip, requireInstance, notInstruction2, andInstruction2, orInstruction2, errorMessage); } public static void FindDiv(ref int index, ref List<CodeInstruction> codes, MethodInfo addCode = null, bool skip = false, bool notInstruction = false, bool andInstruction = false, bool orInstruction = false, bool requireInstance = false, string errorMessage = "Not found") { object findValue = OpCodes.Div; bool notInstruction2 = notInstruction; bool andInstruction2 = andInstruction; bool orInstruction2 = orInstruction; FindCodeInstruction(ref index, ref codes, findValue, addCode, skip, requireInstance, notInstruction2, andInstruction2, orInstruction2, errorMessage); } public static void FindAdd(ref int index, ref List<CodeInstruction> codes, MethodInfo addCode = null, bool skip = false, bool notInstruction = false, bool andInstruction = false, bool orInstruction = false, bool requireInstance = false, string errorMessage = "Not found") { object findValue = OpCodes.Add; bool notInstruction2 = notInstruction; bool andInstruction2 = andInstruction; bool orInstruction2 = orInstruction; FindCodeInstruction(ref index, ref codes, findValue, addCode, skip, requireInstance, notInstruction2, andInstruction2, orInstruction2, errorMessage); } public static void FindMul(ref int index, ref List<CodeInstruction> codes, MethodInfo addCode = null, bool skip = false, bool notInstruction = false, bool andInstruction = false, bool orInstruction = false, bool requireInstance = false, string errorMessage = "Not found") { object findValue = OpCodes.Mul; bool notInstruction2 = notInstruction; bool andInstruction2 = andInstruction; bool orInstruction2 = orInstruction; FindCodeInstruction(ref index, ref codes, findValue, addCode, skip, requireInstance, notInstruction2, andInstruction2, orInstruction2, errorMessage); } private static bool CheckCodeInstruction(CodeInstruction code, int localIndex, bool store = false) { if (!store) { return localIndex switch { 0 => code.opcode == OpCodes.Ldloc_0, 1 => code.opcode == OpCodes.Ldloc_1, 2 => code.opcode == OpCodes.Ldloc_2, 3 => code.opcode == OpCodes.Ldloc_3, _ => code.opcode == OpCodes.Ldloc && (int)code.operand == localIndex, }; } return localIndex switch { 0 => code.opcode == OpCodes.Stloc_0, 1 => code.opcode == OpCodes.Stloc_1, 2 => code.opcode == OpCodes.Stloc_2, 3 => code.opcode == OpCodes.Stloc_3, _ => code.opcode == OpCodes.Stloc && (int)code.operand == localIndex, }; } private static bool CheckCodeInstruction(CodeInstruction code, object findValue) { if (findValue is sbyte) { return CheckIntegerCodeInstruction(code, findValue); } if (findValue is float) { return code.opcode == OpCodes.Ldc_R4 && code.operand.Equals(findValue); } if (findValue is string) { return code.opcode == OpCodes.Ldstr && code.operand.Equals(findValue); } if (findValue is MethodInfo) { return (code.opcode == OpCodes.Call || code.opcode == OpCodes.Callvirt) && code.operand == findValue; } if (findValue is FieldInfo) { return (code.opcode == OpCodes.Ldfld || code.opcode == OpCodes.Stfld) && code.operand == findValue; } if (findValue is OpCode) { return code.opcode == (OpCode)findValue; } return false; } private static bool CheckIntegerCodeInstruction(CodeInstruction code, object findValue) { return (sbyte)findValue switch { 0 => code.opcode == OpCodes.Ldc_I4_0, 1 => code.opcode == OpCodes.Ldc_I4_1, 2 => code.opcode == OpCodes.Ldc_I4_2, 3 => code.opcode == OpCodes.Ldc_I4_3, 4 => code.opcode == OpCodes.Ldc_I4_4, 5 => code.opcode == OpCodes.Ldc_I4_5, 6 => code.opcode == OpCodes.Ldc_I4_6, 7 => code.opcode == OpCodes.Ldc_I4_7, 8 => code.opcode == OpCodes.Ldc_I4_8, _ => code.opcode == OpCodes.Ldc_I4_S && code.operand.Equals(findValue), }; } public static void ShuffleList<T>(List<T> list) { if (list == null) { throw new ArgumentNullException("list"); } Random random = new Random(); int num = list.Count; while (num > 1) { num--; int index = random.Next(num + 1); T value = list[index]; list[index] = list[num]; list[num] = value; } } public static bool SpawnMob(string mob, Vector3 position, int numToSpawn) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < RoundManager.Instance.currentLevel.Enemies.Count; i++) { if (RoundManager.Instance.currentLevel.Enemies[i].enemyType.enemyName == mob) { for (int j = 0; j < numToSpawn; j++) { RoundManager.Instance.SpawnEnemyOnServer(position, 0f, i); } return true; } } return false; } internal static string GenerateInfoForUpgrade(string infoFormat, int initialPrice, int[] incrementalPrices, Func<int, float> infoFunction) { string text = string.Format(infoFormat, 1, initialPrice, infoFunction(0)); for (int i = 0; i < incrementalPrices.Length; i++) { float num = infoFunction(i + 1); text = ((num % 1f != 0f) ? (text + string.Format(infoFormat, i + 2, incrementalPrices[i], num)) : (text + string.Format(infoFormat, i + 2, incrementalPrices[i], Mathf.RoundToInt(num)))); } return text; } public static Color ConvertValueToColor(string hex, Color defaultValue) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0035: 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_003d: Unknown result type (might be due to invalid IL or missing references) Color result = default(Color); if (hex == null || !ColorUtility.TryParseHtmlString("#" + hex.Trim('#', ' '), ref result)) { return defaultValue; } return result; } internal static string WrapText(string text, int availableLength, string leftPadding = "", string rightPadding = "", bool padLeftFirst = true) { int num = availableLength - leftPadding.Length - rightPadding.Length; string text2 = ""; string text3 = ""; int num2 = 0; int num3 = -1; bool flag = true; bool flag2 = false; for (int i = 0; i < text.Length; i++) { char c = text[i]; if (c == '<') { flag2 = true; } if (c == ' ' && !flag2) { num3 = text3.Length; } if (c != '\n') { text3 += c; if (!flag2) { num2++; } } if (c == '>' && flag2) { flag2 = false; } if (num2 < num && c != '\n') { continue; } if (c != '\n' && c != ' ') { if (num3 != -1) { string text4 = ((padLeftFirst || !flag) ? leftPadding : "") + text3.Substring(0, num3) + new string(' ', Mathf.Max(0, num - num3)) + rightPadding; text2 = text2 + text4 + "\n"; text3 = text3.Substring(num3 + 1); } else { string text5 = ((padLeftFirst || !flag) ? leftPadding : "") + text3 + rightPadding; text2 = text2 + text5 + "\n"; text3 = ""; } } else { if (text3 != "") { text2 = text2 + ((padLeftFirst || !flag) ? leftPadding : "") + text3 + new string(' ', Mathf.Max(0, num - num2)) + rightPadding + "\n"; } text3 = ""; } num3 = -1; flag = false; num2 = text3.Length; } if (text3 != "") { text2 = text2 + ((padLeftFirst || !flag) ? leftPadding : "") + text3 + new string(' ', Mathf.Max(0, num - num2)) + rightPadding + "\n"; } return text2; } internal static void SpawnExplosion(Vector3 explosionPosition, bool spawnExplosionEffect = false, float killRange = 1f, float damageRange = 1f, int nonLethalDamage = 50, float physicsForce = 0f, GameObject overridePrefab = null) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) Landmine.SpawnExplosion(explosionPosition, spawnExplosionEffect, killRange, damageRange, nonLethalDamage, physicsForce, overridePrefab, false); } internal static Terminal GetTerminal() { if ((Object)(object)terminal == (Object)null) { terminal = GameObject.Find("TerminalScript").GetComponent<Terminal>(); } return terminal; } } } namespace ExtendDeadline.Patches.TerminalComponents { [HarmonyPatch(typeof(Terminal))] internal static class TerminalPatcher { [HarmonyPostfix] [HarmonyPatch("ParsePlayerSentence")] private static void CustomParser(ref Terminal __instance, ref TerminalNode __result) { string fullText = __instance.screenText.text.Substring(__instance.screenText.text.Length - __instance.textAdded); CommandParser.ParseCommands(fullText, ref __instance, ref __result); } } } namespace ExtendDeadline.Patches.RoundComponents { [HarmonyPatch(typeof(RoundManager))] internal static class RoundManagerPatcher { private static int previousDaysDeadline = TimeOfDay.Instance.daysUntilDeadline; private static int DEFAULT_DAYS_DEADLINE = 4; private static bool savedPrevious = false; [HarmonyPatch("PlotOutEnemiesForNextHour")] [HarmonyPatch("AdvanceHourAndSpawnNewBatchOfEnemies")] [HarmonyPrefix] private static void ChangeDaysForEnemySpawns() { if (TimeOfDay.Instance.daysUntilDeadline >= DEFAULT_DAYS_DEADLINE) { Plugin.mls.LogDebug((object)"Changing deadline to allow spawning enemies."); previousDaysDeadline = TimeOfDay.Instance.daysUntilDeadline; TimeOfDay instance = TimeOfDay.Instance; instance.daysUntilDeadline %= DEFAULT_DAYS_DEADLINE; savedPrevious = true; } } [HarmonyPatch("PlotOutEnemiesForNextHour")] [HarmonyPatch("AdvanceHourAndSpawnNewBatchOfEnemies")] [HarmonyPostfix] private static void UndoChangeDaysForEnemySpawns() { if (savedPrevious) { Plugin.mls.LogDebug((object)"Changing back the deadline..."); TimeOfDay.Instance.daysUntilDeadline = previousDaysDeadline; savedPrevious = false; } } } [HarmonyPatch(typeof(StartOfRound))] internal static class StartOfRoundPatcher { [HarmonyPrefix] [HarmonyPatch("Awake")] private static void InitLguStore(StartOfRound __instance) { Plugin.mls.LogDebug((object)"Initiating components..."); if (((NetworkBehaviour)__instance).NetworkManager.IsHost || ((NetworkBehaviour)__instance).NetworkManager.IsServer) { GameObject val = Object.Instantiate<GameObject>(Plugin.networkPrefab); ((Object)val).hideFlags = (HideFlags)61; val.GetComponent<NetworkObject>().Spawn(false); Plugin.mls.LogDebug((object)"Spawned behaviour..."); } } } [HarmonyPatch(typeof(TimeOfDay))] internal static class TimeOfDayPatcher { [HarmonyPostfix] [HarmonyPatch("SyncNewProfitQuotaClientRpc")] private static void SyncNewProfitQuotaClientRpcPostfix() { ExtendDeadlineBehaviour.SetDaysExtended(0); } } } namespace ExtendDeadline.Misc { internal static class CommandParser { private const string EXTEND_HELP_COMMAND = ">EXTEND DEADLINE\nAllows extending the deadline by selecting the amount. Consumes {0} for each day extended and the price is increased by {1} per every quota fullfilled and by {2} per each day extension.\n\n"; private static TerminalNode DisplayTerminalMessage(string message, bool clearPreviousText = true) { TerminalNode val = ScriptableObject.CreateInstance<TerminalNode>(); val.displayText = message; val.clearPreviousText = clearPreviousText; return val; } public static void ParseCommands(string fullText, ref Terminal terminal, ref TerminalNode outputNode) { string[] array = fullText.Split(); string text = array[0].ToLower(); string secondWord = ((array.Length > 1) ? array[1].ToLower() : ""); string thirdWord = ((array.Length > 2) ? array[2].ToLower() : ""); string text2 = text; string text3 = text2; if (text3 == "extend") { outputNode = ExecuteExtendCommands(secondWord, thirdWord, ref terminal, ref outputNode); } } private static TerminalNode ExecuteExtendCommands(string secondWord, string thirdWord, ref Terminal terminal, ref TerminalNode outputNode) { if (1 == 0) { } TerminalNode result = ((!(secondWord == "deadline")) ? outputNode : ExecuteExtendDeadlineCommand(thirdWord, ref terminal, ref outputNode)); if (1 == 0) { } return result; } private static TerminalNode ExecuteExtendDeadlineCommand(string thirdWord, ref Terminal terminal, ref TerminalNode outputNode) { if (!string.IsNullOrEmpty(thirdWord) && thirdWord == "help") { return DisplayTerminalMessage($">EXTEND DEADLINE\nAllows extending the deadline by selecting the amount. Consumes {Plugin.Config.EXTEND_DEADLINE_PRICE.Value} for each day extended and the price is increased by {Plugin.Config.EXTEND_DEADLINE_ADDITIONAL_PRICE_PER_QUOTA.Value} per every quota fullfilled and by {Plugin.Config.EXTEND_DEADLINE_ADDITIONAL_PRICE_PER_DAY.Value} per each day extension.\n\n"); } return outputNode; } } public class ExtendDeadlineBehaviour : NetworkBehaviour { internal const string COMMAND_NAME = "Extend Deadline"; private int daysExtended; internal static ExtendDeadlineBehaviour Instance { get; set; } private static void SetInstance(ExtendDeadlineBehaviour instance) { Instance = instance; } private void Start() { SetInstance(this); Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject); if (ES3.KeyExists("daysExtended", GameNetworkManager.Instance.currentSaveFileName)) { daysExtended = ES3.Load<int>("daysExtended", GameNetworkManager.Instance.currentSaveFileName); } else { daysExtended = 0; } } [ClientRpc] public void ExtendDeadlineClientRpc(int days) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsServer || networkManager.IsHost)) { ClientRpcParams val = default(ClientRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendClientRpc(1464111162u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, days); ((NetworkBehaviour)this).__endSendClientRpc(ref val2, 1464111162u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsClient || networkManager.IsHost)) { base.__rpc_exec_stage = (__RpcExecStage)0; float timeUntilDeadline = TimeOfDay.Instance.timeUntilDeadline; TimeOfDay instance = TimeOfDay.Instance; instance.timeUntilDeadline += TimeOfDay.Instance.totalTime * (float)days; TimeOfDay.Instance.UpdateProfitQuotaCurrentTime(); TimeOfDay.Instance.SyncTimeClientRpc(TimeOfDay.Instance.globalTime, (int)TimeOfDay.Instance.timeUntilDeadline); SetDaysExtended(GetDaysExtended() + days); Plugin.mls.LogDebug((object)$"Previous time: {timeUntilDeadline}, new time: {TimeOfDay.Instance.timeUntilDeadline}"); } } } [ServerRpc(RequireOwnership = false)] public void ExtendDeadlineServerRpc(int days) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Invalid comparison between Unknown and I4 //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = ((NetworkBehaviour)this).NetworkManager; if (networkManager != null && networkManager.IsListening) { if ((int)base.__rpc_exec_stage != 1 && (networkManager.IsClient || networkManager.IsHost)) { ServerRpcParams val = default(ServerRpcParams); FastBufferWriter val2 = ((NetworkBehaviour)this).__beginSendServerRpc(2427383476u, val, (RpcDelivery)0); BytePacker.WriteValueBitPacked(val2, days); ((NetworkBehaviour)this).__endSendServerRpc(ref val2, 2427383476u, val, (RpcDelivery)0); } if ((int)base.__rpc_exec_stage == 1 && (networkManager.IsServer || networkManager.IsHost)) { base.__rpc_exec_stage = (__RpcExecStage)0; ExtendDeadlineClientRpc(days); } } } internal static int GetTotalCost() { return SyncedEntry<int>.op_Implicit(Plugin.Config.EXTEND_DEADLINE_PRICE) + SyncedEntry<int>.op_Implicit(Plugin.Config.EXTEND_DEADLINE_ADDITIONAL_PRICE_PER_QUOTA) * TimeOfDay.Instance.timesFulfilledQuota; } internal int GetTotalCostPerDay(int days) { int num = GetDaysExtended(); int num2 = 0; for (int i = 0; i < days; i++) { num2 += GetTotalCost() + num * SyncedEntry<int>.op_Implicit(Plugin.Config.EXTEND_DEADLINE_ADDITIONAL_PRICE_PER_DAY); num++; } return num2; } public static int GetDaysExtended() { return Instance.daysExtended; } public static void SetDaysExtended(int daysExtended) { Instance.daysExtended = daysExtended; if (((NetworkBehaviour)Instance).IsHost || ((NetworkBehaviour)Instance).IsServer) { ES3.Save<int>("daysExtended", daysExtended, GameNetworkManager.Instance.currentSaveFileName); Plugin.mls.LogInfo((object)$"Saved {daysExtended} days extended into the current save file"); } } protected override void __initializeVariables() { ((NetworkBehaviour)this).__initializeVariables(); } protected override void __initializeRpcs() { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown ((NetworkBehaviour)this).__registerRpc(1464111162u, new RpcReceiveHandler(__rpc_handler_1464111162), "ExtendDeadlineClientRpc"); ((NetworkBehaviour)this).__registerRpc(2427383476u, new RpcReceiveHandler(__rpc_handler_2427383476), "ExtendDeadlineServerRpc"); ((NetworkBehaviour)this).__initializeRpcs(); } private static void __rpc_handler_1464111162(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: 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_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int days = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref days); target.__rpc_exec_stage = (__RpcExecStage)1; ((ExtendDeadlineBehaviour)(object)target).ExtendDeadlineClientRpc(days); target.__rpc_exec_stage = (__RpcExecStage)0; } } private static void __rpc_handler_2427383476(NetworkBehaviour target, FastBufferReader reader, __RpcParams rpcParams) { //IL_0023: 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_0050: Unknown result type (might be due to invalid IL or missing references) NetworkManager networkManager = target.NetworkManager; if (networkManager != null && networkManager.IsListening) { int days = default(int); ByteUnpacker.ReadValueBitPacked(reader, ref days); target.__rpc_exec_stage = (__RpcExecStage)1; ((ExtendDeadlineBehaviour)(object)target).ExtendDeadlineServerRpc(days); target.__rpc_exec_stage = (__RpcExecStage)0; } } protected internal override string __getTypeName() { return "ExtendDeadlineBehaviour"; } } [DataContract] public class PluginConfig : SyncedConfig2<PluginConfig> { [field: SyncedEntryField] public SyncedEntry<int> EXTEND_DEADLINE_PRICE { get; set; } [field: SyncedEntryField] public SyncedEntry<int> EXTEND_DEADLINE_ADDITIONAL_PRICE_PER_DAY { get; set; } [field: SyncedEntryField] public SyncedEntry<int> EXTEND_DEADLINE_ADDITIONAL_PRICE_PER_QUOTA { get; set; } public PluginConfig(ConfigFile cfg) : base("com.github.WhiteSpike.ExtendDeadline") { string text = "General"; EXTEND_DEADLINE_PRICE = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, text, "Extend Deadline Price", 800, "Price of each day extension requested in the terminal."); EXTEND_DEADLINE_ADDITIONAL_PRICE_PER_QUOTA = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, text, "Extend Deadline Additional Cost per Quota", 0, "Additional cost added to the Extend Deadline command per every quota completed"); EXTEND_DEADLINE_ADDITIONAL_PRICE_PER_DAY = SyncedBindingExtensions.BindSyncedEntry<int>(cfg, text, "Extend Deadline Additional Cost per Day", 0, "Additional cost added to the Extend Deadline command per every day extended"); ConfigManager.Register<PluginConfig>((SyncedConfig2<PluginConfig>)this); } } internal static class Metadata { public const string GUID = "com.github.WhiteSpike.ExtendDeadline"; public const string NAME = "Extend Deadline"; public const string VERSION = "1.0.4"; } } namespace ExtendDeadline.Misc.Util { internal static class Constants { internal const string EXTEND_DEADLINE_PRICE_KEY = "Extend Deadline Price"; internal const int EXTEND_DEADLINE_PRICE_DEFAULT = 800; internal const string EXTEND_DEADLINE_PRICE_DESCRIPTION = "Price of each day extension requested in the terminal."; internal const string EXTEND_DEADLINE_ADDITIONAL_PRICE_PER_QUOTA_KEY = "Extend Deadline Additional Cost per Quota"; internal const int EXTEND_DEADLINE_ADDITIONAL_PRICE_PER_QUOTA_DEFAULT = 0; internal const string EXTEND_DEADLINE_ADDITIONAL_PRICE_PER_QUOTA_DESCRIPTION = "Additional cost added to the Extend Deadline command per every quota completed"; internal const string EXTEND_DEADLINE_ADDITIONAL_PRICE_PER_DAY_KEY = "Extend Deadline Additional Cost per Day"; internal const int EXTEND_DEADLINE_ADDITIONAL_PRICE_PER_DAY_DEFAULT = 0; internal const string EXTEND_DEADLINE_ADDITIONAL_PRICE_PER_DAY_DESCRIPTION = "Additional cost added to the Extend Deadline command per every day extended"; internal const string NOT_ENOUGH_CREDITS_EXTEND = "Not enough credits to purchase the selected amount of days to extend."; internal const string PURCHASE_EXTEND_DEADLINE_FORMAT = "Do you wish to purchase {0} days to extend the deadline for the cost of {1} credits?"; } } namespace ExtendDeadline.Misc.UI.Application { internal class ExtendDeadlineApplication : InteractiveCounterApplication<CursorOutputElement<string>> { public override void Initialization() { CursorOutputElement<string>[] cursorCounterElements = new CursorOutputElement<string>[1]; Func<int, string>[] array = new Func<int, string>[1]; CursorMenu<CursorOutputElement<string>> cursorCounterMenu = CursorMenu<CursorOutputElement<string>>.Create(0, '>', cursorCounterElements, (Func<CursorOutputElement<string>, CursorOutputElement<string>, int>[])null); IScreen screen = (IScreen)(object)BoxedOutputScreen<string, string>.Create("Extend Deadline", (ITextElement[])(object)new ITextElement[1] { (ITextElement)cursorCounterMenu }, (Func<string>)(() => cursorCounterElements[0].ApplyFunction()), (Func<string, string>)((string x) => x)); for (int i = 0; i < cursorCounterElements.Length; i++) { int counter = i; array[i] = (int x) => $"${ExtendDeadlineBehaviour.Instance.GetTotalCostPerDay(x)}"; cursorCounterElements[i] = CursorOutputElement<string>.Create("Days to extend", "", (Action)delegate { TryPurchaseExtendedDays<string>(cursorCounterElements[counter], delegate { ((BaseInteractiveApplication<CursorOutputElement<string>>)(object)this).SwitchScreen(screen, (BaseCursorMenu<CursorOutputElement<string>>)(object)cursorCounterMenu, true); }); }, 0, array[counter], (Func<CursorElement, bool>)null, true, true); } ((BaseInteractiveApplication<CursorOutputElement<string>>)(object)this).currentCursorMenu = (BaseCursorMenu<CursorOutputElement<string>>)(object)cursorCounterMenu; ((TerminalApplication)this).currentScreen = screen; } private void TryPurchaseExtendedDays<T>(CursorOutputElement<T> element, Action backAction) { int days = ((CursorCounterElement)element).Counter; int totalCost = ExtendDeadlineBehaviour.Instance.GetTotalCostPerDay(days); if (((TerminalApplication)this).terminal.groupCredits < totalCost) { ErrorMessage("Extend Deadline", "Not enough credits to purchase the selected amount of days to extend.", backAction, ""); return; } Confirm("Extend Deadline", $"Do you wish to purchase {days} days to extend the deadline for the cost of {totalCost} credits?", delegate { PurchaseExtendedDays(days, totalCost, backAction); }, backAction); } private void PurchaseExtendedDays(int days, int totalCost, Action backAction) { if (((NetworkBehaviour)((TerminalApplication)this).terminal).IsServer) { ExtendDeadlineBehaviour.Instance.ExtendDeadlineClientRpc(days); ((TerminalApplication)this).terminal.SyncGroupCreditsClientRpc(((TerminalApplication)this).terminal.groupCredits - totalCost, ((TerminalApplication)this).terminal.numberOfItemsInDropship); } else { ExtendDeadlineBehaviour.Instance.ExtendDeadlineServerRpc(days); ((TerminalApplication)this).terminal.BuyItemsServerRpc(Array.Empty<int>(), ((TerminalApplication)this).terminal.groupCredits - totalCost, ((TerminalApplication)this).terminal.numberOfItemsInDropship); } backAction(); } protected void Confirm(string title, string description, Action confirmAction, Action declineAction, string additionalMessage = "") { CursorOutputElement<string>[] array = new CursorOutputElement<string>[2] { CursorOutputElement<string>.Create("Confirm", "", confirmAction, 0, (Func<int, string>)null, (Func<CursorElement, bool>)null, true, false), CursorOutputElement<string>.Create("Abort", "", declineAction, 0, (Func<int, string>)null, (Func<CursorElement, bool>)null, true, false) }; CursorMenu<CursorOutputElement<string>> val = CursorMenu<CursorOutputElement<string>>.Create(0, '>', array, (Func<CursorOutputElement<string>, CursorOutputElement<string>, int>[])null); ITextElement[] array2 = (ITextElement[])(object)new ITextElement[4] { (ITextElement)TextElement.Create(description), (ITextElement)TextElement.Create(" "), (ITextElement)TextElement.Create(additionalMessage), (ITextElement)val }; IScreen val2 = (IScreen)(object)BoxedScreen.Create(title, array2); ((BaseInteractiveApplication<CursorOutputElement<string>>)(object)this).SwitchScreen(val2, (BaseCursorMenu<CursorOutputElement<string>>)(object)val, false); } protected void ErrorMessage(string title, string description, Action backAction, string error) { CursorOutputElement<string>[] array = new CursorOutputElement<string>[1] { CursorOutputElement<string>.Create("Back", "", backAction, 0, (Func<int, string>)null, (Func<CursorElement, bool>)null, true, false) }; CursorMenu<CursorOutputElement<string>> val = CursorMenu<CursorOutputElement<string>>.Create(0, '>', array, (Func<CursorOutputElement<string>, CursorOutputElement<string>, int>[])null); ITextElement[] array2 = (ITextElement[])(object)new ITextElement[5] { (ITextElement)TextElement.Create(description), (ITextElement)TextElement.Create(" "), (ITextElement)TextElement.Create(error), (ITextElement)TextElement.Create(" "), (ITextElement)val }; IScreen val2 = (IScreen)(object)BoxedScreen.Create(title, array2); ((BaseInteractiveApplication<CursorOutputElement<string>>)(object)this).SwitchScreen(val2, (BaseCursorMenu<CursorOutputElement<string>>)(object)val, false); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace __GEN { internal class NetworkVariableSerializationHelper { [RuntimeInitializeOnLoadMethod] internal static void InitializeSerialization() { } } } namespace ExtendDeadline.NetcodePatcher { [AttributeUsage(AttributeTargets.Module)] internal class NetcodePatchedAssemblyAttribute : Attribute { } }