예제 #1
0
        internal static void CollectTypes(Type[] types, bool isPipModAssembly)
        {
            foreach (var(attr, method) in collectors)
            {
                int total = 0, found = 0;
                foreach (var type in types)
                {
                    total++;
                    if (PipMod.TypeCollector.IsImpl(attr.Predicate, type))
                    {
                        if (isPipModAssembly || attr.CaptureNonPipTypes)
                        {
                            found++;
                            Logger.Debug("Invoked type collector {0} on: {1}", method.DeclaringType.FullName, type.FullName);
                            method.Invoke(null, new object[1] {
                                type
                            });
                        }
                        else
                        {
                            Logger.Debug("Type collector {0} found `{1}`, but was skipped by filtering", method.DeclaringType.FullName, type.FullName);
                        }
                    }
                }

                Logger.Debug("Collector searched {0} type(s) (should be {1}), {2} found matching predicate", total, types.Length, found);
            }
        }
        /// <summary>
        /// Set a setting by using an object as a key rather than a string.
        /// This may be used to index settings with an enum rather than a string.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="mapObject"></param>
        /// <param name="value"></param>
        public void SetSetting <T>(T mapObject, object value)
        {
            string key = mapObject.ToString();

            if (!Settings.ContainsKey(key))
            {
                if (Logger != null)
                {
                    Logger.Debug("Creating setting in DI container: " + key);
                }
                Settings.Add(key, null);
            }
            Settings[key] = value;
        }
예제 #3
0
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IHostApplicationLifetime appLifetime)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseAuthentication();

            app.UseMiddleware <CachingMiddleware>();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "api/{controller}/{action}/{id?}");
            }).UseResponseCaching().UseResponseCompression();

            app.UseSwagger();

            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint("/swagger/v1/swagger.json", "SmartGrocery API V1");
                c.EnableValidator();
                c.DisplayRequestDuration();
                c.EnableFilter();
            });

            ApplicationLogger = app.ApplicationServices.GetService <Logging.ILogger <Startup> >();

            appLifetime.ApplicationStopped.Register(() =>
            {
                ApplicationLogger.Debug("Application ending");
            });

            appLifetime.ApplicationStarted.Register(async() =>
            {
                ApplicationLogger.Debug("Application starting");

                var indexManager = app.ApplicationServices.GetService <IndexesManager>();
                await indexManager.UpdateIndexes().ConfigureAwait(false);

                var blobs = app.ApplicationServices.GetService <BlobsInitializator>();
                await blobs.Init().ConfigureAwait(false);

                var queues = app.ApplicationServices.GetService <ChannelsInitializator>();
                await queues.Init().ConfigureAwait(false);
            });
        }
예제 #4
0
        private void reorganizeIndexs(IDatabase database, IList <string> tables)
        {
            _logger.Debug("Reorganizing Indexs...");

            foreach (var table in tables)
            {
                _logger.Debug($"Reorganizing Indexs for table '{table}'");
                var indexs = database.GetFragmentedIndexes(table, _reorganizeFragmentationThreshold);

                foreach (var index in indexs)
                {
                    _logger.Information($"Reorganizing Indexs for table '{table}', Index '{index}'");

                    database.ReorganizeIndex(index, table);
                }
            }
        }
예제 #5
0
        public async Task InitAsync(CancellationToken ct)
        {
            _logger.Verbose("Preparing to init {windowName} window (id: {windowId}) with url {windowUrl}", Name, Id, Url);
            using (_logger.Timed("Initiating {windowName} window", Name))
            {
                Window = await ElectronNET.API.Electron.WindowManager.CreateWindowAsync(Options, Url);
                await OnCreatedAsync(Window, ct);

                Window.OnClosed += () =>
                {
                    _logger.Debug("Window {windowName} has been closed.", Name);
                    if (_isDisposing)
                    {
                        _logger.Information("Disposing {windowName}. Window wont be recreated", Name);
                        return;
                    }
                    _logger.Information("Recreating window {windowName}", Name);
                    InitAsync(CancellationToken.None).GetAwaiter().GetResult();
                };
            }
        }
예제 #6
0
        protected async Task ExecuteWhenReady_Generic(Action job, bool block = false)
        {
            var jobID = Guid.NewGuid();

            Logger.Trace($"Running job on async queue (blocking: {block}). ID: {jobID}");

            AutoResetEvent myEvent         = new AutoResetEvent(false);
            AutoResetEvent currentJobEvent = default(AutoResetEvent);

            //Grab the next signaler and add us as the last job
            lock (QueueLock)
            {
                if (JobQueue.Count == 0)
                {
                    Logger.Trace($"0 jobs in queue, so using a new reset event. It should instantly start");
                    currentJobEvent = new AutoResetEvent(true);
                }
                else
                {
                    Logger.Trace($"{JobQueue.Count} jobs in queue, so using an existing reset event. It should start when all other jobs are finished.");
                    currentJobEvent = JobQueue.Last().Item2;
                }
                JobQueue.Enqueue(Tuple.Create(job, myEvent));
            }

            //Wait for our turn
            Logger.Debug($"Waiting for turn for job {jobID}");

            if (block)
            {
                currentJobEvent.WaitOne();
            }
            else
            {
                await Task.Run(() => currentJobEvent.WaitOne());
            }

            try
            {
                //Run our crap
                Logger.Debug($"Beginning enqueued job: {jobID}");
                job.Invoke();
                Logger.Debug($"Completed job: {jobID}");
            }
            finally
            {
                //Remove ourselves from the queue FIRST, that way if we're the only thing in the queue and a new
                //job gets added, it will either attach to our event which HASN'T been set yet, or it'll see
                //nothing in the queue and not have any wait.
                lock (QueueLock)
                {
                    var dequeuedJob = JobQueue.Dequeue();
                    if (!object.ReferenceEquals(dequeuedJob.Item1, job))
                    {
                        throw new InvalidOperationException("The queue had a programming failure; the dequeued job is not the same as the one that just completed!");
                    }
                }

                //Tell the next person in line to go.
                myEvent.Set();
            }
        }
예제 #7
0
        public void Execute(IJobExecutionContext context)
        {
            _logger.Debug("** Stepping into the execution of EncounterPlayerStatistics!");
            Debug.WriteLine("** Stepping into the execution of EncounterPlayerStatistics!");

            var task = _taskRepository.Get("EncounterPlayerStatistics");

            if (task == null)
            {
                Debug.WriteLine("Can't update EncounterPlayerStatistics - no matching task definition exists in the database.");
                _logger.Debug("Can't update EncounterPlayerStatistics - no matching task definition exists in the database.");
                _discord.Log(
                    "Can't update EncounterPlayerStatistics - no matching task definition exists in the database.",
                    "EncounterPlayerStatistics", LogLevel.Error);
                return;
            }

            // Check if enough time has passed for us to run this task again
            if (task.LastRun.AddMinutes(task.ScheduleMinutes) > DateTime.Now)
            {
                _logger.Debug("Not enough time has passed for this scheduled task, so it won't be executed now");
                Debug.WriteLine("Not enough time has passed for this scheduled task, so it won't be executed now");
                _discord.Log(
                    "Not enough time has passed for this scheduled task, so it won't be executed now",
                    "EncounterPlayerStatistics", LogLevel.Warning);
                return;
            }

            // Update the task lastrun time first, so if it takes a minute to run, we don't run it on another server at the same time
            //TODO: Uncomment this before we push to production
            //_taskRepository.UpdateTask(task.Id, DateTime.Now);

            Stopwatch sw = new Stopwatch();

            // Don't bother saving stats for encounters that aren't valid for rankings.
            // There's no point saving DPS/HPS/APS for encounters that are not successful, either.
            var maxEncounters = 100;
            var encList       = _encounterRepository.GetEncountersMissingPlayerStatistics(maxEncounters);

            if (!encList.Any())
            {
                Debug.WriteLine("Found no encounters that require statistics updates!");
                _logger.Debug("Found no encounters that require statistics updates!");
                //_discord.Log(
                //    "Found no encounters that require statistics updates!",
                //    "EncounterPlayerStatistics", LogLevel.Warning);
            }
            else
            {
                _logger.Debug(string.Format("Found {0} encounters to save statistics for", encList.Count));
                Debug.WriteLine(string.Format("Found {0} encounters to save statistics for", encList.Count));
                _discord.Log(
                    string.Format("Found {0} encounters to save statistics for (max {1})", encList.Count, maxEncounters),
                    "EncounterPlayerStatistics", LogLevel.Information);
                // Optionally filter our list for a specific bossfight here for testing
                //encList = encList.Where(e => e.BossFightId == 41).ToList();
                //_logger.Debug(string.Format("Updating stats for a filtered set of {0} encounters", encList.Count));

                // Get the list of NPC names to check against when determining single target dps
                var bossFightSingleTargetDetails = _bossFightSingleTargetDetailRepository.GetAll();


                var addPlayerStats = new List <Database.Models.EncounterPlayerStatistics>();

                #region Loop through encounters that we previously identified as needing stats

                for (var i = 1; i <= encList.Count; i++)
                {
                    sw.Reset();
                    sw.Start();
                    var enc = encList[i - 1];

                    if ((int)enc.Duration.TotalSeconds == 0)
                    {
                        _logger.Debug(
                            string.Format(
                                "Skipping stats for encounter {0}/{1} as it has a 0-second duration that needs to be fixed.",
                                i, encList.Count));
                        _discord.Log(
                            string.Format(
                                "Skipping stats for encounter {0}/{1} as it has a 0-second duration that needs to be fixed.",
                                i, encList.Count), "EncounterPlayerStatistics", LogLevel.Information);
                        continue;
                    }

                    //_logger.Debug(string.Format("Calculating stats for encounter {0}/{1}", i, encList.Count));
                    addPlayerStats = new List <Database.Models.EncounterPlayerStatistics>();
                    // DPS/HPS/APS

                    #region Damage

                    foreach (var dmg in _encounterRepository.GetOverviewPlayerDamageDone(enc.Id))
                    {
                        var thisPlayer = addPlayerStats.FirstOrDefault(p => p.PlayerId == dmg.PlayerId);
                        if (thisPlayer == null)
                        {
                            addPlayerStats.Add(new Database.Models.EncounterPlayerStatistics()
                            {
                                EncounterId = enc.Id,
                                PlayerId    = dmg.PlayerId,
                                Deaths      = 0,
                                APS         = 0,
                                DPS         = dmg.TotalToNpcs / (long)enc.Duration.TotalSeconds,
                                HPS         = 0,
                            });
                        }
                        else
                        {
                            thisPlayer.DPS = dmg.TotalToNpcs / (long)enc.Duration.TotalSeconds;
                        }
                    }

                    #endregion

                    #region Healing

                    foreach (var heal in _encounterRepository.GetOverviewPlayerHealingDone(enc.Id))
                    {
                        var thisPlayer = addPlayerStats.FirstOrDefault(p => p.PlayerId == heal.PlayerId);
                        if (thisPlayer == null)
                        {
                            addPlayerStats.Add(new Database.Models.EncounterPlayerStatistics()
                            {
                                EncounterId = enc.Id,
                                PlayerId    = heal.PlayerId,
                                Deaths      = 0,
                                APS         = 0,
                                DPS         = 0,
                                HPS         = (heal.TotalToOtherPlayers + heal.TotalToSelf) / (long)enc.Duration.TotalSeconds
                            });
                        }
                        else
                        {
                            thisPlayer.HPS = (heal.TotalToOtherPlayers + heal.TotalToSelf) /
                                             (long)enc.Duration.TotalSeconds;
                        }
                    }

                    #endregion

                    #region Shielding

                    foreach (var shield in _encounterRepository.GetOverviewPlayerShieldingDone(enc.Id))
                    {
                        var thisPlayer = addPlayerStats.FirstOrDefault(p => p.PlayerId == shield.PlayerId);
                        if (thisPlayer == null)
                        {
                            addPlayerStats.Add(new Database.Models.EncounterPlayerStatistics()
                            {
                                EncounterId = enc.Id,
                                PlayerId    = shield.PlayerId,
                                Deaths      = 0,
                                APS         = (shield.TotalToSelf + shield.TotalToOtherPlayers) / (long)enc.Duration.TotalSeconds,
                                DPS         = 0,
                                HPS         = 0
                            });
                        }
                        else
                        {
                            thisPlayer.APS = (shield.TotalToOtherPlayers + shield.TotalToSelf) /
                                             (long)enc.Duration.TotalSeconds;
                        }
                    }

                    #endregion

                    #region Deaths

                    foreach (var playerDeathCount in _encounterRepository.CountDeathsPerPlayer(enc.Id))
                    {
                        var thisPlayer = addPlayerStats.FirstOrDefault(p => p.PlayerId == playerDeathCount.PlayerId);
                        if (thisPlayer == null)
                        {
                            addPlayerStats.Add(new Database.Models.EncounterPlayerStatistics()
                            {
                                EncounterId = enc.Id,
                                PlayerId    = playerDeathCount.PlayerId,
                                Deaths      = playerDeathCount.Deaths,
                                APS         = 0,
                                DPS         = 0,
                                HPS         = 0
                            });
                        }
                        else
                        {
                            thisPlayer.Deaths = playerDeathCount.Deaths;
                        }
                    }

                    #endregion

                    // Top Hits

                    #region Damage

                    var topDmg = _encounterRepository.GetTopDamageHits(enc.Id);
                    foreach (var dmg in topDmg)
                    {
                        var thisPlayer = addPlayerStats.FirstOrDefault(p => p.PlayerId == dmg.PlayerId);
                        if (thisPlayer == null)
                        {
                            addPlayerStats.Add(new Database.Models.EncounterPlayerStatistics()
                            {
                                EncounterId        = enc.Id,
                                PlayerId           = dmg.PlayerId,
                                TopDpsAbilityId    = dmg.TopDpsAbilityId,
                                TopDpsAbilityValue = dmg.TopDpsAbilityValue
                            });
                        }
                        else
                        {
                            thisPlayer.TopDpsAbilityId    = dmg.TopDpsAbilityId;
                            thisPlayer.TopDpsAbilityValue = dmg.TopDpsAbilityValue;
                        }
                    }

                    #endregion

                    #region Healing

                    var topHeal = _encounterRepository.GetTopHealingHits(enc.Id);
                    foreach (var heal in topHeal)
                    {
                        var thisPlayer = addPlayerStats.FirstOrDefault(p => p.PlayerId == heal.PlayerId);
                        if (thisPlayer == null)
                        {
                            addPlayerStats.Add(new Database.Models.EncounterPlayerStatistics()
                            {
                                EncounterId        = enc.Id,
                                PlayerId           = heal.PlayerId,
                                TopHpsAbilityId    = heal.TopHpsAbilityId,
                                TopHpsAbilityValue = heal.TopHpsAbilityValue
                            });
                        }
                        else
                        {
                            thisPlayer.TopHpsAbilityId    = heal.TopHpsAbilityId;
                            thisPlayer.TopHpsAbilityValue = heal.TopHpsAbilityValue;
                        }
                    }

                    #endregion

                    #region Shielding

                    var topShield = _encounterRepository.GetTopShieldHits(enc.Id);
                    foreach (var shield in topShield)
                    {
                        var thisPlayer = addPlayerStats.FirstOrDefault(p => p.PlayerId == shield.PlayerId);
                        if (thisPlayer == null)
                        {
                            addPlayerStats.Add(new Database.Models.EncounterPlayerStatistics()
                            {
                                EncounterId        = enc.Id,
                                PlayerId           = shield.PlayerId,
                                TopApsAbilityId    = shield.TopApsAbilityId,
                                TopApsAbilityValue = shield.TopApsAbilityValue
                            });
                        }
                        else
                        {
                            thisPlayer.TopApsAbilityId    = shield.TopApsAbilityId;
                            thisPlayer.TopApsAbilityValue = shield.TopApsAbilityValue;
                        }
                    }

                    #endregion

                    #region Single target DPS

                    var bossFight = bossFightSingleTargetDetails.FirstOrDefault(b => b.BossFightId == enc.BossFightId);
                    if (bossFight != null)
                    {
                        if (bossFight.TargetName.Contains(","))
                        {
                            var npcsToCheck = bossFight.TargetName.Split(',');
                            foreach (var npcName in npcsToCheck)
                            {
                                var dmgRecords = _encounterRepository.GetPlayerSingleTargetDamageDone(enc.Id, npcName);
                                if (dmgRecords.Any())
                                {
                                    foreach (var dmg in dmgRecords)
                                    {
                                        if (dmg.PlayerId == 0)
                                        {
                                            continue;
                                        }

                                        var thisPlayer = addPlayerStats.FirstOrDefault(p => p.PlayerId == dmg.PlayerId);
                                        if (thisPlayer == null)
                                        {
                                            addPlayerStats.Add(new Database.Models.EncounterPlayerStatistics()
                                            {
                                                EncounterId     = enc.Id,
                                                PlayerId        = dmg.PlayerId,
                                                SingleTargetDps = dmg.Damage / (long)enc.Duration.TotalSeconds
                                            });
                                        }
                                        else
                                        {
                                            thisPlayer.SingleTargetDps = dmg.Damage / (long)enc.Duration.TotalSeconds;
                                        }
                                    }
                                    // If we've found one name that matches records, then don't bother checking the other names (might save a few queries)
                                    break;
                                }
                            }
                        }
                        else
                        {
                            foreach (
                                var dmg in
                                _encounterRepository.GetPlayerSingleTargetDamageDone(enc.Id, bossFight.TargetName))
                            {
                                if (dmg.PlayerId == 0)
                                {
                                    continue;
                                }

                                var thisPlayer = addPlayerStats.FirstOrDefault(p => p.PlayerId == dmg.PlayerId);
                                if (thisPlayer == null)
                                {
                                    addPlayerStats.Add(new Database.Models.EncounterPlayerStatistics()
                                    {
                                        EncounterId     = enc.Id,
                                        PlayerId        = dmg.PlayerId,
                                        SingleTargetDps = dmg.Damage / (long)enc.Duration.TotalSeconds
                                    });
                                }
                                else
                                {
                                    thisPlayer.SingleTargetDps = dmg.Damage / (long)enc.Duration.TotalSeconds;
                                }
                            }
                        }
                    }

                    #endregion

                    sw.Stop();
                    var generateTime = sw.Elapsed.ToString();
                    sw.Reset();
                    sw.Start();
                    // Finished generating statistics, save this encounter's stats now
                    var result = _encounterRepository.SaveEncounterPlayerStatistics(addPlayerStats);
                    sw.Stop();
                    _logger.Debug(
                        string.Format(
                            "Finished saving stats for encounter {0} ({3}/{4}). Stats generated in {1} and saved in {2}.", enc.Id,
                            generateTime, sw.Elapsed, i, encList.Count));
                    Debug.WriteLine(string.Format(
                                        "Finished saving stats for encounter {0}. Stats generated in {1} and saved in {2}.", enc.Id,
                                        generateTime, sw.Elapsed));
                    _discord.Log(
                        string.Format(
                            "Finished saving stats for encounter {0}. Stats generated in {1} and saved in {2}.", enc.Id,
                            generateTime, sw.Elapsed), "EncounterPlayerStatistics", LogLevel.Warning);
                    //addPlayerStats.AddRange(addPlayerStats);
                }

                #endregion
            }
            // Now that we have added stats that didn't exist before, check if there are any single target stats that haven't been calculated at all yet
            var stEncList = _encounterRepository.GetEncountersMissingSingleTargetDpsStatistics(300);
            if (!stEncList.Any())
            {
                _logger.Debug("Found no encounters that require ST DPS updates!");
            }
            else
            {
                _logger.Debug(string.Format("Found {0} encounters to save ST DPS statistics for", stEncList.Count));

                var updatePlayerStats            = new List <Database.Models.EncounterPlayerStatistics>();
                var bossFightSingleTargetDetails = _bossFightSingleTargetDetailRepository.GetAll();

                for (var i = 1; i <= stEncList.Count; i++)
                {
                    sw.Reset();
                    sw.Start();
                    var enc = stEncList[i - 1];

                    if ((int)enc.Duration.TotalSeconds == 0)
                    {
                        _logger.Debug(string.Format("Skipping ST DPS stats for encounter {0}/{1} as it has a 0-second duration that needs to be fixed.", i, stEncList.Count));
                        continue;
                    }

                    var bossFight = bossFightSingleTargetDetails.FirstOrDefault(b => b.BossFightId == enc.BossFightId);
                    if (bossFight == null)
                    {
                        _logger.Debug(string.Format("Skipping ST DPS stats for encounter {0}/{1} as a matching bossfight couldn't be found.", i, stEncList.Count));
                        continue;
                    }

                    _logger.Debug(string.Format("Calculating ST DPS stats for encounter {0}/{1}", i, stEncList.Count));
                    //updatePlayerStats = new List<EncounterPlayerStatistics>();

                    #region Damage
                    // Handle comma-separated names here!

                    if (bossFight.TargetName.Contains(","))
                    {
                        var npcsToCheck = bossFight.TargetName.Split(',');
                        foreach (var npcName in npcsToCheck)
                        {
                            var dmgRecords = _encounterRepository.GetPlayerSingleTargetDamageDone(enc.Id, npcName);
                            if (dmgRecords.Any())
                            {
                                foreach (var dmg in dmgRecords)
                                {
                                    if (dmg.PlayerId == 0)
                                    {
                                        continue;
                                    }

                                    var thisPlayer = updatePlayerStats.FirstOrDefault(p => p.PlayerId == dmg.PlayerId && p.EncounterId == enc.Id);
                                    if (thisPlayer == null)
                                    {
                                        updatePlayerStats.Add(new Database.Models.EncounterPlayerStatistics()
                                        {
                                            EncounterId     = enc.Id,
                                            PlayerId        = dmg.PlayerId,
                                            SingleTargetDps = dmg.Damage / (long)enc.Duration.TotalSeconds
                                        });
                                    }
                                }
                                // If we've found one name that matches records, then don't bother checking the other names (might save a few queries)
                                break;
                            }
                        }
                    }
                    else
                    {
                        var stDmgRecords =
                            _encounterRepository.GetPlayerSingleTargetDamageDone(enc.Id, bossFight.TargetName);
                        if (stDmgRecords.Any())
                        {
                            foreach (var dmg in stDmgRecords)
                            {
                                if (dmg.PlayerId == 0)
                                {
                                    continue;
                                }

                                var thisPlayer = updatePlayerStats.FirstOrDefault(p =>
                                                                                  p.PlayerId == dmg.PlayerId && p.EncounterId == enc.Id);
                                if (thisPlayer == null)
                                {
                                    updatePlayerStats.Add(new Database.Models.EncounterPlayerStatistics()
                                    {
                                        EncounterId     = enc.Id,
                                        PlayerId        = dmg.PlayerId,
                                        SingleTargetDps = dmg.Damage / (long)enc.Duration.TotalSeconds
                                    });
                                }
                            }
                        }
                        else
                        {
                            // Check if this encounter actually has any damage records at all.
                            // If it doesn't, remove the encounter entirely.
                            var recordCounts = _encounterRepository.CountBasicRecordsForEncounter(enc.Id);
                            if (recordCounts.DamageCount == 0)
                            {
                                // Remove this encounter so we don't try and use it again
                                _logger.Debug($"Removing encounter {enc.Id} as there are no damage records in the database.");
                                _encounterRepository.RemoveEncounter("system", enc.Id);
                            }
                        }
                    }

                    #endregion
                    sw.Stop();
                    var generateTime = sw.Elapsed.ToString();
                    _logger.Debug(string.Format("Finished calculating {2} ST DPS stats for encounter {0}. Stats generated in {1}.", enc.Id, generateTime, updatePlayerStats.Count));
                    //sw.Reset();
                    //sw.Start();
                    //// Finished generating statistics, save this encounter's stats now
                    //var result = _encounterRepository.UpdateEncounterSingleTargetDpsStatistics(updatePlayerStats);
                    //sw.Stop();
                    //_logger.Debug(string.Format("Finished updating ST DPS stats for encounter {0}. Stats generated in {1} and updated in {2}.", enc.Id, generateTime, sw.Elapsed));
                    //addPlayerStats.AddRange(addPlayerStats);
                }
                var result = _encounterRepository.UpdateEncounterSingleTargetDpsStatistics(updatePlayerStats);
                _logger.Debug(string.Format("Finished updating {0} ST DPS stats for {1} encounters.", updatePlayerStats.Count, stEncList.Count));
            }
        }