using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Globalization; using System.IO; using NitroxModel.Helper; namespace NitroxModel.GameLogic.FMOD; public class FMODWhitelist { private readonly HashSet whitelistedPaths = new(); private readonly Dictionary soundsWhitelist = new(); public static FMODWhitelist Load(GameInfo game) { return new FMODWhitelist(game); } private FMODWhitelist(GameInfo game) { string filePath = Path.Combine(NitroxUser.AssetsPath, "Resources", $"SoundWhitelist_{game.Name}.csv"); string fileData = ""; try { fileData = File.ReadAllText(filePath); } catch (Exception) { // ignored } if (string.IsNullOrWhiteSpace(fileData)) { Log.Error($"[{nameof(FMODWhitelist)}]: Provided sound whitelist at '{filePath}' is null or whitespace"); return; } foreach (string entry in fileData.Split('\n')) { if (string.IsNullOrWhiteSpace(entry) || entry.StartsWith("#") || entry.StartsWith(";")) { continue; } string[] keyValuePair = entry.Split(';'); if (bool.TryParse(keyValuePair[1], out bool isWhitelisted) && bool.TryParse(keyValuePair[2], out bool isGlobal) && float.TryParse(keyValuePair[3], NumberStyles.Any, CultureInfo.InvariantCulture, out float soundRadius)) { soundsWhitelist.Add(keyValuePair[0], new SoundData(isWhitelisted, isGlobal, soundRadius)); if (isWhitelisted) { whitelistedPaths.Add(keyValuePair[0]); } } else { Log.Error($"[{nameof(FMODWhitelist)}]: Error while parsing {filePath} at line {entry}"); } } } public bool IsWhitelisted(string path) { return whitelistedPaths.Contains(path); } public bool IsWhitelisted(string path, out float radius) { if (soundsWhitelist.TryGetValue(path, out SoundData soundData)) { radius = soundData.Radius; return soundData.IsWhitelisted; } radius = -1f; return false; } public bool TryGetSoundData(string path, out SoundData soundData) { return soundsWhitelist.TryGetValue(path, out soundData); } public ReadOnlyDictionary GetWhitelist() => new(soundsWhitelist); } public readonly struct SoundData { public bool IsWhitelisted { get; } public bool IsGlobal { get; } public float Radius { get; } public SoundData(bool isWhitelisted, bool isGlobal, float radius) { IsWhitelisted = isWhitelisted; IsGlobal = isGlobal; Radius = radius; } }