private bool CheckValidModifiers(Dictionary <string, double> manualModifiers, Action <string> messageCallback) { if (manualModifiers == null) { return(true); } foreach (string currentMod in manualModifiers.Keys) { if (!ModifierRanges.ContainsKey(currentMod)) { messageCallback.Invoke(ColorCoder.Error($"The modifier '{currentMod}' doesn't exist!")); } double manualVal = manualModifiers[currentMod]; double min = ModifierRanges[currentMod].Item1; double max = ModifierRanges[currentMod].Item2; if (manualVal < min || manualVal > max) { messageCallback.Invoke(ColorCoder.Error($"The modifier '{currentMod}' is not in the valid range of [{min} to {max}]!")); return(false); } } return(true); }
private void AddPlaysound(string name, uint price, string fileName, string source, Action <string> messageCallback) { if (Settings.PlaysoundsSavedSounds.FirstOrDefault(ps => ps.Name == name) != null) { messageCallback.Invoke(ColorCoder.Error($"A playsound with the name {ColorCoder.Bold($"'{name}'")} already exists!")); return; } string filePath = Utils.GetProjectFilePath($"{SoundsFolder}\\{fileName}"); if (!File.Exists(filePath)) { messageCallback.Invoke(ColorCoder.Error($"No file with the name {ColorCoder.Bold($"'{fileName}'")} was found in the playsounds folder!")); return; } Settings.PlaysoundsSavedSounds.Add(new Playsound() { Name = name, FileName = fileName, BasePrice = (int)price, Source = source, }); Settings.DelayedSave(); messageCallback.Invoke(ColorCoder.Success($"Added playsound {ColorCoder.Bold($"'{name}'")}!")); }
private void RemovePlaysound(string name, Action <string> messageCallback) { if (Settings.PlaysoundsSavedSounds.FirstOrDefault(ps => ps.Name == name) == null) { messageCallback.Invoke(ColorCoder.Error($"A playsound with the name {ColorCoder.Bold($"'{name}'")} wasn't found!")); return; } Playsound sound = Settings.PlaysoundsSavedSounds.First(ps => ps.Name == name); Settings.PlaysoundsSavedSounds.Remove(sound); Settings.DelayedSave(); messageCallback.Invoke(ColorCoder.Success($"Removed playsound {ColorCoder.Bold($"'{name}'")}!")); }
public override void HandleCommand(NotifyTextMessageEvent evt, string command, List <string> parameters, Action <string> messageCallback) { // +----------------------+ // | Administrative Block | // +----------------------+ if (IsAdministrativeCommand) { if (AdminAction == "add-file") { AddPlaysound(AdminPlaysoundName, AdminPlaysoundPrice, AdminPlaysoundFileName, AdminPlaysoundSource, messageCallback); } else if (AdminAction == "add-yt") { } else if (AdminAction == "remove") { RemovePlaysound(AdminPlaysoundName, messageCallback); } else if (AdminAction == "add-modifier") { } else if (AdminAction == "list-devices") { string devices = string.Join("\n\t", AudioHelper.GetAudioDevices()); messageCallback.Invoke($"All audio devices:\n\t{devices}"); } else if (AdminAction == "stop-sounds") { int killed = 0; foreach (Process p in AllStartedSoundProcesses) { if (!p.HasExited) { p.Kill(); killed++; } } AllStartedSoundProcesses.Clear(); messageCallback.Invoke(ColorCoder.ErrorBright($"Killed {ColorCoder.Bold($"'{killed}'")} audio process(es)")); } return; } if (parameters.Count == 2 && parameters[0] == "price") { int price = CalculateYoutubePlaysoundCost(PriceLookupDuration); messageCallback.Invoke($"Cost for {ColorCoder.Bold($"'{PriceLookupDuration}'")} seconds of a youtube video: {ColorCoder.Currency(price)}"); return; } // +----------------------+ // | Pagination | // +----------------------+ if (HasRequestedPagination) { int entriesPerPage = Settings.PlaysoundsSoundsPerPage; int maxPage = (int)Math.Ceiling((double)Settings.PlaysoundsSavedSounds.Count / entriesPerPage); if (RequestedPage < 1 || RequestedPage > maxPage) { messageCallback.Invoke($"The page '{RequestedPage}' is not in the valid range of [1 to {maxPage}]!"); return; } int pageIndex = (int)RequestedPage - 1; int skipValues = pageIndex * entriesPerPage; List <Playsound> thisPage = Settings.PlaysoundsSavedSounds.OrderBy(ps => ps.BasePrice).ThenBy(ps => ps.Name).Skip(skipValues).Take(entriesPerPage).ToList(); string toPrint = ""; foreach (Playsound listSound in thisPage) { toPrint += $"\n'{listSound.Name}'\t({listSound.BasePrice} {Settings.EcoPointUnitName})"; } toPrint += $"\n\t\t\t{ColorCoder.Bold($"-\tPage ({RequestedPage}/{maxPage})\t-")}"; toPrint += $"\n\nTo switch pages write '{Settings.ChatCommandPrefix}{command} <1/2/3/...>'"; messageCallback.Invoke(toPrint); return; } if (evt.TargetMode != TSClient.Enums.MessageMode.Channel) { messageCallback.Invoke(ColorCoder.Error("Playsounds can only be used in channel chats!")); return; } Client myClient = Parent.Client.GetClientById(Parent.MyClientId); if (Parent.Client.IsClientOutputMuted(myClient)) { messageCallback.Invoke(ColorCoder.Error("This doesn't work right now...")); return; } if (Parent.Client.IsClientInputMuted(myClient)) { messageCallback.Invoke(ColorCoder.Error("Host is muted, playsound can still be played but others won't hear it (@Panther)")); } CooldownManager.ThrowIfCooldown(evt.InvokerUniqueId, "command:playsounds"); // +-------------------------+ // | Playback of local files | // +-------------------------+ if (!CheckValidModifiers(ManualModifiers, messageCallback)) { return; } double speed = 1.0, pitch = 1.0, volume = 1.0; if (SelectedModifier != null) { Dictionary <string, double> modifiers = Settings.PlaysoundsModifiers[SelectedModifier]; if (modifiers.ContainsKey(ModifierNameSpeed)) { speed = modifiers[ModifierNameSpeed]; } if (modifiers.ContainsKey(ModifierNamePitch)) { pitch = modifiers[ModifierNamePitch]; } if (modifiers.ContainsKey(ModifierNameVolume)) { volume = modifiers[ModifierNameVolume]; } } if (ManualModifiers != null) { if (ManualModifiers.ContainsKey(ModifierNameSpeed)) { speed = ManualModifiers[ModifierNameSpeed]; } if (ManualModifiers.ContainsKey(ModifierNamePitch)) { pitch = ManualModifiers[ModifierNamePitch]; } if (ManualModifiers.ContainsKey(ModifierNameVolume)) { volume = ManualModifiers[ModifierNameVolume]; } } Dictionary <string, double> actualModifiers = new Dictionary <string, double>() { [ModifierNameSpeed] = speed, [ModifierNamePitch] = pitch, [ModifierNameVolume] = volume, }; double priceFactor = GetPriceFactorForModifiers(actualModifiers); int basePrice; string filePath; double baseDuration; string playingSoundStr; if (SourceIsYoutube) { // +----------------------+ // | Youtube fetching | // +----------------------+ if (SoundSource.ToLower().StartsWith("[url]")) { SoundSource = Utils.RemoveTag(SoundSource, "url"); } string title = ""; string youtubeUrl = AudioHelper.IsYouTubeVideoUrl(SoundSource); if (youtubeUrl != null) { lock (YoutubeDownloadLock) { if (IsLoadingYoutubeAudio) { string loadingStr = LoadingPercentDone == -1 ? "download not yet started" : $"{LoadingPercentDone:0.##}%"; messageCallback.Invoke(ColorCoder.ErrorBright($"Chill, I'm still loading another clip... ({loadingStr})")); return; } IsLoadingYoutubeAudio = true; } string videoId = youtubeUrl.Substring(youtubeUrl.IndexOf($"v=") + 2, 11); try { (filePath, title) = AudioHelper.LoadYoutubeVideo(videoId, (int)YoutubeStartTime, (int)(YoutubeEndTime - YoutubeStartTime) + 1, new ProgressSaver()); Parent.UpdateYoutubeFolderSize(); } catch (ArgumentException ex) { messageCallback.Invoke(ColorCoder.ErrorBright($"Error with youtube video: {ex.Message}")); lock (YoutubeDownloadLock) { IsLoadingYoutubeAudio = false; LoadingPercentDone = -1; } return; } lock (YoutubeDownloadLock) { IsLoadingYoutubeAudio = false; LoadingPercentDone = -1; } } else { messageCallback.Invoke(ColorCoder.ErrorBright($"The URL is not a youtube link...")); return; } baseDuration = AudioHelper.GetAudioDurationInSeconds(filePath); if (double.IsNaN(baseDuration)) { messageCallback.Invoke(ColorCoder.ErrorBright($"Couldn't get audio duration from file '{filePath}'")); return; } basePrice = CalculateYoutubePlaysoundCost(baseDuration); if (baseDuration <= 60 && Settings.PlaysoundsYoutubeOnePointEvent) { basePrice = 1; } playingSoundStr = ColorCoder.SuccessDim($" Playing YouTube clip {ColorCoder.Bold($"'{title}'")} [{TimeSpan.FromSeconds((int)baseDuration)}]."); } else { Playsound sound; if (SoundSource == "random") { Random r = new Random(); sound = Settings.PlaysoundsSavedSounds.FindAll(ps => Math.Ceiling(ps.BasePrice * priceFactor) <= EconomyManager.GetBalanceForUser(evt.InvokerUniqueId)).OrderBy(ps => r.Next()).First(); } else { List <Playsound> sounds = Settings.PlaysoundsSavedSounds.FindAll(ps => ps.Name.ToLower().Contains(SoundSource.ToLower())); //Fix for matching the exact sound name Playsound exactSound = Settings.PlaysoundsSavedSounds.Find(ps => ps.Name == SoundSource); if (exactSound != null) { sounds.Clear(); sounds.Add(exactSound); } if (sounds.Count == 0) { messageCallback.Invoke(ColorCoder.Error($"A playsound with the name {ColorCoder.Bold($"'{SoundSource}'")} wasn't found!")); return; } else if (sounds.Count > 1) { string soundsJoined = string.Join(", ", sounds.Select(ps => ColorCoder.Bold($"'{ps.Name}'"))); messageCallback.Invoke(ColorCoder.Error($"Multiple sounds with {ColorCoder.Bold($"'{SoundSource}'")} in their name were found: ({soundsJoined})")); return; } else { sound = sounds[0]; } } basePrice = sound.BasePrice; filePath = Utils.GetProjectFilePath($"{SoundsFolder}\\{sound.FileName}"); baseDuration = AudioHelper.GetAudioDurationInSeconds(filePath); playingSoundStr = ColorCoder.SuccessDim($" Playing sound {ColorCoder.Bold($"'{sound.Name}'")}."); } int modifiedPrice = Math.Max(1, (int)Math.Round(basePrice * priceFactor)); double modifiedDuration = baseDuration / speed; int balanceAfter = EconomyManager.GetUserBalanceAfterPaying(evt.InvokerUniqueId, modifiedPrice); if (balanceAfter < 0) { messageCallback.Invoke(ColorCoder.Error($"You dont have enough cash for that sound, {ColorCoder.Username(evt.InvokerName)}. Price: {ColorCoder.Currency(modifiedPrice, Settings.EcoPointUnitName)}, Needed: {ColorCoder.Currency(-balanceAfter, Settings.EcoPointUnitName)}")); return; } CooldownManager.SetCooldown(evt.InvokerUniqueId, "command:playsounds", CalculateCooldown(modifiedDuration)); EconomyManager.ChangeBalanceForUser(evt.InvokerUniqueId, -modifiedPrice); string usernameStr = ColorCoder.Username(evt.InvokerName); string priceAdditionStr = priceFactor == 1 ? "" : $" x{priceFactor:0.##} = -{modifiedPrice}"; string balanceStr = $"Your balance: {EconomyManager.GetBalanceForUser(evt.InvokerUniqueId)} {Settings.EcoPointUnitName} {ColorCoder.ErrorBright($"(-{basePrice}{priceAdditionStr})")}"; messageCallback.Invoke($"{usernameStr} {playingSoundStr} {balanceStr}"); Process audioProcess = AudioHelper.PlayAudio(filePath, volume, speed, pitch, audioDevice: Settings.PlaysoundsSoundDevice); AllStartedSoundProcesses.Add(audioProcess); }