private BeatmapCharacteristicObject CreateCharacteristic(Characteristic characteristic) { if (characteristic == Characteristic.Standard) { throw new Exception("Tried to create standard beatmap characteristic which means it's missing. Assets are broken."); } BeatmapCharacteristicObject standardCharacteristic = GetCharacteristicAsset(Characteristic.Standard); if (standardCharacteristic == null) { Log.LogErr($"Unable to locate the standard beatmap characteristic while verifying characteristics!"); throw new Exception("Could not locate standard beatmap characteristic!"); } int count = _assetsFile.Manager.MassFindAssets <BeatmapCharacteristicObject>(x => true, false).Count(); try { string characteristicName = $"LEVEL_{characteristic.ToString().ToUpper()}"; string hintText = $"{characteristicName}_HINT"; string assetName = MiscUtils.GetCharacteristicAssetName(characteristic); var lightshowAsset = (BeatmapCharacteristicObject)standardCharacteristic.ObjectInfo.Clone(standardCharacteristic.ObjectInfo.ParentFile); lightshowAsset.Name = assetName; lightshowAsset.SerializedName = characteristic.ToString(); lightshowAsset.SortingOrder = count; lightshowAsset.CompoundIdPartName = characteristic.ToString(); //todo: text translation stuff //lightshowAsset.CharacteristicName = characteristicName; //lightshowAsset.HintText = hintText; var allChar = _assetsFile.Manager.MassFirstOrDefaultAsset <BeatmapCharacteristicCollectionObject>(x => true); if (allChar == null) { throw new Exception("Unable to find AllBeatmapCharacteristics object!"); } if (!allChar.Object.BeatmapCharacteristics.Any(x => x.Object.Name == lightshowAsset.Name)) { allChar.Object.BeatmapCharacteristics.Add(lightshowAsset.PtrFrom(allChar.Object)); } try { byte[] lightshowIcon = _config.EmbeddedResourcesFileProvider.Read($"{characteristic}.png"); if (lightshowIcon == null || lightshowIcon.Length < 1) { throw new Exception($"{characteristic}.png read was null or empty!"); } var clonedSprite = (SpriteObject)standardCharacteristic.Icon.Object.ObjectInfo.Clone(standardCharacteristic.ObjectInfo.ParentFile); var newTexture = new Texture2DObject(standardCharacteristic.ObjectInfo.ParentFile) { Name = assetName }; clonedSprite.RenderData.AtlasRectOffset.X = -1; clonedSprite.RenderData.AtlasRectOffset.Y = -1; clonedSprite.RenderData.TextureRect.X = 0; clonedSprite.RenderData.TextureRect.Y = 0; clonedSprite.RenderData.Texture = newTexture.PtrFrom(clonedSprite); clonedSprite.Name = assetName + "Icon"; ImageUtils.Instance.AssignImageToTexture(lightshowIcon, newTexture, 128, 128, Int32.MaxValue, TextureConversionFormat.Auto); lightshowAsset.Icon = clonedSprite.PtrFrom(lightshowAsset); standardCharacteristic.ObjectInfo.ParentFile.AddObject(clonedSprite); standardCharacteristic.ObjectInfo.ParentFile.AddObject(newTexture); standardCharacteristic.ObjectInfo.ParentFile.AddObject(lightshowAsset); } catch (Exception ex) { Log.LogErr($"Failed to load {characteristic}'s png icon!", ex); throw; } return(lightshowAsset); } catch (Exception ex) { Log.LogErr($"Exception trying to create {characteristic} characteristic!", ex); throw new Exception($"Error trying to create characteristic {characteristic}!", ex); } }
public BeatmapLevelDataObject LoadSongToAsset(BeatmapLevelDataObject beatmapLevel, string songPath, bool includeCovers = true) { try { beatmapLevel.Name = $"{beatmapLevel.LevelID}Level"; //cover art Texture2DObject coverImage = null; if (includeCovers) { coverImage = LoadSongCover(songPath, beatmapLevel); } //audio var audioAsset = LoadSongAudioAsset(songPath, beatmapLevel); if (audioAsset == null) { Log.LogErr($"failed to get audio for song at path {songPath}"); return(null); } var toRemoveSet = new List <DifficultyBeatmapSet>(); foreach (var difficultySet in beatmapLevel.DifficultyBeatmapSets) { var characteristic = GetCharacteristicAsset(difficultySet.BeatmapCharacteristicName)?.PtrFrom(beatmapLevel); if (characteristic == null) { Log.LogErr($"Characteristic {difficultySet.BeatmapCharacteristicName} couldn't be found. Set will be removed."); toRemoveSet.Add(difficultySet); continue; } difficultySet.BeatmapCharacteristic = characteristic; List <DifficultyBeatmap> toRemove = new List <DifficultyBeatmap>(); foreach (var difficultyBeatmap in difficultySet.DifficultyBeatmaps) { string dataFile = null; if (!string.IsNullOrWhiteSpace(difficultyBeatmap.BeatmapFilename)) { dataFile = songPath.CombineFwdSlash(difficultyBeatmap.BeatmapFilename); if (!_config.SongFileProvider.FileExists(dataFile)) { Log.LogErr($"BeatmapFilename was set to {dataFile} but the file didn't exist, will try to fall back to difficulty name."); dataFile = null; } } if (dataFile == null) { dataFile = songPath.CombineFwdSlash($"{difficultyBeatmap.Difficulty.ToString()}.dat"); } if (!_config.SongFileProvider.FileExists(dataFile)) { Log.LogErr(dataFile + " is missing, skipping this difficulty"); toRemove.Add(difficultyBeatmap); continue; } string jsonData = _config.SongFileProvider.ReadToString(dataFile); if (_assetsFile != null) { difficultyBeatmap.BeatmapData = new BeatmapDataObject(_assetsFile); } difficultyBeatmap.BeatmapData.Name = beatmapLevel.LevelID + ((difficultySet.BeatmapCharacteristicName == Characteristic.Standard) ? "" : difficultySet.BeatmapCharacteristicName.ToString()) + difficultyBeatmap.Difficulty.ToString() + "BeatmapData"; difficultyBeatmap.BeatmapData.BeatsPerMinute = beatmapLevel.BeatsPerMinute; difficultyBeatmap.BeatmapData.Shuffle = beatmapLevel.Shuffle; difficultyBeatmap.BeatmapData.ShufflePeriod = beatmapLevel.ShufflePeriod; difficultyBeatmap.BeatmapData.JsonData = jsonData; _assetsFile.AddObject(difficultyBeatmap.BeatmapData, true); difficultyBeatmap.BeatmapDataPtr = difficultyBeatmap.BeatmapData.PtrFrom(beatmapLevel); } toRemove.ForEach(x => difficultySet.DifficultyBeatmaps.Remove(x)); if (difficultySet.DifficultyBeatmaps.Count < 1) { Log.LogErr($"Song at path {songPath} has no valid beatmaps for any difficulty on set {difficultySet.BeatmapCharacteristicName}, removing it"); toRemoveSet.Add(difficultySet); continue; } } toRemoveSet.ForEach(x => beatmapLevel.DifficultyBeatmapSets.Remove(x)); if (beatmapLevel.DifficultyBeatmapSets.Count < 1) { Log.LogErr($"Song at path {songPath} has no valid characterstics, it will not be imported"); return(null); } _assetsFile.AddObject(audioAsset, true); if (coverImage != null) { _assetsFile.AddObject(coverImage); } beatmapLevel.AudioClip = audioAsset.PtrFrom(beatmapLevel); if (coverImage == null) { var bsCover = _assetsFile.FindAsset <Texture2DObject>(x => x.Object.Name == "BeatSaberCover"); if (bsCover == null) { Log.LogErr("Unable to find BeatSaberCover in assets! How is that gone?"); throw new Exception("Could not find beat saber cover in assets! That should never be missing."); } var cover = bsCover.Clone(); _assetsFile.AddObject(cover, true); beatmapLevel.CoverImageTexture2D = cover.PtrFrom(beatmapLevel); } else { beatmapLevel.CoverImageTexture2D = coverImage.PtrFrom(beatmapLevel); } var environment = GetEnvironment(beatmapLevel.EnvironmentName); if (environment == null) { Log.LogMsg($"Unknown environment name '{beatmapLevel.EnvironmentName}' on '{beatmapLevel.SongName}', falling back to default."); environment = GetEnvironment("DefaultEnvironment"); if (environment == null) { throw new Exception("Unable to find the default environment!"); } } beatmapLevel.EnvironmentInfo = environment.PtrFrom(beatmapLevel); _assetsFile.AddObject(beatmapLevel, true); return(beatmapLevel); } catch (Exception ex) { Log.LogErr($"Error loading song from path {songPath}", ex); return(null); } }
public BeatmapLevelDataObject LoadSongToAsset(BeatmapLevelDataObject beatmapLevel, string songPath, out string oggFileName, bool includeCovers = true) { oggFileName = null; try { beatmapLevel.Name = $"{beatmapLevel.LevelID}Level"; //cover art Texture2DObject coverImage = null; if (includeCovers) { coverImage = LoadSongCover(songPath, beatmapLevel); } //audio var audioAsset = LoadSongAudioAsset(songPath, beatmapLevel); if (audioAsset == null) { Log.LogErr($"failed to get audio for song at path {songPath}"); return(null); } oggFileName = Path.Combine(songPath, beatmapLevel.SongFilename);; foreach (var difficultySet in beatmapLevel.DifficultyBeatmapSets) { difficultySet.BeatmapCharacteristic = GetCharacteristicAsset(difficultySet.BeatmapCharacteristicName).PtrFrom(beatmapLevel); List <DifficultyBeatmap> toRemove = new List <DifficultyBeatmap>(); foreach (var difficultyBeatmap in difficultySet.DifficultyBeatmaps) { var dataFile = Path.Combine(songPath, $"{difficultyBeatmap.Difficulty.ToString()}.dat"); if (!File.Exists(dataFile)) { Log.LogErr(dataFile + " is missing, skipping this difficulty"); toRemove.Add(difficultyBeatmap); continue; } string jsonData; using (var sr = new StreamReader(dataFile)) { jsonData = sr.ReadToEnd(); } if (_assetsFile != null) { difficultyBeatmap.BeatmapData = new BeatmapDataObject(_assetsFile); } difficultyBeatmap.BeatmapData.Name = beatmapLevel.LevelID + ((difficultySet.BeatmapCharacteristicName == Characteristic.Standard) ? "" : difficultySet.BeatmapCharacteristicName.ToString()) + difficultyBeatmap.Difficulty.ToString() + "BeatmapData"; difficultyBeatmap.BeatmapData.BeatsPerMinute = beatmapLevel.BeatsPerMinute; difficultyBeatmap.BeatmapData.Shuffle = beatmapLevel.Shuffle; difficultyBeatmap.BeatmapData.ShufflePeriod = beatmapLevel.ShufflePeriod; difficultyBeatmap.BeatmapData.JsonData = jsonData; difficultyBeatmap.BeatmapData.TransformToProjectedData(); difficultyBeatmap.BeatmapData.JsonData = null; _assetsFile.AddObject(difficultyBeatmap.BeatmapData, true); difficultyBeatmap.BeatmapDataPtr = difficultyBeatmap.BeatmapData.PtrFrom(beatmapLevel); } toRemove.ForEach(x => difficultySet.DifficultyBeatmaps.Remove(x)); if (difficultySet.DifficultyBeatmaps.Count < 1) { Log.LogErr($"Song at path {songPath} has no valid beatmaps for any difficulty, skipping song"); return(null); } } _assetsFile.AddObject(audioAsset, true); if (coverImage != null) { _assetsFile.AddObject(coverImage); } beatmapLevel.AudioClip = audioAsset.PtrFrom(beatmapLevel); if (coverImage == null) { beatmapLevel.CoverImageTexture2D = _assetsFile.FindAsset <Texture2DObject>(x => x.Object.Name == "BeatSaberCover").PtrFrom(beatmapLevel); } else { beatmapLevel.CoverImageTexture2D = coverImage.PtrFrom(beatmapLevel); } var environment = _assetsFile.Manager.MassFirstOrDefaultAsset <MonoBehaviourObject>(x => x.Object.Name == $"{beatmapLevel.EnvironmentName}SceneInfo"); if (environment == null) { Log.LogMsg($"Unknown environment name '{beatmapLevel.EnvironmentName}' on '{beatmapLevel.SongName}', falling back to default."); environment = _assetsFile.Manager.MassFirstAsset <MonoBehaviourObject>(x => x.Object.Name == "DefaultEnvironmentSceneInfo"); } beatmapLevel.EnvironmentSceneInfo = environment.PtrFrom(beatmapLevel); _assetsFile.AddObject(beatmapLevel, true); return(beatmapLevel); } catch (Exception ex) { Log.LogErr($"Error loading song from path {songPath}", ex); return(null); } }