using System.Collections; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using Photon.Pun; using TMPro; using UnityEngine; 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: AssemblyTitle("Preset")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("Preset")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("83d1a53b-0718-4cdc-a505-af41b8ed031e")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] public sealed class PresetLog { private const string LogColor = "#00FF00"; private const float LogDuration = 4f; private readonly MonoBehaviour owner; private string currentDisplayedColoredText = ""; private float nativeLogExpireTime; private Coroutine nativeLogCoroutine; private AudioSource uiAudioSource; public PresetLog(MonoBehaviour owner) { this.owner = owner; CreateAudioSource(); } public void ShowSaved(int slot) { string localizedSavedMessage = GetLocalizedSavedMessage(GetDisplaySlot(slot)); ShowNativeGameLog(localizedSavedMessage); } public void ShowLoaded(int slot) { string localizedLoadedMessage = GetLocalizedLoadedMessage(GetDisplaySlot(slot)); ShowNativeGameLog(localizedLoadedMessage); } private void CreateAudioSource() { if (!((Object)(object)owner == (Object)null)) { uiAudioSource = ((Component)owner).gameObject.AddComponent(); if (!((Object)(object)uiAudioSource == (Object)null)) { uiAudioSource.playOnAwake = false; uiAudioSource.loop = false; uiAudioSource.spatialBlend = 0f; uiAudioSource.dopplerLevel = 0f; uiAudioSource.ignoreListenerPause = true; uiAudioSource.ignoreListenerVolume = false; uiAudioSource.priority = 32; uiAudioSource.bypassEffects = false; uiAudioSource.bypassListenerEffects = false; uiAudioSource.bypassReverbZones = true; ApplyGameMixer(); } } } private void ApplyGameMixer() { if (!((Object)(object)uiAudioSource == (Object)null) && !((Object)(object)SFX_Player.instance == (Object)null) && !((Object)(object)SFX_Player.instance.defaultMixerGroup == (Object)null)) { uiAudioSource.outputAudioMixerGroup = SFX_Player.instance.defaultMixerGroup; } } private void PlayNotificationSound(PlayerConnectionLog playerLog) { if ((Object)(object)playerLog == (Object)null || (Object)(object)playerLog.sfxJoin == (Object)null || playerLog.sfxJoin.clips == null || playerLog.sfxJoin.clips.Length == 0) { return; } if ((Object)(object)uiAudioSource == (Object)null) { CreateAudioSource(); } if ((Object)(object)uiAudioSource == (Object)null) { return; } ApplyGameMixer(); AudioClip clip = playerLog.sfxJoin.GetClip(); if (!((Object)(object)clip == (Object)null)) { float volume = 1f; float pitch = 1f; if (playerLog.sfxJoin.settings != null) { SFX_Settings settings = playerLog.sfxJoin.settings; volume = settings.volume * Random.Range(1f - settings.volume_Variation, 1f); pitch = settings.pitch + Random.Range((0f - settings.pitch_Variation) * 0.5f, settings.pitch_Variation * 0.5f); } uiAudioSource.Stop(); uiAudioSource.clip = clip; uiAudioSource.volume = volume; uiAudioSource.pitch = pitch; uiAudioSource.mute = false; uiAudioSource.spatialBlend = 0f; uiAudioSource.ignoreListenerPause = true; uiAudioSource.Play(); } } private string GetDisplaySlot(int slot) { if (slot == 10) { return "0"; } return slot.ToString(); } private string GetLocalizedSavedMessage(string slot) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected I4, but got Unknown Language cURRENT_LANGUAGE = LocalizedText.CURRENT_LANGUAGE; Language val = cURRENT_LANGUAGE; return (int)val switch { 0 => "Preset " + slot + " saved.", 1 => "Préréglage " + slot + " enregistré.", 2 => "Preset " + slot + " salvato.", 3 => "Preset " + slot + " gespeichert.", 4 => "Preajuste " + slot + " guardado.", 5 => "Preajuste " + slot + " guardado.", 6 => "Predefinição " + slot + " salva.", 7 => "Пресет " + slot + " сохранён.", 8 => "Пресет " + slot + " збережено.", 9 => "预设 " + slot + " 已保存。", 10 => "預設 " + slot + " 已儲存。", 11 => "プリセット " + slot + " を保存しました。", 12 => "프리셋 " + slot + "이 저장되었습니다.", 13 => "Preset " + slot + " zapisany.", 14 => "Ön ayar " + slot + " kaydedildi.", _ => "Preset " + slot + " saved.", }; } private string GetLocalizedLoadedMessage(string slot) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Expected I4, but got Unknown Language cURRENT_LANGUAGE = LocalizedText.CURRENT_LANGUAGE; Language val = cURRENT_LANGUAGE; return (int)val switch { 0 => "Preset " + slot + " loaded.", 1 => "Préréglage " + slot + " chargé.", 2 => "Preset " + slot + " caricato.", 3 => "Preset " + slot + " geladen.", 4 => "Preajuste " + slot + " cargado.", 5 => "Preajuste " + slot + " cargado.", 6 => "Predefinição " + slot + " carregada.", 7 => "Пресет " + slot + " загружен.", 8 => "Пресет " + slot + " завантажено.", 9 => "预设 " + slot + " 已加载。", 10 => "預設 " + slot + " 已載入。", 11 => "プリセット " + slot + " を読み込みました。", 12 => "프리셋 " + slot + "을 불러왔습니다.", 13 => "Preset " + slot + " wczytany.", 14 => "Ön ayar " + slot + " yüklendi.", _ => "Preset " + slot + " loaded.", }; } private void ShowNativeGameLog(string message) { PlayerConnectionLog val = Object.FindFirstObjectByType(); if ((Object)(object)val == (Object)null) { return; } PlayNotificationSound(val); if (!((Object)(object)val.text == (Object)null)) { RemoveCurrentLogMessage(val); currentDisplayedColoredText = "" + message + ""; TextMeshProUGUI text = val.text; ((TMP_Text)text).text = ((TMP_Text)text).text + currentDisplayedColoredText + "\n"; nativeLogExpireTime = Time.realtimeSinceStartup + 4f; if (nativeLogCoroutine == null && (Object)(object)owner != (Object)null) { nativeLogCoroutine = owner.StartCoroutine(NativeLogTimeoutRoutine()); } } } private void RemoveCurrentLogMessage(PlayerConnectionLog playerLog) { if (!((Object)(object)playerLog == (Object)null) && !((Object)(object)playerLog.text == (Object)null) && !string.IsNullOrEmpty(currentDisplayedColoredText)) { ((TMP_Text)playerLog.text).text = ((TMP_Text)playerLog.text).text.Replace(currentDisplayedColoredText + "\n", ""); } } private IEnumerator NativeLogTimeoutRoutine() { while (Time.realtimeSinceStartup < nativeLogExpireTime) { yield return null; } PlayerConnectionLog playerLog = Object.FindFirstObjectByType(); if ((Object)(object)playerLog != (Object)null && (Object)(object)playerLog.text != (Object)null) { RemoveCurrentLogMessage(playerLog); } currentDisplayedColoredText = ""; nativeLogCoroutine = null; } } [BepInPlugin("Sapphire009.Preset", "Passport Preset", "1.0.3")] public sealed class Preset : BaseUnityPlugin { public const string PluginGuid = "Sapphire009.Preset"; public const string PluginName = "Passport Preset"; public const string PluginVersion = "1.0.3"; private const int PresetCount = 10; private readonly ConfigEntry[] hasPreset = new ConfigEntry[10]; private readonly ConfigEntry[] skin = new ConfigEntry[10]; private readonly ConfigEntry[] accessory = new ConfigEntry[10]; private readonly ConfigEntry[] eyes = new ConfigEntry[10]; private readonly ConfigEntry[] mouth = new ConfigEntry[10]; private readonly ConfigEntry[] outfit = new ConfigEntry[10]; private readonly ConfigEntry[] hat = new ConfigEntry[10]; private readonly ConfigEntry[] sash = new ConfigEntry[10]; private PresetLog presetLog; private int pendingSlot = 0; private bool pendingSave = false; private int pendingFrame = -1; private void Awake() { for (int i = 0; i < 10; i++) { string text = "Preset" + (i + 1); hasPreset[i] = ((BaseUnityPlugin)this).Config.Bind(text, "HasPreset", false, (ConfigDescription)null); skin[i] = ((BaseUnityPlugin)this).Config.Bind(text, "Skin", 0, (ConfigDescription)null); accessory[i] = ((BaseUnityPlugin)this).Config.Bind(text, "Accessory", 0, (ConfigDescription)null); eyes[i] = ((BaseUnityPlugin)this).Config.Bind(text, "Eyes", 0, (ConfigDescription)null); mouth[i] = ((BaseUnityPlugin)this).Config.Bind(text, "Mouth", 0, (ConfigDescription)null); outfit[i] = ((BaseUnityPlugin)this).Config.Bind(text, "Outfit", 0, (ConfigDescription)null); hat[i] = ((BaseUnityPlugin)this).Config.Bind(text, "Hat", 0, (ConfigDescription)null); sash[i] = ((BaseUnityPlugin)this).Config.Bind(text, "Sash", 0, (ConfigDescription)null); } presetLog = new PresetLog((MonoBehaviour)(object)this); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[Preset] PresetLog initialized."); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[Preset] Loaded | Passport only | 1-0 Load | Shift+1-0 Save"); } private void Update() { if (pendingSlot != 0 && Time.frameCount > pendingFrame) { int slot = pendingSlot; bool flag = pendingSave; pendingSlot = 0; pendingSave = false; pendingFrame = -1; if (IsPassportOpen()) { if (flag) { SavePreset(slot); } else { LoadPreset(slot); } } } else if (!IsPassportOpen()) { pendingSlot = 0; pendingSave = false; pendingFrame = -1; } else { int pressedSlot = GetPressedSlot(); if (pressedSlot != 0) { bool flag2 = Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303); pendingSlot = pressedSlot; pendingSave = flag2; pendingFrame = Time.frameCount; } } } private bool IsPassportOpen() { if (!PhotonNetwork.InRoom) { return false; } if (PhotonNetwork.LocalPlayer == null) { return false; } PassportManager instance = PassportManager.instance; if ((Object)(object)instance == (Object)null) { return false; } if (!((MenuWindow)instance).isOpen) { return false; } if (!((MenuWindow)instance).inputActive) { return false; } if ((Object)(object)instance.uiObject == (Object)null) { return false; } if (!instance.uiObject.activeInHierarchy) { return false; } if ((Object)(object)Singleton.Instance == (Object)null) { return false; } return true; } private int GetPressedSlot() { if (Input.GetKeyDown((KeyCode)49) || Input.GetKeyDown((KeyCode)257)) { return 1; } if (Input.GetKeyDown((KeyCode)50) || Input.GetKeyDown((KeyCode)258)) { return 2; } if (Input.GetKeyDown((KeyCode)51) || Input.GetKeyDown((KeyCode)259)) { return 3; } if (Input.GetKeyDown((KeyCode)52) || Input.GetKeyDown((KeyCode)260)) { return 4; } if (Input.GetKeyDown((KeyCode)53) || Input.GetKeyDown((KeyCode)261)) { return 5; } if (Input.GetKeyDown((KeyCode)54) || Input.GetKeyDown((KeyCode)262)) { return 6; } if (Input.GetKeyDown((KeyCode)55) || Input.GetKeyDown((KeyCode)263)) { return 7; } if (Input.GetKeyDown((KeyCode)56) || Input.GetKeyDown((KeyCode)264)) { return 8; } if (Input.GetKeyDown((KeyCode)57) || Input.GetKeyDown((KeyCode)265)) { return 9; } if (Input.GetKeyDown((KeyCode)48) || Input.GetKeyDown((KeyCode)256)) { return 10; } return 0; } private void SavePreset(int slot) { PersistentPlayerDataService service = GameHandler.GetService(); if (service == null) { return; } PersistentPlayerData playerData = service.GetPlayerData(PhotonNetwork.LocalPlayer); if (playerData != null && playerData.customizationData != null) { int num = slot - 1; CharacterCustomizationData customizationData = playerData.customizationData; skin[num].Value = customizationData.currentSkin; accessory[num].Value = customizationData.currentAccessory; eyes[num].Value = customizationData.currentEyes; mouth[num].Value = customizationData.currentMouth; outfit[num].Value = customizationData.currentOutfit; hat[num].Value = customizationData.currentHat; sash[num].Value = customizationData.currentSash; hasPreset[num].Value = true; ((BaseUnityPlugin)this).Config.Save(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[Preset] Calling PresetLog.ShowSaved."); if (presetLog != null) { presetLog.ShowSaved(slot); } else { ((BaseUnityPlugin)this).Logger.LogError((object)"[Preset] presetLog is NULL."); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("[Preset] Preset " + GetDisplayKey(slot) + " saved.")); } } private void LoadPreset(int slot) { int num = slot - 1; if (!hasPreset[num].Value) { ((BaseUnityPlugin)this).Logger.LogInfo((object)("[Preset] Preset " + GetDisplayKey(slot) + " is empty.")); return; } PassportManager instance = PassportManager.instance; Customization instance2 = Singleton.Instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)instance2 == (Object)null)) { ApplyPassportOption(instance, instance2.skins, skin[num].Value); ApplyPassportOption(instance, instance2.eyes, eyes[num].Value); ApplyPassportOption(instance, instance2.mouths, mouth[num].Value); ApplyPassportOption(instance, instance2.accessories, accessory[num].Value); ApplyPassportOption(instance, instance2.fits, outfit[num].Value); ApplyPassportOption(instance, instance2.hats, hat[num].Value); ApplyPassportOption(instance, instance2.sashes, sash[num].Value); instance.SetButtons(false); ((BaseUnityPlugin)this).Logger.LogInfo((object)"[Preset] Calling PresetLog.ShowLoaded."); if (presetLog != null) { presetLog.ShowLoaded(slot); } else { ((BaseUnityPlugin)this).Logger.LogError((object)"[Preset] presetLog is NULL."); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("[Preset] Preset " + GetDisplayKey(slot) + " loaded.")); } } private void ApplyPassportOption(PassportManager passport, CustomizationOption[] options, int optionIndex) { if (!((Object)(object)passport == (Object)null) && options != null && options.Length != 0 && optionIndex >= 0 && optionIndex < options.Length) { CustomizationOption val = options[optionIndex]; if (!((Object)(object)val == (Object)null)) { passport.SetOption(val, optionIndex); } } } private string GetDisplayKey(int slot) { if (slot == 10) { return "0"; } return slot.ToString(); } }