public void Sync() { while (ObjectsForDeallocation.Count > 0) { foreach (var obj in ObjectsForDeallocation.ToArray()) { if (obj.RefCount == 0) { obj.VisitChilds <SceneObject>(obj => { if (obj.RefCount == 1) { obj.Deallocate(); } }, child => child.RefCount <= 1); } } foreach (var obj in ObjectsForDeallocation.ToArray()) { obj.DoDeallocation(); ObjectsForDeallocation.Remove(obj); } } foreach (var act in Actors.ToArray()) { act.SyncChanges(); } RenderContext.DeleteOrphaned(); }
public void UpdatePathableStates() { foreach (var pathable in Pathables.ToArray()) { this.ProcessPathableState(pathable); } }
/// <summary> /// Gets all cached exceptions. /// </summary> /// <param name="clear">A value indicating whether to clear the internal cache after cloning it.</param> /// <returns>A clone of the exception cache.</returns> public static ExceptionInfo[] GetExceptions(bool clear = false) { var exceptions = _exceptionList.ToArray(); if (clear) { ClearExceptions(); } return(exceptions); }
public void ToArrayReturnsAllItems() { SynchronizedCollection <int> collection = new SynchronizedCollection <int>(); collection.Add(1); collection.Add(2); collection.Add(3); var array = collection.ToArray(); array.Should().BeEquivalentTo(1, 2, 3); }
public IWebSocketConnection[] GetAllConnections() { try { _readerWriterLockSlim.EnterReadLock(); return(_connections.ToArray()); } finally { _readerWriterLockSlim.ExitReadLock(); } }
public static T[] ToArrayLocked <T>(this SynchronizedCollection <T> coll) { if (coll == null) { throw new ArgumentNullException(nameof(coll)); } lock (coll.SyncRoot) { return(coll.ToArray()); } }
public override async Task <Position[]> GetPossibleRoles(int championId) { string champ = (await Riot.GetChampion(championId)).Key; var ret = new SynchronizedCollection <Position> (); await Task.WhenAll(PositionToName.Select(async item => { if (item.Key == Position.Fill) { return; } var data = await WebCache.String($"http://lolflavor.com/champions/{champ}/Recommended/{champ}_{item.Value}_scrape.json", soft: true); if (data != null) { ret.Add(item.Key); } })); return(ret.ToArray()); }
/// <summary> /// Puts the message to log into a set of <see cref="Task"/> one for each internal logger. /// </summary> /// <param name="logAction"></param> protected virtual void Log(Action <ILogger> logAction) { IList <Task> loggerTasks = new SynchronizedCollection <Task>(); foreach (ILogger logger in Loggers) { ILogger log = logger; var task = Task.Factory.StartNewSafely(() => { logAction(log); }); loggerTasks.Add(task); } bool anyFailed = Task.Factory.ContinueWhenAll(loggerTasks.ToArray(), tasks => { return(tasks.Any(task => task.IsFaulted)); }).Result; if (anyFailed) { Trace.TraceError("One of the loggers failed."); } }
public void Write() { if (started != true) { return; } if (_commentCollection.Count == 0 && _opecommentCollection.Count == 0) { return; } var arr = _commentCollection.ToArray(); List <string> _commentList = new List <string>(); int count = 0; foreach (var data in arr) { string msg = ""; //2019/08/25 コメジェネの仕様で、handleタグが無いと"0コメ"に置換されてしまう。だから空欄でも良いからhandleタグは必須。 var handle = string.IsNullOrEmpty(data.Nickname) ? "" : data.Nickname; msg = @"{" + "live=\"" + data.SiteName + "\"," + "date=" + ToUnixTime(GetCurrentDateTime()) + "," + "user=\"" + handle + "\"," + "msg=\"" + data.Comment + "\"}"; _commentList.Add(msg); _commentCollection.RemoveAt(0); count++; if (count > 9) { break; } } for (int i = 0; i < (9 - count); i++) { commentList[i] = commentList[i + count]; } for (int i = 0; i < count; i++) { commentList[9 - count + i] = _commentList[i]; } var arr1 = _opecommentCollection.ToArray(); List <string> _opecommentList = new List <string>(); count = 0; foreach (var data in arr1) { string msg = ""; //2019/08/25 コメジェネの仕様で、handleタグが無いと"0コメ"に置換されてしまう。だから空欄でも良いからhandleタグは必須。 var handle = string.IsNullOrEmpty(data.Nickname) ? "" : data.Nickname; msg = @"{" + "date=" + ToUnixTime(GetCurrentDateTime()) + ", " + "msg=\"" + data.Comment + "\"}"; _opecommentList.Add(msg); _opecommentCollection.RemoveAt(0); count++; if (count > 9) { break; } } for (int i = 0; i < (9 - count); i++) { opecommentList[i] = opecommentList[i + count]; } for (int i = 0; i < count; i++) { opecommentList[9 - count + i] = _opecommentList[i]; } try { writeLuaFile(); } catch (IOException ex) { //コメントの流れが早すぎるとused in another processが来てしまう。 //この場合、コメントが書き込まれずに消されてしまう。 Debug.WriteLine(ex.Message); return; } return; }
/// <summary> /// _commentCollectionの内容をファイルに書き出す /// </summary> public void Write() { if (!Options.IsEnabled || _commentCollection.Count == 0) { return; } //TODO:各ファイルが存在しなかった時のエラー表示 if (string.IsNullOrEmpty(CommentXmlPath) && IsHcgSettingFileExists()) { var hcgPath = GetHcgPath(Options.HcgSettingFilePath); CommentXmlPath = hcgPath + "\\comment.xml"; //TODO:パスがxmlファイルで無かった場合の対応。ディレクトリの可能性も。 } if (!File.Exists(CommentXmlPath)) { var doc = new XmlDocument(); var root = doc.CreateElement("log"); doc.AppendChild(root); doc.Save(CommentXmlPath); } XElement xml; try { xml = XElement.Load(CommentXmlPath); } catch (IOException ex) { //being used in another process Debug.WriteLine(ex.Message); return; } catch (XmlException) { //Root element is missing. xml = new XElement("log"); } lock (_commentCollection) { var arr = _commentCollection.ToArray(); _commentCollection.Clear(); foreach (var data in arr) { var item = new XElement("comment", data.Comment); item.SetAttributeValue("no", "0"); item.SetAttributeValue("time", ToUnixTime(GetCurrentDateTime())); item.SetAttributeValue("owner", 0); item.SetAttributeValue("service", data.SiteName); if (!string.IsNullOrEmpty(data.Nickname)) { item.SetAttributeValue("handle", data.Nickname); } xml.Add(item); } } try { WriteXml(xml, CommentXmlPath); } catch (IOException ex) { //コメントの流れが早すぎるとused in another processが来てしまう。 //この場合、コメントが書き込まれずに消されてしまう。 Debug.WriteLine(ex.Message); } }
public static void DumpMassIcons(GpkStore store, String outdir, Dictionary <String, List <CompositeMapEntry> > filterList) { logger.Info("Started dumping textures to " + outdir); Directory.CreateDirectory(outdir); SynchronizedCollection <Task> runningTasks = new SynchronizedCollection <Task>(); int MAX_TASKS = 100; foreach (var file in filterList) { if (!file.Value.Any(x => x.UID.StartsWith("Icon_"))) { continue; } //throttle thread creation while (runningTasks.Count > MAX_TASKS) { Thread.Sleep(1000); } //limit to 5 threads by default foreach (var entry in file.Value) { if (!entry.UID.StartsWith("Icon_")) { continue; } Task newTask = null; newTask = new Task(() => { string path = string.Format("{0}\\{1}.gpk", store.BaseSearchPath, entry.SubGPKName); var fullName = entry.UID.Split('.'); //create out dir var fileOutPath = string.Format("{0}\\{1}\\", outdir, fullName[0]); Directory.CreateDirectory(fileOutPath); if (!File.Exists(path)) { logger.Warn("GPK to load not found. Searched for: " + path); return; } Reader r = new Reader(); var package = r.ReadSubGpkFromComposite(path, entry.UID, entry.FileOffset, entry.FileLength); package.LowMemMode = true; //extract var exports = package.GetExportsByClass("Core.Texture2D"); foreach (var export in exports) { //UID->Composite UID //S1UI_Chat2.Chat2,c7a706fb_6a349a6f_1d212.Chat2_dup | //we use this uid from pkgmapper //var imagePath = string.Format("{0}{1}_{2}.dds", fileOutPath, entry.UID, export.UID); var imagePath = string.Format("{0}{1}.dds", fileOutPath, fullName[1]); TextureTools.exportTexture(export, imagePath); logger.Info("Extracted texture {0} to {1}", entry.UID, imagePath); } //remove ref to ease gc exports.Clear(); package = null; runningTasks.Remove(newTask); }); newTask.Start(); runningTasks.Add(newTask); } } Task.WaitAll(runningTasks.ToArray()); NLogConfig.EnableFormLogging(); logger.Info("Dumping done"); }
public BuildResult GenBuilds(string prefix = "") { if (Type == BuildType.Lock) { Best = new Monster(Mon, true); return BuildResult.Success; } else if (Type == BuildType.Link) { if (LinkBuild == null) { for (int i = 0; i < 6; i++) runes[i] = new Rune[0]; return BuildResult.Failure; } else { CopyFrom(LinkBuild); } } if (runes.Any(r => r == null)) { BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, "Null rune")); return BuildResult.BadRune; } if (!BuildSaveStats) BuildGoodRunes = false; if (!BuildGoodRunes) { RuneUsage = new RuneUsage(); BuildUsage = new BuildUsage(); } try { // if to get awakened if (DownloadAwake && !Mon.downloaded) { BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, "Downloading Awake def")); var mref = MonsterStat.FindMon(Mon); if (mref != null) { // download the current (unawakened monster) var mstat = mref.Download(); BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, "Reading stats")); // if the retrieved mon is unawakened, get the awakened if (!mstat.Awakened && mstat.AwakenTo != null) { BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, "Awakening")); Mon = mstat.AwakenTo.Download().GetMon(Mon); } } BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, "Downloaded")); } // getting awakened also gets level 40, so... // only get lvl 40 stats if the monster isn't 40, wants to download AND isn't already downloaded (first and last are about the same) else if (Mon.level < 40 && DownloadStats && !Mon.downloaded) { BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, "Downloading 40 def")); var mref = MonsterStat.FindMon(Mon); if (mref != null) Mon = mref.Download().GetMon(Mon); } } catch (Exception e) { BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, "Failed downloading def: " + e.Message + Environment.NewLine + e.StackTrace)); } if (!getRunningHandle()) throw new InvalidOperationException("The build is locked with another action."); Loads.Clear(); if (!Sort[Attr.Speed].EqualTo(0) && Sort[Attr.Speed] <= 1 // 1 SPD is too good to pass || Mon.Current.Runes.Any(r => r == null) || !Mon.Current.Runes.All(r => runes[r.Slot - 1].Contains(r)) // only IgnoreLess5 if I have my own runes || Sort.NonZeroStats.HasCount(1)) // if there is only 1 sorting, must be too important to drop??? IgnoreLess5 = false; Thread timeThread = null; if (!string.IsNullOrWhiteSpace(BuildStrategy)) { var types = AppDomain.CurrentDomain.GetAssemblies().SelectMany(asm => asm.GetTypes().Where(t => typeof(IBuildStrategyDefinition).IsAssignableFrom(t))); var type = types.FirstOrDefault(t => t.AssemblyQualifiedName.Contains(BuildStrategy)); if (type != null) { RunStrategy(); } } tcs.TrySetResult(null); try { Best = null; Stats bstats = null; count = 0; actual = 0; total = runes[0].Length; total *= runes[1].Length; total *= runes[2].Length; total *= runes[3].Length; total *= runes[4].Length; total *= runes[5].Length; complete = total; Mon.ExtraCritRate = extraCritRate; Mon.GetStats(); Mon.DamageFormula?.Invoke(Mon); int?[] slotFakesTemp = new int?[6]; bool[] slotPred = new bool[6]; getPrediction(slotFakesTemp, slotPred); int[] slotFakes = slotFakesTemp.Select(i => i ?? 0).ToArray(); var currentLoad = new Monster(Mon, true); currentLoad.Current.TempLoad = true; currentLoad.Current.Buffs = Buffs; currentLoad.Current.Shrines = Shrines; currentLoad.Current.Leader = Leader; currentLoad.Current.FakeLevel = slotFakes; currentLoad.Current.PredictSubs = slotPred; double currentScore = CalcScore(currentLoad.GetStats(true)); BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, "cooking")); if (total == 0) { BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, "0 perms")); RuneLog.Info("Zero permuations"); return BuildResult.NoPermutations; } bool hasSort = Sort.IsNonZero; if (BuildTake == 0 && !hasSort) { BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, "No sort")); RuneLog.Info("No method of determining best"); return BuildResult.NoSorting; } DateTime begin = DateTime.Now; RuneLog.Debug(count + "/" + total + " " + string.Format("{0:P2}", (count + complete - total) / (double)complete)); // set to running IsRunning = true; #if BUILD_PRECHECK_BUILDS_DEBUG SynchronizedCollection<string> outstrs = new SynchronizedCollection<string>(); #endif BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, "...")); List<Monster> tests = new List<Monster>(); timeThread = new Thread(() => { while (IsRunning) { if (RunesOnlyFillEmpty) Thread.Sleep(30 / ((Mon?.Current?.RuneCount ?? 1) + 1)); else Thread.Sleep(400); // every second, give a bit of feedback to those watching RuneLog.Debug(count + "/" + total + " " + string.Format("{0:P2}", (count + complete - total) / (double)complete)); if (tests != null) BuildProgTo?.Invoke(this, ProgToEventArgs.GetEvent(this, (count + complete - total) / (double)complete, tests.Count)); if (BuildTimeout > 0 && DateTime.Now > begin.AddSeconds(BuildTimeout)) { RuneLog.Info("Timeout"); BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, prefix + "Timeout")); BuildProgTo?.Invoke(this, ProgToEventArgs.GetEvent(this, 1, tests.Count)); IsRunning = false; } } }); timeThread.Start(); double bestScore = double.MinValue; var opts = new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount - 1 }; var mmm = Maximum.NonZeroCached; // Parallel the outer loop // TODO: setup the begin/finish Actions with syncList. void body (Rune r0, ParallelLoopState loopState) { var tempReq = RequiredSets.ToList(); var tempMax = Maximum == null || !Maximum.IsNonZero ? null : new Stats(Maximum, true); int tempCheck = 0; Monster myBest = null; List<Monster> syncList = new List<Monster>(); void syncMyList() { lock (bestLock) { #if DEBUG_SYNC_BUILDS foreach (var s in syncList) { if (s.Current.Runes.All(r => r.Assigned == mon)) { Console.WriteLine("!"); } } #endif tests.AddRange(syncList); } //syncList.ForEach(_ => tests.Add(_)); syncList.Clear(); if (tests.Count > Math.Max(BuildGenerate, 250000)) { #if DEBUG_SYNC_BUILDS var rems = tests.OrderByDescending(b => b.score).Skip(75000).ToList(); foreach (var bbb in rems) { if (bbb.Current.Runes.All(r => r.Assigned == mon)) { Console.WriteLine("!"); } } #endif lock (bestLock) { tests = tests.OrderByDescending(b => b.score).Take(75000).ToList(); } } if (tests.Count > MaxBuilds32) IsRunning = false; } if (!IsRunning_Unsafe) { syncMyList(); loopState.Break(); } // number of builds ruled out since last sync int kill = 0; // number of builds added since last sync int plus = 0; // number of builds skipped int skip = 0; bool isBad; double myBestScore = double.MinValue, curScore, lastBest = double.MinValue; Stats cstats, myStats; Monster test = new Monster(Mon); test.Current.TempLoad = true; test.Current.Buffs = Buffs; test.Current.Shrines = Shrines; test.Current.Leader = Leader; test.Current.FakeLevel = slotFakes; test.Current.PredictSubs = slotPred; test.ApplyRune(r0, 7); RuneSet set4 = r0.SetIs4 ? r0.Set : RuneSet.Null; RuneSet set2 = r0.SetIs4 ? RuneSet.Null : r0.Set; int pop4 = 0; int pop2 = 0; foreach (Rune r1 in runes[1]) { // TODO: refactor to local method if (!IsRunning_Unsafe) // Can't break to a label, don't want to goto break; // TODO: break into multiple implementations that have less branching #if BUILD_PRECHECK_BUILDS if (!AllowBroken && !RunesOnlyFillEmpty) { if (r1.SetIs4) { if (pop2 == 2) pop2 = 7; if (set4 == RuneSet.Null || pop4 >= 2) { set4 = r1.Set; pop4 = 2; } else if (set4 != r1.Set) { #if BUILD_PRECHECK_BUILDS_DEBUG outstrs.Add($"bad4@2 {set4} {set2} | {r0.Set} {r1.Set}"); #endif skip += runes[2].Length * runes[3].Length * runes[4].Length * runes[5].Length; continue; } } else { if (pop4 == 2) pop4 = 7; if (set2 == RuneSet.Null || pop2 >= 2) { set2 = r1.Set; pop2 = 2; } } } #endif test.ApplyRune(r1, 7); foreach (Rune r2 in runes[2]) { if (!IsRunning_Unsafe) break; #if BUILD_PRECHECK_BUILDS if (!AllowBroken && !RunesOnlyFillEmpty) { if (r2.SetIs4) { if (pop2 == 3) pop2 = 7; if (set4 == RuneSet.Null || pop4 >= 3) { set4 = r2.Set; pop4 = 3; } else if (set4 != r2.Set) { #if BUILD_PRECHECK_BUILDS_DEBUG outstrs.Add($"bad4@3 {set4} {set2} | {r0.Set} {r1.Set} {r2.Set}"); #endif skip += runes[3].Length * runes[4].Length * runes[5].Length; continue; } } else { if (pop4 == 3) pop4 = 7; if (set2 == RuneSet.Null || pop2 >= 3) { set2 = r2.Set; pop2 = 3; } else if (set4 != RuneSet.Null && set2 != r2.Set) { #if BUILD_PRECHECK_BUILDS_DEBUG outstrs.Add($"bad2@3 {set4} {set2} | {r0.Set} {r1.Set} {r2.Set}"); #endif skip += runes[3].Length * runes[4].Length * runes[5].Length; continue; } } } #endif test.ApplyRune(r2, 7); foreach (Rune r3 in runes[3]) { if (!IsRunning_Unsafe) break; #if BUILD_PRECHECK_BUILDS if (!AllowBroken && !RunesOnlyFillEmpty) { if (r3.SetIs4) { if (pop2 == 4) pop2 = 7; if (set4 == RuneSet.Null || pop4 >= 4) { set4 = r3.Set; pop4 = 4; } else if (set4 != r3.Set) { #if BUILD_PRECHECK_BUILDS_DEBUG outstrs.Add($"bad4@4 {set4} {set2} | {r0.Set} {r1.Set} {r2.Set} {r3.Set}"); #endif skip += runes[4].Length * runes[5].Length; continue; } } else { if (pop4 == 4) pop4 = 7; if (set2 == RuneSet.Null || pop2 >= 4) { set2 = r3.Set; pop2 = 4; } else if (set4 != RuneSet.Null && set2 != r3.Set) { #if BUILD_PRECHECK_BUILDS_DEBUG outstrs.Add($"bad2@4 {set4} {set2} | {r0.Set} {r1.Set} {r2.Set} {r3.Set}"); #endif skip += runes[4].Length * runes[5].Length; continue; } } } #endif test.ApplyRune(r3, 7); foreach (Rune r4 in runes[4]) { if (!IsRunning_Unsafe) { break; } #if BUILD_PRECHECK_BUILDS if (!AllowBroken && !RunesOnlyFillEmpty) { if (r4.SetIs4) { if (pop2 == 5) pop2 = 7; if (set4 == RuneSet.Null || pop4 >= 5) { set4 = r4.Set; pop4 = 5; } else if (set4 != r4.Set) { #if BUILD_PRECHECK_BUILDS_DEBUG outstrs.Add($"bad4@5 {set4} {set2} | {r0.Set} {r1.Set} {r2.Set} {r3.Set} {r4.Set}"); #endif skip += runes[5].Length; continue; } } else { if (pop4 == 5) pop4 = 7; if (set2 == RuneSet.Null || pop2 >= 5) { set2 = r4.Set; pop2 = 5; } else if (set4 != RuneSet.Null && set2 != r4.Set) { #if BUILD_PRECHECK_BUILDS_DEBUG outstrs.Add($"bad2@5 {set4} {set2} | {r0.Set} {r1.Set} {r2.Set} {r3.Set} {r4.Set}"); #endif skip += runes[5].Length; continue; } } } #endif test.ApplyRune(r4, 7); foreach (Rune r5 in runes[5]) { if (!IsRunning_Unsafe) break; test.ApplyRune(r5, 7); test.Current.CheckSets(); #if BUILD_PRECHECK_BUILDS_DEBUG outstrs.Add($"fine {set4} {set2} | {r0.Set} {r1.Set} {r2.Set} {r3.Set} {r4.Set} {r5.Set}"); #endif isBad = false; cstats = test.GetStats(); // check if build meets minimum isBad |= !RunesOnlyFillEmpty && !AllowBroken && !test.Current.SetsFull; isBad |= tempMax != null && cstats.AnyExceedCached(tempMax); if (!isBad && GrindLoads) { var mahGrinds = grinds.ToList(); for (int rg = 0; rg < 6; rg++) { var lgrinds = test.Runes[rg].FilterGrinds(mahGrinds); foreach (var g in lgrinds) { var tr = test.Runes[rg].Grind(g); } // TODO: } } isBad |= !RunesOnlyFillEmpty && Minimum != null && !cstats.GreaterEqual(Minimum, true); // if no broken sets, check for broken sets // if there are required sets, ensure we have them /*isBad |= (tempReq != null && tempReq.Count > 0 // this Linq adds no overhead compared to GetStats() and ApplyRune() //&& !tempReq.All(s => test.Current.Sets.Count(q => q == s) >= tempReq.Count(q => q == s)) //&& !tempReq.GroupBy(s => s).All(s => test.Current.Sets.Count(q => q == s.Key) >= s.Count()) );*/ // TODO: recheck this code is correct if (tempReq != null && tempReq.Count > 0) { tempCheck = 0; foreach (var r in tempReq) { int i; for (i = 0; i < 3; i++) { if (test.Current.Sets[i] == r && (tempCheck & 1 << i) != 1 << i) { tempCheck |= 1 << i; break; } } if (i >= 3) { isBad |= true; break; } } } if (isBad) { kill++; curScore = 0; } else { // try to reduce CalcScore hits curScore = CalcScore(cstats); isBad |= IgnoreLess5 && curScore < currentScore * 1.05; if (isBad) kill++; } if (!isBad) { // we found an okay build! plus++; test.score = curScore; if (BuildSaveStats) { foreach (Rune r in test.Current.Runes) { if (!BuildGoodRunes) { r.manageStats.AddOrUpdate("LoadFilt", 1, (s, d) => { return d + 1; }); RuneUsage.runesGood.AddOrUpdate(r, (byte)r.Slot, (key, ov) => (byte)r.Slot); r.manageStats.AddOrUpdate("currentBuildPoints", curScore, (k, v) => Math.Max(v, curScore)); r.manageStats.AddOrUpdate("cbp" + ID, curScore, (k, v) => Math.Max(v, curScore)); } else { r.manageStats.AddOrUpdate("LoadFilt", 0.001, (s, d) => { return d + 0.001; }); RuneUsage.runesOkay.AddOrUpdate(r, (byte)r.Slot, (key, ov) => (byte)r.Slot); r.manageStats.AddOrUpdate("cbp" + ID, curScore, (k, v) => Math.Max(v, curScore * 0.9)); } } } if (syncList.Count >= 500) { syncMyList(); } // if we are to track all good builds, keep it if (!BuildDumpBads) { syncList.Add(new Monster(test, true)); // locally track my best if (myBest == null || curScore > myBestScore) { myBest = new Monster(test, true); myStats = myBest.GetStats(); myBestScore = CalcScore(myStats); myBest.score = myBestScore; } // if mine is better than what I last saw if (myBestScore > lastBest) { lock (bestLock) { if (Best == null) { Best = new Monster(myBest, true); bstats = Best.GetStats(); bestScore = CalcScore(bstats); Best.score = bestScore; } else { // sync best score lastBest = bestScore; // double check if (myBestScore > lastBest) { Best = new Monster(myBest, true); bestScore = CalcScore(bstats); Best.score = bestScore; bstats = Best.GetStats(); } } } } } // if we only want to track really good builds else { // if there are currently no good builds, keep it // or if this build is better than the best, keep it // locally track my best if (myBest == null || curScore > myBestScore) { myBest = new Monster(test, true); myStats = myBest.GetStats(); myBestScore = CalcScore(myStats); myBest.score = myBestScore; syncList.Add(myBest); } else if (BuildSaveStats) { // keep it for spreadsheeting syncList.Add(new Monster(test, true) { score = curScore }); } } } } // sum up what work we've done Interlocked.Add(ref count, kill); Interlocked.Add(ref count, skip); Interlocked.Add(ref skipped, skip); Interlocked.Add(ref actual, kill); Interlocked.Add(ref BuildUsage.failed, kill); kill = 0; skip = 0; Interlocked.Add(ref count, plus); Interlocked.Add(ref actual, plus); Interlocked.Add(ref BuildUsage.passed, plus); plus = 0; // if we've got enough, stop if (BuildGenerate > 0 && BuildUsage.passed >= BuildGenerate) { IsRunning = false; break; } } } } } // just before dying syncMyList(); } Parallel.ForEach(runes[0], opts, body); BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, prefix + "finalizing...")); BuildProgTo?.Invoke(this, ProgToEventArgs.GetEvent(this, 0.99, -1)); #if BUILD_PRECHECK_BUILDS_DEBUG System.IO.File.WriteAllLines("_into_the_bridge.txt", outstrs.ToArray()); #endif if (BuildSaveStats) { foreach (var ra in runes) { foreach (var r in ra) { if (!BuildGoodRunes) { r.manageStats.AddOrUpdate("buildScoreTotal", CalcScore(Best), (k, v) => v + CalcScore(Best)); RuneUsage.runesUsed.AddOrUpdate(r, (byte)r.Slot, (key, ov) => (byte)r.Slot); r.manageStats.AddOrUpdate("LoadGen", total, (s, d) => { return d + total; }); } else { RuneUsage.runesBetter.AddOrUpdate(r, (byte)r.Slot, (key, ov) => (byte)r.Slot); r.manageStats.AddOrUpdate("LoadGen", total * 0.001, (s, d) => { return d + total * 0.001; }); } } } } // write out completion RuneLog.Debug(IsRunning + " " + count + "/" + total + " " + string.Format("{0:P2}", (count + complete - total) / (double)complete)); BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, prefix + " completed")); BuildProgTo?.Invoke(this, ProgToEventArgs.GetEvent(this, 1, tests.Count)); // sort *all* the builds int takeAmount = 1; if (BuildSaveStats) takeAmount = 10; if (BuildTake > 0) takeAmount = BuildTake; if (IgnoreLess5) tests.Add(new Monster(Mon, true)); foreach (var ll in tests.Where(t => t != null).OrderByDescending(r => CalcScore(r.GetStats())).Take(takeAmount)) Loads.Add(ll); BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, "Found a load " + Loads.Count())); if (!BuildGoodRunes) BuildUsage.loads = tests.ToList(); // dump everything to console, if nothing to print to if (BuildPrintTo == null) foreach (var l in Loads) { RuneLog.Debug(l.GetStats().Health + " " + l.GetStats().Attack + " " + l.GetStats().Defense + " " + l.GetStats().Speed + " " + l.GetStats().CritRate + "%" + " " + l.GetStats().CritDamage + "%" + " " + l.GetStats().Resistance + "%" + " " + l.GetStats().Accuracy + "%"); } // sadface if no builds if (!Loads.Any()) { RuneLog.Info("No builds :("); BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, prefix + "Zero :(")); } else { // remember the good one Best = Loads.First(); Best.Current.TempLoad = false; Best.score = CalcScore(Best.GetStats()); BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, prefix + "best " + (Best?.score ?? -1))); Best.Current.ActualTests = actual; foreach (var bb in Loads) { foreach (Rune r in bb.Current.Runes) { double val = Best.score; if (BuildGoodRunes) { val *= 0.25; if (bb == Best) RuneUsage.runesSecond.AddOrUpdate(r, (byte)r.Slot, (key, ov) => (byte)r.Slot); } if (bb != Best) val *= 0.1; else r.manageStats.AddOrUpdate("In", BuildGoodRunes ? 2 : 1, (s, e) => BuildGoodRunes ? 2 : 1); r.manageStats.AddOrUpdate("buildScoreIn", val, (k, v) => v + val); } } for (int i = 0; i < 6; i++) { if (!BuildGoodRunes && Mon.Current.Runes[i] != null && Mon.Current.Runes[i].Id != Best.Current.Runes[i].Id) Mon.Current.Runes[i].Swapped = true; } foreach (var ra in runes) { foreach (var r in ra) { var cbp = r.manageStats.GetOrAdd("currentBuildPoints", 0); if (cbp / Best.score < 1) r.manageStats.AddOrUpdate("bestBuildPercent", cbp / Best.score, (k, v) => Math.Max(v, cbp / Best.score)); } } } tests.Clear(); tests = null; BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, prefix + "Test cleared")); return BuildResult.Success; } catch (Exception e) { RuneLog.Error("Error " + e); BuildPrintTo?.Invoke(this, PrintToEventArgs.GetEvent(this, prefix + e.ToString())); return BuildResult.Failure; } finally { tcs = new TaskCompletionSource<IBuildRunner>(); IsRunning = false; if (timeThread != null) timeThread.Join(); } }
public static void DownloadAlbum(string sUrl) { string albumHTML = String.Empty; try { albumHTML = GetHTMLFromURL(sUrl).HTML; } catch (Exception e) { string errorMessage = $"Failed to open {sUrl} ({e.Message})"; Program.MainForm.Log(errorMessage); #if DEBUG Debug.WriteLine(errorMessage); #endif return; } var parser = new HtmlParser(); var albumHtmlDocument = parser.ParseDocument(albumHTML); Program.MainForm.Log($"Parsing {sUrl}"); var songNodes = albumHtmlDocument.All.Where(element => element.LocalName == "td" && element.ClassName == "playlistDownloadSong"); //.SelectNodes("//td[contains(@class, 'playlistDownloadSong')]"); var qualityNode = albumHtmlDocument.All.FirstOrDefault(element => element.LocalName == "tr" && element.Id == "songlist_header"); //DocumentNode.SelectNodes("//tr[contains(@id, 'songlist_header')]/th"); var albumNameNode = albumHtmlDocument.All .FirstOrDefault(element => element.Id == "pageContent") ?.Children[1]; //DocumentNode.SelectSingleNode("//*[@id=\"EchoTopic\"]/h2[1]"); string szAlbumName; if (albumNameNode != null && songNodes.Any() && qualityNode != null) { //Trim spaces and dots! szAlbumName = string .Join("_", WebUtility.HtmlDecode(albumNameNode.InnerHtml).Split(Path.GetInvalidFileNameChars())) .Trim(new char[] { ' ', '.' }); } else { Program.MainForm.Log($"Failed to parse {sUrl}"); return; } Directory.CreateDirectory(Downloader.m_szDownloadPath + "\\" + szAlbumName); var selectedFormat = ".mp3"; if (eQuality != EDownloadQuality.QUALITY_MP3_ONLY) { //List<IElement> qualitySubNodes = qualityNodes.Skip(3).ToList(); //find non mp3 file bool bBreak = false; foreach (var cell in qualityNode.Children.ToList()) { foreach (var cellchilds in cell.Children.ToList()) { if (cellchilds.InnerHtml == "FLAC") { selectedFormat = ".flac"; bBreak = true; break; } if (cellchilds.InnerHtml == "OGG") { selectedFormat = ".ogg"; bBreak = true; break; } if (cellchilds.InnerHtml == "M4A") { selectedFormat = ".m4a"; bBreak = true; break; } } if (bBreak) { break; } } } SynchronizedCollection <Task> currentTasks = new SynchronizedCollection <Task>(); int nTotalSongs = songNodes.Count(); int nCurrentSong = 0; try { Parallel.ForEach(songNodes, g_songsParralelOptions, song => { var songPageURL = "https://downloads.khinsider.com" + song.Children[0].GetAttribute("href"); //["href"].Value; IHtmlDocument songPageDocument; try { if (g_songsParralelOptions.MaxDegreeOfParallelism == 1) { songPageDocument = new HtmlParser().ParseDocument(GetHTMLFromURL(songPageURL).HTML); } else { songPageDocument = parser.ParseDocument(GetHTMLFromURL(songPageURL).HTML); } } catch (Exception e) { string message = $"Failed to parse {songPageURL} ({e.Message})"; Program.MainForm.Log(message); #if DEBUG Debug.WriteLine(message); #endif return; } var downloadLinkNodes = songPageDocument.All.Where(element => element.ClassName == "songDownloadLink") .ToList(); //"//span[@class='songDownloadLink']"); //[1].ParentElement.GetAttribute("href"); //Do not use Parallel.ForEach as we usually have ~2 nodes int nDownloadNodes = downloadLinkNodes.Count(); for (var index = 0; index < nDownloadNodes; index++) { var dlsongentry = downloadLinkNodes[index]; var songFileURL = dlsongentry.ParentElement.GetAttribute("href"); //.Value; if (songFileURL.EndsWith(selectedFormat)) { var name = WebUtility.UrlDecode( songFileURL.Substring(songFileURL.LastIndexOf("/", StringComparison.Ordinal) + 1)); if (!IsDownloading) { return; } if (!m_bSuppessLogs) { Program.MainForm.Log($"Downloading {name}..."); } string filename = m_szDownloadPath + "\\" + szAlbumName + "\\" + string.Join("_", name.Split(Path.GetInvalidFileNameChars())); try { WebClient downloadClient = new WebClient(); downloadClient.Proxy = null; Task currentTask = downloadClient.DownloadFileTaskAsync(new Uri(songFileURL), filename); currentTask.ContinueWith( task => { downloadClient.Dispose(); if (!IsDownloading) { File.Delete(filename); return; } ++nCurrentSong; if (nTotalAlbums == 1) { UpdateTitle(nCurrentSong, nTotalSongs); } if (!m_bSuppessLogs) { Program.MainForm.Log($"{name} has been downloaded!"); } }); currentTasks.Add(currentTask); } catch (Exception e) { string errorMessage = $"Failed to download {songFileURL} to {filename} ({e.Message})"; Program.MainForm.Log(errorMessage); #if DEBUG Debug.WriteLine(errorMessage); #endif } } } }); Task.WaitAll(currentTasks.ToArray(), cancelTokenSource.Token); } catch (OperationCanceledException) { } Program.MainForm.Log($"Finished downloading {szAlbumName}!"); if (nTotalAlbums != 1) { UpdateTitle(++nAlbumsDownloaded, nTotalAlbums); } }
public Task LoadFileTree() { this.treeNode_Folders = new Dictionary <string, TreeNode>(); this.treeNode_Root = new List <TreeNode>(); this.nodeTree = new Dictionary <TreeNode, List <TreeNode> >(); this.nodeTree.Add(this.treeNode_Unknown, new List <TreeNode>()); this.unknownFilesType = new Dictionary <string, TreeNode>(); LoadingArchives loaderProgress = new LoadingArchives(); int fileCount = 0; int loadedCount = 0; // Determine file count foreach (Archive a in ArchiveManager.Archives) { fileCount += (int)a.FileCount; } loaderProgress.UpdateProgres(fileCount, 0); if (this.Visible) { loaderProgress.Parent = this; loaderProgress.Show(); } else { loaderProgress.Show(); } return(Task.Run(() => { // Start loading SynchronizedCollection <ArchiveFileInfo> appendFiles = new SynchronizedCollection <ArchiveFileInfo>(); List <Task> loadTasks = new List <Task>(); IAsyncResult updateCall = null; foreach (Archive a in ArchiveManager.Archives) { Console.WriteLine("Starting file listing for: " + a.File.Name); loadTasks.Add(a.ListFilesAsync((ArchiveFileInfo file) => { appendFiles.Add(file); loadedCount++; if (appendFiles.Count >= 100) { lock (appendFiles.SyncRoot) { ArchiveFileInfo[] files = appendFiles.ToArray(); appendFiles.Clear(); this.AppendFileBrowser(files); loaderProgress.UpdateProgres(fileCount, loadedCount); /*if (updateCall == null || updateCall.IsCompleted) * { * updateCall = this.BeginInvoke((MethodInvoker)delegate () * { * this.UpdateFileBrowser(); * }); * }*/ } } })); } Task.WaitAll(loadTasks.ToArray()); loaderProgress.UpdateProgres(fileCount, loadedCount); this.AppendFileBrowser(appendFiles.ToArray()); this.BeginInvoke((MethodInvoker) delegate() { this.UpdateFileBrowser(); this.Show(); }).AsyncWaitHandle.WaitOne();; loaderProgress.BeginInvoke((MethodInvoker) delegate() { loaderProgress.Close(); }); Console.WriteLine("All files added"); })); }