Decompiled source of LethalCompanyProgressionPatchFix v2.0.0
LethalProgression.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.CodeDom.Compiler; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalNetworkAPI; using LethalProgression.Config; using LethalProgression.GUI.HandSlot; using LethalProgression.GUI.Skills; using LethalProgression.GUI.XPBar; using LethalProgression.LessShitConfig; using LethalProgression.LessShitConfig.Attributes; using LethalProgression.LessShitConfig.Internal; using LethalProgression.LessShitConfig.Internal.ClassBuilders; using LethalProgression.LessShitConfig.Sources; using LethalProgression.Network; using LethalProgression.Patches; using LethalProgression.Properties; using LethalProgression.Saving; using LethalProgression.Skills; using LethalProgression.Skills.Upgrades; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Steamworks; using TMPro; using Unity.Netcode; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [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: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("LethalProgression")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("Leveling and skillpoints through a managed GUI! Patched and bugfixed until official copy updated.")] [assembly: AssemblyFileVersion("2.0.0.0")] [assembly: AssemblyInformationalVersion("2.0.0")] [assembly: AssemblyProduct("LethalProgression")] [assembly: AssemblyTitle("LethalProgression")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LethalProgression { internal class LC_XP : NetworkBehaviour { public LethalNetworkVariable<int> teamLevel = new LethalNetworkVariable<int>("teamLevel") { Value = 0 }; public LethalNetworkVariable<int> teamXP = new LethalNetworkVariable<int>("teamXP") { Value = 0 }; public LethalNetworkVariable<int> teamTotalValue = new LethalNetworkVariable<int>("teamTotalValue") { Value = 0 }; public LethalNetworkVariable<int> teamXPRequired = new LethalNetworkVariable<int>("teamXPRequired") { Value = 0 }; public LethalNetworkVariable<int> teamLootLevel = new LethalNetworkVariable<int>("teamLootLevel") { Value = 0 }; public LethalClientEvent playerConnectClientEvent = new LethalClientEvent("playerConnectEvent", (Action)null, (Action<ulong>)null); public LethalServerEvent playerConnectServerEvent = new LethalServerEvent("playerConnectEvent", (Action<ulong>)null); public LethalClientEvent evaluateXPRequirementClientEvent = new LethalClientEvent("evaluateXPRequirementEvent", (Action)null, (Action<ulong>)null); public LethalServerEvent evaluateXPRequirementServerEvent = new LethalServerEvent("evaluateXPRequirementEvent", (Action<ulong>)null); public LethalClientEvent calculateAllPlayersHandSlotsClientEvent = new LethalClientEvent("calculateAllPlayersHandSlotsEvent", (Action)null, (Action<ulong>)null); public LethalServerEvent calculateAllPlayersHandSlotsServerEvent = new LethalServerEvent("calculateAllPlayersHandSlotsEvent", (Action<ulong>)null); public LethalServerMessage<string> sendConfigServerMessage = new LethalServerMessage<string>("sendConfigMessage", (Action<string, ulong>)null); public LethalClientMessage<string> sendConfigClientMessage = new LethalClientMessage<string>("sendConfigMessage", (Action<string>)null, (Action<string, ulong>)null); public LethalServerMessage<ulong> requestProfileDataServerMessage = new LethalServerMessage<ulong>("requestProfileDataMessage", (Action<ulong, ulong>)null); public LethalClientMessage<ulong> requestProfileDataClientMessage = new LethalClientMessage<ulong>("requestProfileDataMessage", (Action<ulong>)null, (Action<ulong, ulong>)null); public LethalServerMessage<string> sendProfileDataServerMessage = new LethalServerMessage<string>("sendProfileDataMessage", (Action<string, ulong>)null); public LethalClientMessage<string> receiveProfileDataClientMessage = new LethalClientMessage<string>("sendProfileDataMessage", (Action<string>)null, (Action<string, ulong>)null); public LethalServerMessage<string> saveProfileDataServerMessage = new LethalServerMessage<string>("saveProfileDataMessage", (Action<string, ulong>)null); public LethalClientMessage<string> saveProfileDataClientMessage = new LethalClientMessage<string>("saveProfileDataMessage", (Action<string>)null, (Action<string, ulong>)null); public LethalServerMessage<int> updateTeamLootLevelServerMessage = new LethalServerMessage<int>("updateTeamLootLevelMessage", (Action<int, ulong>)null); public LethalClientMessage<int> updateTeamLootLevelClientMessage = new LethalClientMessage<int>("updateTeamLootLevelMessage", (Action<int>)null, (Action<int, ulong>)null); public LethalServerMessage<int> updateTeamXPServerMessage = new LethalServerMessage<int>("updateTeamXPMessage", (Action<int, ulong>)null); public LethalClientMessage<int> updateTeamXPClientMessage = new LethalClientMessage<int>("updateTeamXPMessage", (Action<int>)null, (Action<int, ulong>)null); public LethalServerMessage<int> updatePlayerSkillpointsServerMessage = new LethalServerMessage<int>("updatePlayerSkillPointsMessage", (Action<int, ulong>)null); public LethalClientMessage<int> updatePlayerSkillpointsClientMessage = new LethalClientMessage<int>("updatePlayerSkillPointsMessage", (Action<int>)null, (Action<int, ulong>)null); public LethalServerMessage<int> updateSPHandSlotsServerMessage = new LethalServerMessage<int>("updateSPHandSlotsMessage", (Action<int, ulong>)null); public LethalClientMessage<int> updateSPHandSlotsClientMessage = new LethalClientMessage<int>("updateSPHandSlotsMessage", (Action<int>)null, (Action<int, ulong>)null); public LethalServerMessage<PlayerHandSlotData> updatePlayerHandSlotsServerMessage = new LethalServerMessage<PlayerHandSlotData>("updatePlayerHandSlotsMessage", (Action<PlayerHandSlotData, ulong>)null); public LethalClientMessage<PlayerHandSlotData> updatePlayerHandSlotsClientMessage = new LethalClientMessage<PlayerHandSlotData>("updatePlayerHandSlotsMessage", (Action<PlayerHandSlotData>)null, (Action<PlayerHandSlotData, ulong>)null); public int skillPoints; public SkillList skillList = new SkillList(); public bool Initialized = false; public bool loadedSave = false; public void Start() { LethalPlugin.Log.LogInfo((object)"XP Network Behavior Made!"); teamLevel.OnValueChanged += OnTeamLevelChange; playerConnectServerEvent.OnReceived += PlayerConnect_C2SEvent; evaluateXPRequirementServerEvent.OnReceived += EvaluateXPRequirements_C2SEvent; calculateAllPlayersHandSlotsServerEvent.OnReceived += RefreshAllPlayerHandSlots_C2SEvent; sendConfigClientMessage.OnReceived += SendHostConfig_S2CMessage; receiveProfileDataClientMessage.OnReceived += LoadProfileData_S2CMessage; updatePlayerSkillpointsClientMessage.OnReceived += UpdateSkillPoints_S2CMessage; updatePlayerHandSlotsClientMessage.OnReceived += UpdatePlayerHandSlots_S2CMessage; requestProfileDataServerMessage.OnReceived += RequestSavedData_C2SMessage; saveProfileDataServerMessage.OnReceived += SaveProfileData_C2SMessage; updateTeamLootLevelServerMessage.OnReceived += UpdateTeamLootLevel_C2SMessage; updateTeamXPServerMessage.OnReceived += UpdateTeamXP_C2SMessage; updateSPHandSlotsServerMessage.OnReceived += UpdateSPHandSlots_C2SMessage; playerConnectClientEvent.InvokeServer(); } public override void OnDestroy() { teamLevel.OnValueChanged -= OnTeamLevelChange; teamLootLevel.OnValueChanged -= LethalPlugin.SkillsGUI.TeamLootHudUpdate; playerConnectServerEvent.OnReceived -= PlayerConnect_C2SEvent; evaluateXPRequirementServerEvent.OnReceived -= EvaluateXPRequirements_C2SEvent; calculateAllPlayersHandSlotsServerEvent.OnReceived -= RefreshAllPlayerHandSlots_C2SEvent; sendConfigClientMessage.OnReceived -= SendHostConfig_S2CMessage; receiveProfileDataClientMessage.OnReceived -= LoadProfileData_S2CMessage; updatePlayerSkillpointsClientMessage.OnReceived -= UpdateSkillPoints_S2CMessage; updatePlayerHandSlotsClientMessage.OnReceived -= UpdatePlayerHandSlots_S2CMessage; requestProfileDataServerMessage.OnReceived -= RequestSavedData_C2SMessage; saveProfileDataServerMessage.OnReceived -= SaveProfileData_C2SMessage; updateTeamLootLevelServerMessage.OnReceived -= UpdateTeamLootLevel_C2SMessage; updateTeamXPServerMessage.OnReceived -= UpdateTeamXP_C2SMessage; updateSPHandSlotsServerMessage.OnReceived -= UpdateSPHandSlots_C2SMessage; ((NetworkBehaviour)this).OnDestroy(); } private void OnTeamLevelChange(int newLevel) { ((MonoBehaviour)this).StartCoroutine(WaitUntilInitialisedThenAction(HUDManagerPatch.ShowLevelUp)); } private void OnTeamXPChange(int newXP) { ((MonoBehaviour)this).StartCoroutine(WaitUntilInitialisedThenAction(HUDManagerPatch.ShowXPUpdate)); } public IEnumerator WaitUntilInitialisedThenAction(Action callback) { yield return (object)new WaitUntil((Func<bool>)(() => Initialized)); callback(); } public void PlayerConnect_C2SEvent(ulong clientId) { LethalPlugin.Log.LogInfo((object)$"Received PlayerConnect message from {clientId}"); LessShitConfigSystem.ClearHostConfigs(); string text = LessShitConfigSystem.SerializeLocalConfigs(); LethalPlugin.Log.LogInfo((object)("Sending config -> " + text)); sendConfigServerMessage.SendClient(text, clientId); } public void LoadSharedData() { SaveSharedData? saveSharedData = SaveManager.LoadSharedFile(); if (!saveSharedData.HasValue) { LethalPlugin.Log.LogInfo((object)"Shared data is null!"); return; } SaveSharedData value = saveSharedData.Value; LethalPlugin.Log.LogInfo((object)"Loading Lobby shared data."); teamXP.Value = value.xp; teamLevel.Value = value.level; teamTotalValue.Value = value.quota; teamXPRequired.Value = CalculateXPRequirement(); LethalPlugin.Log.LogInfo((object)$"{value.level} current lvl, {value.xp} XP, {value.quota} Profit, {teamXPRequired.Value} teamXPRequired"); } public IEnumerator LoadProfileData(string data) { LethalPlugin.Log.LogInfo((object)("Received player data from host -> " + data)); yield return (object)new WaitUntil((Func<bool>)(() => Initialized)); if (loadedSave) { LethalPlugin.Log.LogWarning((object)"Already loaded player data from host."); yield return null; } loadedSave = true; SaveData saveData = JsonConvert.DeserializeObject<SaveData>(data); skillPoints = saveData.skillPoints; LethalPlugin.Log.LogDebug((object)$"skillPoints -> {skillPoints}"); int skillCheck = 0; foreach (KeyValuePair<UpgradeType, int> skill in saveData.skillAllocation) { LethalPlugin.Log.LogDebug((object)$"{skill.Key} -> {skill.Value}"); skillList.skills[skill.Key].SetLevel(skill.Value, triggerHostProfileSave: false); skillCheck += skill.Value; LethalPlugin.Log.LogDebug((object)$"skillCheck -> {skillCheck}"); } if (skillCheck + skillPoints < teamLevel.Value + 5) { LethalPlugin.Log.LogInfo((object)$"Skill check is less than current level, adding {teamLevel.Value + 5 - (skillCheck + skillPoints)} skill points."); skillPoints += teamLevel.Value + 5 - (skillCheck + skillPoints); } LethalPlugin.SkillsGUI.UpdateAllStats(); } public int CalculateXPRequirement() { int connectedPlayersAmount = StartOfRound.Instance.connectedPlayersAmount; int timesFulfilledQuota = TimeOfDay.Instance.timesFulfilledQuota; IGeneralConfig active = LessShitConfigSystem.GetActive<IGeneralConfig>(); int num = connectedPlayersAmount * active.personMultiplier; int num2 = active.minXP + num; int num3 = timesFulfilledQuota * active.quotaMultiplier; num2 += (int)((float)num2 * ((float)num3 / 100f)); if (num2 > active.maxXP) { num2 = active.maxXP; } LethalPlugin.Log.LogInfo((object)$"{connectedPlayersAmount} players, {timesFulfilledQuota} quotas, {active.minXP} initial cost, {num} person value, {num3} quota value, {num2} total cost."); return num2; } public int GetXP() { return teamXP.Value; } public int GetLevel() { return teamLevel.Value; } public int GetProfit() { return teamTotalValue.Value; } public int GetSkillPoints() { return skillPoints; } public void SetSkillPoints(int num) { skillPoints = num; } public void EvaluateXPRequirements_C2SEvent(ulong clientId) { ((MonoBehaviour)this).StartCoroutine(XPRequirementCoroutine()); } public IEnumerator XPRequirementCoroutine() { yield return (object)new WaitForSeconds(0.5f); teamXPRequired.Value = CalculateXPRequirement(); } public void UpdateTeamXP_C2SMessage(int xpToAdd, ulong clientId) { LethalNetworkVariable<int> obj = teamXP; obj.Value += xpToAdd; LethalNetworkVariable<int> obj2 = teamTotalValue; obj2.Value += xpToAdd; int num = GetXP(); if (num >= teamXPRequired.Value) { int num2 = 0; while (num >= teamXPRequired.Value) { num2++; num -= teamXPRequired.Value; } teamXP.Value = num; LethalNetworkVariable<int> obj3 = teamLevel; obj3.Value += num2; updatePlayerSkillpointsServerMessage.SendAllClients(num2, true); } } public void UpdateSkillPoints_S2CMessage(int pointsToAdd) { skillPoints += pointsToAdd; } public void UpdateTeamLootLevel_C2SMessage(int change, ulong clientId) { int value = teamLootLevel.Value; if (value + change < 0) { teamLootLevel.Value = 0; } else { LethalNetworkVariable<int> obj = teamLootLevel; obj.Value += change; } LethalPlugin.Log.LogInfo((object)$"Changed team loot value by {change} turning into {teamLootLevel.Value}."); } public void UpdateSPHandSlots_C2SMessage(int slotChange, ulong clientId) { if (!LethalPlugin.ReservedSlots) { LethalPlugin.Log.LogInfo((object)$"C2S Received update for Player {clientId} to add {slotChange} slots"); updatePlayerHandSlotsServerMessage.SendAllClients(new PlayerHandSlotData(clientId, slotChange), true); } } public void UpdatePlayerHandSlots_S2CMessage(PlayerHandSlotData data) { LethalPlugin.Log.LogInfo((object)$"S2C Received update for Player {data.clientId} to add {data.additionalSlots} slots"); SetHandSlot(data.clientId, data.additionalSlots); } public void SetHandSlot(ulong playerID, int additionalSlots) { //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (val.playerClientId != playerID) { continue; } int num = 4 + additionalSlots; List<GrabbableObject> list = val.ItemSlots.ToList(); if (val.currentItemSlot > num - 1) { HandSlots.SwitchItemSlots(val, num - 1); } for (int j = 0; j < list.Count; j++) { if (j > num - 1 && (Object)(object)list[j] != (Object)null) { HandSlots.SwitchItemSlots(val, j); val.DiscardHeldObject(false, (NetworkObject)null, default(Vector3), true); } } val.ItemSlots = (GrabbableObject[])(object)new GrabbableObject[num]; for (int k = 0; k < list.Count; k++) { if (!((Object)(object)list[k] == (Object)null)) { val.ItemSlots[k] = list[k]; } } LethalPlugin.Log.LogDebug((object)$"Player {playerID} has {val.ItemSlots.Length} slots after setting."); if ((Object)(object)val == (Object)(object)GameNetworkManager.Instance.localPlayerController) { LethalPlugin.Log.LogDebug((object)"Updating HUD slots."); HandSlots.UpdateHudSlots(); } break; } } public void RefreshAllPlayerHandSlots_C2SEvent(ulong clientId) { if (LethalPlugin.ReservedSlots || !LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.HandSlot)) { return; } PlayerControllerB[] allPlayerScripts = StartOfRound.Instance.allPlayerScripts; foreach (PlayerControllerB val in allPlayerScripts) { if (((Component)val).gameObject.activeSelf) { ulong playerClientId = val.playerClientId; int additionalSlots = val.ItemSlots.Length - 4; updatePlayerHandSlotsServerMessage.SendAllClients(new PlayerHandSlotData(playerClientId, additionalSlots), true); } } } public void SendHostConfig_S2CMessage(string serializedConfig) { LessShitConfigSystem.ApplyHostConfigs(serializedConfig); if (!Initialized) { Initialized = true; LP_NetworkManager.xpInstance = this; skillList.InitializeSkills(); if (GameNetworkManager.Instance.isHostingGame) { LoadSharedData(); } teamLootLevel.OnValueChanged += LethalPlugin.SkillsGUI.TeamLootHudUpdate; skillPoints = teamLevel.Value + 5; calculateAllPlayersHandSlotsClientEvent.InvokeServer(); evaluateXPRequirementClientEvent.InvokeServer(); } } public void RequestSavedData_C2SMessage(ulong steamID, ulong clientId) { string text = SaveManager.LoadPlayerFile(steamID); PlayerControllerB playerController = LethalNetworkExtensions.GetPlayerController(clientId); sendProfileDataServerMessage.SendClient(text, playerController.actualClientId); } public void LoadProfileData_S2CMessage(string saveData) { LethalPlugin.Log.LogInfo((object)("Received LoadProfileData_S2CMessage -> " + saveData)); if (saveData != null) { ((MonoBehaviour)this).StartCoroutine(LoadProfileData(saveData)); } } public void SaveProfileData_C2SMessage(string data, ulong clientId) { SaveProfileData saveProfileData = JsonConvert.DeserializeObject<SaveProfileData>(data); LethalPlugin.Log.LogInfo((object)$"Received SaveData request for {saveProfileData.steamId} with data -> {JsonConvert.SerializeObject((object)saveProfileData.saveData)}"); SaveManager.Save(saveProfileData.steamId, saveProfileData.saveData); SaveManager.SaveShared(teamXP.Value, teamLevel.Value, teamTotalValue.Value); } } [HarmonyPatch] internal class LP_NetworkManager { public static LC_XP xpInstance; public static GameObject xpNetworkObject; [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "Start")] public static void Init() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown if (!((Object)(object)xpNetworkObject != (Object)null)) { xpNetworkObject = (GameObject)LethalPlugin.skillBundle.LoadAsset("LP_XPHandler"); xpNetworkObject.AddComponent<LC_XP>(); NetworkManager.Singleton.AddNetworkPrefab(xpNetworkObject); } } [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "Awake")] private static void SpawnNetworkHandler() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) if (NetworkManager.Singleton.IsHost || NetworkManager.Singleton.IsServer) { GameObject val = Object.Instantiate<GameObject>(xpNetworkObject, Vector3.zero, Quaternion.identity); val.GetComponent<NetworkObject>().Spawn(false); xpInstance = val.GetComponent<LC_XP>(); LethalPlugin.Log.LogInfo((object)"XPHandler Initialized."); } } } [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("TisRyno.LethalProgression", "Lethal Progression", "2.0.0")] internal class LethalPlugin : BaseUnityPlugin { private const string modGUID = "TisRyno.LethalProgression"; private const string modName = "Lethal Progression"; private const string modVersion = "2.0.0"; public static AssetBundle skillBundle; internal static ManualLogSource Log; internal static bool ReservedSlots; public static LethalPlugin Instance { get; private set; } public static XPBarGUI XPBarGUI { get; private set; } public static SkillsGUI SkillsGUI { get; private set; } public static SlotTemplate SlotTemplate { get; private set; } private void Awake() { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown Instance = this; XPBarGUI = new XPBarGUI(); SkillsGUI = new SkillsGUI(); SlotTemplate = new SlotTemplate(); Harmony val = new Harmony("TisRyno.LethalProgression"); val.PatchAll(); skillBundle = AssetBundle.LoadFromMemory(Resources.skillmenu); Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"Lethal Progression initialised."); LessShitConfigSystem.RegisterSection<IGeneralConfig>(); LessShitConfigSystem.RegisterSection<IBatteryLifeConfig>(); LessShitConfigSystem.RegisterSection<IHandSlotsConfig>(); LessShitConfigSystem.RegisterSection<IHealthRegenConfig>(); LessShitConfigSystem.RegisterSection<IJumpHeightConfig>(); LessShitConfigSystem.RegisterSection<ILootValueConfig>(); LessShitConfigSystem.RegisterSection<ISprintSpeedConfig>(); LessShitConfigSystem.RegisterSection<IStaminaConfig>(); LessShitConfigSystem.RegisterSection<IStrengthConfig>(); LessShitConfigSystem.Bake(((BaseUnityPlugin)this).Config); LessShitConfigSystem.SerializeLocalConfigs(); Log.LogInfo((object)"Lethal Progression Config loaded."); foreach (KeyValuePair<string, PluginInfo> pluginInfo in Chainloader.PluginInfos) { string gUID = pluginInfo.Value.Metadata.GUID; if (gUID.Contains("ReservedItem")) { ReservedSlots = true; break; } if (gUID.Contains("mikestweaks") && (from entry in pluginInfo.Value.Instance.Config.GetConfigEntries() where entry.Definition.Key == "ExtraItemSlots" where int.TryParse(entry.GetSerializedValue(), out var result) && result > 0 select entry).Any()) { ReservedSlots = true; break; } } } public IDictionary<string, object> GetAllConfigEntries() { return ((IEnumerable<KeyValuePair<ConfigDefinition, ConfigEntryBase>>)((BaseUnityPlugin)this).Config).ToDictionary((KeyValuePair<ConfigDefinition, ConfigEntryBase> entry) => entry.Value.Definition.Key, (KeyValuePair<ConfigDefinition, ConfigEntryBase> entry) => entry.Value.BoxedValue); } } public static class PluginInfo { public const string PLUGIN_GUID = "LethalProgression"; public const string PLUGIN_NAME = "LethalProgression"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace LethalProgression.Skills { internal class Skill { private readonly string _shortName; private readonly string _name; private readonly string _attribute; private readonly string _description; private readonly UpgradeType _upgradeType; private readonly int _cost; private readonly int _maxLevel; private readonly float _multiplier; private readonly Action<int> _callback; public bool _teamShared; private int _level; public Skill(string name, string description, string shortname, string attribute, UpgradeType upgradeType, int cost, int maxLevel, float multiplier, Action<int> callback = null, bool teamShared = false) { _name = name; _shortName = shortname; _attribute = attribute; _description = description; _upgradeType = upgradeType; _cost = cost; _maxLevel = maxLevel; _multiplier = multiplier; _level = 0; _callback = callback; _teamShared = teamShared; } public string GetName() { return _name; } public string GetShortName() { return _shortName; } public string GetAttribute() { return _attribute; } public string GetDescription() { return _description; } public UpgradeType GetUpgradeType() { return _upgradeType; } public int GetCost() { return _cost; } public int GetMaxLevel() { return _maxLevel; } public int GetLevel() { return _level; } public float GetMultiplier() { return _multiplier; } public float GetTrueValue() { return _multiplier * (float)_level; } public void SetLevel(int newLevel, bool triggerHostProfileSave = true) { int level = _level; _level = newLevel; _callback?.Invoke(newLevel - level); if (triggerHostProfileSave) { SaveManager.TriggerHostProfileSave(); } } public void AddLevel(int change) { _level += change; _callback?.Invoke(change); SaveManager.TriggerHostProfileSave(); } } internal class SkillList { public Dictionary<UpgradeType, Skill> skills = new Dictionary<UpgradeType, Skill>(); public void CreateSkill(UpgradeType upgrade, string name, string description, string shortname, string attribute, int cost, int maxLevel, float multiplier, Action<int> callback = null, bool teamShared = false) { Skill value = new Skill(name, description, shortname, attribute, upgrade, cost, maxLevel, multiplier, callback, teamShared); skills.Add(upgrade, value); } public bool IsSkillValid(UpgradeType upgrade) { return skills.ContainsKey(upgrade) && skills[upgrade].GetLevel() > 0; } public Skill GetSkill(UpgradeType upgrade) { if (!IsSkillValid(upgrade)) { return null; } return skills[upgrade]; } public Dictionary<UpgradeType, Skill> GetSkills() { return skills; } public void InitializeSkills() { IHealthRegenConfig active = LessShitConfigSystem.GetActive<IHealthRegenConfig>(); IStaminaConfig active2 = LessShitConfigSystem.GetActive<IStaminaConfig>(); IBatteryLifeConfig active3 = LessShitConfigSystem.GetActive<IBatteryLifeConfig>(); IHandSlotsConfig active4 = LessShitConfigSystem.GetActive<IHandSlotsConfig>(); ILootValueConfig active5 = LessShitConfigSystem.GetActive<ILootValueConfig>(); IStrengthConfig active6 = LessShitConfigSystem.GetActive<IStrengthConfig>(); IJumpHeightConfig active7 = LessShitConfigSystem.GetActive<IJumpHeightConfig>(); ISprintSpeedConfig active8 = LessShitConfigSystem.GetActive<ISprintSpeedConfig>(); if (active.isEnabled) { CreateSkill(UpgradeType.HPRegen, "Health Regen", "The company installs a basic healer into your suit, letting you regenerate health slowly. Only regenerate up to 100 HP.", "HPR", "Health Regeneration", 1, active.maxLevel, active.multiplier); } if (active2.isEnabled) { CreateSkill(UpgradeType.Stamina, "Stamina", "Hours on that company gym finally coming into play. Allows you to run for longer, but has to regenerate it slower.", "STM", "Stamina", 1, active2.maxLevel, active2.multiplier); } if (active3.isEnabled) { CreateSkill(UpgradeType.Battery, "Battery Life", "The company provides you with better batteries. Replace your batteries AT THE SHIP'S CHARGER to see an effect.", "BAT", "Battery Life", 1, active3.maxLevel, active3.multiplier); } if (active4.isEnabled && !LethalPlugin.ReservedSlots) { CreateSkill(UpgradeType.HandSlot, "Hand Slot", "The company finally gives you a better belt! Fit more stuff! (One slot every 100%.)", "HND", "Hand Slots", 1, active4.maxLevel, active4.multiplier, HandSlots.HandSlotsUpdate); } if (active5.isEnabled) { CreateSkill(UpgradeType.Value, "Loot Value", "The company gives you a better pair of eyes, allowing you to see the value in things.", "VAL", "Loot Value", 1, active5.maxLevel, active5.multiplier, LootValue.LootValueUpdate, teamShared: true); } if (active6.isEnabled) { CreateSkill(UpgradeType.Strength, "Strength", "More work at the Company's gym gives you pure muscles! You can carry better. (Reduces weight by a percentage.)", "STR", "Weight Reduction", 1, active6.maxLevel, active6.multiplier, Strength.StrengthUpdate); } if (active7.isEnabled) { CreateSkill(UpgradeType.JumpHeight, "Jump Height", "The company installs you with jumping boots! (The company is not responsible for any broken knees.)", "JMP", "Jump Height", 1, active7.maxLevel, active7.multiplier); } if (active8.isEnabled) { CreateSkill(UpgradeType.SprintSpeed, "Sprint Speed", "The company empowers you with pure steroids, run, spaceman.", "SPD", "Sprint Speed", 1, active8.maxLevel, active8.multiplier); } } } public enum UpgradeType { HPRegen, Stamina, Battery, HandSlot, Value, JumpHeight, SprintSpeed, Strength } } namespace LethalProgression.Skills.Upgrades { internal class BatteryLife { public static float GetUseItemBatteryUsage(float defaultBatteryUsage) { if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Battery)) { return defaultBatteryUsage; } float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Battery].GetTrueValue() / 100f; float num2 = 1f / num; return defaultBatteryUsage * num2; } public static List<CodeInstruction> UseItemBatteriesOpCode(List<CodeInstruction> codes) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown FieldInfo field = typeof(Item).GetField("batteryUsage"); for (int i = 0; i < codes.Count; i++) { if (codes[i].opcode == OpCodes.Ldfld && (FieldInfo)codes[i].operand == field) { codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(BatteryLife).GetMethod("GetUseItemBatteryUsage"))); } } return codes; } public static float GetUpdateBatteryUsage(float defaultBatteryUsage) { if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Battery)) { return defaultBatteryUsage; } float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Battery].GetTrueValue() / 100f; return defaultBatteryUsage * num; } public static List<CodeInstruction> BatteryDegradeUpdateOpCode(List<CodeInstruction> codes) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown FieldInfo field = typeof(Item).GetField("batteryUsage"); for (int i = 0; i < codes.Count; i++) { if (codes[i].opcode == OpCodes.Ldfld && (FieldInfo)codes[i].operand == field) { codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(BatteryLife).GetMethod("GetUpdateBatteryUsage"))); } } return codes; } } internal class HandSlots { public static int currentSlotCount = 4; public static void HandSlotsUpdate(int updateValue) { if (!LethalPlugin.ReservedSlots && LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.HandSlot)) { LC_XP xpInstance = LP_NetworkManager.xpInstance; int num = (int)xpInstance.skillList.skills[UpgradeType.HandSlot].GetTrueValue(); int num2 = (int)Math.Floor((double)(num / 100)); ulong playerClientId = GameNetworkManager.Instance.localPlayerController.playerClientId; LethalPlugin.Log.LogInfo((object)$"Updating Player HandSlot {playerClientId}"); xpInstance.updateSPHandSlotsClientMessage.SendServer(num2); } } public static void UpdateHudSlots() { //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_0221: Unknown result type (might be due to invalid IL or missing references) //IL_022d: Unknown result type (might be due to invalid IL or missing references) //IL_0296: Unknown result type (might be due to invalid IL or missing references) //IL_029b: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) LC_XP xpInstance = LP_NetworkManager.xpInstance; float num = xpInstance.skillList.skills[UpgradeType.HandSlot].GetTrueValue() / 100f; int num2 = 4 + (int)Math.Floor(num); int num3 = num2 - currentSlotCount; GameObject val = GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD/Inventory"); List<string> list = new List<string> { "Slot0", "Slot1", "Slot2", "Slot3" }; for (int i = 0; i < val.transform.childCount; i++) { Transform child = val.transform.GetChild(i); if (!list.Contains(((Object)((Component)child).gameObject).name)) { Object.Destroy((Object)(object)((Component)child).gameObject); } } int num4 = (int)xpInstance.skillList.skills[UpgradeType.HandSlot].GetTrueValue(); int num5 = (int)Math.Floor((double)(num4 / 100)); Image[] array = (Image[])(object)new Image[num2]; array[0] = HUDManager.Instance.itemSlotIconFrames[0]; array[1] = HUDManager.Instance.itemSlotIconFrames[1]; array[2] = HUDManager.Instance.itemSlotIconFrames[2]; array[3] = HUDManager.Instance.itemSlotIconFrames[3]; Image[] array2 = (Image[])(object)new Image[num2]; array2[0] = HUDManager.Instance.itemSlotIcons[0]; array2[1] = HUDManager.Instance.itemSlotIcons[1]; array2[2] = HUDManager.Instance.itemSlotIcons[2]; array2[3] = HUDManager.Instance.itemSlotIcons[3]; GameObject val2 = GameObject.Find("Systems/UI/Canvas/IngamePlayerHUD/Inventory/Slot3"); GameObject templateSlot = LethalPlugin.SlotTemplate.GetTemplateSlot(); GameObject val3 = val2; currentSlotCount = num2; for (int j = 0; j < (int)num; j++) { GameObject val4 = Object.Instantiate<GameObject>(templateSlot); ((Object)val4).name = $"Slot{3 + (j + 1)}"; val4.transform.SetParent(val.transform); Vector3 localPosition = val3.transform.localPosition; val4.transform.SetLocalPositionAndRotation(new Vector3(localPosition.x + 50f, localPosition.y, localPosition.z), val3.transform.localRotation); val3 = val4; array[3 + (j + 1)] = val4.GetComponent<Image>(); array2[3 + (j + 1)] = ((Component)val4.transform.GetChild(0)).GetComponent<Image>(); val4.SetActive(true); } for (int k = 0; k < array.Length; k++) { Vector3 localPosition2 = ((Component)array[k]).transform.localPosition; ((Component)array[k]).transform.SetLocalPositionAndRotation(new Vector3(localPosition2.x - (float)(num3 * 25), localPosition2.y, localPosition2.z), ((Component)array[k]).transform.localRotation); } HUDManager.Instance.itemSlotIconFrames = array; HUDManager.Instance.itemSlotIcons = array2; } public static bool IsItemSwitchPossible(PlayerControllerB player) { return (double)player.timeSinceSwitchingSlots >= 0.01 && !player.inTerminalMenu && !player.isGrabbingObjectAnimation && !player.inSpecialInteractAnimation && !player.throwingObject && !player.isTypingChat && !player.twoHanded && !player.activatingItem && !player.jetpackControls && !player.disablingJetpackControls; } public static bool SwitchItemSlots(PlayerControllerB player, int requestedSlot) { if (!IsItemSwitchPossible(player) || player.currentItemSlot == requestedSlot) { return false; } LethalPlugin.Log.LogDebug((object)$"Trying to switch to slot {requestedSlot}"); int num = player.currentItemSlot - requestedSlot; bool flag = num > 0; if (Math.Abs(num) == player.ItemSlots.Length - 1) { player.SwitchItemSlotsServerRpc(flag); } else { do { player.SwitchItemSlotsServerRpc(flag); num += ((!flag) ? 1 : (-1)); } while (num != 0); } ShipBuildModeManager.Instance.CancelBuildMode(true); player.playerBodyAnimator.SetBool("GrabValidated", false); LethalPlugin.Log.LogDebug((object)$"Switched to slot {requestedSlot}"); player.SwitchToItemSlot(requestedSlot, (GrabbableObject)null); if ((Object)(object)player.currentlyHeldObjectServer != (Object)null) { ((Component)player.currentlyHeldObjectServer).gameObject.GetComponent<AudioSource>().PlayOneShot(player.currentlyHeldObjectServer.itemProperties.grabSFX, 0.6f); } return true; } } internal class HPRegen { public static List<CodeInstruction> DisableBaseGameHPRegen(List<CodeInstruction> codes) { //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Expected O, but got Unknown if (!Object.op_Implicit((Object)(object)LP_NetworkManager.xpInstance) || !LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.HPRegen)) { return codes; } FieldInfo field = typeof(PlayerControllerB).GetField("health"); for (int i = 0; i < codes.Count; i++) { if (!(codes[i].opcode != OpCodes.Ldfld) && !((FieldInfo)codes[i].operand != field) && !(codes[i + 1].opcode != OpCodes.Ldc_I4) && (int)codes[i + 1].operand == 20 && !(codes[i + 2].opcode != OpCodes.Bge_S)) { codes.Insert(i + 2, new CodeInstruction(OpCodes.Pop, (object)null)); codes.Insert(i + 3, new CodeInstruction(OpCodes.Dup, (object)null)); } } return codes; } } internal class JumpHeight { public static float GetJumpForce(float defaultJumpForce) { if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.JumpHeight)) { return defaultJumpForce; } float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.JumpHeight].GetTrueValue() / 100f; return defaultJumpForce * num; } public static List<CodeInstruction> PlayerJumpOpCode(List<CodeInstruction> codes) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown FieldInfo field = typeof(PlayerControllerB).GetField("jumpForce"); for (int i = 0; i < codes.Count; i++) { if (codes[i].opcode == OpCodes.Ldfld && (FieldInfo)codes[i].operand == field) { codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(JumpHeight).GetMethod("GetJumpForce"))); } } return codes; } } internal class LootValue { public static float GetScrapValueMultiplier(float defaultScrapValueMultiplier) { if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Value)) { return defaultScrapValueMultiplier; } float multiplier = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Value].GetMultiplier(); float num = (float)LP_NetworkManager.xpInstance.teamLootLevel.Value * multiplier; float num2 = 1f + num / 100f; return defaultScrapValueMultiplier * num2; } public static List<CodeInstruction> ScrapValueMultiplierOpCode(List<CodeInstruction> codes) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown FieldInfo field = typeof(RoundManager).GetField("scrapValueMultiplier"); for (int i = 0; i < codes.Count; i++) { if (codes[i].opcode == OpCodes.Ldfld && (FieldInfo)codes[i].operand == field) { codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(LootValue).GetMethod("GetScrapValueMultiplier"))); } } return codes; } public static void LootValueUpdate(int change) { if (LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Value)) { LP_NetworkManager.xpInstance.updateTeamLootLevelClientMessage.SendServer(change); } } } public static class SprintSpeed { public static float GetSprintSpeed(float defaultSprintSpeed) { if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.SprintSpeed)) { return defaultSprintSpeed; } float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.SprintSpeed].GetTrueValue() / 100f; return defaultSprintSpeed * num; } public static List<CodeInstruction> PlayerSprintSpeedOpCode(List<CodeInstruction> codes) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown for (int i = 0; i < codes.Count; i++) { if (codes[i].opcode == OpCodes.Ldc_R4 && codes[i].operand.Equals(2.25f)) { codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(SprintSpeed).GetMethod("GetSprintSpeed"))); } } return codes; } } internal class Stamina { public static float GetJumpStaminaUsage(float defaultJumpStaminaUsage) { if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Stamina)) { return defaultJumpStaminaUsage; } float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Stamina].GetTrueValue() / 100f; float num2 = 1f / num; return defaultJumpStaminaUsage * num2; } public static List<CodeInstruction> PlayerJumpStaminaOpCode(List<CodeInstruction> codes) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown for (int i = 0; i < codes.Count; i++) { if (codes[i].opcode == OpCodes.Ldc_R4 && codes[i].operand.Equals(0.08f)) { codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(Stamina).GetMethod("GetJumpStaminaUsage"))); } } return codes; } public static float GetSprintTime(float defaultStaminaTime) { if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Stamina)) { return defaultStaminaTime; } float num = 1f + LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Stamina].GetTrueValue() / 100f; return defaultStaminaTime * num; } public static List<CodeInstruction> PlayerSprintTimeOpCode(List<CodeInstruction> codes) { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown FieldInfo field = typeof(PlayerControllerB).GetField("sprintTime"); for (int i = 0; i < codes.Count; i++) { if (codes[i].opcode == OpCodes.Ldfld && (FieldInfo)codes[i].operand == field) { codes.Insert(i + 1, new CodeInstruction(OpCodes.Call, (object)typeof(Stamina).GetMethod("GetSprintTime"))); } } return codes; } } [HarmonyPatch] internal class Strength { public static void StrengthUpdate(int change = 0) { if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.Strength) || LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Strength].GetLevel() == 0) { return; } PlayerControllerB localPlayerController = GameNetworkManager.Instance.localPlayerController; List<GrabbableObject> list = localPlayerController.ItemSlots.ToList(); LethalPlugin.Log.LogDebug((object)$"Carry weight was {localPlayerController.carryWeight}"); float trueValue = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Strength].GetTrueValue(); float num = trueValue / 100f; float num2 = 0f; foreach (GrabbableObject item in list) { if (!((Object)(object)item == (Object)null)) { float num3 = item.itemProperties.weight - 1f; num3 *= 1f - num; num2 += num3; LethalPlugin.Log.LogDebug((object)$"Item weight was {item.itemProperties.weight - 1f} and is now {num3}"); LethalPlugin.Log.LogDebug((object)$"Adding carryweight.. now up to {num2}"); } } localPlayerController.carryWeight = Math.Clamp(1f + num2, 0f, 10f); LethalPlugin.Log.LogDebug((object)$"Player carry weight is now {localPlayerController.carryWeight}"); } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "GrabObjectClientRpc")] private static void UpdateObjects() { StrengthUpdate(); } [HarmonyPostfix] [HarmonyPatch(typeof(GrabbableObject), "DiscardItem")] private static void UpdateByDiscard(GrabbableObject __instance) { if (((NetworkBehaviour)__instance).IsOwner) { StrengthUpdate(); } } } } namespace LethalProgression.Saving { internal struct SaveData { public ulong steamId; public int skillPoints; public Dictionary<UpgradeType, int> skillAllocation; public SaveData(ulong steamId, int skillPoints) { skillAllocation = new Dictionary<UpgradeType, int>(); this.steamId = steamId; this.skillPoints = skillPoints; } } internal static class SaveManager { public static int saveFileSlot; public static void TriggerHostProfileSave() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ulong num = SteamId.op_Implicit(SteamClient.SteamId); SaveData saveData = default(SaveData); saveData.steamId = num; saveData.skillPoints = LP_NetworkManager.xpInstance.skillPoints; saveData.skillAllocation = new Dictionary<UpgradeType, int>(); SaveData saveData2 = saveData; foreach (KeyValuePair<UpgradeType, Skill> skill in LP_NetworkManager.xpInstance.skillList.skills) { LethalPlugin.Log.LogInfo((object)$"Skill is {skill.Key} and value is {skill.Value.GetLevel()}"); saveData2.skillAllocation.Add(skill.Key, skill.Value.GetLevel()); } LethalPlugin.Log.LogInfo((object)$"Invoke saveProfileDataClientMessage({num}, {JsonConvert.SerializeObject((object)saveData2)})"); LP_NetworkManager.xpInstance.saveProfileDataClientMessage.SendServer(JsonConvert.SerializeObject((object)new SaveProfileData(num, saveData2))); } public static void Save(ulong steamid, SaveData data) { saveFileSlot = GameNetworkManager.Instance.saveFileNum; LethalPlugin.Log.LogInfo((object)$"Saving to slot {saveFileSlot + 1} in {GetSavePath()}"); if (!Directory.Exists(GetSavePath())) { Directory.CreateDirectory(GetSavePath()); } File.WriteAllText(GetSavePath() + steamid + ".json", JsonConvert.SerializeObject((object)data)); } public static void SaveShared(int xp, int level, int quota) { saveFileSlot = GameNetworkManager.Instance.saveFileNum; LethalPlugin.Log.LogInfo((object)("Saving to slot " + saveFileSlot + 1)); if (!Directory.Exists(GetSavePath())) { Directory.CreateDirectory(GetSavePath()); } File.WriteAllText(GetSavePath() + "shared.json", JsonConvert.SerializeObject((object)new SaveSharedData(xp, level, quota))); } public static void DeleteSave(int _saveFileSlot) { saveFileSlot = _saveFileSlot; if (Directory.Exists(GetSavePath())) { Directory.Delete(Application.persistentDataPath + "/lethalprogression/save" + (saveFileSlot + 1), recursive: true); } } public static string GetSavePath() { return Application.persistentDataPath + "/lethalprogression/save" + (saveFileSlot + 1) + "/"; } public static string LoadPlayerFile(ulong steamId) { saveFileSlot = GameNetworkManager.Instance.saveFileNum; if (!File.Exists(GetSavePath() + steamId + ".json")) { LethalPlugin.Log.LogInfo((object)$"Player file for {steamId} doesn't exist"); return null; } LethalPlugin.Log.LogInfo((object)$"Player file for {steamId} found"); return File.ReadAllText(GetSavePath() + steamId + ".json"); } public static SaveSharedData? LoadSharedFile() { saveFileSlot = GameNetworkManager.Instance.saveFileNum; if (!File.Exists(GetSavePath() + "shared.json")) { LethalPlugin.Log.LogInfo((object)"Shared file doesn't exist"); return null; } LethalPlugin.Log.LogInfo((object)"Shared file exists"); string text = File.ReadAllText(GetSavePath() + "shared.json"); return JsonConvert.DeserializeObject<SaveSharedData>(text); } } internal struct SaveSharedData { public int xp; public int level; public int quota; public SaveSharedData(int xp, int level, int quota) { this.xp = xp; this.level = level; this.quota = quota; } } } namespace LethalProgression.Properties { [GeneratedCode("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] [DebuggerNonUserCode] [CompilerGenerated] internal class Resources { private static ResourceManager resourceMan; private static CultureInfo resourceCulture; [EditorBrowsable(EditorBrowsableState.Advanced)] internal static ResourceManager ResourceManager { get { if (resourceMan == null) { ResourceManager resourceManager = new ResourceManager("LethalProgression.Properties.Resources", typeof(Resources).Assembly); resourceMan = resourceManager; } return resourceMan; } } [EditorBrowsable(EditorBrowsableState.Advanced)] internal static CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } internal static byte[] skillmenu { get { object @object = ResourceManager.GetObject("skillmenu", resourceCulture); return (byte[])@object; } } internal Resources() { } } } namespace LethalProgression.Patches { [HarmonyPatch] internal class SavePatches { [HarmonyPostfix] [HarmonyPatch(typeof(DeleteFileButton), "DeleteFile")] private static void DeleteSaveFile(DeleteFileButton __instance) { SaveManager.DeleteSave(__instance.fileToDelete); } } [HarmonyPatch] internal class EnemyAIPatch { private static Dictionary<string, int> _enemyReward = new Dictionary<string, int> { { "HoarderBug (EnemyType)", 30 }, { "BaboonBird (EnemyType)", 15 }, { "MouthDog (EnemyType)", 200 }, { "Centipede (EnemyType)", 30 }, { "Flowerman (EnemyType)", 200 }, { "SandSpider (EnemyType)", 50 }, { "Crawler (EnemyType)", 50 }, { "Puffer (EnemyType)", 15 } }; [HarmonyPostfix] [HarmonyPatch(typeof(EnemyAI), "KillEnemy")] private static void CalculateXPForEnemyDeath(EnemyAI __instance) { if (GameNetworkManager.Instance.isHostingGame) { string text = ((object)__instance.enemyType).ToString(); LethalPlugin.Log.LogInfo((object)("Enemy type: " + text)); int num = 30; if (_enemyReward.ContainsKey(text)) { num = _enemyReward[text]; } LP_NetworkManager.xpInstance.updateTeamXPClientMessage.SendServer(num); } } [HarmonyPostfix] [HarmonyPatch(typeof(EnemyAI), "HitEnemyServerRpc")] private static void HitEnemyTrigger(EnemyAI __instance, int force, int playerWhoHit) { LethalPlugin.Log.LogInfo((object)$"Player {playerWhoHit} hit enemy {((object)__instance).GetType()} with force {force}"); } } [HarmonyPatch] internal class GameNetworkManagerPatch { [HarmonyPostfix] [HarmonyPatch(typeof(GameNetworkManager), "Disconnect")] private static void DisconnectXPHandler() { if (LP_NetworkManager.xpInstance.skillList.GetSkill(UpgradeType.Value).GetLevel() != 0) { int level = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Value].GetLevel(); LP_NetworkManager.xpInstance.updateTeamLootLevelClientMessage.SendServer(-level); } HandSlots.currentSlotCount = 4; LethalPlugin.SkillsGUI.CleanupGUI(); LethalPlugin.SkillsGUI.CloseSkillMenu(); } [HarmonyPrefix] [HarmonyPatch(typeof(GameNetworkManager), "SaveGame")] [HarmonyPriority(800)] private static void SaveGamePrefix() { LethalPlugin.Log.LogDebug((object)"Invoked DoSave via SaveGame"); SaveManager.TriggerHostProfileSave(); } } [HarmonyPatch] internal class GrabbableObjectPatch { [HarmonyTranspiler] [HarmonyPatch(typeof(GrabbableObject), "UseItemBatteries")] private static IEnumerable<CodeInstruction> UseItemBatteriesTranspiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> codes = new List<CodeInstruction>(instructions); return BatteryLife.UseItemBatteriesOpCode(codes); } [HarmonyTranspiler] [HarmonyPatch(typeof(GrabbableObject), "Update")] private static IEnumerable<CodeInstruction> UpdateTranspiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> codes = new List<CodeInstruction>(instructions); return BatteryLife.BatteryDegradeUpdateOpCode(codes); } } [HarmonyPatch] internal class HUDManagerPatch { private static GameObject _tempBar; private static GameObject _bottomMiddle; private static TextMeshProUGUI _tempText; private static float _tempBarTime; private static GameObject levelText; private static float levelTextTime; [HarmonyPrefix] [HarmonyPatch(typeof(HUDManager), "AddNewScrapFoundToDisplay")] private static void GiveXPForScrap(GrabbableObject GObject) { if (GameNetworkManager.Instance.isHostingGame) { int scrapValue = GObject.scrapValue; float multiplier = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.Value].GetMultiplier(); float num = (float)LP_NetworkManager.xpInstance.teamLootLevel.Value * multiplier; float num2 = 1f + num / 100f; int num3 = (int)Math.Floor((float)scrapValue / num2); LP_NetworkManager.xpInstance.updateTeamXPClientMessage.SendServer(num3); } } public static void ShowXPUpdate() { if (!Object.op_Implicit((Object)(object)_tempBar)) { MakeBar(); } LC_XP xpInstance = LP_NetworkManager.xpInstance; GameObject val = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddleXPStatus/XPUpdate/XPBarProgress"); val.GetComponent<Image>().fillAmount = (float)xpInstance.teamXP.Value / (float)xpInstance.CalculateXPRequirement(); ((TMP_Text)_tempText).text = xpInstance.teamXP.Value + " / " + (float)xpInstance.CalculateXPRequirement(); _tempBarTime = 2f; if (!_tempBar.activeSelf) { ((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(XPBarCoroutine()); } } private static IEnumerator XPBarCoroutine() { _tempBar.SetActive(true); while (_tempBarTime > 0f) { float time = _tempBarTime; _tempBarTime = 0f; yield return (object)new WaitForSeconds(time); } _tempBar.SetActive(false); } public static void ShowLevelUp() { if (!Object.op_Implicit((Object)(object)levelText)) { MakeLevelUp(); } levelTextTime = 5f; if (!levelText.gameObject.activeSelf) { ((MonoBehaviour)GameNetworkManager.Instance).StartCoroutine(LevelUpCoroutine()); } } public static void MakeLevelUp() { levelText = Object.Instantiate<GameObject>(LethalPlugin.skillBundle.LoadAsset<GameObject>("LevelUp")); ((TMP_Text)((Component)levelText.transform.GetChild(0)).GetComponent<TextMeshProUGUI>()).text = "Level Up! Spend your skill points."; levelText.gameObject.SetActive(false); } private static IEnumerator LevelUpCoroutine() { levelText.gameObject.SetActive(true); while (levelTextTime > 0f) { float time = levelTextTime; levelTextTime = 0f; yield return (object)new WaitForSeconds(time); } levelText.gameObject.SetActive(false); } private static void MakeBar() { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) LethalPlugin.XPBarGUI.CreateAllObjectsIfRequired(); GameObject val = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD"); GameObject val2 = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddle"); _bottomMiddle = Object.Instantiate<GameObject>(val2); _bottomMiddle.transform.SetParent(val.transform, false); ((Object)_bottomMiddle).name = "BottomMiddleXPStatus"; foreach (Transform item in _bottomMiddle.transform) { Transform val3 = item; Object.Destroy((Object)(object)((Component)val3).gameObject); } GameObject val4 = GameObject.Find("/Systems/UI/Canvas/QuickMenu/XpInfoContainer/XPBar"); _tempBar = Object.Instantiate<GameObject>(val4); ((Object)_tempBar).name = "XPUpdate"; _tempBar.SetActive(false); _tempText = _tempBar.GetComponentInChildren<TextMeshProUGUI>(); _tempBar.transform.SetParent(_bottomMiddle.transform, false); _tempBar.transform.localScale = new Vector3(0.4f, 0.4f, 0.4f); GameObject val5 = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddleXPStatus/XPUpdate/XPLevel"); Object.Destroy((Object)(object)val5); GameObject val6 = GameObject.Find("/Systems/UI/Canvas/IngamePlayerHUD/BottomMiddleXPStatus/XPUpdate/XPProfit"); Object.Destroy((Object)(object)val6); Vector3 localPosition = _bottomMiddle.transform.localPosition; float x = _bottomMiddle.GetComponent<RectTransform>().sizeDelta.x; float x2 = _tempBar.GetComponent<RectTransform>().sizeDelta.x; LethalPlugin.Log.LogInfo((object)$"Move Bar {x} {x2}"); _tempBar.transform.Translate(0f, 0f, 0f); _tempBar.transform.localPosition = new Vector3(x + 50f, localPosition.y - 30f, localPosition.z); } } [HarmonyPatch] internal class PlayerControllerBPatch { [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")] private static void ConnectClientToPlayerObjectHandler() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ulong num = SteamId.op_Implicit(SteamClient.SteamId); LethalPlugin.Log.LogInfo((object)$"Player {num} has joined the game."); LP_NetworkManager.xpInstance.requestProfileDataClientMessage.SendServer(num); } [HarmonyTranspiler] [HarmonyPatch(/*Could not decode attribute arguments.*/)] private static IEnumerable<CodeInstruction> PlayerJumpTranspiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> codes = new List<CodeInstruction>(instructions); return JumpHeight.PlayerJumpOpCode(codes); } [HarmonyTranspiler] [HarmonyPatch(typeof(PlayerControllerB), "Jump_performed")] private static IEnumerable<CodeInstruction> Jump_performedTransplier(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> codes = new List<CodeInstruction>(instructions); return Stamina.PlayerJumpStaminaOpCode(codes); } [HarmonyTranspiler] [HarmonyPatch(typeof(PlayerControllerB), "Update")] private static IEnumerable<CodeInstruction> UpdateTranspiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> codes = new List<CodeInstruction>(instructions); codes = JumpHeight.PlayerJumpOpCode(codes); return SprintSpeed.PlayerSprintSpeedOpCode(codes); } [HarmonyTranspiler] [HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")] private static IEnumerable<CodeInstruction> LateUpdateTranspiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> codes = new List<CodeInstruction>(instructions); codes = HPRegen.DisableBaseGameHPRegen(codes); return Stamina.PlayerSprintTimeOpCode(codes); } [HarmonyPostfix] [HarmonyPatch(typeof(PlayerControllerB), "LateUpdate")] private static void HPRegenUpdate(PlayerControllerB __instance) { if (!LP_NetworkManager.xpInstance.skillList.IsSkillValid(UpgradeType.HPRegen)) { return; } if (__instance.healthRegenerateTimer > 0f) { __instance.healthRegenerateTimer -= Time.deltaTime; return; } Skill skill = LP_NetworkManager.xpInstance.skillList.skills[UpgradeType.HPRegen]; __instance.healthRegenerateTimer = 1f / skill.GetTrueValue(); __instance.health++; if (__instance.health >= 20) { __instance.MakeCriticallyInjured(false); } if (((NetworkBehaviour)__instance).IsOwner && (!((NetworkBehaviour)__instance).IsServer || __instance.isHostPlayerObject) && __instance.isPlayerControlled && __instance.health < 100 && !__instance.isPlayerDead) { HUDManager.Instance.UpdateHealthUI(__instance.health, false); } } } [HarmonyPatch] internal class QuickMenuManagerPatch { [HarmonyPostfix] [HarmonyPatch(typeof(QuickMenuManager), "OpenQuickMenu")] private static void OpenQuickMenu_Postfix(QuickMenuManager __instance) { if (__instance.isMenuOpen) { LethalPlugin.XPBarGUI.Show(); } } [HarmonyPostfix] [HarmonyPatch(typeof(QuickMenuManager), "Update")] private static void QuickMenuManager_Postfix(QuickMenuManager __instance) { LethalPlugin.XPBarGUI.Update(__instance.mainButtonsPanel.activeSelf); if (!LethalPlugin.SkillsGUI.isMenuOpen) { LethalPlugin.SkillsGUI.CloseSkillMenu(); return; } IGeneralConfig active = LessShitConfigSystem.GetActive<IGeneralConfig>(); if (active.enableUnspecInShip && !active.disableUnspec) { if (GameNetworkManager.Instance.localPlayerController.isInHangarShipRoom) { LethalPlugin.SkillsGUI.SetUnspec(show: true); } else { LethalPlugin.SkillsGUI.SetUnspec(show: false); } } if (active.enableUnspecInOrbit) { if (StartOfRound.Instance.inShipPhase) { LethalPlugin.SkillsGUI.SetUnspec(show: true); } else { LethalPlugin.SkillsGUI.SetUnspec(show: false); } } if (active.disableUnspec) { LethalPlugin.SkillsGUI.SetUnspec(show: false); } LethalPlugin.SkillsGUI.OpenSkillMenu(); } [HarmonyPostfix] [HarmonyPatch(typeof(QuickMenuManager), "CloseQuickMenu")] private static void SkillMenuClose() { LethalPlugin.SkillsGUI.CloseSkillMenu(); } } [HarmonyPatch] internal class RoundManagerPatch { [HarmonyTranspiler] [HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")] private static IEnumerable<CodeInstruction> SpawnScrapInLevelTranspiler(IEnumerable<CodeInstruction> instructions) { List<CodeInstruction> codes = new List<CodeInstruction>(instructions); return LootValue.ScrapValueMultiplierOpCode(codes); } } [HarmonyPatch] internal class StartOfRoundPatch { [HarmonyPostfix] [HarmonyPatch(typeof(StartOfRound), "FirePlayersAfterDeadlineClientRpc")] private static void ResetXPValues(StartOfRound __instance) { IGeneralConfig active = LessShitConfigSystem.GetActive<IGeneralConfig>(); if (active.keepProgress) { return; } LC_XP xpInstance = LP_NetworkManager.xpInstance; int saveFileSlot = GameNetworkManager.Instance.saveFileNum + 1; SaveManager.DeleteSave(saveFileSlot); xpInstance.teamXPRequired.Value = xpInstance.CalculateXPRequirement(); foreach (Skill value in xpInstance.skillList.skills.Values) { value.SetLevel(0); } xpInstance.SetSkillPoints(5); xpInstance.teamXP.Value = 0; xpInstance.teamTotalValue.Value = 0; xpInstance.teamLevel.Value = 0; xpInstance.teamLootLevel.Value = 0; } } [HarmonyPatch] internal class TimeOfDayPatch { [HarmonyPostfix] [HarmonyPatch(typeof(TimeOfDay), "SetNewProfitQuota")] private static void ProfitQuotaUpdate(TimeOfDay __instance) { if (GameNetworkManager.Instance.isHostingGame) { LP_NetworkManager.xpInstance.teamXPRequired.Value = LP_NetworkManager.xpInstance.CalculateXPRequirement(); } } } } namespace LethalProgression.LessShitConfig { public static class LessShitConfigSystem { private static readonly IDictionary<ConfigDefinition, ConfigEntryData> entries = new Dictionary<ConfigDefinition, ConfigEntryData>(); private static readonly IDictionary<Type, ConfigSectionData> sections = new Dictionary<Type, ConfigSectionData>(); private static readonly IDictionary<Type, LocalConfigBase> localSections = new Dictionary<Type, LocalConfigBase>(); private static readonly IDictionary<Type, DictionaryOverlayConfigBase> activeSections = new Dictionary<Type, DictionaryOverlayConfigBase>(); private static readonly IDictionary<ConfigDefinition, object> hostConfigOverlay = new Dictionary<ConfigDefinition, object>(); public static object ActiveConfig { get; internal set; } public static void RegisterSection<T>() { Type typeFromHandle = typeof(T); LethalPlugin.Log.LogInfo((object)("RegisterSection: " + typeFromHandle.FullName)); if (sections.ContainsKey(typeFromHandle)) { throw new ConfigRegistrationException("The config section defintion has already been registered: " + typeFromHandle.FullName); } ConfigSectionData configSectionData = new ConfigSectionData(typeFromHandle); sections[typeFromHandle] = configSectionData; foreach (ConfigEntryData entry in configSectionData.Entries) { entries[entry.Definition] = entry; } } public static void Bake(ConfigFile configFile) { if (configFile == null) { throw new ArgumentNullException("config"); } if (localSections.Count > 0) { throw new InvalidOperationException("Calling Bind multiple times is not allowed."); } foreach (ConfigEntryData value in entries.Values) { value.Bind(configFile); } foreach (KeyValuePair<Type, ConfigSectionData> section in sections) { LocalConfigSectionClassBuilder localConfigSectionClassBuilder = new LocalConfigSectionClassBuilder(section.Value, configFile); foreach (ConfigEntryData entry in section.Value.Entries) { localConfigSectionClassBuilder.AddEntry(entry); } LocalConfigBase localConfigBase = localConfigSectionClassBuilder.Build(); localSections[section.Key] = localConfigBase; DictionaryOverlayConfigSectionClassBuilder dictionaryOverlayConfigSectionClassBuilder = new DictionaryOverlayConfigSectionClassBuilder(section.Value, localConfigBase, hostConfigOverlay); foreach (ConfigEntryData entry2 in section.Value.Entries) { dictionaryOverlayConfigSectionClassBuilder.AddEntry(entry2); } activeSections[section.Key] = dictionaryOverlayConfigSectionClassBuilder.Build(); } } internal static T GetActive<T>() { return (T)(object)activeSections[typeof(T)]; } internal static string SerializeLocalConfigs() { IDictionary<string, IDictionary<string, string>> dictionary = new Dictionary<string, IDictionary<string, string>>(); foreach (ConfigEntryData value2 in entries.Values) { string section = value2.Definition.Section; string key = value2.Definition.Key; if (!dictionary.ContainsKey(section)) { dictionary[section] = new Dictionary<string, string>(); } object value = localSections[value2.Section.InterfaceType].GetValue(value2.Definition); dictionary[section][key] = TomlTypeConverter.ConvertToString(value, value2.Property.PropertyType); } return JsonConvert.SerializeObject((object)dictionary); } internal static void ApplyHostConfigs(string configString) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected O, but got Unknown IDictionary<string, IDictionary<string, string>> dictionary = JsonConvert.DeserializeObject<IDictionary<string, IDictionary<string, string>>>(configString); foreach (KeyValuePair<string, IDictionary<string, string>> item in dictionary) { foreach (KeyValuePair<string, string> item2 in item.Value) { ConfigDefinition val = new ConfigDefinition(item.Key, item2.Key); Type propertyType = entries[val].Property.PropertyType; hostConfigOverlay[val] = TomlTypeConverter.ConvertToValue(item2.Value, propertyType); LethalPlugin.Log.LogInfo((object)$"Applied host config override: {val} = {item2.Value}"); } } } internal static void ClearHostConfigs() { hostConfigOverlay.Clear(); LethalPlugin.Log.LogInfo((object)"Cleared host config overrides"); } } } namespace LethalProgression.LessShitConfig.Internal { public class ConfigEntryData { public readonly ConfigSectionData Section; public readonly PropertyInfo Property; public readonly ConfigDefinition Definition; public readonly ConfigDescription Description; public readonly object DefaultValue; public ConfigEntryData(ConfigSectionData section, PropertyInfo property) { //IL_0181: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Expected O, but got Unknown if (!TomlTypeConverter.CanConvert(property.PropertyType)) { throw new ConfigRegistrationException("There is no TOML converter registered for " + property.PropertyType.FullName + " entries: " + section.InterfaceType.FullName); } if (property.CanWrite) { throw new ConfigRegistrationException("Config section entries must not have property setter: (" + property.Name + " in " + section.InterfaceType.FullName + ")"); } if (!property.CanRead) { throw new ConfigRegistrationException("Config section entries must have property getter: (" + property.Name + " in " + section.InterfaceType.FullName + ")"); } ConfigNameAttribute customAttribute = property.GetCustomAttribute<ConfigNameAttribute>(); if (customAttribute == null) { throw new ConfigRegistrationException("Config section must have a named defined with Configname (" + property.Name + " in " + section.InterfaceType.FullName + ")"); } ConfigDescriptionAttribute customAttribute2 = property.GetCustomAttribute<ConfigDescriptionAttribute>(); ConfigDefaultAttribute customAttribute3 = property.GetCustomAttribute<ConfigDefaultAttribute>(inherit: true); LethalPlugin.Log.LogInfo((object)("Register Property: " + section.Name + " " + customAttribute.name)); Section = section; Property = property; Definition = new ConfigDefinition(section.Name, customAttribute.name); Description = customAttribute2?.Description; DefaultValue = ResolveDefaultValue(customAttribute3); } private object ResolveDefaultValue(ConfigDefaultAttribute defaultValue) { if (defaultValue != null) { return defaultValue.Value; } return Property.PropertyType.IsValueType ? Activator.CreateInstance(Property.PropertyType) : null; } public void Bind(ConfigFile file) { MethodInfo methodInfo = typeof(ConfigFile).GetMethod("Bind", new Type[3] { typeof(ConfigDefinition), Type.MakeGenericMethodParameter(0), typeof(ConfigDescription) }).MakeGenericMethod(Property.PropertyType); methodInfo.Invoke(file, new List<object> { Definition, DefaultValue, Description }.ToArray()); } } public class ConfigRegistrationException : Exception { public ConfigRegistrationException(string message) : base(message) { } } public class ConfigSectionData { public readonly Type InterfaceType; public readonly ICollection<ConfigEntryData> Entries; public readonly string Name; public ConfigDescription Description { get; private set; } public ConfigSectionData(Type type) { if (!type.IsInterface) { throw new ConfigRegistrationException("Config section definitions must be interfaces: " + type.FullName); } ConfigSectionAttribute customAttribute = type.GetCustomAttribute<ConfigSectionAttribute>(); if (customAttribute == null) { throw new ConfigRegistrationException("Cannot register a config section without a ConfigSection attribute: " + type.FullName); } Name = customAttribute.section; InterfaceType = type; Entries = new List<ConfigEntryData>(); MemberInfo[] members = type.GetMembers(); foreach (MemberInfo memberInfo in members) { if (memberInfo.MemberType != MemberTypes.Property) { if (memberInfo.MemberType != MemberTypes.Method || !((MethodInfo)memberInfo).Name.StartsWith("get_")) { throw new ConfigRegistrationException($"Non-property members are not allowed in config section definitions: ({memberInfo.Name} is {memberInfo.MemberType})"); } } else { LethalPlugin.Log.LogInfo((object)("Register: " + type.Name + " = " + memberInfo.Name)); ConfigEntryData item = new ConfigEntryData(this, (PropertyInfo)memberInfo); Entries.Add(item); } } } } } namespace LethalProgression.LessShitConfig.Internal.ClassBuilders { public abstract class ConfigSectionClassBuilder { protected static readonly MethodAttributes propertyMethodAttributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.SpecialName; protected static readonly MethodInfo AbstractConfigBase_GetDefinitionMethod = typeof(AbstractConfigBase).GetMethod("GetDefinition", BindingFlags.Instance | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null); protected readonly TypeBuilder typeBuilder; protected readonly ILGenerator constructorGenerator; protected readonly ConfigSectionData sectionData; protected abstract Type ConfigBaseType { get; } protected abstract ConstructorInfo BaseConstructor { get; } public ConfigSectionClassBuilder(ConfigSectionData section) { sectionData = section; string text = "DynamicConfigClass_" + ConfigBaseType.Name + "_" + section.Name; AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(text), AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(text); typeBuilder = moduleBuilder.DefineType(ConfigBaseType.Name + "_" + section.Name, TypeAttributes.Public | TypeAttributes.AutoClass | TypeAttributes.BeforeFieldInit, ConfigBaseType, new Type[1] { section.InterfaceType }); Type[] parameterTypes = (from param in BaseConstructor.GetParameters() select param.ParameterType).ToArray(); ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, CallingConventions.Standard, parameterTypes); constructorGenerator = constructorBuilder.GetILGenerator(); AppendBaseConstructorOpcodes(); } protected abstract void AppendBaseConstructorOpcodes(); public void AddEntry(ConfigEntryData entry) { PropertyInfo property = entry.Property; Type propertyType = property.PropertyType; string fieldName = "Definition_" + property.Name; FieldBuilder field = typeBuilder.DefineField(fieldName, typeof(ConfigDefinition), FieldAttributes.Private); MethodInfo methodInfo = ConfigBaseType.GetMethods().First((MethodInfo m) => m.Name == "GetValue" && m.IsGenericMethod); constructorGenerator.Emit(OpCodes.Ldarg_0); constructorGenerator.Emit(OpCodes.Ldarg_0); constructorGenerator.Emit(OpCodes.Ldstr, entry.Definition.Key); constructorGenerator.Emit(OpCodes.Callvirt, AbstractConfigBase_GetDefinitionMethod); constructorGenerator.Emit(OpCodes.Stfld, field); string name = "get_" + property.Name; MethodBuilder methodBuilder = typeBuilder.DefineMethod(name, propertyMethodAttributes, propertyType, Type.EmptyTypes); ILGenerator iLGenerator = methodBuilder.GetILGenerator(); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldfld, field); iLGenerator.Emit(OpCodes.Callvirt, methodInfo.MakeGenericMethod(propertyType)); iLGenerator.Emit(OpCodes.Ret); PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(property.Name, PropertyAttributes.None, propertyType, Type.EmptyTypes); propertyBuilder.SetGetMethod(methodBuilder); } public AbstractConfigBase Build() { constructorGenerator.Emit(OpCodes.Ret); Type type = typeBuilder.CreateType(); return ConstructGeneratedType(type); } protected abstract AbstractConfigBase ConstructGeneratedType(Type type); } public class DictionaryOverlayConfigSectionClassBuilder : ConfigSectionClassBuilder { private readonly AbstractConfigBase baseConfig; private readonly IDictionary<ConfigDefinition, object> overlay; protected override Type ConfigBaseType => typeof(DictionaryOverlayConfigBase); protected override ConstructorInfo BaseConstructor => ConfigBaseType.GetConstructor(new Type[3] { typeof(string), typeof(AbstractConfigBase), typeof(Dictionary<ConfigDefinition, object>) }); public DictionaryOverlayConfigSectionClassBuilder(ConfigSectionData section, AbstractConfigBase baseConfig, IDictionary<ConfigDefinition, object> overlay) : base(section) { this.baseConfig = baseConfig; this.overlay = overlay; } protected override void AppendBaseConstructorOpcodes() { constructorGenerator.Emit(OpCodes.Ldarg_0); constructorGenerator.Emit(OpCodes.Ldarg_1); constructorGenerator.Emit(OpCodes.Ldarg_2); constructorGenerator.Emit(OpCodes.Ldarg_3); constructorGenerator.Emit(OpCodes.Call, BaseConstructor); } protected override AbstractConfigBase ConstructGeneratedType(Type type) { return (AbstractConfigBase)Activator.CreateInstance(type, sectionData.Name, baseConfig, overlay); } public new DictionaryOverlayConfigBase Build() { return (DictionaryOverlayConfigBase)base.Build(); } } public class LocalConfigSectionClassBuilder : ConfigSectionClassBuilder { private readonly ConfigFile configFile; protected override Type ConfigBaseType => typeof(LocalConfigBase); protected override ConstructorInfo BaseConstructor => ConfigBaseType.GetConstructor(new Type[2] { typeof(string), typeof(ConfigFile) }); public LocalConfigSectionClassBuilder(ConfigSectionData section, ConfigFile config) : base(section) { configFile = config; } protected override void AppendBaseConstructorOpcodes() { constructorGenerator.Emit(OpCodes.Ldarg_0); constructorGenerator.Emit(OpCodes.Ldarg_1); constructorGenerator.Emit(OpCodes.Ldarg_2); constructorGenerator.Emit(OpCodes.Call, BaseConstructor); } protected override AbstractConfigBase ConstructGeneratedType(Type type) { return (AbstractConfigBase)Activator.CreateInstance(type, sectionData.Name, configFile); } public new LocalConfigBase Build() { return (LocalConfigBase)base.Build(); } } } namespace LethalProgression.LessShitConfig.Sources { public abstract class AbstractConfigBase { private string sectionName; protected AbstractConfigBase(string sectionName) { this.sectionName = sectionName; } protected ConfigDefinition GetDefinition(string key) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown return new ConfigDefinition(sectionName, key); } public abstract object GetValue(ConfigDefinition definition); public abstract T GetValue<T>(ConfigDefinition definition); } public abstract class DictionaryOverlayConfigBase : AbstractConfigBase { private readonly AbstractConfigBase baseConfig; private readonly IDictionary<ConfigDefinition, object> overlay; public DictionaryOverlayConfigBase(string sectionName, AbstractConfigBase baseConfig, IDictionary<ConfigDefinition, object> overlay) : base(sectionName) { this.baseConfig = baseConfig; this.overlay = overlay; } public override object GetValue(ConfigDefinition definition) { if (overlay.TryGetValue(definition, out var value)) { return value; } return baseConfig.GetValue(definition); } public override T GetValue<T>(ConfigDefinition definition) { if (overlay.TryGetValue(definition, out var value)) { return (T)value; } return baseConfig.GetValue<T>(definition); } } public abstract class LocalConfigBase : AbstractConfigBase { private readonly ConfigFile configFile; public LocalConfigBase(string sectionName, ConfigFile config) : base(sectionName) { configFile = config; } public override object GetValue(ConfigDefinition definition) { IDictionary<ConfigDefinition, ConfigEntryBase> dictionary = (IDictionary<ConfigDefinition, ConfigEntryBase>)configFile; if (dictionary.TryGetValue(definition, out var value)) { return value.BoxedValue; } throw new ArgumentException($"The config entry {definition} is not registered.", "definition"); } public override T GetValue<T>(ConfigDefinition definition) { ConfigEntry<T> val = default(ConfigEntry<T>); if (configFile.TryGetEntry<T>(definition, ref val)) { return val.Value; } throw new ArgumentException($"The config entry {definition} is not registered.", "definition"); } } } namespace LethalProgression.LessShitConfig.Attributes { [AttributeUsage(AttributeTargets.Property)] public class ConfigDefaultAttribute : Attribute { public object Value; public ConfigDefaultAttribute(object value) { Value = value; } } [AttributeUsage(AttributeTargets.Property)] internal class ConfigDescriptionAttribute : Attribute { public readonly ConfigDescription Description; public ConfigDescriptionAttribute(string description) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Expected O, but got Unknown Description = new ConfigDescription(description, (AcceptableValueBase)null, Array.Empty<object>()); } } [AttributeUsage(AttributeTargets.Property)] internal class ConfigNameAttribute : Attribute { public readonly string name; public ConfigNameAttribute(string name) { this.name = name; } } [AttributeUsage(AttributeTargets.Interface)] internal class ConfigSectionAttribute : Attribute { public readonly string section; public ConfigSectionAttribute(string section) { this.section = section; } } } namespace LethalProgression.GUI.XPBar { internal class XPBarGUI { [CompilerGenerated] private static class <>O { public static UnityAction <0>__OpenSkillTree; } private GameObject xpBar; private GameObject xpInfoContainer; private GameObject xpBarProgress; private GameObject skillTreeButton; private TextMeshProUGUI xpText; private TextMeshProUGUI xpLevel; private TextMeshProUGUI profit; public void Show() { CreateAllObjectsIfRequired(); xpBar.SetActive(true); xpBarProgress.SetActive(true); } public void Update(bool active) { CreateAllObjectsIfRequired(); LC_XP xpInstance = LP_NetworkManager.xpInstance; xpInfoContainer.SetActive(active); ((TMP_Text)xpText).text = $"{xpInstance.GetXP()} / {xpInstance.teamXPRequired.Value}"; ((TMP_Text)xpLevel).text = $"Level: {xpInstance.GetLevel()}"; ((TMP_Text)profit).text = $"You've made.. {xpInstance.GetProfit()}$"; xpBarProgress.GetComponent<Image>().fillAmount = (float)xpInstance.GetXP() / (float)xpInstance.teamXPRequired.Value; } private void CreateContainer() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)xpInfoContainer)) { GameObject val = GameObject.Find("/Systems/UI/Canvas/QuickMenu"); xpInfoContainer = new GameObject("XpInfoContainer"); xpInfoContainer.transform.SetParent(val.transform, false); xpInfoContainer.transform.localScale = new Vector3(0.75f, 0.75f, 0.75f); xpInfoContainer.transform.Translate(-1.7f, 0.9f, 0f); } } private void CreateXPBar() { //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02cf: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)xpBar)) { GameObject val = GameObject.Find("/Systems/UI/Canvas/EndgameStats/LevelUp/LevelUpBox"); GameObject val2 = GameObject.Find("/Systems/UI/Canvas/EndgameStats/LevelUp/Total"); xpBar = Object.Instantiate<GameObject>(val); ((Object)xpBar).name = "XPBar"; xpBar.transform.SetParent(xpInfoContainer.transform, false); xpText = Object.Instantiate<GameObject>(val2).GetComponent<TextMeshProUGUI>(); ((Object)xpText).name = "XPText"; ((TMP_Text)xpText).SetText("0/1000", true); ((TMP_Text)xpText).alignment = (TextAlignmentOptions)514; ((Graphic)xpText).color = new Color(1f, 0.6f, 0f, 1f); ((TMP_Text)xpText).transform.SetParent(xpBar.transform, false); ((TMP_Text)xpText).transform.Translate(-0.75f, 0.21f, 0f); xpLevel = Object.Instantiate<GameObject>(val2).GetComponent<TextMeshProUGUI>(); ((Object)xpLevel).name = "XPLevel"; ((TMP_Text)xpLevel).SetText("Level: 0", true); ((TMP_Text)xpLevel).alignment = (TextAlignmentOptions)514; ((Graphic)xpLevel).color = new Color(1f, 0.6f, 0f, 1f); ((TMP_Text)xpLevel).transform.SetParent(xpInfoContainer.transform, false); ((TMP_Text)xpLevel).transform.position = new Vector3(xpBar.transform.position.x, xpBar.transform.position.y, xpBar.transform.position.z); ((TMP_Text)xpLevel).transform.Translate(-0.3f, 0.2f, 0f); profit = Object.Instantiate<GameObject>(val2).GetComponent<TextMeshProUGUI>(); ((Object)profit).name = "XPProfit"; ((TMP_Text)profit).SetText("You've made.. 0$.", true); ((Graphic)profit).color = new Color(1f, 0.6f, 0f, 1f); ((TMP_Text)profit).alignment = (TextAlignmentOptions)514; ((TMP_Text)profit).transform.SetParent(xpInfoContainer.transform, false); ((TMP_Text)profit).transform.position = new Vector3(xpBar.transform.position.x, xpBar.transform.position.y, xpBar.transform.position.z); ((TMP_Text)profit).transform.Translate(-0.1f, -0.2f, 0f); } } private void CreateXPBarProgress() { //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)xpBarProgress)) { GameObject val = GameObject.Find("/Systems/UI/Canvas/EndgameStats/LevelUp/LevelUpMeter"); xpBarProgress = Object.Instantiate<GameObject>(val); ((Object)xpBarProgress).name = "XPBarProgress"; xpBarProgress.GetComponent<Image>().fillAmount = 0f; xpBarProgress.transform.SetParent(xpBar.transform, false); xpBarProgress.transform.SetAsFirstSibling(); xpBarProgress.transform.localScale = new Vector3(0.597f, 5.21f, 1f); xpBarProgress.transform.Translate(-0.8f, 0.2f, 0f); xpBarProgress.transform.localPosition = new Vector3(0f, 0f, 0f); } } private void CreateSkillTreeButton() { //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: 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_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Expected O, but got Unknown //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Expected O, but got Unknown GameObject val = GameObject.Find("Systems/UI/Canvas/QuickMenu/MainButtons/Resume"); GameObject val2 = GameObject.Find("Systems/UI/Canvas/QuickMenu/MainButtons"); skillTreeButton = Object.Instantiate<GameObject>(val); ((Object)skillTreeButton).name = "Skills"; ((TMP_Text)skillTreeButton.GetComponentInChildren<TextMeshProUGUI>()).text = "> Skills"; skillTreeButton.transform.SetParent(val2.transform, false); skillTreeButton.transform.position = new Vector3(0.55f + xpBar.transform.position.x, 1.09f + xpBar.transform.position.y, xpBar.transform.position.z); Transform transform = ((TMP_Text)xpText).transform; skillTreeButton.transform.localPosition = new Vector3(transform.position.x, transform.position.y, transform.position.z); Transform transform2 = skillTreeButton.transform; transform2.position += new Vector3(-0.15f, 1.056f); ButtonClickedEvent val3 = new ButtonClickedEvent(); object obj = <>O.<0>__OpenSkillTree; if (obj == null) { UnityAction val4 = OpenSkillTree; <>O.<0>__OpenSkillTree = val4; obj = (object)val4; } ((UnityEvent)val3).AddListener((UnityAction)obj); skillTreeButton.GetComponent<Button>().onClick = val3; Button component = xpBar.GetComponent<Button>(); if (component == null) { component = xpBar.AddComponent<Button>(); component.onClick = val3; } component = xpBarProgress.GetComponent<Button>(); if (component == null) { component = xpBarProgress.AddComponent<Button>(); component.onClick = val3; } } public void CreateAllObjectsIfRequired() { if (!Object.op_Implicit((Object)(object)xpInfoContainer)) { CreateContainer(); } if (!Object.op_Implicit((Object)(object)xpBar)) { CreateXPBar(); } if (!Object.op_Implicit((Object)(object)xpBarProgress)) { CreateXPBarProgress(); } if (!Object.op_Implicit((Object)(object)skillTreeButton)) { CreateSkillTreeButton(); } } private static void OpenSkillTree() { LethalPlugin.SkillsGUI.OpenSkillMenu(); } } } namespace LethalProgression.GUI.Skills { internal class SkillsGUI { private GameObject mainPanel; private GameObject infoPanel; private List<GameObject> skillButtonsList = new List<GameObject>(); public bool isMenuOpen = false; public void OpenSkillMenu() { CreateAllObjectsIfRequired(); isMenuOpen = true; mainPanel.SetActive(true); GameObject val = GameObject.Find("Systems/UI/Canvas/QuickMenu/MainButtons"); val.SetActive(false); GameObject val2 = GameObject.Find("Systems/UI/Canvas/QuickMenu/PlayerList"); val2.SetActive(false); RealTimeUpdateInfo(); } public void CloseSkillMenu() { isMenuOpen = false; GameObject obj = mainPanel; if (obj != null) { obj.SetActive(false); } } public void CleanupGUI() { isMenuOpen = false; skillButtonsList = new List<GameObject>(); } private void CreateAllObjectsIfRequired() { if (!Object.op_Implicit((Object)(object)mainPanel)) { CreateMainSkillMenu(); } if (!Object.op_Implicit((Object)(object)infoPanel)) { CreateInfoPanel(); } } private void CreateMainSkillMenu() { if (!Object.op_Implicit((Object)(object)mainPanel)) { mainPanel = Object.Instantiate<GameObject>(LethalPlugin.skillBundle.LoadAsset<GameObject>("SkillMenu")); ((Object)mainPanel).name = "SkillMenu"; mainPanel.SetActive(false); } } private void CreateInfoPanel() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown infoPanel = ((Component)mainPanel.transform.GetChild(1)).gameObject; infoPanel.SetActive(false); GameObject gameObject = ((Component)mainPanel.transform.GetChild(4)).gameObject; gameObject.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)gameObject.GetComponent<Button>().onClick).AddListener(new UnityAction(BackButton)); if (LP_NetworkManager.xpInstance.skillList.skills == null) { return; } foreach (KeyValuePair<UpgradeType, Skill> skill in LP_NetworkManager.xpInstance.skillList.skills) { LethalPlugin.Log.LogInfo((object)("Creating button for " + skill.Value.GetShortName())); GameObject val = SetupUpgradeButton(skill.Value); LethalPlugin.Log.LogInfo((object)"Setup passed!"); skillButtonsList.Add(val); LethalPlugin.Log.LogInfo((object)"Added to skill list.."); LoadSkillData(skill.Value, val); } TeamLootHudUpdate(0); } public void BackButton() { CreateAllObjectsIfRequired(); isMenuOpen = false; GameObject val = GameObject.Find("Systems/UI/Canvas/QuickMenu/MainButtons"); val.SetActive(true); GameObject val2 = GameObject.Find("Systems/UI/Canvas/QuickMenu/PlayerList"); val2.SetActive(true); } public void SetUnspec(bool show) { CreateAllObjectsIfRequired(); GameObject gameObject = ((Component)infoPanel.transform.GetChild(6)).gameObject; GameObject gameObject2 = ((Component)infoPanel.transform.GetChild(7)).gameObject; GameObject gameObject3 = ((Component)infoPanel.transform.GetChild(8)).gameObject; gameObject.SetActive(show); gameObject2.SetActive(show); gameObject3.SetActive(show); IGeneralConfig active = LessShitConfigSystem.GetActive<IGeneralConfig>(); if (!active.disableUnspec) { GameObject gameObject4 = ((Component)infoPanel.transform.GetChild(9)).gameObject; gameObject4.SetActive(!show); } if (active.enableUnspecInOrbit) { GameObject gameObject5 = ((Component)infoPanel.transform.GetChild(9)).gameObject; ((TMP_Text)((Component)gameObject5.transform).GetComponent<TextMeshProUGUI>()).SetText("Return to orbit to unspec.", true); } } public GameObject SetupUpgradeButton(Skill skill) { //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Expected O, but got Unknown //IL_01c9: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Expected O, but got Unknown CreateAllObjectsIfRequired(); GameObject gameObject = ((Component)mainPanel.transform.GetChild(0)).gameObject; GameObject val = Object.Instantiate<GameObject>(gameObject); if (!Object.op_Implicit((Object)(object)gameObject)) { LethalPlugin.Log.LogError((object)"Couldn't find template button!"); return null; } ((Object)val).name = skill.GetShortName(); GameObject gameObject2 = ((Component)mainPanel.transform.GetChild(3)).gameObject; GameObject gameObject3 = ((Component)gameObject2.transform.GetChild(1)).gameObject; val.transform.SetParent(gameObject3.transform, false); GameObject gameObject4 = ((Component)val.transform.GetChild(0)).gameObject; ((TMP_Text)gameObject4.GetComponent<TextMeshProUGUI>()).SetText(skill.GetShortName(), true); GameObject gameObject5 = ((Component)val.transform.GetChild(1)).gameObject; ((TMP_Text)gameObject5.GetComponent<TextMeshProUGUI>()).SetText(skill.GetLevel().ToString(), true); GameObject gameObject6 = ((Component)val.transform.GetChild(2)).gameObject; ((TMP_Text)gameObject6.GetComponent<TextMeshProUGUI>()).SetText("(" + skill.GetLevel() + " " + skill.GetAttribute() + ")", true); ((TMP_Text)val.GetComponentInChildren<TextMeshProUGUI>()).SetText(skill.GetShortName() + ":", true); val.SetActive(true); val.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)val.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { UpdateStatInfo(skill); }); return val; } public void LoadSkillData(Skill skill, GameObject skillButton) { CreateAllObjectsIfRequired(); if (!skill._teamShared) { GameObject gameObject = ((Component)skillButton.transform.GetChild(1)).gameObject; ((TMP_Text)gameObject.GetComponent<TextMeshProUGUI>()).SetText(skill.GetLevel().ToString(), true); GameObject gameObject2 = ((Component)skillButton.transform.GetChild(2)).gameObject; ((TMP_Text)gameObject2.GetComponent<TextMeshProUGUI>()).SetText($"(+{(float)skill.GetLevel() * skill.GetMultiplier()}% {skill.GetAttribute()})", true); ((TMP_Text)skillButton.GetComponentInChildren<TextMeshProUGUI>()).SetText(skill.GetShortName() + ":", true); } } public void UpdateAllStats() { CreateAllObjectsIfRequired(); foreach (KeyValuePair<UpgradeType, Skill> skill in LP_NetworkManager.xpInstance.skillList.skills) { if (!skill.Value._teamShared) { GameObject skillButton = skillButtonsList.Find((GameObject x) => ((Object)x).name == skill.Value.GetShortName()); LoadSkillData(skill.Value, skillButton); } } } public void UpdateStatInfo(Skill skill) { //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Expected O, but got Unknown //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Expected O, but got Unknown //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Expected O, but got Unknown //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Expected O, but got Unknown //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Expected O, but got Unknown //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Expected O, but got Unknown //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Expected O, but got Unknown //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Expected O, but got Unknown //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Expected O, but got Unknown //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a8: Expected O, but got Unknown //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Expected O, but got Unknown //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Expected O, but got Unknown CreateAllObjectsIfRequired(); if (!infoPanel.activeSelf) { infoPanel.SetActive(true); } TextMeshProUGUI component = ((Component)infoPanel.transform.GetChild(0)).gameObject.GetComponent<TextMeshProUGUI>(); TextMeshProUGUI component2 = ((Component)infoPanel.transform.GetChild(1)).gameObject.GetComponent<TextMeshProUGUI>(); TextMeshProUGUI component3 = ((Component)infoPanel.transform.GetChild(2)).gameObject.GetComponent<TextMeshProUGUI>(); ((TMP_Text)component).SetText(skill.GetName(), true); if (skill.GetMaxLevel() == 99999) { ((TMP_Text)component2).SetText($"{skill.GetLevel()}", true); } else { ((TMP_Text)component2).SetText($"{skill.GetLevel()} / {skill.GetMaxLevel()}", true); } ((TMP_Text)component3).SetText(skill.GetDescription(), true); GameObject gameObject = ((Component)infoPanel.transform.GetChild(3)).gameObject; GameObject gameObject2 = ((Component)infoPanel.transform.GetChild(4)).gameObject; GameObject gameObject3 = ((Component)infoPanel.transform.GetChild(5)).gameObject; gameObject.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)gameObject.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { ModifySkillPoints(skill, 5); }); gameObject2.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)gameObject2.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { ModifySkillPoints(skill, 2); }); gameObject3.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)gameObject3.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { ModifySkillPoints(skill, 1); }); GameObject gameObject4 = ((Component)infoPanel.transform.GetChild(6)).gameObject; GameObject gameObject5 = ((Component)infoPanel.transform.GetChild(7)).gameObject; GameObject gameObject6 = ((Component)infoPanel.transform.GetChild(8)).gameObject; gameObject4.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)gameObject4.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { ModifySkillPoints(skill, -5); }); gameObject5.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)gameObject5.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { ModifySkillPoints(skill, -2); }); gameObject6.GetComponent<Button>().onClick = new ButtonClickedEvent(); ((UnityEvent)gameObject6.GetComponent<Button>().onClick).AddListener((UnityAction)delegate { ModifySkillPoints(skill, -1); }); } public void ModifyS