using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Unity.IL2CPP;
using BigMenu;
using Dissonance;
using Dissonance.Audio.Capture;
using Dissonance.Config;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using Il2CppInterop.Runtime.InteropTypes;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Mirror;
using TMPro;
using UnityEngine;
using UnityEngine.Audio;
using UnityEngine.EventSystems;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("BigCamera")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("BigCamera")]
[assembly: AssemblyTitle("BigCamera")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[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 BigCamera
{
internal static class BigMenuHook
{
private static readonly string[] NoiseLevels = new string[5] { "OFF", "LOW", "MODERATE", "HIGH", "VERY HIGH" };
private static readonly string[] EchoLevels = new string[4] { "OFF", "LOW", "MODERATE", "HIGH" };
private static string[] Mics()
{
return new string[1] { "Game's mic" }.Concat((IEnumerable<string>)Microphone.devices).ToArray();
}
public static void Register()
{
BigMenuApi.Register("Big Camera").AddToggle("VOICE LOOPBACK", (Func<bool>)(() => MicVoice.LoopbackOn), (Action<bool>)delegate(bool v)
{
MicVoice.LoopbackOn = v;
}).AddChoice("LOOPBACK MIC", (Func<string[]>)Mics, (Func<int>)(() => Math.Max(0, Array.IndexOf(Mics(), Plugin.MicName.Value))), (Action<int>)delegate(int i)
{
Plugin.Set(Plugin.MicName, (i == 0) ? "" : Mics()[i]);
MicVoice.RestartCapture();
})
.AddChoice("LOOPBACK OUTPUT", MicVoice.Routes, (Func<int>)(() => Math.Max(0, Array.IndexOf(MicVoice.Routes, Plugin.LoopbackRoute.Value))), (Action<int>)delegate(int i)
{
Plugin.Set(Plugin.LoopbackRoute, MicVoice.Routes[i]);
MicVoice.RecreateSource();
})
.AddToggle("3D LOOPBACK", (Func<bool>)(() => Plugin.Loopback3D.Value), (Action<bool>)delegate(bool v)
{
Plugin.Set(Plugin.Loopback3D, v);
MicVoice.RecreateSource();
})
.AddChoice("NOISE REDUCTION", NoiseLevels, (Func<int>)(() => VoiceSettings.Instance.DenoiseAmount + 1), (Action<int>)delegate(int i)
{
VoiceSettings.Instance.DenoiseAmount = (NoiseSuppressionLevels)(i - 1);
})
.AddChoice("ECHO REDUCTION", EchoLevels, (Func<int>)(() => VoiceSettings.Instance.AecSuppressionAmount + 1), (Action<int>)delegate(int i)
{
VoiceSettings.Instance.AecSuppressionAmount = (AecSuppressionLevels)(i - 1);
})
.AddToggle("BACKGROUND SOUND REMOVAL", (Func<bool>)(() => VoiceSettings.Instance.BackgroundSoundRemovalEnabled), (Action<bool>)delegate(bool v)
{
VoiceSettings.Instance.BackgroundSoundRemovalEnabled = v;
})
.AddSlider("MOUTH MULTIPLIER", 0f, 10f, 0.1f, (Func<float>)(() => Plugin.MouthGain.Value), (Action<float>)delegate(float v)
{
Plugin.Set(Plugin.MouthGain, v);
}, "0.0", "x")
.AddSlider("LOOPBACK VOLUME", 0f, 200f, 5f, (Func<float>)(() => Plugin.LoopbackVolume.Value * 100f), (Action<float>)delegate(float v)
{
Plugin.Set(Plugin.LoopbackVolume, v / 100f);
}, "0", "%");
}
}
public class CameraLocker : MonoBehaviour
{
private bool locked;
private Vector3 pos;
private Quaternion rot;
private Vector3 savedLocalPos;
private Quaternion savedLocalRot;
public CameraLocker(IntPtr ptr)
: base(ptr)
{
}
private void Update()
{
//IL_0081: Unknown result type (might be due to invalid IL or missing references)
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_0051: Unknown result type (might be due to invalid IL or missing references)
//IL_005d: Unknown result type (might be due to invalid IL or missing references)
//IL_0062: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: 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)
if (!Input.GetKeyDown((KeyCode)288))
{
return;
}
Camera main = Camera.main;
if (!((Object)(object)main == (Object)null))
{
locked = !locked;
if (locked)
{
savedLocalPos = ((Component)main).transform.localPosition;
savedLocalRot = ((Component)main).transform.localRotation;
pos = ((Component)main).transform.position;
rot = ((Component)main).transform.rotation;
}
else
{
((Component)main).transform.localPosition = savedLocalPos;
((Component)main).transform.localRotation = savedLocalRot;
}
SetBodyMode(locked);
MicVoice.CameraActive = locked;
}
}
private void LateUpdate()
{
//IL_001f: 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)
if (locked)
{
Camera main = Camera.main;
if ((Object)(object)main != (Object)null)
{
((Component)main).transform.SetPositionAndRotation(pos, rot);
}
}
}
private static void SetBodyMode(bool remote)
{
foreach (PlayerCharacter item in Object.FindObjectsOfType<PlayerCharacter>())
{
if (((NetworkBehaviour)item).isLocalPlayer && item.looks != null)
{
if (remote)
{
item.looks.SetBodyToRemoteMode();
}
else
{
item.looks.SetBodyToLocalMode();
}
}
}
}
}
internal static class MenuSettings
{
private sealed class Item
{
public string Title;
public SettingsType Type;
public Func<bool> GetOn;
public Action<bool> SetOn;
public Func<string[]> Options;
public Func<int> GetIndex;
public Action<int> SetIndex;
public float Min;
public float Max;
public float Step;
public Func<float> Get;
public Action<float> Set;
public string Format;
public string Suffix;
public int Steps => (int)Math.Round((Max - Min) / Step);
public int ToStep(float v)
{
return Mathf.Clamp((int)Math.Round((v - Min) / Step), 0, Steps);
}
}
private sealed class Pager
{
public SettingsCatagory Category;
public SettingsRow PageRow;
public SettingsRow[] Rows;
public Vector3[] Positions;
public int PerPage;
public int Page;
public int Pages => (Rows.Length + PerPage - 1) / PerPage;
}
private const SettingsType ToggleRow = (SettingsType)201;
private const SettingsType ChoiceRow = (SettingsType)202;
private const SettingsType SliderRow = (SettingsType)203;
private const SettingsType PageType = (SettingsType)204;
private static readonly MethodInfo SwapToCategoryMethod = AccessTools.Method(typeof(SettingsMenu), "SwapToCatagory", (Type[])null, (Type[])null);
private static readonly Dictionary<int, Item> items = new Dictionary<int, Item>();
private static bool configuringSlider;
private static readonly string[] NoiseLevels = new string[5] { "OFF", "LOW", "MODERATE", "HIGH", "VERY HIGH" };
private static readonly string[] EchoLevels = new string[4] { "OFF", "LOW", "MODERATE", "HIGH" };
private static readonly Dictionary<int, Pager> pagers = new Dictionary<int, Pager>();
private static string[] Mics()
{
return new string[1] { "Game's mic" }.Concat((IEnumerable<string>)Microphone.devices).ToArray();
}
private static Item Toggle(string title, Func<bool> get, Action<bool> set)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
return new Item
{
Title = title,
Type = (SettingsType)201,
GetOn = get,
SetOn = set
};
}
private static Item Choice(string title, Func<string[]> options, Func<int> get, Action<int> set)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
return new Item
{
Title = title,
Type = (SettingsType)202,
Options = options,
GetIndex = get,
SetIndex = set
};
}
private static Item Slider(string title, float min, float max, float step, Func<float> get, Action<float> set, string format, string suffix)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
return new Item
{
Title = title,
Type = (SettingsType)203,
Min = min,
Max = max,
Step = step,
Get = get,
Set = set,
Format = format,
Suffix = suffix
};
}
private static List<Item> Definitions()
{
return new List<Item>
{
Toggle("VOICE LOOPBACK", () => MicVoice.LoopbackOn, delegate(bool v)
{
MicVoice.LoopbackOn = v;
}),
Choice("LOOPBACK MIC", Mics, () => Math.Max(0, Array.IndexOf(Mics(), Plugin.MicName.Value)), delegate(int i)
{
Plugin.Set(Plugin.MicName, (i == 0) ? "" : Mics()[i]);
MicVoice.RestartCapture();
}),
Choice("LOOPBACK OUTPUT", () => MicVoice.Routes, () => Math.Max(0, Array.IndexOf(MicVoice.Routes, Plugin.LoopbackRoute.Value)), delegate(int i)
{
Plugin.Set(Plugin.LoopbackRoute, MicVoice.Routes[i]);
MicVoice.RecreateSource();
}),
Toggle("3D LOOPBACK", () => Plugin.Loopback3D.Value, delegate(bool v)
{
Plugin.Set(Plugin.Loopback3D, v);
MicVoice.RecreateSource();
}),
Choice("NOISE REDUCTION", () => NoiseLevels, () => VoiceSettings.Instance.DenoiseAmount + 1, delegate(int i)
{
VoiceSettings.Instance.DenoiseAmount = (NoiseSuppressionLevels)(i - 1);
}),
Choice("ECHO REDUCTION", () => EchoLevels, () => VoiceSettings.Instance.AecSuppressionAmount + 1, delegate(int i)
{
VoiceSettings.Instance.AecSuppressionAmount = (AecSuppressionLevels)(i - 1);
}),
Toggle("BACKGROUND SOUND REMOVAL", () => VoiceSettings.Instance.BackgroundSoundRemovalEnabled, delegate(bool v)
{
VoiceSettings.Instance.BackgroundSoundRemovalEnabled = v;
}),
Slider("MOUTH MULTIPLIER", 0f, 10f, 0.1f, () => Plugin.MouthGain.Value, delegate(float v)
{
Plugin.Set(Plugin.MouthGain, v);
}, "0.0", "x"),
Slider("LOOPBACK VOLUME", 0f, 200f, 5f, () => Plugin.LoopbackVolume.Value * 100f, delegate(float v)
{
Plugin.Set(Plugin.LoopbackVolume, v / 100f);
}, "0", "%")
};
}
private static bool IsOurs(SettingsRow row)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: Invalid comparison between Unknown and I4
//IL_000e: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Invalid comparison between Unknown and I4
if ((int)row.settingsType >= 201)
{
return (int)row.settingsType <= 204;
}
return false;
}
internal static void Install(Harmony harmony)
{
Patch(harmony, typeof(MainMenuManager), "Awake", "AddMainMenuCategory", postfix: true);
Patch(harmony, typeof(WorldMenuManager), "Awake", "AddPauseMenuCategory", postfix: true);
Patch(harmony, typeof(SettingsRow), "Start", "StartRow", postfix: false);
Patch(harmony, typeof(SettingsRow), "OnEnable", "EnableRow", postfix: false);
Patch(harmony, typeof(SettingsRow), "Refresh", "RefreshRow", postfix: false);
Patch(harmony, typeof(SettingsRow), "ActionCycle", "CycleRow", postfix: false);
Patch(harmony, typeof(SettingsRow), "ActionSelect", "SelectRow", postfix: false);
Patch(harmony, typeof(SettingsRow), "ActionNavigate", "NavigateRow", postfix: false);
Patch(harmony, typeof(SettingsRow), "ActionSetFromSlider", "SetSliderRow", postfix: false);
Patch(harmony, typeof(SettingsRow), "ActionBack", "BackFromRow", postfix: false);
}
private static void Patch(Harmony harmony, Type type, string method, string handler, bool postfix)
{
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0012: Expected O, but got Unknown
HarmonyMethod val = new HarmonyMethod(typeof(MenuSettings), handler, (Type[])null);
MethodInfo methodInfo = AccessTools.Method(type, method, (Type[])null, (Type[])null);
if (postfix)
{
harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
else
{
harmony.Patch((MethodBase)methodInfo, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
}
}
private static void AddMainMenuCategory(MainMenuManager __instance)
{
AddCategory(__instance.settingsMenu);
}
private static void AddPauseMenuCategory(WorldMenuManager __instance)
{
AddCategory(__instance.settingsMenu);
}
private static void ShowPage(Pager pager, int page)
{
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
pager.Page = Mathf.Clamp(page, 0, pager.Pages - 1);
List<SettingsRow> list = new List<SettingsRow>();
if ((Object)(object)pager.PageRow != (Object)null)
{
list.Add(pager.PageRow);
}
int num = pager.Page * pager.PerPage;
for (int i = 0; i < pager.Rows.Length; i++)
{
bool flag = i >= num && i < num + pager.PerPage;
((Component)pager.Rows[i]).gameObject.SetActive(flag);
if (flag)
{
list.Add(pager.Rows[i]);
}
}
for (int j = 0; j < list.Count; j++)
{
((Component)list[j]).transform.localPosition = pager.Positions[j];
list[j].SetNavigation((j == 0) ? null : list[j - 1], (j == list.Count - 1) ? null : list[j + 1]);
Refresh(list[j]);
}
pager.Category.rows = new Il2CppReferenceArray<SettingsRow>(list.ToArray());
}
private static void AddCategory(SettingsMenu menu)
{
//IL_013a: 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_01a7: Unknown result type (might be due to invalid IL or missing references)
//IL_01b1: Invalid comparison between Unknown and I4
//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
//IL_01bf: Invalid comparison between Unknown and I4
//IL_01e1: Unknown result type (might be due to invalid IL or missing references)
//IL_0258: Unknown result type (might be due to invalid IL or missing references)
//IL_0262: Invalid comparison between Unknown and I4
//IL_02b7: Unknown result type (might be due to invalid IL or missing references)
//IL_02c1: Invalid comparison between Unknown and I4
//IL_03bc: Unknown result type (might be due to invalid IL or missing references)
//IL_03c3: Unknown result type (might be due to invalid IL or missing references)
//IL_03c8: Unknown result type (might be due to invalid IL or missing references)
//IL_03cf: Unknown result type (might be due to invalid IL or missing references)
//IL_03d4: Unknown result type (might be due to invalid IL or missing references)
//IL_03fb: Unknown result type (might be due to invalid IL or missing references)
//IL_0405: Expected O, but got Unknown
//IL_0442: Unknown result type (might be due to invalid IL or missing references)
//IL_0449: Invalid comparison between Unknown and I4
//IL_044d: Unknown result type (might be due to invalid IL or missing references)
//IL_0457: Expected O, but got Unknown
List<Item> list = Definitions();
SettingsCatagory category = Object.Instantiate<GameObject>(((Component)menu.catagoryGraphics).gameObject, ((Component)menu.catagoryGraphics).transform.parent, false).GetComponent<SettingsCatagory>();
((Object)((Component)category).gameObject).name = "BigCamera Settings";
((Component)category).gameObject.SetActive(false);
Il2CppReferenceArray<SettingsRow> rows = category.rows;
SettingsRow val = FindRow(menu.catagoryControls, (SettingsType)41);
SettingsRow val2 = FindRow(menu.catagoryGraphics, (SettingsType)33);
SettingsRow val3 = FindRow(menu.catagoryControls, (SettingsType)44);
bool flag = list.Count > ((Il2CppArrayBase<SettingsRow>)(object)rows).Length;
Pager pager = new Pager
{
Category = category,
PerPage = (flag ? (((Il2CppArrayBase<SettingsRow>)(object)rows).Length - 1) : ((Il2CppArrayBase<SettingsRow>)(object)rows).Length),
Positions = ((IEnumerable<SettingsRow>)rows).Select((SettingsRow s) => ((Component)s).transform.localPosition).ToArray()
};
if (flag)
{
pager.PageRow = CloneRow(val2, ((Il2CppArrayBase<SettingsRow>)(object)rows)[0], pager.Positions[0], new Item
{
Title = "PAGE",
Type = (SettingsType)204
});
pager.PageRow.wrap = false;
pagers[((Object)pager.PageRow).GetInstanceID()] = pager;
}
SettingsRow[] array = (SettingsRow[])(object)new SettingsRow[list.Count];
for (int num = 0; num < list.Count; num++)
{
Item item = list[num];
SettingsRow template = (((int)item.Type == 201) ? val : (((int)item.Type == 202) ? val2 : val3));
array[num] = CloneRow(template, ((Il2CppArrayBase<SettingsRow>)(object)rows)[0], pager.Positions[0], item);
items[((Object)array[num]).GetInstanceID()] = item;
}
pager.Rows = array;
for (int num2 = 0; num2 < ((Il2CppArrayBase<SettingsRow>)(object)rows).Length; num2++)
{
Object.Destroy((Object)(object)((Component)((Il2CppArrayBase<SettingsRow>)(object)rows)[num2]).gameObject);
}
for (int num3 = 0; num3 < array.Length; num3++)
{
Item item2 = list[num3];
if ((int)item2.Type == 201)
{
SetRawText(array[num3].label0, "ON");
SetRawText(array[num3].label1, "OFF");
if ((Object)(object)array[num3].label2 != (Object)null)
{
((Component)array[num3].label2).gameObject.SetActive(false);
}
}
else if ((int)item2.Type == 202)
{
array[num3].wrap = false;
}
else
{
ConfigureSlider(array[num3], item2.Steps);
}
}
ShowPage(pager, 0);
DisableResetButton(category);
Button component = ((Component)menu.catagoryControls.catagoryButton).GetComponent<Button>();
Transform val4 = FindCommonParent(((Component)component).transform, ((Component)menu.catagoryAudio.catagoryButton).transform);
Transform val5 = FindChildUnder(((Component)component).transform, val4);
Transform val6 = FindChildUnder(((Component)menu.catagoryAudio.catagoryButton).transform, val4);
Transform child = val4.GetChild(val4.childCount - 1);
Button controlsButton = ((Component)child).GetComponentInChildren<Button>(true) ?? component;
GameObject obj = Object.Instantiate<GameObject>(((Component)val5).gameObject, val4, false);
((Object)obj).name = "BigCamera Category";
obj.transform.SetAsLastSibling();
obj.transform.localPosition = child.localPosition + val5.localPosition - val6.localPosition;
Button componentInChildren = obj.GetComponentInChildren<Button>(true);
((Component)componentInChildren).GetComponentInChildren<LocalizedText>(true).Change("Big Camera", (DisplayType)1);
componentInChildren.onClick = new ButtonClickedEvent();
((UnityEvent)componentInChildren.onClick).AddListener(UnityAction.op_Implicit((Action)delegate
{
SwapToCategoryMethod.Invoke(menu, new object[1] { category });
}));
Enumerator<Entry> enumerator = ((Component)componentInChildren).GetComponent<EventTrigger>().triggers.GetEnumerator();
while (enumerator.MoveNext())
{
Entry current = enumerator.Current;
if ((int)current.eventID == 9)
{
current.callback = new TriggerEvent();
((UnityEvent<BaseEventData>)(object)current.callback).AddListener(UnityAction<BaseEventData>.op_Implicit((Action<BaseEventData>)delegate
{
menu.NavigateToCatagory(category);
}));
}
}
category.catagoryButton = (Selectable)(object)componentInChildren;
menu.buttonList.Add(componentInChildren);
LinkNavigation(menu, controlsButton, componentInChildren);
LayoutRebuilder.ForceRebuildLayoutImmediate(((Component)val4).GetComponent<RectTransform>());
}
private unsafe static SettingsRow FindRow(SettingsCatagory category, SettingsType type)
{
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
foreach (SettingsRow item in (Il2CppArrayBase<SettingsRow>)(object)category.rows)
{
if (item.settingsType == type)
{
return item;
}
}
throw new InvalidOperationException("Settings row " + ((object)(*(SettingsType*)(&type))/*cast due to .constrained prefix*/).ToString() + " was not found.");
}
private static SettingsRow CloneRow(SettingsRow template, SettingsRow slot, Vector3 position, Item item)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
GameObject obj = Object.Instantiate<GameObject>(((Component)template).gameObject, ((Component)slot).transform.parent, false);
((Object)obj).name = "BigCamera " + item.Title;
obj.transform.localPosition = position;
obj.transform.localRotation = ((Component)slot).transform.localRotation;
obj.transform.localScale = ((Component)slot).transform.localScale;
obj.transform.SetSiblingIndex(((Component)slot).transform.GetSiblingIndex());
SettingsRow component = obj.GetComponent<SettingsRow>();
component.settingsType = item.Type;
foreach (TMP_Text componentsInChild in obj.GetComponentsInChildren<TMP_Text>(true))
{
if (!(((Object)((Component)componentsInChild).gameObject).name != "Title"))
{
SetRawText(componentsInChild, item.Title);
break;
}
}
return component;
}
private static void SetRawText(TMP_Text text, string value)
{
LocalizedText component = ((Component)text).GetComponent<LocalizedText>();
if ((Object)(object)component != (Object)null)
{
((Behaviour)component).enabled = false;
}
text.text = value;
}
private static void ConfigureSlider(SettingsRow row, int steps)
{
configuringSlider = true;
row.slider.minValue = 0f;
row.slider.maxValue = steps;
row.slider.wholeNumbers = true;
configuringSlider = false;
}
private static void DisableResetButton(SettingsCatagory category)
{
foreach (Button componentsInChild in ((Component)category).GetComponentsInChildren<Button>(true))
{
for (int i = 0; i < ((UnityEventBase)componentsInChild.onClick).GetPersistentEventCount(); i++)
{
if (((UnityEventBase)componentsInChild.onClick).GetPersistentMethodName(i) == "ActionResetControls")
{
((Component)componentsInChild).gameObject.SetActive(false);
}
}
}
}
private static Transform FindCommonParent(Transform first, Transform second)
{
Transform parent = first.parent;
while (!second.IsChildOf(parent))
{
parent = parent.parent;
}
return parent;
}
private static Transform FindChildUnder(Transform child, Transform parent)
{
while ((Object)(object)child.parent != (Object)(object)parent)
{
child = child.parent;
}
return child;
}
private static void LinkNavigation(SettingsMenu menu, Button controlsButton, Button ours)
{
Navigation navigation = ((Selectable)controlsButton).navigation;
Navigation navigation2 = ((Selectable)ours).navigation;
navigation.selectOnDown = (Selectable)(object)ours;
navigation2.selectOnUp = (Selectable)(object)controlsButton;
navigation2.selectOnDown = menu.catagoryGeneral.catagoryButton;
((Selectable)controlsButton).navigation = navigation;
((Selectable)ours).navigation = navigation2;
}
private static bool StartRow(SettingsRow __instance)
{
if (!IsOurs(__instance))
{
return true;
}
__instance.settingsMenu = ((Component)__instance).GetComponentInParent<SettingsMenu>(true);
Refresh(__instance);
return false;
}
private static bool EnableRow(SettingsRow __instance)
{
if (!IsOurs(__instance))
{
return true;
}
Refresh(__instance);
return false;
}
private static bool RefreshRow(SettingsRow __instance)
{
if (!IsOurs(__instance))
{
return true;
}
Refresh(__instance);
return false;
}
private static bool NavigateRow(SettingsRow __instance)
{
return !IsOurs(__instance);
}
private static bool BackFromRow(SettingsRow __instance)
{
if (!IsOurs(__instance))
{
return true;
}
__instance.settingsMenu.GoBackFromCatagory();
return false;
}
private static bool CycleRow(SettingsRow __instance, int delta)
{
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
//IL_005c: Invalid comparison between Unknown and I4
if (!IsOurs(__instance))
{
return true;
}
if (pagers.TryGetValue(((Object)__instance).GetInstanceID(), out var value))
{
ShowPage(value, value.Page + delta);
return false;
}
if (items.TryGetValue(((Object)__instance).GetInstanceID(), out var item) && (int)item.Type == 202)
{
int index = Math.Clamp(item.GetIndex() + delta, 0, item.Options().Length - 1);
Try(delegate
{
item.SetIndex(index);
});
Refresh(__instance);
}
return false;
}
private static bool SelectRow(SettingsRow __instance, int valueIndex)
{
//IL_0035: Unknown result type (might be due to invalid IL or missing references)
//IL_003f: Invalid comparison between Unknown and I4
if (!IsOurs(__instance))
{
return true;
}
if (items.TryGetValue(((Object)__instance).GetInstanceID(), out var item) && (int)item.Type == 201)
{
Try(delegate
{
item.SetOn(valueIndex == 0);
});
Refresh(__instance);
}
return false;
}
private static bool SetSliderRow(SettingsRow __instance)
{
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_0041: Invalid comparison between Unknown and I4
if (!IsOurs(__instance))
{
return true;
}
if (configuringSlider)
{
return false;
}
if (items.TryGetValue(((Object)__instance).GetInstanceID(), out var item) && (int)item.Type == 203)
{
float value = item.Min + (float)Mathf.RoundToInt(__instance.slider.value) * item.Step;
Try(delegate
{
item.Set(value);
});
Refresh(__instance);
}
return false;
}
private static void Try(Action action)
{
try
{
action();
}
catch (Exception ex)
{
((BasePlugin)Plugin.Instance).Log.LogWarning((object)ex.Message);
}
}
private static T Read<T>(Func<T> get, T fallback)
{
try
{
return get();
}
catch
{
return fallback;
}
}
private static void Refresh(SettingsRow row)
{
//IL_008e: Unknown result type (might be due to invalid IL or missing references)
//IL_0098: Invalid comparison between Unknown and I4
//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d0: Invalid comparison between Unknown and I4
if (pagers.TryGetValue(((Object)row).GetInstanceID(), out var value))
{
row.arrayLabel.Change(value.Page + 1 + " / " + value.Pages, (DisplayType)1);
((Selectable)row.leftButton).interactable = value.Page > 0;
((Selectable)row.rightButton).interactable = value.Page < value.Pages - 1;
}
else
{
if (!items.TryGetValue(((Object)row).GetInstanceID(), out var value2))
{
return;
}
if ((int)value2.Type == 201)
{
bool flag = Read(value2.GetOn, fallback: false);
row.SetUnderlineSingle(row.label0, flag);
row.SetUnderlineSingle(row.label1, !flag);
}
else if ((int)value2.Type == 202)
{
string[] array = value2.Options();
int num = Math.Clamp(Read(value2.GetIndex, 0), 0, array.Length - 1);
string text = array[num];
if (text.Length > 24)
{
text = text.Substring(0, 24);
}
row.arrayLabel.Change(text, (DisplayType)1);
((Selectable)row.leftButton).interactable = num > 0;
((Selectable)row.rightButton).interactable = num < array.Length - 1;
}
else
{
float v = Read(value2.Get, value2.Min);
configuringSlider = true;
row.slider.SetValueWithoutNotify((float)value2.ToStep(v));
configuringSlider = false;
row.sliderLabel.Change(v.ToString(value2.Format) + value2.Suffix, (DisplayType)1);
}
}
}
}
public class MicVoice : MonoBehaviour
{
public const string RouteDirect = "Direct";
public static readonly string[] Routes = new string[3] { "Self Voice", "Voice", "Direct" };
public static float Level;
public static bool LoopbackOn = true;
public static bool CameraActive;
private const int Window = 512;
private const int CopyWindow = 4096;
private static bool restart;
private static bool recreate;
private AudioClip clip;
private AudioClip mirror;
private AudioSource source;
private PlayerCharacter local;
private string device;
private bool ownCapture;
private float findTimer;
private Il2CppStructArray<float> buffer;
private Il2CppStructArray<float> copy;
public MicVoice(IntPtr ptr)
: base(ptr)
{
}
public static void RestartCapture()
{
restart = true;
}
public static void RecreateSource()
{
recreate = true;
}
private void Awake()
{
buffer = new Il2CppStructArray<float>(512L);
copy = new Il2CppStructArray<float>(4096L);
}
private void Update()
{
if (Input.GetKeyDown((KeyCode)289))
{
LoopbackOn = !LoopbackOn;
}
if (restart)
{
ResetCapture();
findTimer = 0f;
}
findTimer -= Time.unscaledDeltaTime;
if (findTimer <= 0f)
{
findTimer = 1f;
if ((Object)(object)local == (Object)null)
{
local = FindLocal();
}
if ((Object)(object)clip == (Object)null)
{
FindClip();
}
}
if ((Object)(object)clip == (Object)null)
{
Level = 0f;
return;
}
int samples = clip.samples;
int position = Microphone.GetPosition(device);
if (position <= 0)
{
Level = 0f;
return;
}
clip.GetData(buffer, Wrap(position - 512, samples));
float num = 0f;
for (int i = 0; i < 512; i++)
{
num += ((Il2CppArrayBase<float>)(object)buffer)[i] * ((Il2CppArrayBase<float>)(object)buffer)[i];
}
float num2 = Mathf.Sqrt(num / 512f);
Level = Mathf.Lerp(Level, Mathf.Clamp01(num2 * Plugin.MouthGain.Value), 0.5f);
UpdateLoopback(position, samples);
}
private static int Wrap(int i, int len)
{
return (i % len + len) % len;
}
private static PlayerCharacter FindLocal()
{
foreach (PlayerCharacter item in Object.FindObjectsOfType<PlayerCharacter>())
{
if (((NetworkBehaviour)item).isLocalPlayer)
{
return item;
}
}
return null;
}
private void ResetCapture()
{
restart = false;
if ((Object)(object)source != (Object)null)
{
source.Stop();
}
if (ownCapture && device != null)
{
Microphone.End(device);
}
if ((Object)(object)mirror != (Object)null)
{
Object.Destroy((Object)(object)mirror);
}
clip = null;
mirror = null;
device = null;
ownCapture = false;
}
private void FindClip()
{
string value = Plugin.MicName.Value;
if (string.IsNullOrEmpty(value))
{
DissonanceComms obj = Object.FindObjectOfType<DissonanceComms>();
object obj2;
if (obj == null)
{
obj2 = null;
}
else
{
IMicrophoneCapture microphoneCapture = obj.MicrophoneCapture;
obj2 = ((microphoneCapture != null) ? ((Il2CppObjectBase)microphoneCapture).TryCast<BasicMicrophoneCapture>() : null);
}
BasicMicrophoneCapture val = (BasicMicrophoneCapture)obj2;
if ((Object)(object)val != (Object)null && (Object)(object)val.Clip != (Object)null && !string.IsNullOrEmpty(val.Device))
{
clip = val.Clip;
device = val.Device;
return;
}
}
Il2CppStringArray devices = Microphone.devices;
if (((Il2CppArrayBase<string>)(object)devices).Length == 0)
{
return;
}
device = ((Il2CppArrayBase<string>)(object)devices)[0];
foreach (string item in (Il2CppArrayBase<string>)(object)devices)
{
if (!string.IsNullOrEmpty(value) && item.IndexOf(value, StringComparison.OrdinalIgnoreCase) >= 0)
{
device = item;
break;
}
}
clip = Microphone.Start(device, true, 1, 48000);
ownCapture = true;
}
private void UpdateLoopback(int head, int len)
{
if (!LoopbackOn || !CameraActive || (Object)(object)local == (Object)null)
{
if ((Object)(object)source != (Object)null && source.isPlaying)
{
source.Stop();
}
return;
}
if ((Object)(object)mirror == (Object)null || mirror.samples != len || mirror.frequency != clip.frequency)
{
if ((Object)(object)mirror != (Object)null)
{
Object.Destroy((Object)(object)mirror);
}
mirror = AudioClip.Create("BigCamera_Mirror", len, clip.channels, clip.frequency, false);
recreate = true;
}
int num = Wrap(head - 4096, len);
clip.GetData(copy, num);
mirror.SetData(copy, num);
if (recreate)
{
recreate = false;
if ((Object)(object)source != (Object)null)
{
Object.Destroy((Object)(object)((Component)source).gameObject);
}
source = null;
}
if ((Object)(object)source == (Object)null)
{
CreateSource();
}
int num2 = Wrap(head - clip.frequency / 20, len);
if (!source.isPlaying)
{
source.timeSamples = num2;
source.Play();
}
source.volume = Plugin.LoopbackVolume.Value;
int num3 = Math.Abs(source.timeSamples - num2);
if (Math.Min(num3, len - num3) > clip.frequency / 7)
{
source.timeSamples = num2;
}
}
private void CreateSource()
{
//IL_0055: Unknown result type (might be due to invalid IL or missing references)
//IL_005b: Expected O, but got Unknown
Transform val = ((local.looks != null && local.lips != null && (Object)(object)local.lips.lipTransform != (Object)null) ? local.lips.lipTransform : ((Component)local).transform);
GameObject val2 = new GameObject("BigCamera_VoiceLoopback");
val2.transform.SetParent(val, false);
source = val2.AddComponent<AudioSource>();
source.clip = mirror;
source.loop = true;
source.spatialBlend = (Plugin.Loopback3D.Value ? 1f : 0f);
source.rolloffMode = (AudioRolloffMode)0;
string value = Plugin.LoopbackRoute.Value;
if (value == "Direct")
{
return;
}
foreach (AudioMixerGroup item in Resources.FindObjectsOfTypeAll<AudioMixerGroup>())
{
if (((Object)item).name == value)
{
source.outputAudioMixerGroup = item;
break;
}
}
}
}
[HarmonyPatch(typeof(PlayerLips), "Update")]
internal static class LipsPatch
{
private static void Prefix(PlayerLips __instance)
{
PlayerCharacter playerCharacter = __instance.playerCharacter;
if ((Object)(object)playerCharacter != (Object)null && ((NetworkBehaviour)playerCharacter).isLocalPlayer)
{
__instance.amplitude = MicVoice.Level;
}
}
}
[BepInPlugin("com.eggdog.bigwalk.bigcamera", "BigCamera", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
public class Plugin : BasePlugin
{
public static Plugin Instance;
public static ConfigEntry<string> MicName;
public static ConfigEntry<float> MouthGain;
public static ConfigEntry<float> LoopbackVolume;
public static ConfigEntry<string> LoopbackRoute;
public static ConfigEntry<bool> Loopback3D;
public override void Load()
{
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Expected O, but got Unknown
Instance = this;
MicName = ((BasePlugin)this).Config.Bind<string>("Voice", "LoopbackMic", "", "Part of the mic device name to use. Empty uses the game's mic");
MouthGain = ((BasePlugin)this).Config.Bind<float>("Voice", "MouthGain", 2.5f, "How strongly your mic level opens your mouth");
LoopbackVolume = ((BasePlugin)this).Config.Bind<float>("Voice", "LoopbackVolume", 1f, "Volume of the voice loopback");
LoopbackRoute = ((BasePlugin)this).Config.Bind<string>("Voice", "LoopbackRoute", "Self Voice", "Self Voice, Voice, or Direct (no mixer group)");
Loopback3D = ((BasePlugin)this).Config.Bind<bool>("Voice", "Loopback3D", true, "Play the loopback from your mouth instead of flat in your ears");
ClassInjector.RegisterTypeInIl2Cpp<CameraLocker>();
ClassInjector.RegisterTypeInIl2Cpp<MicVoice>();
((BasePlugin)this).AddComponent<CameraLocker>();
((BasePlugin)this).AddComponent<MicVoice>();
Harmony val = new Harmony("com.eggdog.bigwalk.bigcamera");
val.PatchAll();
if (((BaseChainloader<BasePlugin>)(object)IL2CPPChainloader.Instance).Plugins.ContainsKey("com.eggdog.bigmenu"))
{
BigMenuHook.Register();
}
else
{
MenuSettings.Install(val);
}
}
public static void Set<T>(ConfigEntry<T> entry, T value)
{
entry.Value = value;
((BasePlugin)Instance).Config.Save();
}
}
}