using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using PEAKLib.Core;
using PEAKLib.Items;
using Photon.Pun;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("MikuFumoToy")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("MikuFumoToy")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("6d283e72-1e03-4e63-8b6a-67d8e60f87ef")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)]
internal sealed class NullableAttribute : Attribute
{
public readonly byte[] NullableFlags;
public NullableAttribute(byte P_0)
{
NullableFlags = new byte[1] { P_0 };
}
public NullableAttribute(byte[] P_0)
{
NullableFlags = P_0;
}
}
[CompilerGenerated]
[Embedded]
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
internal sealed class NullableContextAttribute : Attribute
{
public readonly byte Flag;
public NullableContextAttribute(byte P_0)
{
Flag = P_0;
}
}
}
public class MikuFumoSqueeze : MonoBehaviour
{
private Transform miku;
private Vector3 originalScale;
private bool isSqueezing;
private float timer;
private float cooldownTimer;
private const float CooldownDuration = 0.5f;
private const float SqueezeDuration = 0.15f;
private const float ReturnDuration = 0.2f;
private const float SqueezeX = 0.65f;
private AudioSource squeezeSource;
private Coroutine squeezeCoroutine;
private void Awake()
{
//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_004d: Unknown result type (might be due to invalid IL or missing references)
//IL_0053: Expected O, but got Unknown
Transform val = ((Component)this).transform.Find("miku");
if ((Object)(object)val == (Object)null)
{
Debug.LogError((object)"[HatsuneMikuFumo] Model 'miku' not found!");
return;
}
miku = val;
originalScale = miku.localScale;
GameObject val2 = new GameObject("MikuFumoSqueezeAudio");
val2.transform.SetParent(((Component)this).transform, false);
squeezeSource = val2.AddComponent<AudioSource>();
squeezeSource.playOnAwake = false;
squeezeSource.spatialBlend = 1f;
Item component = ((Component)this).GetComponent<Item>();
PhotonView component2 = ((Component)this).GetComponent<PhotonView>();
Debug.Log((object)("[HatsuneMikuFumo] PhotonView found: " + ((Object)(object)component2 != (Object)null)));
if ((Object)(object)component != (Object)null)
{
component.OnPrimaryStarted = (Action)Delegate.Combine(component.OnPrimaryStarted, new Action(RequestSqueeze));
}
Debug.Log((object)"[HatsuneMikuFumo] Squeeze animation initialized!");
}
private void RequestSqueeze()
{
AudioClip[] squeezeSounds = MikuFumoAudio.SqueezeSounds;
if (squeezeSounds == null || squeezeSounds.Length == 0)
{
Debug.LogWarning((object)"[HatsuneMikuFumo] No squeeze sounds loaded!");
return;
}
int num = Random.Range(0, squeezeSounds.Length);
PhotonView component = ((Component)this).GetComponent<PhotonView>();
if ((Object)(object)component == (Object)null || !PhotonNetwork.InRoom)
{
PlaySqueezeLocally(num);
return;
}
component.RPC("RPC_PlaySqueeze", (RpcTarget)0, new object[1] { num });
}
[PunRPC]
private void RPC_PlaySqueeze(int soundIndex)
{
PlaySqueezeLocally(soundIndex);
}
public void RequestPickupSound()
{
AudioClip[] pickupSounds = MikuFumoAudio.PickupSounds;
if (pickupSounds == null || pickupSounds.Length == 0)
{
Debug.LogWarning((object)"[HatsuneMikuFumo] No pickup sounds loaded!");
return;
}
int num = Random.Range(0, pickupSounds.Length);
PhotonView component = ((Component)this).GetComponent<PhotonView>();
if ((Object)(object)component == (Object)null || !PhotonNetwork.InRoom)
{
MikuFumoAudio.PlayPickupSound(((Component)this).gameObject, num);
return;
}
component.RPC("RPC_PlayPickupSound", (RpcTarget)0, new object[1] { num });
}
[PunRPC]
private void RPC_PlayPickupSound(int soundIndex)
{
MikuFumoAudio.PlayPickupSound(((Component)this).gameObject, soundIndex);
}
private void PlaySqueezeLocally(int soundIndex)
{
PlaySqueezeVoice(soundIndex);
if (!((Object)(object)miku == (Object)null) && !(cooldownTimer > 0f))
{
timer = 0f;
isSqueezing = true;
cooldownTimer = 0.5f;
}
}
private void PlaySqueezeVoice(int soundIndex)
{
AudioClip[] squeezeSounds = MikuFumoAudio.SqueezeSounds;
if (squeezeSounds == null || soundIndex < 0 || soundIndex >= squeezeSounds.Length)
{
Debug.LogWarning((object)"[HatsuneMikuFumo] Invalid squeeze sound index!");
}
else
{
if ((Object)(object)squeezeSource == (Object)null)
{
return;
}
AudioClip val = squeezeSounds[soundIndex];
if (!((Object)(object)val == (Object)null))
{
squeezeSource.Stop();
if (squeezeCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(squeezeCoroutine);
squeezeCoroutine = null;
}
squeezeCoroutine = ((MonoBehaviour)this).StartCoroutine(PlaySqueezeAfterDelay(val));
}
}
}
private IEnumerator PlaySqueezeAfterDelay(AudioClip clip)
{
yield return (object)new WaitForSeconds(0.5f);
if ((Object)(object)squeezeSource != (Object)null && (Object)(object)clip != (Object)null)
{
squeezeSource.clip = clip;
squeezeSource.pitch = MikuFumoAudio.GetVoicePitch(((Component)this).gameObject);
squeezeSource.Play();
Debug.Log((object)("[HatsuneMikuFumo] Playing squeeze sound: " + ((Object)clip).name));
}
squeezeCoroutine = null;
}
private void Update()
{
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_0161: Unknown result type (might be due to invalid IL or missing references)
//IL_014b: Unknown result type (might be due to invalid IL or missing references)
if (cooldownTimer > 0f)
{
cooldownTimer -= Time.deltaTime;
if (cooldownTimer < 0f)
{
cooldownTimer = 0f;
}
}
if (isSqueezing && !((Object)(object)miku == (Object)null))
{
timer += Time.deltaTime;
if (timer < 0.15f)
{
float num = timer / 0.15f;
miku.localScale = new Vector3(Mathf.Lerp(originalScale.x, originalScale.x * 0.65f, num), originalScale.y, originalScale.z);
}
else if (timer < 0.35000002f)
{
float num2 = (timer - 0.15f) / 0.2f;
miku.localScale = new Vector3(Mathf.Lerp(originalScale.x * 0.65f, originalScale.x, num2), originalScale.y, originalScale.z);
}
else
{
miku.localScale = originalScale;
isSqueezing = false;
}
}
}
private void OnDestroy()
{
Item component = ((Component)this).GetComponent<Item>();
if ((Object)(object)component != (Object)null)
{
component.OnPrimaryStarted = (Action)Delegate.Remove(component.OnPrimaryStarted, new Action(RequestSqueeze));
}
if (squeezeCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(squeezeCoroutine);
}
if ((Object)(object)squeezeSource != (Object)null)
{
squeezeSource.Stop();
}
}
}
public static class MikuFumoAudio
{
public static AudioClip[] SqueezeSounds;
public static AudioClip[] PickupSounds;
public static float GetVoicePitch(GameObject target)
{
if ((Object)(object)target == (Object)null)
{
return 1f;
}
ItemCooking val = target.GetComponent<ItemCooking>();
if ((Object)(object)val == (Object)null)
{
val = target.GetComponentInChildren<ItemCooking>();
}
if ((Object)(object)val == (Object)null)
{
return 1f;
}
int timesCookedLocal = val.timesCookedLocal;
if (timesCookedLocal >= 4)
{
return 0.35f;
}
return timesCookedLocal switch
{
3 => 0.5f,
2 => 0.65f,
1 => 0.8f,
_ => 1f,
};
}
public static void PlayPickupSound(GameObject target)
{
if (PickupSounds == null || PickupSounds.Length == 0)
{
Debug.LogWarning((object)"[HatsuneMikuFumo] No pickup sounds loaded!");
return;
}
int soundIndex = Random.Range(0, PickupSounds.Length);
PlayPickupSound(target, soundIndex);
}
public static void PlayPickupSound(GameObject target, int soundIndex)
{
if ((Object)(object)target == (Object)null)
{
return;
}
if (PickupSounds == null || soundIndex < 0 || soundIndex >= PickupSounds.Length)
{
Debug.LogWarning((object)"[HatsuneMikuFumo] Invalid pickup sound index!");
return;
}
AudioClip val = PickupSounds[soundIndex];
if (!((Object)(object)val == (Object)null))
{
AudioSource val2 = target.GetComponent<AudioSource>();
if ((Object)(object)val2 == (Object)null)
{
val2 = target.AddComponent<AudioSource>();
}
val2.playOnAwake = false;
val2.spatialBlend = 1f;
val2.pitch = GetVoicePitch(target);
val2.PlayOneShot(val);
Debug.Log((object)("[HatsuneMikuFumo] Playing pickup sound: " + ((Object)val).name));
}
}
}
[HarmonyPatch]
public static class MikuFumoPickupPatch
{
[HarmonyTargetMethod]
private static MethodBase TargetMethod()
{
return AccessTools.Method(typeof(CharacterItems), "OnPickupAccepted", (Type[])null, (Type[])null);
}
private static void Postfix(CharacterItems __instance, byte slotID)
{
object? obj = AccessTools.Field(typeof(CharacterItems), "character")?.GetValue(__instance);
Character val = (Character)((obj is Character) ? obj : null);
if (!((Object)(object)val == (Object)null) && !((Object)(object)val.player == (Object)null))
{
ItemSlot itemSlot = val.player.GetItemSlot(slotID);
string text = ((itemSlot != null) ? itemSlot.GetPrefabName() : "");
Debug.Log((object)("[HatsuneMikuFumo] Pickup slot " + slotID + ", prefab: " + text));
}
}
}
[HarmonyPatch(typeof(CharacterItems), "EquipSlotRpc")]
public static class MikuFumoEquipPatch
{
private static void Postfix(CharacterItems __instance, int slotID)
{
if (slotID < 0)
{
return;
}
object? obj = AccessTools.Field(typeof(CharacterItems), "character")?.GetValue(__instance);
Character val = (Character)((obj is Character) ? obj : null);
if (!((Object)(object)val == (Object)null) && val.IsLocal && !((Object)(object)val.data.currentItem == (Object)null) && ((Object)((Component)val.data.currentItem).gameObject).name.Contains("MikuFumo"))
{
MikuFumoSqueeze component = ((Component)val.data.currentItem).GetComponent<MikuFumoSqueeze>();
if ((Object)(object)component != (Object)null)
{
component.RequestPickupSound();
}
}
}
}
[HarmonyPatch]
public static class MikuFumoPlaneSpawnPatch
{
private static bool spawned;
public static void ResetSpawnFlag()
{
spawned = false;
}
[HarmonyTargetMethod]
private static MethodBase TargetMethod()
{
return AccessTools.Method(AccessTools.TypeByName("SingleItemSpawner"), "TrySpawnItems", (Type[])null, (Type[])null);
}
private static void Postfix(object __instance)
{
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
if (!PhotonNetwork.IsMasterClient)
{
return;
}
object? obj = AccessTools.Field(__instance.GetType(), "prefab")?.GetValue(__instance);
GameObject val = (GameObject)((obj is GameObject) ? obj : null);
if ((Object)(object)val == (Object)null || ((Object)val).name != "BingBong" || spawned)
{
return;
}
spawned = true;
MonoBehaviour val2 = (MonoBehaviour)((__instance is MonoBehaviour) ? __instance : null);
if ((Object)(object)val2 == (Object)null)
{
return;
}
Vector3 val3 = default(Vector3);
((Vector3)(ref val3))..ctor(12.8f, 3.65f, -379.8f);
try
{
PhotonNetwork.InstantiateItemRoom("OvrSlepr.HatsuneMikuFumo:MikuFumo", val3, Quaternion.Euler(90f, 90f, 0f), true);
Debug.Log((object)"[HatsuneMikuFumo] Spawned Miku near BingBong!");
}
catch (Exception ex)
{
spawned = false;
Debug.LogError((object)("[HatsuneMikuFumo] Spawn failed: " + ex));
}
}
}
[HarmonyPatch]
public static class MikuFumoAirportSpawnPatch
{
private static bool spawned;
public static void ResetSpawnFlag()
{
spawned = false;
}
public static IEnumerator SpawnInAirport()
{
for (int i = 0; i < 30; i++)
{
yield return (object)new WaitForSeconds(1f);
if (!PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient)
{
continue;
}
GameObject chess = GameObject.Find("Chess");
if (!((Object)(object)chess == (Object)null))
{
if (spawned)
{
break;
}
spawned = true;
Vector3 position = new Vector3(2.3f, 1.5f, 87.74f);
try
{
PhotonNetwork.InstantiateItemRoom("OvrSlepr.HatsuneMikuFumo:MikuFumo", position, Quaternion.Euler(0f, 90f, 0f), true);
Debug.Log((object)"[HatsuneMikuFumo] Spawned Miku in airport!");
break;
}
catch (Exception ex)
{
spawned = false;
Debug.LogError((object)("[HatsuneMikuFumo] Airport spawn failed: " + ex));
break;
}
}
}
}
}
[HarmonyPatch(typeof(LootData), "PopulateLootData")]
public static class MikuFumoLuggageLootPatch
{
private const ushort MikuFumoItemID = 12671;
private const int TestWeight = 9;
private static readonly string[] AllowedPools = new string[9] { "LuggageBeach", "LuggageJungle", "LuggageRoots", "LuggageTundra", "LuggageMesa", "LuggageCaldera", "LuggageGloom", "LuggageCitadel", "LuggageClown" };
private static void Postfix()
{
//IL_0044: Unknown result type (might be due to invalid IL or missing references)
Dictionary<SpawnPool, Dictionary<ushort, int>> allSpawnWeightData = LootData.AllSpawnWeightData;
if (allSpawnWeightData == null)
{
Debug.LogError((object)"[HatsuneMikuFumo] Loot tables are not available!");
return;
}
string[] allowedPools = AllowedPools;
foreach (string text in allowedPools)
{
if (Enum.TryParse<SpawnPool>(text, out SpawnPool result) && allSpawnWeightData.TryGetValue(result, out var value) && value != null)
{
value[12671] = 9;
Debug.Log((object)("[HatsuneMikuFumo] Test loot weight set: " + text + " = " + 9));
}
}
}
}
namespace HatsuneMikuFumo
{
[BepInPlugin("OvrSlepr.HatsuneMikuFumo", "HatsuneMikuFumo", "1.0.0")]
public class MikuFumoToyPlugin : BaseUnityPlugin
{
private AssetBundle audioBundle;
private AudioClip[] pickupSounds;
private AudioClip[] squeezeSounds;
private readonly string[] squeezeSoundNames = new string[13]
{
"hatsune-miku-ameno", "kkkiaimen", "miku-ahhhhh", "miku-eats-lemon", "miku-godzilla", "miku-linggang-guli-guli", "miku-po-pi-po", "nonono", "miku-alarm-scary", "hello-miku",
"excuse me", "mikuudaayooo", "miku-oh-thank-you"
};
private readonly string[] pickupSoundNames = new string[2] { "pppp-miku", "hmm-hatsune-miku" };
private void Awake()
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Expected O, but got Unknown
SceneManager.sceneLoaded += OnSceneLoaded;
((BaseUnityPlugin)this).Logger.LogInfo((object)"HatsuneMikuFumo loaded!");
Harmony val = new Harmony("OvrSlepr.HatsuneMikuFumo");
val.PatchAll();
string text = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "mikufumo_audio");
audioBundle = AssetBundle.LoadFromFile(text);
if ((Object)(object)audioBundle == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogError((object)("Failed to load Miku audio bundle: " + text));
}
else
{
((BaseUnityPlugin)this).Logger.LogInfo((object)"Miku audio bundle loaded!");
pickupSounds = LoadAudioClips(pickupSoundNames);
squeezeSounds = LoadAudioClips(squeezeSoundNames);
MikuFumoAudio.PickupSounds = pickupSounds;
MikuFumoAudio.SqueezeSounds = squeezeSounds;
}
BundleLoader.LoadBundleWithName((BaseUnityPlugin)(object)this, "HatsuneMikuFumo.peakbundle", (Action<PeakBundle>)delegate(PeakBundle bundle)
{
//IL_009f: Unknown result type (might be due to invalid IL or missing references)
//IL_00a9: Expected O, but got Unknown
GameObject val2 = bundle.LoadAsset<GameObject>("assets/mikufumo/mikufumo.prefab");
if ((Object)(object)val2 == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogError((object)"MikuFumo prefab not found!");
}
else
{
Item component = val2.GetComponent<Item>();
if ((Object)(object)component == (Object)null)
{
((BaseUnityPlugin)this).Logger.LogError((object)"MikuFumo prefab has no Item component!");
}
else
{
component.UIData.hasMainInteract = true;
component.usingTimePrimary = 0f;
if ((Object)(object)val2.GetComponent<MikuFumoSqueeze>() == (Object)null)
{
val2.AddComponent<MikuFumoSqueeze>();
}
AddMikuFumoTranslations();
ModDefinition orCreate = ModDefinition.GetOrCreate(((BaseUnityPlugin)this).Info);
orCreate.Register<ItemContent>(new ItemContent(component));
((BaseUnityPlugin)this).Logger.LogInfo((object)("[HatsuneMikuFumo] Registered item ID: " + component.itemID));
((BaseUnityPlugin)this).Logger.LogInfo((object)"Miku Fumo registered!");
}
}
});
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
if ((Object)(object)audioBundle != (Object)null)
{
audioBundle.Unload(false);
}
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
MikuFumoPlaneSpawnPatch.ResetSpawnFlag();
MikuFumoAirportSpawnPatch.ResetSpawnFlag();
((BaseUnityPlugin)this).Logger.LogInfo((object)("[HatsuneMikuFumo] Spawn flag reset: " + ((Scene)(ref scene)).name));
((MonoBehaviour)this).StartCoroutine(MikuFumoAirportSpawnPatch.SpawnInAirport());
}
private AudioClip[] LoadAudioClips(string[] clipNames)
{
List<AudioClip> list = new List<AudioClip>();
foreach (string text in clipNames)
{
AudioClip val = audioBundle.LoadAsset<AudioClip>(text);
if ((Object)(object)val != (Object)null)
{
list.Add(val);
((BaseUnityPlugin)this).Logger.LogInfo((object)("Loaded audio clip: " + text));
}
else
{
((BaseUnityPlugin)this).Logger.LogError((object)("Failed to load audio clip: " + text));
}
}
return list.ToArray();
}
private void AddMikuFumoTranslations()
{
//IL_002b: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: 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_0034: 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_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_0057: Expected I4, but got Unknown
Language[] array = (Language[])Enum.GetValues(typeof(Language));
List<string> list = new List<string>();
Language[] array2 = array;
foreach (Language val in array2)
{
Language val2 = val;
Language val3 = val2;
switch (val3 - 7)
{
case 0:
list.Add("ФУМО ХАЦУНЭ МИКУ");
break;
case 1:
list.Add("ФУМО ХАЦУНЕ МІКУ");
break;
case 2:
list.Add("初音未来 FUMO");
break;
case 3:
list.Add("初音未來 FUMO");
break;
case 4:
list.Add("初音ミクふも");
break;
case 5:
list.Add("하츠네 미쿠 후모");
break;
default:
list.Add("HATSUNE MIKU FUMO");
break;
}
}
string key = LocalizedText.GetNameIndex("Miku Fumo").ToUpperInvariant();
if (LocalizedText.mainTable.ContainsKey(key))
{
LocalizedText.mainTable[key] = list;
}
else
{
LocalizedText.mainTable.Add(key, list);
}
((BaseUnityPlugin)this).Logger.LogInfo((object)"HatsuneMikuFumo translations added for all languages!");
}
}
}