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()); } }
/// <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))))); }
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(); } }