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 ValuableBreakNotifier v1.0.0
plugins/ValuableBreakNotifier.dll
Decompiled 7 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; 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: AssemblyCompany("ValuableBreakNotifier")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyDescription("A mod for R.E.P.O. that adds a notifier for broken valuables.")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ValuableBreakNotifier")] [assembly: AssemblyTitle("ValuableBreakNotifier")] [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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ValuableBreakNotifier { [HarmonyPatch(typeof(PhysGrabber))] public static class PhysGrabberPatch { private static ManualLogSource Logger = Logger.CreateLogSource("PhysGrabberPatch"); [HarmonyPrefix] [HarmonyPatch("ReleaseObject")] private static void ReleaseObject_Prefix(PhysGrabber __instance) { object? value = AccessTools.Field(typeof(PhysGrabber), "grabbedPhysGrabObject").GetValue(__instance); PhysGrabObject val = (PhysGrabObject)((value is PhysGrabObject) ? value : null); if ((Object)(object)val != (Object)null) { int instanceID = ((Object)val).GetInstanceID(); PlayerAvatar playerAvatar = __instance.playerAvatar; PhysGrabObjectImpactDetectorPatch.lastTouchedByPlayer[instanceID] = playerAvatar; string arg = AccessTools.Field(typeof(PlayerAvatar), "playerName").GetValue(playerAvatar) as string; Logger.LogInfo((object)$"JUGADOR '{arg}' ha soltado el objeto ID '{instanceID}'. Lo estamos rastreando."); } } } [HarmonyPatch(typeof(PhysGrabObjectImpactDetector))] internal static class PhysGrabObjectImpactDetector_CollisionPatch { private static ManualLogSource Logger = Logger.CreateLogSource("ValuableBreakNotifierCollisionPatch"); internal static HashSet<int> hitByEnemyThisFrame = new HashSet<int>(); [HarmonyPostfix] [HarmonyPatch("FixedUpdate")] private static void FixedUpdate_Postfix() { hitByEnemyThisFrame.Clear(); } [HarmonyPrefix] [HarmonyPatch("OnCollisionStay")] private static void OnCollisionStay_Prefix(PhysGrabObjectImpactDetector __instance, Collision collision) { if (((Component)collision.transform).CompareTag("Enemy")) { int instanceID = ((Object)((Component)__instance).gameObject).GetInstanceID(); hitByEnemyThisFrame.Add(instanceID); } } } [HarmonyPatch(typeof(PhysGrabObjectImpactDetector))] internal static class PhysGrabObjectImpactDetectorPatch { public static Dictionary<int, PlayerAvatar> lastTouchedByPlayer = new Dictionary<int, PlayerAvatar>(); private static ManualLogSource Logger = Logger.CreateLogSource("ValuableBreakNotifierPatch"); [HarmonyPrefix] [HarmonyPatch("BreakRPC")] private static void BreakRPC_Prefix(PhysGrabObjectImpactDetector __instance, float valueLost, bool _loseValue) { if (!ValuableBreakNotifierPlugin.IsEnabled.Value) { return; } int instanceID = ((Object)((Component)__instance).gameObject).GetInstanceID(); if (PhysGrabObjectImpactDetector_CollisionPatch.hitByEnemyThisFrame.Contains(instanceID)) { return; } object? value = AccessTools.Field(typeof(PhysGrabObjectImpactDetector), "valuableObject").GetValue(__instance); ValuableObject val = (ValuableObject)((value is ValuableObject) ? value : null); if (!_loseValue || !((Object)(object)val != (Object)null)) { return; } float num = (float)AccessTools.Field(typeof(ValuableObject), "dollarValueCurrent").GetValue(val); float num2 = (float)AccessTools.Field(typeof(ValuableObject), "dollarValueOriginal").GetValue(val); if (!(num - valueLost < num2 * 0.15f)) { return; } object? value2 = AccessTools.Field(typeof(PhysGrabObjectImpactDetector), "physGrabObject").GetValue(__instance); PhysGrabObject val2 = (PhysGrabObject)((value2 is PhysGrabObject) ? value2 : null); List<string> list = new List<string>(); if ((Object)(object)val2 != (Object)null) { List<PhysGrabber> list2 = AccessTools.Field(typeof(PhysGrabObject), "playerGrabbing").GetValue(val2) as List<PhysGrabber>; int instanceID2 = ((Object)val2).GetInstanceID(); if (list2 != null && list2.Count > 0) { foreach (PhysGrabber item in list2) { list.Add(AccessTools.Field(typeof(PlayerAvatar), "playerName").GetValue(item.playerAvatar) as string); } } else if (lastTouchedByPlayer.ContainsKey(instanceID2)) { PlayerAvatar obj = lastTouchedByPlayer[instanceID2]; list.Add(AccessTools.Field(typeof(PlayerAvatar), "playerName").GetValue(obj) as string); } if (lastTouchedByPlayer.ContainsKey(instanceID2)) { lastTouchedByPlayer.Remove(instanceID2); } } if (list.Count != 0 && !list.All(string.IsNullOrEmpty)) { string text = string.Join(" y ", list.Where((string name) => !string.IsNullOrEmpty(name)).Distinct()); string text2 = ((Object)val).name.Replace("(Clone)", ""); string message = "<color=yellow>" + text + "</color> ha DESTRUIDO un " + text2 + "!"; if ((Object)(object)UINotifier.Instance != (Object)null) { UINotifier.Instance.ShowNotification(message); } } } } public static class PluginInfo { public const string PLUGIN_GUID = "com.gambrinus.valuablebreaknotifier"; public const string PLUGIN_NAME = "ValuableBreakNotifier"; public const string PLUGIN_VERSION = "1.0.0"; } public class UINotifier : MonoBehaviour { private TextMeshProUGUI notificationText; private Coroutine hideCoroutine; public static UINotifier Instance { get; private set; } private void Awake() { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) Instance = this; notificationText = ((Component)this).GetComponent<TextMeshProUGUI>(); if (!((Object)(object)notificationText == (Object)null)) { ((TMP_Text)notificationText).fontSize = 22f; ((TMP_Text)notificationText).text = ""; ((Graphic)notificationText).color = Color.white; ((TMP_Text)notificationText).alignment = (TextAlignmentOptions)514; RectTransform component = ((Component)this).GetComponent<RectTransform>(); component.anchoredPosition = new Vector2(0f, -300f); component.sizeDelta = new Vector2(700f, 60f); ((Component)this).gameObject.SetActive(false); } } public void ShowNotification(string message, float duration = 4f) { if (!((Object)(object)notificationText == (Object)null)) { ((TMP_Text)notificationText).text = message; ((Component)this).gameObject.SetActive(true); if (hideCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(hideCoroutine); } hideCoroutine = ((MonoBehaviour)this).StartCoroutine(HideAfterDelay(duration)); } } private IEnumerator HideAfterDelay(float delay) { yield return (object)new WaitForSeconds(delay); ((Component)this).gameObject.SetActive(false); } } [HarmonyPatch(typeof(LevelGenerator), "GenerateDone")] public static class UIPatcher { private static ManualLogSource Logger = Logger.CreateLogSource("UIPatcher"); private static GameObject CreateUIElementFromClone<T>(string name) where T : MonoBehaviour { Logger.LogInfo((object)"Intentando crear elemento de UI..."); GameObject val = GameObject.Find("UI/HUD/HUD Canvas/HUD/Game Hud"); if ((Object)(object)val == (Object)null) { Logger.LogError((object)"No se encontró 'Game Hud'. No se puede crear la UI."); return null; } GameObject val2 = GameObject.Find("UI/HUD/HUD Canvas/HUD/Game Hud/Health"); if ((Object)(object)val2 == (Object)null) { Logger.LogError((object)"No se encontró el objeto 'Health' para clonar. No se puede crear la UI."); return null; } GameObject val3 = Object.Instantiate<GameObject>(val2, val.transform); ((Object)val3).name = name; Object.DestroyImmediate((Object)(object)val3.GetComponent<HealthUI>()); Transform[] array = ((IEnumerable)val3.transform).Cast<Transform>().ToArray(); foreach (Transform val4 in array) { Object.DestroyImmediate((Object)(object)((Component)val4).gameObject); } val3.AddComponent<T>(); Logger.LogInfo((object)("¡Elemento de UI '" + name + "' creado y componente '" + typeof(T).Name + "' añadido con éxito!")); return val3; } private static void Postfix() { Logger.LogInfo((object)"UIPatcher Postfix EJECUTADO!"); if ((Object)(object)UINotifier.Instance == (Object)null) { CreateUIElementFromClone<UINotifier>("ValuableBreakNotifierUI"); } else { Logger.LogInfo((object)"La instancia de UINotifier ya existe, no se creará de nuevo."); } } } [BepInPlugin("com.gambrinus.valuablebreaknotifier", "ValuableBreakNotifier", "1.0.0")] public class ValuableBreakNotifierPlugin : BaseUnityPlugin { private static Harmony harmony; public static ConfigEntry<bool> IsEnabled { get; set; } private void Awake() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown IsEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Enabled", true, "Activa o desactiva las notificaciones de rotura de objetos."); harmony = new Harmony("com.gambrinus.valuablebreaknotifier"); if (IsEnabled.Value) { harmony.PatchAll(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Mod ValuableBreakNotifier v1.0.0 cargado y parches aplicados."); } } private void OnDestroy() { if (harmony != null) { harmony.UnpatchSelf(); } } } }