using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
using UnityEngine.Networking;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("TheLooker")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("TheLooker")]
[assembly: AssemblyTitle("TheLooker")]
[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;
}
}
}
namespace TheLooker
{
public class ModConfig
{
public readonly ConfigEntry<float> SFXVolume;
public readonly ConfigEntry<float> SFXRange;
public readonly ConfigEntry<float> SFXSpatialBlend;
public readonly ConfigEntry<float> MinRepeatGap;
public readonly ConfigEntry<bool> DebugLogging;
public readonly ConfigEntry<float> LookerFrequency;
public ModConfig(ConfigFile cfg)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Expected O, but got Unknown
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_007a: Expected O, but got Unknown
//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
//IL_00b3: Expected O, but got Unknown
//IL_00e2: Unknown result type (might be due to invalid IL or missing references)
//IL_00ec: Expected O, but got Unknown
//IL_0137: Unknown result type (might be due to invalid IL or missing references)
//IL_0141: Expected O, but got Unknown
cfg.SaveOnConfigSet = false;
SFXVolume = cfg.Bind<float>("General", "Looker Volume", 1f, new ConfigDescription("Volume of the looker sound.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
SFXRange = cfg.Bind<float>("General", "Looker Sound Range", 150f, new ConfigDescription("Maximum distance the looker sound can be heard from.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 250f), Array.Empty<object>()));
SFXSpatialBlend = cfg.Bind<float>("General", "Spatial Blend", 0.95f, new ConfigDescription("How 3D the sound is. 0 = heard equally everywhere, 1 = full positional audio.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
MinRepeatGap = cfg.Bind<float>("General", "Min Repeat Gap", 3f, new ConfigDescription("Minimum seconds before the same looker can trigger the sound again.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 20f), Array.Empty<object>()));
DebugLogging = cfg.Bind<bool>("Debug", "Debug Logging", false, "Enable extra log messages.");
LookerFrequency = cfg.Bind<float>("General", "Looker Frequency", 0.25f, new ConfigDescription("Controls how often Lookers are active. 0 = vanilla (~1 per group), 1 = all active. Requires a new game/area load to take effect.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
ClearOrphanedEntries(cfg);
cfg.Save();
cfg.SaveOnConfigSet = true;
}
private static void ClearOrphanedEntries(ConfigFile cfg)
{
((Dictionary<ConfigDefinition, string>)AccessTools.Property(typeof(ConfigFile), "OrphanedEntries").GetValue(cfg)).Clear();
}
}
[HarmonyPatch(typeof(Looker), "RPCA_Switch")]
public static class PatchLookerSwitch
{
[CompilerGenerated]
private sealed class <PlayAfterDelay>d__2 : IEnumerator<object>, IEnumerator, IDisposable
{
private int <>1__state;
private object <>2__current;
public Transform pivot;
public int id;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <PlayAfterDelay>d__2(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0027: Expected O, but got Unknown
//IL_00b9: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
if ((Object)(object)pivot == (Object)null || (Object)(object)Plugin.TheLooker == (Object)null)
{
return false;
}
Plugin.TheLooker.settings.volume = Plugin.BoundConfig.SFXVolume.Value;
Plugin.TheLooker.settings.range = Plugin.BoundConfig.SFXRange.Value;
Plugin.TheLooker.settings.spatialBlend = Plugin.BoundConfig.SFXSpatialBlend.Value;
Plugin.TheLooker.Play(pivot.position);
if (Plugin.BoundConfig.DebugLogging.Value)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogInfo((object)$"Looker popped up — sound triggered for instance {id}");
}
}
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static readonly Dictionary<int, float> lastPlayTime = new Dictionary<int, float>();
private static void Postfix(Looker __instance, bool switchTo)
{
try
{
if (!switchTo || (Object)(object)Plugin.TheLooker == (Object)null || Plugin.TheLooker.clips == null || Plugin.TheLooker.clips.Length == 0 || Traverse.Create((object)__instance).Field<bool>("neverReturn").Value)
{
return;
}
Transform val = ((Component)__instance).transform.Find("Pivot");
if (!((Object)(object)val == (Object)null))
{
int instanceID = ((Object)__instance).GetInstanceID();
float time = Time.time;
float value;
float num = (lastPlayTime.TryGetValue(instanceID, out value) ? value : (-999f));
if (time - num >= Plugin.BoundConfig.MinRepeatGap.Value)
{
lastPlayTime[instanceID] = time;
((MonoBehaviour)Plugin.Instance).StartCoroutine(PlayAfterDelay(val, instanceID));
}
}
}
catch (Exception arg)
{
ManualLogSource log = Plugin.Log;
if (log != null)
{
log.LogError((object)$"TheLooker patch error: {arg}");
}
}
}
[IteratorStateMachine(typeof(<PlayAfterDelay>d__2))]
private static IEnumerator PlayAfterDelay(Transform pivot, int id)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <PlayAfterDelay>d__2(0)
{
pivot = pivot,
id = id
};
}
}
[HarmonyPatch(typeof(Looker), "ToggleLookers")]
public static class PatchToggleLookers
{
private static bool Prefix(Looker __instance)
{
float value = Plugin.BoundConfig.LookerFrequency.Value;
if (value <= 0f)
{
return true;
}
Looker[] componentsInChildren = ((Component)((Component)__instance).transform.parent).GetComponentsInChildren<Looker>();
foreach (Looker val in componentsInChildren)
{
if (Random.value > value)
{
((Component)val).GetComponent<PhotonView>().RPC("RPCA_DisableLooker", (RpcTarget)0, Array.Empty<object>());
}
}
return false;
}
}
[BepInPlugin("TheLooker", "TheLooker", "1.0.1")]
public class Plugin : BaseUnityPlugin
{
public const string Id = "TheLooker";
internal static SFX_Instance TheLooker;
private readonly Harmony harmony = new Harmony("TheLooker");
private const int SFXLimit = 10;
internal static ManualLogSource Log { get; private set; }
internal static Plugin Instance { get; private set; }
internal static ModConfig BoundConfig { get; private set; }
private void Awake()
{
if ((Object)(object)Instance != (Object)null && (Object)(object)Instance != (Object)(object)this)
{
Object.Destroy((Object)(object)this);
return;
}
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
BoundConfig = new ModConfig(((BaseUnityPlugin)this).Config);
LoadTheLooker();
harmony.PatchAll();
Log.LogInfo((object)"TheLooker loaded.");
}
private void LoadTheLooker()
{
//IL_0121: Unknown result type (might be due to invalid IL or missing references)
//IL_0126: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0150: Unknown result type (might be due to invalid IL or missing references)
//IL_016a: Expected O, but got Unknown
string directoryName = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
List<string> list = Directory.GetFiles(directoryName, "*.wav").Take(10).ToList();
if (list.Count == 0)
{
Log.LogWarning((object)("No .wav files found in " + directoryName));
return;
}
List<AudioClip> list2 = new List<AudioClip>();
foreach (string item in list)
{
try
{
AudioClip val = LoadAudioClip(item);
if ((Object)(object)val != (Object)null)
{
list2.Add(val);
if (BoundConfig.DebugLogging.Value)
{
Log.LogInfo((object)("Loaded looker clip: " + Path.GetFileName(item)));
}
}
}
catch (Exception ex)
{
Log.LogError((object)("Failed to load sound file " + item + ": " + ex.Message));
}
}
if (list2.Count == 0)
{
Log.LogError((object)"No looker audio clips were loaded.");
return;
}
TheLooker = ScriptableObject.CreateInstance<SFX_Instance>();
TheLooker.clips = list2.ToArray();
TheLooker.settings = new SFX_Settings
{
volume = BoundConfig.SFXVolume.Value,
range = BoundConfig.SFXRange.Value,
spatialBlend = BoundConfig.SFXSpatialBlend.Value
};
Log.LogInfo((object)$"Created looker SFX with {list2.Count} clip(s).");
}
private AudioClip LoadAudioClip(string filePath)
{
//IL_0023: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Invalid comparison between Unknown and I4
//IL_002c: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Invalid comparison between Unknown and I4
UnityWebRequest audioClip = UnityWebRequestMultimedia.GetAudioClip(new Uri(filePath).AbsoluteUri, (AudioType)20);
try
{
UnityWebRequestAsyncOperation val = audioClip.SendWebRequest();
while (!((AsyncOperation)val).isDone)
{
}
if ((int)audioClip.result == 2 || (int)audioClip.result == 3)
{
Log.LogError((object)("Error loading " + filePath + ": " + audioClip.error));
return null;
}
return DownloadHandlerAudioClip.GetContent(audioClip);
}
finally
{
((IDisposable)audioClip)?.Dispose();
}
}
}
}