Beispiel #1
0
 public void StartTimedSnapshots()
 {
     if (ticker != null)
     {
         throw new InvalidOperationException("Ticker already running");
     }
     ticker = TickPool.RegisterTick(CreateSnapshot, TimeSpan.FromSeconds(1), true);
 }
Beispiel #2
0
        private void SetIdleTickWorker(TickWorker worker)
        {
            var oldWoker = Interlocked.Exchange(ref idleTickWorker, worker);

            if (oldWoker != null)
            {
                TickPool.UnregisterTicker(oldWoker);
            }
        }
Beispiel #3
0
 public void StartTimer(bool upload)
 {
     uploadParamEnabled = upload;
     if (ticker != null)
     {
         throw new InvalidOperationException();
     }
     ticker = TickPool.RegisterTick(() => TrackPoint(), CheckInterval, true);
 }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        private void StopReconnectTickWorker()
        {
            var reconnectTickLocal = reconnectTick;

            reconnectTick = null;
            if (reconnectTickLocal != null)
            {
                TickPool.UnregisterTicker(reconnectTickLocal);
            }
        }
Beispiel #6
0
        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.");
        }
Beispiel #7
0
 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");
     }
 }
Beispiel #8
0
        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);
        }
Beispiel #9
0
        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>();
        }
Beispiel #10
0
        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;
        }
Beispiel #12
0
        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
            };
        }
Beispiel #13
0
        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);
            }
        }
Beispiel #14
0
		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>();
		}