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 MyBearFriend v0.2.0
MyBearFriend.dll
Decompiled 2 months agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("MyBearFriend")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("MyBearFriend")] [assembly: AssemblyCopyright("Copyright © 2025")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("0.1.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.0.0")] namespace MyBearFriend; internal static class LocalizationHelper { private static readonly List<string> languages = new List<string> { "English", "Swedish", "French", "Italian", "German", "Spanish", "Russian", "Romanian", "Bulgarian", "Macedonian", "Finnish", "Danish", "Norwegian", "Icelandic", "Turkish", "Lithuanian", "Czech", "Hungarian", "Slovak", "Polish", "Dutch", "Portuguese_European", "Portuguese_Brazilian", "Chinese", "Chinese_Trad", "Japanese", "Korean", "Hindi", "Thai", "Abenaki", "Croatian", "Georgian", "Greek", "Serbian", "Ukrainian", "Latvian" }; public static bool IsLanguageSupported(string language) { return languages.Contains(language); } } [BepInPlugin("com.milkwyzard.MyBearFriend", "MyBearFriend", "0.2.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] public class MyBearFriend : BaseUnityPlugin { [CompilerGenerated] private sealed class <EnumerateConsumables>d__23 : IEnumerable<string>, IEnumerable, IEnumerator<string>, IDisposable, IEnumerator { private int <>1__state; private string <>2__current; private int <>l__initialThreadId; private ConfigEntry<string> configConsumables; public ConfigEntry<string> <>3__configConsumables; private string[] <>7__wrap1; private int <>7__wrap2; string IEnumerator<string>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <EnumerateConsumables>d__23(int <>1__state) { this.<>1__state = <>1__state; <>l__initialThreadId = Environment.CurrentManagedThreadId; } [DebuggerHidden] void IDisposable.Dispose() { <>7__wrap1 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; string[] array = configConsumables.Value.Split(new char[1] { ';' }, StringSplitOptions.RemoveEmptyEntries); <>7__wrap1 = array; <>7__wrap2 = 0; break; } case 1: <>1__state = -1; <>7__wrap2++; break; } if (<>7__wrap2 < <>7__wrap1.Length) { string text = <>7__wrap1[<>7__wrap2]; <>2__current = text.Trim(); <>1__state = 1; return true; } <>7__wrap1 = null; return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } [DebuggerHidden] IEnumerator<string> IEnumerable<string>.GetEnumerator() { <EnumerateConsumables>d__23 <EnumerateConsumables>d__; if (<>1__state == -2 && <>l__initialThreadId == Environment.CurrentManagedThreadId) { <>1__state = 0; <EnumerateConsumables>d__ = this; } else { <EnumerateConsumables>d__ = new <EnumerateConsumables>d__23(0); } <EnumerateConsumables>d__.configConsumables = <>3__configConsumables; return <EnumerateConsumables>d__; } [DebuggerHidden] IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable<string>)this).GetEnumerator(); } } public const string PluginGUID = "com.milkwyzard.MyBearFriend"; public const string PluginName = "MyBearFriend"; public const string PluginVersion = "0.2.0"; public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization(); private const string bearNameLocalizedFormat = "name_randBearName"; private Harmony harmony; private int randomNameCount; private bool creaturesAvailable; private bool prefabsAvailable; private bool isConfigured; public static ConfigEntry<string> BearConsumableItems; public static ConfigEntry<float> BearTameTime; public static ConfigEntry<float> BearFedDuration; public MyBearFriend() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown harmony = new Harmony("com.milkwyzard.MyBearFriend"); } public void Start() { harmony.PatchAll(Assembly.GetExecutingAssembly()); } private void Awake() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Expected O, but got Unknown ConfigurationManagerAttributes val = new ConfigurationManagerAttributes { IsAdminOnly = true }; BearConsumableItems = ((BaseUnityPlugin)this).Config.Bind<string>("General", "BearConsumableItems", "Blueberries; Honey; RawMeat; DeerMeat", new ConfigDescription("Items that the Bear can consume/eat. Must be the name of the prefab. See Jotunn docs.", (AcceptableValueBase)null, new object[1] { val })); BearTameTime = ((BaseUnityPlugin)this).Config.Bind<float>("General", "BearTameTime", 1600f, new ConfigDescription("Amount of time (in seconds) it takes to tame a Bear (default is slightly less than wolf).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10000f), new object[1] { val })); BearFedDuration = ((BaseUnityPlugin)this).Config.Bind<float>("General", "BearFedDuration", 400f, new ConfigDescription("Amount of time (in seconds) after feeding a Bear before it becomes hungry again (default is slightly less than wolf).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1000f), new object[1] { val })); CreatureManager.OnVanillaCreaturesAvailable += OnVanillaCreaturesAvailable; PrefabManager.OnVanillaPrefabsAvailable += OnVanillaPrefabsAvailable; LocalizationManager.OnLocalizationAdded += OnLocalizationsAdded; Logger.LogInfo((object)"MyBearFriend v0.2.0 loaded and patched."); } private void OnLocalizationsAdded() { ResolveLocalizations(); string text = Localization.GetLanguages().FirstOrDefault(); if (text != null) { randomNameCount = Localization.GetTranslations(ref text).Count((KeyValuePair<string, string> kvp) => kvp.Key.StartsWith("name_randBearName")); Logger.LogWarning((object)$"Random name count: {randomNameCount}"); } } private void OnVanillaPrefabsAvailable() { prefabsAvailable = true; if (prefabsAvailable && creaturesAvailable && !isConfigured) { MakeBearTameable(); } } private void OnVanillaCreaturesAvailable() { creaturesAvailable = true; if (prefabsAvailable && creaturesAvailable && !isConfigured) { MakeBearTameable(); } } private void MakeBearTameable() { //IL_016b: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_0295: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) GameObject creaturePrefab = CreatureManager.Instance.GetCreaturePrefab("Wolf"); if ((Object)(object)creaturePrefab == (Object)null) { Logger.LogWarning((object)"Could not Wolf creature prefab."); return; } Tameable component = creaturePrefab.GetComponent<Tameable>(); if ((Object)(object)component == (Object)null) { Logger.LogWarning((object)"Could not find Tameable Component for the Wolf prefab."); return; } GameObject creaturePrefab2 = CreatureManager.Instance.GetCreaturePrefab("Bjorn"); if ((Object)(object)creaturePrefab2 == (Object)null) { Logger.LogWarning((object)"Could not find Bear creature prefab."); return; } MonsterAI component2 = creaturePrefab2.GetComponent<MonsterAI>(); if ((Object)(object)component2 == (Object)null) { Logger.LogWarning((object)"Expected Bear prefab to have Monster AI."); return; } component2.m_consumeItems.Clear(); foreach (string item in EnumerateConsumables(BearConsumableItems)) { AddConsumableItem(component2, item); } Tameable component3 = creaturePrefab2.GetComponent<Tameable>(); if ((Object)(object)component3 != (Object)null) { Logger.LogWarning((object)"Expected Bear prefab to not have a Tameable component."); return; } if (component.m_tamedEffect.m_effectPrefabs.Length == 0 || component.m_petEffect.m_effectPrefabs.Length == 0 || component.m_sootheEffect.m_effectPrefabs.Length == 0) { Logger.LogWarning((object)"Could not get taming effect prefabs from Wolf prefab type."); return; } EffectData val = DuplicateEffectData(component.m_tamedEffect.m_effectPrefabs[0]); if (val == null) { return; } EffectData val2 = DuplicateEffectData(component.m_petEffect.m_effectPrefabs[0]); if (val2 != null) { EffectData val3 = DuplicateEffectData(component.m_sootheEffect.m_effectPrefabs[0]); if (val3 != null) { Logger.LogDebug((object)$"m_levelUpOwnerSkill - {component.m_levelUpOwnerSkill}"); Logger.LogDebug((object)$"m_tamingTime - {component.m_tamingTime}"); Logger.LogDebug((object)$"m_fedDuration - {component.m_fedDuration}"); component3 = creaturePrefab2.AddComponent<Tameable>(); component3.m_fedDuration = BearFedDuration.Value; component3.m_tamingTime = BearTameTime.Value; component3.m_startsTamed = false; component3.m_tamedEffect.m_effectPrefabs = (EffectData[])(object)new EffectData[1] { val }; component3.m_sootheEffect.m_effectPrefabs = (EffectData[])(object)new EffectData[1] { val3 }; component3.m_petEffect.m_effectPrefabs = (EffectData[])(object)new EffectData[1] { val2 }; component3.m_commandable = component.m_commandable; component3.m_unsummonDistance = component.m_unsummonDistance; component3.m_unsummonOnOwnerLogoutSeconds = component.m_unsummonOnOwnerLogoutSeconds; component3.m_levelUpOwnerSkill = component.m_levelUpOwnerSkill; component3.m_levelUpFactor = component.m_levelUpFactor; component3.m_saddleItem = component.m_saddleItem; component3.m_saddle = component.m_saddle; component3.m_dropSaddleOnDeath = component.m_dropSaddleOnDeath; component3.m_dropSaddleOffset = component.m_dropSaddleOffset; component3.m_dropItemVel = component.m_dropItemVel; component3.m_tamingSpeedMultiplierRange = component.m_tamingSpeedMultiplierRange; component3.m_tamingBoostMultiplier = component.m_tamingBoostMultiplier; SetRandomStartingNames(component3); isConfigured = true; } } } private static void AddConsumableItem(MonsterAI monsterAi, string itemName) { ItemDrop val = null; GameObject prefab = PrefabManager.Instance.GetPrefab(itemName); if ((Object)(object)prefab != (Object)null) { val = prefab.GetComponent<ItemDrop>(); if ((Object)(object)val != (Object)null) { monsterAi.m_consumeItems.Add(val); } } if ((Object)(object)val == (Object)null) { Logger.LogWarning((object)("Could not find item: " + itemName)); } else { Logger.LogDebug((object)("Bear can consume " + ((Object)val).name)); } } private void SetRandomStartingNames(Tameable tameable) { tameable.m_randomStartingName = new List<string>(); for (int i = 0; i < randomNameCount; i++) { tameable.m_randomStartingName.Add(string.Format("${0}{1}", "name_randBearName", i)); } } private EffectData DuplicateEffectData(EffectData fxData) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: 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_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown if ((Object)(object)fxData.m_prefab == (Object)null) { return null; } GameObject prefab = PrefabManager.Instance.GetPrefab(((Object)fxData.m_prefab).name); if ((Object)(object)prefab == (Object)null) { Logger.LogWarning((object)("Could not get effect prefab " + ((Object)fxData.m_prefab).name)); return null; } return new EffectData { m_prefab = prefab, m_enabled = fxData.m_enabled, m_variant = fxData.m_variant, m_attach = fxData.m_attach, m_follow = fxData.m_follow, m_inheritParentRotation = fxData.m_inheritParentRotation, m_inheritParentScale = fxData.m_inheritParentScale, m_multiplyParentVisualScale = fxData.m_multiplyParentVisualScale, m_randomRotation = fxData.m_randomRotation, m_scale = fxData.m_scale, m_childTransform = fxData.m_childTransform }; } [IteratorStateMachine(typeof(<EnumerateConsumables>d__23))] private IEnumerable<string> EnumerateConsumables(ConfigEntry<string> configConsumables) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <EnumerateConsumables>d__23(-2) { <>3__configConsumables = configConsumables }; } private void ResolveLocalizations() { try { DirectoryInfo directoryInfo = new DirectoryInfo(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); Dictionary<string, List<FileInfo>> dictionary = new Dictionary<string, List<FileInfo>>(); foreach (FileInfo item in directoryInfo.EnumerateFiles("*.json", SearchOption.TopDirectoryOnly)) { string[] array = item.Name.Split(new char[1] { '.' }, StringSplitOptions.RemoveEmptyEntries); if (array.Length <= 2 || !(array.Last() == "json")) { continue; } string text = array[^2].Trim(); if (LocalizationHelper.IsLanguageSupported(text)) { if (!dictionary.ContainsKey(text)) { dictionary.Add(text, new List<FileInfo>()); } dictionary[text].Add(item); } } foreach (string key in dictionary.Keys) { if (Localization.GetLanguages().Contains(key)) { continue; } foreach (FileInfo item2 in dictionary[key]) { Localization.AddJsonFile(key, File.ReadAllText(item2.FullName)); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Added localization file [" + item2.Name + "] from non-standard location.")); } } foreach (string language in Localization.GetLanguages()) { ((BaseUnityPlugin)this).Logger.LogInfo((object)(language + " localization loaded and available.")); } } catch (Exception) { ((BaseUnityPlugin)this).Logger.LogError((object)"Error resolving localizations."); } } }