private (Bot?bot, BotInfo?info) InstantiateNewBot(ConfBot config) { lock (lockObj) { if (!string.IsNullOrEmpty(config.Name)) { var maybeBot = GetBotSave(config.Name); if (maybeBot != null) { return(null, maybeBot.GetInfo()); } } var id = GetFreeId(); if (id == null) { return(null, null); // "BotManager is shutting down" } var botInjector = new BotInjector(coreInjector); botInjector.AddModule(botInjector); botInjector.AddModule(new Id(id.Value)); botInjector.AddModule(config); if (!botInjector.TryCreate <Bot>(out var bot)) { return(null, null); // "Failed to create new Bot" } InsertBot(bot); return(bot, null); } }
public Voting(Player player, Ts3Client client, TsFullClient ts3FullClient, ConfBot config) { this.player = player; this.client = client; this.config = config; this.ts3FullClient = ts3FullClient; }
public Player(ConfBot config, Id id) { FfmpegProducer = new FfmpegProducer(config.GetParent().Tools.Ffmpeg, id); WebSocketPipe = new WebSocketPipe(); StallCheckPipe = new StallCheckPipe(); VolumePipe = new VolumePipe(); Volume = config.Audio.Volume.Default; EncoderPipe = new EncoderPipe(SendCodec) { Bitrate = ScaleBitrate(config.Audio.Bitrate) }; EncoderPipeHighQuality = new EncoderPipe(Codec.OpusMusic) { Bitrate = 192000 }; TimePipe = new PreciseTimedPipe { ReadBufferSize = EncoderPipe.PacketSize }; TimePipe.Initialize(EncoderPipe, id); MergePipe = new PassiveMergePipe(); SplitterPipe = new PassiveSplitterPipe(); config.Audio.Bitrate.Changed += (s, e) => EncoderPipe.Bitrate = ScaleBitrate(e.NewValue); MergePipe.Into(TimePipe).Chain <CheckActivePipe>().Chain(SplitterPipe); SplitterPipe.Chain(EncoderPipeHighQuality).Chain(WebSocketPipe); SplitterPipe.Chain(StallCheckPipe).Chain(VolumePipe).Chain(EncoderPipe); }
public PlayManager(ConfBot config, IPlayerConnection playerConnection, PlaylistManager playlistManager, ResourceFactory resourceFactory) { confBot = config; this.playerConnection = playerConnection; this.playlistManager = playlistManager; this.resourceFactory = resourceFactory; }
public PlayManager(ConfBot config, Player playerConnection, PlaylistManager playlistManager, ResourceResolver resourceResolver) { confBot = config; this.playerConnection = playerConnection; this.playlistManager = playlistManager; this.resourceResolver = resourceResolver; }
public PlaylistIO(ConfBot confBot) { this.confBot = confBot; playlistCache = new LruCache <string, Playlist>(16); Util.Init(out playlistInfo); Util.Init(out dirtyList); }
public static string ExecuteTryCatch( ConfBot config, bool answer, Func <string> action, Action <string> errorHandler) { try { return(action()); } catch (CommandException ex) { NLog.LogLevel commandErrorLevel = answer ? NLog.LogLevel.Debug : NLog.LogLevel.Warn; Log.Log(commandErrorLevel, ex, "Command Error ({0})", ex.Message); if (answer) { errorHandler(TextMod.Format(config.Commands.Color, "Error: {0}".Mod().Color(Color.Red).Bold(), ex.Message)); } } catch (Exception ex) { Log.Error(ex, "Unexpected command error: {0}", ex.UnrollException()); if (answer) { errorHandler(TextMod.Format(config.Commands.Color, "An unexpected error occured: {0}".Mod().Color(Color.Red).Bold(), ex.Message)); } } return(null); }
public PlayManager(ConfBot config, Player playerConnection, PlaylistManager playlistManager, ResolveContext resourceResolver, Stats stats) { confBot = config; this.playerConnection = playerConnection; this.playlistManager = playlistManager; this.resourceResolver = resourceResolver; this.stats = stats; }
private R <ResData, LocalStr> ValidateFromString(ConfBot config, string uriStr) { if (TryGetUri(config, uriStr).GetOk(out var uri)) { return(ValidateUri(uri)); } return(new LocalStr(strings.error_media_invalid_uri)); }
public StartSongTask(ResolveContext resourceResolver, Player player, ConfBot config, object playManagerLock, QueueItem queueItem) { this.resourceResolver = resourceResolver; this.player = player; this.config = config; this.playManagerLock = playManagerLock; QueueItem = queueItem; }
public Bot(Id id, ConfBot config, BotInjector injector, ResourceFactory resourceFactory, CommandManager commandManager) { this.Id = id; this.config = config; this.Injector = injector; this.resourceFactory = resourceFactory; this.commandManager = commandManager; }
// Needed for the injector cancer public PlayManager( ConfBot config, Player playerConnection, ResolveContext resourceResolver, PlaylistManager playlistManager) : this(playerConnection, playlistManager) { taskHost = new StartSongTaskHost( item => new StartSongTaskHandler(new StartSongTask(resourceResolver, playerConnection, config.Audio.Volume, Lock, item)) ); Init(); }
public Ts3Client(ConfBot config, TsFullClient ts3FullClient, Id id) { this.id = id; this.ts3FullClient = ts3FullClient; ts3FullClient.OnEachTextMessage += ExtendedTextMessage; ts3FullClient.OnErrorEvent += TsFullClient_OnErrorEvent; ts3FullClient.OnConnected += TsFullClient_OnConnected; ts3FullClient.OnDisconnected += TsFullClient_OnDisconnected; ts3FullClient.OnEachClientMoved += (s, e) => { UpdateReconnectChannel(e.ClientId, e.TargetChannelId); if (AloneRecheckRequired(e.ClientId, e.TargetChannelId)) { IsAloneRecheck(); } }; ts3FullClient.OnEachClientEnterView += (s, e) => { UpdateReconnectChannel(e.ClientId, e.TargetChannelId); if (AloneRecheckRequired(e.ClientId, e.TargetChannelId)) { IsAloneRecheck(); } else if (AloneRecheckRequired(e.ClientId, e.SourceChannelId)) { IsAloneRecheck(); } }; ts3FullClient.OnEachClientLeftView += (s, e) => { UpdateReconnectChannel(e.ClientId, e.TargetChannelId); if (AloneRecheckRequired(e.ClientId, e.TargetChannelId)) { IsAloneRecheck(); } else if (AloneRecheckRequired(e.ClientId, e.SourceChannelId)) { IsAloneRecheck(); } }; this.config = config; identity = null; }
public R <BotInfo, string> RunBot(ConfBot config) { Bot bot; lock (lockObj) { if (!string.IsNullOrEmpty(config.Name)) { bot = GetBotSave(config.Name); if (bot != null) { return(bot.GetInfo()); } } var id = GetFreeId(); if (id == null) { return("BotManager is shutting down"); } var botInjector = new BotInjector(coreInjector); botInjector.AddModule(botInjector); botInjector.AddModule(new TS3Client.Helper.Id(id.Value)); botInjector.AddModule(config); if (!botInjector.TryCreate(out bot)) { return("Failed to create new Bot"); } InsertBot(bot); } lock (bot.SyncRoot) { var initializeResult = bot.InitializeBot(); if (!initializeResult.Ok) { StopBot(bot); return($"Bot failed to connect ({initializeResult.Error})"); } } return(bot.GetInfo()); }
public PlayManager(ConfBot config, Player playerConnection, ResolveContext resourceResolver, Stats stats, PlaylistManager playlistManager) { confBot = config; this.playerConnection = playerConnection; this.resourceResolver = resourceResolver; this.stats = stats; this.playlistManager = playlistManager; playerConnection.FfmpegProducer.OnSongLengthParsed += (sender, args) => { lock (Lock) { if (Current == null) { return; } Log.Info("Preparing song analyzer... (OnSongLengthParsed)"); Current.UpdateStartAnalyzeTime(GetAnalyzeTaskStartTime()); } }; }
private R <Uri, LocalStr> TryGetUri(ConfBot conf, string uri) { if (Uri.TryCreate(uri, UriKind.Absolute, out Uri uriResult)) { return(uriResult); } else { Log.Trace("Finding media path: '{0}'", uri); var file = TryInPath(Path.Combine(conf.LocalConfigDir, BotPaths.Music), uri) ?? TryInPath(conf.GetParent().Factories.Media.Path.Value, uri); if (file == null) { return(new LocalStr(strings.error_media_file_not_found)); } return(file); } }
public R <BotInfo, string> RunBot(ConfBot config, string name = null) { var bot = new Bot(config) { Injector = CoreInjector.CloneRealm <BotInjector>(), Name = name }; if (!CoreInjector.TryInject(bot)) { Log.Warn("Partial bot dependency loaded only"); } lock (bot.SyncRoot) { var initializeResult = bot.InitializeBot(); var removeBot = false; if (initializeResult.Ok) { lock (lockObj) { if (!InsertIntoFreeId(bot)) { removeBot = true; } } } else { return($"Bot failed to connect ({initializeResult.Error})"); } if (removeBot) { StopBot(bot); return("BotManager is shutting down"); } } return(bot.GetInfo()); }
public Player(ConfRoot confRoot, ConfBot config, DedicatedTaskScheduler scheduler, Id id) { this.scheduler = scheduler; FfmpegProducer = new FfmpegProducer(confRoot.Tools.Ffmpeg, scheduler, id); StallCheckPipe = new StallCheckPipe(); VolumePipe = new VolumePipe(); Volume = config.Audio.Volume.Default; EncoderPipe = new EncoderPipe(SendCodec) { Bitrate = ScaleBitrate(config.Audio.Bitrate) }; TimePipe = new PreciseTimedPipe(EncoderPipe, id) { ReadBufferSize = EncoderPipe.PacketSize }; MergePipe = new PassiveMergePipe(); config.Audio.Bitrate.Changed += (s, e) => EncoderPipe.Bitrate = ScaleBitrate(e.NewValue); MergePipe.Into(TimePipe).Chain <CheckActivePipe>().Chain(StallCheckPipe).Chain(VolumePipe).Chain(EncoderPipe); }
public Ts3Client(ConfBot config) { Util.Init(out clientDbNames); Util.Init(out clientbuffer); TsFullClient = new Ts3FullClient(EventDispatchType.DoubleThread); TsFullClient.OnClientLeftView += ExtendedClientLeftView; TsFullClient.OnClientEnterView += ExtendedClientEnterView; TsFullClient.OnTextMessage += ExtendedTextMessage; TsFullClient.OnErrorEvent += TsFullClient_OnErrorEvent; TsFullClient.OnConnected += TsFullClient_OnConnected; TsFullClient.OnDisconnected += TsFullClient_OnDisconnected; int ScaleBitrate(int value) => Math.Min(Math.Max(1, value), 255) * 1000; this.config = config; this.config.Audio.Bitrate.Changed += (s, e) => encoderPipe.Bitrate = ScaleBitrate(e.NewValue); ffmpegProducer = new FfmpegProducer(config.GetParent().Tools.Ffmpeg); stallCheckPipe = new StallCheckPipe(); volumePipe = new VolumePipe(); Volume = config.Audio.Volume.Default; encoderPipe = new EncoderPipe(SendCodec) { Bitrate = ScaleBitrate(config.Audio.Bitrate) }; timePipe = new PreciseTimedPipe { ReadBufferSize = encoderPipe.PacketSize }; timePipe.Initialize(encoderPipe); TargetPipe = new CustomTargetPipe(TsFullClient); mergePipe = new PassiveMergePipe(); mergePipe.Add(ffmpegProducer); mergePipe.Into(timePipe).Chain <CheckActivePipe>().Chain(stallCheckPipe).Chain(volumePipe).Chain(encoderPipe).Chain(TargetPipe); identity = null; }
public Ts3Client(ConfBot config, Ts3FullClient tsFullClient, Id id) { this.id = id; Util.Init(out clientDbNames); Util.Init(out clientbuffer); dbIdCache = new LruCache <string, ulong>(1024); this.tsFullClient = tsFullClient; tsFullClient.OnEachTextMessage += ExtendedTextMessage; tsFullClient.OnErrorEvent += TsFullClient_OnErrorEvent; tsFullClient.OnConnected += TsFullClient_OnConnected; tsFullClient.OnDisconnected += TsFullClient_OnDisconnected; int ScaleBitrate(int value) => Util.Clamp(value, 1, 255) * 1000; this.config = config; this.config.Audio.Bitrate.Changed += (s, e) => encoderPipe.Bitrate = ScaleBitrate(e.NewValue); ffmpegProducer = new FfmpegProducer(config.GetParent().Tools.Ffmpeg, id); stallCheckPipe = new StallCheckPipe(); volumePipe = new VolumePipe(); Volume = config.Audio.Volume.Default; encoderPipe = new EncoderPipe(SendCodec) { Bitrate = ScaleBitrate(config.Audio.Bitrate) }; timePipe = new PreciseTimedPipe { ReadBufferSize = encoderPipe.PacketSize }; timePipe.Initialize(encoderPipe, id); TargetPipe = new CustomTargetPipe(tsFullClient); mergePipe = new PassiveMergePipe(); mergePipe.Add(ffmpegProducer); mergePipe.Into(timePipe).Chain <CheckActivePipe>().Chain(stallCheckPipe).Chain(volumePipe).Chain(encoderPipe).Chain(TargetPipe); identity = null; }
private Uri GetUri(ConfBot conf, string uri) { if (Uri.TryCreate(uri, UriKind.Absolute, out Uri? uriResult)) { return(uriResult); } else { Log.Trace("Finding media path: '{0}'", uri); Uri?file = null; if (conf.LocalConfigDir != null) { file ??= TryInPath(Path.Combine(conf.LocalConfigDir, BotPaths.Music), uri); } file ??= TryInPath(conf.GetParent().Factories.Media.Path.Value, uri); if (file is null) { throw Error.LocalStr(strings.error_media_file_not_found); } return(file); } }
public async Task <R <BotInfo, string> > RunBot(ConfBot config) { var(bot, info) = InstantiateNewBot(config); if (info != null) { return(info); } if (bot is null) { return("Failed to create new Bot"); } return(await bot.Scheduler.InvokeAsync <R <BotInfo, string> >(async() => { var initializeResult = await bot.Run(); if (!initializeResult.Ok) { await StopBot(bot); return $"Bot failed to initialize ({initializeResult.Error})"; } return bot.GetInfo(); })); }
public Bot(Id id, ConfBot config, BotInjector injector) { this.Id = id; this.config = config; this.Injector = injector; }
public PlaylistIO(ConfBot confBot) { this.confBot = confBot; ReloadFolder(); }
public PlaylistIO(ConfBot confBot) { this.confBot = confBot; }
public Bot(ConfBot config, BotInjector injector) { this.config = config; this.Injector = injector; }
public Bot(Id id, ConfBot config, BotInjector injector) { this.Id = id; this.config = config; this.Injector = injector; // Registering config changes config.Language.Changed += async(s, e) => { var langResult = await localization.LoadLanguage(e.NewValue, true); if (!langResult.Ok) { Log.Error("Failed to load language file ({0})", langResult.Error); } }; config.Events.IdleDelay.Changed += (s, e) => EnableIdleTickWorker(); config.Events.OnIdle.Changed += (s, e) => EnableIdleTickWorker(); var builder = new DependencyBuilder(Injector); Injector.HideParentModule <CommandManager>(); Injector.HideParentModule <DedicatedTaskScheduler>(); Injector.AddModule(this); Injector.AddModule(config); Injector.AddModule(Injector); Injector.AddModule(config.Playlists); Injector.AddModule(config.History); Injector.AddModule(Id); builder.RequestModule <PlaylistIO>(); builder.RequestModule <PlaylistManager>(); builder.RequestModule <DedicatedTaskScheduler>(); builder.RequestModule <TsFullClient>(); builder.RequestModule <TsBaseFunctions, TsFullClient>(); builder.RequestModule <Ts3Client>(); builder.RequestModule <Player>(); builder.RequestModule <CustomTargetPipe>(); builder.RequestModule <IVoiceTarget, CustomTargetPipe>(); builder.RequestModule <SessionManager>(); builder.RequestModule <ResolveContext>(); builder.RequestModule <CommandManager>(); builder.RequestModule <LocalizationManager>(); if (config.History.Enabled) { builder.RequestModule <HistoryManager>(); } builder.RequestModule <PlayManager>(); if (!builder.Build()) { Log.Error("Missing bot module dependency"); throw new Exception("Could not load all bot modules"); } Injector.ClearHiddenParentModules(); resourceResolver = Injector.GetModuleOrThrow <ResolveContext>(); ts3FullClient = Injector.GetModuleOrThrow <TsFullClient>(); ts3client = Injector.GetModuleOrThrow <Ts3Client>(); player = Injector.GetModuleOrThrow <Player>(); Scheduler = Injector.GetModuleOrThrow <DedicatedTaskScheduler>(); var customTarget = Injector.GetModuleOrThrow <CustomTargetPipe>(); player.SetTarget(customTarget); Injector.AddModule(ts3FullClient.Book); playManager = Injector.GetModuleOrThrow <PlayManager>(); targetManager = Injector.GetModuleOrThrow <IVoiceTarget>(); sessionManager = Injector.GetModuleOrThrow <SessionManager>(); stats = Injector.GetModuleOrThrow <Stats>(); var commandManager = Injector.GetModuleOrThrow <CommandManager>(); localization = Injector.GetModuleOrThrow <LocalizationManager>(); idleTickWorker = Scheduler.Invoke(() => Scheduler.CreateTimer(OnIdle, TimeSpan.MaxValue, false)).Result; player.OnSongEnd += playManager.SongStoppedEvent; player.OnSongUpdated += (s, e) => playManager.Update(e); // Update idle status events playManager.BeforeResourceStarted += (s, e) => { DisableIdleTickWorker(); return(Task.CompletedTask); }; playManager.PlaybackStopped += (s, e) => { EnableIdleTickWorker(); return(Task.CompletedTask); }; // Used for custom scripts, like voice_mode, onsongstart playManager.BeforeResourceStarted += BeforeResourceStarted; playManager.AfterResourceStarted += AfterResourceStarted; // Update the own status text to the current song title playManager.AfterResourceStarted += (s, e) => UpdateBotStatus(); playManager.PlaybackStopped += (s, e) => UpdateBotStatus(); playManager.OnResourceUpdated += (s, e) => UpdateBotStatus(); // Log our resource in the history if (Injector.TryGet <HistoryManager>(out var historyManager)) { playManager.AfterResourceStarted += (s, e) => { if (e.PlayInfo != null) { historyManager.LogAudioResource(new HistorySaveData(e.PlayResource.AudioResource, e.PlayInfo.ResourceOwnerUid)); } return(Task.CompletedTask); } } ; // Update our thumbnail playManager.AfterResourceStarted += (s, e) => GenerateStatusImage(true, e); playManager.PlaybackStopped += (s, e) => GenerateStatusImage(false, null); // Stats playManager.AfterResourceStarted += (s, e) => { stats.TrackSongStart(Id, e.ResourceData.AudioType); return(Task.CompletedTask); }; playManager.ResourceStopped += (s, e) => { stats.TrackSongStop(Id); return(Task.CompletedTask); }; // Register callback for all messages happening ts3client.OnMessageReceived += OnMessageReceived; // Register callback to remove open private sessions, when user disconnects ts3FullClient.OnEachClientLeftView += OnClientLeftView; ts3client.OnBotConnected += OnBotConnected; ts3client.OnBotDisconnected += OnBotDisconnected; ts3client.OnBotStoppedReconnecting += OnBotStoppedReconnecting; // Alone mode ts3client.OnAloneChanged += OnAloneChanged; ts3client.OnAloneChanged += (s, e) => { customTarget.Alone = e.Alone; return(Task.CompletedTask); }; // Whisper stall ts3client.OnWhisperNoTarget += (s, e) => player.SetStall(); commandManager.RegisterCollection(MainCommands.Bag); // TODO remove after plugin rework var pluginManager = Injector.GetModuleOrThrow <PluginManager>(); foreach (var plugin in pluginManager.Plugins) { if (plugin.Type == PluginType.CorePlugin || plugin.Type == PluginType.Commands) { commandManager.RegisterCollection(plugin.CorePlugin.Bag); } } // Restore all alias from the config foreach (var alias in config.Commands.Alias.GetAllItems()) { commandManager.RegisterAlias(alias.Key, alias.Value).UnwrapToLog(Log); } }
private Task <ResData> ValidateFromString(ConfBot config, string uriStr) { var uri = GetUri(config, uriStr); return(ValidateUri(uri)); }
public ResolveContext(ResourceResolver resolver, ConfBot config) { Resolver = resolver; Config = config; }
public Bot(ConfBot config) { this.config = config; }