Пример #1
0
        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();
        }
Пример #2
0
 public void UpdatePathableStates()
 {
     foreach (var pathable in Pathables.ToArray())
     {
         this.ProcessPathableState(pathable);
     }
 }
Пример #3
0
        /// <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);
        }
Пример #4
0
        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);
        }
Пример #5
0
 public IWebSocketConnection[] GetAllConnections()
 {
     try
     {
         _readerWriterLockSlim.EnterReadLock();
         return(_connections.ToArray());
     }
     finally
     {
         _readerWriterLockSlim.ExitReadLock();
     }
 }
Пример #6
0
        public static T[] ToArrayLocked <T>(this SynchronizedCollection <T> coll)
        {
            if (coll == null)
            {
                throw new ArgumentNullException(nameof(coll));
            }

            lock (coll.SyncRoot)
            {
                return(coll.ToArray());
            }
        }
Пример #7
0
        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());
        }
Пример #8
0
        /// <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.");
            }
        }
Пример #9
0
        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;
        }
Пример #10
0
        /// <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);
            }
        }
Пример #11
0
        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");
        }
Пример #12
0
		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();
			}
		}
Пример #13
0
        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);
            }
        }
Пример #14
0
        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");
            }));
        }