Decompiled source of fufu v1.0.0
plugins/MikuFufu.dll
Decompiled 2 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; 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 TMPro; using UnityEngine; using UnityEngine.Networking; using UnityEngine.Rendering; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: AssemblyCompany("MikuFufu")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("MikuFufu")] [assembly: AssemblyTitle("MikuFufu")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] public sealed class IgnoresAccessChecksToAttribute : Attribute { private readonly string _assemblyName; public string AssemblyName => _assemblyName; public IgnoresAccessChecksToAttribute(string assemblyName) { _assemblyName = assemblyName; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] public sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte value) { NullableFlags = new byte[1] { value }; } public NullableAttribute(byte[] value) { NullableFlags = value; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] public sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte value) { Flag = value; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] public sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int version) { Version = version; } } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public sealed class BepInAutoPluginAttribute : Attribute { private string _guid; private string _name; private string _version; public string GUID { get { return _guid; } set { _guid = value; } } public string Name { get { return _name; } set { _name = value; } } public string Version { get { return _version; } set { _version = value; } } public BepInAutoPluginAttribute(string guid = null, string name = null, string version = null) { _guid = guid; _name = name; _version = version; } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public sealed class PatcherAutoPluginAttribute : Attribute { private string _guid; private string _name; private string _version; public string GUID { get { return _guid; } set { _guid = value; } } public string Name { get { return _name; } set { _name = value; } } public string Version { get { return _version; } set { _version = value; } } public PatcherAutoPluginAttribute(string guid = null, string name = null, string version = null) { _guid = guid; _name = name; _version = version; } } } namespace MikuFufu { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.github.Thanks.MikuFufu", "MikuFufu", "1.0.0")] public class Plugin : BaseUnityPlugin { private const string LegacyPluginId = "com.github.FelineEntity.MikuBongFix"; private const string BundleFileName = "fufupeak"; private const string ModelAssetPath = "assets/mikufumo/fufu.fbx"; private const string MaterialAssetPath = "assets/mikufumo/materials/miku.mat"; private const string IconTextureAssetPath = "assets/mikufumo/miku_icon.png"; private const string MainTextureAssetPath = "assets/mikufumo/miku.png"; private const string AltTextureAssetPath = "assets/mikufumo/miku1.png"; private const string ConfigSection = "Main"; private const float InventoryIconVisibleScale = 0.76f; private const float WorldMinScaleMultiplier = 0.7f; private const float WorldMaxScaleMultiplier = 1.1f; private const float BackpackMinScaleMultiplier = 0.2f; private const float BackpackMaxScaleMultiplier = 1f; private const float DefaultWorldScaleMultiplier = 0.9f; private const float DefaultBackpackScaleMultiplier = 0.4f; private static readonly string[] PreferredTextureProps = new string[2] { "_BaseMap", "_MainTex" }; private static readonly string[] PrefabNameHints = new string[4] { "mikufumo", "miku", "fumo", "fufu" }; private static readonly string[] MaterialNameHints = new string[4] { "m_mikufumo", "mikufumo", "miku", "fufu" }; private static readonly string[] IconTextureNameHints = new string[4] { "miku_icon", "icon", "miku", "fufu" }; private static readonly string[] MainTextureNameHints = new string[4] { "miku", "mikufumo", "albedo", "fufu" }; private static readonly string[] AltTextureNameHints = new string[4] { "miku1", "fufu1", "alt", "detail" }; private static readonly Color MikuStyleTint = new Color(0.98f, 1f, 1f, 1f); private static ConfigEntry<bool> _modEnabled; private static ConfigEntry<float> _worldScaleMultiplier; private static ConfigEntry<float> _backpackScaleMultiplier; private static ManualLogSource _log; private static AssetBundle _bundle; private static GameObject _mochiPrefab; private static Material _mochiMaterial; private static Material _runtimeMikuMaterial; private static Texture2D _mochiTexture; private static Texture2D _mikuMainTexture; private static Texture2D _mikuAltTexture; public const string Name = "MikuFufu"; public const string Id = "com.github.Thanks.MikuFufu"; public const string Version = "1.0.0"; internal static Harmony Harmony = new Harmony("com.github.Thanks.MikuFufu"); internal static ManualLogSource Log { get { return _log; } private set { _log = value; } } internal static AssetBundle Bundle { get { return _bundle; } private set { _bundle = value; } } internal static GameObject MochiPrefab { get { return _mochiPrefab; } private set { _mochiPrefab = value; } } internal static Material MochiMaterial { get { return _mochiMaterial; } private set { _mochiMaterial = value; } } internal static Material RuntimeMikuMaterial { get { return _runtimeMikuMaterial; } private set { _runtimeMikuMaterial = value; } } internal static Texture2D MochiTexture { get { return _mochiTexture; } private set { _mochiTexture = value; } } internal static Texture2D MikuMainTexture { get { return _mikuMainTexture; } private set { _mikuMainTexture = value; } } internal static Texture2D MikuAltTexture { get { return _mikuAltTexture; } private set { _mikuAltTexture = value; } } internal static bool ModEnabled { get { if (_modEnabled != null) { return _modEnabled.Value; } return true; } } internal static bool KeepOriginalRendererRefs => true; internal static bool EnableVisibilityGuard => true; internal static float WorldScaleMultiplier { get { if (_worldScaleMultiplier != null) { return Mathf.Clamp(_worldScaleMultiplier.Value, 0.7f, 1.1f); } return 0.9f; } } internal static float BackpackScaleMultiplier { get { if (_backpackScaleMultiplier != null) { return Mathf.Clamp(_backpackScaleMultiplier.Value, 0.2f, 1f); } return 0.4f; } } internal static string directory => Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); private void Awake() { Log = ((BaseUnityPlugin)this).Logger; MigrateLegacyConfigIfNeeded(); InitializeConfig(); LoadAssets(); try { Harmony.PatchAll(Assembly.GetExecutingAssembly()); } catch (Exception ex) { Log.LogError((object)("Failed to apply Harmony patches: " + ex)); } } private void MigrateLegacyConfigIfNeeded() { try { string configFilePath = ((BaseUnityPlugin)this).Config.ConfigFilePath; string text = Path.Combine(Paths.ConfigPath, "com.github.FelineEntity.MikuBongFix.cfg"); if (!string.IsNullOrEmpty(configFilePath) && !string.IsNullOrEmpty(text) && !File.Exists(configFilePath) && File.Exists(text)) { File.Copy(text, configFilePath, overwrite: false); ((BaseUnityPlugin)this).Config.Reload(); Log.LogInfo((object)("Migrated legacy config to: " + configFilePath)); } } catch (Exception ex) { Log.LogWarning((object)("Failed to migrate legacy config file: " + ex.Message)); } } private void InitializeConfig() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown _modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Main", "Enable Fufu Replacement", true, new ConfigDescription("Master switch for the mod. When disabled, the original BingBong visuals, name, icon, and colliders are restored.", (AcceptableValueBase)null, Array.Empty<object>())); _worldScaleMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Main", "Fufu Size In World", 0.9f, new ConfigDescription("Scale multiplier for Fufu while held or lying in the world.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.7f, 1.1f), Array.Empty<object>())); _backpackScaleMultiplier = ((BaseUnityPlugin)this).Config.Bind<float>("Main", "Fufu Size In Backpack", 0.4f, new ConfigDescription("Scale multiplier for the Fufu replacement while stored in the backpack.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.2f, 1f), Array.Empty<object>())); } private void LoadAssets() { string text = Path.Combine(directory, "fufupeak"); Bundle = AssetBundle.LoadFromFile(text); if ((Object)(object)Bundle == (Object)null) { Log.LogError((object)("Failed to load AssetBundle: " + text)); return; } MochiPrefab = LoadBundleAssetWithFallback<GameObject>("assets/mikufumo/fufu.fbx", PrefabNameHints); MochiMaterial = LoadBundleAssetWithFallback<Material>("assets/mikufumo/materials/miku.mat", MaterialNameHints); Texture2D val = LoadBundleAssetWithFallback<Texture2D>("assets/mikufumo/miku_icon.png", IconTextureNameHints); Texture2D val2 = CreateReadableTexture(val) ?? val; MochiTexture = CreatePaddedIconTexture(val2, 0.76f) ?? val2 ?? val; MikuMainTexture = LoadBundleAssetWithFallback<Texture2D>("assets/mikufumo/miku.png", MainTextureNameHints); MikuAltTexture = LoadBundleAssetWithFallback<Texture2D>("assets/mikufumo/miku1.png", AltTextureNameHints); if ((Object)(object)MochiPrefab == (Object)null) { Log.LogError((object)"Failed to load replacement model from asset bundle."); return; } ConfigureMochiMaterial(); RuntimeMikuMaterial = (((Object)(object)MochiMaterial == (Object)null) ? CreateRuntimeMikuMaterial(MikuMainTexture) : null); if ((Object)(object)RuntimeMikuMaterial == (Object)null) { Log.LogInfo((object)"Using bundled material from fufupeak."); } if ((Object)(object)MochiTexture == (Object)null) { Log.LogWarning((object)"Failed to load replacement icon texture."); } if ((Object)(object)MikuMainTexture == (Object)null) { Log.LogWarning((object)"Failed to load replacement main texture."); } if ((Object)(object)MikuAltTexture == (Object)null) { Log.LogWarning((object)"Failed to load replacement secondary texture."); } LogBundleResourceStatus(); } internal static void VerboseLog(string message) { } private static T LoadBundleAssetWithFallback<T>(string preferredPath, params string[] nameHints) where T : Object { if ((Object)(object)Bundle == (Object)null) { return default(T); } if (!string.IsNullOrEmpty(preferredPath)) { T val = Bundle.LoadAsset<T>(preferredPath); if ((Object)(object)val != (Object)null) { return val; } } string[] allAssetNames = Bundle.GetAllAssetNames(); if (allAssetNames != null) { foreach (string text in allAssetNames) { if (AssetNameLooksRelevant(text, preferredPath, nameHints)) { T val2 = Bundle.LoadAsset<T>(text); if ((Object)(object)val2 != (Object)null) { Log.LogWarning((object)("Loaded fallback " + typeof(T).Name + " from bundle path: " + text)); return val2; } } } } T[] array = Bundle.LoadAllAssets<T>(); if (array == null || array.Length == 0) { Log.LogWarning((object)("No " + typeof(T).Name + " assets found in bundle for requested path: " + preferredPath)); return default(T); } T val3 = FindAssetByObjectName(array, preferredPath, nameHints); if ((Object)(object)val3 != (Object)null) { Log.LogWarning((object)("Loaded fallback " + typeof(T).Name + " by object name: " + ((Object)val3).name)); return val3; } if (array.Length == 1) { Log.LogWarning((object)("Loaded only available " + typeof(T).Name + " asset as fallback: " + ((Object)array[0]).name)); return array[0]; } Log.LogWarning((object)("Unable to identify " + typeof(T).Name + " for requested path '" + preferredPath + "'. Candidates: " + string.Join(", ", Array.ConvertAll(array, (T asset) => (!((Object)(object)asset != (Object)null)) ? "<null>" : ((Object)asset).name)))); return default(T); } private static T FindAssetByObjectName<T>(T[] assets, string preferredPath, string[] nameHints) where T : Object { string needle = (string.IsNullOrEmpty(preferredPath) ? string.Empty : Path.GetFileNameWithoutExtension(preferredPath)); foreach (T val in assets) { if (!((Object)(object)val == (Object)null)) { string value = ((Object)val).name ?? string.Empty; if (NameMatches(value, needle) || NameMatchesAnyHint(value, nameHints)) { return val; } } } return default(T); } private static bool AssetNameLooksRelevant(string assetName, string preferredPath, string[] nameHints) { if (string.IsNullOrEmpty(assetName)) { return false; } if (!string.IsNullOrEmpty(preferredPath)) { if (assetName.Equals(preferredPath, StringComparison.OrdinalIgnoreCase)) { return true; } string fileName = Path.GetFileName(preferredPath); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(preferredPath); if (!string.IsNullOrEmpty(fileName) && assetName.EndsWith(fileName, StringComparison.OrdinalIgnoreCase)) { return true; } if (NameMatches(assetName, fileNameWithoutExtension)) { return true; } } return NameMatchesAnyHint(assetName, nameHints); } private static bool NameMatchesAnyHint(string value, string[] hints) { if (string.IsNullOrEmpty(value) || hints == null) { return false; } for (int i = 0; i < hints.Length; i++) { if (NameMatches(value, hints[i])) { return true; } } return false; } private static bool NameMatches(string value, string needle) { if (string.IsNullOrEmpty(value) || string.IsNullOrEmpty(needle)) { return false; } return value.IndexOf(needle, StringComparison.OrdinalIgnoreCase) >= 0; } private static void ConfigureMochiMaterial() { if (!((Object)(object)MochiMaterial == (Object)null) && ((Object)(object)MochiMaterial.shader == (Object)null || !MochiMaterial.shader.isSupported)) { Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard"); if ((Object)(object)val != (Object)null) { MochiMaterial.shader = val; Log.LogWarning((object)("Bundled material shader was unavailable. Switched to fallback shader: " + ((Object)val).name)); } } } private static void LogBundleResourceStatus() { Log.LogInfo((object)("fufupeak resource check: prefab=" + ((Object)(object)MochiPrefab != (Object)null) + ", material=" + ((Object)(object)MochiMaterial != (Object)null) + ", icon=" + ((Object)(object)MochiTexture != (Object)null) + ", mainTex=" + ((Object)(object)MikuMainTexture != (Object)null) + ", altTex=" + ((Object)(object)MikuAltTexture != (Object)null))); } private static bool TryAssignTexture(Material material, string propertyName, Texture texture) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)material == (Object)null || (Object)(object)texture == (Object)null || string.IsNullOrEmpty(propertyName) || !material.HasProperty(propertyName)) { return false; } try { material.SetTexture(propertyName, texture); material.SetTextureScale(propertyName, Vector2.one); material.SetTextureOffset(propertyName, Vector2.zero); return true; } catch (Exception ex) { VerboseLog("Skip texture assignment on material '" + ((Object)material).name + "', property '" + propertyName + "': " + ex.Message); return false; } } private static void TryAssignTexture(Material material, string[] propertyNames, Texture texture) { if (!((Object)(object)material == (Object)null) && !((Object)(object)texture == (Object)null) && propertyNames != null) { for (int i = 0; i < propertyNames.Length; i++) { TryAssignTexture(material, propertyNames[i], texture); } } } private static void ApplyTextureSet(Material material, Texture2D albedo) { if (!((Object)(object)material == (Object)null)) { TryAssignTexture(material, PreferredTextureProps, (Texture)(object)albedo); ApplyMikuColorStyle(material); } } private static void ApplyMikuColorStyle(Material material) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_013f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)material == (Object)null)) { if (material.HasProperty("_Tint")) { material.SetColor("_Tint", MikuStyleTint); } if (material.HasProperty("_BaseColor")) { material.SetColor("_BaseColor", MikuStyleTint); } if (material.HasProperty("_Color")) { material.SetColor("_Color", MikuStyleTint); } if (material.HasProperty("_Smoothness")) { material.SetFloat("_Smoothness", 0.1f); } if (material.HasProperty("_Glossiness")) { material.SetFloat("_Glossiness", 0.1f); } if (material.HasProperty("_Metallic")) { material.SetFloat("_Metallic", 0f); } if (material.HasProperty("_BumpScale")) { material.SetFloat("_BumpScale", 0f); } if (material.HasProperty("_OcclusionStrength")) { material.SetFloat("_OcclusionStrength", 0f); } if (material.HasProperty("_SpecularHighlights")) { material.SetFloat("_SpecularHighlights", 0f); } if (material.HasProperty("_EnvironmentReflections")) { material.SetFloat("_EnvironmentReflections", 0f); } if (material.HasProperty("_EmissionColor")) { material.SetColor("_EmissionColor", Color.black); material.DisableKeyword("_EMISSION"); } material.DisableKeyword("_NORMALMAP"); material.DisableKeyword("_METALLICSPECGLOSSMAP"); material.DisableKeyword("_OCCLUSIONMAP"); } } private static Texture2D CreateReadableTexture(Texture2D source) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0089: 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) //IL_009e: Expected O, but got Unknown if ((Object)(object)source == (Object)null) { return null; } try { source.GetPixel(0, 0); return source; } catch { } RenderTexture temporary = RenderTexture.GetTemporary(((Texture)source).width, ((Texture)source).height, 0, (RenderTextureFormat)0); RenderTexture active = RenderTexture.active; try { Graphics.Blit((Texture)(object)source, temporary); RenderTexture.active = temporary; Texture2D val = new Texture2D(((Texture)source).width, ((Texture)source).height, (TextureFormat)4, true, false) { name = ((Object)source).name + "_Readable" }; val.ReadPixels(new Rect(0f, 0f, (float)((Texture)source).width, (float)((Texture)source).height), 0, 0); val.Apply(true, false); return val; } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } } private static Texture2D CreatePaddedIconTexture(Texture2D source, float visibleScale) { //IL_006a: 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_0087: Expected O, but got Unknown //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)source == (Object)null) { return null; } visibleScale = Mathf.Clamp(visibleScale, 0.45f, 1f); int num = Mathf.Max(1, ((Texture)source).width); int num2 = Mathf.Max(1, ((Texture)source).height); int num3 = Mathf.Max(1, Mathf.RoundToInt((float)num * visibleScale)); int num4 = Mathf.Max(1, Mathf.RoundToInt((float)num2 * visibleScale)); int num5 = (num - num3) / 2; int num6 = (num2 - num4) / 2; Texture2D val = new Texture2D(num, num2, (TextureFormat)4, false, false) { name = ((Object)source).name + "_Inventory" }; Color32[] pixels = (Color32[])(object)new Color32[num * num2]; val.SetPixels32(pixels); Color[] array = (Color[])(object)new Color[num3 * num4]; for (int i = 0; i < num4; i++) { float num7 = ((num4 == 1) ? 0.5f : ((float)i / (float)(num4 - 1))); for (int j = 0; j < num3; j++) { float num8 = ((num3 == 1) ? 0.5f : ((float)j / (float)(num3 - 1))); array[i * num3 + j] = source.GetPixelBilinear(num8, num7); } } val.SetPixels(num5, num6, num3, num4, array); ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).filterMode = (FilterMode)1; val.Apply(false, false); return val; } private static Material CreateRuntimeMikuMaterial(Texture2D texture) { //IL_005e: 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_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Expected O, but got Unknown Shader val = Shader.Find("Universal Render Pipeline/Unlit") ?? Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("W/Peak_Standard") ?? Shader.Find("Standard") ?? Shader.Find("Unlit/Texture"); if ((Object)(object)val == (Object)null) { Log.LogError((object)"Failed to create runtime material because no compatible shader was found."); return null; } Material val2 = new Material(val) { name = "Fufu_RuntimeMaterial", renderQueue = 2000, color = Color.white }; if ((Object)(object)texture != (Object)null) { TryAssignTexture(val2, "_BaseMap", (Texture)(object)texture); TryAssignTexture(val2, "_MainTex", (Texture)(object)texture); } if (val2.HasProperty("_Surface")) { val2.SetFloat("_Surface", 0f); } if (val2.HasProperty("_Blend")) { val2.SetFloat("_Blend", 0f); } if (val2.HasProperty("_ZWrite")) { val2.SetFloat("_ZWrite", 1f); } if (val2.HasProperty("_Cull")) { val2.SetFloat("_Cull", 0f); } val2.SetOverrideTag("RenderType", "Opaque"); val2.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); val2.EnableKeyword("_SURFACE_TYPE_OPAQUE"); ApplyMikuColorStyle(val2); return val2; } } public class MikuMarker : MonoBehaviour { } public class MikuSuppressedRendererSource : MonoBehaviour { } public class MikuPoseTemplate : MonoBehaviour { private Vector3 _authoredLocalPosition = Vector3.zero; private Quaternion _authoredLocalRotation = Quaternion.identity; private Vector3 _authoredLocalScale = Vector3.one; public Vector3 AuthoredLocalPosition => _authoredLocalPosition; public Quaternion AuthoredLocalRotation => _authoredLocalRotation; public Vector3 AuthoredLocalScale => _authoredLocalScale; public void Initialize(Vector3 localPosition, Quaternion localRotation, Vector3 localScale) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) _authoredLocalPosition = localPosition; _authoredLocalRotation = localRotation; _authoredLocalScale = ((localScale == Vector3.zero) ? Vector3.one : localScale); } } public class MikuDeformGuard : MonoBehaviour { private const float SqueezeDuration = 0.78f; private const float SqueezeCompressPhase = 0.42f; private Transform[] _allTransforms = Array.Empty<Transform>(); private Vector3[] _initialChildScales = Array.Empty<Vector3>(); private Vector3 _rootLocalPosition; private Quaternion _rootLocalRotation; private Vector3 _rootLocalScale; private Item _boundItem; private bool _wasUsing; private float _squeezeElapsed = 0.78f; public void Initialize(Vector3 rootLocalPosition, Quaternion rootLocalRotation, Vector3 rootLocalScale) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) _rootLocalPosition = rootLocalPosition; _rootLocalRotation = rootLocalRotation; _rootLocalScale = rootLocalScale; _wasUsing = false; _squeezeElapsed = 0.78f; Capture(); } public void Bind(Item item) { _boundItem = item; } public void SetRootTarget(Vector3 rootLocalPosition, Quaternion rootLocalRotation, Vector3 rootLocalScale) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) _rootLocalPosition = rootLocalPosition; _rootLocalRotation = rootLocalRotation; _rootLocalScale = rootLocalScale; } private bool IsHeldAndUsing() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Invalid comparison between Unknown and I4 if ((Object)(object)_boundItem != (Object)null && (int)_boundItem.itemState == 1) { if (!_boundItem.isUsingPrimary) { return _boundItem.isUsingSecondary; } return true; } return false; } private void UpdateSingleSqueezeState() { bool flag = IsHeldAndUsing(); if (flag && !_wasUsing) { _squeezeElapsed = 0f; } _wasUsing = flag; if (_squeezeElapsed < 0.78f) { _squeezeElapsed += Time.deltaTime; } } private float EvaluateSingleSqueezeWeight() { if (_squeezeElapsed >= 0.78f) { return 0f; } float num = Mathf.Clamp01(_squeezeElapsed / 0.78f); if (num <= 0.42f) { return Mathf.SmoothStep(0f, 1f, num / 0.42f); } float num2 = (num - 0.42f) / 0.58000004f; return Mathf.SmoothStep(1f, 0f, Mathf.Clamp01(num2)); } private Vector3 GetDesiredRootScale(float squeezeWeight) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) if (squeezeWeight <= 0.0005f) { return _rootLocalScale; } Vector3 val = default(Vector3); ((Vector3)(ref val))..ctor(1f - 0.14f * squeezeWeight, 1f + 0.11f * squeezeWeight, 1f - 0.14f * squeezeWeight); return Vector3.Scale(_rootLocalScale, val); } public void Capture() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) _allTransforms = ((Component)this).GetComponentsInChildren<Transform>(true); _initialChildScales = (Vector3[])(object)new Vector3[_allTransforms.Length]; for (int i = 0; i < _allTransforms.Length; i++) { _initialChildScales[i] = _allTransforms[i].localScale; } } private void LateUpdate() { //IL_0027: 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) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_008e: 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_0069: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) if (_allTransforms.Length == 0 || _allTransforms.Length != _initialChildScales.Length) { Capture(); } if (((Component)this).transform.localPosition != _rootLocalPosition) { ((Component)this).transform.localPosition = _rootLocalPosition; } if (((Component)this).transform.localRotation != _rootLocalRotation) { ((Component)this).transform.localRotation = _rootLocalRotation; } UpdateSingleSqueezeState(); float squeezeWeight = EvaluateSingleSqueezeWeight(); Vector3 desiredRootScale = GetDesiredRootScale(squeezeWeight); if (((Component)this).transform.localScale != desiredRootScale) { ((Component)this).transform.localScale = desiredRootScale; } for (int i = 0; i < _allTransforms.Length; i++) { Transform val = _allTransforms[i]; if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)((Component)this).transform) && val.localScale != _initialChildScales[i]) { val.localScale = _initialChildScales[i]; } } } } public class MikuRendererGuard : MonoBehaviour { private const float RefreshInterval = 0.1f; private float _nextRefreshTime; private Item _boundItem; private Renderer[] _cachedRenderers = Array.Empty<Renderer>(); public void Bind(Item item) { _boundItem = item; } private void LateUpdate() { if (!Plugin.ModEnabled || !Plugin.EnableVisibilityGuard || Time.time < _nextRefreshTime) { return; } _nextRefreshTime = Time.time + 0.1f; if (!((Component)this).gameObject.activeSelf) { ((Component)this).gameObject.SetActive(true); } int num = (((Object)(object)_boundItem != (Object)null) ? ((Component)_boundItem).gameObject.layer : ((Component)this).gameObject.layer); if (((Component)this).gameObject.layer != num) { ((Component)this).gameObject.layer = num; } Renderer[] renderableChildren = GetRenderableChildren(); foreach (Renderer val in renderableChildren) { if (!((Object)(object)val == (Object)null) && !ItemPatch.IsSuppressedReplacementRenderer(val)) { EnsureRendererVisible(val, num); } } if ((Object)(object)_boundItem != (Object)null && Time.frameCount % 300 == 0) { ItemPatch.ForceNormalizeAllMaterials(((Component)this).transform); } } private Renderer[] GetRenderableChildren() { if (_cachedRenderers.Length == 0 || HasNullRenderer(_cachedRenderers)) { _cachedRenderers = ((Component)this).GetComponentsInChildren<Renderer>(true); } return _cachedRenderers; } private static bool HasNullRenderer(Renderer[] renderers) { for (int i = 0; i < renderers.Length; i++) { if ((Object)(object)renderers[i] == (Object)null) { return true; } } return false; } private static void EnsureRendererVisible(Renderer renderer, int targetLayer) { if (!((Component)renderer).gameObject.activeSelf) { ((Component)renderer).gameObject.SetActive(true); } if (renderer.forceRenderingOff) { renderer.forceRenderingOff = false; } if (!renderer.enabled) { renderer.enabled = true; } renderer.SetPropertyBlock((MaterialPropertyBlock)null); ((Component)renderer).gameObject.layer = targetLayer; renderer.allowOcclusionWhenDynamic = false; } } [HarmonyPatch(typeof(Item))] public class ItemPatch { private const int VisibleLayer = 0; private static readonly Color MikuMaterialTint = new Color(0.98f, 1f, 1f, 1f); private const string MikuVisualName = "FufuVisual"; private static readonly Vector3 WorldMikuLocalPositionOffset = new Vector3(0f, 0.08f, 0.03f); private static readonly Quaternion WorldMikuLocalRotationOffset = Quaternion.Euler(0f, 180f, 0f); private static readonly Vector3 HeldMikuLocalPositionOffset = new Vector3(0f, 0f, 0f); private static readonly Quaternion HeldMikuLocalRotationOffset = Quaternion.Euler(10f, 180f, 0f); private static readonly string[] AltTextureRendererKeywords = new string[1] { "装饰" }; private static readonly string[] MainTextureRendererKeywords = new string[4] { "头发", "衣服", "身子", "马尾" }; private static readonly string[] ClothingRendererKeywords = new string[1] { "衣服" }; private static readonly string[] UnwantedFootKeywords = new string[3] { "hand", "glove", "mitten" }; private const float BaseModelScaleFactor = 0.25f; private static Shader _cachedPreferredShader; private static bool IsBingBong(Item item) { if ((Object)(object)item != (Object)null) { return ((Object)item).name.IndexOf("BingBong", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } private static bool IsReplacementItemName(string itemName) { if (string.IsNullOrEmpty(itemName)) { return false; } if (itemName.IndexOf("Bing Bong", StringComparison.OrdinalIgnoreCase) < 0 && itemName.IndexOf("BingBong", StringComparison.OrdinalIgnoreCase) < 0) { return itemName.IndexOf("Fufu", StringComparison.OrdinalIgnoreCase) >= 0; } return true; } internal static bool IsMikuTransform(Transform transform) { if ((Object)(object)transform != (Object)null) { return (Object)(object)((Component)transform).GetComponentInParent<MikuMarker>() != (Object)null; } return false; } internal static bool IsSuppressedReplacementRenderer(Renderer renderer) { if ((Object)(object)renderer != (Object)null) { return (Object)(object)((Component)renderer).GetComponent<MikuSuppressedRendererSource>() != (Object)null; } return false; } private static bool IsInBackpack(Item item) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 if ((Object)(object)item != (Object)null) { return (int)item.itemState == 2; } return false; } private static bool IsHeld(Item item) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Invalid comparison between Unknown and I4 if ((Object)(object)item != (Object)null) { return (int)item.itemState == 1; } return false; } private static bool ShouldShowReplacement(Item item) { if ((Object)(object)item != (Object)null) { return Plugin.ModEnabled; } return false; } private static void GetAuthoredRootPose(Transform mikuRoot, out Vector3 localPosition, out Quaternion localRotation, out Vector3 localScale) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_0099: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) MikuPoseTemplate mikuPoseTemplate = (((Object)(object)mikuRoot != (Object)null) ? ((Component)mikuRoot).GetComponent<MikuPoseTemplate>() : null); if ((Object)(object)mikuPoseTemplate != (Object)null) { localPosition = mikuPoseTemplate.AuthoredLocalPosition; localRotation = mikuPoseTemplate.AuthoredLocalRotation; localScale = mikuPoseTemplate.AuthoredLocalScale; } else if ((Object)(object)mikuRoot != (Object)null) { localPosition = mikuRoot.localPosition; localRotation = mikuRoot.localRotation; localScale = ((mikuRoot.localScale == Vector3.zero) ? Vector3.one : mikuRoot.localScale); } else { localPosition = Vector3.zero; localRotation = Quaternion.identity; localScale = Vector3.one; } } private static Vector3 ResolveScaleByState(Item item, Vector3 authoredScale) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) float num = (IsInBackpack(item) ? Plugin.BackpackScaleMultiplier : Plugin.WorldScaleMultiplier); return ApplyPlayerFacingScale((authoredScale == Vector3.zero) ? Vector3.one : authoredScale) * 0.25f * num; } private static Vector3 ApplyPlayerFacingScale(Vector3 scale) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) return new Vector3(Mathf.Abs(scale.x), Mathf.Abs(scale.y), Mathf.Abs(scale.z)); } private static void ResolvePoseByState(Item item, Transform mikuRoot, out Vector3 localPosition, out Quaternion localRotation, out Vector3 localScale) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) GetAuthoredRootPose(mikuRoot, out var localPosition2, out var localRotation2, out var localScale2); ResolvePoseByState(item, localPosition2, localRotation2, localScale2, out localPosition, out localRotation, out localScale); } private static void ResolvePoseByState(Item item, Vector3 authoredPosition, Quaternion authoredRotation, Vector3 authoredScale, out Vector3 localPosition, out Quaternion localRotation, out Vector3 localScale) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0064: 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_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) localScale = ResolveScaleByState(item, authoredScale); if (IsHeld(item)) { localPosition = authoredPosition + HeldMikuLocalPositionOffset; localRotation = authoredRotation * HeldMikuLocalRotationOffset; } else { localPosition = authoredPosition + WorldMikuLocalPositionOffset; localRotation = (IsInBackpack(item) ? authoredRotation : (authoredRotation * WorldMikuLocalRotationOffset)); } } private static Transform FindMikuRoot(Item item) { if ((Object)(object)item == (Object)null) { return null; } MikuMarker[] componentsInChildren = ((Component)item).GetComponentsInChildren<MikuMarker>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { return ((Component)componentsInChildren[i]).transform; } } return ((Component)item).transform.Find("FufuVisual"); } private static Texture GetMikuTexture() { if ((Object)(object)Plugin.MikuMainTexture != (Object)null) { return (Texture)(object)Plugin.MikuMainTexture; } return null; } private static Texture GetAltMikuTexture() { return (Texture)(object)Plugin.MikuAltTexture; } private static bool IsMainTextureRenderer(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return false; } string obj = ((Object)((Component)renderer).gameObject).name?.ToLowerInvariant() ?? string.Empty; string text = ((Object)renderer).name?.ToLowerInvariant() ?? string.Empty; string text2 = obj + " " + text; if (ContainsKeyword(obj, MainTextureRendererKeywords) || ContainsKeyword(text, MainTextureRendererKeywords)) { return true; } if (text2.Contains("cloth") || text2.Contains("clothes") || text2.Contains("dress") || text2.Contains("shirt")) { return true; } if (text2.Contains("头发") || text2.Contains("发")) { return true; } if (text2.Contains("身体") || text2.Contains("身子")) { return true; } if (text2.Contains("马尾") || text2.Contains("尾巴")) { return true; } if (text2.Contains("衣服") || text2.Contains("服装")) { return true; } return false; } private static bool IsClothingRenderer(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return false; } string obj = ((Object)((Component)renderer).gameObject).name?.ToLowerInvariant() ?? string.Empty; string text = ((Object)renderer).name?.ToLowerInvariant() ?? string.Empty; string text2 = obj + " " + text; if (ContainsKeyword(obj, ClothingRendererKeywords) || ContainsKeyword(text, ClothingRendererKeywords)) { return true; } if (text2.Contains("cloth") || text2.Contains("clothes") || text2.Contains("dress") || text2.Contains("shirt")) { return true; } if (text2.Contains("衣服") || text2.Contains("服装")) { return true; } return false; } private static bool IsAltTextureRenderer(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return false; } string value = ((Object)((Component)renderer).gameObject).name?.ToLowerInvariant() ?? string.Empty; string value2 = ((Object)renderer).name?.ToLowerInvariant() ?? string.Empty; if (!ContainsKeyword(value, AltTextureRendererKeywords)) { return ContainsKeyword(value2, AltTextureRendererKeywords); } return true; } private static Texture TryGetTexture(Material material) { if ((Object)(object)material == (Object)null) { return null; } if (material.HasProperty("_BaseMap")) { Texture texture = material.GetTexture("_BaseMap"); if ((Object)(object)texture != (Object)null) { return texture; } } if (material.HasProperty("_MainTex")) { return material.GetTexture("_MainTex"); } return null; } private static bool TrySetTextureSafe(Material material, string propertyName, Texture texture) { if ((Object)(object)material == (Object)null || string.IsNullOrEmpty(propertyName) || !material.HasProperty(propertyName)) { return false; } try { material.SetTexture(propertyName, texture); return true; } catch (Exception ex) { Plugin.VerboseLog("[ItemPatch] Skip SetTexture on material '" + ((Object)material).name + "' property '" + propertyName + "': " + ex.Message); return false; } } private static void TrySetTextureTransformSafe(Material material, string propertyName, Vector2 scale, Vector2 offset) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)material == (Object)null || string.IsNullOrEmpty(propertyName) || !material.HasProperty(propertyName)) { return; } try { material.SetTextureScale(propertyName, scale); material.SetTextureOffset(propertyName, offset); } catch (Exception ex) { Plugin.VerboseLog("[ItemPatch] Skip texture transform on material '" + ((Object)material).name + "' property '" + propertyName + "': " + ex.Message); } } private static void ApplyMikuTextureSafe(Material material, Texture mikuTexture) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_005c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)material == (Object)null) && !((Object)(object)mikuTexture == (Object)null)) { try { material.mainTexture = mikuTexture; } catch { } if (TrySetTextureSafe(material, "_BaseMap", mikuTexture)) { TrySetTextureTransformSafe(material, "_BaseMap", Vector2.one, Vector2.zero); } if (TrySetTextureSafe(material, "_MainTex", mikuTexture)) { TrySetTextureTransformSafe(material, "_MainTex", Vector2.one, Vector2.zero); } } } private static void DisableOptionalSurfaceTextures(Material material) { if (!((Object)(object)material == (Object)null)) { TrySetTextureSafe(material, "_BumpMap", null); TrySetTextureSafe(material, "_NormalMap", null); TrySetTextureSafe(material, "_OcclusionMap", null); TrySetTextureSafe(material, "_MetallicGlossMap", null); TrySetTextureSafe(material, "_SpecGlossMap", null); material.DisableKeyword("_NORMALMAP"); material.DisableKeyword("_METALLICSPECGLOSSMAP"); material.DisableKeyword("_OCCLUSIONMAP"); } } private static void OptimizeTextureSampling(Texture texture) { Texture2D val = (Texture2D)(object)((texture is Texture2D) ? texture : null); if (!((Object)(object)val == (Object)null)) { ((Texture)val).filterMode = (FilterMode)2; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Texture)val).anisoLevel = Mathf.Max(((Texture)val).anisoLevel, 16); ((Texture)val).mipMapBias = Mathf.Min(((Texture)val).mipMapBias, -0.75f); } } private static void ApplyRealisticMaterialTuning(Material material) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_0145: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)material == (Object)null)) { if (material.HasProperty("_Tint")) { material.SetColor("_Tint", MikuMaterialTint); } if (material.HasProperty("_BaseColor")) { material.SetColor("_BaseColor", MikuMaterialTint); } if (material.HasProperty("_Color")) { material.SetColor("_Color", MikuMaterialTint); } if (material.HasProperty("_Smoothness")) { material.SetFloat("_Smoothness", 0.1f); } if (material.HasProperty("_Glossiness")) { material.SetFloat("_Glossiness", 0.1f); } if (material.HasProperty("_Metallic")) { material.SetFloat("_Metallic", 0f); } if (material.HasProperty("_BumpScale")) { material.SetFloat("_BumpScale", 0f); } if (material.HasProperty("_OcclusionStrength")) { material.SetFloat("_OcclusionStrength", 0f); } if (material.HasProperty("_SpecularHighlights")) { material.SetFloat("_SpecularHighlights", 0f); } if (material.HasProperty("_EnvironmentReflections")) { material.SetFloat("_EnvironmentReflections", 0f); } DisableOptionalSurfaceTextures(material); if (material.HasProperty("_EmissionColor")) { material.SetColor("_EmissionColor", Color.black); material.DisableKeyword("_EMISSION"); } } } private static Shader GetPreferredRendererShader() { if ((Object)(object)_cachedPreferredShader != (Object)null && _cachedPreferredShader.isSupported) { return _cachedPreferredShader; } _cachedPreferredShader = null; Shader val = Shader.Find("Universal Render Pipeline/Lit"); if ((Object)(object)val != (Object)null && val.isSupported) { _cachedPreferredShader = val; return val; } val = Shader.Find("Universal Render Pipeline/Unlit"); if ((Object)(object)val != (Object)null && val.isSupported) { _cachedPreferredShader = val; return val; } val = Shader.Find("W/Peak_Standard"); if ((Object)(object)val != (Object)null && val.isSupported) { _cachedPreferredShader = val; return val; } val = Shader.Find("Standard"); if ((Object)(object)val != (Object)null && val.isSupported) { _cachedPreferredShader = val; return val; } val = Shader.Find("Unlit/Texture"); if ((Object)(object)val != (Object)null && val.isSupported) { _cachedPreferredShader = val; return val; } return null; } private static Material CreateFallbackMaterial() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown Shader preferredRendererShader = GetPreferredRendererShader(); if ((Object)(object)preferredRendererShader == (Object)null) { return null; } return new Material(preferredRendererShader) { name = "Fufu_Fallback", color = Color.white }; } private static void ApplyOpaqueSurfaceFlags(Material material, CullMode cullMode) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)material == (Object)null)) { if (material.HasProperty("_Surface")) { material.SetFloat("_Surface", 0f); } if (material.HasProperty("_Blend")) { material.SetFloat("_Blend", 0f); } if (material.HasProperty("_ZWrite")) { material.SetFloat("_ZWrite", 1f); } if (material.HasProperty("_SrcBlend")) { material.SetFloat("_SrcBlend", 1f); } if (material.HasProperty("_DstBlend")) { material.SetFloat("_DstBlend", 0f); } if (material.HasProperty("_Cull")) { material.SetFloat("_Cull", (float)cullMode); } if (material.HasProperty("_AlphaClip")) { material.SetFloat("_AlphaClip", 0f); } if (material.HasProperty("_Cutoff")) { material.SetFloat("_Cutoff", 0f); } if (material.HasProperty("_LOD")) { material.SetFloat("_LOD", 600f); } material.renderQueue = 2000; material.SetOverrideTag("RenderType", "Opaque"); material.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); material.EnableKeyword("_SURFACE_TYPE_OPAQUE"); material.DisableKeyword("_ALPHATEST_ON"); material.DisableKeyword("_ALPHABLEND_ON"); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.DisableKeyword("LOD_FADE_CROSSFADE"); } } private static int GetRendererSubMeshCount(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return 1; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if ((Object)(object)val != (Object)null && (Object)(object)val.sharedMesh != (Object)null) { return Mathf.Max(1, val.sharedMesh.subMeshCount); } MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>(); if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) { return Mathf.Max(1, component.sharedMesh.subMeshCount); } return 1; } private static Material PickFallbackMaterial(Material[] materials) { if (materials != null) { for (int i = 0; i < materials.Length; i++) { if ((Object)(object)materials[i] != (Object)null) { return materials[i]; } } } return Plugin.MochiMaterial ?? Plugin.RuntimeMikuMaterial; } private static Material[] CreateNormalizedMaterialArray(Material[] sourceMaterials, int subMeshCount) { int num = Mathf.Max(1, subMeshCount); Material[] array = (Material[])(object)new Material[num]; Material val = PickFallbackMaterial(sourceMaterials); for (int i = 0; i < num; i++) { Material val2 = ((sourceMaterials != null && i < sourceMaterials.Length) ? sourceMaterials[i] : null); array[i] = val2 ?? val; } return array; } private static bool MaterialArraysMatch(Material[] current, Material[] expected) { if (current == expected) { return true; } if (current == null || expected == null || current.Length != expected.Length) { return false; } for (int i = 0; i < current.Length; i++) { if ((Object)(object)current[i] != (Object)(object)expected[i]) { return false; } } return true; } private static bool NormalizeRendererMaterialLayout(Renderer renderer) { if ((Object)(object)renderer == (Object)null || IsSuppressedReplacementRenderer(renderer)) { return false; } int rendererSubMeshCount = GetRendererSubMeshCount(renderer); Material[] sharedMaterials = renderer.sharedMaterials; Material[] array = CreateNormalizedMaterialArray(sharedMaterials, rendererSubMeshCount); if (MaterialArraysMatch(sharedMaterials, array)) { return false; } renderer.sharedMaterials = array; return true; } private static void CopyRendererSettings(Renderer source, MeshRenderer target) { //IL_0015: 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) //IL_0039: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)source == (Object)null) && !((Object)(object)target == (Object)null)) { ((Renderer)target).shadowCastingMode = source.shadowCastingMode; ((Renderer)target).receiveShadows = source.receiveShadows; ((Renderer)target).lightProbeUsage = source.lightProbeUsage; ((Renderer)target).reflectionProbeUsage = source.reflectionProbeUsage; ((Renderer)target).probeAnchor = source.probeAnchor; ((Renderer)target).allowOcclusionWhenDynamic = source.allowOcclusionWhenDynamic; ((Renderer)target).enabled = source.enabled; } } private static bool BakeSkinnedRendererToStaticRenderer(SkinnedMeshRenderer source) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_0093: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: 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_00e7: 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) if ((Object)(object)source == (Object)null || (Object)(object)source.sharedMesh == (Object)null || IsSuppressedReplacementRenderer((Renderer)(object)source)) { return false; } Mesh val = new Mesh { name = ((Object)source.sharedMesh).name + "_RuntimeBaked" }; try { source.BakeMesh(val); } catch (Exception ex) { Object.Destroy((Object)(object)val); Plugin.Log.LogWarning((object)("[ItemPatch] Failed to bake skinned renderer '" + ((Object)source).name + "': " + ex.Message)); return false; } GameObject val2 = new GameObject(((Object)((Component)source).gameObject).name + "_Baked"); val2.transform.SetParent(((Component)source).transform.parent, false); val2.transform.localPosition = ((Component)source).transform.localPosition; val2.transform.localRotation = ((Component)source).transform.localRotation; val2.transform.localScale = ((Component)source).transform.localScale; val2.AddComponent<MeshFilter>().sharedMesh = val; MeshRenderer val3 = val2.AddComponent<MeshRenderer>(); CopyRendererSettings((Renderer)(object)source, val3); ((Renderer)val3).sharedMaterials = CreateNormalizedMaterialArray(((Renderer)source).sharedMaterials, val.subMeshCount); if ((Object)(object)((Component)source).gameObject.GetComponent<MikuSuppressedRendererSource>() == (Object)null) { ((Component)source).gameObject.AddComponent<MikuSuppressedRendererSource>(); } ((Renderer)source).enabled = false; ((Renderer)source).forceRenderingOff = true; return true; } private static void RegeneratePrefabRenderers(Transform mikuRoot) { if ((Object)(object)mikuRoot == (Object)null) { return; } int num = 0; SkinnedMeshRenderer[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<SkinnedMeshRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if (BakeSkinnedRendererToStaticRenderer(componentsInChildren[i])) { num++; } } int num2 = 0; MeshRenderer[] componentsInChildren2 = ((Component)mikuRoot).GetComponentsInChildren<MeshRenderer>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { if (NormalizeRendererMaterialLayout((Renderer)(object)componentsInChildren2[j])) { num2++; } } ForceNormalizeAllMaterials(mikuRoot); if (num > 0 || num2 > 0) { Plugin.Log.LogInfo((object)("[ItemPatch] Regenerated renderers for prefab '" + ((Object)mikuRoot).name + "': bakedSkinned=" + num + ", normalizedMaterials=" + num2)); } } internal static void ForceNormalizeAllMaterials(Transform mikuRoot) { if ((Object)(object)mikuRoot == (Object)null) { return; } Renderer[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Renderer>(true); int num = 0; foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null || IsSuppressedReplacementRenderer(val)) { continue; } int rendererSubMeshCount = GetRendererSubMeshCount(val); Material[] sharedMaterials = val.sharedMaterials; if (sharedMaterials != null && sharedMaterials.Length > rendererSubMeshCount) { Material[] array = (Material[])(object)new Material[rendererSubMeshCount]; for (int j = 0; j < rendererSubMeshCount; j++) { array[j] = sharedMaterials[j]; } val.sharedMaterials = array; num++; } else if (sharedMaterials == null || sharedMaterials.Length == 0) { Material val2 = Plugin.MochiMaterial ?? Plugin.RuntimeMikuMaterial; if ((Object)(object)val2 != (Object)null) { val.material = val2; num++; } } } if (num > 0) { Plugin.Log.LogInfo((object)("[Fix] Normalized materials on " + num + " renderers under '" + ((Object)mikuRoot).name + "'")); } } private static void ReplaceRendererMaterialsCompletely(Renderer renderer, int targetLayer) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Expected O, but got Unknown //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)renderer == (Object)null) { return; } int rendererSubMeshCount = GetRendererSubMeshCount(renderer); if (rendererSubMeshCount == 0) { return; } Shader preferredRendererShader = GetPreferredRendererShader(); if ((Object)(object)preferredRendererShader == (Object)null) { return; } bool num = IsAltTextureRenderer(renderer); bool flag = IsMainTextureRenderer(renderer); bool flag2 = IsClothingRenderer(renderer); Texture val = (num ? GetAltMikuTexture() : (flag ? GetMikuTexture() : GetMikuTexture())); if ((Object)(object)val == (Object)null && !flag2) { return; } Material[] array = (Material[])(object)new Material[rendererSubMeshCount]; for (int i = 0; i < rendererSubMeshCount; i++) { Material val2 = new Material(preferredRendererShader); ((Object)val2).name = "Fufu_" + ((Object)renderer).name + "_" + i; val2.color = Color.white; val2.renderQueue = 2000; ApplyOpaqueSurfaceFlags(val2, (CullMode)0); if ((Object)(object)val != (Object)null) { ApplyMikuTextureSafe(val2, val); } if (val2.HasProperty("_Smoothness")) { val2.SetFloat("_Smoothness", 0.1f); } if (val2.HasProperty("_Glossiness")) { val2.SetFloat("_Glossiness", 0.1f); } if (val2.HasProperty("_Metallic")) { val2.SetFloat("_Metallic", 0f); } if (val2.HasProperty("_BumpScale")) { val2.SetFloat("_BumpScale", 0f); } if (val2.HasProperty("_OcclusionStrength")) { val2.SetFloat("_OcclusionStrength", 0f); } if (val2.HasProperty("_SpecularHighlights")) { val2.SetFloat("_SpecularHighlights", 0f); } if (val2.HasProperty("_EnvironmentReflections")) { val2.SetFloat("_EnvironmentReflections", 0f); } if (val2.HasProperty("_EmissionColor")) { val2.SetColor("_EmissionColor", Color.black); val2.DisableKeyword("_EMISSION"); } array[i] = val2; } renderer.sharedMaterials = array; } private static bool HasVisibleReplacementRenderers(Transform mikuRoot) { if ((Object)(object)mikuRoot == (Object)null) { return false; } Renderer[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if ((Object)(object)val == (Object)null || IsSuppressedReplacementRenderer(val)) { continue; } Material[] sharedMaterials = val.sharedMaterials; if (sharedMaterials == null || sharedMaterials.Length == 0) { continue; } for (int j = 0; j < sharedMaterials.Length; j++) { if ((Object)(object)sharedMaterials[j] != (Object)null) { return true; } } } return false; } private static void DisableOriginalRenderers(Item item) { if ((Object)(object)item == (Object)null) { return; } Transform val = FindMikuRoot(item); Renderer[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Renderer>(true); int num = 0; foreach (Renderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && !IsMikuTransform(((Component)val2).transform) && (!((Object)(object)val != (Object)null) || !((Component)val2).transform.IsChildOf(val))) { bool enabled = val2.enabled; val2.enabled = false; val2.forceRenderingOff = true; if (enabled) { num++; } } } if (num > 0) { Plugin.VerboseLog("[Fix] Disabled " + num + " original renderers on item: " + ((Object)item).name); } } private static void EnableOriginalRenderers(Item item) { if ((Object)(object)item == (Object)null) { return; } Transform val = FindMikuRoot(item); Renderer[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && !IsMikuTransform(((Component)val2).transform) && (!((Object)(object)val != (Object)null) || !((Component)val2).transform.IsChildOf(val))) { val2.enabled = true; } } } private static void EnableOriginalColliders(Item item) { Collider[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Collider>(true); List<Collider> list = new List<Collider>(); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !IsMikuTransform(((Component)val).transform)) { val.enabled = true; list.Add(val); } } if ((Object)(object)item != (Object)null) { item.colliders = list.ToArray(); } } private static void DisableOriginalColliders(Item item) { Collider[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !IsMikuTransform(((Component)val).transform)) { val.enabled = false; } } } private static Collider FindColliderTemplate(Item item) { if ((Object)(object)item == (Object)null) { return null; } Collider[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if ((Object)(object)val != (Object)null && !IsMikuTransform(((Component)val).transform)) { return val; } } return null; } private static Vector3 ClampColliderSize(Vector3 size) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) return new Vector3(Mathf.Max(size.x, 0.02f), Mathf.Max(size.y, 0.02f), Mathf.Max(size.z, 0.02f)); } private static bool HasNegativeScaleInHierarchy(Transform transform) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) Transform val = transform; while ((Object)(object)val != (Object)null) { Vector3 localScale = val.localScale; if (localScale.x < 0f || localScale.y < 0f || localScale.z < 0f) { return true; } val = val.parent; } return false; } private static void CopyColliderSettings(Collider source, Collider target) { if (!((Object)(object)target == (Object)null)) { if ((Object)(object)source != (Object)null) { target.isTrigger = source.isTrigger; target.sharedMaterial = source.sharedMaterial; target.contactOffset = source.contactOffset; } target.enabled = true; } } private static Collider AddBoxColliderForMeshRenderer(MeshRenderer renderer, Collider templateCollider) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)renderer == (Object)null) { return null; } if (HasNegativeScaleInHierarchy(((Component)renderer).transform)) { return null; } MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>(); if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null) { return null; } Bounds bounds = component.sharedMesh.bounds; Vector3 size = ((Bounds)(ref bounds)).size; if (((Vector3)(ref size)).sqrMagnitude <= 0f) { return null; } BoxCollider val = ((Component)renderer).gameObject.GetComponent<BoxCollider>(); if ((Object)(object)val == (Object)null) { val = ((Component)renderer).gameObject.AddComponent<BoxCollider>(); } val.center = ((Bounds)(ref bounds)).center; val.size = ClampColliderSize(((Bounds)(ref bounds)).size); CopyColliderSettings(templateCollider, (Collider)(object)val); return (Collider)(object)val; } private static Collider AddBoxColliderForSkinnedRenderer(SkinnedMeshRenderer renderer, Collider templateCollider) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //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_008d: 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) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)renderer == (Object)null) { return null; } if (HasNegativeScaleInHierarchy(((Component)renderer).transform)) { return null; } Bounds val = ((Renderer)renderer).localBounds; Vector3 size = ((Bounds)(ref val)).size; if (((Vector3)(ref size)).sqrMagnitude <= 0f && (Object)(object)renderer.sharedMesh != (Object)null) { val = renderer.sharedMesh.bounds; } size = ((Bounds)(ref val)).size; if (((Vector3)(ref size)).sqrMagnitude <= 0f) { return null; } BoxCollider val2 = ((Component)renderer).gameObject.GetComponent<BoxCollider>(); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)renderer).gameObject.AddComponent<BoxCollider>(); } val2.center = ((Bounds)(ref val)).center; val2.size = ClampColliderSize(((Bounds)(ref val)).size); CopyColliderSettings(templateCollider, (Collider)(object)val2); return (Collider)(object)val2; } private static void EncapsulateBoundsCorners(ref Bounds aggregateBounds, ref bool hasBounds, Transform root, Bounds rendererBounds) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: 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_0099: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: 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_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0108: 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) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0120: 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_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0172: 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_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: 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) Vector3 center = ((Bounds)(ref rendererBounds)).center; Vector3 extents = ((Bounds)(ref rendererBounds)).extents; Vector3[] array = (Vector3[])(object)new Vector3[8] { center + new Vector3(0f - extents.x, 0f - extents.y, 0f - extents.z), center + new Vector3(0f - extents.x, 0f - extents.y, extents.z), center + new Vector3(0f - extents.x, extents.y, 0f - extents.z), center + new Vector3(0f - extents.x, extents.y, extents.z), center + new Vector3(extents.x, 0f - extents.y, 0f - extents.z), center + new Vector3(extents.x, 0f - extents.y, extents.z), center + new Vector3(extents.x, extents.y, 0f - extents.z), center + new Vector3(extents.x, extents.y, extents.z) }; for (int i = 0; i < array.Length; i++) { Vector3 val = root.InverseTransformPoint(array[i]); if (!hasBounds) { aggregateBounds = new Bounds(val, Vector3.zero); hasBounds = true; } else { ((Bounds)(ref aggregateBounds)).Encapsulate(val); } } } private static Collider AddFallbackRootCollider(Transform mikuRoot, Collider templateCollider) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)mikuRoot == (Object)null) { return null; } Renderer[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Renderer>(true); Bounds aggregateBounds = default(Bounds); bool hasBounds = false; foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { EncapsulateBoundsCorners(ref aggregateBounds, ref hasBounds, mikuRoot, val.bounds); } } if (!hasBounds) { return null; } BoxCollider val2 = ((Component)mikuRoot).gameObject.GetComponent<BoxCollider>(); if ((Object)(object)val2 == (Object)null) { val2 = ((Component)mikuRoot).gameObject.AddComponent<BoxCollider>(); } val2.center = ((Bounds)(ref aggregateBounds)).center; val2.size = ClampColliderSize(((Bounds)(ref aggregateBounds)).size); CopyColliderSettings(templateCollider, (Collider)(object)val2); return (Collider)(object)val2; } private static void RebuildModelColliders(Item item, Transform mikuRoot) { if ((Object)(object)item == (Object)null || (Object)(object)mikuRoot == (Object)null) { return; } Collider templateCollider = FindColliderTemplate(item); Collider[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if ((Object)(object)val != (Object)null) { Object.Destroy((Object)(object)val); } } List<Collider> list = new List<Collider>(); MeshRenderer[] componentsInChildren2 = ((Component)mikuRoot).GetComponentsInChildren<MeshRenderer>(true); foreach (MeshRenderer val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null) && !IsSuppressedReplacementRenderer((Renderer)(object)val2)) { Collider val3 = AddBoxColliderForMeshRenderer(val2, templateCollider); if ((Object)(object)val3 != (Object)null) { list.Add(val3); } } } SkinnedMeshRenderer[] componentsInChildren3 = ((Component)mikuRoot).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val4 in componentsInChildren3) { if (!((Object)(object)val4 == (Object)null) && !IsSuppressedReplacementRenderer((Renderer)(object)val4)) { Collider val5 = AddBoxColliderForSkinnedRenderer(val4, templateCollider); if ((Object)(object)val5 != (Object)null) { list.Add(val5); } } } if (list.Count == 0) { Collider val6 = AddFallbackRootCollider(mikuRoot, templateCollider); if ((Object)(object)val6 != (Object)null) { list.Add(val6); } } if (list.Count > 0) { item.colliders = list.ToArray(); DisableOriginalColliders(item); } } private static void EnsureModelColliders(Item item, Transform mikuRoot) { if (!((Object)(object)item == (Object)null) && !((Object)(object)mikuRoot == (Object)null)) { Collider[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Collider>(true); if (componentsInChildren.Length == 0) { RebuildModelColliders(item, mikuRoot); componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Collider>(true); } if (componentsInChildren.Length != 0) { item.colliders = componentsInChildren; DisableOriginalColliders(item); } } } private static int DetermineTargetLayer(Item item) { if ((Object)(object)item == (Object)null) { return 0; } Renderer[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !IsMikuTransform(((Component)val).transform)) { return ((Component)val).gameObject.layer; } } return ((Component)item).gameObject.layer; } private static void ConfigureMikuRenderer(Renderer renderer, int targetLayer) { ((Component)renderer).gameObject.layer = targetLayer; renderer.allowOcclusionWhenDynamic = false; renderer.shadowCastingMode = (ShadowCastingMode)1; renderer.receiveShadows = true; renderer.forceRenderingOff = false; renderer.enabled = true; renderer.SetPropertyBlock((MaterialPropertyBlock)null); if (!((Component)renderer).gameObject.activeSelf) { ((Component)renderer).gameObject.SetActive(true); } } private static bool RendererHasMainTexSlot(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return false; } Material[] sharedMaterials = renderer.sharedMaterials; if (sharedMaterials == null || sharedMaterials.Length == 0) { return false; } foreach (Material val in sharedMaterials) { if ((Object)(object)val != (Object)null && (val.HasProperty("_MainTex") || val.HasProperty("_BaseMap"))) { return true; } } return false; } private static Renderer[] BuildAdditionalRenderers(Renderer primaryRenderer, Renderer[] renderers) { if (renderers == null || renderers.Length == 0) { return Array.Empty<Renderer>(); } List<Renderer> list = new List<Renderer>(); foreach (Renderer val in renderers) { if (!((Object)(object)val == (Object)null) && !((Object)(object)val == (Object)(object)primaryRenderer)) { list.Add(val); } } if (list.Count != 0) { return list.ToArray(); } return Array.Empty<Renderer>(); } private static bool TryGetOriginalItemRenderers(Item item, out Renderer primaryRenderer, out Renderer[] additionalRenderers) { primaryRenderer = null; additionalRenderers = Array.Empty<Renderer>(); if ((Object)(object)item == (Object)null) { return false; } Renderer[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Renderer>(true); List<Renderer> list = new List<Renderer>(); foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !IsMikuTransform(((Component)val).transform) && !IsSuppressedReplacementRenderer(val)) { list.Add(val); } } if (list.Count == 0) { return false; } for (int j = 0; j < list.Count; j++) { Renderer val2 = list[j]; if ((Object)(object)primaryRenderer == (Object)null) { primaryRenderer = val2; } if (RendererHasMainTexSlot(val2)) { primaryRenderer = val2; break; } } if ((Object)(object)primaryRenderer == (Object)null) { return false; } additionalRenderers = BuildAdditionalRenderers(primaryRenderer, list.ToArray()); return true; } private static void EnsureItemRendererRefs(Item item, Transform mikuRoot) { if (Plugin.KeepOriginalRendererRefs && TryGetOriginalItemRenderers(item, out var primaryRenderer, out var additionalRenderers)) { item.mainRenderer = primaryRenderer; item.addtlRenderers = additionalRenderers; return; } Renderer[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Renderer>(true); if (componentsInChildren.Length == 0) { return; } Renderer val = null; foreach (Renderer val2 in componentsInChildren) { if (!((Object)(object)val2 == (Object)null) && !IsSuppressedReplacementRenderer(val2)) { if ((Object)(object)val == (Object)null) { val = val2; } if (RendererHasMainTexSlot(val2)) { val = val2; break; } } } if (!((Object)(object)val == (Object)null)) { item.mainRenderer = val; item.addtlRenderers = BuildAdditionalRenderers(val, componentsInChildren); } } private static void RestoreOriginalItemRendererRefs(Item item) { if (!((Object)(object)item == (Object)null) && TryGetOriginalItemRenderers(item, out var primaryRenderer, out var additionalRenderers)) { item.mainRenderer = primaryRenderer; item.addtlRenderers = additionalRenderers; } } private static void RemoveReplacement(Item item, Transform mikuRoot) { EnableOriginalRenderers(item); EnableOriginalColliders(item); RestoreOriginalItemRendererRefs(item); if ((Object)(object)mikuRoot != (Object)null) { Object.Destroy((Object)(object)((Component)mikuRoot).gameObject); } } private static void ApplyInitialMikuRendererSetup(Item item, Transform mikuRoot) { int num = DetermineTargetLayer(item); ((Component)mikuRoot).gameObject.layer = num; MeshRenderer[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<MeshRenderer>(true); SkinnedMeshRenderer[] componentsInChildren2 = ((Component)mikuRoot).GetComponentsInChildren<SkinnedMeshRenderer>(true); Plugin.VerboseLog("[ItemPatch] Renderer layout for " + ((Object)item).name + ": MeshRenderers=" + componentsInChildren.Length + ", SkinnedMeshRenderers=" + componentsInChildren2.Length); foreach (MeshRenderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !IsSuppressedReplacementRenderer((Renderer)(object)val)) { ConfigureMikuRenderer((Renderer)(object)val, num); ReplaceRendererMaterialsCompletely((Renderer)(object)val, num); } } foreach (SkinnedMeshRenderer val2 in componentsInChildren2) { if (!((Object)(object)val2 == (Object)null) && !IsSuppressedReplacementRenderer((Renderer)(object)val2)) { val2.updateWhenOffscreen = true; ConfigureMikuRenderer((Renderer)(object)val2, num); ReplaceRendererMaterialsCompletely((Renderer)(object)val2, num); } } EnsureItemRendererRefs(item, mikuRoot); } private static bool IsWhitelistedBehaviour(MonoBehaviour behaviour) { if (!(behaviour is MikuMarker) && !(behaviour is MikuSuppressedRendererSource) && !(behaviour is MikuPoseTemplate) && !(behaviour is MikuRendererGuard)) { return behaviour is MikuDeformGuard; } return true; } private static void SanitizeVisualObject(GameObject visualRoot, int targetLayer) { Collider[] componentsInChildren = visualRoot.GetComponentsInChildren<Collider>(true); foreach (Collider val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { val.enabled = false; Object.Destroy((Object)(object)val); } } Rigidbody[] componentsInChildren2 = visualRoot.GetComponentsInChildren<Rigidbody>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { if ((Object)(object)componentsInChildren2[j] != (Object)null) { Object.Destroy((Object)(object)componentsInChildren2[j]); } } Joint[] componentsInChildren3 = visualRoot.GetComponentsInChildren<Joint>(true); for (int k = 0; k < componentsInChildren3.Length; k++) { if ((Object)(object)componentsInChildren3[k] != (Object)null) { Object.Destroy((Object)(object)componentsInChildren3[k]); } } LODGroup[] componentsInChildren4 = visualRoot.GetComponentsInChildren<LODGroup>(true); foreach (LODGroup val2 in componentsInChildren4) { if (!((Object)(object)val2 == (Object)null)) { val2.enabled = false; Object.Destroy((Object)(object)val2); } } MonoBehaviour[] componentsInChildren5 = visualRoot.GetComponentsInChildren<MonoBehaviour>(true); foreach (MonoBehaviour val3 in componentsInChildren5) { if (!((Object)(object)val3 == (Object)null) && !IsWhitelistedBehaviour(val3)) { ((Behaviour)val3).enabled = false; Object.Destroy((Object)(object)val3); } } Transform[] componentsInChildren6 = visualRoot.GetComponentsInChildren<Transform>(true); foreach (Transform val4 in componentsInChildren6) { if (!((Object)(object)val4 == (Object)null)) { ((Component)val4).gameObject.tag = "Untagged"; ((Component)val4).gameObject.layer = targetLayer; } } } private static bool ContainsKeyword(string value, string[] keywords) { if (string.IsNullOrEmpty(value)) { return false; } string text = value.ToLowerInvariant(); for (int i = 0; i < keywords.Length; i++) { if (text.Contains(keywords[i])) { return true; } } return false; } private static void RemoveUnwantedFootAttachments(Transform mikuRoot) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) Renderer[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Renderer>(true); int num = 0; foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && ContainsKeyword(((Object)((Component)val).gameObject).name, UnwantedFootKeywords)) { Bounds bounds = val.bounds; if (!(mikuRoot.InverseTransformPoint(((Bounds)(ref bounds)).center).y > 0.2f)) { Object.Destroy((Object)(object)((Component)val).gameObject); num++; } } } if (num > 0) { Plugin.VerboseLog("[ItemPatch] Removed unwanted foot attachments: " + num); } } private static void SyncVisibilityState(Item item) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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_0088: Unknown result type (might be due to invalid IL or missing references) Transform val = FindMikuRoot(item); if ((Object)(object)val == (Object)null) { return; } int num = DetermineTargetLayer(item); ((Component)val).gameObject.layer = num; ResolvePoseByState(item, val, out var localPosition, out var localRotation, out var localScale); if (val.localPosition != localPosition) { val.localPosition = localPosition; } if (val.localRotation != localRotation) { val.localRotation = localRotation; } if (val.localScale != localScale) { val.localScale = localScale; } MikuDeformGuard component = ((Component)val).GetComponent<MikuDeformGuard>(); if ((Object)(object)component != (Object)null) { component.SetRootTarget(localPosition, localRotation, localScale); } bool flag = ShouldShowReplacement(item); if (((Component)val).gameObject.activeSelf != flag) { ((Component)val).gameObject.SetActive(flag); } if (!flag) { EnableOriginalRenderers(item); EnableOriginalColliders(item); RestoreOriginalItemRendererRefs(item); return; } EnsureModelColliders(item, val); if (HasVisibleReplacementRenderers(val)) { DisableOriginalRenderers(item); } else { EnableOriginalRenderers(item); } Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null && !IsSuppressedReplacementRenderer(val2)) { ConfigureMikuRenderer(val2, num); } } EnsureItemRendererRefs(item, val); } private static Transform EnsureMikuModel(Item item, bool createIfMissing) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: 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_007c: 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) //IL_008e: 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) //IL_00ad: 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_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown