public void StartTimedSnapshots() { if (ticker != null) { throw new InvalidOperationException("Ticker already running"); } ticker = TickPool.RegisterTick(CreateSnapshot, TimeSpan.FromSeconds(1), true); }
private void SetIdleTickWorker(TickWorker worker) { var oldWoker = Interlocked.Exchange(ref idleTickWorker, worker); if (oldWoker != null) { TickPool.UnregisterTicker(oldWoker); } }
public void StartTimer(bool upload) { uploadParamEnabled = upload; if (ticker != null) { throw new InvalidOperationException(); } ticker = TickPool.RegisterTick(() => TrackPoint(), CheckInterval, true); }
private void TsFullClient_OnDisconnected(object sender, DisconnectEventArgs e) { if (e.Error != null) { var error = e.Error; switch (error.Id) { case Ts3ErrorCode.client_could_not_validate_identity: if (config.Connect.Identity.Level.Value == -1) { int targetSecLevel = int.Parse(error.ExtraMessage); UpdateIndentityToSecurityLevel(targetSecLevel); ConnectClient(); return; // skip triggering event, we want to reconnect } else { Log.Warn("The server reported that the security level you set is not high enough." + "Increase the value to '{0}' or set it to '-1' to generate it on demand when connecting.", error.ExtraMessage); } break; case Ts3ErrorCode.client_too_many_clones_connected: if (reconnectCounter++ < MaxReconnects) { Log.Warn("Seems like another client with the same identity is already connected. Waiting {0:0} seconds to reconnect.", TooManyClonesReconnectDelay.TotalSeconds); reconnectTick = TickPool.RegisterTickOnce(() => ConnectClient(), TooManyClonesReconnectDelay); return; // skip triggering event, we want to reconnect } break; default: Log.Warn("Could not connect: {0}", error.ErrorFormat()); break; } } else { Log.Debug("Bot disconnected. Reason: {0}", e.ExitReason); if (reconnectCounter < LostConnectionReconnectDelay.Length && !closed) { var delay = LostConnectionReconnectDelay[reconnectCounter++]; Log.Info("Trying to reconnect. Delaying reconnect for {0:0} seconds", delay.TotalSeconds); reconnectTick = TickPool.RegisterTickOnce(() => ConnectClient(), delay); return; } } if (reconnectCounter >= LostConnectionReconnectDelay.Length) { Log.Warn("Could not (re)connect after {0} tries. Giving up.", reconnectCounter); } OnBotDisconnect?.Invoke(this, e); }
private void StopReconnectTickWorker() { var reconnectTickLocal = reconnectTick; reconnectTick = null; if (reconnectTickLocal != null) { TickPool.UnregisterTicker(reconnectTickLocal); } }
public void Initialize(MainBot mainBot) { bot = mainBot; //var pluginPath = mainBot.ConfigManager.GetDataStruct<PluginManagerData>("PluginManager", true).PluginPath; var pluginPath = "Plugins"; cfgfile = Path.Combine(pluginPath, $"{PluginInfo.Name}.cfg"); try { if (File.Exists(cfgfile)) { var parser = new FileIniDataParser(); cfg = parser.ReadFile(cfgfile); PluginLog(Log.Level.Debug, $"cfgfile = {cfgfile}"); if (cfg["Ignore"]["uids"].Contains(',')) { whitelistUID = cfg["Ignore"]["uids"].Split(',').ToList(); } else { whitelistUID.Add(cfg["Ignore"]["uids"]); } if (cfg["Ignore"]["sgids"].Contains(',')) { var _whitelistSGID = cfg["Ignore"]["sgids"].Split(','); foreach (var wsgid in _whitelistSGID) { whitelistSGID.Add(ServerGroupIdT.Parse(wsgid)); } } else { whitelistSGID.Add(ServerGroupIdT.Parse(cfg["Ignore"]["sgids"])); } } } catch (Exception ex) { throw new Exception($"{PluginInfo.Name} Can't load \"{cfgfile}\"! Error:\n{ex}"); cfg = new IniData(); //while (!Setup()) { } } ispfile = Path.Combine(pluginPath, "ISPs.txt"); PluginLog(Log.Level.Debug, $"ispfile = {ispfile}"); if (File.Exists(ispfile)) { isps = File.ReadAllLines(ispfile).ToList(); } lib = mainBot.QueryConnection.GetLowLibrary <Ts3FullClient>(); lib.OnClientEnterView += Lib_OnClientEnterView; lib.OnConnected += Lib_OnConnected; ClearCache = TickPool.RegisterTick(Tick, TimeSpan.FromMinutes(UInt64.Parse(cfg["General"]["clearcache"])), false); Enabled = true; PluginLog(Log.Level.Debug, "Plugin " + PluginInfo.Name + " v" + PluginInfo.Version + " by " + PluginInfo.Author + " loaded."); }
public string CommandSetClientToggleBadges() { if (!Timer.Active) { Timer = TickPool.RegisterTick(SetRandomBadge, TimeSpan.FromMilliseconds(500), true); return("Auto toggeling badges"); } else { Timer.Active = false; Timer = null; return("Stopped toggeling badges"); } }
private bool TryReconnect(ReconnectType type) { if (closed) { return(false); } if (lastReconnect != type) { reconnectCounter = 0; } lastReconnect = type; TimeSpan?delay; switch (type) { case ReconnectType.Timeout: delay = config.Reconnect.OnTimeout.GetValueAsTime(reconnectCounter); break; case ReconnectType.Kick: delay = config.Reconnect.OnKick.GetValueAsTime(reconnectCounter); break; case ReconnectType.Ban: delay = config.Reconnect.OnBan.GetValueAsTime(reconnectCounter); break; case ReconnectType.ServerShutdown: delay = config.Reconnect.OnShutdown.GetValueAsTime(reconnectCounter); break; case ReconnectType.Error: delay = config.Reconnect.OnError.GetValueAsTime(reconnectCounter); break; case ReconnectType.None: return(false); default: throw Util.UnhandledDefault(type); } reconnectCounter++; if (delay == null) { Log.Info("Reconnect strategy for '{0}' has reached the end. Closing instance.", type); return(false); } Log.Info("Trying to reconnect because of {0}. Delaying reconnect for {1:0} seconds", type, delay.Value.TotalSeconds); reconnectTick = TickPool.RegisterTickOnce(() => ConnectClient(), delay); return(true); }
public BobController(BobControllerData data, QueryConnection queryConnection) { if (queryConnection == null) { throw new ArgumentNullException(nameof(queryConnection)); } timeout = TickPool.RegisterTick(TimeoutCheck, TimeSpan.FromMilliseconds(100), false); musicInfoWaiter = new WaitEventBlock <MusicData>(); isRunning = false; awaitingConnect = false; this.bobControllerData = data; this.queryConnection = queryConnection; queryConnection.OnMessageReceived += GetResponse; queryConnection.OnClientConnect += OnBobConnect; queryConnection.OnClientDisconnect += OnBobDisconnnect; commandQueue = new Queue <string>(); channelSubscriptions = new Dictionary <int, SubscriptionData>(); }
public Ts3Full(Ts3FullClientData tfcd) : base(ClientType.Full) { tsFullClient = (Ts3FullClient)tsBaseClient; ts3FullClientData = tfcd; tfcd.PropertyChanged += Tfcd_PropertyChanged; sendTick = TickPool.RegisterTick(AudioSend, sendCheckInterval, false); encoder = new AudioEncoder(SendCodec) { Bitrate = ts3FullClientData.AudioBitrate * 1000 }; audioTimer = new PreciseAudioTimer(encoder.SampleRate, encoder.BitsPerSample, encoder.Channels); isStall = false; stallCount = 0; identity = null; Util.Init(ref channelSubscriptionsSetup); Util.Init(ref clientSubscriptionsSetup); subscriptionSetupChanged = true; }
// Audioframework /// <summary>Creates a new AudioFramework</summary> /// <param name="afd">Required initialization data from a ConfigFile interpreter.</param> internal AudioFramework(AudioFrameworkData afd, IPlayerConnection audioBackEnd, PlaylistManager playlistMgr) { if (audioBackEnd == null) { throw new ArgumentNullException(nameof(audioBackEnd)); } if (audioBackEnd.SupportsEndCallback) { audioBackEnd.OnSongEnd += (s, e) => OnSongEnd(); } else { waitEndTick = TickPool.RegisterTick(NotifyEnd, SongEndTimeoutInterval, false); } audioFrameworkData = afd; playerConnection = audioBackEnd; playerConnection.Initialize(); PlaylistManager = playlistMgr; }
public Stats(ConfRoot conf, DbStore database, BotManager botManager, DedicatedTaskScheduler scheduler) { this.conf = conf; this.database = database; this.botManager = botManager; uploadParamEnabled = true; runtimeLastTrack = Tools.Now; ticker = scheduler.CreateTimer(TrackPoint, CheckInterval, false); meta = database.GetMetaData(StatsTable); trackEntries = database.GetCollection <StatsData>(StatsTable); trackEntries.EnsureIndex(x => x.Id, true); trackEntries.EnsureIndex(x => x.Time); accEntries = database.GetCollection <StatsData>(StatsTableAcc); accEntries.EnsureIndex(x => x.Id, true); if (meta.Version != StatsVersion || meta.CustomData is null) { statsPoints = new StatsMeta { LastSend = Tools.Now, }; meta.Version = StatsVersion; UpdateMeta(); } else { statsPoints = JsonConvert.DeserializeObject <StatsMeta>(meta.CustomData, JsonSettings) ?? new StatsMeta(); // Upgrade steps here } overallStats = accEntries.FindById(OverallId) ?? new StatsData { Id = OverallId }; }
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); } }
public BobController(BobControllerData data, QueryConnection queryConnection) { if (queryConnection == null) throw new ArgumentNullException(nameof(queryConnection)); timeout = TickPool.RegisterTick(TimeoutCheck, TimeSpan.FromMilliseconds(100), false); musicInfoWaiter = new WaitEventBlock<MusicData>(); isRunning = false; awaitingConnect = false; this.bobControllerData = data; this.queryConnection = queryConnection; queryConnection.OnMessageReceived += GetResponse; queryConnection.OnClientConnect += OnBobConnect; queryConnection.OnClientDisconnect += OnBobDisconnnect; commandQueue = new Queue<string>(); channelSubscriptions = new Dictionary<int, SubscriptionData>(); }