public async Task UpdateData()
        {
            try
            {
                var request =
                    WebRequest.Create("https://github.com/Liquidize/FFXIV_PercentilePlugin/raw/master/parsedata.bin");
                var response = await request.GetResponseAsync();

                if (response.GetResponseStream() != null)
                {
                    using (var bsonReader = new BsonReader(response.GetResponseStream()))
                    {
                        var serializer = new JsonSerializer();
                        var data       = serializer.Deserialize <PercentileData>(bsonReader);
                        if (data != null)
                        {
                            PercentileData = data;
                            var file = new FileStream("PercentilePlugin/parsedata.bin", FileMode.OpenOrCreate);
                            using (var writer = new BsonWriter(file))
                            {
                                serializer.Serialize(writer, data);
                            }

                            file.Close();
                            Logger.Log(LogLevel.Info, "Percentile Data has been updated.");
                            percentileUi.UpdateLabelText();
                        }
                        else
                        {
                            MessageBox.Show("Error in updating data.");
                        }
                    }
                }
            }
            catch (WebException webEx)
            {
                Logger.Log(LogLevel.Error, "Error in updating data.");
                Logger.Log(LogLevel.Error, webEx.ToString());
            }
            catch (JsonException jsonEx)
            {
                Logger.Log(LogLevel.Error, "Error in updating data.");
                Logger.Log(LogLevel.Error, jsonEx.ToString());
            }
        }
Пример #2
0
        /// <summary>
        /// Gets the percentile for item. Note: with [0,1,2,3,3,3], 3 will be in the 50th percentile.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="srcItems">The _SRC items.</param>
        /// <param name="targetItem">The target item.</param>
        /// <param name="valueGetter">The value getter.</param>
        /// <param name="pd">The object that will hold state for repeated calls to this method on the same list.</param>
        /// <returns></returns>
        public static double GetPercentileForItem <T>(this List <T> srcItems, T targetItem, Func <T, double> valueGetter, ref object pd)
        {
            if (pd == null)
            {
                List <T> lclSrcItems = new List <T>(srcItems);
                lclSrcItems.Sort((t1, t2) => Comparer <double> .Default.Compare(valueGetter(t1), valueGetter(t2)));
                int nItems = lclSrcItems.Count;

                // Added the following to collapse repeated xvalues (with which it is impossible
                // to calculate a slope, dy/dx because dx==0).
                List <double> data        = new List <double>();
                List <double> percentiles = new List <double>();
                for (int i = 0; i < nItems; i++)
                {
                    double xval = valueGetter(lclSrcItems[i]);
                    if (data.Count == 0 || xval != data.Last())
                    {
                        data.Add(xval);
                        percentiles.Add(((double)i + 1) / nItems);
                    }
                }
                // The preceding was added.

                //double[] data = new double[nItems];
                //double[] percentiles = new double[nItems];
                //for (int i = 0; i < nItems; i++) {
                //    data[i] = valueGetter(srcItems[i]);
                //    percentiles[i] = ((double)i+1) / ((double)nItems);
                //}

                LinearDoubleInterpolator ldi = new LinearDoubleInterpolator();
                //ldi.SetData(data, percentiles);
                //_pd = new PercentileData() { min = data[0], ldi = ldi };
                ldi.SetData(data.ToArray(), percentiles.ToArray());
                pd = new PercentileData()
                {
                    Min = data[0], Ldi = ldi
                };
            }
            PercentileData lclPd = (PercentileData)pd;

            return(Math.Max(0, Math.Min(1, lclPd.Ldi.GetYValue(valueGetter(targetItem)))));
        }
Пример #3
0
        public static async Task Main(string[] args)
        {
            var config        = new LoggingConfiguration();
            var consoleTarget = new ColoredConsoleTarget("target1")
            {
                Layout = @"${date:format=HH\:mm\:ss} ${level} ${message} ${exception}"
            };

            config.AddTarget(consoleTarget);

            var fileTarget = new FileTarget("target2")
            {
                FileName = "${basedir}/file.txt",
                Layout   = "${longdate} ${level} ${message}  ${exception}"
            };

            config.AddTarget(fileTarget);
            config.AddRuleForOneLevel(LogLevel.Error, fileTarget); // only errors to file
            config.AddRuleForAllLevels(consoleTarget);             // all to console

            LogManager.Configuration = config;

            Logger = LogManager.GetLogger("Main");

            // Backup data before we begin.
            if (File.Exists("parsedata.bin"))
            {
                if (File.Exists("parsedata.bak"))
                {
                    File.Delete("parsedata.bak");
                }
                Logger.Log(LogLevel.Info, "Backing Up Parse Data.");
                File.Copy("parsedata.bin", "parsedata.bak");
            }

            Logger.Log(LogLevel.Info, "Loading Parse Data.");
            percentileData = PercentileData.Load("parsedata.bin");
            Logger.Log(LogLevel.Info, "Parse Data Loaded, Last Update: " + percentileData.LastUpdated);


            Logger.Log(LogLevel.Info, "Obtaining Job/Class Data.");
            await BuildClasses(APIKey);

            Logger.Log(LogLevel.Info, "Job/Class Data Obtained.");
            Logger.Log(LogLevel.Info, "Obtaining Zone/Instance Data.");
            await BuildInstances(APIKey);

            Logger.Log(LogLevel.Info, "Zone/Instance Data Obtained.");
            Logger.Log(LogLevel.Info, "Obtaining latest Parse Data.");
            await BuildPercentiles();

            Logger.Log(LogLevel.Info, "Latest Parse Data Obtained.");
            Logger.Log(LogLevel.Info, "Cleaning Up New Data.");

            // Remove Duplicated Entries.
            var distinctDictionary =
                new Dictionary <string, Dictionary <string, List <double> > >(percentileData.Rankings);


            Logger.Log(LogLevel.Info, "Removing Unused Fights.");

            // Remove unused fights
            foreach (var encounter in distinctDictionary.Keys)
            {
                var used = false;
                foreach (var instance in instances)
                {
                    if (instance.Encounters.FirstOrDefault(e => e.Value.Name.ToLower() == encounter.ToLower()).Value !=
                        null)
                    {
                        Logger.Log(LogLevel.Debug, encounter + " is used.");
                        used = true;
                    }
                }

                if (!used)
                {
                    Logger.Log(LogLevel.Warn, "Encounter: " + encounter + " Is no longer needed.");
                }
            }

            Logger.Log(LogLevel.Info, "Unused Fights Removed.");

            percentileData.Rankings = distinctDictionary;

            Logger.Log(LogLevel.Info, "Saving Parse Data.");

            // Save
            var file = new FileStream("parsedata.bin", FileMode.OpenOrCreate);

            using (var writer = new BsonWriter(file))
            {
                var serializer = new JsonSerializer();
                serializer.Serialize(writer, percentileData);
            }
            file.Close();
            File.WriteAllText("parsejson.json", JsonConvert.SerializeObject(percentileData, Formatting.Indented));
            Logger.Log(LogLevel.Info, "Parse Data Saved.");
            Console.ReadKey();
        }
        public async void InitPlugin(TabPage pluginScreenSpace, Label pluginStatusText)
        {
            Logger = new Logger();
            Logger.Log(LogLevel.Info, "Plugin Init.");


            if (Directory.Exists("PercentilePlugin") != true)
            {
                Logger.Log(LogLevel.Warning, "Creating PercentilePlugin Directory....");
                Directory.CreateDirectory("PercentilePlugin");
            }

            Options.Load();
            Logger.Log(LogLevel.Info, "Loaded Options.");
            PercentileData = PercentileData.Load("PercentilePlugin/parsedata.bin");
            Logger.Log(LogLevel.Info, "Percentile Data Loaded.");

            percentileUi      = new PercentileUi();
            pluginLabel       = pluginStatusText;
            percentileUi.Dock = DockStyle.Fill;
            pluginScreenSpace.Controls.Add(percentileUi);

            CombatantData.ColumnDefs.Add("Percentile", new CombatantData.ColumnDef("Percentile", true, "FLOAT",
                                                                                   "Percentile",
                                                                                   Data => { return(GetPercentile(Data).ToString()); },
                                                                                   Data => { return(GetPercentile(Data).ToString()); },
                                                                                   (Left, Right) => { return(GetPercentile(Left).CompareTo(GetPercentile(Right))); }));
            ActGlobals.oFormActMain.ValidateTableSetup();
            CombatantData.ExportVariables.Add("Percentile", new CombatantData.TextExportFormatter("percentile",
                                                                                                  "Percentile", "2 Week Historical Percentile based off current DPS.",
                                                                                                  (Data, Extra) => { return(GetPercentile(Data).ToString()); }));
            ActGlobals.oFormActMain.ValidateLists();
            Logger.Log(LogLevel.Info, "Percentile Column Added.");
            pluginStatusText.Text          = "Plugin Loaded.";
            percentileUi.lastCheckLbl.Text =
                "Last Updated: " + new DateTime(1970, 1, 1).AddMilliseconds(PercentileData.LastUpdated).ToLocalTime()
                .ToString("F");
            Logger.Log(LogLevel.Info, "Plugin Loaded");

            var checker = new VersionChecker();
            var local   = checker.GetLocalVersion();
            var remote  = checker.GetRemoteVersion();

            if (remote.Major == 0 && remote.Minor == 0)
            {
                var result = MessageBox.Show(
                    "Github error while checking PercentilePlugin version. " +
                    "Your current version is " + local + ".\n\n" +
                    "Manually check for newer version now?",
                    "PercentilePlugin Manual Check",
                    MessageBoxButtons.YesNo);
                if (result == DialogResult.Yes)
                {
                    Process.Start(VersionChecker.kReleaseUrl);
                }
            }
            else if (local < remote)
            {
                if (Options.Instance != null && string.IsNullOrEmpty(Options.Instance.RemoteVersionSeen))
                {
                    Options.Instance.RemoteVersionSeen = "0.0.0";
                }

                var remote_seen_before = new Version(Options.Instance.RemoteVersionSeen);
                Options.Instance.RemoteVersionSeen = remote.ToString();

                var update_message = "There is a new version of PercentilePlugin is available at: \n" +
                                     VersionChecker.kReleaseUrl + " \n\n" +
                                     "New version " + remote + " \n" +
                                     "Current version " + local;
                if (remote == remote_seen_before)
                {
                    Logger.Log(LogLevel.Warning, "Remote Version Seen Before.");
                }
                else
                {
                    var result = MessageBox.Show(
                        update_message + "\n\n" +
                        "Get it now?",
                        "PercentilePlugin update available",
                        MessageBoxButtons.YesNo);
                    if (result == DialogResult.Yes)
                    {
                        Process.Start(VersionChecker.kReleaseUrl);
                    }
                }

                var net_version_str = FileVersionInfo
                                      .GetVersionInfo(typeof(int).Assembly.Location).ProductVersion;
                var net_version = net_version_str.Split('.');
                if (int.Parse(net_version[0]) < kRequiredNETVersionMajor ||
                    int.Parse(net_version[1]) < kRequiredNETVersionMinor ||
                    int.Parse(net_version[2]) < kRequiredNETVersionRevision)
                {
                    Logger.Log(LogLevel.Error, "Requires .NET 4.5.1 or above. Using " + net_version_str);
                }


                Options.Instance.RemoteVersionSeen = remote.ToString();
                Options.Instance.Save();
            }

            if (Options.Instance.AutoUpdate)
            {
                var backgroundWorker = new BackgroundWorker();
                backgroundWorker.DoWork += (sender, args) => { UpdateData(); };
                backgroundWorker.RunWorkerAsync();
            }
        }