Decompiled source of MikuFufu v2.0.5
plugins/MikuFufu2.dll
Decompiled a month 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.Drawing; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; 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("MikuFufu2")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("2.0.0.0")] [assembly: AssemblyInformationalVersion("2.0.0")] [assembly: AssemblyProduct("MikuFufu2")] [assembly: AssemblyTitle("MikuFufu2")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.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 MikuBongFix { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.github.Thanks.MikuFufu2", "MikuFufu2", "2.0.0")] public class Plugin : BaseUnityPlugin { private static readonly string[] LegacyPluginIds = new string[2] { "com.github.Thanks.MikuBongFix", "com.github.FelineEntity.MikuBongFix" }; private const string BundleFileName = "mikupeak"; private const string RuntimeReplacementFolderName = "FUFU"; private const string ExternalIconFileName = "Fufu2.png"; private const string PrefabAssetPath = "assets/mikufumo/mikufumo.prefab"; private const string MaterialAssetPath = "assets/mikufumo/m_mikufumo.mat"; private const string IconTextureAssetPath = "assets/mikufumo/miku_icon.png"; private const string MainTextureAssetPath = "assets/mikufumo/miku.png"; private const string ConfigSection = "Main"; private const float WorldMinScaleMultiplier = 0.4f; 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 const string DefaultExpressionName = "None"; private const float DefaultExpressionWeight = 1f; private static readonly Vector3 DefaultReplacementBaseScale = new Vector3(1.5f, 1.5f, 1.5f); private static readonly string[] PreferredTextureProps = new string[2] { "_BaseMap", "_MainTex" }; private static readonly string[] PrefabNameHints = new string[3] { "mikufumo", "miku", "fumo" }; private static readonly string[] MaterialNameHints = new string[3] { "m_mikufumo", "mikufumo", "miku" }; private static readonly string[] IconTextureNameHints = new string[3] { "miku_icon", "icon", "miku" }; private static readonly string[] MainTextureNameHints = new string[3] { "miku", "mikufumo", "albedo" }; 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 RuntimeReplacementModel _runtimeReplacementModel; public const string Name = "MikuFufu2"; public const string Id = "com.github.Thanks.MikuFufu2"; public const string Version = "2.0.5"; internal static Harmony Harmony = new Harmony("com.github.Thanks.MikuFufu2"); 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 RuntimeReplacementModel RuntimeReplacementModel { get { return _runtimeReplacementModel; } private set { _runtimeReplacementModel = value; } } internal static bool ModEnabled { get { if (_modEnabled != null) { return _modEnabled.Value; } return true; } } internal static bool KeepOriginalRendererRefs => RuntimeReplacementModel == null; internal static bool EnableVisibilityGuard => true; internal static float WorldScaleMultiplier { get { if (_worldScaleMultiplier != null) { return Mathf.Clamp(_worldScaleMultiplier.Value, 0.4f, 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 Vector3 ReplacementBaseScale { get { //IL_0026: 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_003a: 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (RuntimeReplacementModel == null) { return DefaultReplacementBaseScale * 0.78f * 1.5f; } return RuntimeReplacementModel.RecommendedBaseScale * 0.78f * 1.5f; } } internal static string ExpressionName => "None"; internal static float ExpressionWeight => 1f; internal static string ReplacementDisplayName { get { if (RuntimeReplacementModel == null) { return "Miku"; } return RuntimeReplacementModel.DisplayName; } } 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; if (string.IsNullOrEmpty(configFilePath) || File.Exists(configFilePath) || LegacyPluginIds == null) { return; } for (int i = 0; i < LegacyPluginIds.Length; i++) { string text = LegacyPluginIds[i]; if (!string.IsNullOrEmpty(text)) { string text2 = Path.Combine(Paths.ConfigPath, text + ".cfg"); if (File.Exists(text2)) { File.Copy(text2, configFilePath, overwrite: false); ((BaseUnityPlugin)this).Config.Reload(); Log.LogInfo((object)("Migrated legacy config to: " + configFilePath)); break; } } } } 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.4f, 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() { Texture2D val = LoadExternalIconTexture(); RuntimeReplacementModel = RuntimePmxLoader.Load(Path.Combine(directory, "FUFU"), Log); if (RuntimeReplacementModel != null) { MochiPrefab = null; Bundle = null; MochiTexture = val ?? RuntimeReplacementModel.IconTexture ?? RuntimeReplacementModel.PrimaryTexture; MikuMainTexture = RuntimeReplacementModel.PrimaryTexture; MochiMaterial = RuntimeReplacementModel.PrimaryMaterial; RuntimeMikuMaterial = RuntimeReplacementModel.PrimaryMaterial ?? CreateRuntimeMikuMaterial(MikuMainTexture); Log.LogInfo((object)("Loaded runtime FUFU replacement from folder: " + Path.Combine(directory, "FUFU"))); return; } string text = Path.Combine(directory, "mikupeak"); Bundle = AssetBundle.LoadFromFile(text); if ((Object)(object)Bundle == (Object)null) { Log.LogError((object)("Failed to load runtime FUFU assets and failed to load AssetBundle: " + text)); return; } MochiPrefab = LoadBundleAssetWithFallback<GameObject>("assets/mikufumo/mikufumo.prefab", PrefabNameHints); MochiMaterial = LoadBundleAssetWithFallback<Material>("assets/mikufumo/m_mikufumo.mat", MaterialNameHints); MochiTexture = val ?? LoadBundleAssetWithFallback<Texture2D>("assets/mikufumo/miku_icon.png", IconTextureNameHints); Texture2D val2 = LoadBundleAssetWithFallback<Texture2D>("assets/mikufumo/miku.png", MainTextureNameHints); MikuMainTexture = CreateReadableTexture(val2) ?? val2; if ((Object)(object)MochiPrefab == (Object)null) { Log.LogError((object)"Failed to load replacement prefab from asset bundle."); return; } ConfigureMochiMaterial(MikuMainTexture); RuntimeMikuMaterial = CreateRuntimeMikuMaterial(MikuMainTexture); if ((Object)(object)RuntimeMikuMaterial == (Object)null) { Log.LogWarning((object)"Runtime fallback material was not created. The bundled material will be used when available."); } 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."); } } private Texture2D LoadExternalIconTexture() { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_00aa: 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_00c3: 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_00d1: 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_00e2: Expected O, but got Unknown //IL_0083: 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) string text = Path.Combine(directory, "Fufu2.png"); if (!File.Exists(text)) { return null; } try { using FileStream fileStream = File.OpenRead(text); Bitmap val = new Bitmap((Stream)fileStream); try { int width = ((Image)val).Width; int height = ((Image)val).Height; Color32[] array = (Color32[])(object)new Color32[width * height]; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { Color pixel = val.GetPixel(j, height - 1 - i); array[i * width + j] = new Color32(pixel.R, pixel.G, pixel.B, pixel.A); } } Texture2D val2 = new Texture2D(width, height, (TextureFormat)4, false, false) { name = Path.GetFileNameWithoutExtension(text) }; val2.SetPixels32(array); ((Texture)val2).filterMode = (FilterMode)1; ((Texture)val2).wrapMode = (TextureWrapMode)1; ((Texture)val2).anisoLevel = 1; val2.Apply(false, false); return val2; } finally { ((IDisposable)val)?.Dispose(); } } catch (Exception ex) { Log.LogWarning((object)("Failed to load external icon texture '" + text + "': " + ex.Message)); return null; } } internal static GameObject CreateReplacementVisualInstance(string name) { if (RuntimeReplacementModel != null) { return RuntimeReplacementModel.Instantiate(name); } if ((Object)(object)MochiPrefab == (Object)null) { return null; } return Object.Instantiate<GameObject>(MochiPrefab); } 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(Texture2D mikuMainTexture) { if ((Object)(object)MochiMaterial == (Object)null) { return; } if ((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; } } if ((Object)(object)mikuMainTexture != (Object)null) { ApplyTextureSet(MochiMaterial, mikuMainTexture); } ApplyMikuColorStyle(MochiMaterial); VerboseLog("Configured bundled material: " + ((Object)MochiMaterial).name); } private static bool TryAssignTextureIfMissing(Material material, string propertyName, Texture2D texture) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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 { if ((Object)(object)material.GetTexture(propertyName) != (Object)null) { return false; } material.SetTexture(propertyName, (Texture)(object)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 TryAssignTextureIfMissing(Material material, string[] propertyNames, Texture2D texture) { if (!((Object)(object)material == (Object)null) && !((Object)(object)texture == (Object)null) && propertyNames != null) { for (int i = 0; i < propertyNames.Length; i++) { TryAssignTextureIfMissing(material, propertyNames[i], texture); } } } private static void ApplyTextureSet(Material material, Texture2D albedo) { if (!((Object)(object)material == (Object)null)) { TryAssignTextureIfMissing(material, PreferredTextureProps, 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.3f); } if (material.HasProperty("_Glossiness")) { material.SetFloat("_Glossiness", 0.3f); } 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 Material CreateRuntimeMikuMaterial(Texture2D texture) { //IL_0042: 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_0052: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("W/Peak_Standard"); 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 = "Miku_RuntimeMaterial", renderQueue = 2000, color = Color.white }; if ((Object)(object)texture != (Object)null) { TryAssignTextureIfMissing(val2, "_BaseMap", texture); TryAssignTextureIfMissing(val2, "_MainTex", 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 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)) { EnsureRendererVisible(val, num); } } } 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; } private static void NormalizeRendererMaterialColor(Renderer renderer) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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) Material[] sharedMaterials = renderer.sharedMaterials; foreach (Material val in sharedMaterials) { if (!((Object)(object)val == (Object)null)) { Color white = Color.white; if (val.HasProperty("_Tint")) { val.SetColor("_Tint", white); } if (val.HasProperty("_BaseColor")) { val.SetColor("_BaseColor", white); } if (val.HasProperty("_Color")) { val.SetColor("_Color", white); } } } } } [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 = "MikuFumo_Visual"; private static readonly Vector3 WorldMikuLocalPosition = new Vector3(0f, 0.2f, 0.1f); private static readonly Quaternion WorldMikuLocalRotation = Quaternion.identity; private static readonly Vector3 HeldMikuLocalPosition = new Vector3(0f, -0.1f, 0.45f); private static readonly Quaternion HeldMikuLocalRotation = Quaternion.Euler(10f, 0f, 0f); private static readonly string[] UnwantedFootKeywords = new string[3] { "hand", "glove", "mitten" }; private static bool IsBingBong(Item item) { if ((Object)(object)item != (Object)null) { return ((Object)item).name.IndexOf("BingBong", StringComparison.OrdinalIgnoreCase) >= 0; } return false; } internal static bool IsMikuTransform(Transform transform) { if ((Object)(object)transform != (Object)null) { return (Object)(object)((Component)transform).GetComponentInParent<MikuMarker>() != (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 Vector3 ResolveScaleByState(Item item) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) float num = (IsInBackpack(item) ? Plugin.BackpackScaleMultiplier : Plugin.WorldScaleMultiplier); return Plugin.ReplacementBaseScale * num; } private static Vector3 ApplyPlayerFacingScale(Vector3 scale) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000c: 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_0023: Unknown result type (might be due to invalid IL or missing references) return new Vector3(0f - Mathf.Abs(scale.x), Mathf.Abs(scale.y), 0f - Mathf.Abs(scale.z)); } private static void ResolvePoseByState(Item item, out Vector3 localPosition, out Quaternion localRotation, out Vector3 localScale) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: 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_0015: Unknown result type (might be due to invalid IL or missing references) //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_0026: 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_002c: 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_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_006f: 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_0075: 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_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ResolveScaleByState(item); if (IsHeld(item)) { localPosition = HeldMikuLocalPosition; localRotation = HeldMikuLocalRotation; localScale = ApplyPlayerFacingScale(val); } else if (IsInBackpack(item)) { localPosition = WorldMikuLocalPosition; localRotation = WorldMikuLocalRotation; localScale = val; } else { localPosition = WorldMikuLocalPosition; localRotation = WorldMikuLocalRotation; localScale = ApplyPlayerFacingScale(val); } } 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("MikuFumo_Visual"); } private static MikuExpressionController FindExpressionController(Transform mikuRoot) { if (!((Object)(object)mikuRoot != (Object)null)) { return null; } return ((Component)mikuRoot).GetComponentInChildren<MikuExpressionController>(true); } private static Texture GetMikuTexture() { if ((Object)(object)Plugin.MikuMainTexture != (Object)null) { return (Texture)(object)Plugin.MikuMainTexture; } Texture val = TryGetTexture(Plugin.MochiMaterial); if ((Object)(object)val != (Object)null) { return val; } return TryGetTexture(Plugin.RuntimeMikuMaterial); } 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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)material == (Object)null) && !((Object)(object)mikuTexture == (Object)null)) { 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_000b: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)material == (Object)null)) { Color val = ResolveMaterialTint(material); val.a = 1f; if (material.HasProperty("_Tint")) { material.SetColor("_Tint", val); } if (material.HasProperty("_BaseColor")) { material.SetColor("_BaseColor", val); } if (material.HasProperty("_Color")) { material.SetColor("_Color", val); } if (material.HasProperty("_Smoothness")) { material.SetFloat("_Smoothness", 0.3f); } if (material.HasProperty("_Glossiness")) { material.SetFloat("_Glossiness", 0.3f); } 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 Material CreateFallbackMaterial() { //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_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown Shader val = Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("Standard") ?? Shader.Find("W/Peak_Standard"); if ((Object)(object)val == (Object)null) { return null; } return new Material(val) { color = Color.white }; } private static Color ResolveMaterialTint(Material material) { //IL_0009: 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_003b: 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_0054: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)material == (Object)null) { return MikuMaterialTint; } if (material.HasProperty("_Tint")) { return material.GetColor("_Tint"); } if (material.HasProperty("_BaseColor")) { return material.GetColor("_BaseColor"); } if (material.HasProperty("_Color")) { return material.GetColor("_Color"); } return MikuMaterialTint; } private static void OptimizeMaterialTextureSampling(Material material) { OptimizeTextureSampling(TryGetTexture(material)); } private static Material CreateRendererMaterialInstance(Material template = null) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown template = template ?? Plugin.RuntimeMikuMaterial ?? Plugin.MochiMaterial; if ((Object)(object)template == (Object)null) { Material val = CreateFallbackMaterial(); if ((Object)(object)val == (Object)null) { return null; } template = val; } Material val2 = new Material(template); Texture val3 = TryGetTexture(val2); Texture mikuTexture = GetMikuTexture(); if ((Object)(object)val3 != (Object)null) { OptimizeTextureSampling(val3); } else if ((Object)(object)mikuTexture != (Object)null) { OptimizeTextureSampling(mikuTexture); ApplyMikuTextureSafe(val2, mikuTexture); } DisableOptionalSurfaceTextures(val2); 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("_SrcBlend")) { val2.SetFloat("_SrcBlend", 1f); } if (val2.HasProperty("_DstBlend")) { val2.SetFloat("_DstBlend", 0f); } if (val2.HasProperty("_Cull")) { val2.SetFloat("_Cull", 0f); } if (val2.HasProperty("_AlphaClip")) { val2.SetFloat("_AlphaClip", 0f); } if (val2.HasProperty("_Cutoff")) { val2.SetFloat("_Cutoff", 0f); } if (val2.HasProperty("_LOD")) { val2.SetFloat("_LOD", 600f); } val2.renderQueue = 2000; val2.SetOverrideTag("RenderType", "Opaque"); val2.DisableKeyword("_SURFACE_TYPE_TRANSPARENT"); val2.EnableKeyword("_SURFACE_TYPE_OPAQUE"); val2.DisableKeyword("_ALPHATEST_ON"); val2.DisableKeyword("_ALPHABLEND_ON"); val2.DisableKeyword("_ALPHAPREMULTIPLY_ON"); val2.DisableKeyword("LOD_FADE_CROSSFADE"); ApplyRealisticMaterialTuning(val2); return val2; } private static Material[] BuildMaterialArray(Material[] sourceMaterials, int subMeshCount) { int num = Mathf.Max(1, subMeshCount); Material[] array = (Material[])(object)new Material[num]; for (int i = 0; i < num; i++) { Material template = null; if (sourceMaterials != null && sourceMaterials.Length != 0) { template = sourceMaterials[Mathf.Min(i, sourceMaterials.Length - 1)]; } Material val = CreateRendererMaterialInstance(template); if ((Object)(object)val == (Object)null) { val = CreateFallbackMaterial(); } if ((Object)(object)val != (Object)null) { Texture val2 = TryGetTexture(val); if ((Object)(object)val2 == (Object)null) { Texture mikuTexture = GetMikuTexture(); if ((Object)(object)mikuTexture != (Object)null) { OptimizeTextureSampling(mikuTexture); ApplyMikuTextureSafe(val, mikuTexture); } } else { OptimizeTextureSampling(val2); } DisableOptionalSurfaceTextures(val); ApplyRealisticMaterialTuning(val); } array[i] = val; } return array; } private static void ApplyMaterialToMeshRenderer(MeshRenderer renderer) { int subMeshCount = 1; MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>(); if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) { subMeshCount = Mathf.Max(1, component.sharedMesh.subMeshCount); } ((Renderer)renderer).sharedMaterials = BuildMaterialArray(((Renderer)renderer).sharedMaterials, subMeshCount); } private static void ApplyMaterialToSkinnedRenderer(SkinnedMeshRenderer renderer) { //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_005b: Unknown result type (might be due to invalid IL or missing references) int subMeshCount = 1; if ((Object)(object)renderer.sharedMesh != (Object)null) { subMeshCount = Mathf.Max(1, renderer.sharedMesh.subMeshCount); } ((Renderer)renderer).sharedMaterials = BuildMaterialArray(((Renderer)renderer).sharedMaterials, subMeshCount); if ((Object)(object)renderer.sharedMesh != (Object)null) { Bounds bounds = renderer.sharedMesh.bounds; ((Bounds)(ref bounds)).Expand(0.5f); ((Renderer)renderer).localBounds = bounds; } } 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) { 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) { Renderer[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !IsMikuTransform(((Component)val).transform)) { val.enabled = false; } } } private static void EnableOriginalRenderers(Item item) { Renderer[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Renderer>(true); foreach (Renderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && !IsMikuTransform(((Component)val).transform)) { val.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 AddConvexMeshColliderForMeshRenderer(MeshRenderer renderer, Collider templateCollider) { if ((Object)(object)renderer == (Object)null) { return null; } MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>(); if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null) { return null; } MeshCollider val = ((Component)renderer).gameObject.GetComponent<MeshCollider>(); if ((Object)(object)val == (Object)null) { val = ((Component)renderer).gameObject.AddComponent<MeshCollider>(); } val.sharedMesh = null; val.convex = true; val.sharedMesh = component.sharedMesh; CopyColliderSettings(templateCollider, (Collider)(object)val); return (Collider)(object)val; } 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>(); bool flag = Plugin.RuntimeReplacementModel != null; MeshRenderer[] componentsInChildren2 = ((Component)mikuRoot).GetComponentsInChildren<MeshRenderer>(true); for (int j = 0; j < componentsInChildren2.Length; j++) { Collider val2 = (flag ? AddConvexMeshColliderForMeshRenderer(componentsInChildren2[j], templateCollider) : AddBoxColliderForMeshRenderer(componentsInChildren2[j], templateCollider)); if ((Object)(object)val2 != (Object)null) { list.Add(val2); } } SkinnedMeshRenderer[] componentsInChildren3 = ((Component)mikuRoot).GetComponentsInChildren<SkinnedMeshRenderer>(true); for (int k = 0; k < componentsInChildren3.Length; k++) { Collider val3 = AddBoxColliderForSkinnedRenderer(componentsInChildren3[k], templateCollider); if ((Object)(object)val3 != (Object)null) { list.Add(val3); } } if (list.Count == 0) { Collider val4 = AddFallbackRootCollider(mikuRoot, templateCollider); if ((Object)(object)val4 != (Object)null) { list.Add(val4); } } 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) { SetColliderArrayEnabled(componentsInChildren, enabled: true); item.colliders = componentsInChildren; DisableOriginalColliders(item); } } } private static void SetColliderArrayEnabled(Collider[] colliders, bool enabled) { if (colliders == null) { return; } foreach (Collider val in colliders) { if (!((Object)(object)val == (Object)null)) { val.enabled = enabled; } } } private static void SyncCollidersByState(Item item, Transform mikuRoot) { if (!((Object)(object)item == (Object)null) && !((Object)(object)mikuRoot == (Object)null)) { Collider[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Collider>(true); if (IsHeld(item)) { SetColliderArrayEnabled(componentsInChildren, enabled: false); EnableOriginalColliders(item); } else { EnsureModelColliders(item, mikuRoot); } } } 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")) { return true; } } return false; } private static Material CreateMainTexCompatMaterial(Texture texture) { //IL_004f: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown Shader val = Shader.Find("Standard") ?? Shader.Find("Unlit/Texture") ?? Shader.Find("Universal Render Pipeline/Unlit") ?? Shader.Find("Universal Render Pipeline/Lit") ?? Shader.Find("W/Peak_Standard"); if ((Object)(object)val == (Object)null) { return null; } Material val2 = new Material(val) { name = "Miku_MainTexCompat", color = Color.white, renderQueue = 2000 }; if ((Object)(object)texture != (Object)null) { ApplyMikuTextureSafe(val2, texture); } ApplyRealisticMaterialTuning(val2); return val2; } private static void EnsureRendererMainTexCompatibility(Renderer renderer) { if ((Object)(object)renderer == (Object)null || Plugin.RuntimeReplacementModel != null) { return; } Material[] sharedMaterials = renderer.sharedMaterials; if (sharedMaterials == null || sharedMaterials.Length == 0) { Material val = CreateMainTexCompatMaterial(GetMikuTexture()) ?? CreateRendererMaterialInstance(); if ((Object)(object)val != (Object)null) { renderer.sharedMaterial = val; } return; } for (int i = 0; i < sharedMaterials.Length; i++) { if ((Object)(object)sharedMaterials[i] != (Object)null && sharedMaterials[i].HasProperty("_MainTex")) { return; } } Material val2 = CreateMainTexCompatMaterial(GetMikuTexture()); if (!((Object)(object)val2 == (Object)null)) { sharedMaterials[0] = val2; renderer.sharedMaterials = sharedMaterials; } } 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)) { 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)) { if ((Object)(object)val == (Object)null) { val = val2; } if (RendererHasMainTexSlot(val2)) { val = val2; break; } } } if (!((Object)(object)val == (Object)null)) { EnsureRendererMainTexCompatibility(val); 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 renderer in componentsInChildren) { ConfigureMikuRenderer((Renderer)(object)renderer, num); ApplyMaterialToMeshRenderer(renderer); } foreach (SkinnedMeshRenderer obj in componentsInChildren2) { obj.updateWhenOffscreen = true; ConfigureMikuRenderer((Renderer)(object)obj, num); ApplyMaterialToSkinnedRenderer(obj); } EnsureItemRendererRefs(item, mikuRoot); } private static bool IsWhitelistedBehaviour(MonoBehaviour behaviour) { if (!(behaviour is MikuMarker) && !(behaviour is MikuRendererGuard) && !(behaviour is MikuDeformGuard)) { return behaviour is MikuExpressionController; } 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_0031: 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_0046: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: 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) Transform val = FindMikuRoot(item); if ((Object)(object)val == (Object)null) { return; } int num = DetermineTargetLayer(item); ((Component)val).gameObject.layer = num; ResolvePoseByState(item, 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; } SyncCollidersByState(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) { ConfigureMikuRenderer(val2, num); } } EnsureItemRendererRefs(item, val); } private static Transform EnsureMikuModel(Item item, bool createIfMissing) { //IL_0080: 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_0099: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_010e: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) Transform val = FindMikuRoot(item); if ((Object)(object)val != (Object)null) { return val; } if (!createIfMissing) { return null; } GameObject val2 = Plugin.CreateReplacementVisualInstance("MikuFumo_Visual"); if ((Object)(object)val2 == (Object)null) { Plugin.Log.LogWarning((object)"[ItemPatch] Replacement visual is unavailable, cannot create model yet."); return null; } val2.transform.SetParent(((Component)item).transform, false); ((Object)val2).name = "MikuFumo_Visual"; val2.SetActive(true); int targetLayer = (val2.layer = DetermineTargetLayer(item)); ResolvePoseByState(item, out var localPosition, out var localRotation, out var localScale); val2.transform.localPosition = localPosition; val2.transform.localRotation = localRotation; val2.transform.localScale = localScale; if ((Object)(object)val2.GetComponent<MikuMarker>() == (Object)null) { val2.AddComponent<MikuMarker>(); } RemoveUnwantedFootAttachments(val2.transform); SanitizeVisualObject(val2, targetLayer); MikuRendererGuard mikuRendererGuard = val2.GetComponent<MikuRendererGuard>(); if ((Object)(object)mikuRendererGuard == (Object)null) { mikuRendererGuard = val2.AddComponent<MikuRendererGuard>(); } mikuRendererGuard.Bind(item); MikuDeformGuard mikuDeformGuard = val2.GetComponent<MikuDeformGuard>(); if ((Object)(object)mikuDeformGuard == (Object)null) { mikuDeformGuard = val2.AddComponent<MikuDeformGuard>(); } mikuDeformGuard.Bind(item); mikuDeformGuard.Initialize(localPosition, localRotation, localScale); MikuExpressionController mikuExpressionController = FindExpressionController(val2.transform); if ((Object)(object)mikuExpressionController != (Object)null) { mikuExpressionController.Bind(item); } ApplyInitialMikuRendererSetup(item, val2.transform); RebuildModelColliders(item, val2.transform); SyncVisibilityState(item); Plugin.VerboseLog("[ItemPatch] Created Miku replacement model under item: " + ((Object)item).name); return val2.transform; } private static void EnsureReplacementAndVisibility(Item item, bool createIfMissing) { if (!IsBingBong(item)) { return; } Transform val = FindMikuRoot(item); if (!Plugin.ModEnabled) { if ((Object)(object)val != (Object)null) { RemoveReplacement(item, val); } return; } if ((Object)(object)val == (Object)null) { val = EnsureMikuModel(item, createIfMissing); } if (!((Object)(object)val == (Object)null)) { MikuRendererGuard component = ((Component)val).GetComponent<MikuRendererGuard>(); if ((Object)(object)component != (Object)null) { component.Bind(item); } MikuDeformGuard component2 = ((Component)val).GetComponent<MikuDeformGuard>(); if ((Object)(object)component2 != (Object)null) { component2.Bind(item); } MikuExpressionController mikuExpressionController = FindExpressionController(val); if ((Object)(object)mikuExpressionController != (Object)null) { mikuExpressionController.Bind(item); } SyncVisibilityState(item); } } [HarmonyPatch("Start")] [HarmonyPostfix] public static void Item_Start(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: true); if (IsBingBong(__instance)) { Plugin.VerboseLog("[ItemPatch] Model replacement complete for: " + ((Object)__instance).name); } } [HarmonyPatch("OnEnable")] [HarmonyPostfix] public static void Item_OnEnable(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: true); } [HarmonyPatch("SetState")] [HarmonyPrefix] public static void Item_SetState_Prefix(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: true); } [HarmonyPatch("SetState")] [HarmonyPostfix] public static void Item_SetState_Postfix(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: true); } [HarmonyPatch("Update")] [HarmonyPostfix] public static void Item_Update_Postfix(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: false); } [HarmonyPatch("RequestPickup")] [HarmonyPrefix] public static void Item_RequestPickup_Prefix(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: true); } [HarmonyPatch("RequestPickup")] [HarmonyPostfix] public static void Item_RequestPickup_Postfix(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: true); } [HarmonyPatch("HideRenderers")] [HarmonyPrefix] public static bool Item_HideRenderers_Prefix(Item __instance) { //IL_0031: 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_0072: 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_0074: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.ModEnabled || !IsBingBong(__instance)) { return true; } Transform val = EnsureMikuModel(__instance, createIfMissing: false); if ((Object)(object)val == (Object)null) { return true; } ResolvePoseByState(__instance, out var localPosition, out var localRotation, out var localScale); val.localPosition = localPosition; val.localRotation = localRotation; val.localScale = localScale; if (!((Component)val).gameObject.activeSelf) { ((Component)val).gameObject.SetActive(true); } MikuDeformGuard component = ((Component)val).GetComponent<MikuDeformGuard>(); if ((Object)(object)component != (Object)null) { component.SetRootTarget(localPosition, localRotation, localScale); } SyncCollidersByState(__instance, val); int targetLayer = DetermineTargetLayer(__instance); Renderer[] componentsInChildren = ((Component)val).GetComponentsInChildren<Renderer>(true); foreach (Renderer val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null) { ConfigureMikuRenderer(val2, targetLayer); } } DisableOriginalRenderers(__instance); EnsureItemRendererRefs(__instance, val); return false; } [HarmonyPatch("PutInBackpackRPC")] [HarmonyPostfix] public static void Item_PutInBackpackRPC_Postfix(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: false); } [HarmonyPatch("ClearDataFromBackpack")] [HarmonyPostfix] public static void Item_ClearDataFromBackpack_Postfix(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: false); } [HarmonyPatch(typeof(ItemUIData), "GetIcon")] [HarmonyPostfix] public static void Item_GetIcon(ItemUIData __instance, ref Texture2D __result) { if (Plugin.ModEnabled && __instance.itemName == "Bing Bong" && (Object)(object)Plugin.MochiTexture != (Object)null) { __result = Plugin.MochiTexture; } } [HarmonyPatch("GetName")] [HarmonyPostfix] public static void Item_GetName_Postfix(Item __instance, ref string __result) { if (Plugin.ModEnabled && IsBingBong(__instance)) { __result = Plugin.ReplacementDisplayName; } } [HarmonyPatch("GetItemName")] [HarmonyPostfix] public static void Item_GetItemName_Postfix(Item __instance, ref string __result) { if (Plugin.ModEnabled && IsBingBong(__instance)) { __result = Plugin.ReplacementDisplayName; } } } [HarmonyPatch] public static class MikuTintCompatibilityPatch { private delegate void ItemCookingIntMethod(ItemCooking instance, int value); private static readonly FieldRef<BackpackOnBackVisuals, MeshRenderer[]> BackpackRenderersRef = AccessTools.FieldRefAccess<BackpackOnBackVisuals, MeshRenderer[]>("renderers"); private static readonly FieldRef<BackpackOnBackVisuals, Color[]> BackpackDefaultTintsRef = AccessTools.FieldRefAccess<BackpackOnBackVisuals, Color[]>("defaultTints"); private static readonly FieldRef<ItemCooking, Renderer[]> ItemCookingRenderersRef = AccessTools.FieldRefAccess<ItemCooking, Renderer[]>("renderers"); private static readonly FieldRef<ItemCooking, Color[]> ItemCookingDefaultTintsRef = AccessTools.FieldRefAccess<ItemCooking, Color[]>("defaultTints"); private static readonly FieldRef<ItemCooking, bool> ItemCookingSetupRef = AccessTools.FieldRefAccess<ItemCooking, bool>("setup"); private static readonly FieldRef<ItemCooking, int> ItemCookingPreCookedRef = AccessTools.FieldRefAccess<ItemCooking, int>("preCooked"); private static readonly FieldRef<ItemCooking, bool> ItemCookingIgnoreDefaultCookBehaviorRef = AccessTools.FieldRefAccess<ItemCooking, bool>("ignoreDefaultCookBehavior"); private static readonly FieldRef<ItemCooking, int> ItemCookingTimesCookedLocalRef = AccessTools.FieldRefAccess<ItemCooking, int>("<timesCookedLocal>k__BackingField"); private static readonly ItemCookingIntMethod RunAdditionalCookingBehaviorsDelegate = AccessTools.MethodDelegate<ItemCookingIntMethod>(AccessTools.Method(typeof(ItemCooking), "RunAdditionalCookingBehaviors", (Type[])null, (Type[])null), (object)null, true); private static readonly ItemCookingIntMethod ChangeStatsCookedDelegate = AccessTools.MethodDelegate<ItemCookingIntMethod>(AccessTools.Method(typeof(ItemCooking), "ChangeStatsCooked", (Type[])null, (Type[])null), (object)null, true); private static readonly ItemCookingIntMethod CookVisuallyDelegate = AccessTools.MethodDelegate<ItemCookingIntMethod>(AccessTools.Method(typeof(ItemCooking), "CookVisually", (Type[])null, (Type[])null), (object)null, true); private static Color GetSafeTint(Material material) { //IL_0009: 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_003b: 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_0054: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)material == (Object)null) { return Color.white; } if (material.HasProperty("_Tint")) { return material.GetColor("_Tint"); } if (material.HasProperty("_BaseColor")) { return material.GetColor("_BaseColor"); } if (material.HasProperty("_Color")) { return material.GetColor("_Color"); } return Color.white; } private static void TryApplyTint(Material material, Color color) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)material != (Object)null && material.HasProperty("_Tint"))