private List <UserRadioContent> LoadSongsFromFolder(String collection, String folder) { List <UserRadioContent> result = new List <UserRadioContent>(); CSLMusicMod.Log("Loading content from " + folder + " into collection " + collection); if (!Directory.Exists(folder)) { CSLMusicMod.Log("Skipping: Folder does not exist."); return(new List <UserRadioContent>()); } foreach (String filename in Directory.GetFiles(folder)) { if (Path.GetExtension(filename) == ".ogg") { UserRadioContent content = new UserRadioContent(collection, filename); m_Songs[content.m_Name] = content; CSLMusicMod.Log("Found content " + content.m_Name + ", path: " + filename); result.Add(content); } } return(result); }
private void LoadChannelsFromCollection(String dir) { CSLMusicMod.Log("Looking for channels in " + dir); if (!Directory.Exists(dir)) { CSLMusicMod.Log("Skipping: Directory does not exist."); return; } // Load json channel configuration foreach (String filename in Directory.GetFiles(dir)) { if (Path.GetExtension(filename) == ".json") { UserRadioChannel channel = UserRadioChannel.LoadFromJson(filename); if (channel != null) { channel.m_DefinitionDirectory = dir; m_Stations[channel.m_Name] = channel; } else { Debug.LogError("[CSLMusic] Error: Cannot load channel from " + filename); } } } }
private void DebugOutput() { for (uint i = 0; i < PrefabCollection <RadioChannelInfo> .PrefabCount(); ++i) { String message = ""; RadioChannelInfo info = PrefabCollection <RadioChannelInfo> .GetPrefab(i); if (info == null) { continue; } message += "[ChannelInfo] " + info + "\n"; message += "Schedule:\n"; if (info.m_stateChain != null) { foreach (RadioChannelInfo.State s in info.m_stateChain) { message += "\t" + s.m_contentType + " " + s.m_minCount + " - " + s.m_maxCount + "\n"; } } message += "Content:\n"; for (uint j = 0; j < PrefabCollection <RadioContentInfo> .PrefabCount(); ++j) { RadioContentInfo content = PrefabCollection <RadioContentInfo> .GetPrefab(j); if (content == null) { continue; } if (content.m_radioChannels != null) { if (content.m_radioChannels.Contains(info)) { message += "\t[ContentInfo] " + content + " " + content.m_fileName + "\n"; } } } CSLMusicMod.Log(message); } for (uint i = 0; i < PrefabCollection <DisasterInfo> .PrefabCount(); ++i) { DisasterInfo info = PrefabCollection <DisasterInfo> .GetPrefab(i); if (info == null) { continue; } CSLMusicMod.Log("[DisasterContext] Disaster name: " + info.name); } }
public void Uninstall() { CSLMusicMod.Log("[CSLMusic] Uninstalling detours ..."); RedirectionHelper.RevertRedirect(m_RedirectObtainMusicClip); RedirectionHelper.RevertRedirect(m_RedirectStationName); RedirectionHelper.RevertRedirect(m_RedirectRadioPanelButtonGeneration); RedirectionHelper.RevertRedirect(m_RedirectAudioManagerQueueBroadcast); RedirectionHelper.RevertRedirect(m_RedirectAudioManagerCollectRadioContentInfo); }
public void Install() { CSLMusicMod.Log("[CSLMusic] Installing detours ..."); m_RedirectObtainMusicClip = RedirectionHelper.RedirectCalls(typeof(RadioContentInfo).GetMethod("ObtainClip", BindingFlags.Instance | BindingFlags.Public), typeof(CustomRadioContentInfo).GetMethod("CustomObtainClip", BindingFlags.Instance | BindingFlags.Public)); m_RedirectStationName = RedirectionHelper.RedirectCalls(typeof(RadioChannelInfo).GetMethod("GetLocalizedTitle", BindingFlags.Instance | BindingFlags.Public), typeof(CustomRadioChannelInfo).GetMethod("CustomGetLocalizedTitle", BindingFlags.Instance | BindingFlags.Public)); m_RedirectRadioPanelButtonGeneration = RedirectionHelper.RedirectCalls(typeof(RadioPanel).GetMethod("AssignStationToButton", BindingFlags.Instance | BindingFlags.NonPublic), typeof(CustomRadioPanel).GetMethod("CustomAssignStationToButton", BindingFlags.Instance | BindingFlags.NonPublic)); m_RedirectAudioManagerQueueBroadcast = RedirectionHelper.RedirectCalls(typeof(AudioManager).GetMethod("QueueBroadcast", BindingFlags.Instance | BindingFlags.Public), typeof(CustomAudioManager).GetMethod("CustomQueueBroadcast", BindingFlags.Instance | BindingFlags.Public)); m_RedirectAudioManagerCollectRadioContentInfo = RedirectionHelper.RedirectCalls(typeof(AudioManager).GetMethod("CollectRadioContentInfo", BindingFlags.Instance | BindingFlags.Public), typeof(CustomAudioManager).GetMethod("CustomCollectRadioContentInfo", BindingFlags.Instance | BindingFlags.Public)); }
//public void Awake() //{ // DontDestroyOnLoad(this); // LoadSettings(); //} public void SaveSettings() { try { StringWriter json = new StringWriter(); JsonWriter f = new JsonWriter(json); f.PrettyPrint = true; JsonMapper.ToJson(m_Options, f); File.WriteAllText(SettingsFilename, json.ToString()); } catch (Exception ex) { Debug.LogError(ex); } finally { CSLMusicMod.Log("Settings saved."); } }
/// <summary> /// Applies the content sensitivity /// </summary> public void ApplyDisallowedContentRestrictions() { if (!ModOptions.Instance.EnableContextSensitivity && !ModOptions.Instance.EnableDisabledContent) { return; } RebuildDisallowedContent(); // Find the current content and check if it is in the list of allowed content // Otherwise trigger radio content rebuild and stop playback RadioChannelData?currentchannel = AudioManagerHelper.GetActiveChannelData(); if (currentchannel != null) { RadioContentData?currentcontent = AudioManagerHelper.GetActiveContentInfo(); if (currentcontent != null && currentcontent.Value.Info != null) { HashSet <RadioContentInfo> disallowed; if (DisallowedContent.TryGetValue(currentchannel.Value.Info, out disallowed)) { if (ModOptions.Instance.EnableDebugInfo) { foreach (var v in disallowed) { CSLMusicMod.Log("Disallowed:" + v.name + "," + v.m_displayName); } } if (disallowed != null && disallowed.Contains(currentcontent.Value.Info)) { AudioManagerHelper.TriggerRebuildInternalSongList(); CSLMusicMod.Log("Wrong context for " + currentcontent.Value.Info.m_fileName); AudioManagerHelper.NextTrack(); } } } } }
private List <UserRadioContent> LoadSongsFromCollection(String legacycollection, String collectionprefix, String dir) { List <UserRadioContent> result = new List <UserRadioContent>(); CSLMusicMod.Log("Looking for songs in " + dir); if (Directory.Exists(dir)) { LoadSongsFromFolder(legacycollection, dir); foreach (String d in Directory.GetDirectories(dir)) { result.AddRange(LoadSongsFromFolder(collectionprefix + Path.GetFileNameWithoutExtension(d), d)); } } else { CSLMusicMod.Log("Skipped: Directory does not exist!"); } return(result); }
public override void OnLevelLoaded(LoadMode mode) { base.OnLevelLoaded(mode); CSLMusicMod.Log("Got OnLevelLoaded: " + mode); if (mode == LoadMode.LoadGame || mode == LoadMode.NewGame || mode == LoadMode.NewGameFromScenario) { CSLMusicMod.Log("Level loaded. Loading mod components."); RemoveUnsupportedContent(); UserRadioContainer.CollectPostLoadingData(); ExtendVanillaContent(); // Build UI and other post loadtime if (UI == null && ModOptions.Instance.EnableCustomUI) { UI = new GameObject("CSLMusicMod_UI").AddComponent <MusicUI>(); } if (UIShortcutHandler == null && ModOptions.Instance.EnableShortcuts) { UIShortcutHandler = new GameObject("CSLMusicMod_UIShortcutHandler").AddComponent <ShortcutHandler>(); } if (DisabledContentContainer == null) { DisabledContentContainer = new GameObject("CSLMusicMod_DisabledContent").AddComponent <RadioContentWatcher>(); } try { DebugOutput(); } catch (Exception ex) { Debug.LogError("[CSLMusic] DebugOutput Error: " + ex); } } }
public void LoadSettings() { if (File.Exists(SettingsFilename)) { try { String data = File.ReadAllText(SettingsFilename); m_Options = JsonMapper.ToObject <Options>(data); } catch (Exception ex) { Debug.LogError(ex); } finally { CSLMusicMod.Log("Settings loaded."); } } else { SaveSettings(); } }
/// <summary> /// Initializes the custom songs /// </summary> protected void InitializeImpl() { UserRadioCollection collection = LoadingExtension.UserRadioContainer; var collectionnames = collection.m_Songs.Values.Select(song => song.m_Collection).Distinct().ToArray(); CSLMusicMod.Log("Available collections: " + String.Join("\n", collectionnames)); foreach (UserRadioContent content in collection.m_Songs.Values) { try { // Bases all music on vanilla "Aukio" song. CreatePrefab(content.m_Name, "aukio", new Action <RadioContentInfo>((RadioContentInfo obj) => { obj.m_fileName = content.m_FileName; obj.m_displayName = content.m_DisplayName; obj.m_contentType = content.m_ContentType; // Add the channels this song is playing in into the song. List <RadioChannelInfo> channels = new List <RadioChannelInfo>(); foreach (UserRadioChannel uchannel in content.m_Channels) { var channel = FindChannelPrefab(uchannel.m_Name); channels.Add(channel); } obj.m_radioChannels = channels.ToArray(); })); } catch (Exception e) { Debug.LogError("[CSLMusic] Error while initializing prefab in " + content.m_Name + "! Exception: " + e.ToString()); } } }
/// <summary> /// The game usually loads its music from its data directories. This is not compatible with /// custom music. This detour method loads vanilla music the vanilla way and /// custom music from absolute paths. /// </summary> /// <returns>The obtained clip.</returns> public WWW CustomObtainClip() { if (File.Exists(this.m_fileName)) { var uri = new Uri(this.m_fileName); var uristring = uri.AbsoluteUri; uristring = uristring.Replace("%20", " "); //var uristring = "file://" + this.m_fileName.Replace("\\","/").Replace("#", "%23"); CSLMusicMod.Log("Loading custom clip from " + this.m_fileName + " (" + uristring + ")"); return(new WWW(uristring)); } else { string text = Path.Combine(DataLocation.gameContentPath, "Radio"); text = Path.Combine(text, this.m_contentType.ToString()); text = Path.Combine(text, this.m_folderName); text = Path.Combine(text, this.m_fileName); CSLMusicMod.Log("Loading Clip from " + text); return(new WWW("file:///" + text)); } }
/// <summary> /// Adds music files that are placed in the vanilla directories to the vanilla channels /// </summary> private void ExtendVanillaContent() { if (!ModOptions.Instance.EnableAddingContentToVanillaStations) { return; } if (!ModOptions.Instance.AddVanillaSongsToMusicMix) { return; } for (uint i = 0; i < PrefabCollection <RadioChannelInfo> .PrefabCount(); ++i) { RadioChannelInfo info = PrefabCollection <RadioChannelInfo> .GetPrefab(i); if (info == null) { continue; } if (!UserRadioContainer.m_UserRadioDict.ContainsKey(info)) { // Collect existing radio content HashSet <string> existing = new HashSet <string>(); for (uint j = 0; j < PrefabCollection <RadioContentInfo> .PrefabCount(); ++j) { RadioContentInfo content = PrefabCollection <RadioContentInfo> .GetPrefab(j); if (content == null) { continue; } if (content.m_radioChannels == null) { continue; } if (content.m_radioChannels.Contains(info)) { string text = Path.Combine(DataLocation.gameContentPath, "Radio"); text = Path.Combine(text, content.m_contentType.ToString()); text = Path.Combine(text, content.m_folderName); text = Path.Combine(text, content.m_fileName); existing.Add(text); } } HashSet <string> validcollectionnames = new HashSet <string>(); foreach (RadioContentInfo.ContentType type in Enum.GetValues(typeof(RadioContentInfo.ContentType))) { validcollectionnames.Add(type + ": " + info.name); } // Check our collection for non-existing files foreach (UserRadioContent usercontent in UserRadioContainer.m_Songs.Values) { if (!existing.Contains(usercontent.m_FileName) && validcollectionnames.Contains(usercontent.m_Collection)) { CSLMusicMod.Log("[ExtendedVanillaContent] Adding " + usercontent.m_FileName + " to vanilla station " + info.name); List <RadioChannelInfo> v = GenericHelper.CopyOrCreateList <RadioChannelInfo>(usercontent.m_VanillaContentInfo.m_radioChannels); v.Add(info); usercontent.m_VanillaContentInfo.m_radioChannels = v.ToArray(); } } } } }
/// <summary> /// Removes disabled content from this channel. /// </summary> /// <param name="info">Info.</param> private void RemoveUnsupportedContent(RadioChannelInfo info) { if (info == null) { return; } if (info.m_stateChain == null) { return; } CSLMusicMod.Log("Removing unsupported content from " + info); var options = ModOptions.Instance; List <RadioChannelInfo.State> states = new List <RadioChannelInfo.State>(info.m_stateChain); states.RemoveAll((RadioChannelInfo.State obj) => { switch (obj.m_contentType) { case RadioContentInfo.ContentType.Blurb: if (!options.AllowContentBlurb) { return(true); } break; case RadioContentInfo.ContentType.Broadcast: if (!options.AllowContentBroadcast) { return(true); } break; case RadioContentInfo.ContentType.Commercial: if (!options.AllowContentCommercial) { return(true); } break; case RadioContentInfo.ContentType.Music: if (!options.AllowContentMusic) { return(true); } break; case RadioContentInfo.ContentType.Talk: if (!options.AllowContentTalk) { return(true); } break; } return(false); }); info.m_stateChain = states.ToArray(); }