public async new void SetLocalPlayerBeatmapLevel(string levelId, BeatmapDifficulty beatmapDifficulty, BeatmapCharacteristicSO characteristic)
        {
            string?hash = Utilities.Utils.LevelIdToHash(levelId);

            if (hash != null)
            {
                Plugin.Log?.Debug($"Local user selected song '{hash}'.");
                PreviewBeatmapStub?preview = null;

                if (_playersData.Values.Any(playerData => playerData.beatmapLevel?.levelID == levelId))
                {
                    IPreviewBeatmapLevel playerPreview = _playersData.Values.Where(playerData => playerData.beatmapLevel?.levelID == levelId).First().beatmapLevel;
                    if (playerPreview is PreviewBeatmapStub playerPreviewStub)
                    {
                        preview = playerPreviewStub;
                    }
                }

                IPreviewBeatmapLevel localPreview = SongCore.Loader.GetLevelById(levelId);
                if (localPreview != null)
                {
                    preview = new PreviewBeatmapStub(hash, localPreview);
                }

                if (preview == null)
                {
                    try
                    {
                        Beatmap bm = await Plugin.BeatSaver.Hash(hash);

                        preview = new PreviewBeatmapStub(bm);
                    }
                    catch
                    {
                        return;
                    }
                }

                if (base.localUserId == base.hostUserId)
                {
                    _sessionManager.SetLocalPlayerState("beatmap_downloaded", preview.isDownloaded);
                }

                HMMainThreadDispatcher.instance.Enqueue(() => base.SetPlayerBeatmapLevel(base.localUserId, preview, beatmapDifficulty, characteristic));
                _packetManager.Send(await PreviewBeatmapPacket.FromPreview(preview, characteristic.serializedName, beatmapDifficulty));
                if (!_sessionManager.connectedPlayers.All(x => x.HasState("modded")))
                {
                    _menuRpcManager.SelectBeatmap(new BeatmapIdentifierNetSerializable(levelId, characteristic.serializedName, beatmapDifficulty));
                }
            }
            else
            {
                base.SetLocalPlayerBeatmapLevel(levelId, beatmapDifficulty, characteristic);
            }
        }
        /// <summary>
        /// Triggered when a player joins and sends the request.
        /// If the newly joined player is not modded or the selected song isn't custom, sends back a vanilla packet.
        /// Otherwise, sends a <see cref="MultiplayerExtensions.Beatmaps.PreviewBeatmapPacket"/>
        /// </summary>
        public async override void HandleMenuRpcManagerGetSelectedBeatmap(string userId)
        {
            ILobbyPlayerDataModel lobbyPlayerDataModel = this.GetLobbyPlayerDataModel(this.localUserId);

            if (lobbyPlayerDataModel != null && MPState.CurrentGameType != MultiplayerGameType.QuickPlay && _multiplayerSessionManager.GetPlayerByUserId(userId).HasState("modded") && lobbyPlayerDataModel?.beatmapLevel is PreviewBeatmapStub preview)
            {
                _packetManager.Send(await PreviewBeatmapPacket.FromPreview(preview, lobbyPlayerDataModel.beatmapCharacteristic.serializedName, lobbyPlayerDataModel.beatmapDifficulty));
            }
            else if (lobbyPlayerDataModel != null && lobbyPlayerDataModel.beatmapLevel != null)
            {
                this._menuRpcManager.SelectBeatmap(new BeatmapIdentifierNetSerializable(lobbyPlayerDataModel.beatmapLevel.levelID, lobbyPlayerDataModel.beatmapCharacteristic.serializedName, lobbyPlayerDataModel.beatmapDifficulty));
            }
        }
        /// <summary>
        /// Triggered when the local player selects a song.
        /// </summary>
        public async new void SetLocalPlayerBeatmapLevel(string levelId, BeatmapDifficulty beatmapDifficulty, BeatmapCharacteristicSO characteristic)
        {
            string?hash = Utilities.Utils.LevelIdToHash(levelId);

            Plugin.Log?.Debug($"Local user selected song '{hash ?? levelId}'.");
            if (hash != null)
            {
                if (_playersData.Values.Any(playerData => playerData.beatmapLevel?.levelID == levelId))
                {
                    PreviewBeatmapStub?preview = GetExistingPreview(levelId);
                    HMMainThreadDispatcher.instance.Enqueue(() => base.SetPlayerBeatmapLevel(base.localUserId, preview, beatmapDifficulty, characteristic));
                    _menuRpcManager.SelectBeatmap(new BeatmapIdentifierNetSerializable(levelId, characteristic.serializedName, beatmapDifficulty));
                }
                else
                {
                    PreviewBeatmapStub?  preview      = null;
                    IPreviewBeatmapLevel localPreview = SongCore.Loader.GetLevelById(levelId);
                    if (localPreview != null)
                    {
                        preview = new PreviewBeatmapStub(hash, localPreview);
                    }
                    if (preview == null)
                    {
                        preview = await FetchBeatSaverPreview(levelId, hash);
                    }

                    HMMainThreadDispatcher.instance.Enqueue(() => base.SetPlayerBeatmapLevel(base.localUserId, preview, beatmapDifficulty, characteristic));
                    _packetManager.Send(await PreviewBeatmapPacket.FromPreview(preview, characteristic.serializedName, beatmapDifficulty));
                    if (!_multiplayerSessionManager.connectedPlayers.All(x => x.HasState("modded")))
                    {
                        _menuRpcManager.SelectBeatmap(new BeatmapIdentifierNetSerializable(levelId, characteristic.serializedName, beatmapDifficulty));
                    }
                }
            }
            else
            {
                base.SetLocalPlayerBeatmapLevel(levelId, beatmapDifficulty, characteristic);
            }
        }