Decompiled source of BoxMiku v1.0.1
plugins/BoxMiku.dll
Decompiled a week 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("BoxMiku")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("BoxMiku")] [assembly: AssemblyTitle("BoxMiku")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] public sealed class IgnoresAccessChecksToAttribute : Attribute { private readonly string _assemblyName; public string AssemblyName => _assemblyName; public IgnoresAccessChecksToAttribute(string assemblyName) { _assemblyName = assemblyName; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] public sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte value) { NullableFlags = new byte[1] { value }; } public NullableAttribute(byte[] value) { NullableFlags = value; } } [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] public sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte value) { Flag = value; } } [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property, AllowMultiple = false, Inherited = false)] public sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int version) { Version = version; } } } namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace BepInEx { [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public sealed class BepInAutoPluginAttribute : Attribute { private string _guid; private string _name; private string _version; public string GUID { get { return _guid; } set { _guid = value; } } public string Name { get { return _name; } set { _name = value; } } public string Version { get { return _version; } set { _version = value; } } public BepInAutoPluginAttribute(string guid = null, string name = null, string version = null) { _guid = guid; _name = name; _version = version; } } } namespace BepInEx.Preloader.Core.Patching { [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)] public sealed class PatcherAutoPluginAttribute : Attribute { private string _guid; private string _name; private string _version; public string GUID { get { return _guid; } set { _guid = value; } } public string Name { get { return _name; } set { _name = value; } } public string Version { get { return _version; } set { _version = value; } } public PatcherAutoPluginAttribute(string guid = null, string name = null, string version = null) { _guid = guid; _name = name; _version = version; } } } namespace BoxMiku { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("com.github.Thanks.BoxMiku", "BoxMiku", "1.0.0")] public class Plugin : BaseUnityPlugin { private const string LegacyPluginId = "com.github.Thanks.BoxMiku"; private const string BundleFileName = "boxmiku"; private const string RuntimeReplacementFolderName = "箱MIKU"; private const string InventoryIconFileName = "BoxMikuUI.png"; private const string PackageIconFileName = "icon.png"; private const string ExternalIconFileName = "ミク!.png"; private const string PrefabAssetPath = "assets/boxmiku/boxmiku.prefab"; private const string MaterialAssetPath = "assets/boxmiku/m_boxmiku.mat"; private const string IconTextureAssetPath = "assets/boxmiku/boxmiku_icon.png"; private const string MainTextureAssetPath = "assets/boxmiku/boxmiku.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 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] { "boxmiku", "miku", "箱" }; private static readonly string[] MaterialNameHints = new string[3] { "m_boxmiku", "boxmiku", "miku" }; private static readonly string[] IconTextureNameHints = new string[3] { "boxmiku_icon", "icon", "見本" }; private static readonly string[] MainTextureNameHints = new string[3] { "boxmiku", "miku", "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 = "BoxMiku"; public const string Id = "com.github.Thanks.BoxMiku"; public const string Version = "1.0.0"; internal static Harmony Harmony = new Harmony("com.github.Thanks.BoxMiku"); 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 => true; 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_0012: 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) if (RuntimeReplacementModel == null) { return DefaultReplacementBaseScale; } return RuntimeReplacementModel.RecommendedBaseScale; } } 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; string text = Path.Combine(Paths.ConfigPath, "com.github.Thanks.BoxMiku.cfg"); if (!string.IsNullOrEmpty(configFilePath) && !string.IsNullOrEmpty(text) && !File.Exists(configFilePath) && File.Exists(text)) { File.Copy(text, configFilePath, overwrite: false); ((BaseUnityPlugin)this).Config.Reload(); Log.LogInfo((object)("Migrated legacy config to: " + configFilePath)); } } catch (Exception ex) { Log.LogWarning((object)("Failed to migrate legacy config file: " + ex.Message)); } } private void InitializeConfig() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Expected O, but got Unknown //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Expected O, but got Unknown _modEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Main", "Enable Box Miku 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", "Box Miku Size In World", 0.9f, new ConfigDescription("Scale multiplier for Box Miku 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", "Box Miku Size In Backpack", 0.4f, new ConfigDescription("Scale multiplier for the Box Miku 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, "箱MIKU"), 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 Box Miku replacement from folder: " + Path.Combine(directory, "箱MIKU"))); return; } string text = Path.Combine(directory, "boxmiku"); Bundle = AssetBundle.LoadFromFile(text); if ((Object)(object)Bundle == (Object)null) { Log.LogError((object)("Failed to load runtime Box Miku assets and failed to load AssetBundle: " + text)); return; } MochiPrefab = LoadBundleAssetWithFallback<GameObject>("assets/boxmiku/boxmiku.prefab", PrefabNameHints); MochiMaterial = LoadBundleAssetWithFallback<Material>("assets/boxmiku/m_boxmiku.mat", MaterialNameHints); MochiTexture = val ?? LoadBundleAssetWithFallback<Texture2D>("assets/boxmiku/boxmiku_icon.png", IconTextureNameHints); Texture2D val2 = LoadBundleAssetWithFallback<Texture2D>("assets/boxmiku/boxmiku.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() { string directoryName = Path.GetDirectoryName(directory); string[] array = new string[7] { Path.Combine(directory, "箱MIKU", "BoxMikuUI.png"), Path.Combine(directory, "BoxMikuUI.png"), string.IsNullOrEmpty(directoryName) ? null : Path.Combine(directoryName, "BoxMikuUI.png"), Path.Combine(directory, "icon.png"), string.IsNullOrEmpty(directoryName) ? null : Path.Combine(directoryName, "icon.png"), Path.Combine(directory, "ミク!.png"), Path.Combine(directory, "箱MIKU", "ミク!.png") }; for (int i = 0; i < array.Length; i++) { Texture2D val = LoadTextureFromFile(array[i], "external icon"); if ((Object)(object)val != (Object)null) { return val; } } return null; } private Texture2D LoadTextureFromFile(string texturePath, string textureLabel) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Expected O, but got Unknown //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(texturePath) || !File.Exists(texturePath)) { return null; } try { using FileStream fileStream = File.OpenRead(texturePath); 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(texturePath) }; 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 " + textureLabel + " texture '" + texturePath + "': " + 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.1f); } if (material.HasProperty("_Glossiness")) { material.SetFloat("_Glossiness", 0.1f); } if (material.HasProperty("_Metallic")) { material.SetFloat("_Metallic", 0f); } if (material.HasProperty("_BumpScale")) { material.SetFloat("_BumpScale", 0f); } if (material.HasProperty("_OcclusionStrength")) { material.SetFloat("_OcclusionStrength", 0f); } if (material.HasProperty("_SpecularHighlights")) { material.SetFloat("_SpecularHighlights", 0f); } if (material.HasProperty("_EnvironmentReflections")) { material.SetFloat("_EnvironmentReflections", 0f); } if (material.HasProperty("_EmissionColor")) { material.SetColor("_EmissionColor", Color.black); material.DisableKeyword("_EMISSION"); } material.DisableKeyword("_NORMALMAP"); material.DisableKeyword("_METALLICSPECGLOSSMAP"); material.DisableKeyword("_OCCLUSIONMAP"); } } private static Texture2D CreateReadableTexture(Texture2D source) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown if ((Object)(object)source == (Object)null) { return null; } try { source.GetPixel(0, 0); return source; } catch { } RenderTexture temporary = RenderTexture.GetTemporary(((Texture)source).width, ((Texture)source).height, 0, (RenderTextureFormat)0); RenderTexture active = RenderTexture.active; try { Graphics.Blit((Texture)(object)source, temporary); RenderTexture.active = temporary; Texture2D val = new Texture2D(((Texture)source).width, ((Texture)source).height, (TextureFormat)4, true, false) { name = ((Object)source).name + "_Readable" }; val.ReadPixels(new Rect(0f, 0f, (float)((Texture)source).width, (float)((Texture)source).height), 0, 0); val.Apply(true, false); return val; } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } } private static 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 = "BoxMiku_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 { private Renderer[] _cachedRenderers; private bool _renderersCached; private bool _materialsConfigured; public Renderer[] CachedRenderers { get { if (!_renderersCached || _cachedRenderers == null) { _cachedRenderers = ((Component)this).GetComponentsInChildren<Renderer>(true); _renderersCached = true; } return _cachedRenderers; } } public bool MaterialsConfigured => _materialsConfigured; public void MarkMaterialsConfigured() { _materialsConfigured = true; } public void InvalidateCache() { _renderersCached = false; _cachedRenderers = null; } } 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]; } } } } [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 = "BoxMiku_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.18f, 0.04f); private static readonly Quaternion HeldMikuLocalRotation = Quaternion.Euler(10f, 0f, 0f); private static readonly Dictionary<int, int> _cachedTargetLayers = new Dictionary<int, int>(); private static readonly Dictionary<int, Renderer[]> _cachedOriginalRenderers = new Dictionary<int, Renderer[]>(); 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 false; } Transform val = transform; while ((Object)(object)val != (Object)null) { if (((Object)val).name == "BoxMiku_Visual") { return true; } val = val.parent; } return false; } private static Transform FindMikuRoot(Item item) { if ((Object)(object)item == (Object)null) { return null; } Transform val = ((Component)item).transform.Find("BoxMiku_Visual"); if ((Object)(object)val != (Object)null) { return val; } 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 null; } private static int DetermineTargetLayer(Item item) { if ((Object)(object)item == (Object)null) { return 0; } int instanceID = ((Object)item).GetInstanceID(); if (_cachedTargetLayers.TryGetValue(instanceID, out var value)) { return value; } Renderer[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Renderer>(true); int layer = ((Component)item).gameObject.layer; for (int i = 0; i < componentsInChildren.Length; i++) { if (!((Object)(object)componentsInChildren[i] == (Object)null) && !IsMikuTransform(((Component)componentsInChildren[i]).transform)) { layer = ((Component)componentsInChildren[i]).gameObject.layer; break; } } _cachedTargetLayers[instanceID] = layer; return layer; } private static Vector3 ResolveScaleByState(Item item) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) float num = (((int)item.itemState == 2) ? 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_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //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_003f: 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_004a: 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_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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_002d: Unknown result type (might be due to invalid IL or missing references) Vector3 scale = ResolveScaleByState(item); if ((int)item.itemState == 1) { localPosition = HeldMikuLocalPosition; localRotation = HeldMikuLocalRotation; localScale = ApplyPlayerFacingScale(scale); } else { localPosition = WorldMikuLocalPosition; localRotation = WorldMikuLocalRotation; localScale = ApplyPlayerFacingScale(scale); } } private static Texture GetMikuTexture() { return (Texture)(((object)Plugin.MikuMainTexture) ?? ((object)(TryGetTexture(Plugin.MochiMaterial) ?? TryGetTexture(Plugin.RuntimeMikuMaterial)))); } private static Texture TryGetTexture(Material material) { if ((Object)(object)material == (Object)null) { return null; } if (material.HasProperty("_BaseMap")) { return material.GetTexture("_BaseMap"); } if (material.HasProperty("_MainTex")) { return material.GetTexture("_MainTex"); } return null; } private static void ApplyMikuTextureSafe(Material material, Texture mikuTexture) { //IL_0032: 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) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007b: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)material == (Object)null) && !((Object)(object)mikuTexture == (Object)null)) { if (material.HasProperty("_BaseMap")) { material.SetTexture("_BaseMap", mikuTexture); material.SetTextureScale("_BaseMap", Vector2.one); material.SetTextureOffset("_BaseMap", Vector2.zero); } if (material.HasProperty("_MainTex")) { material.SetTexture("_MainTex", mikuTexture); material.SetTextureScale("_MainTex", Vector2.one); material.SetTextureOffset("_MainTex", Vector2.zero); } } } private static Material CreateRendererMaterialInstance(Material template = null) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_004c: Expected O, but got Unknown //IL_004d: Expected O, but got Unknown //IL_00c0: 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_00fa: Unknown result type (might be due to invalid IL or missing references) template = template ?? Plugin.RuntimeMikuMaterial ?? Plugin.MochiMaterial; if ((Object)(object)template == (Object)null) { Material val = new Material(Shader.Find("Standard") ?? Shader.Find("Universal Render Pipeline/Lit")) { color = Color.white }; RuntimePmxLoader.ConfigureOpaqueSurface(val); return val; } Material val2 = new Material(template); Texture val3 = TryGetTexture(val2); Texture mikuTexture = GetMikuTexture(); if ((Object)(object)val3 != (Object)null) { Texture2D val4 = (Texture2D)(object)((val3 is Texture2D) ? val3 : null); if ((Object)(object)val4 != (Object)null) { ((Texture)val4).filterMode = (FilterMode)2; ((Texture)val4).wrapMode = (TextureWrapMode)1; ((Texture)val4).anisoLevel = Mathf.Max(((Texture)val4).anisoLevel, 16); } } else if ((Object)(object)mikuTexture != (Object)null) { ApplyMikuTextureSafe(val2, mikuTexture); } if (val2.HasProperty("_Tint")) { val2.SetColor("_Tint", MikuMaterialTint); } if (val2.HasProperty("_BaseColor")) { val2.SetColor("_BaseColor", MikuMaterialTint); } if (val2.HasProperty("_Color")) { val2.SetColor("_Color", MikuMaterialTint); } if (val2.HasProperty("_Smoothness")) { val2.SetFloat("_Smoothness", 0.1f); } if (val2.HasProperty("_Glossiness")) { val2.SetFloat("_Glossiness", 0.1f); } if (val2.HasProperty("_Metallic")) { val2.SetFloat("_Metallic", 0f); } 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 = ((sourceMaterials != null && sourceMaterials.Length != 0) ? sourceMaterials[Mathf.Min(i, sourceMaterials.Length - 1)] : null); array[i] = CreateRendererMaterialInstance(template); } return array; } private static void ApplyMaterialToRenderer(Renderer renderer) { //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_0041: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)renderer == (Object)null)) { SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if ((Object)(object)val != (Object)null && (Object)(object)val.sharedMesh != (Object)null) { Bounds bounds = val.sharedMesh.bounds; ((Bounds)(ref bounds)).Expand(0.5f); ((Renderer)val).localBounds = bounds; } } } private static int GetRendererSubMeshCount(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return 1; } SkinnedMeshRenderer val = (SkinnedMeshRenderer)(object)((renderer is SkinnedMeshRenderer) ? renderer : null); if ((Object)(object)val != (Object)null && (Object)(object)val.sharedMesh != (Object)null) { return Mathf.Max(1, val.sharedMesh.subMeshCount); } MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>(); if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) { return Mathf.Max(1, component.sharedMesh.subMeshCount); } return 1; } private static bool RendererNeedsMaterialRepair(Material[] materials, int subMeshCount) { if (materials == null || materials.Length != Mathf.Max(1, subMeshCount)) { return true; } for (int i = 0; i < materials.Length; i++) { if ((Object)(object)materials[i] == (Object)null) { return true; } } return false; } private static bool EnsureRendererMaterialIntegrity(Renderer renderer) { if ((Object)(object)renderer == (Object)null) { return false; } if (Plugin.RuntimeReplacementModel != null) { MeshFilter component = ((Component)renderer).GetComponent<MeshFilter>(); if ((Object)(object)component != (Object)null && (Object)(object)Plugin.RuntimeReplacementModel.Mesh != (Object)null && (Object)(object)component.sharedMesh != (Object)(object)Plugin.RuntimeReplacementModel.Mesh) { component.sharedMesh = Plugin.RuntimeReplacementModel.Mesh; } } int rendererSubMeshCount = GetRendererSubMeshCount(renderer); Material[] sharedMaterials = renderer.sharedMaterials; if (!RendererNeedsMaterialRepair(sharedMaterials, rendererSubMeshCount)) { ApplyMaterialToRenderer(renderer); return false; } if (Plugin.RuntimeReplacementModel != null) { renderer.sharedMaterials = Plugin.RuntimeReplacementModel.CreateMaterialsForRenderer(rendererSubMeshCount); } else { renderer.sharedMaterials = BuildMaterialArray(sharedMaterials, rendererSubMeshCount); } ApplyMaterialToRenderer(renderer); return true; } private static void EnsureReplacementMaterials(Transform mikuRoot) { if ((Object)(object)mikuRoot == (Object)null) { return; } MikuMarker component = ((Component)mikuRoot).GetComponent<MikuMarker>(); Renderer[] array = (((Object)(object)component != (Object)null) ? component.CachedRenderers : ((Component)mikuRoot).GetComponentsInChildren<Renderer>(true)); bool flag = false; foreach (Renderer val in array) { if (!((Object)(object)val == (Object)null)) { EnsureRendererMaterialIntegrity(val); flag = true; } } if ((Object)(object)component != (Object)null && flag) { component.MarkMaterialsConfigured(); } } private static Renderer[] GetOriginalRenderers(Item item) { if ((Object)(object)item == (Object)null) { return Array.Empty<Renderer>(); } int instanceID = ((Object)item).GetInstanceID(); if (_cachedOriginalRenderers.TryGetValue(instanceID, out var value)) { bool flag = false; for (int i = 0; i < value.Length; i++) { if ((Object)(object)value[i] == (Object)null) { flag = true; break; } } if (!flag) { return value; } } Renderer[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Renderer>(true); List<Renderer> list = new List<Renderer>(); for (int j = 0; j < componentsInChildren.Length; j++) { if ((Object)(object)componentsInChildren[j] != (Object)null && !IsMikuTransform(((Component)componentsInChildren[j]).transform)) { list.Add(componentsInChildren[j]); } } Renderer[] array = list.ToArray(); _cachedOriginalRenderers[instanceID] = array; return array; } private static void DisableOriginalRenderers(Item item) { Renderer[] originalRenderers = GetOriginalRenderers(item); for (int i = 0; i < originalRenderers.Length; i++) { if ((Object)(object)originalRenderers[i] != (Object)null) { originalRenderers[i].enabled = false; } } } private static void EnableOriginalRenderers(Item item) { Renderer[] originalRenderers = GetOriginalRenderers(item); for (int i = 0; i < originalRenderers.Length; i++) { if ((Object)(object)originalRenderers[i] != (Object)null) { originalRenderers[i].enabled = true; } } } 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 HasVisibleReplacementRenderers(Transform mikuRoot) { if ((Object)(object)mikuRoot == (Object)null) { return false; } Renderer[] array = ((Component)mikuRoot).GetComponent<MikuMarker>()?.CachedRenderers ?? ((Component)mikuRoot).GetComponentsInChildren<Renderer>(true); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] == (Object)null) { continue; } Material[] sharedMaterials = array[i].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 SyncVisibilityState(Item item, bool forceRefresh) { //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 modEnabled = Plugin.ModEnabled; if (((Component)val).gameObject.activeSelf != modEnabled) { ((Component)val).gameObject.SetActive(modEnabled); } if (!modEnabled) { EnableOriginalRenderers(item); RestoreOriginalItemRendererRefs(item); } else { if (!forceRefresh) { return; } EnsureReplacementMaterials(val); if (HasVisibleReplacementRenderers(val)) { DisableOriginalRenderers(item); } else { EnableOriginalRenderers(item); } Renderer[] array = ((Component)val).GetComponent<MikuMarker>()?.CachedRenderers ?? ((Component)val).GetComponentsInChildren<Renderer>(true); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null) { ConfigureMikuRenderer(array[i], num); } } EnsureItemRendererRefs(item, val); } } private static void EnsureReplacementAndVisibility(Item item, bool createIfMissing, bool forceRefresh) { 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)) { MikuDeformGuard component = ((Component)val).GetComponent<MikuDeformGuard>(); if ((Object)(object)component != (Object)null) { component.Bind(item); } SyncVisibilityState(item, forceRefresh); } } private static void RemoveReplacement(Item item, Transform mikuRoot) { EnableOriginalRenderers(item); RestoreOriginalItemRendererRefs(item); if ((Object)(object)mikuRoot != (Object)null) { Object.Destroy((Object)(object)((Component)mikuRoot).gameObject); } _cachedOriginalRenderers.Remove(((Object)item).GetInstanceID()); } private static void SanitizeVisualObject(GameObject visualRoot, int targetLayer) { Collider[] componentsInChildren = visualRoot.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { componentsInChildren[i].enabled = false; Object.Destroy((Object)(object)componentsInChildren[i]); } } 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 val in componentsInChildren4) { if ((Object)(object)val != (Object)null) { val.enabled = false; Object.Destroy((Object)(object)val); } } MonoBehaviour[] componentsInChildren5 = visualRoot.GetComponentsInChildren<MonoBehaviour>(true); for (int m = 0; m < componentsInChildren5.Length; m++) { if ((Object)(object)componentsInChildren5[m] != (Object)null && !(componentsInChildren5[m] is MikuMarker)) { ((Behaviour)componentsInChildren5[m]).enabled = false; } } Transform[] componentsInChildren6 = visualRoot.GetComponentsInChildren<Transform>(true); for (int n = 0; n < componentsInChildren6.Length; n++) { if ((Object)(object)componentsInChildren6[n] != (Object)null) { ((Component)componentsInChildren6[n]).gameObject.tag = "Untagged"; ((Component)componentsInChildren6[n]).gameObject.layer = targetLayer; } } } private static Collider FindColliderTemplate(Item item) { if ((Object)(object)item == (Object)null) { return null; } Collider[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && !IsMikuTransform(((Component)componentsInChildren[i]).transform)) { return componentsInChildren[i]; } } return null; } 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 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 RebuildModelColliders(Item item, Transform mikuRoot) { //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_016d: 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_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: 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_00fd: 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_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null || (Object)(object)mikuRoot == (Object)null) { return; } Collider source = FindColliderTemplate(item); Collider[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null) { Object.Destroy((Object)(object)componentsInChildren[i]); } } List<Collider> list = new List<Collider>(); MeshRenderer[] componentsInChildren2 = ((Component)mikuRoot).GetComponentsInChildren<MeshRenderer>(true); Vector3 size; foreach (MeshRenderer val in componentsInChildren2) { if ((Object)(object)val == (Object)null) { continue; } MeshFilter component = ((Component)val).GetComponent<MeshFilter>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null) && !HasNegativeScaleInHierarchy(((Component)val).transform)) { Bounds bounds = component.sharedMesh.bounds; size = ((Bounds)(ref bounds)).size; if (!(((Vector3)(ref size)).sqrMagnitude <= 0f)) { BoxCollider val2 = ((Component)val).gameObject.GetComponent<BoxCollider>() ?? ((Component)val).gameObject.AddComponent<BoxCollider>(); val2.center = ((Bounds)(ref bounds)).center; val2.size = ClampColliderSize(((Bounds)(ref bounds)).size); CopyColliderSettings(source, (Collider)(object)val2); list.Add((Collider)(object)val2); } } } SkinnedMeshRenderer[] componentsInChildren3 = ((Component)mikuRoot).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val3 in componentsInChildren3) { if (!((Object)(object)val3 == (Object)null) && !HasNegativeScaleInHierarchy(((Component)val3).transform)) { Bounds val4 = ((Renderer)val3).localBounds; size = ((Bounds)(ref val4)).size; if (((Vector3)(ref size)).sqrMagnitude <= 0f && (Object)(object)val3.sharedMesh != (Object)null) { val4 = val3.sharedMesh.bounds; } size = ((Bounds)(ref val4)).size; if (!(((Vector3)(ref size)).sqrMagnitude <= 0f)) { BoxCollider val5 = ((Component)val3).gameObject.GetComponent<BoxCollider>() ?? ((Component)val3).gameObject.AddComponent<BoxCollider>(); val5.center = ((Bounds)(ref val4)).center; val5.size = ClampColliderSize(((Bounds)(ref val4)).size); CopyColliderSettings(source, (Collider)(object)val5); list.Add((Collider)(object)val5); } } } if (list.Count > 0) { item.colliders = list.ToArray(); } } private static void EnableOriginalColliders(Item item) { Collider[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Collider>(true); List<Collider> list = new List<Collider>(); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && !IsMikuTransform(((Component)componentsInChildren[i]).transform)) { componentsInChildren[i].enabled = true; list.Add(componentsInChildren[i]); } } if ((Object)(object)item != (Object)null) { item.colliders = list.ToArray(); } } private static void DisableOriginalColliders(Item item) { Collider[] componentsInChildren = ((Component)item).gameObject.GetComponentsInChildren<Collider>(true); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && !IsMikuTransform(((Component)componentsInChildren[i]).transform)) { componentsInChildren[i].enabled = false; } } } private static void SyncCollidersByState(Item item, Transform mikuRoot) { //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)item == (Object)null || (Object)(object)mikuRoot == (Object)null) { return; } if ((int)item.itemState == 1) { SetColliderArrayEnabled(((Component)mikuRoot).GetComponentsInChildren<Collider>(true), enabled: false); EnableOriginalColliders(item); return; } Collider[] componentsInChildren = ((Component)mikuRoot).GetComponentsInChildren<Collider>(true); if (componentsInChildren.Length == 0) { RebuildModelColliders(item, mikuRoot); } 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; } for (int i = 0; i < colliders.Length; i++) { if ((Object)(object)colliders[i] != (Object)null) { colliders[i].enabled = enabled; } } } 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; } for (int i = 0; i < sharedMaterials.Length; i++) { if ((Object)(object)sharedMaterials[i] != (Object)null && sharedMaterials[i].HasProperty("_MainTex")) { return true; } } return false; } private static Renderer[] BuildAdditionalRenderers(Renderer primaryRenderer, Renderer[] renderers) { if (renderers == null || renderers.Length == 0) { return Array.Empty<Renderer>(); } List<Renderer> list = new List<Renderer>(); for (int i = 0; i < renderers.Length; i++) { if ((Object)(object)renderers[i] != (Object)null && (Object)(object)renderers[i] != (Object)(object)primaryRenderer) { list.Add(renderers[i]); } } 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[] originalRenderers = GetOriginalRenderers(item); if (originalRenderers.Length == 0) { return false; } for (int i = 0; i < originalRenderers.Length; i++) { if ((Object)(object)primaryRenderer == (Object)null) { primaryRenderer = originalRenderers[i]; } if (RendererHasMainTexSlot(originalRenderers[i])) { primaryRenderer = originalRenderers[i]; break; } } if ((Object)(object)primaryRenderer == (Object)null) { return false; } additionalRenderers = BuildAdditionalRenderers(primaryRenderer, originalRenderers); 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; for (int i = 0; i < componentsInChildren.Length; i++) { if (!((Object)(object)componentsInChildren[i] == (Object)null)) { if ((Object)(object)val == (Object)null) { val = componentsInChildren[i]; } if (RendererHasMainTexSlot(componentsInChildren[i])) { val = componentsInChildren[i]; break; } } } if (!((Object)(object)val == (Object)null)) { item.mainRenderer = val; item.addtlRenderers = BuildAdditionalRenderers(val, componentsInChildren); } } private static void RestoreOriginalItemRendererRefs(Item item) { if (!((Object)(object)item == (Object)null) && TryGetOriginalItemRenderers(item, out var primaryRenderer, out var additionalRenderers)) { item.mainRenderer = primaryRenderer; item.addtlRenderers = additionalRenderers; } } private static Transform EnsureMikuModel(Item item, bool createIfMissing) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: 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("BoxMiku_Visual"); if ((Object)(object)val2 == (Object)null) { return null; } val2.transform.SetParent(((Component)item).transform, false); ((Object)val2).name = "BoxMiku_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; MikuMarker mikuMarker = val2.GetComponent<MikuMarker>() ?? val2.AddComponent<MikuMarker>(); SanitizeVisualObject(val2, targetLayer); MikuDeformGuard obj = val2.GetComponent<MikuDeformGuard>() ?? val2.AddComponent<MikuDeformGuard>(); obj.Bind(item); obj.Initialize(localPosition, localRotation, localScale); EnsureReplacementMaterials(val2.transform); MeshRenderer[] componentsInChildren = val2.GetComponentsInChildren<MeshRenderer>(true); SkinnedMeshRenderer[] componentsInChildren2 = val2.GetComponentsInChildren<SkinnedMeshRenderer>(true); for (int i = 0; i < componentsInChildren.Length; i++) { ConfigureMikuRenderer((Renderer)(object)componentsInChildren[i], targetLayer); } for (int j = 0; j < componentsInChildren2.Length; j++) { componentsInChildren2[j].updateWhenOffscreen = true; ConfigureMikuRenderer((Renderer)(object)componentsInChildren2[j], targetLayer); } mikuMarker.MarkMaterialsConfigured(); EnsureItemRendererRefs(item, val2.transform); RebuildModelColliders(item, val2.transform); return val2.transform; } [HarmonyPatch("Start")] [HarmonyPostfix] public static void Item_Start(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: true, forceRefresh: true); } [HarmonyPatch("OnEnable")] [HarmonyPostfix] public static void Item_OnEnable(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: true, forceRefresh: true); } [HarmonyPatch("SetState")] [HarmonyPrefix] public static void Item_SetState_Prefix(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: true, forceRefresh: true); } [HarmonyPatch("SetState")] [HarmonyPostfix] public static void Item_SetState_Postfix(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: true, forceRefresh: true); } [HarmonyPatch("Update")] [HarmonyPostfix] public static void Item_Update_Postfix(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: false, forceRefresh: false); } [HarmonyPatch("RequestPickup")] [HarmonyPrefix] public static void Item_RequestPickup_Prefix(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: true, forceRefresh: 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); EnsureReplacementMaterials(val); int targetLayer = DetermineTargetLayer(__instance); Renderer[] array = ((Component)val).GetComponent<MikuMarker>()?.CachedRenderers ?? ((Component)val).GetComponentsInChildren<Renderer>(true); for (int i = 0; i < array.Length; i++) { if ((Object)(object)array[i] != (Object)null) { ConfigureMikuRenderer(array[i], targetLayer); } } DisableOriginalRenderers(__instance); EnsureItemRendererRefs(__instance, val); return false; } [HarmonyPatch("PutInBackpackRPC")] [HarmonyPostfix] public static void Item_PutInBackpackRPC_Postfix(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: false, forceRefresh: true); } [HarmonyPatch("ClearDataFromBackpack")] [HarmonyPostfix] public static void Item_ClearDataFromBackpack_Postfix(Item __instance) { EnsureReplacementAndVisibility(__instance, createIfMissing: false, forceRefresh: true); } [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 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")) { material.SetColor("_Tint", color); } } private static Color[] CaptureDefaultTints(Renderer[] renderers) { //IL_0029: 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_002e: Unknown result type (might be due to invalid IL or missing references) Color[] array = (Color[])(object)new Color[renderers.Length]; for (int i = 0; i < renderers.Length; i++) { array[i] = (((Object)(object)renderers[i] == (Object)null) ? Color.white : GetSafeTint(renderers[i].material)); } return array; } private static MeshRenderer[] GetBackpackSafeRenderers(BackpackOnBackVisuals instance) { MeshRenderer[] componentsInChildren = ((Component)instance).GetComponentsInChildren<MeshRenderer>(); List<MeshRenderer> list = new List<MeshRenderer>(); for (int i = 0; i < componentsInChildren.Length; i++) { if ((Object)(object)componentsInChildren[i] != (Object)null && !ItemPatch.IsMikuTransform(((Component)componentsInChildren[i]).transform)) { list.Add(componentsInChildren[i]); } } return list.ToArray(); } private static Renderer[] GetItemCookingSafeRenderers(ItemCooking instance) { List<Renderer> list = new List<Renderer>(); MeshRenderer[] componentsInChildren = ((Component)instance).GetComponentsInChildren<MeshRenderer>(); foreach (MeshRenderer val in componentsInChildren) { if ((Object)(object)val != (Object)null && !ItemPatch.IsMikuTransform(((Component)val).transform)) { list.Add((Renderer)(object)val); } } SkinnedMeshRenderer[] componentsInChildren2 = ((Component)instance).GetComponentsInChildren<SkinnedMeshRenderer>(true); foreach (SkinnedMeshRenderer val2 in componentsInChildren2) { if ((Object)(object)val2 != (Object)null && !ItemPatch.IsMikuTransform(((Component)val2).transform)) { list.Add((Renderer)(object)val2); } } return list.ToArray(); } [HarmonyPatch(typeof(BackpackOnBackVisuals), "InitRenderers")] [HarmonyPrefix] public static bool BackpackOnBackVisuals_InitRenderers_Prefix(BackpackOnBackVisuals __instance) { MeshRenderer[] backpackSafeRenderers = GetBackpackSafeRenderers(__instance); BackpackRenderersRef.Invoke(__instance) = backpackSafeRenderers; ref Color[] reference = ref BackpackDefaultTintsRef.Invoke(__instance); Renderer[] renderers = (Renderer[])(object)backpackSafeRenderers; reference = CaptureDefaultTints(renderers); return false; } [HarmonyPatch(typeof(BackpackOnBackVisuals), "CookVisually")] [HarmonyPrefix] public static bool BackpackOnBackVisuals_CookVisually_Prefix(BackpackOnBackVisuals __instance, int __0) { //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_0057: 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_005c: 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_0068: 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) MeshRenderer[] array = BackpackRenderersRef.Invoke(__instance) ?? Array.Empty<MeshRenderer>(); Color[] array2 = BackpackDefaultTintsRef.Invoke(__instance) ?? Array.Empty<Color>(); if (__0 <= 0) { return false; } Color cookColor = ItemCooking.GetCookColor(__0); for (int i = 0; i < array.Length; i++) { if (!((Object)(object)array[i] == (Object)null)) { Color val = ((i < array2.Length) ? array2[i] : Color.white); TryApplyTint(((Renderer)array[i]).material, val * cookColor); } } return false; } [HarmonyPatch(typeof(ItemCooking), "UpdateCookedBehavior")] [HarmonyPrefix] public static bool ItemCooking_UpdateCookedBehavior_Prefix(ItemCooking __instance) { Item component = ((Component)__instance).GetComponent<Item>(); if ((Object)(object)component == (Object)null) { return true; } IntItemData data = component.GetData<IntItemData>((DataEntryKey)1); if (data == null) { return true; } if (data.Value == 0) { data.Value = data.Value; } if (ItemCookingRenderersRef.Invoke(__instance) == null) { Array.Empty<Renderer>(); } if (ItemCookingDefaultTintsRef.Invoke(__instance) == null) { Array.Empty<Color>(); } _ = data.Value; CookVisuallyDelegate(__instance, data.Value); RunAdditionalCookingBehaviorsDelegate(__instance, data.Value); ChangeStatsCookedDelegate(__instance, data.Value); return false; } [HarmonyPatch(typeof(ItemCooking), "CookVisually")] [HarmonyPrefix] public static bool ItemCooking_CookVisually_Prefix(ItemCooking __instance, int __0) { //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_0061: 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_0066: 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_0074: 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) Renderer[] array = ItemCookingRenderersRef.Invoke(__instance) ?? Array.Empty<Renderer>(); Color[] array2 = ItemCookingDefaultTintsRef.Invoke(__instance) ?? Array.Empty<Color>(); if (__0 <= 0) { return false; } Color cookColor = ItemCooking.GetCookColor(__0); for (int i = 0; i < array.Length; i++) { if (!((Object)(object)array[i] == (Object)null)) { Material[] materials = array[i].materials; Color val = ((i < array2.Length) ? array2[i] : Color.white); for (int j = 0; j < materials.Length; j++) { TryApplyTint(materials[j], val * cookColor); } } } return false; } } internal sealed class RuntimeReplacementModel { internal string DisplayName { get; private set; } internal Mesh Mesh { get; private set; } internal Material[] Materials { get; private set; } internal Vector3 MeshLocalOffset { get; private set; } internal Vector3 RecommendedBaseScale { get; private set; } internal Texture2D PrimaryTexture { get; private set; } internal Texture2D IconTexture { get; private set; } internal Material PrimaryMaterial { get { if (Materials == null || Materials.Length == 0) { return null; } return Materials[0]; } } internal RuntimeReplacementModel(string displayName, Mesh mesh, Material[] materials, Vector3 meshLocalOffset, Vector3 recommendedBaseScale, Texture2D primaryTexture, Texture2D iconTexture) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) DisplayName = (string.IsNullOrEmpty(displayName) ? "MIKU" : displayName); Mesh = mesh; Materials = materials ?? Array.Empty<Material>(); MeshLocalOffset = meshLocalOffset; RecommendedBaseScale = recommendedBaseScale; PrimaryTexture = primaryTexture; IconTexture = iconTexture; } internal GameObject Instantiate(string rootName) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown //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_0032: 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_0043: 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_0053: 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_0063: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(string.IsNullOrEmpty(rootName) ? "BoxMiku_Visual" : rootName); GameObject val2 = new GameObject("RuntimeMesh"); val2.transform.SetParent(val.transform, false); val2.transform.localPosition = MeshLocalOffset; val2.transform.localRotation = Quaternion.identity; val2.transform.localScale = Vector3.one; val2.AddComponent<MeshFilter>().sharedMesh = Mesh; ((Renderer)val2.AddComponent<MeshRenderer>()).sharedMaterials = CreateMaterialsForRenderer((!((Object)(object)Mesh != (Object)null)) ? 1 : Mesh.subMeshCount); return val; } internal Material[] CreateMaterialsForRenderer(int subMeshCount) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(1, subMeshCount); if (Materials == null || Materials.Length == 0) { Material val = CreateFallbackMaterial(); if ((Object)(object)val == (Object)null) { return Array.Empty<Material>(); } Material[] array = (Material[])(object)new Material[num]; for (int i = 0; i < array.Length; i++) { array[i] = new Material(val); } return array; } Material[] array2 = (Material[])(object)new Material[num]; for (int j = 0; j < num; j++) { Material val2 = Materials[Mathf.Min(j, Materials.Length - 1)]; object obj = array2; int num2 = j; obj = (((Object)(object)val2 != (Object)null) ? ((object)new Material(val2)) : ((object)CreateFallbackMaterial())); ((object[])obj)[num2] = obj; } return array2; } private static Material CreateFallbackMaterial() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_003e: Expected O, but got Unknown //IL_003f: Expected O, but got Unknown Shader val = RuntimePmxLoader.FindCompatibleShader(); if ((Object)(object)val == (Object)null) { return null; } Material val2 = new Material(val) { name = "BoxMiku_Fallback", color = Color.white, renderQueue = 2000 }; RuntimePmxLoader.ConfigureOpaqueSurface(val2); return val2; } } internal static class RuntimePmxLoader { private sealed class PmxMaterialInfo { internal string Name; internal string MainTexturePath; internal string ToonTexturePath; internal Color DiffuseColor; internal int SurfaceIndexCount; } private sealed class PmxHeader { internal Encoding TextEncoding; internal int AdditionalUvCount; internal int VertexIndexSize; internal int TextureIndexSize; internal int BoneIndexSize; } private const string PreferredModelFileName = "_箱MIKU(50cm).pmx"; private static readonly Vector3 ReferenceVisibleSizeAtBaseScale = new Vector3(1.5852638f, 1.2168914f, 0.8999324f); private static readonly Vector3 ReferenceVisibleCenterAtBaseScale = new Vector3(0.0330699f, 0.06277876f, 0.09902591f); internal static RuntimeReplacementModel Load(string replacementRoot, ManualLogSource log) { try { if (string.IsNullOrEmpty(replacementRoot) || !Directory.Exists(replacementRoot)) { return null; } string text = FindPmxPath(replacementRoot); if (string.IsNullOrEmpty(text)) { return null; } return BuildRuntimeModel(text, log); } catch (Exception ex) { if (log != null) { log.LogError((object)("Failed to load runtime PMX replacement: " + ex)); } return null; } } private static string FindPmxPath(string replacementRoot) { string text = Path.Combine(replacementRoot, "_箱MIKU(50cm).pmx"); if (File.Exists(text)) { return text; } string[] files = Directory.GetFiles(replacementRoot, "*.pmx", SearchOption.TopDirectoryOnly); if (files.Length == 0) { return null; } return files[0]; } private static RuntimeReplacementModel BuildRuntimeModel(string pmxPath, ManualLogSource log) { //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_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) //IL_0090: 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) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0168: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) using FileStream input = File.OpenRead(pmxPath); using BinaryReader binaryReader = new BinaryReader(input); PmxHeader pmxHeader = ReadHeader(binaryReader); ReadText(binaryReader, pmxHeader.TextEncoding); ReadText(binaryReader, pmxHeader.TextEncoding); ReadText(binaryReader, pmxHeader.TextEncoding); ReadText(binaryReader, pmxHeader.TextEncoding); int num = binaryReader.ReadInt32(); Vector3[] array = (Vector3[])(object)new Vector3[num]; Vector3[] array2 = (Vector3[])(object)new Vector3[num]; Vector2[] array3 = (Vector2[])(object)new Vector2[num]; for (int i = 0; i < num; i++) { array[i] = ConvertPosition(ReadVector3(binaryReader)); array2[i] = ConvertNormal(ReadVector3(binaryReader)); array3[i] = ConvertUv(ReadVector2(binaryReader)); SkipAdditionalUv(binaryReader, pmxHeader.AdditionalUvCount); SkipVertexWeight(binaryReader, pmxHeader.BoneIndexSize); binaryReader.ReadSingle(); } int num2 = binaryReader.ReadInt32(); int[] array4 = new int[num2]; for (int j = 0; j < num2; j++) { array4[j] = ReadUnsignedIndex(binaryReader, pmxHeader.VertexIndexSize); } List<string> texturePaths = ReadTexturePaths(binaryReader, pmxHeader.TextEncoding, pmxPath); List<PmxMaterialInfo> materials = ReadMaterials(binaryReader, pmxHeader, texturePaths); Dictionary<string, Texture2D> textureCache = new Dictionary<string, Texture2D>(StringComparer.OrdinalIgnoreCase); Texture2D primaryTexture; Texture2D iconTexture; Material[] materials2 = BuildMaterials(materials, textureCache, log, out primaryTexture, out iconTexture); Mesh val = BuildMesh(Path.GetFileNameWithoutExtension(pmxPath), array, array2, array3, array4, materials); Bounds bounds = val.bounds; Vector3 recommendedBaseScale = CalculateRecommendedBaseScale(((Bounds)(ref bounds)).size.y); Vector3 meshLocalOffset = CalculateMeshOffset(val.bounds, recommendedBaseScale); return new RuntimeReplacementModel("MIKU", val, materials2, meshLocalOffset, recommendedBaseScale, primaryTexture, iconTexture); } private static PmxHeader ReadHeader(BinaryReader reader) { string @string = Encoding.ASCII.GetString(reader.ReadBytes(4)); if (!string.Equals(@string, "PMX ", StringComparison.Ordinal)) { throw new InvalidDataException("Unsupported PMX signature: " + @string); } float num = reader.ReadSingle(); if (num < 2f || num >= 3f) { throw new InvalidDataException("Unsupported PMX version: " + num); } byte count = reader.ReadByte(); byte[] array = reader.ReadBytes(count); if (array.Length < 8) { throw new InvalidDataException("PMX header is incomplete."); } return new PmxHeader { TextEncoding = ((array[0] == 0) ? Encoding.Unicode : Encoding.UTF8), AdditionalUvCount = array[1], VertexIndexSize = array[2], TextureIndexSize = array[3], BoneIndexSize = array[5] }; } private static string ReadText(BinaryReader reader, Encoding encoding) { int num = reader.ReadInt32(); if (num <= 0) { return string.Empty; } byte[] bytes = reader.ReadBytes(num); return encoding.GetString(bytes); } private static void SkipAdditionalUv(BinaryReader reader, int additionalUvCount) { for (int i = 0; i < additionalUvCount; i++) { reader.ReadSingle(); reader.ReadSingle(); reader.ReadSingle(); reader.ReadSingle(); } } private static void SkipVertexWeight(BinaryReader reader, int boneIndexSize) { byte b = reader.ReadByte(); switch (b) { case 0: ReadSignedIndex(reader, boneIndexSize); break; case 1: ReadSignedIndex(reader, boneIndexSize); ReadSignedIndex(reader, boneIndexSize); reader.ReadSingle(); break; case 2: case 4: { for (int j = 0; j < 4; j++) { ReadSignedIndex(reader, boneIndexSize); } for (int k = 0; k < 4; k++) { reader.ReadSingle(); } break; } case 3: { ReadSignedIndex(reader, boneIndexSize); ReadSignedIndex(reader, boneIndexSize); reader.ReadSingle(); for (int i = 0; i < 9; i++) { reader.ReadSingle(); } break; } default: throw new InvalidDataException("Unsupported PMX vertex deform type: " + b); } } private static List<string> ReadTexturePaths(BinaryReader reader, Encoding encoding, string pmxPath) { int num = reader.ReadInt32(); List<string> list = new List<string>(num); string baseDirectory = Path.GetDirectoryName(pmxPath) ?? string.Empty; for (int i = 0; i < num; i++) { string relativePath = ReadText(reader, encoding); list.Add(ResolveRelativePath(baseDirectory, relativePath)); } return list; } private static List<PmxMaterialInfo> ReadMaterials(BinaryReader reader, PmxHeader header, List<string> texturePaths) { //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Unknown result type (might be due to invalid IL or missing references) int num = reader.ReadInt32(); List<PmxMaterialInfo> list = new List<PmxMaterialInfo>(num); Color diffuseColor = default(Color); for (int i = 0; i < num; i++) { string name = ReadText(reader, header.TextEncoding); ReadText(reader, header.TextEncoding); ((Color)(ref diffuseColor))..ctor(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); reader.ReadSingle(); reader.ReadSingle(); reader.ReadSingle(); reader.ReadSingle(); reader.ReadSingle(); reader.ReadSingle(); reader.ReadSingle(); reader.ReadByte(); reader.ReadSingle(); reader.ReadSingle(); reader.ReadSingle(); reader.ReadSingle(); reader.ReadSingle(); int index = ReadSignedIndex(reader, header.TextureIndexSize); ReadSignedIndex(reader, header.TextureIndexSize); reader.ReadByte(); byte b = reader.ReadByte(); int index2 = ((b == 0) ? ReadSignedIndex(reader, header.TextureIndexSize) : reader.ReadByte()); ReadText(reader, header.TextEncoding); int surfaceIndexCount = reader.ReadInt32(); list.Add(new PmxMaterialInfo { Name = name, MainTexturePath = GetTexturePath(texturePaths, index), ToonTexturePath = ((b == 0) ? GetTexturePath(texturePaths, index2) : null), DiffuseColor = diffuseColor, SurfaceIndexCount = surfaceIndexCount }); _ = 0; } return list; } private static Material[] BuildMaterials(List<PmxMaterialInfo> materials, Dictionary<string, Texture2D> textureCache, ManualLogSource log, out Texture2D primaryTexture, out Texture2D iconTexture) { //IL_005c: 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_0063: Expected O, but got Unknown //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) primaryTexture = null; iconTexture = null; Shader val = FindCompatibleShader(); Material[] array = (Material[])(object)new Material[Mathf.Max(1, materials.Count)]; Dictionary<Texture2D, bool> transparencyCache = new Dictionary<Texture2D, bool>(); for (int i = 0; i < array.Length; i++) { PmxMaterialInfo pmxMaterialInfo = ((i < materials.Count) ? materials[i] : null); Material val2 = (((Object)(object)val != (Object)null) ? ne