From 2f656340317826874c54472d0075fbc65f0bad56 Mon Sep 17 00:00:00 2001 From: NotAKidoS <37721153+NotAKidoS@users.noreply.github.com> Date: Mon, 2 Sep 2024 00:18:57 -0500 Subject: [PATCH] Stickers: minor changes --- .../BTKUI/UIAddon.Category.DebugOptions.cs | 13 -- .../BTKUI/UIAddon.Category.MiscOptions.cs | 24 ++++ .../BTKUI/UIAddon.Category.StickersMod.cs | 4 +- Stickers/Integrations/BTKUI/UIAddon.Main.cs | 2 +- .../BTKUI/UIAddon.Page.StickerSelect.cs | 13 +- Stickers/ModSettings.cs | 14 +-- Stickers/Properties/AssemblyInfo.cs | 2 +- Stickers/Stickers.csproj | 2 +- .../Networking/ModNetwork.Constants.cs | 5 +- .../Stickers/Networking/ModNetwork.Inbound.cs | 114 ++++++++++++------ Stickers/Stickers/StickerData.cs | 28 ++--- .../Stickers/StickerSystem.ImageLoading.cs | 5 + Stickers/Stickers/StickerSystem.Main.cs | 41 ++++++- .../Stickers/StickerSystem.PlayerCallbacks.cs | 43 +------ .../StickerSystem.StickerLifecycle.cs | 27 ++--- Stickers/Stickers/Utilities/StickerCache.cs | 7 ++ 16 files changed, 204 insertions(+), 140 deletions(-) delete mode 100644 Stickers/Integrations/BTKUI/UIAddon.Category.DebugOptions.cs create mode 100644 Stickers/Integrations/BTKUI/UIAddon.Category.MiscOptions.cs diff --git a/Stickers/Integrations/BTKUI/UIAddon.Category.DebugOptions.cs b/Stickers/Integrations/BTKUI/UIAddon.Category.DebugOptions.cs deleted file mode 100644 index 0a8fc32..0000000 --- a/Stickers/Integrations/BTKUI/UIAddon.Category.DebugOptions.cs +++ /dev/null @@ -1,13 +0,0 @@ -using BTKUILib.UIObjects; - -namespace NAK.Stickers.Integrations; - -public static partial class BTKUIAddon -{ - private static void Setup_DebugOptionsCategory() - { - Category debugCategory = _rootPage.AddMelonCategory(ModSettings.Hidden_Foldout_DebugCategory); - debugCategory.AddMelonToggle(ModSettings.Debug_NetworkInbound); - debugCategory.AddMelonToggle(ModSettings.Debug_NetworkOutbound); - } -} \ No newline at end of file diff --git a/Stickers/Integrations/BTKUI/UIAddon.Category.MiscOptions.cs b/Stickers/Integrations/BTKUI/UIAddon.Category.MiscOptions.cs new file mode 100644 index 0000000..3c6e385 --- /dev/null +++ b/Stickers/Integrations/BTKUI/UIAddon.Category.MiscOptions.cs @@ -0,0 +1,24 @@ +using BTKUILib; +using BTKUILib.UIObjects; +using BTKUILib.UIObjects.Components; +using NAK.Stickers.Utilities; + +namespace NAK.Stickers.Integrations; + +public static partial class BTKUIAddon +{ + private static void Setup_OtherOptionsCategory() + { + Category debugCategory = _rootPage.AddMelonCategory(ModSettings.Hidden_Foldout_MiscCategory); + debugCategory.AddMelonToggle(ModSettings.Debug_NetworkInbound); + debugCategory.AddMelonToggle(ModSettings.Debug_NetworkOutbound); + debugCategory.AddMelonToggle(ModSettings.Entry_FriendsOnly); + debugCategory.AddButton("Clear Thumbnail Cache", "Stickers-rubbish-bin", "Clear the cache of all loaded stickers.", ButtonStyle.TextWithIcon) + .OnPress += () => QuickMenuAPI.ShowConfirm("Clear Thumbnail Cache", "Are you sure you want to clear the Cohtml thumbnail cache for all stickers?", + () => + { + StickerCache.ClearCache(); + QuickMenuAPI.ShowAlertToast("Thumbnail cache cleared.", 2); + }); + } +} \ No newline at end of file diff --git a/Stickers/Integrations/BTKUI/UIAddon.Category.StickersMod.cs b/Stickers/Integrations/BTKUI/UIAddon.Category.StickersMod.cs index 22b67bd..65d874d 100644 --- a/Stickers/Integrations/BTKUI/UIAddon.Category.StickersMod.cs +++ b/Stickers/Integrations/BTKUI/UIAddon.Category.StickersMod.cs @@ -36,8 +36,8 @@ public static partial class BTKUIAddon Button openStickersFolderButton = _ourCategory.AddButton("Open Stickers Folder", "Stickers-folder", "Open UserData/Stickers folder in explorer. If above 256kb your image will automatically be downscaled for networking reasons.", ButtonStyle.TextWithIcon); openStickersFolderButton.OnPress += OnOpenStickersFolderButtonClick; - Button openMultiSelectionButton = _ourCategory.AddButton("Sticker SFX", "Stickers-headset", "Choose the SFX used when a sticker is placed.", ButtonStyle.TextWithIcon); - openMultiSelectionButton.OnPress += () => QuickMenuAPI.OpenMultiSelect(_sfxSelection); + Button openStickerSFXButton = _ourCategory.AddButton("Sticker SFX", "Stickers-headset", "Choose the SFX used when a sticker is placed.", ButtonStyle.TextWithIcon); + openStickerSFXButton.OnPress += () => QuickMenuAPI.OpenMultiSelect(_sfxSelection); ToggleButton toggleDesktopKeybindButton = _ourCategory.AddToggle("Use Desktop Keybind", "Should the Desktop keybind be active.", ModSettings.Entry_UsePlaceBinding.Value); Button openDesktopKeybindButton = _ourCategory.AddButton("Desktop Keybind", "Stickers-alphabet", "Choose the key binding to place stickers.", ButtonStyle.TextWithIcon); diff --git a/Stickers/Integrations/BTKUI/UIAddon.Main.cs b/Stickers/Integrations/BTKUI/UIAddon.Main.cs index 76345c0..a56f8f1 100644 --- a/Stickers/Integrations/BTKUI/UIAddon.Main.cs +++ b/Stickers/Integrations/BTKUI/UIAddon.Main.cs @@ -66,7 +66,7 @@ public static partial class BTKUIAddon Setup_StickersModCategory(); Setup_StickerSelectionCategory(); - Setup_DebugOptionsCategory(); + Setup_OtherOptionsCategory(); } #endregion Setup diff --git a/Stickers/Integrations/BTKUI/UIAddon.Page.StickerSelect.cs b/Stickers/Integrations/BTKUI/UIAddon.Page.StickerSelect.cs index eed6307..c36c8cb 100644 --- a/Stickers/Integrations/BTKUI/UIAddon.Page.StickerSelect.cs +++ b/Stickers/Integrations/BTKUI/UIAddon.Page.StickerSelect.cs @@ -18,6 +18,7 @@ public static partial class BTKUIAddon private static Category _fileCategory; private static Category _folderCategory; + private static TextBlock _noFilesTextBlock; private const int MAX_BUTTONS = 512; // cohtml literally will start to explode private static Button[] _fileButtons = new Button[80]; // 100 files, will resize if needed @@ -49,10 +50,12 @@ public static partial class BTKUIAddon // Create page _ourDirectoryBrowserPage = Page.GetOrCreatePage(ModSettings.ModName, "Directory Browser"); QuickMenuAPI.AddRootPage(_ourDirectoryBrowserPage); - + // Setup categories _folderCategory = _ourDirectoryBrowserPage.AddCategory("Subdirectories"); _fileCategory = _ourDirectoryBrowserPage.AddCategory("Images"); + _noFilesTextBlock = _fileCategory.AddTextBlock("No images found in this directory. You can add your own images and subfolders to the `UserData/Stickers/` folder."); + _noFilesTextBlock.Hidden = true; SetupFolderButtons(); SetupFileButtons(); @@ -88,6 +91,7 @@ public static partial class BTKUIAddon string absolutePath = Path.Combine(_curDirectoryInfo.FullName, button.ButtonTooltip[5..]); string relativePath = Path.GetRelativePath(_initialDirectory, absolutePath); StickerSystem.Instance.LoadImage(relativePath, _curSelectedSticker); + _rootPage.OpenPage(true); // close the directory browser to artificially limit loading speed }; _fileButtons[i] = button; } @@ -162,12 +166,16 @@ public static partial class BTKUIAddon return; } _stickerSelectionButtonDoubleClickTime = Time.time; + + // quick menu notification + QuickMenuAPI.ShowAlertToast($"Selected sticker slot {index + 1}", 1); } private static void OpenStickerSelectionForSlot(int index) { if (IsPopulatingPage) return; _curSelectedSticker = index; + _initialDirectory = StickerSystem.GetStickersFolderPath(); // creates folder if needed (lazy fix) _curDirectoryInfo = new DirectoryInfo(_initialDirectory); _ourDirectoryBrowserPage.OpenPage(false, true); } @@ -203,8 +211,9 @@ public static partial class BTKUIAddon _folderCategory.Hidden = foldersCount == 0; _folderCategory.CategoryName = $"Subdirectories ({foldersCount})"; - _fileCategory.Hidden = filesCount == 0; + //_fileCategory.Hidden = filesCount == 0; _fileCategory.CategoryName = $"Images ({filesCount})"; + _noFilesTextBlock.Hidden = filesCount > 0; }); PopulateFolders(directories); diff --git a/Stickers/ModSettings.cs b/Stickers/ModSettings.cs index 0278f3e..85dbae5 100644 --- a/Stickers/ModSettings.cs +++ b/Stickers/ModSettings.cs @@ -11,7 +11,7 @@ public static class ModSettings internal const string SM_SettingsCategory = "Stickers Mod"; private const string SM_SelectionCategory = "Sticker Selection"; - private const string DEBUG_SettingsCategory = "Debug Options"; + private const string MISC_SettingsCategory = "Miscellaneous Options"; internal const int MaxStickerSlots = 4; @@ -27,17 +27,14 @@ public static class ModSettings internal static readonly MelonPreferences_Entry Hidden_Foldout_SelectionCategory = Category.CreateEntry("hidden_foldout_selection", true, is_hidden: true, display_name: SM_SelectionCategory, description: "Foldout state for Sticker selection."); - - internal static readonly MelonPreferences_Entry Hidden_Foldout_DebugCategory = - Category.CreateEntry("hidden_foldout_debug", false, is_hidden: true, display_name: DEBUG_SettingsCategory, description: "Foldout state for Debug settings."); + + internal static readonly MelonPreferences_Entry Hidden_Foldout_MiscCategory = + Category.CreateEntry("hidden_foldout_miscellaneous", false, is_hidden: true, display_name: MISC_SettingsCategory, description: "Foldout state for Miscellaneous settings."); #endregion Hidden Foldout Entries #region Stickers Mod Settings - internal static readonly MelonPreferences_Entry Entry_HapticsOnPlace = - Category.CreateEntry("haptics_on_place", true, "Haptics On Place", "Enable haptic feedback when placing stickers."); - internal static readonly MelonPreferences_Entry Entry_PlayerUpAlignmentThreshold = Category.CreateEntry("player_up_alignment_threshold", 20f, "Player Up Alignment Threshold", "The threshold the controller roll can be within to align perfectly with the player up vector. Set to 0f to always align to controller up."); @@ -58,6 +55,9 @@ public static class ModSettings display_name: "Selected Sticker Name", description: "The name of the sticker selected for stickering.", is_hidden: true); + + internal static readonly MelonPreferences_Entry Entry_FriendsOnly = + Category.CreateEntry("friends_only", false, "Friends Only", "Only allow friends to use stickers."); #endregion Stickers Mod Settings diff --git a/Stickers/Properties/AssemblyInfo.cs b/Stickers/Properties/AssemblyInfo.cs index 818da71..cf05529 100644 --- a/Stickers/Properties/AssemblyInfo.cs +++ b/Stickers/Properties/AssemblyInfo.cs @@ -27,6 +27,6 @@ using System.Reflection; namespace NAK.Stickers.Properties; internal static class AssemblyInfoParams { - public const string Version = "1.0.4"; + public const string Version = "1.0.5"; public const string Author = "NotAKidoS"; } \ No newline at end of file diff --git a/Stickers/Stickers.csproj b/Stickers/Stickers.csproj index 990d2db..de4a315 100644 --- a/Stickers/Stickers.csproj +++ b/Stickers/Stickers.csproj @@ -4,7 +4,7 @@ net48 - TRACE;TRACE;UNITY_2017_1_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2019_3_OR_NEWER;USE_BURST;USE_NEWMATHS;USE_BURST_REALLY; + TRACE;TRACE;UNITY_2017_1_OR_NEWER;UNITY_2018_1_OR_NEWER;UNITY_2019_3_OR_NEWER;USE_BURST;USE_NEWMATHS;USE_BURST_REALLY;USEDFORSTICKERMOD; diff --git a/Stickers/Stickers/Networking/ModNetwork.Constants.cs b/Stickers/Stickers/Networking/ModNetwork.Constants.cs index 152b952..0f24904 100644 --- a/Stickers/Stickers/Networking/ModNetwork.Constants.cs +++ b/Stickers/Stickers/Networking/ModNetwork.Constants.cs @@ -1,4 +1,5 @@ -using NAK.Stickers.Properties; +using ABI_RC.Core.Util.AnimatorManager; +using NAK.Stickers.Properties; namespace NAK.Stickers.Networking; @@ -12,6 +13,6 @@ public static partial class ModNetwork private const string ModId = $"MelonMod.NAK.Stickers_v{NetworkVersion}"; private const int ChunkSize = 1024; // roughly 1KB per ModNetworkMessage private const int MaxChunkCount = MaxTextureSize / ChunkSize; - + #endregion Constants } \ No newline at end of file diff --git a/Stickers/Stickers/Networking/ModNetwork.Inbound.cs b/Stickers/Stickers/Networking/ModNetwork.Inbound.cs index fbada5b..b59d5db 100644 --- a/Stickers/Stickers/Networking/ModNetwork.Inbound.cs +++ b/Stickers/Stickers/Networking/ModNetwork.Inbound.cs @@ -1,4 +1,5 @@ -using ABI_RC.Core.Savior; +using ABI_RC.Core.Networking.IO.Social; +using ABI_RC.Core.Savior; using ABI_RC.Systems.ModNetwork; using NAK.Stickers.Utilities; using UnityEngine; @@ -15,58 +16,91 @@ public static partial class ModNetwork private static readonly Dictionary _textureMetadata = new(); #endregion Inbound Buffers + + #region Reset Method + + public static void Reset() + { + _textureChunkBuffers.Clear(); + _receivedChunkCounts.Clear(); + _expectedChunkCounts.Clear(); + _textureMetadata.Clear(); + + LoggerInbound("ModNetwork inbound buffers and metadata have been reset."); + } + + #endregion Reset Method #region Inbound Methods + + private static bool ShouldReceiveFromSender(string sender) + { + if (_disallowedForSession.Contains(sender)) + return false; // ignore messages from disallowed users + + if (MetaPort.Instance.blockedUserIds.Contains(sender)) + return false; // ignore messages from blocked users + + if (ModSettings.Entry_FriendsOnly.Value && !Friends.FriendsWith(sender)) + return false; // ignore messages from non-friends if friends only is enabled + + return true; + } private static void HandleMessageReceived(ModNetworkMessage msg) { - string sender = msg.Sender; - msg.Read(out byte msgTypeRaw); - - if (!Enum.IsDefined(typeof(MessageType), msgTypeRaw)) - return; - - if (_disallowedForSession.Contains(sender)) - return; // ignore messages from disallowed users - - if (MetaPort.Instance.blockedUserIds.Contains(sender)) - return; // ignore messages from blocked users - - LoggerInbound($"Received message from {msg.Sender}, Type: {(MessageType)msgTypeRaw}"); - - switch ((MessageType)msgTypeRaw) + try { - case MessageType.PlaceSticker: - HandlePlaceSticker(msg); - break; + string sender = msg.Sender; + msg.Read(out byte msgTypeRaw); - case MessageType.ClearSticker: - HandleClearSticker(msg); - break; + if (!Enum.IsDefined(typeof(MessageType), msgTypeRaw)) + return; + + if (!ShouldReceiveFromSender(sender)) + return; - case MessageType.ClearAllStickers: - HandleClearAllStickers(msg); - break; + LoggerInbound($"Received message from {msg.Sender}, Type: {(MessageType)msgTypeRaw}"); - case MessageType.StartTexture: - HandleStartTexture(msg); - break; + switch ((MessageType)msgTypeRaw) + { + case MessageType.PlaceSticker: + HandlePlaceSticker(msg); + break; + + case MessageType.ClearSticker: + HandleClearSticker(msg); + break; + + case MessageType.ClearAllStickers: + HandleClearAllStickers(msg); + break; - case MessageType.SendTexture: - HandleSendTexture(msg); - break; + case MessageType.StartTexture: + HandleStartTexture(msg); + break; - case MessageType.EndTexture: - HandleEndTexture(msg); - break; + case MessageType.SendTexture: + HandleSendTexture(msg); + break; - case MessageType.RequestTexture: - HandleRequestTexture(msg); - break; + case MessageType.EndTexture: + HandleEndTexture(msg); + break; - default: - LoggerInbound($"Invalid message type received: {msgTypeRaw}"); - break; + case MessageType.RequestTexture: + HandleRequestTexture(msg); + break; + + default: + LoggerInbound($"Invalid message type received: {msgTypeRaw}"); + break; + } + + } + catch (Exception e) + { + LoggerInbound($"Error handling message from {msg.Sender}: {e.Message}", true); } } diff --git a/Stickers/Stickers/StickerData.cs b/Stickers/Stickers/StickerData.cs index c2bed17..f193d12 100644 --- a/Stickers/Stickers/StickerData.cs +++ b/Stickers/Stickers/StickerData.cs @@ -8,14 +8,13 @@ namespace NAK.Stickers public class StickerData { private const float DECAL_SIZE = 0.25f; - - private static readonly int s_EmissionStrengthID = Shader.PropertyToID("_EmissionStrength"); - - public float DeathTime; // when a remote player leaves, we need to kill their stickers + + public readonly string PlayerId; public float LastPlacedTime; + public float DeathTime = -1f; + private Vector3 _lastPlacedPosition = Vector3.zero; - public readonly bool IsLocal; private readonly DecalType _decal; private readonly DecalSpawner[] _decalSpawners; @@ -23,9 +22,9 @@ namespace NAK.Stickers private readonly Material[] _materials; private readonly AudioSource _audioSource; - public StickerData(bool isLocal, int decalSpawnersCount) + public StickerData(string playerId, int decalSpawnersCount) { - IsLocal = isLocal; + PlayerId = playerId; _decal = ScriptableObject.CreateInstance(); _decalSpawners = new DecalSpawner[decalSpawnersCount]; @@ -54,7 +53,7 @@ namespace NAK.Stickers _audioSource.maxDistance = 5f; _audioSource.minDistance = 1f; _audioSource.outputAudioMixerGroup = RootLogic.Instance.propSfx; // props are close enough to stickers - if (isLocal) Object.DontDestroyOnLoad(_audioSource.gameObject); // keep audio source through world transitions + if (PlayerId == StickerSystem.PlayerLocalId) Object.DontDestroyOnLoad(_audioSource.gameObject); // keep audio source through world transitions } public Guid GetTextureHash(int spawnerIndex = 0) @@ -95,8 +94,6 @@ namespace NAK.Stickers ? FilterMode.Bilinear // smear it cause its fat : FilterMode.Point; // my minecraft skin looked shit - if (IsLocal) StickerMod.Logger.Msg($"Set texture filter mode to: {texture.filterMode}"); - Material material = _materials[spawnerIndex]; // Destroy the previous texture to avoid memory leaks @@ -117,9 +114,9 @@ namespace NAK.Stickers Transform rootObject = null; GameObject hitGO = hit.transform.gameObject; - if (hitGO.TryGetComponent(out Rigidbody _) - || hitGO.TryGetComponent(out Animator _) - || hitGO.scene.buildIndex == 4) // additive (dynamic) content + if (hitGO.scene.buildIndex == 4 // additive (dynamic) content + || hitGO.TryGetComponent(out Animator _) // potentially movable + || hitGO.GetComponentInParent() != null) // movable rootObject = hitGO.transform; _lastPlacedPosition = hit.point; @@ -128,7 +125,7 @@ namespace NAK.Stickers // Add decal to the specified spawner _decalSpawners[spawnerIndex].AddDecal( _lastPlacedPosition, Quaternion.LookRotation(forwardDirection, upDirection), - hit.collider.gameObject, + hitGO, DECAL_SIZE, DECAL_SIZE, 1f, 1f, 0f, rootObject); } @@ -162,8 +159,9 @@ namespace NAK.Stickers _decalSpawners[i].Release(); _decalSpawners[i].staticGroups.Clear(); _decalSpawners[i].movableGroups.Clear(); - + // Clean up textures and materials + if (_materials[i] == null) continue; if (_materials[i].mainTexture != null) Object.Destroy(_materials[i].mainTexture); Object.Destroy(_materials[i]); } diff --git a/Stickers/Stickers/StickerSystem.ImageLoading.cs b/Stickers/Stickers/StickerSystem.ImageLoading.cs index 254cd02..def203a 100644 --- a/Stickers/Stickers/StickerSystem.ImageLoading.cs +++ b/Stickers/Stickers/StickerSystem.ImageLoading.cs @@ -149,6 +149,11 @@ public partial class StickerSystem if (!Directory.Exists(s_StickersFolderPath)) Directory.CreateDirectory(s_StickersFolderPath); return s_StickersFolderPath; } + + public static void EnsureStickersFolderExists() + { + if (!Directory.Exists(s_StickersFolderPath)) Directory.CreateDirectory(s_StickersFolderPath); + } #endregion Image Loading } \ No newline at end of file diff --git a/Stickers/Stickers/StickerSystem.Main.cs b/Stickers/Stickers/StickerSystem.Main.cs index 24338bd..ad02060 100644 --- a/Stickers/Stickers/StickerSystem.Main.cs +++ b/Stickers/Stickers/StickerSystem.Main.cs @@ -1,5 +1,8 @@ -using ABI_RC.Core.UI; +using ABI_RC.Core.IO; +using ABI_RC.Core.Networking.IO.Instancing; +using ABI_RC.Core.UI; using ABI_RC.Systems.GameEventSystem; +using NAK.Stickers.Networking; using NAK.Stickers.Utilities; using UnityEngine; @@ -22,7 +25,7 @@ public partial class StickerSystem DecalManager.SetPreferredMode(DecalUtils.Mode.GPU, false, 0); // ensure cache folder exists - if (!Directory.Exists(s_StickersFolderPath)) Directory.CreateDirectory(s_StickersFolderPath); + EnsureStickersFolderExists(); // listen for game events CVRGameEventSystem.Initialization.OnPlayerSetupStart.AddListener(Instance.OnPlayerSetupStart); @@ -30,6 +33,36 @@ public partial class StickerSystem #endregion Singleton + #region Callback Registration + + private void OnPlayerSetupStart() + { + CVRGameEventSystem.World.OnUnload.AddListener(_ => OnWorldUnload()); + CVRGameEventSystem.Instance.OnConnected.AddListener((_) => { if (!Instances.IsReconnecting) OnInitialConnection(); }); + + CVRGameEventSystem.Player.OnJoinEntity.AddListener(Instance.OnPlayerJoined); + CVRGameEventSystem.Player.OnLeaveEntity.AddListener(Instance.OnPlayerLeft); + SchedulerSystem.AddJob(Instance.OnOccasionalUpdate, 10f, 1f); + LoadAllImagesAtStartup(); + } + + #endregion Callback Registration + + #region Game Events + + private void OnInitialConnection() + { + ClearStickersSelf(); // clear stickers on remotes just in case we rejoined + ModNetwork.Reset(); // reset network buffers and metadata + } + + private void OnWorldUnload() + { + CleanupAllButSelf(); // release all stickers except for self + } + + #endregion Game Events + #region Data private int _selectedStickerSlot; @@ -63,9 +96,7 @@ public partial class StickerSystem private const float StickerKillTime = 30f; private const float StickerCooldown = 0.2f; private readonly Dictionary _playerStickers = new(); - private const string PlayerLocalId = "_PLAYERLOCAL"; + internal const string PlayerLocalId = "_PLAYERLOCAL"; - private readonly List _deadStickerPool = new(); // for cleanup on player leave - #endregion Data } \ No newline at end of file diff --git a/Stickers/Stickers/StickerSystem.PlayerCallbacks.cs b/Stickers/Stickers/StickerSystem.PlayerCallbacks.cs index 3c99106..3637abc 100644 --- a/Stickers/Stickers/StickerSystem.PlayerCallbacks.cs +++ b/Stickers/Stickers/StickerSystem.PlayerCallbacks.cs @@ -1,7 +1,4 @@ -using ABI_RC.Core.IO; -using ABI_RC.Core.Networking.IO.Instancing; -using ABI_RC.Core.Player; -using ABI_RC.Systems.GameEventSystem; +using ABI_RC.Core.Player; using UnityEngine; namespace NAK.Stickers; @@ -10,17 +7,6 @@ public partial class StickerSystem { #region Player Callbacks - private void OnPlayerSetupStart() - { - CVRGameEventSystem.World.OnUnload.AddListener(_ => Instance.CleanupAllButSelf()); - CVRGameEventSystem.Instance.OnConnected.AddListener((_) => { if (!Instances.IsReconnecting) Instance.ClearStickersSelf(); }); - - CVRGameEventSystem.Player.OnJoinEntity.AddListener(Instance.OnPlayerJoined); - CVRGameEventSystem.Player.OnLeaveEntity.AddListener(Instance.OnPlayerLeft); - SchedulerSystem.AddJob(Instance.OnOccasionalUpdate, 10f, 1f); - LoadAllImagesAtStartup(); - } - private void OnPlayerJoined(CVRPlayerEntity playerEntity) { if (!_playerStickers.TryGetValue(playerEntity.Uuid, out StickerData stickerData)) @@ -28,7 +14,6 @@ public partial class StickerSystem stickerData.DeathTime = -1f; stickerData.SetAlpha(1f); - _deadStickerPool.Remove(stickerData); } private void OnPlayerLeft(CVRPlayerEntity playerEntity) @@ -38,25 +23,16 @@ public partial class StickerSystem stickerData.DeathTime = Time.time + StickerKillTime; stickerData.SetAlpha(1f); - _deadStickerPool.Add(stickerData); } private void OnOccasionalUpdate() { - if (_deadStickerPool.Count == 0) - return; - - for (var i = _deadStickerPool.Count - 1; i >= 0; i--) + float currentTime = Time.time; + for (int i = 0; i < _playerStickers.Values.Count; i++) { - float currentTime = Time.time; - StickerData stickerData = _deadStickerPool[i]; - if (stickerData == null) - { - _deadStickerPool.RemoveAt(i); - continue; - } + StickerData stickerData = _playerStickers.Values.ElementAt(i); - if (stickerData.DeathTime < 0f) + if (stickerData.DeathTime < 0f) continue; if (currentTime < stickerData.DeathTime) @@ -65,15 +41,8 @@ public partial class StickerSystem continue; } - for (int j = 0; j < _playerStickers.Values.Count; j++) - { - if (_playerStickers.Values.ElementAt(j) != stickerData) continue; - _playerStickers.Remove(_playerStickers.Keys.ElementAt(j)); - break; - } - - _deadStickerPool.RemoveAt(i); stickerData.Cleanup(); + _playerStickers.Remove(stickerData.PlayerId); } } diff --git a/Stickers/Stickers/StickerSystem.StickerLifecycle.cs b/Stickers/Stickers/StickerSystem.StickerLifecycle.cs index a24ebd8..ee2d76e 100644 --- a/Stickers/Stickers/StickerSystem.StickerLifecycle.cs +++ b/Stickers/Stickers/StickerSystem.StickerLifecycle.cs @@ -15,7 +15,7 @@ public partial class StickerSystem if (_playerStickers.TryGetValue(playerId, out StickerData stickerData)) return stickerData; - stickerData = new StickerData(playerId == PlayerLocalId, ModSettings.MaxStickerSlots); + stickerData = new StickerData(playerId, ModSettings.MaxStickerSlots); _playerStickers[playerId] = stickerData; return stickerData; } @@ -40,8 +40,6 @@ public partial class StickerSystem if (!PlaceStickerSelf(transform.position, transform.forward, targetUp)) return; - // do haptic if not lame - if (!ModSettings.Entry_HapticsOnPlace.Value) return; CVRInputManager.Instance.Vibrate(0f, 0.1f, 10f, 0.1f, hand); } @@ -67,6 +65,10 @@ public partial class StickerSystem 10f, LayerMask, QueryTriggerInteraction.Ignore)) return false; + // if gameobject name starts with [NoSticker] then don't place sticker + if (hit.transform.gameObject.name.StartsWith("[NoSticker]")) + return false; + stickerData.Place(hit, alignWithNormal ? -hit.normal : forward, up, stickerSlot); stickerData.PlayAudio(); return true; @@ -78,6 +80,12 @@ public partial class StickerSystem ModNetwork.SendClearAllStickers(); } + public void ClearStickerSelf(int stickerSlot) + { + ClearStickersForPlayer(PlayerLocalId, stickerSlot); + ModNetwork.SendClearSticker(stickerSlot); + } + private void ClearStickersForPlayer(string playerId) { if (!_playerStickers.TryGetValue(playerId, out StickerData stickerData)) @@ -100,6 +108,7 @@ public partial class StickerSystem texture.LoadImage(imageBytes); texture.Compress(true); // noachi said to do + ClearStickerSelf(stickerSlot); // clear placed stickers in-scene so we can't replace an entire wall at once OnPlayerStickerTextureReceived(PlayerLocalId, Guid.Empty, texture, stickerSlot); ModNetwork.SetTexture(stickerSlot, imageBytes); } @@ -138,7 +147,7 @@ public partial class StickerSystem foreach ((_, StickerData data) in _playerStickers) { - if (data.IsLocal) data.Clear(); + if (data == localStickerData) data.Clear(); else data.Cleanup(); } @@ -146,15 +155,5 @@ public partial class StickerSystem _playerStickers[PlayerLocalId] = localStickerData; } - public void SelectStickerSlot(int stickerSlot) - { - SelectedStickerSlot = Mathf.Clamp(stickerSlot, 0, ModSettings.MaxStickerSlots - 1); - } - - public int GetCurrentStickerSlot() - { - return SelectedStickerSlot; - } - #endregion Sticker Lifecycle } diff --git a/Stickers/Stickers/Utilities/StickerCache.cs b/Stickers/Stickers/Utilities/StickerCache.cs index eb5ae87..3d4c2a2 100644 --- a/Stickers/Stickers/Utilities/StickerCache.cs +++ b/Stickers/Stickers/Utilities/StickerCache.cs @@ -66,6 +66,13 @@ public static class StickerCache } } + public static void ClearCache() + { + if (!Directory.Exists(ThumbnailPath)) return; + Directory.Delete(ThumbnailPath, true); + StickerMod.Logger.Msg("Cleared thumbnail cache."); + } + #endregion Public Methods #region Private Methods