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 AshleyRE4Model v1.0.3
AshleyGrahamReplacement.dll
Decompiled 2 weeks agousing System; using System.Diagnostics; using System.IO; 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 ModelReplacement; using ModelReplacement.AvatarBodyUpdater; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("AshleyGrahamReplacement")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Ashley Graham (Resident Evil 4) character model replacement for Lethal Company")] [assembly: AssemblyFileVersion("1.0.3.0")] [assembly: AssemblyInformationalVersion("1.0.3")] [assembly: AssemblyProduct("AshleyGrahamReplacement")] [assembly: AssemblyTitle("AshleyGrahamReplacement")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.3.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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 AshleyGrahamReplacement { public class AshleyGrahamModel : BodyReplacementBase { protected override GameObject LoadAssetsAndReturnModel() { //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_0498: Expected O, but got Unknown if ((Object)(object)Assets.MainAssetBundle == (Object)null) { Plugin.Logger.LogError((object)"Cannot load Ashley Graham model: AssetBundle is null."); return null; } string[] obj = new string[3] { "Ashley Graham", "AshleyGraham", "demo2" }; GameObject val = null; string[] array = obj; foreach (string text in array) { val = Assets.MainAssetBundle.LoadAsset<GameObject>(text); if ((Object)(object)val != (Object)null) { Plugin.Logger.LogInfo((object)("Loaded prefab '" + text + "' from AssetBundle.")); break; } } if ((Object)(object)val == (Object)null) { string[] allAssetNames = Assets.MainAssetBundle.GetAllAssetNames(); Plugin.Logger.LogWarning((object)$"Named prefabs not found. Bundle contains {allAssetNames.Length} assets:"); array = allAssetNames; foreach (string text2 in array) { Plugin.Logger.LogWarning((object)(" - " + text2)); if ((Object)(object)val == (Object)null) { GameObject val2 = Assets.MainAssetBundle.LoadAsset<GameObject>(text2); if ((Object)(object)val2 != (Object)null) { val = val2; Plugin.Logger.LogInfo((object)("Using asset '" + text2 + "' as model prefab.")); } } } } if ((Object)(object)val == (Object)null) { Plugin.Logger.LogError((object)"No GameObject prefab found in AssetBundle."); return null; } Animator val3 = val.GetComponentInChildren<Animator>(); if ((Object)(object)val3 == (Object)null) { Plugin.Logger.LogWarning((object)"No Animator found on prefab. Adding one to root SkinnedMeshRenderer or root."); SkinnedMeshRenderer componentInChildren = val.GetComponentInChildren<SkinnedMeshRenderer>(); GameObject val4 = (((Object)(object)componentInChildren != (Object)null) ? ((Component)componentInChildren).gameObject : val); val3 = val4.AddComponent<Animator>(); Plugin.Logger.LogInfo((object)("Animator added to '" + ((Object)val4).name + "'.")); } OffsetBuilder val5 = ((Component)val3).gameObject.GetComponent<OffsetBuilder>(); if ((Object)(object)val5 == (Object)null) { val5 = ((Component)val3).gameObject.AddComponent<OffsetBuilder>(); val5.rootScale = Vector3.one; val5.UseNoPostProcessing = false; val5.GenerateViewModel = Plugin.EnableCustomViewModel.Value; val5.RemoveHelmet = Plugin.RemoveHelmetSetting.Value; Plugin.Logger.LogInfo((object)"OffsetBuilder component injected at runtime."); } val5.rootPositionOffset = new Vector3(0f, Plugin.RootOffsetY.Value, Plugin.RootOffsetZ.Value); Plugin.Logger.LogInfo((object)$"Root position offset set to ({val5.rootPositionOffset.x}, {val5.rootPositionOffset.y}, {val5.rootPositionOffset.z})."); RotationOffset component = val.GetComponent<RotationOffset>(); if ((Object)(object)component != (Object)null) { Object.DestroyImmediate((Object)(object)component); } SkinnedMeshRenderer[] componentsInChildren = val.GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val6 in componentsInChildren) { if ((Object)(object)val6.sharedMesh == (Object)null || !val6.sharedMesh.isReadable) { continue; } try { Material[] sharedMaterials = ((Renderer)val6).sharedMaterials; bool flag = false; for (int j = 0; j < sharedMaterials.Length; j++) { if ((Object)(object)sharedMaterials[j] != (Object)null && (((Object)sharedMaterials[j]).name.IndexOf("wetness", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)sharedMaterials[j]).name.IndexOf("AO_m", StringComparison.OrdinalIgnoreCase) >= 0)) { flag = true; break; } } if (!flag) { continue; } Mesh val7 = Object.Instantiate<Mesh>(val6.sharedMesh); for (int k = 0; k < sharedMaterials.Length; k++) { if ((Object)(object)sharedMaterials[k] != (Object)null && (((Object)sharedMaterials[k]).name.IndexOf("wetness", StringComparison.OrdinalIgnoreCase) >= 0 || ((Object)sharedMaterials[k]).name.IndexOf("AO_m", StringComparison.OrdinalIgnoreCase) >= 0)) { val7.SetTriangles(new int[0], k); Plugin.Logger.LogInfo((object)$"Runtime: Zeroed out submesh {k} ({((Object)sharedMaterials[k]).name}) on '{((Object)val6).name}' to remove occluding shell."); } } val6.sharedMesh = val7; } catch (Exception ex) { Plugin.Logger.LogWarning((object)("Could not clean submeshes on '" + ((Object)val6).name + "' at runtime (already cleaned at build time): " + ex.Message)); } } Renderer[] componentsInChildren2 = val.GetComponentsInChildren<Renderer>(true); foreach (Renderer val8 in componentsInChildren2) { Material[] sharedMaterials2 = val8.sharedMaterials; bool flag2 = false; for (int l = 0; l < sharedMaterials2.Length; l++) { if ((Object)(object)sharedMaterials2[l] == (Object)null) { flag2 = true; Shader val9 = Shader.Find("HDRP/Lit") ?? Shader.Find("Standard") ?? Shader.Find("Sprites/Default"); if ((Object)(object)val9 != (Object)null) { sharedMaterials2[l] = new Material(val9); } ManualLogSource logger = Plugin.Logger; string name = ((Object)val8).name; object arg = l; Material obj2 = sharedMaterials2[l]; object obj3; if (obj2 == null) { obj3 = null; } else { Shader shader = obj2.shader; obj3 = ((shader != null) ? ((Object)shader).name : null); } if (obj3 == null) { obj3 = "none"; } logger.LogWarning((object)$"Renderer '{name}' had null material at slot {arg}; replaced with fallback shader '{obj3}'."); } } if (flag2) { val8.sharedMaterials = sharedMaterials2; } } return val; } protected override void AddModelScripts() { //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)base.replacementModel == (Object)null) { return; } Renderer[] componentsInChildren = base.replacementModel.GetComponentsInChildren<Renderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { Material[] materials = componentsInChildren[i].materials; for (int j = 0; j < materials.Length; j++) { if ((Object)(object)materials[j] != (Object)null && ((Object)materials[j]).name.IndexOf("eyes_m", StringComparison.OrdinalIgnoreCase) >= 0) { materials[j].EnableKeyword("_EMISSION"); if (materials[j].HasProperty("_EmissiveColor")) { materials[j].SetColor("_EmissiveColor", new Color(0.2f, 0.2f, 0.2f, 1f)); } if (materials[j].HasProperty("_EmissionColor")) { materials[j].SetColor("_EmissionColor", new Color(0.2f, 0.2f, 0.2f, 1f)); } Plugin.Logger.LogInfo((object)("Set natural eye illumination on '" + ((Object)materials[j]).name + "'.")); } } } } } public static class Assets { public const string AssetBundleName = "ashleygraham"; public const string SecondaryBundleName = "AshleyGrahamRE4bundle"; public const string PrefabModelName = "Ashley Graham"; public const string FallbackPrefabModelName = "AshleyGraham"; public static AssetBundle MainAssetBundle { get; private set; } public static void PopulateAssets() { if ((Object)(object)MainAssetBundle != (Object)null) { return; } string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); string[] obj = new string[6] { Path.Combine(directoryName, "ashleygraham"), Path.Combine(directoryName, "AshleyGrahamRE4bundle"), Path.Combine(directoryName, "AssetBundles", "ashleygraham"), Path.Combine(directoryName, "AssetBundles", "AshleyGrahamRE4bundle"), Path.Combine(Directory.GetCurrentDirectory(), "ashleygraham"), Path.Combine(Directory.GetCurrentDirectory(), "AshleyGrahamRE4bundle") }; string text = null; string[] array = obj; foreach (string text2 in array) { if (File.Exists(text2)) { text = text2; break; } } if (text == null) { Plugin.Logger.LogError((object)"AssetBundle 'ashleygraham' could not be located in plugin directory."); return; } MainAssetBundle = AssetBundle.LoadFromFile(text); if ((Object)(object)MainAssetBundle == (Object)null) { Plugin.Logger.LogError((object)("Failed to load AssetBundle from '" + text + "'.")); } else { Plugin.Logger.LogInfo((object)("Successfully loaded AssetBundle from '" + text + "'.")); } } } public static class PluginInfo { public const string GUID = "com.v0id.ashleygraham"; public const string NAME = "AshleyGrahamReplacement"; public const string VERSION = "1.0.3"; } [BepInPlugin("com.v0id.ashleygraham", "AshleyGrahamReplacement", "1.0.3")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public static Plugin Instance { get; private set; } public static ManualLogSource Logger { get; private set; } public static ConfigEntry<string> SuitNamesToReplace { get; private set; } public static ConfigEntry<bool> EnableCustomViewModel { get; private set; } public static ConfigEntry<bool> RemoveHelmetSetting { get; private set; } public static ConfigEntry<float> RootOffsetY { get; private set; } public static ConfigEntry<float> RootOffsetZ { get; private set; } private void Awake() { //IL_00a2: Unknown result type (might be due to invalid IL or missing references) Instance = this; Logger = ((BaseUnityPlugin)this).Logger; InitConfig(); try { Assets.PopulateAssets(); string[] array = (from s in SuitNamesToReplace.Value.Split(new char[1] { ',' }, StringSplitOptions.RemoveEmptyEntries) select s.Trim()).ToArray(); foreach (string text in array) { ModelReplacementAPI.RegisterSuitModelReplacement(text, typeof(AshleyGrahamModel)); Logger.LogInfo((object)("Registered Ashley Graham model replacement for suit: '" + text + "'")); } new Harmony("com.v0id.ashleygraham").PatchAll(); Logger.LogInfo((object)"AshleyGrahamReplacement v1.0.3 initialized successfully."); } catch (Exception arg) { Logger.LogError((object)string.Format("Failed to initialize {0}: {1}", "AshleyGrahamReplacement", arg)); } } private void InitConfig() { SuitNamesToReplace = ((BaseUnityPlugin)this).Config.Bind<string>("Suits", "SuitNames", "Ashley Graham", "Comma-separated list of suit names that will trigger the Ashley Graham model replacement (case-sensitive)."); EnableCustomViewModel = ((BaseUnityPlugin)this).Config.Bind<bool>("Visuals", "EnableViewModel", true, "Generate first-person arms/viewmodel based on the replacement model."); RemoveHelmetSetting = ((BaseUnityPlugin)this).Config.Bind<bool>("Visuals", "RemoveHelmet", true, "Remove the scavenger helmet mesh when the Ashley model is active."); RootOffsetY = ((BaseUnityPlugin)this).Config.Bind<float>("Offsets", "RootOffsetY", 0.38f, "Vertical height offset to prevent model shoes sinking into the ground (in meters)."); RootOffsetZ = ((BaseUnityPlugin)this).Config.Bind<float>("Offsets", "RootOffsetZ", 0f, "Forward/backward offset for the model root (in meters)."); } } }