Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of CustomCurrency v1.0.0
CustomCurrency.dll
Decompiled a year agousing System; using System.Diagnostics; using System.Globalization; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using REPOLib.Modules; using TMPro; using UnityEngine; 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-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("Autodesk.Fbx")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("FbxBuildTestAssets")] [assembly: IgnoresAccessChecksTo("Klattersynth")] [assembly: IgnoresAccessChecksTo("Photon3Unity3D")] [assembly: IgnoresAccessChecksTo("PhotonChat")] [assembly: IgnoresAccessChecksTo("PhotonRealtime")] [assembly: IgnoresAccessChecksTo("PhotonUnityNetworking")] [assembly: IgnoresAccessChecksTo("PhotonUnityNetworking.Utilities")] [assembly: IgnoresAccessChecksTo("PhotonVoice.API")] [assembly: IgnoresAccessChecksTo("PhotonVoice")] [assembly: IgnoresAccessChecksTo("PhotonVoice.PUN")] [assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime")] [assembly: IgnoresAccessChecksTo("SingularityGroup.HotReload.Runtime.Public")] [assembly: IgnoresAccessChecksTo("Sirenix.OdinInspector.Attributes")] [assembly: IgnoresAccessChecksTo("Sirenix.Serialization.Config")] [assembly: IgnoresAccessChecksTo("Sirenix.Serialization")] [assembly: IgnoresAccessChecksTo("Sirenix.Utilities")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Formats.Fbx.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Postprocessing.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Antlr3.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Core")] [assembly: IgnoresAccessChecksTo("Unity.VisualScripting.Flow")] [assembly: IgnoresAccessChecksTo("Unity.VisualScripting.State")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: IgnoresAccessChecksTo("websocket-sharp")] [assembly: AssemblyCompany("Dj_Haski")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CustomCurrency")] [assembly: AssemblyTitle("CustomCurrency")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace CustomCurrency { [BepInPlugin("Dj_Haski.CustomCurrency", "CustomCurrency", "1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class CustomCurrency : BaseUnityPlugin { public static NetworkedEvent CurrencyRespectEvent; internal static CustomCurrency Instance { get; private set; } internal static ManualLogSource Logger => Instance._logger; private ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; internal Harmony? Harmony { get; set; } private void Awake() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Expected O, but got Unknown Instance = this; ((Component)this).gameObject.transform.parent = null; ((Object)((Component)this).gameObject).hideFlags = (HideFlags)61; Patch(); PluginConfig.Awake(((BaseUnityPlugin)this).Config); CurrencyRespectEvent = new NetworkedEvent("CurrencyRespectEvent", (Action<EventData>)OnCurrencyRespectEvent); Logger.LogInfo((object)$"v{((BaseUnityPlugin)this).Info.Metadata.Version} has loaded!"); } private static void OnCurrencyRespectEvent(EventData eventData) { if (PluginConfig.respectCurrencyPromotion.Value && eventData.CustomData != null) { string text = (string)eventData.CustomData; string[] array = text.Split(':'); if (array.Length != 2) { Logger.LogError((object)("Received invalid currency respect event: " + text)); return; } Logger.LogInfo((object)("Accepted incoming respect for currency name: " + text)); PluginConfig.UpdateCustomCurrency(array[0], array[1]); } } internal void Patch() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown if (Harmony == null) { Harmony val = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); } internal void Unpatch() { Harmony? harmony = Harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private void Update() { } } [HarmonyPatch(typeof(LoadingUI), "StartLoading")] public class PreLoadingPatch { public static void Prefix() { PluginConfig.ResetCustomCurrency(); } public static void Postfix() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) if (SemiFunc.IsMasterClient() && PluginConfig.promoteCurrencyOverNetwork.Value) { CustomCurrency.CurrencyRespectEvent.RaiseEvent((object)(PluginConfig.currentCurrency + ":" + PluginConfig.currentCulture), NetworkingEvents.RaiseOthers, SendOptions.SendReliable); } } } internal static class PluginConfig { public static ConfigEntry<string> currencyName = null; public static ConfigEntry<string> currencyCulture = null; public static ConfigEntry<bool> promoteCurrencyOverNetwork = null; public static ConfigEntry<bool> respectCurrencyPromotion = null; public static string currentCurrency = ""; public static string currentCulture = ""; public static void Awake(ConfigFile config) { currencyName = config.Bind<string>("General", "CurrencyName", "Rub", "The name of the currency in the game. Maximum 3 characters."); currencyCulture = config.Bind<string>("General", "CurrencyCulture", "ru-RU", "The culture to use for the currency, e.g. ru-RU, en-US, de-DE, etc. See https://www.csharp-examples.net/culture-names/ for more information."); promoteCurrencyOverNetwork = config.Bind<bool>("General", "PromoteCurrencyOverNetwork", true, "Whether to promote the currency and culture over the network for other players. Players will see your currency when they join automatically."); respectCurrencyPromotion = config.Bind<bool>("General", "RespectCurrencyPromotion", true, "Whether to respect the currency and culture promotion of other players. Disable, if you want to play with custom currency."); currentCurrency = currencyName.Value.Substring(0, Math.Min(3, currencyName.Value.Length)); if (currentCurrency.Length == 0) { CustomCurrency.Logger.LogError((object)"Currency name must be at least 1 character long. Defaulting to 'Rub'."); currentCurrency = "Rub"; } currentCulture = currencyCulture.Value; if (currentCulture.Length == 0) { CustomCurrency.Logger.LogError((object)"Currency culture must be at least 1 character long. Defaulting to 'ru-RU'."); currentCulture = "ru-RU"; } try { new CultureInfo(currentCulture); } catch { CustomCurrency.Logger.LogError((object)"Invalid currency culture. Defaulting to 'ru-RU'."); currentCulture = "ru-RU"; } } public static void UpdateCustomCurrency(string currencyName, string currencyCulture) { currentCurrency = currencyName.Substring(0, Math.Min(3, currencyName.Length)); currentCulture = currencyCulture; } public static void ResetCustomCurrency() { UpdateCustomCurrency(currencyName.Value, currencyCulture.Value); } } [HarmonyPatch(typeof(WorldSpaceUIValue), "Show")] internal class WorldSpaceUIValuePatch { public static void Postfix(WorldSpaceUIValue __instance, int _value, bool _cost) { if (_cost) { ((TMP_Text)__instance.text).text = Utils.GetFormattedCurrencyString(_value, prefixWithK: true); } else { ((TMP_Text)__instance.text).text = Utils.GetFormattedCurrencyString(_value); } } } [HarmonyPatch(typeof(WorldSpaceUIValueLost), "Start")] internal class WorldSpaceUIValueLostPatch { public static void Postfix(WorldSpaceUIValueLost __instance) { ((TMP_Text)__instance.text).text = "-" + Utils.GetFormattedCurrencyString(__instance.value); } } [HarmonyPatch] internal class ShopCostUIPatch { [MethodImpl(MethodImplOptions.NoInlining)] [HarmonyReversePatch(/*Could not decode attribute arguments.*/)] [HarmonyPatch(typeof(SemiUI), "Update")] private static void BaseUpdate(ShopCostUI instance) { throw null; } [HarmonyPatch(typeof(ShopCostUI), "Update")] public static bool Prefix(ShopCostUI __instance) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) BaseUpdate(__instance); if (SemiFunc.RunIsShop()) { int num = SemiFunc.ShopGetTotalCost(); if (num > 0) { ((TMP_Text)__instance.Text).text = Utils.GetFormattedCurrencyString(-num, prefixWithK: true); ((Graphic)__instance.Text).color = __instance.originalColor; } else { ((SemiUI)__instance).Hide(); } __instance.currentValue = num; if (__instance.currentValue != __instance.prevValue) { Color val = Color.white; if (__instance.currentValue > __instance.prevValue) { val = Color.red; } ((SemiUI)__instance).SemiUISpringShakeY(20f, 10f, 0.3f); ((SemiUI)__instance).SemiUITextFlashColor(val, 0.2f); ((SemiUI)__instance).SemiUISpringScale(0.4f, 5f, 0.2f); __instance.prevValue = __instance.currentValue; } } if (!SemiFunc.RunIsShop()) { ((SemiUI)__instance).Hide(); } if ((double)((SemiUI)__instance).showTimer <= 0.0 || !SemiFunc.RunIsLevel()) { return false; } ((TMP_Text)__instance.Text).text = "+" + Utils.GetFormattedCurrencyString(__instance.animatedValue, prefixWithK: true); ((Graphic)__instance.Text).color = Color.green; return false; } } [HarmonyPatch(typeof(PhysGrabCart), "SetHaulText")] internal class PhysGrabCartPatch { public static bool Prefix(PhysGrabCart __instance) { ((TMP_Text)__instance.displayText).text = Utils.GetFormattedCurrencyString(Mathf.Max(0, __instance.haulCurrent)); return false; } } [HarmonyPatch(typeof(CurrencyUI), "Update")] internal class CurrencyUIPatch { public static void Postfix(CurrencyUI __instance) { ((TMP_Text)__instance.Text).text = Utils.GetFormattedCurrencyString(SemiFunc.StatGetRunCurrency(), prefixWithK: true); } } [HarmonyPatch(typeof(CurrencyUI), "FetchCurrency")] internal class CurrencyUIPatch2 { public static bool Prefix(CurrencyUI __instance) { ((TMP_Text)__instance.Text).text = Utils.GetFormattedCurrencyString(SemiFunc.StatGetRunCurrency(), prefixWithK: true); return false; } } [HarmonyPatch(typeof(HaulUI), "Update")] internal class HaulUIPatch { public static void Postfix(HaulUI __instance) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) string text; if (SemiFunc.RunIsLevel()) { if (!RoundDirector.instance.extractionPointActive) { return; } int currentHaul = RoundDirector.instance.currentHaul; int amount = Mathf.Max(0, currentHaul); int extractionHaulGoal = RoundDirector.instance.extractionHaulGoal; text = "<size=30>" + Utils.GetFormattedCurrencyString(amount, prefixWithK: false, "#558B2F") + "<color=#616161> <size=45>/</size> </color><u>" + Utils.GetFormattedCurrencyString(extractionHaulGoal, prefixWithK: false, "#558B2F"); if (__instance.currentHaulValue > __instance.prevHaulValue) { ((SemiUI)__instance).SemiUISpringShakeY(10f, 10f, 0.3f); ((SemiUI)__instance).SemiUISpringScale(0.05f, 5f, 0.2f); ((SemiUI)__instance).SemiUITextFlashColor(Color.green, 0.2f); __instance.prevHaulValue = __instance.currentHaulValue; } if (__instance.currentHaulValue < __instance.prevHaulValue) { ((SemiUI)__instance).SemiUISpringShakeY(10f, 10f, 0.3f); ((SemiUI)__instance).SemiUISpringScale(0.05f, 5f, 0.2f); ((SemiUI)__instance).SemiUITextFlashColor(Color.red, 0.2f); __instance.prevHaulValue = __instance.currentHaulValue; } } else { text = Utils.GetFormattedCurrencyString(SemiFunc.StatGetRunCurrency(), prefixWithK: false, "#558B2F"); ((SemiUI)__instance).Hide(); } ((TMP_Text)__instance.Text).text = text; } } [HarmonyPatch] internal class ExtractionPointPatch { [HarmonyPatch(typeof(ExtractionPoint), "SetHaulText")] public static bool Prefix(ExtractionPoint __instance) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if (!__instance.isShop) { ((TMP_Text)__instance.haulGoalScreen).text = Utils.GetFormattedCurrencyString(Mathf.Max(0, __instance.haulCurrent), prefixWithK: false, "#bd4300"); __instance.haulBarTargetScale = (float)__instance.haulCurrent / (float)__instance.haulGoal; } else { ((TMP_Text)__instance.haulGoalScreen).text = Utils.GetFormattedCurrencyString(__instance.haulGoal - __instance.haulCurrent, prefixWithK: false, "#bd4300"); if (__instance.haulGoal - __instance.haulCurrent >= 0) { return false; } ((TMP_Text)__instance.haulGoalScreen).text = Utils.GetFormattedCurrencyString(__instance.haulGoal - __instance.haulCurrent); ((Graphic)__instance.haulGoalScreen).color = Color.red; } return false; } [HarmonyPatch(typeof(ExtractionPoint), "StateSurplus")] public static void Postfix(ExtractionPoint __instance) { if (((TMP_Text)__instance.haulGoalScreen).text.Contains("+$")) { ((TMP_Text)__instance.haulGoalScreen).text = "+" + Utils.GetFormattedCurrencyString(__instance.haulSurplusAnimated); } } } [HarmonyPatch(typeof(ExtractionPoint), "StateSuccess")] internal class ExtractionPointStatePatch { public static void Postfix(ExtractionPoint __instance) { if (__instance.stateStart) { ((TMP_Text)__instance.haulGoalScreen).text = Utils.GetFormattedCurrencyString(__instance.haulSurplusAnimated); } } } internal class Utils { public static string GetFormattedCurrencyString(int amount, bool prefixWithK = false, string? prefixColor = null) { CultureInfo cultureInfo = new CultureInfo(PluginConfig.currentCulture); string text = " " + PluginConfig.currentCurrency; if (prefixColor != null) { text = "<color=" + prefixColor + ">" + text + "</color>"; } return amount.ToString("N0", cultureInfo) + (prefixWithK ? "K" : "") + text; } public static string GetFormattedCurrencyString(float amount, bool prefixWithK = false, string? prefixColor = null) { return GetFormattedCurrencyString((int)amount, prefixWithK, prefixColor); } } }