using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using GameNetcodeStuff;
using HarmonyLib;
using LethalLib;
using LethalLib.Modules;
using LethalUIIAmod;
using LethalUIIAmod.Behaviors;
using Microsoft.CodeAnalysis;
using Unity.Collections;
using Unity.Netcode;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("LethalUIIAmod")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("LethalUIIAcat")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("97aae1ef-8b14-4aad-a467-877c269c77c8")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
[BepInPlugin("com.Snow.UIIAcat", "Lethal UIIA Cat", "2.0.0")]
public class UIIAscrap : BaseUnityPlugin
{
public static UIIAscrap instance;
internal static UIIAConfig BoundConfig { get; private set; }
private void Awake()
{
//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00db: Unknown result type (might be due to invalid IL or missing references)
instance = this;
BoundConfig = new UIIAConfig(((BaseUnityPlugin)this).Config);
if (BoundConfig.AutoPlay.Value)
{
((BaseUnityPlugin)this).Logger.LogInfo((object)BoundConfig.Volume.Value);
}
string text = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "uiia_cat");
AssetBundle val = AssetBundle.LoadFromFile(text);
string text2 = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "audiobundle");
AssetBundle val2 = AssetBundle.LoadFromFile(text2);
Item val3 = val.LoadAsset<Item>("Assets/- UIIAcat/UIIA_Item.asset");
UIIABehavior uIIABehavior = val3.spawnPrefab.AddComponent<UIIABehavior>();
val3.rotationOffset = new Vector3(90f, 0f, -90f);
val3.positionOffset = new Vector3(0f, 0.2f, -0.15f);
val3.canBeGrabbedBeforeGameStart = true;
((GrabbableObject)uIIABehavior).grabbable = true;
((GrabbableObject)uIIABehavior).grabbableToEnemies = true;
((GrabbableObject)uIIABehavior).itemProperties = val3;
uIIABehavior.ItemAudioClip[0] = val2.LoadAsset<AudioClip>("Assets/- UIIAcat/Audio/After_Dark.mp3");
uIIABehavior.ItemAudioClip[1] = val2.LoadAsset<AudioClip>("Assets/- UIIAcat/Audio/Right_Now.mp3");
uIIABehavior.ItemAudioClip[2] = val2.LoadAsset<AudioClip>("Assets/- UIIAcat/Audio/Sigma_Boy.mp3");
uIIABehavior.ItemAudioClip[3] = val2.LoadAsset<AudioClip>("Assets/- UIIAcat/Audio/Sugar2.mp3");
NetworkPrefabs.RegisterNetworkPrefab(val3.spawnPrefab);
Utilities.FixMixerGroups(val3.spawnPrefab);
Items.RegisterScrap(val3, 14, (LevelTypes)(-1));
}
}
namespace LethalUIIAmod
{
[Serializable]
public class UIIAConfig : UIIASyncedInstance<UIIAConfig>
{
[CompilerGenerated]
private static class <>O
{
public static HandleNamedMessageDelegate <0>__OnRequestSync;
public static HandleNamedMessageDelegate <1>__OnReceiveSync;
}
public readonly ConfigEntry<float> Volume;
public readonly ConfigEntry<bool> AutoPlay;
public UIIAConfig(ConfigFile cfg)
{
InitInstance(this);
cfg.SaveOnConfigSet = false;
Volume = cfg.Bind<float>("General", "Audio Volume", 1f, "Volume of the music played by the cat.");
AutoPlay = cfg.Bind<bool>("Toggles", "Autoplay", true, "Plays music at random intervals when not Gathered by player YET...");
ClearOrphanedEntries(cfg);
cfg.Save();
cfg.SaveOnConfigSet = true;
}
private static void ClearOrphanedEntries(ConfigFile cfg)
{
PropertyInfo propertyInfo = AccessTools.Property(typeof(ConfigFile), "OrphanedEntries");
Dictionary<ConfigDefinition, string> dictionary = (Dictionary<ConfigDefinition, string>)propertyInfo.GetValue(cfg);
dictionary.Clear();
}
public static void RequestSync()
{
//IL_0029: Unknown result type (might be due to invalid IL or missing references)
if (!UIIASyncedInstance<UIIAConfig>.IsClient)
{
return;
}
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(UIIASyncedInstance<UIIAConfig>.IntSize, (Allocator)2, -1);
try
{
UIIASyncedInstance<UIIAConfig>.MessageManager.SendNamedMessage("ModName_OnRequestConfigSync", 0uL, val, (NetworkDelivery)3);
}
finally
{
((IDisposable)(FastBufferWriter)(ref val)).Dispose();
}
}
public static void OnRequestSync(ulong clientId, FastBufferReader _)
{
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
if (!UIIASyncedInstance<UIIAConfig>.IsHost)
{
return;
}
Plugin.logger.LogInfo((object)$"Config sync request received from client: {clientId}");
byte[] array = UIIASyncedInstance<UIIAConfig>.SerializeToBytes(UIIASyncedInstance<UIIAConfig>.Instance);
int num = array.Length;
int num2 = FastBufferWriter.GetWriteSize<byte>(array, -1, 0) + UIIASyncedInstance<UIIAConfig>.IntSize;
FastBufferWriter val = default(FastBufferWriter);
((FastBufferWriter)(ref val))..ctor(num2, (Allocator)2, -1);
try
{
((FastBufferWriter)(ref val)).WriteValueSafe<int>(ref num, default(ForPrimitives));
((FastBufferWriter)(ref val)).WriteBytesSafe(array, -1, 0);
UIIASyncedInstance<UIIAConfig>.MessageManager.SendNamedMessage("ModName_OnReceiveConfigSync", clientId, val, (NetworkDelivery)3);
}
catch (Exception arg)
{
Plugin.logger.LogInfo((object)$"Error occurred syncing config with client: {clientId}\n{arg}");
}
finally
{
((IDisposable)(FastBufferWriter)(ref val)).Dispose();
}
}
public static void OnReceiveSync(ulong _, FastBufferReader reader)
{
//IL_002d: 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)
if (!((FastBufferReader)(ref reader)).TryBeginRead(UIIASyncedInstance<UIIAConfig>.IntSize))
{
Plugin.logger.LogError((object)"Config sync error: Could not begin reading buffer.");
return;
}
int num = default(int);
((FastBufferReader)(ref reader)).ReadValueSafe<int>(ref num, default(ForPrimitives));
if (!((FastBufferReader)(ref reader)).TryBeginRead(num))
{
Plugin.logger.LogError((object)"Config sync error: Host could not sync.");
return;
}
byte[] data = new byte[num];
((FastBufferReader)(ref reader)).ReadBytesSafe(ref data, num, 0);
UIIASyncedInstance<UIIAConfig>.SyncInstance(data);
Plugin.logger.LogInfo((object)"Successfully synced config with host.");
}
[HarmonyPostfix]
[HarmonyPatch(typeof(PlayerControllerB), "ConnectClientToPlayerObject")]
public static void InitializeLocalPlayer()
{
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_006b: Expected O, but got Unknown
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
if (UIIASyncedInstance<UIIAConfig>.IsHost)
{
CustomMessagingManager messageManager = UIIASyncedInstance<UIIAConfig>.MessageManager;
object obj = <>O.<0>__OnRequestSync;
if (obj == null)
{
HandleNamedMessageDelegate val = OnRequestSync;
<>O.<0>__OnRequestSync = val;
obj = (object)val;
}
messageManager.RegisterNamedMessageHandler("Lethal OIIA Cat_OnRequestConfigSync", (HandleNamedMessageDelegate)obj);
UIIASyncedInstance<UIIAConfig>.Synced = true;
return;
}
UIIASyncedInstance<UIIAConfig>.Synced = false;
CustomMessagingManager messageManager2 = UIIASyncedInstance<UIIAConfig>.MessageManager;
object obj2 = <>O.<1>__OnReceiveSync;
if (obj2 == null)
{
HandleNamedMessageDelegate val2 = OnReceiveSync;
<>O.<1>__OnReceiveSync = val2;
obj2 = (object)val2;
}
messageManager2.RegisterNamedMessageHandler("Lethal OIIA Cat_OnReceiveConfigSync", (HandleNamedMessageDelegate)obj2);
RequestSync();
}
[HarmonyPostfix]
[HarmonyPatch(typeof(GameNetworkManager), "StartDisconnect")]
public static void PlayerLeave()
{
UIIASyncedInstance<UIIAConfig>.RevertSync();
}
}
[Serializable]
public class UIIASyncedInstance<T>
{
[NonSerialized]
protected static int IntSize = 4;
internal static CustomMessagingManager MessageManager => NetworkManager.Singleton.CustomMessagingManager;
internal static bool IsClient => NetworkManager.Singleton.IsClient;
internal static bool IsHost => NetworkManager.Singleton.IsHost;
public static T Default { get; private set; }
public static T Instance { get; private set; }
public static bool Synced { get; internal set; }
protected void InitInstance(T instance)
{
Default = instance;
Instance = instance;
IntSize = 4;
}
internal static void SyncInstance(byte[] data)
{
Instance = DeserializeFromBytes(data);
Synced = true;
}
internal static void RevertSync()
{
Instance = Default;
Synced = false;
}
public static byte[] SerializeToBytes(T val)
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
using MemoryStream memoryStream = new MemoryStream();
try
{
binaryFormatter.Serialize(memoryStream, val);
return memoryStream.ToArray();
}
catch (Exception arg)
{
Plugin.logger.LogError((object)$"Error serializing instance: {arg}");
return null;
}
}
public static T DeserializeFromBytes(byte[] data)
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
using MemoryStream serializationStream = new MemoryStream(data);
try
{
return (T)binaryFormatter.Deserialize(serializationStream);
}
catch (Exception arg)
{
Plugin.logger.LogError((object)$"Error deserializing instance: {arg}");
return default(T);
}
}
}
}
namespace LethalUIIAmod.Behaviors
{
internal class UIIABehavior : PhysicsProp
{
public Animator ItemAnimator;
public AudioSource ItemAudioSrc;
public AudioClip[] ItemAudioClip = (AudioClip[])(object)new AudioClip[5];
public float AnimationTime = 0f;
public float AutoPlayCooldown = -1f;
public int song = 0;
public bool FRESH = true;
public bool Autoplay = true;
public bool Animating = false;
public override void ItemActivate(bool used, bool buttonDown = true)
{
((GrabbableObject)this).ItemActivate(used, buttonDown);
if (!Animating)
{
song = Random.Range(0, 4);
ItemAudioSrc.clip = ItemAudioClip[song];
AnimationTime = ItemAudioSrc.clip.length;
ItemAudioSrc.Play();
Debug.Log((object)("uiia rolled a " + song));
if (song == 0)
{
ItemAnimator.SetBool("AfterDark_M", true);
}
if (song == 1)
{
ItemAnimator.SetBool("Right_Now", true);
}
if (song == 2)
{
ItemAnimator.SetBool("Sigma_Boy", true);
}
if (song == 3)
{
ItemAnimator.SetBool("Sugar", true);
}
CheckNearby(stop: false);
}
if (Animating)
{
STOP();
CheckNearby(stop: true);
}
}
private void CheckNearby(bool stop)
{
//IL_0007: 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_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
RaycastHit[] array = Physics.SphereCastAll(((Component)this).transform.position, 5f, ((Component)this).transform.forward, 0f);
RaycastHit[] array2 = array;
for (int i = 0; i < array2.Length; i++)
{
RaycastHit val = array2[i];
if (((Object)((Component)((RaycastHit)(ref val)).collider).gameObject).name == "UIIA_cat(Clone)")
{
if (stop)
{
((Component)((RaycastHit)(ref val)).collider).gameObject.GetComponent<UIIABehavior>().STOP();
}
else
{
((Component)((RaycastHit)(ref val)).collider).gameObject.GetComponent<UIIABehavior>().GetCheck(song);
}
}
}
}
public void GetCheck(int clip)
{
ItemAudioSrc.clip = ItemAudioClip[clip];
AnimationTime = ItemAudioSrc.clip.length;
if (clip == 0)
{
ItemAnimator.SetBool("AfterDark_F", true);
}
if (clip == 1)
{
ItemAnimator.SetBool("Right_Now", true);
}
if (clip == 2)
{
ItemAnimator.SetBool("Sigma_Boy", true);
}
if (clip == 3)
{
ItemAnimator.SetBool("Sugar", true);
}
}
public void STOP()
{
ItemAnimator.SetBool("Spinning", false);
ItemAnimator.SetBool("AfterDark_M", false);
ItemAnimator.SetBool("AfterDark_F", false);
ItemAnimator.SetBool("Sigma_Boy", false);
ItemAnimator.SetBool("Right_Now", false);
ItemAnimator.SetBool("Sugar", false);
ItemAudioSrc.Stop();
ItemAudioSrc.clip = null;
Animating = false;
AnimationTime = -1f;
}
public void Awake()
{
AutoPlayCooldown = 30f;
ItemAnimator = ((Component)this).gameObject.GetComponent<Animator>();
ItemAudioSrc = ((Component)this).gameObject.GetComponent<AudioSource>();
ItemAudioSrc.playOnAwake = false;
((Behaviour)ItemAudioSrc).enabled = true;
ItemAudioSrc.minDistance = 1f;
ItemAudioSrc.maxDistance = 60f;
Autoplay = UIIASyncedInstance<UIIAConfig>.Instance.AutoPlay.Value;
ItemAudioSrc.volume = UIIASyncedInstance<UIIAConfig>.Instance.Volume.Value;
}
public override void Update()
{
((GrabbableObject)this).Update();
if (AutoPlayCooldown >= 0f)
{
AutoPlayCooldown -= Time.deltaTime;
}
if (AnimationTime > 0f)
{
AnimationTime -= Time.deltaTime;
Animating = true;
}
if (Animating && AnimationTime < ItemAudioSrc.clip.length / 2f && AnimationTime > 0f)
{
ItemAnimator.SetBool("Spinning", true);
}
if (AnimationTime < 0f)
{
STOP();
}
if (FRESH && Autoplay && AutoPlayCooldown < 0f)
{
((GrabbableObject)this).ItemActivate(true, true);
AutoPlayCooldown = ItemAudioSrc.clip.length + (float)Random.Range(30, 90);
}
}
public override void GrabItem()
{
((GrabbableObject)this).GrabItem();
FRESH = false;
}
public override int GetItemDataToSave()
{
if (FRESH)
{
return 1;
}
return 0;
}
public override void LoadItemSaveData(int saveData)
{
if (saveData == 0)
{
FRESH = false;
}
else
{
FRESH = true;
}
}
}
}