static bool Prefix(ref BeatmapIdentifierNetSerializable beatmapId, ref GameplayModifiers gameplayModifiers, ref float initialStartTime, MultiplayerLevelLoader __instance) { if (!beatmapId.levelID.StartsWith(CustomLevelPrefix) || SongCore.Loader.GetLevelById(beatmapId.levelID) != null) { return(true); } MultiplayerLevelLoader = __instance; string levelId = beatmapId?.levelID; BeatmapIdentifierNetSerializable bmId = beatmapId; GameplayModifiers modifiers = gameplayModifiers; float startTime = initialStartTime; if (levelId != null && levelId.StartsWith(CustomLevelPrefix)) { if (SongCore.Loader.GetLevelById(levelId) != null) { LoadingLevelId = null; return(true); } if (LoadingLevelId == null || LoadingLevelId != levelId) { LoadingLevelId = levelId; var downloadTask = Downloader.TryDownloadSong(levelId, CancellationToken.None, r => { if (r) { //Plugin.Log?.Debug($"Triggering 'LobbyGameStateController.HandleMenuRpcManagerStartedLevel' after level download."); //LobbyGameStateController_HandleMenuRpcManagerStartedLevel.LobbyGameStateController.HandleMenuRpcManagerStartedLevel(LobbyGameStateController_HandleMenuRpcManagerStartedLevel.LastUserId, bmId, modifiers, startTime); } else { Plugin.Log?.Warn($"TryDownloadSong was unsuccessful."); } MultiplayerLevelLoader.LoadLevel(bmId, modifiers, startTime); LoadingLevelId = null; }); return(false); } } LoadingLevelId = null; return(true); }
static bool Prefix(string userId, BeatmapIdentifierNetSerializable beatmapId, LobbyPlayersDataModel __instance) { if (beatmapId != null) { if (beatmapId.levelID.StartsWith("custom_level_")) { Plugin.Log?.Debug($"'{userId}' selected song '{beatmapId.levelID}'"); if (SongCore.Loader.GetLevelById(beatmapId.levelID) != null) { Plugin.Log?.Debug($"Custom song '{beatmapId.levelID}' loaded."); return(true); } Plugin.Log?.Debug("getting characteristics"); var beatmapCharacteristicCollection = __instance.GetField <BeatmapCharacteristicCollectionSO, LobbyPlayersDataModel>("_beatmapCharacteristicCollection"); Plugin.Log?.Debug("setting preview"); __instance.SetPlayerBeatmapLevel(userId, new OverrideClasses.PreviewBeatmapLevelStub(beatmapId.levelID), beatmapId.difficulty, beatmapCharacteristicCollection.GetBeatmapCharacteristicBySerializedName(beatmapId.beatmapCharacteristicSerializedName)); return(false); } } return(true); }
public async override void HandleMenuRpcManagerSelectedBeatmap(string userId, BeatmapIdentifierNetSerializable beatmapId) { if (beatmapId != null) { string?hash = Utilities.Utils.LevelIdToHash(beatmapId.levelID); if (hash != null) { Plugin.Log?.Debug($"'{userId}' selected song '{hash}'."); BeatmapCharacteristicSO characteristic = _beatmapCharacteristicCollection.GetBeatmapCharacteristicBySerializedName(beatmapId.beatmapCharacteristicSerializedName); PreviewBeatmapStub? preview = null; if (_playersData.Values.Any(playerData => playerData.beatmapLevel?.levelID == beatmapId.levelID)) { IPreviewBeatmapLevel playerPreview = _playersData.Values.Where(playerData => playerData.beatmapLevel?.levelID == beatmapId.levelID).First().beatmapLevel; if (playerPreview is PreviewBeatmapStub playerPreviewStub) { preview = playerPreviewStub; } } IPreviewBeatmapLevel localPreview = SongCore.Loader.GetLevelById(beatmapId.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 (userId == base.hostUserId) { _sessionManager.SetLocalPlayerState("beatmap_downloaded", preview.isDownloaded); } HMMainThreadDispatcher.instance.Enqueue(() => base.SetPlayerBeatmapLevel(userId, preview, beatmapId.difficulty, characteristic)); return; } } base.HandleMenuRpcManagerSelectedBeatmap(userId, beatmapId); }
/// <summary> /// Triggered when a player selects a song using a vanilla packet. /// </summary> public async override void HandleMenuRpcManagerSelectedBeatmap(string userId, BeatmapIdentifierNetSerializable beatmapId) { OnSelectedBeatmap(userId, beatmapId); string?hash = Utilities.Utils.LevelIdToHash(beatmapId.levelID); Plugin.Log?.Debug($"'{userId}' selected song '{hash ?? beatmapId.levelID}'."); if (hash != null) { BeatmapCharacteristicSO characteristic = _beatmapCharacteristicCollection.GetBeatmapCharacteristicBySerializedName(beatmapId.beatmapCharacteristicSerializedName); if (_playersData.Values.Any(playerData => playerData.beatmapLevel?.levelID == beatmapId.levelID)) { PreviewBeatmapStub?preview = GetExistingPreview(beatmapId.levelID); HMMainThreadDispatcher.instance.Enqueue(() => base.SetPlayerBeatmapLevel(userId, preview, beatmapId.difficulty, characteristic)); } else { PreviewBeatmapStub? preview = null; IPreviewBeatmapLevel localPreview = SongCore.Loader.GetLevelById(beatmapId.levelID); if (localPreview != null) { preview = new PreviewBeatmapStub(hash, localPreview); } if (preview == null) { preview = await FetchBeatSaverPreview(beatmapId.levelID, hash); } HMMainThreadDispatcher.instance.Enqueue(() => base.SetPlayerBeatmapLevel(userId, preview, beatmapId.difficulty, characteristic)); } } else { base.HandleMenuRpcManagerSelectedBeatmap(userId, beatmapId); } }
static bool Prefix(ref BeatmapIdentifierNetSerializable beatmapId, ref GameplayModifiers gameplayModifiers, ref float initialStartTime, MultiplayerLevelLoader __instance) { string?levelId = beatmapId.levelID; if (SongCore.Loader.GetLevelById(levelId) != null) { if (LoadingLevelId != levelId) { Plugin.Log?.Debug($"Level with ID '{levelId}' already exists."); // Don't log if LoadLevel was called when a download finished. } LoadingLevelId = null; return(true); } string?hash = Utilities.Utils.LevelIdToHash(beatmapId.levelID); if (hash == null) { Plugin.Log?.Info($"Could not get a hash from beatmap with LevelId {beatmapId.levelID}"); LoadingLevelId = null; return(true); } if (Downloader.TryGetDownload(levelId, out _)) { Plugin.Log?.Debug($"Download for '{levelId}' is already in progress."); return(false); } MultiplayerLevelLoader = __instance; BeatmapIdentifierNetSerializable bmId = beatmapId; GameplayModifiers modifiers = gameplayModifiers; float startTime = initialStartTime; // TODO: Link to UI progress bar. Don't forget case where downloaded song may be switched back to a currently downloading one. // Probably best to have a class containing a download that the IProgress updates with the current progress. // Then that class can be hooked/unhooked from the UI progress bar. IProgress <double>?progress = null; //IProgress<double> progress = new Progress<double>(p => //{ // Plugin.Log?.Debug($"Progress for '{bmId.levelID}': {p:P}"); //}); if (LoadingLevelId == null || LoadingLevelId != levelId) { LoadingLevelId = levelId; Plugin.Log?.Debug($"Attempting to download level with ID '{levelId}'..."); Task?downloadTask = Downloader.TryDownloadSong(levelId, progress, CancellationToken.None).ContinueWith(b => { try { IPreviewBeatmapLevel?level = b.Result; if (level != null) { Plugin.Log?.Debug($"Level with ID '{levelId}' was downloaded successfully."); //Plugin.Log?.Debug($"Triggering 'LobbyGameStateController.HandleMenuRpcManagerStartedLevel' after level download."); //LobbyGameStateController_HandleMenuRpcManagerStartedLevel.LobbyGameStateController.HandleMenuRpcManagerStartedLevel(LobbyGameStateController_HandleMenuRpcManagerStartedLevel.LastUserId, bmId, modifiers, startTime); MultiplayerLevelLoader.LoadLevel(bmId, modifiers, startTime); } else { Plugin.Log?.Warn($"TryDownloadSong was unsuccessful."); } } catch (Exception ex) { Plugin.Log?.Warn($"Error in TryDownloadSong continuation: {ex.Message}"); Plugin.Log?.Debug(ex); } finally { LoadingLevelId = null; } }); return(false); } return(true); }