Decompiled source of Crispberry PiPhone v0.17.69
tony4twentys-Crispberry PiPhone.dll
Decompiled 2 weeks 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.Drawing.Imaging; using System.Drawing.Text; using System.Globalization; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading; using BepInEx; using BepInEx.Configuration; using ExitGames.Client.Photon; using HarmonyLib; using Photon.Pun; using Photon.Realtime; using Photon.Voice; using Photon.Voice.Unity; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.SceneManagement; using UnityEngine.TextCore; using UnityEngine.UI; using Zorro.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("PhotonVoice")] [assembly: AssemblyTitle("Crispberry PiPhone")] [assembly: AssemblyDescription("Android-style in-game phone for PEAK, with a public app API.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("tony4twentys")] [assembly: AssemblyProduct("Crispberry PiPhone")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("b86841f9-1cd5-41de-ba99-f10d663d2700")] [assembly: AssemblyFileVersion("0.17.69.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.17.69.0")] [module: UnverifiableCode] namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } } namespace Crispberry_PiPhone { [BepInPlugin("tony4twentys.Crispberry_PiPhone", "Crispberry PiPhone", "0.17.69")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInProcess("PEAK.exe")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "tony4twentys.Crispberry_PiPhone"; public const string PluginName = "Crispberry PiPhone"; public const string PluginVersion = "0.17.69"; public const string OsName = "Crispberry OS"; internal const byte PhotonEventCode = 185; internal const string EventMagic = "tony4twentys.Crispberry_PiPhone"; public static Plugin Instance; public ConfigEntry<KeyCode> MenuKey; public ConfigEntry<KeyCode> MenuModifier; public ConfigEntry<bool> ShowPauseMenuButton; public ConfigEntry<KeyCode> CameraCursorKey; public ConfigEntry<KeyCode> CameraFlipKey; public ConfigEntry<KeyCode> CameraRotateKey; public ConfigEntry<KeyCode> CameraShutterKey; public ConfigEntry<KeyCode> AnswerKey; public ConfigEntry<KeyCode> DeclineKey; public ConfigEntry<KeyCode> LandscapeKey; public ConfigEntry<string> TenorApiKey; internal static bool CapturingHotkey; internal static int CaptureEndedFrame = -1; private Harmony _harmony; public static string OsVersionLabel => "Crispberry OS 0.17.69"; private void Awake() { //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Expected O, but got Unknown Instance = this; MenuKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "MenuKey", (KeyCode)112, "Opens the phone. Used with MenuModifier."); MenuModifier = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "MenuModifier", (KeyCode)308, "Hold this with MenuKey. Set to None for the key alone."); ShowPauseMenuButton = ((BaseUnityPlugin)this).Config.Bind<bool>("Controls", "ShowPauseMenuButton", true, "Add a PiPhone button to the pause menu."); CameraCursorKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Camera", "CursorKey", (KeyCode)308, "While Camera is open: show or hide the cursor. Only this app uses it."); CameraFlipKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Camera", "FlipKey", (KeyCode)102, "While Camera is open: flip front/back. Does not stop a recording."); CameraRotateKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Camera", "RotateKey", (KeyCode)114, "While Camera is open: tall/wide. Does not stop a recording."); CameraShutterKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Camera", "ShutterKey", (KeyCode)118, "While Camera is open: photo snaps, video starts or stops."); AnswerKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Alerts", "AnswerKey", (KeyCode)282, "Answer an incoming call, or open the latest text in Messages."); DeclineKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Alerts", "DeclineKey", (KeyCode)283, "Decline an incoming call, or dismiss a text banner."); LandscapeKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("Controls", "LandscapeKey", (KeyCode)284, "While the phone is open: switch portrait and landscape (same phone shape)."); TenorApiKey = ((BaseUnityPlugin)this).Config.Bind<string>("Network", "TenorApiKey", "", "Optional Google Tenor API key for GIF search. Leave blank to use the built-in Tenor search page."); PhoneStore.Load(); PhoneTheme.Load(); PhoneLang.Ensure(); PhoneTones.Load(); PhoneContacts.Ensure(); VoiceIo.Ensure(); MusicPlayer.Ensure(); PhoneNet.Ensure(); CallService.Ensure(); AlertHud.Ensure(); PhoneMenu.EnsureCreated(); BuiltinApps.Register(); PhoneKeys.RegisterBuiltins(); PhoneKeys.Load(); _harmony = new Harmony("tony4twentys.Crispberry_PiPhone"); try { _harmony.PatchAll(typeof(Plugin).Assembly); } catch (Exception ex) { LogError("Harmony PatchAll failed: " + ex.Message); } SceneManager.sceneLoaded += OnSceneLoaded; LogInfo("Crispberry PiPhone v0.17.69 loaded. Open with " + FormatHotkey() + "."); } private void Update() { PhoneMenu.TickUseLock(); if (!PhoneKeys.TickCapture()) { PhoneKeys.FirePressed(); if (CameraApp.IsOpen) { CameraApp.TickHotkeys(); } } } internal static string FormatCameraKeys() { return PhoneKeys.Format("pip.camera.cursor") + " cursor · " + PhoneKeys.Format("pip.camera.flip") + " flip · " + PhoneKeys.Format("pip.camera.rotate") + " rotate · " + PhoneKeys.Format("pip.camera.shutter") + " shutter · wheel zoom"; } internal static string FormatLandscapeKey() { return PhoneKeys.Format("pip.landscape"); } internal static string FormatAlertKeys(bool text = false) { string text2 = PhoneKeys.Format("pip.answer"); string text3 = PhoneKeys.Format("pip.decline"); return text ? (text2 + " open · " + text3 + " dismiss") : (text2 + " answer · " + text3 + " decline"); } public static string FormatHotkey() { return PhoneKeys.Format("pip.open"); } internal static string Pretty(KeyCode key) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) return PhoneKeys.Pretty(key); } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; try { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } catch { } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { PhoneUi.InvalidateFont(); PhoneMenu.OnAfterSceneLoad(); } public static bool GetShowPauseMenuButton() { return (Object)(object)Instance == (Object)null || Instance.ShowPauseMenuButton == null || Instance.ShowPauseMenuButton.Value; } public static void SetShowPauseMenuButton(bool show) { if ((Object)(object)Instance != (Object)null && Instance.ShowPauseMenuButton != null) { Instance.ShowPauseMenuButton.Value = show; } } public static void LogInfo(string message) { if (PhoneTheme.WriteLogs) { if ((Object)(object)Instance != (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogInfo((object)message); } else { Debug.Log((object)("[PiPhone] " + message)); } } } public static void LogError(string message) { if ((Object)(object)Instance != (Object)null) { ((BaseUnityPlugin)Instance).Logger.LogError((object)message); } else { Debug.LogError((object)("[PiPhone] " + message)); } } } public static class PiPhoneApi { public const string PluginGuid = "tony4twentys.Crispberry_PiPhone"; public const string OsName = "Crispberry OS"; internal static readonly List<PiPhoneApp> Apps = new List<PiPhoneApp>(16); public static int BatteryPercent = 100; public static bool BatteryCharging; public static PiPhoneCarrier Carrier = PiPhoneCarrier.Lte; public static int SignalBars = 4; public const int MaxIconSize = 128; public const int MaxIconBytes = 2097152; private static readonly List<PiPhoneCategory> Categories = new List<PiPhoneCategory>(); public static string OsVersion => Plugin.OsVersionLabel; public static bool IsReady => (Object)(object)Plugin.Instance != (Object)null; public static bool IsOpen => PhoneMenu.IsOpen; public static bool CanUsePhone => PhoneMenu.CanUsePhone(); public static bool IsPlayThrough => PhoneMenu.IsPlayThrough; public static PiPhonePlayThrough PlayThroughMode => PhoneMenu.PlayThroughMode; public static bool PlayThroughAllowed => PhoneMenu.PlayThroughAllowed(); public static string CurrentAppId => PhoneMenu.CurrentAppId; public static bool IsLandscape => PhoneMenu.IsLandscape; public static bool IsFullscreen => PhoneMenu.IsFullscreen; public static bool IsImmersive => PhoneMenu.IsImmersive; public static string AlertsFolder => PhoneStore.AlertsDir; public static bool IsLocalDead => ScoutQuery.LocalIsDead(); public static bool IsLocalGhost => ScoutQuery.LocalIsGhost(); public static event Action AppsChanged; public static event Action OrientationChanged; public static void SetPlayThrough(bool on) { PhoneMenu.SetPlayThrough(on); } public static void SetPlayThrough(PiPhonePlayThrough mode) { PhoneMenu.SetPlayThrough(mode); } public static void TogglePlayThrough() { PhoneMenu.TogglePlayThrough(); } public static void Open() { PhoneMenu.Open(); } public static void Close() { PhoneMenu.Close(); } public static void Toggle() { PhoneMenu.Toggle(); } public static void GoHome() { PhoneMenu.GoHome(); } public static void GoBack() { PhoneMenu.GoBack(); } public static bool OpenApp(string id) { return PhoneMenu.OpenApp(id); } public static void SetLandscape(bool landscape) { PhoneMenu.SetLandscape(landscape); } public static void SetFullscreen(bool fullscreen) { PhoneMenu.SetFullscreen(fullscreen); } public static void SetWallpaperPaused(bool paused) { PhoneMenu.SetWallpaperPaused(paused); } public static void RegisterKeybind(PiPhoneKeybind bind) { PhoneKeys.Add(bind); } public static void RegisterShadeButton(PiPhoneShadeButton button) { PhoneShade.Register(button); PhoneMenu.RefreshShade(); } public static void RegisterNavButton(PiPhoneNavButton button) { PhoneMenu.RegisterNavButton(button); } public static void RegisterNumber(PiPhoneNumber number) { PhoneNumbers.Register(number); } public static bool UnregisterNumber(string number) { return PhoneNumbers.Unregister(number); } public static void SetBattery(int percent, bool charging) { if (percent < 0) { percent = 0; } if (percent > 100) { percent = 100; } BatteryPercent = percent; BatteryCharging = charging; } public static void SetCarrier(PiPhoneCarrier carrier, int bars) { Carrier = carrier; if (bars < 0) { bars = 0; } if (bars > 4) { bars = 4; } SignalBars = bars; } public static void SetContactName(string id, string customName) { PhoneContacts.SetCustomName(id, customName); } public static bool SetContactPhoto(string id, byte[] pngOrJpg) { return PhoneContacts.SetPhoto(id, pngOrJpg); } public static bool TryGetContact(string id, out PiPhoneContact contact) { contact = PhoneContacts.Get(id); return contact != null; } public static string ContactDisplayName(string id, string fallback) { return PhoneContacts.Display(id, fallback); } public static PiPhoneContact[] GetContacts() { return PhoneContacts.All(); } public static PiPhoneLook GetLook() { //IL_0007: 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_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_001d: 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_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) //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_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_0049: 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_0054: 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_005f: 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_006a: Unknown result type (might be due to invalid IL or missing references) //IL_006f: 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) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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) return new PiPhoneLook { Screen = PhoneTheme.ScreenColor, Surface = PhoneTheme.SurfaceColor, Nav = PhoneTheme.NavColor, NavButton = PhoneTheme.NavButtonColor, NavIcon = PhoneTheme.NavIconColor, Text = PhoneTheme.TextColor, Accent = PhoneTheme.AccentColor, Icon = PhoneTheme.IconColor, Case = PhoneTheme.CaseColor, Clock = PhoneTheme.ClockColor, ButtonFill = PhoneTheme.ButtonFillColor, ButtonText = PhoneTheme.ButtonFontColor, FontScale = PhoneTheme.FontScale, ButtonRadius = PhoneTheme.ButtonRadius, IconRadius = PhoneTheme.IconRadius }; } public static void SetLook(PiPhoneLook look) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //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) //IL_002a: 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) //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_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_0051: 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_005c: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_0077: 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_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) if (look != null) { PhoneTheme.ScreenColor = look.Screen; PhoneTheme.SurfaceColor = look.Surface; PhoneTheme.NavColor = look.Nav; PhoneTheme.NavButtonColor = look.NavButton; PhoneTheme.NavIconColor = look.NavIcon; PhoneTheme.TextColor = look.Text; PhoneTheme.AccentColor = look.Accent; PhoneTheme.IconColor = look.Icon; PhoneTheme.CaseColor = look.Case; PhoneTheme.ClockColor = look.Clock; PhoneTheme.ButtonFillColor = look.ButtonFill; PhoneTheme.ButtonFontColor = look.ButtonText; PhoneTheme.FontScale = Mathf.Clamp(look.FontScale, 0.7f, 1.6f); PhoneTheme.ButtonRadius = ((look.ButtonRadius >= 0) ? ((look.ButtonRadius > 28) ? 28 : look.ButtonRadius) : 0); PhoneTheme.IconRadius = ((look.IconRadius >= 0) ? ((look.IconRadius > 28) ? 28 : look.IconRadius) : 0); PhoneTheme.Commit(); } } public static void ResetLook() { PhoneTheme.ResetLook(); } public static void ResetButtons() { PhoneTheme.ResetButtons(); } public static void ResetCase() { PhoneTheme.ResetCase(); } public static void ResetClockColor() { PhoneTheme.ResetClockColor(); } public static void RegisterLanguage(PiPhoneLanguage pack) { PhoneLang.Register(pack); } public static bool SetLanguage(string code) { return PhoneLang.Set(code); } public static void UseSystemLanguage() { PhoneLang.UseSystem(); } public static string GetLanguage() { return PhoneLang.Code; } public static string T(string key, string fallback) { return PhoneLang.T(key, fallback); } public static PiPhoneLanguage[] GetLanguages() { return PhoneLang.All(); } public static void SetScreenColor(Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) PhoneTheme.SetScreenColor(color); } public static void SetSurfaceColor(Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) PhoneTheme.SetSurfaceColor(color); } public static void SetNavColor(Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) PhoneTheme.SetNavColor(color); } public static void SetNavButtonColor(Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) PhoneTheme.SetNavButtonColor(color); } public static void SetNavIconColor(Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) PhoneTheme.SetNavIconColor(color); } public static void SetTextColor(Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) PhoneTheme.SetTextColor(color); } public static void SetAccentColor(Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) PhoneTheme.SetAccentColor(color); } public static void SetIconColor(Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) PhoneTheme.SetIconColor(color); } public static void SetFontScale(float scale) { PhoneTheme.SetFontScale(scale); } public static void SetButtonRadius(int radius) { PhoneTheme.SetButtonRadius(radius); } public static void SetIconRadius(int radius) { PhoneTheme.SetIconRadius(radius); } public static bool UnregisterShadeButton(string id) { bool flag = PhoneShade.Unregister(id); if (flag) { PhoneMenu.RefreshShade(); } return flag; } public static PiPhoneShadeButton[] GetShadeButtons() { return PhoneShade.All(); } public static bool ShadeButtonVisible(string id) { PiPhoneShadeButton[] array = PhoneShade.All(); for (int i = 0; i < array.Length; i++) { if (array[i] != null && string.Equals(array[i].Id, id, StringComparison.OrdinalIgnoreCase)) { return PhoneShade.Visible(array[i]); } } return false; } public static void SetShadeButtonVisible(string id, bool visible) { PhoneTheme.SetShadeButtonOn(id, visible); PhoneMenu.RefreshShade(); } public static bool UnregisterKeybind(string id) { return PhoneKeys.Remove(id); } public static bool KeyDown(string id) { return PhoneKeys.Down(id); } public static bool KeyHeld(string id) { return PhoneKeys.Held(id); } public static string FormatKey(string id) { return PhoneKeys.Format(id); } public static PiPhoneKeybind[] GetKeybinds() { return PhoneKeys.All(); } public static void CaptureKeybind(string id, Action onDone) { PhoneKeys.BeginCapture(id, onDone); } public static void ClearKeybind(string id) { PhoneKeys.Clear(id); } public static void SetImmersive(bool immersive) { PhoneMenu.SetImmersive(immersive); } public static void SetUserLandscape(bool landscape) { PhoneMenu.SetUserLandscape(landscape); } public static void ToggleLandscape() { PhoneMenu.ToggleUserLandscape(); } public static void Notify(string appId, string title, string body) { PhoneNotify.Post(appId, title, body, persist: true, sound: true); } public static string ImportAlert(string path) { return PhoneStore.AddSound(path, alert: true, 20f)?.Id; } public static void SetAppAlertSound(string appId, string soundId) { PhoneTones.SetAppTone(appId, soundId); } public static string GetAppAlertSound(string appId) { return PhoneTones.AppTone(appId); } public static void Toast(string message) { PhoneMenu.Toast(message); } public static PiPhoneScout LocalScout() { return ScoutQuery.Local(); } public static PiPhoneScout[] GetScouts() { return ScoutQuery.All(othersOnly: false); } public static PiPhoneScout[] GetOtherScouts() { return ScoutQuery.All(othersOnly: true); } public static PiPhoneScout[] GetDeadScouts() { return ScoutQuery.Where((PiPhoneScout s) => s.IsDead); } public static PiPhoneScout[] GetGhostScouts() { return ScoutQuery.Where((PiPhoneScout s) => s.IsGhost); } public static PiPhoneScout[] GetPassedOutScouts() { return ScoutQuery.Where((PiPhoneScout s) => s.IsPassedOut && !s.IsDead && !s.IsGhost); } public static PiPhoneScout[] GetCarriedScouts() { return ScoutQuery.Where((PiPhoneScout s) => s.IsCarried); } public static bool TryGetScout(string id, out PiPhoneScout scout) { return ScoutQuery.TryById(id, out scout); } public static bool TryGetScout(int actorNumber, out PiPhoneScout scout) { return ScoutQuery.TryByActor(actorNumber, out scout); } public static bool IsScoutDead(string id) { PiPhoneScout scout; return TryGetScout(id, out scout) && scout.IsDead; } public static bool IsScoutGhost(string id) { PiPhoneScout scout; return TryGetScout(id, out scout) && scout.IsGhost; } public static bool IsScoutDead(int actorNumber) { PiPhoneScout scout; return TryGetScout(actorNumber, out scout) && scout.IsDead; } public static bool IsScoutGhost(int actorNumber) { PiPhoneScout scout; return TryGetScout(actorNumber, out scout) && scout.IsGhost; } public static bool TryGetVoiceFilter(string id, out PiPhoneVoiceFilter filter) { return VoiceFx.TryGet(id, out filter); } public static bool TryGetVoiceFilter(int actorNumber, out PiPhoneVoiceFilter filter) { return VoiceFx.TryGet(actorNumber, out filter); } public static bool SetVoiceFilter(string id, PiPhoneVoiceFilter filter) { return VoiceFx.SetHold(id, filter); } public static bool SetVoiceFilter(int actorNumber, PiPhoneVoiceFilter filter) { return VoiceFx.SetHold(actorNumber, filter); } public static bool ClearVoiceFilter(string id) { return VoiceFx.ClearHold(id); } public static bool ClearVoiceFilter(int actorNumber) { return VoiceFx.ClearHold(actorNumber); } public static void ClearAllVoiceFilters() { VoiceFx.ClearAllHolds(); } public static bool VoiceFilterHeld(string id) { return VoiceFx.IsHeld(id); } public static void RegisterApp(PiPhoneApp app) { if (app == null || string.IsNullOrEmpty(app.Id)) { throw new ArgumentException("PiPhone app needs a non-empty Id.", "app"); } int num = IndexOf(app.Id); if (num >= 0) { Apps[num] = app; } else { Apps.Add(app); } if ((Object)(object)app.IconSprite != (Object)null) { app.IconSprite = PhoneIcons.ClampSprite(app.IconSprite); } if (!string.IsNullOrEmpty(app.BundledAlertPath) && File.Exists(app.BundledAlertPath)) { SoundItem soundItem = PhoneStore.AddSound(app.BundledAlertPath, alert: true, 20f); if (soundItem != null && string.IsNullOrEmpty(PhoneTones.AppTone(app.Id))) { PhoneTones.SetAppTone(app.Id, soundItem.Id); } } if (PhoneStore.DefaultsReady && app.Preinstalled && !PhoneStore.IsInstalled(app.Id)) { PhoneStore.Install(app.Id); } SortApps(); RaiseAppsChanged(); PhoneMenu.OnAppsChanged(); } public static Sprite CreateIcon(Texture2D texture) { return PhoneIcons.FromTexture(texture, consumeSource: false); } public static Sprite CreateIcon(byte[] pngOrJpg) { return PhoneIcons.FromBytes(pngOrJpg); } public static Sprite CreateIconFromFile(string path) { return PhoneIcons.FromFile(path); } public static Button CreateIconButton(Transform parent, Sprite icon, UnityAction onClick, Vector2 size) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) return PhoneUi.CreateIconChip(parent, string.Empty, icon, onClick, lit: false, size, tintIcon: false); } public static Button CreateIconButton(Transform parent, byte[] pngOrJpg, UnityAction onClick, Vector2 size) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) return CreateIconButton(parent, CreateIcon(pngOrJpg), onClick, size); } public static bool UnregisterApp(string id) { int num = IndexOf(id); if (num < 0) { return false; } Apps.RemoveAt(num); RaiseAppsChanged(); PhoneMenu.OnAppsChanged(); return true; } public static bool TryGetApp(string id, out PiPhoneApp app) { int num = IndexOf(id); if (num < 0) { app = null; return false; } app = Apps[num]; return true; } public static PiPhoneApp[] GetApps() { return Apps.ToArray(); } public static PiPhoneApp[] GetInstalledApps() { List<PiPhoneApp> list = new List<PiPhoneApp>(); for (int i = 0; i < Apps.Count; i++) { if (Apps[i] != null && PhoneStore.IsInstalled(Apps[i].Id)) { list.Add(Apps[i]); } } return list.ToArray(); } public static void RegisterCategory(string id, string displayName, int sortOrder) { if (string.IsNullOrEmpty(id)) { return; } for (int i = 0; i < Categories.Count; i++) { if (Categories[i] != null && string.Equals(Categories[i].Id, id, StringComparison.OrdinalIgnoreCase)) { Categories[i].DisplayName = (string.IsNullOrEmpty(displayName) ? id : displayName); Categories[i].SortOrder = sortOrder; return; } } Categories.Add(new PiPhoneCategory { Id = id, DisplayName = (string.IsNullOrEmpty(displayName) ? id : displayName), SortOrder = sortOrder }); } public static PiPhoneCategory[] GetCategories() { List<PiPhoneCategory> list = new List<PiPhoneCategory>(Categories); list.Sort(delegate(PiPhoneCategory a, PiPhoneCategory b) { int num = a?.SortOrder ?? 0; int value = b?.SortOrder ?? 0; int num2 = num.CompareTo(value); return (num2 != 0) ? num2 : string.Compare((a != null) ? a.DisplayName : string.Empty, (b != null) ? b.DisplayName : string.Empty, StringComparison.OrdinalIgnoreCase); }); return list.ToArray(); } public static PiPhoneApp[] GetStoreApps() { List<PiPhoneApp> list = new List<PiPhoneApp>(); for (int i = 0; i < Apps.Count; i++) { PiPhoneApp piPhoneApp = Apps[i]; if (piPhoneApp != null && piPhoneApp.ListedInStore) { list.Add(piPhoneApp); } } return list.ToArray(); } public static bool IsInstalled(string id) { return PhoneStore.IsInstalled(id); } public static bool CanUninstall(string id) { if (!TryGetApp(id, out var app) || app == null || app.Sticky) { return false; } return PhoneStore.IsInstalled(id); } public static bool Install(string id) { if (!TryGetApp(id, out var app) || app == null) { return false; } if (!PhoneStore.Install(id)) { return false; } RaiseAppsChanged(); PhoneMenu.OnAppsChanged(); return true; } public static bool IsOnHome(string id) { return PhoneStore.IsOnHome(id); } public static bool AddToHome(string id) { if (!PhoneStore.AddToHome(id)) { return false; } RaiseAppsChanged(); PhoneMenu.OnAppsChanged(); return true; } public static bool RemoveFromHome(string id) { if (!PhoneStore.RemoveFromHome(id)) { return false; } RaiseAppsChanged(); PhoneMenu.OnAppsChanged(); return true; } public static bool Uninstall(string id) { if (!CanUninstall(id)) { return false; } if (CurrentAppId == id) { PhoneMenu.GoHome(); } if (!PhoneStore.Uninstall(id)) { return false; } RaiseAppsChanged(); PhoneMenu.OnAppsChanged(); return true; } internal static int IndexOf(string id) { if (string.IsNullOrEmpty(id)) { return -1; } for (int i = 0; i < Apps.Count; i++) { if (Apps[i] != null && string.Equals(Apps[i].Id, id, StringComparison.OrdinalIgnoreCase)) { return i; } } return -1; } private static void SortApps() { Apps.Sort(CompareApps); } private static int CompareApps(PiPhoneApp a, PiPhoneApp b) { int num = ((b != null && b.ShowOnDock) ? 1 : 0) - ((a != null && a.ShowOnDock) ? 1 : 0); if (num != 0) { return num; } int num2 = (a?.SortOrder ?? 0).CompareTo(b?.SortOrder ?? 0); if (num2 != 0) { return num2; } string strA = ((a != null) ? a.DisplayName : string.Empty); string strB = ((b != null) ? b.DisplayName : string.Empty); return string.Compare(strA, strB, StringComparison.OrdinalIgnoreCase); } private static void RaiseAppsChanged() { PiPhoneApi.AppsChanged?.Invoke(); } internal static void RaiseOrientation() { PiPhoneApi.OrientationChanged?.Invoke(); } } public enum PiPhonePlayThrough { Off, Walk, WalkAndCursor } public enum PiPhoneCarrier { None, Edge, ThreeG, Lte, FiveG } public sealed class PiPhoneContact { public string Id; public string CustomName; public string RealName; public string PhotoFile; public bool BlockCalls; public bool BlockTexts; } public sealed class PiPhoneCategory { public string Id; public string DisplayName; public int SortOrder; } public sealed class PiPhoneLook { public Color Screen = new Color(0.08f, 0.1f, 0.13f, 1f); public Color Surface = new Color(0.16f, 0.18f, 0.21f, 0.96f); public Color Nav = new Color(0.1f, 0.11f, 0.13f, 1f); public Color NavButton = new Color(0.2f, 0.22f, 0.26f, 1f); public Color NavIcon = new Color(0.96f, 0.97f, 0.98f, 1f); public Color Text = new Color(0.96f, 0.97f, 0.98f, 1f); public Color Accent = new Color(0.24f, 0.86f, 0.52f, 1f); public Color Icon = Color.white; public Color Case = new Color(0.07f, 0.07f, 0.08f, 1f); public Color Clock = new Color(0.96f, 0.97f, 0.98f, 1f); public Color ButtonFill = new Color(0.2f, 0.22f, 0.26f, 1f); public Color ButtonText = new Color(0.96f, 0.97f, 0.98f, 1f); public float FontScale = 1f; public int ButtonRadius = 18; public int IconRadius = 20; } public sealed class PiPhoneApp { public string Id; public string DisplayName; public string IconGlyph; public Color IconBackground = new Color(0.22f, 0.45f, 0.72f, 1f); public Color IconForeground = Color.white; public Sprite IconSprite; public int SortOrder; public bool ShowOnDock; public bool ShowOnHome = true; public bool Preinstalled; public bool ListedInStore = true; public string Category; public string Description; private readonly List<Sprite> _screenshots = new List<Sprite>(); public bool Sticky; public bool PostsNotices = true; public bool AllowPlayThrough = true; public string BundledAlertPath; public bool Landscape; public bool Fullscreen; public bool CoversWallpaper = true; public bool Immersive; public bool ApplyPhoneFonts = true; public Action<IPiPhoneHost> OnOpen; public Action OnClose; public Func<bool> OnBack; public Action OnOrientation; public Sprite[] Screenshots => _screenshots.ToArray(); public bool SetIcon(byte[] pngOrJpg) { Sprite val = PhoneIcons.FromBytes(pngOrJpg); if ((Object)(object)val == (Object)null) { return false; } IconSprite = val; return true; } public void SetIcon(Texture2D texture) { IconSprite = PhoneIcons.FromTexture(texture, consumeSource: false); } public bool SetIconFile(string path) { Sprite val = PhoneIcons.FromFile(path); if ((Object)(object)val == (Object)null) { return false; } IconSprite = val; return true; } public bool AddScreenshot(byte[] pngOrJpg) { return AddScreenshot(PhoneIcons.FromBytes(pngOrJpg, allowOversizeFile: true, 480)); } public bool AddScreenshot(Texture2D texture) { return AddScreenshot(PhoneIcons.Screenshot(texture)); } public bool AddScreenshot(Sprite sprite) { if ((Object)(object)sprite == (Object)null || _screenshots.Count >= 8) { return false; } Sprite val = PhoneIcons.ClampSprite(sprite, 480); if ((Object)(object)val == (Object)null) { return false; } _screenshots.Add(val); return true; } } public sealed class PiPhoneKeybind { public string Id; public string Label; public string Group = "Apps"; public string AppId; public string[] AlsoApps; public KeyCode DefaultKey; public KeyCode DefaultModifier; public KeyCode Key; public KeyCode Modifier; public bool WithModifier; public bool Global; public bool PhoneOpen; public bool Required; public int SortOrder; public Action OnPressed; } public sealed class PiPhoneNavButton { public string Id; public string Glyph; public Sprite Icon; public Func<Sprite> IconFn; public bool TintIcon = true; public int SortOrder = 100; public Action OnClick; public Func<bool> Available; } public sealed class PiPhoneShadeButton { public string Id; public string Label; public string Glyph; public Sprite Icon; public bool UseText; public int SortOrder = 100; public bool DefaultVisible = true; public Action OnClick; public Func<bool> IsActive; public Func<bool> Available; public bool CanHide = true; public Func<string> GlyphFn; public Func<Sprite> IconFn; } public interface IPiPhoneHost { RectTransform Content { get; } bool IsMasterClient { get; } bool IsLandscape { get; } bool IsFullscreen { get; } bool IsPlayThrough { get; } PiPhonePlayThrough PlayThroughMode { get; } void SetTitle(string title); void GoHome(); void GoBack(); void ClosePhone(); void ShowToast(string message); Coroutine StartHostCoroutine(IEnumerator routine); Button CreateButton(Transform parent, string label, UnityAction onClick, Vector2 size); void SetLandscape(bool landscape); void SetFullscreen(bool fullscreen); void SetImmersive(bool immersive); void ToggleLandscape(); void SetPlayThrough(bool on); void SetPlayThrough(PiPhonePlayThrough mode); void TogglePlayThrough(); void SetWallpaperPaused(bool paused); } public sealed class PiPhoneScout { public string Id; public string Name; public int ActorNumber; public bool IsLocal; public bool IsDead; public bool IsGhost; public bool IsPassedOut; public bool IsFullyPassedOut; public bool IsFullyConscious; public float PassOutValue; public float DeathTimer; public float DeathLeft; public float DeathSecondsLeft; public float TimeSinceDied; public bool IsInFog; public bool IsInWater; public bool IsCarried; public string CarrierId; public string CarrierName; public int CarrierActor; public bool IsCarrying; public string CarriedId; public string CarriedName; public int CarriedActor; public Vector3 Position; public Vector3 VoicePosition; } internal static class ScoutQuery { internal static PiPhoneScout Local() { try { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null) { return FromCharacter(localCharacter); } } catch { } return null; } internal static bool LocalIsDead() { return Local()?.IsDead ?? false; } internal static bool LocalIsGhost() { return Local()?.IsGhost ?? false; } internal static PiPhoneScout[] All(bool othersOnly) { List<PiPhoneScout> list = new List<PiPhoneScout>(); try { List<Character> allCharacters = Character.AllCharacters; if (allCharacters == null) { return list.ToArray(); } for (int i = 0; i < allCharacters.Count; i++) { Character val = allCharacters[i]; if ((Object)(object)val == (Object)null) { continue; } try { if (val.isBot) { continue; } } catch { } PiPhoneScout piPhoneScout = FromCharacter(val); if (piPhoneScout != null && (!othersOnly || !piPhoneScout.IsLocal)) { list.Add(piPhoneScout); } } } catch { } return list.ToArray(); } internal static PiPhoneScout[] Where(Func<PiPhoneScout, bool> match) { PiPhoneScout[] array = All(othersOnly: false); if (match == null) { return array; } List<PiPhoneScout> list = new List<PiPhoneScout>(); for (int i = 0; i < array.Length; i++) { if (array[i] != null && match(array[i])) { list.Add(array[i]); } } return list.ToArray(); } internal static bool TryById(string id, out PiPhoneScout scout) { scout = null; if (string.IsNullOrEmpty(id)) { return false; } PiPhoneScout[] array = All(othersOnly: false); for (int i = 0; i < array.Length; i++) { if (array[i] != null && string.Equals(array[i].Id, id, StringComparison.Ordinal)) { scout = array[i]; return true; } } return false; } internal static bool TryByActor(int actor, out PiPhoneScout scout) { scout = null; if (actor <= 0) { return false; } PiPhoneScout[] array = All(othersOnly: false); for (int i = 0; i < array.Length; i++) { if (array[i] != null && array[i].ActorNumber == actor) { scout = array[i]; return true; } } return false; } private static PiPhoneScout FromCharacter(Character character) { //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null) { return null; } PiPhoneScout piPhoneScout = new PiPhoneScout(); Player val = null; try { if ((Object)(object)((MonoBehaviourPun)character).photonView != (Object)null) { val = ((MonoBehaviourPun)character).photonView.Owner; } } catch { } if (val != null) { piPhoneScout.Id = BuiltinApps.PlayerId(val); piPhoneScout.Name = BuiltinApps.PlayerName(val); piPhoneScout.ActorNumber = val.ActorNumber; piPhoneScout.IsLocal = val.IsLocal; } else { piPhoneScout.Id = (character.IsLocal ? BuiltinApps.LocalId() : "unknown"); piPhoneScout.Name = (character.IsLocal ? BuiltinApps.LocalName() : "Scout"); piPhoneScout.IsLocal = character.IsLocal; } try { if (character.IsLocal) { piPhoneScout.IsLocal = true; } } catch { } try { CharacterData data = character.data; if ((Object)(object)data != (Object)null) { piPhoneScout.IsDead = data.dead; piPhoneScout.IsFullyPassedOut = data.fullyPassedOut; piPhoneScout.IsPassedOut = data.passedOut || data.fullyPassedOut; piPhoneScout.IsFullyConscious = data.fullyConscious; piPhoneScout.PassOutValue = data.passOutValue; piPhoneScout.DeathTimer = Mathf.Clamp01(data.deathTimer); piPhoneScout.DeathLeft = (piPhoneScout.IsDead ? 0f : Mathf.Clamp01(1f - piPhoneScout.DeathTimer)); if (piPhoneScout.IsFullyPassedOut && !piPhoneScout.IsDead) { piPhoneScout.DeathSecondsLeft = piPhoneScout.DeathLeft * 60f; } if (data.dead) { piPhoneScout.TimeSinceDied = data.sinceDied; } piPhoneScout.IsInFog = data.isInFog; try { piPhoneScout.IsInWater = data.isInWater; } catch { } piPhoneScout.IsCarried = data.isCarried || (Object)(object)data.carrier != (Object)null; FillPeer(data.carrier, out piPhoneScout.CarrierId, out piPhoneScout.CarrierName, out piPhoneScout.CarrierActor); piPhoneScout.IsCarrying = data.IsCarryingCharacter || (Object)(object)data.carriedPlayer != (Object)null; FillPeer(data.carriedPlayer, out piPhoneScout.CarriedId, out piPhoneScout.CarriedName, out piPhoneScout.CarriedActor); } } catch { } try { piPhoneScout.IsGhost = character.IsGhost; } catch { } piPhoneScout.Position = WorldPos(character); piPhoneScout.VoicePosition = VoicePos(character); return piPhoneScout; } private static Vector3 WorldPos(Character character) { //IL_007f: 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) //IL_001d: 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_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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_005f: 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) try { if ((Object)(object)character.Ghost != (Object)null) { return ((Component)character.Ghost).transform.position; } } catch { } try { if (character.refs != null && (Object)(object)character.refs.head != (Object)null) { return character.refs.head.transform.position; } } catch { } try { return character.Center; } catch { } return Vector3.zero; } private static Vector3 VoicePos(Character character) { //IL_003d: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) try { CharacterVoiceHandler componentInChildren = ((Component)character).GetComponentInChildren<CharacterVoiceHandler>(); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.m_transformProvider != (Object)null) { return componentInChildren.m_transformProvider.GetVoicePosition(false); } } catch { } return WorldPos(character); } private static void FillPeer(Character other, out string id, out string name, out int actor) { id = null; name = null; actor = 0; if ((Object)(object)other == (Object)null) { return; } actor = ActorOf(other); Player val = null; try { if ((Object)(object)((MonoBehaviourPun)other).photonView != (Object)null) { val = ((MonoBehaviourPun)other).photonView.Owner; } } catch { } if (val != null) { id = BuiltinApps.PlayerId(val); name = BuiltinApps.PlayerName(val); actor = val.ActorNumber; } else { id = (other.IsLocal ? BuiltinApps.LocalId() : "unknown"); name = (other.IsLocal ? BuiltinApps.LocalName() : "Scout"); } } internal static int ActorOf(Character character) { if ((Object)(object)character == (Object)null) { return 0; } try { if ((Object)(object)((MonoBehaviourPun)character).photonView != (Object)null && ((MonoBehaviourPun)character).photonView.Owner != null) { return ((MonoBehaviourPun)character).photonView.Owner.ActorNumber; } } catch { } return 0; } internal static CharacterVoiceHandler HandlerOf(Character character) { if ((Object)(object)character == (Object)null) { return null; } try { return ((Component)character).GetComponentInChildren<CharacterVoiceHandler>(); } catch { return null; } } internal static CharacterVoiceHandler HandlerById(string id) { if (string.IsNullOrEmpty(id)) { return null; } try { List<Character> allCharacters = Character.AllCharacters; if (allCharacters == null) { return null; } for (int i = 0; i < allCharacters.Count; i++) { Character val = allCharacters[i]; if ((Object)(object)val == (Object)null) { continue; } Player val2 = null; try { if ((Object)(object)((MonoBehaviourPun)val).photonView != (Object)null) { val2 = ((MonoBehaviourPun)val).photonView.Owner; } } catch { } if (val2 != null && string.Equals(BuiltinApps.PlayerId(val2), id, StringComparison.Ordinal)) { return HandlerOf(val); } } } catch { } return null; } internal static CharacterVoiceHandler HandlerByActor(int actor) { if (actor <= 0) { return null; } try { List<Character> allCharacters = Character.AllCharacters; if (allCharacters == null) { return null; } for (int i = 0; i < allCharacters.Count; i++) { Character character = allCharacters[i]; if (ActorOf(character) == actor) { return HandlerOf(character); } } } catch { } return null; } } public sealed class PiPhoneVoiceFilter { public bool LowPass; public float LowPassCutoff = 7500f; public float LowPassResonance = 1f; public bool HighPass; public float HighPassCutoff = 10f; public float HighPassResonance = 1f; public bool Reverb; public AudioReverbPreset ReverbPreset = (AudioReverbPreset)0; public bool Echo; public float EchoWet; public float EchoDry = 1f; public float EchoDelay = 10f; public float EchoDecay; public static PiPhoneVoiceFilter Dry() { return new PiPhoneVoiceFilter(); } public static PiPhoneVoiceFilter Realm() { //IL_004a: Unknown result type (might be due to invalid IL or missing references) return new PiPhoneVoiceFilter { LowPass = true, LowPassCutoff = 2800f, LowPassResonance = 1.05f, HighPass = true, HighPassCutoff = 900f, HighPassResonance = 1f, Reverb = true, ReverbPreset = (AudioReverbPreset)9, Echo = true, EchoWet = 0.22f, EchoDry = 0.7f, EchoDelay = 280f, EchoDecay = 0.25f }; } internal PiPhoneVoiceFilter Clone() { //IL_005c: 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) return new PiPhoneVoiceFilter { LowPass = LowPass, LowPassCutoff = LowPassCutoff, LowPassResonance = LowPassResonance, HighPass = HighPass, HighPassCutoff = HighPassCutoff, HighPassResonance = HighPassResonance, Reverb = Reverb, ReverbPreset = ReverbPreset, Echo = Echo, EchoWet = EchoWet, EchoDry = EchoDry, EchoDelay = EchoDelay, EchoDecay = EchoDecay }; } } internal static class VoiceFx { [HarmonyPatch(typeof(VoiceObscuranceFilter), "Update")] private static class Patch_VoiceFx { private static bool Prefix(VoiceObscuranceFilter __instance) { try { if (!TryOverride(__instance, out var spec)) { return true; } Write(__instance, spec); return false; } catch (Exception ex) { LogOnce("Voice filter patch failed: " + ex.Message); return true; } } } private static readonly Dictionary<int, PiPhoneVoiceFilter> ApiHold = new Dictionary<int, PiPhoneVoiceFilter>(); private static readonly Dictionary<int, PiPhoneVoiceFilter> CallLayer = new Dictionary<int, PiPhoneVoiceFilter>(); private static readonly Dictionary<int, PiPhoneVoiceFilter> VanillaSnap = new Dictionary<int, PiPhoneVoiceFilter>(); private static bool _logged; internal static bool TryGet(string id, out PiPhoneVoiceFilter filter) { filter = null; CharacterVoiceHandler handler = ScoutQuery.HandlerById(id); return TryRead(handler, out filter); } internal static bool TryGet(int actor, out PiPhoneVoiceFilter filter) { filter = null; CharacterVoiceHandler handler = ScoutQuery.HandlerByActor(actor); return TryRead(handler, out filter); } internal static bool SetHold(string id, PiPhoneVoiceFilter spec) { return SetHold(ScoutQuery.HandlerById(id), spec); } internal static bool SetHold(int actor, PiPhoneVoiceFilter spec) { return SetHold(ScoutQuery.HandlerByActor(actor), spec); } internal static bool ClearHold(string id) { return ClearHoldActor(ActorFromId(id)); } internal static bool ClearHold(int actor) { return ClearHoldActor(actor); } internal static void ClearAllHolds() { List<int> list = new List<int>(ApiHold.Keys); ApiHold.Clear(); for (int i = 0; i < list.Count; i++) { MaybeRestore(list[i]); } } internal static bool IsHeld(string id) { int num = ActorFromId(id); return num > 0 && ApiHold.ContainsKey(num); } internal static void SetCallLayer(CharacterVoiceHandler handler, PiPhoneVoiceFilter spec) { int num = ActorOf(handler); if (num > 0 && spec != null) { RememberVanilla(num, ((Object)(object)handler != (Object)null) ? handler.voiceObscuranceFilter : null); CallLayer[num] = spec.Clone(); Write(((Object)(object)handler != (Object)null) ? handler.voiceObscuranceFilter : null, spec); } } internal static void ClearCallLayer(CharacterVoiceHandler handler) { int num = ActorOf(handler); if (num > 0) { CallLayer.Remove(num); MaybeRestore(num); } } internal static void ClearAllCallLayers() { List<int> list = new List<int>(CallLayer.Keys); CallLayer.Clear(); for (int i = 0; i < list.Count; i++) { MaybeRestore(list[i]); } } internal static bool HasCallLayer(CharacterVoiceHandler handler) { int num = ActorOf(handler); return num > 0 && CallLayer.ContainsKey(num); } private static bool SetHold(CharacterVoiceHandler handler, PiPhoneVoiceFilter spec) { int num = ActorOf(handler); if (num <= 0 || spec == null) { return false; } RememberVanilla(num, handler.voiceObscuranceFilter); ApiHold[num] = spec.Clone(); Write(handler.voiceObscuranceFilter, spec); return true; } private static bool ClearHoldActor(int actor) { if (actor <= 0 || !ApiHold.Remove(actor)) { return false; } MaybeRestore(actor); return true; } private static void RememberVanilla(int actor, VoiceObscuranceFilter fx) { if (actor > 0 && !((Object)(object)fx == (Object)null) && !VanillaSnap.ContainsKey(actor)) { VanillaSnap[actor] = Read(fx); } } private static void MaybeRestore(int actor) { if (actor > 0 && !CallLayer.ContainsKey(actor) && !ApiHold.ContainsKey(actor)) { CharacterVoiceHandler val = ScoutQuery.HandlerByActor(actor); VoiceObscuranceFilter val2 = (((Object)(object)val != (Object)null) ? val.voiceObscuranceFilter : null); if (VanillaSnap.TryGetValue(actor, out var value)) { Write(val2, value); VanillaSnap.Remove(actor); } if ((Object)(object)val2 != (Object)null) { ((Behaviour)val2).enabled = true; } } } private static bool TryRead(CharacterVoiceHandler handler, out PiPhoneVoiceFilter filter) { filter = null; if ((Object)(object)handler == (Object)null || (Object)(object)handler.voiceObscuranceFilter == (Object)null) { return false; } filter = Read(handler.voiceObscuranceFilter); return true; } private static PiPhoneVoiceFilter Read(VoiceObscuranceFilter fx) { //IL_00b3: 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) PiPhoneVoiceFilter piPhoneVoiceFilter = new PiPhoneVoiceFilter(); if ((Object)(object)fx == (Object)null) { return piPhoneVoiceFilter; } AudioLowPassFilter lowPass = fx.lowPass; if ((Object)(object)lowPass != (Object)null) { piPhoneVoiceFilter.LowPass = ((Behaviour)lowPass).enabled; piPhoneVoiceFilter.LowPassCutoff = lowPass.cutoffFrequency; piPhoneVoiceFilter.LowPassResonance = lowPass.lowpassResonanceQ; } AudioHighPassFilter highPass = fx.highPass; if ((Object)(object)highPass != (Object)null) { piPhoneVoiceFilter.HighPass = ((Behaviour)highPass).enabled; piPhoneVoiceFilter.HighPassCutoff = highPass.cutoffFrequency; piPhoneVoiceFilter.HighPassResonance = highPass.highpassResonanceQ; } AudioReverbFilter reverb = fx.reverb; if ((Object)(object)reverb != (Object)null) { piPhoneVoiceFilter.Reverb = ((Behaviour)reverb).enabled; piPhoneVoiceFilter.ReverbPreset = reverb.reverbPreset; } AudioEchoFilter echo = fx.echo; if ((Object)(object)echo != (Object)null) { piPhoneVoiceFilter.Echo = ((Behaviour)echo).enabled; piPhoneVoiceFilter.EchoWet = echo.wetMix; piPhoneVoiceFilter.EchoDry = echo.dryMix; piPhoneVoiceFilter.EchoDelay = echo.delay; piPhoneVoiceFilter.EchoDecay = echo.decayRatio; } return piPhoneVoiceFilter; } internal static void Write(VoiceObscuranceFilter fx, PiPhoneVoiceFilter spec) { //IL_00e2: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)fx == (Object)null || spec == null) { return; } try { AudioLowPassFilter lowPass = fx.lowPass; if ((Object)(object)lowPass != (Object)null) { ((Behaviour)lowPass).enabled = spec.LowPass; if (spec.LowPass) { lowPass.cutoffFrequency = spec.LowPassCutoff; lowPass.lowpassResonanceQ = spec.LowPassResonance; } } AudioHighPassFilter highPass = fx.highPass; if ((Object)(object)highPass != (Object)null) { ((Behaviour)highPass).enabled = spec.HighPass; if (spec.HighPass) { highPass.cutoffFrequency = spec.HighPassCutoff; highPass.highpassResonanceQ = spec.HighPassResonance; } } AudioReverbFilter reverb = fx.reverb; if ((Object)(object)reverb != (Object)null) { ((Behaviour)reverb).enabled = spec.Reverb; if (spec.Reverb) { reverb.reverbPreset = spec.ReverbPreset; } } AudioEchoFilter echo = fx.echo; if ((Object)(object)echo != (Object)null) { ((Behaviour)echo).enabled = spec.Echo; echo.wetMix = (spec.Echo ? spec.EchoWet : 0f); echo.dryMix = (spec.Echo ? spec.EchoDry : 1f); echo.delay = (spec.Echo ? spec.EchoDelay : 10f); echo.decayRatio = (spec.Echo ? spec.EchoDecay : 0f); } } catch (Exception ex) { LogOnce("Voice filter write failed: " + ex.Message); } } private static bool TryOverride(VoiceObscuranceFilter fx, out PiPhoneVoiceFilter spec) { spec = null; if ((Object)(object)fx == (Object)null || (Object)(object)fx._voiceHandler == (Object)null) { return false; } int num = ActorOf(fx._voiceHandler); if (num <= 0) { return false; } if (CallLayer.TryGetValue(num, out spec)) { return true; } return ApiHold.TryGetValue(num, out spec); } private static int ActorOf(CharacterVoiceHandler handler) { if ((Object)(object)handler == (Object)null) { return 0; } return ScoutQuery.ActorOf(handler.m_character); } private static int ActorFromId(string id) { CharacterVoiceHandler handler = ScoutQuery.HandlerById(id); return ActorOf(handler); } private static void LogOnce(string message) { if (!_logged) { _logged = true; Plugin.LogError(message); } } } internal static class PhoneKeys { private struct Saved { public KeyCode Key; public KeyCode Modifier; } public const string Open = "pip.open"; public const string Landscape = "pip.landscape"; public const string Answer = "pip.answer"; public const string Decline = "pip.decline"; public const string CamCursor = "pip.camera.cursor"; public const string CamFlip = "pip.camera.flip"; public const string CamRotate = "pip.camera.rotate"; public const string CamShutter = "pip.camera.shutter"; public const string CamZoomIn = "pip.camera.zoomin"; public const string CamZoomOut = "pip.camera.zoomout"; public const string MusicPlay = "pip.music.play"; public const string MusicNext = "pip.music.next"; public const string MusicPrev = "pip.music.prev"; public const string GameUp = "pip.games.up"; public const string GameDown = "pip.games.down"; public const string GameLeft = "pip.games.left"; public const string GameRight = "pip.games.right"; public const string TetrisRotate = "pip.tetris.rotate"; public const string TetrisDrop = "pip.tetris.drop"; public const string BreakoutServe = "pip.breakout.serve"; private static readonly List<PiPhoneKeybind> Binds = new List<PiPhoneKeybind>(24); private static readonly Dictionary<string, Saved> SavedKeys = new Dictionary<string, Saved>(StringComparer.OrdinalIgnoreCase); private static string _captureId; private static Action _captureDone; private static bool _fileLoaded; public static event Action Changed; public static void RegisterBuiltins() { //IL_005a: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_023a: Unknown result type (might be due to invalid IL or missing references) //IL_0281: Unknown result type (might be due to invalid IL or missing references) //IL_02c8: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_043c: Unknown result type (might be due to invalid IL or missing references) //IL_0492: Unknown result type (might be due to invalid IL or missing references) //IL_04d5: Unknown result type (might be due to invalid IL or missing references) //IL_0518: Unknown result type (might be due to invalid IL or missing references) //IL_055b: Unknown result type (might be due to invalid IL or missing references) //IL_05a8: Unknown result type (might be due to invalid IL or missing references) //IL_05ef: Unknown result type (might be due to invalid IL or missing references) //IL_0636: Unknown result type (might be due to invalid IL or missing references) string[] alsoApps = new string[5] { "pip.snake", "pip.2048", "pip.mines", "pip.tetris", "pip.breakout" }; PiPhoneKeybind piPhoneKeybind = new PiPhoneKeybind(); piPhoneKeybind.Id = "pip.open"; piPhoneKeybind.Label = "Open phone"; piPhoneKeybind.Group = "Phone"; piPhoneKeybind.DefaultKey = (KeyCode)112; piPhoneKeybind.DefaultModifier = (KeyCode)308; piPhoneKeybind.WithModifier = true; piPhoneKeybind.Global = true; piPhoneKeybind.Required = true; piPhoneKeybind.SortOrder = 0; piPhoneKeybind.OnPressed = PhoneMenu.Toggle; Add(piPhoneKeybind); piPhoneKeybind = new PiPhoneKeybind(); piPhoneKeybind.Id = "pip.landscape"; piPhoneKeybind.Label = "Rotate phone"; piPhoneKeybind.Group = "Phone"; piPhoneKeybind.DefaultKey = (KeyCode)284; piPhoneKeybind.PhoneOpen = true; piPhoneKeybind.SortOrder = 1; piPhoneKeybind.OnPressed = PhoneMenu.ToggleUserLandscape; Add(piPhoneKeybind); piPhoneKeybind = new PiPhoneKeybind(); piPhoneKeybind.Id = "pip.answer"; piPhoneKeybind.Label = "Answer call / open text"; piPhoneKeybind.Group = "Alerts"; piPhoneKeybind.DefaultKey = (KeyCode)282; piPhoneKeybind.Global = true; piPhoneKeybind.SortOrder = 10; piPhoneKeybind.OnPressed = AlertHud.HotkeyAnswer; Add(piPhoneKeybind); piPhoneKeybind = new PiPhoneKeybind(); piPhoneKeybind.Id = "pip.decline"; piPhoneKeybind.Label = "Decline call / dismiss text"; piPhoneKeybind.Group = "Alerts"; piPhoneKeybind.DefaultKey = (KeyCode)283; piPhoneKeybind.Global = true; piPhoneKeybind.SortOrder = 11; piPhoneKeybind.OnPressed = AlertHud.HotkeyDecline; Add(piPhoneKeybind); piPhoneKeybind = new PiPhoneKeybind(); piPhoneKeybind.Id = "pip.camera.cursor"; piPhoneKeybind.Label = "Walk around"; piPhoneKeybind.Group = "Phone"; piPhoneKeybind.PhoneOpen = true; piPhoneKeybind.DefaultKey = (KeyCode)308; piPhoneKeybind.SortOrder = 20; piPhoneKeybind.OnPressed = PhoneMenu.TogglePlayThrough; Add(piPhoneKeybind); Add(new PiPhoneKeybind { Id = "pip.camera.flip", Label = "Flip camera", Group = "Camera", AppId = "pip.camera", DefaultKey = (KeyCode)102, SortOrder = 21 }); Add(new PiPhoneKeybind { Id = "pip.camera.rotate", Label = "Tall / wide", Group = "Camera", AppId = "pip.camera", DefaultKey = (KeyCode)114, SortOrder = 22 }); Add(new PiPhoneKeybind { Id = "pip.camera.shutter", Label = "Shutter", Group = "Camera", AppId = "pip.camera", DefaultKey = (KeyCode)118, SortOrder = 23 }); Add(new PiPhoneKeybind { Id = "pip.camera.zoomin", Label = "Zoom in", Group = "Camera", AppId = "pip.camera", DefaultKey = (KeyCode)0, SortOrder = 24 }); Add(new PiPhoneKeybind { Id = "pip.camera.zoomout", Label = "Zoom out", Group = "Camera", AppId = "pip.camera", DefaultKey = (KeyCode)0, SortOrder = 25 }); piPhoneKeybind = new PiPhoneKeybind(); piPhoneKeybind.Id = "pip.music.play"; piPhoneKeybind.Label = "Play / pause music"; piPhoneKeybind.Group = "Music"; piPhoneKeybind.DefaultKey = (KeyCode)0; piPhoneKeybind.Global = true; piPhoneKeybind.SortOrder = 30; piPhoneKeybind.OnPressed = MusicPlayer.Toggle; Add(piPhoneKeybind); piPhoneKeybind = new PiPhoneKeybind(); piPhoneKeybind.Id = "pip.music.next"; piPhoneKeybind.Label = "Next song"; piPhoneKeybind.Group = "Music"; piPhoneKeybind.DefaultKey = (KeyCode)0; piPhoneKeybind.Global = true; piPhoneKeybind.SortOrder = 31; piPhoneKeybind.OnPressed = MusicPlayer.Next; Add(piPhoneKeybind); piPhoneKeybind = new PiPhoneKeybind(); piPhoneKeybind.Id = "pip.music.prev"; piPhoneKeybind.Label = "Previous song"; piPhoneKeybind.Group = "Music"; piPhoneKeybind.DefaultKey = (KeyCode)0; piPhoneKeybind.Global = true; piPhoneKeybind.SortOrder = 32; piPhoneKeybind.OnPressed = MusicPlayer.Prev; Add(piPhoneKeybind); Add(new PiPhoneKeybind { Id = "pip.games.up", Label = "Up", Group = "Games", DefaultKey = (KeyCode)119, AlsoApps = alsoApps, SortOrder = 40 }); Add(new PiPhoneKeybind { Id = "pip.games.down", Label = "Down", Group = "Games", DefaultKey = (KeyCode)115, AlsoApps = alsoApps, SortOrder = 41 }); Add(new PiPhoneKeybind { Id = "pip.games.left", Label = "Left", Group = "Games", DefaultKey = (KeyCode)97, AlsoApps = alsoApps, SortOrder = 42 }); Add(new PiPhoneKeybind { Id = "pip.games.right", Label = "Right", Group = "Games", DefaultKey = (KeyCode)100, AlsoApps = alsoApps, SortOrder = 43 }); Add(new PiPhoneKeybind { Id = "pip.tetris.rotate", Label = "Rotate", Group = "Stacker", AppId = "pip.tetris", DefaultKey = (KeyCode)0, SortOrder = 50 }); Add(new PiPhoneKeybind { Id = "pip.tetris.drop", Label = "Hard drop", Group = "Stacker", AppId = "pip.tetris", DefaultKey = (KeyCode)32, SortOrder = 51 }); Add(new PiPhoneKeybind { Id = "pip.breakout.serve", Label = "Serve", Group = "Brick Break", AppId = "pip.breakout", DefaultKey = (KeyCode)32, SortOrder = 60 }); } public static void Add(PiPhoneKeybind bind) { //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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: 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_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) if (bind != null && !string.IsNullOrEmpty(bind.Id)) { int num = IndexOf(bind.Id); if (num >= 0) { bind.Key = Binds[num].Key; bind.Modifier = Binds[num].Modifier; Binds[num] = bind; } else { bind.Key = bind.DefaultKey; bind.Modifier = bind.DefaultModifier; Binds.Add(bind); } ApplySaved(bind); EnforceRequired(bind); Sort(); RaiseChanged(); } } public static bool Remove(string id) { int num = IndexOf(id); if (num < 0) { return false; } Binds.RemoveAt(num); RaiseChanged(); return true; } public static PiPhoneKeybind Find(string id) { int num = IndexOf(id); return (num >= 0) ? Binds[num] : null; } public static PiPhoneKeybind[] All() { return Binds.ToArray(); } public static bool Down(string id) { PiPhoneKeybind bind = Find(id); return Down(bind); } public static bool Held(string id) { //IL_0025: 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) PiPhoneKeybind piPhoneKeybind = Find(id); if (!Ready(piPhoneKeybind) || !ShouldFire(piPhoneKeybind)) { return false; } if (!Input.GetKey(piPhoneKeybind.Key)) { return false; } return ModifierOk(piPhoneKeybind.Modifier); } public static string Format(string id) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) PiPhoneKeybind piPhoneKeybind = Find(id); if (piPhoneKeybind == null) { return "None"; } return Format(piPhoneKeybind.Key, piPhoneKeybind.Modifier); } public static string Format(KeyCode key, KeyCode modifier) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_0022: 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_0019: Unknown result type (might be due to invalid IL or missing references) if ((int)key == 0) { return "None"; } if ((int)modifier == 0) { return Pretty(key); } return Pretty(modifier) + "+" + Pretty(key); } public unsafe static string Pretty(KeyCode key) { //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_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //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_000d: Invalid comparison between Unknown and I4 //IL_0011: 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_0035: Expected I4, but got Unknown KeyCode val = key; KeyCode val2 = val; if ((int)val2 != 0) { if ((int)val2 != 32) { switch (val2 - 303) { case 2: case 3: return "Ctrl"; case 4: case 5: return "Alt"; case 0: case 1: return "Shift"; default: return ((object)(*(KeyCode*)(&key))/*cast due to .constrained prefix*/).ToString(); } } return "Space"; } return "None"; } public static void Set(string id, KeyCode key, KeyCode modifier) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_003e: 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_0045: 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_005b: 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_0063: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_00da: 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) PiPhoneKeybind piPhoneKeybind = Find(id); if (piPhoneKeybind != null && (!piPhoneKeybind.Required || (int)key != 0)) { if (!piPhoneKeybind.WithModifier) { modifier = (KeyCode)0; } piPhoneKeybind.Key = key; piPhoneKeybind.Modifier = modifier; SavedKeys[id] = new Saved { Key = key, Modifier = modifier }; Save(); SyncConfig(piPhoneKeybind); switch (id) { case "pip.games.up": PhoneTheme.SnakeUp = key; break; case "pip.games.down": PhoneTheme.SnakeDown = key; break; case "pip.games.left": PhoneTheme.SnakeLeft = key; break; case "pip.games.right": PhoneTheme.SnakeRight = key; break; } RaiseChanged(); } } public static void Clear(string id) { PiPhoneKeybind piPhoneKeybind = Find(id); if (piPhoneKeybind != null && !piPhoneKeybind.Required) { Set(id, (KeyCode)0, (KeyCode)0); } } public static void BeginCapture(string id, Action onDone) { if (Find(id) != null) { _captureId = id; _captureDone = onDone; Plugin.CapturingHotkey = true; } } public static bool TickCapture() { //IL_006b: 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_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) if (!Plugin.CapturingHotkey || string.IsNullOrEmpty(_captureId)) { return Plugin.CapturingHotkey; } if (Input.GetKeyDown((KeyCode)27)) { EndCapture(); return true; } PiPhoneKeybind piPhoneKeybind = Find(_captureId); foreach (KeyCode value in Enum.GetValues(typeof(KeyCode))) { if (IsIgnored(value, piPhoneKeybind?.WithModifier ?? false) || !Input.GetKeyDown(value)) { continue; } KeyCode modifier = (KeyCode)0; if (piPhoneKeybind != null && piPhoneKeybind.WithModifier) { if (Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305)) { modifier = (KeyCode)306; } else if (Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307)) { modifier = (KeyCode)308; } else if (Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)) { modifier = (KeyCode)304; } } Set(_captureId, value, modifier); EndCapture(); return true; } return true; } public static void FirePressed() { if (Plugin.CapturingHotkey) { return; } for (int i = 0; i < Binds.Count; i++) { PiPhoneKeybind piPhoneKeybind = Binds[i]; if (piPhoneKeybind != null && piPhoneKeybind.OnPressed != null && (!(piPhoneKeybind.Id == "pip.open") || !PhoneUi.IsTyping()) && Down(piPhoneKeybind)) { try { piPhoneKeybind.OnPressed(); } catch (Exception ex) { Plugin.LogError("Keybind '" + piPhoneKeybind.Id + "': " + ex.Message); } } } } public static void Load() { //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: 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) SavedKeys.Clear(); string path = Path.Combine(PhoneStore.RootDir, "keys.txt"); _fileLoaded = File.Exists(path); if (_fileLoaded) { try { string[] array = File.ReadAllLines(path); foreach (string text in array) { int num = text.IndexOf('='); if (num > 0) { string text2 = text.Substring(0, num).Trim(); string val = text.Substring(num + 1).Trim(); bool flag = text2.EndsWith(".mod", StringComparison.OrdinalIgnoreCase); string key = (flag ? text2.Substring(0, text2.Length - 4) : text2); KeyCode val2 = ParseKey(val, (KeyCode)0); SavedKeys.TryGetValue(key, out var value); if (flag) { value.Modifier = val2; } else { value.Key = val2; } SavedKeys[key] = value; } } } catch (Exception ex) { Plugin.LogError("Keybinds load failed: " + ex.Message); } } for (int j = 0; j < Binds.Count; j++) { ApplySaved(Binds[j]); } if (!_fileLoaded) { SeedFromLegacy(); } bool flag2 = false; for (int k = 0; k < Binds.Count; k++) { if (EnforceRequired(Binds[k])) { flag2 = true; } } if (flag2) { Save(); } } private static void SeedFromLegacy() { //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Invalid comparison between Unknown and I4 //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Invalid comparison between Unknown and I4 //IL_016f: 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_019e: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Invalid comparison between Unknown and I4 //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0067: 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_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Invalid comparison between Unknown and I4 //IL_01b5: Unknown result type (might be due to invalid IL or missing references) //IL_008d: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_0125: 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) Plugin instance = Plugin.Instance; if ((Object)(object)instance != (Object)null) { if (instance.MenuKey != null) { Set("pip.open", instance.MenuKey.Value, (KeyCode)((instance.MenuModifier != null) ? ((int)instance.MenuModifier.Value) : 0)); } if (instance.LandscapeKey != null) { Set("pip.landscape", instance.LandscapeKey.Value, (KeyCode)0); } if (instance.AnswerKey != null) { Set("pip.answer", instance.AnswerKey.Value, (KeyCode)0); } if (instance.DeclineKey != null) { Set("pip.decline", instance.DeclineKey.Value, (KeyCode)0); } if (instance.CameraCursorKey != null) { Set("pip.camera.cursor", instance.CameraCursorKey.Value, (KeyCode)0); } if (instance.CameraFlipKey != null) { Set("pip.camera.flip", instance.CameraFlipKey.Value, (KeyCode)0); } if (instance.CameraRotateKey != null) { Set("pip.camera.rotate", instance.CameraRotateKey.Value, (KeyCode)0); } if (instance.CameraShutterKey != null) { Set("pip.camera.shutter", instance.CameraShutterKey.Value, (KeyCode)0); } } if ((int)PhoneTheme.SnakeUp != 119) { Set("pip.games.up", PhoneTheme.SnakeUp, (KeyCode)0); } if ((int)PhoneTheme.SnakeDown != 115) { Set("pip.games.down", PhoneTheme.SnakeDown, (KeyCode)0); } if ((int)PhoneTheme.SnakeLeft != 97) { Set("pip.games.left", PhoneTheme.SnakeLeft, (KeyCode)0); } if ((int)PhoneTheme.SnakeRight != 100) { Set("pip.games.right", PhoneTheme.SnakeRight, (KeyCode)0); } Save(); } private static void Save() { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) try { PhoneStore.EnsureDir(); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < Binds.Count; i++) { PiPhoneKeybind piPhoneKeybind = Binds[i]; if (piPhoneKeybind != null) { stringBuilder.Append(piPhoneKeybind.Id).Append('=').Append(piPhoneKeybind.Key) .Append('\n'); if (piPhoneKeybind.WithModifier) { stringBuilder.Append(piPhoneKeybind.Id).Append(".mod=").Append(piPhoneKeybind.Modifier) .Append('\n'); } } } File.WriteAllText(Path.Combine(PhoneStore.RootDir, "keys.txt"), stringBuilder.ToString()); _fileLoaded = true; } catch (Exception ex) { Plugin.LogError("Keybinds save failed: " + ex.Message); } } private static bool Down(PiPhoneKeybind bind) { //IL_001e: 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) if (!Ready(bind) || !ShouldFire(bind)) { return false; } if (!Input.GetKeyDown(bind.Key)) { return false; } return ModifierOk(bind.Modifier); } private static bool Ready(PiPhoneKeybind bind) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Invalid comparison between Unknown and I4 return bind != null && (int)bind.Key > 0; } internal static bool ShouldFire(PiPhoneKeybind bind) { if (bind == null) { return false; } if (bind.Global) { return true; } if (!PhoneMenu.IsOpen) { return false; } if (bind.PhoneOpen && string.IsNullOrEmpty(bind.AppId) && (bind.AlsoApps == null || bind.AlsoApps.Length == 0)) { return true; } string currentAppId = PhoneMenu.CurrentAppId; if (string.IsNullOrEmpty(currentAppId)) { return false; } if (!string.IsNullOrEmpty(bind.AppId) && string.Equals(bind.AppId, currentAppId, StringComparison.OrdinalIgnoreCase)) { return true; } if (bind.AlsoApps == null) { return false; } for (int i = 0; i < bind.AlsoApps.Length; i++) { if (string.Equals(bind.AlsoApps[i], currentAppId, StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } private static bool ModifierOk(KeyCode modifier) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Invalid comparison between Unknown and I4 //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Invalid comparison between Unknown and I4 //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Invalid comparison between Unknown and I4 //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Invalid comparison between Unknown and I4 //IL_00ab: Unknown result type (might be due to invalid IL or missing references) if ((int)modifier == 0) { return true; } if ((int)modifier == 306 || (int)modifier == 305) { return Input.GetKey((KeyCode)306) || Input.GetKey((KeyCode)305); } if ((int)modifier == 308 || (int)modifier == 307) { return Input.GetKey((KeyCode)308) || Input.GetKey((KeyCode)307); } if ((int)modifier == 304 || (int)modifier == 303) { return Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); } return Input.GetKey(modifier); } private static void ApplySaved(PiPhoneKeybind bind) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 //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_005a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) if (bind != null && SavedKeys.TryGetValue(bind.Id, out var value) && (!bind.Required || (int)value.Key != 0)) { bind.Key = value.Key; if (bind.WithModifier) { bind.Modifier = value.Modifier; } } } private static bool EnforceRequired(PiPhoneKeybind bind) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Invalid comparison between Unknown and I4 //IL_0022: 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_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_004e: 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_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) if (bind == null || !bind.Required || (int)bind.Key > 0) { return false; } bind.Key = bind.DefaultKey; bind.Modifier = bind.DefaultModifier; SavedKeys[bind.Id] = new Saved { Key = bind.Key, Modifier = bind.Modifier }; return true; } private static void SyncConfig(PiPhoneKeybind bind) { //IL_0049: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Unknown result type (might be due to invalid IL or missing references) Plugin instance = Plugin.Instance; if ((Object)(object)instance == (Object)null || bind == null) { return; } if (bind.Id == "pip.open") { if (instance.MenuKey != null) { instance.MenuKey.Value = bind.Key; } if (instance.MenuModifier != null) { instance.MenuModifier.Value = bind.Modifier; } } else if (bind.Id == "pip.landscape" && instance.LandscapeKey != null) { instance.LandscapeKey.Value = bind.Key; } else if (bind.Id == "pip.answer" && instance.AnswerKey != null) { instance.AnswerKey.Value = bind.Key; } else if (bind.Id == "pip.decline" && instance.DeclineKey != null) { instance.DeclineKey.Value = bind.Key; } else if (bind.Id == "pip.camera.cursor" && instance.CameraCursorKey != null) { instance.CameraCursorKey.Value = bind.Key; } else if (bind.Id == "pip.camera.flip" && instance.CameraFlipKey != null) { instance.CameraFlipKey.Value = bind.Key; } else if (bind.Id == "pip.camera.rotate" && instance.CameraRotateKey != null) { instance.CameraRotateKey.Value = bind.Key; } else if (bind.Id == "pip.camera.shutter" && instance.CameraShutterKey != null) { instance.CameraShutterKey.Value = bind.Key; } } private static void EndCapture() { Plugin.CapturingHotkey = false; Plugin.CaptureEndedFrame = Time.frameCount; _captureId = null; Action captureDone = _captureDone; _captureDone = null; captureDone?.Invoke(); } private static bool IsIgnored(KeyCode key, bool modifiersAreMods) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected I4, but got Unknown //IL_0042: 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_0045: 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_0049: 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_0053: Invalid comparison between Unknown and I4 if ((int)key == 0 || (int)key == 27) { return true; } int num = (int)key; if (num >= 323 && num <= 329) { return true; } if (!modifiersAreMods) { return false; } if (key - 303 <= 10) { return true; } return false; } private static KeyCode ParseKey(string val, KeyCode fallback) { //IL_002c: 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_000b: 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_0030: 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_0027: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(val)) { return fallback; } try { return (KeyCode)Enum.Parse(typeof(KeyCode), val, ignoreCase: true); } catch { return fallback; } } private static int IndexOf(string id) { if (string.IsNullOrEmpty(id)) { return -1; } for (int i = 0; i < Binds.Count; i++) { if (Binds[i] != null && string.Equals(Binds[i].Id, id, StringComparison.OrdinalIgnoreCase)) { return i; } } return -1; } private static void Sort() { Binds.Sort(Compare); } private static int Compare(PiPhoneKeybind a, PiPhoneKeybind b) { int num = string.Compare((a != null) ? a.Group : string.Empty, (b != null) ? b.Group : string.Empty, StringComparison.OrdinalIgnoreCase); if (num != 0) { return num; } int num2 = (a?.SortOrder ?? 0).CompareTo(b?.SortOrder ?? 0); if (num2 != 0) { return num2; } return string.Compare((a != null) ? a.Label : string.Empty, (b != null) ? b.Label : string.Empty, StringComparison.OrdinalIgnoreCase); } private static void RaiseChanged() { PhoneKeys.Changed?.Invoke(); } } public static class PhoneUi { private sealed class ReadableLabel : MonoBehaviour { } public static Color Bezel = new Color(0.07f, 0.07f, 0.08f, 1f); public static Color Screen = new Color(0.08f, 0.1f, 0.13f, 1f); public static Color Surface = new Color(0.16f, 0.18f, 0.21f, 0.96f); public static Color SurfaceAlt = new Color(0.2f, 0.22f, 0.26f, 1f); public static Color Text = new Color(0.96f, 0.97f, 0.98f, 1f); public static Color ClockText = new Color(0.96f, 0.97f, 0.98f, 1f); public static Color ButtonText = new Color(0.96f, 0.97f, 0.98f, 1f); public static Color TextDim = new Color(0.7f, 0.74f, 0.78f, 1f); public static Color Accent = new Color(0.24f, 0.86f, 0.52f, 1f); public static Color CallGreen = new Color(0.18f, 0.72f, 0.38f, 1f); public static Color HangRed = new Color(0.86f, 0.24f, 0.24f, 1f); public static Color Nav = new Color(0.1f, 0.11f, 0.13f, 1f); public static Color PhoneIcon = new Color(0.18f, 0.72f, 0.38f, 1f); public static Color MessagesIcon = new Color(0.15f, 0.55f, 0.92f, 1f); public static Color VoicemailIcon = new Color(0.95f, 0.55f, 0.16f, 1f); public static Color SettingsIcon = new Color(0.45f, 0.48f, 0.52f, 1f); public static Color NotesIcon = new Color(0.96f, 0.78f, 0.2f, 1f); public static Color CameraIcon = new Color(0.35f, 0.72f, 0.82f, 1f); public static Color PhotosIcon = new Color(0.72f, 0.42f, 0.82f, 1f); public static Color MemosIcon = new Color(0.92f, 0.32f, 0.42f, 1f); private static Sprite _white; private static Sprite _circle; private static Sprite _wallpaper; private static readonly Dictionary<int, Sprite> RoundedCache = new Dictionary<int, Sprite>(); private static TMP_FontAsset _cachedFont; private static int _cachedSceneHandle = -1; private static TMP_FontAsset _readableFont; public static bool Landscape => PiPhoneApi.IsLandscape; public static Canvas CreateOverlayCanvas(GameObject root, int sortingOrder) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) Canvas val = root.GetComponent<Canvas>() ?? root.AddComponent<Canvas>(); val.renderMode = (RenderMode)0; val.sortingOrder = sortingOrder; val.additionalShaderChannels = (AdditionalCanvasShaderChannels)25; CanvasScaler val2 = root.GetComponent<CanvasScaler>() ?? root.AddComponent<CanvasScaler>(); val2.uiScaleMode = (ScaleMode)1; val2.referenceResolution = new Vector2(1920f, 1080f); val2.matchWidthOrHeight = 1f; if ((Object)(object)root.GetComponent<GraphicRaycaster>() == (Object)null) { root.AddComponent<GraphicRaycaster>(); } return val; } public static RectTransform CreateImage(Transform parent, string name, Sprite sprite, Color color) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //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_007c: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.transform.SetParent(parent, false); Image component = val.GetComponent<Image>(); component.sprite = sprite; int num; if ((Object)(object)sprite != (Object)null) { Vector4 border = sprite.border; if (((Vector4)(ref border)).sqrMagnitude > 0f) { num = 1; goto IL_0075; } } num = 0; goto IL_0075; IL_0075: component.type = (Type)num; ((Graphic)component).color = color; ((Graphic)component).raycastTarget = true; return val.GetComponent<RectTransform>(); } public static TextMeshProUGUI CreateLabel(Transform parent, string name, string text, float fontSize, FontStyles style = (FontStyles)0, TextAlignmentOptions align = (TextAlignmentOptions)513) { //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown //IL_005d: 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_006f: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name, new Type[2] { typeof(RectTransform), typeof(CanvasRenderer) }); val.transform.SetParent(parent, false); TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val2).text = text ?? string.Empty; ((TMP_Text)val2).fontSize = fontSize * PhoneTheme.FontScale; ((TMP_Text)val2).fontStyle = style; ((TMP_Text)val2).alignment = align; ((Graphic)val2).color = Text; ((Graphic)val2).raycastTarget = false; ((TMP_Text)val2).enableWordWrapping = false; ((TMP_Text)val2).overflowMode = (TextOverflowModes)0; ((MaskableGraphic)val2).maskable = true; ApplyFont(val2); return val2; } public static Button CreateButton(Transform parent, string label, UnityAction onClick, Vector2 preferredSize) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_0084: Unknown result type (might be due to invalid IL or missing references) RectTransform val = CreateImage(parent, "Btn_" + Sanitize(label), ButtonShape(), SurfaceAlt); Image component = ((Component)val).GetComponent<Image>(); Button val2 = ((Component)val).gameObject.AddComponent<Button>(); ((Selectable)val2).targetGraphic = (Graphic)(object)component; ((Selectable)val2).colors = TintColors(); TextMeshProUGUI val3 = CreateLabel((Transform)(object)val, "Text", label, 18f, (FontStyles)0, (TextAlignmentOptions)514); ((Graphic)val3).color = ButtonText; Stretch(((TMP_Text)val3).rectTransform, 8f, 4f); ApplySize(val, preferredSize); if (onClick != null) { ((UnityEvent)val2.onClick).AddListener(onClick); } return val2; } public static Button CreateIconChip(Transform parent, string glyph, Sprite icon, UnityAction onClick, bool lit, Vector2 size, bool tintIcon = true) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0005: 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_001d: 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_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: 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_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_013a: 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) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) Color color = (lit ? Accent : SurfaceAlt); RectTransform val = CreateImage(parent, "Chip", ChipShape(), color); Image component = ((Component)val).GetComponent<Image>(); Button val2 = ((Component)val).gameObject.AddComponent<Button>(); ((Selectable)val2).targetGraphic = (Graphic)(object)component; ((Selectable)val2).colors = TintColors(); Color color2 = (Color)((!tintIcon) ? Color.white : (lit ? new Color(0.1f, 0.11f, 0.12f, 1f) : ButtonText)); if ((Object)(object)icon != (Object)null) { RectTransform val3 = CreateImage((Transform)(object)val, "I", icon, color2); Stretch(val3, 6f, 6f); Image component2 = ((Component)val3).GetCompone